Ticket #4191: wp-app.php.diff
| File wp-app.php.diff, 33.2 kB (added by placey, 1 year ago) |
|---|
-
wp-app.php
old new 11 11 12 12 require_once('./wp-config.php'); 13 13 require_once(ABSPATH . WPINC . '/post-template.php'); 14 require_once(ABSPATH . WPINC . '/atomlib.php'); 14 15 15 16 // Attempt to automatically detect whether to use querystring 16 17 // or PATH_INFO, based on our environment: … … 28 29 $_SERVER['PATH_INFO'] .= "/$eid"; 29 30 } 30 31 } else { 31 $_SERVER['PATH_INFO'] = str_replace( ' /wp-app.php', '', $_SERVER['REQUEST_URI'] );32 $_SERVER['PATH_INFO'] = str_replace( '.*/wp-app.php', '', $_SERVER['REQUEST_URI'] ); 32 33 } 33 34 34 35 $app_logging = 0; 35 36 37 // TODO: Should be an option somewhere 38 $always_authenticate = 1; 39 36 40 function log_app($label,$msg) { 37 41 global $app_logging; 38 42 if ($app_logging) { 39 $fp = fopen( ' app.log', 'a+');43 $fp = fopen( 'wp-app.log', 'a+'); 40 44 $date = gmdate( 'Y-m-d H:i:s' ); 41 45 fwrite($fp, "\n\n$date - $label\n$msg\n"); 42 46 fclose($fp); … … 57 61 endif; 58 62 59 63 function wa_posts_where_include_drafts_filter($where) { 60 $where = ereg_replace("post_author = ([0-9]+) AND post_status != 'draft'","post_author = \\1 AND post_status = 'draft'", $where); 61 return $where; 64 $where = str_replace("post_status = 'publish'","post_status = 'publish' OR post_status = 'future' OR post_status = 'draft' OR post_status = 'inherit'", $where); 65 return $where; 66 62 67 } 63 68 add_filter('posts_where', 'wa_posts_where_include_drafts_filter'); 64 69 65 class AtomEntry {66 var $links = array();67 var $categories = array();68 }69 70 class AtomParser {71 72 var $ATOM_CONTENT_ELEMENTS = array('content','summary','title','subtitle','rights');73 var $ATOM_SIMPLE_ELEMENTS = array('id','updated','published','draft');74 75 var $depth = 0;76 var $indent = 2;77 var $in_content;78 var $ns_contexts = array();79 var $ns_decls = array();80 var $is_xhtml = false;81 var $skipped_div = false;82 83 var $entry;84 85 function AtomParser() {86 87 $this->entry = new AtomEntry();88 $this->map_attrs_func = create_function('$k,$v', 'return "$k=\"$v\"";');89 $this->map_xmlns_func = create_function('$p,$n', '$xd = "xmlns"; if(strlen($n[0])>0) $xd .= ":{$n[0]}"; return "{$xd}=\"{$n[1]}\"";');90 }91 92 function parse() {93 94 global $app_logging;95 array_unshift($this->ns_contexts, array());96 97 $parser = xml_parser_create_ns();98 xml_set_object($parser, $this);99 xml_set_element_handler($parser, "start_element", "end_element");100 xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0);101 xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,0);102 xml_set_character_data_handler($parser, "cdata");103 xml_set_default_handler($parser, "_default");104 xml_set_start_namespace_decl_handler($parser, "start_ns");105 xml_set_end_namespace_decl_handler($parser, "end_ns");106 107 $contents = "";108 109 $fp = fopen("php://input", "r");110 while(!feof($fp)) {111 $line = fgets($fp, 4096);112 113 if($app_logging) $contents .= $line;114 115 if(!xml_parse($parser, $line)) {116 log_app("xml_parse_error", "line: $line");117 $this->error = sprintf(__('XML error: %s at line %d')."\n",118 xml_error_string(xml_get_error_code($xml_parser)),119 xml_get_current_line_number($xml_parser));120 log_app("xml_parse_error", $this->error);121 return false;122 }123 }124 fclose($fp);125 126 xml_parser_free($parser);127 128 log_app("AtomParser->parse()",trim($contents));129 130 return true;131 }132 133 function start_element($parser, $name, $attrs) {134 135 $tag = array_pop(split(":", $name));136 137 array_unshift($this->ns_contexts, $this->ns_decls);138 139 $this->depth++;140 141 #print str_repeat(" ", $this->depth * $this->indent) . "start_element('$name')" ."\n";142 #print str_repeat(" ", $this->depth+1 * $this->indent) . print_r($this->ns_contexts,true) ."\n";143 144 if(!empty($this->in_content)) {145 $attrs_prefix = array();146 147 // resolve prefixes for attributes148 foreach($attrs as $key => $value) {149 $attrs_prefix[$this->ns_to_prefix($key)] = $this->xml_escape($value);150 }151 $attrs_str = join(' ', array_map($this->map_attrs_func, array_keys($attrs_prefix), array_values($attrs_prefix)));152 if(strlen($attrs_str) > 0) {153 $attrs_str = " " . $attrs_str;154 }155 156 $xmlns_str = join(' ', array_map($this->map_xmlns_func, array_keys($this->ns_contexts[0]), array_values($this->ns_contexts[0])));157 if(strlen($xmlns_str) > 0) {158 $xmlns_str = " " . $xmlns_str;159 }160 161 // handle self-closing tags (case: a new child found right-away, no text node)162 if(count($this->in_content) == 2) {163 array_push($this->in_content, ">");164 }165 166 array_push($this->in_content, "<". $this->ns_to_prefix($name) ."{$xmlns_str}{$attrs_str}");167 } else if(in_array($tag, $this->ATOM_CONTENT_ELEMENTS) || in_array($tag, $this->ATOM_SIMPLE_ELEMENTS)) {168 $this->in_content = array();169 $this->is_xhtml = $attrs['type'] == 'xhtml';170 array_push($this->in_content, array($tag,$this->depth));171 } else if($tag == 'link') {172 array_push($this->entry->links, $attrs);173 } else if($tag == 'category') {174 array_push($this->entry->categories, $attrs);175 }176 177 $this->ns_decls = array();178 }179 180 function end_element($parser, $name) {181 182 $tag = array_pop(split(":", $name));183 184 if(!empty($this->in_content)) {185 if($this->in_content[0][0] == $tag &&186 $this->in_content[0][1] == $this->depth) {187 array_shift($this->in_content);188 if($this->is_xhtml) {189 $this->in_content = array_slice($this->in_content, 2, count($this->in_content)-3);190 }191 $this->entry->$tag = join('',$this->in_content);192 $this->in_content = array();193 } else {194 $endtag = $this->ns_to_prefix($name);195 if (strpos($this->in_content[count($this->in_content)-1], '<' . $endtag) !== false) {196 array_push($this->in_content, "/>");197 } else {198 array_push($this->in_content, "</$endtag>");199 }200 }201 }202 203 array_shift($this->ns_contexts);204 205 #print str_repeat(" ", $this->depth * $this->indent) . "end_element('$name')" ."\n";206 207 $this->depth--;208 }209 210 function start_ns($parser, $prefix, $uri) {211 #print str_repeat(" ", $this->depth * $this->indent) . "starting: " . $prefix . ":" . $uri . "\n";212 array_push($this->ns_decls, array($prefix,$uri));213 }214 215 function end_ns($parser, $prefix) {216 #print str_repeat(" ", $this->depth * $this->indent) . "ending: #" . $prefix . "#\n";217 }218 219 function cdata($parser, $data) {220 #print str_repeat(" ", $this->depth * $this->indent) . "data: #" . $data . "#\n";221 if(!empty($this->in_content)) {222 // handle self-closing tags (case: text node found, need to close element started)223 if (strpos($this->in_content[count($this->in_content)-1], '<') !== false) {224 array_push($this->in_content, ">");225 }226 array_push($this->in_content, $this->xml_escape($data));227 }228 }229 230 function _default($parser, $data) {231 # when does this gets called?232 }233 234 235 function ns_to_prefix($qname) {236 $components = split(":", $qname);237 $name = array_pop($components);238 239 if(!empty($components)) {240 $ns = join(":",$components);241 foreach($this->ns_contexts as $context) {242 foreach($context as $mapping) {243 if($mapping[1] == $ns && strlen($mapping[0]) > 0) {244 return "$mapping[0]:$name";245 }246 }247 }248 }249 return $name;250 }251 252 function xml_escape($string)253 {254 return str_replace(array('&','"',"'",'<','>'),255 array('&','"',''','<','>'),256 $string );257 }258 }259 260 70 class AtomServer { 261 71 262 72 var $ATOM_CONTENT_TYPE = 'application/atom+xml'; 263 73 var $CATEGORIES_CONTENT_TYPE = 'application/atomcat+xml'; 264 var $ INTROSPECTION_CONTENT_TYPE = 'application/atomserv+xml';74 var $SERVICE_CONTENT_TYPE = 'application/atomsvc+xml'; 265 75 76 var $ATOM_NS = 'http://www.w3.org/2005/Atom'; 77 var $ATOMPUB_NS = 'http://www.w3.org/2007/app'; 78 266 79 var $ENTRIES_PATH = "posts"; 267 80 var $CATEGORIES_PATH = "categories"; 268 81 var $MEDIA_PATH = "attachments"; 269 82 var $ENTRY_PATH = "post"; 83 var $SERVICE_PATH = "service"; 270 84 var $MEDIA_SINGLE_PATH = "attachment"; 271 85 272 86 var $params = array(); … … 284 98 $this->script_name = array_pop(explode('/',$_SERVER['SCRIPT_NAME'])); 285 99 286 100 $this->selectors = array( 287 '@/service @' =>101 '@/service$@' => 288 102 array('GET' => 'get_service'), 289 '@/categories @' =>103 '@/categories$@' => 290 104 array('GET' => 'get_categories_xml'), 291 '@/post/(\d+) @' =>105 '@/post/(\d+)$@' => 292 106 array('GET' => 'get_post', 293 107 'PUT' => 'put_post', 294 108 'DELETE' => 'delete_post'), 295 '@/posts/?( [^/]+)?@' =>109 '@/posts/?(\d+)?$@' => 296 110 array('GET' => 'get_posts', 297 111 'POST' => 'create_post'), 298 '@/attachments/?(\d+)? @' =>112 '@/attachments/?(\d+)?$@' => 299 113 array('GET' => 'get_attachment', 300 114 'POST' => 'create_attachment'), 301 '@/attachment/file/(\d+) @' =>115 '@/attachment/file/(\d+)$@' => 302 116 array('GET' => 'get_file', 303 117 'PUT' => 'put_file', 304 118 'DELETE' => 'delete_file'), 305 '@/attachment/(\d+) @' =>119 '@/attachment/(\d+)$@' => 306 120 array('GET' => 'get_attachment', 307 121 'PUT' => 'put_attachment', 308 122 'DELETE' => 'delete_attachment'), … … 310 124 } 311 125 312 126 function handle_request() { 127 global $always_authenticate; 313 128 314 129 $path = $_SERVER['PATH_INFO']; 315 130 $method = $_SERVER['REQUEST_METHOD']; 316 131 317 132 log_app('REQUEST',"$method $path\n================"); 318 133 134 $this->process_conditionals(); 319 135 //$this->process_conditionals(); 320 136 321 137 // exception case for HEAD (treat exactly as GET, but don't output) … … 324 140 $method = 'GET'; 325 141 } 326 142 327 // lame.143 // redirect to /service in case no path is found. 328 144 if(strlen($path) == 0 || $path == '/') { 329 $path = '/service';145 $this->redirect($this->get_service_url()); 330 146 } 331 332 // authenticate regardless of the operation and set the current 333 // user. each handler will decide if auth is required or not. 334 $this->authenticate(); 335 147 336 148 // dispatch 337 149 foreach($this->selectors as $regex => $funcs) { 338 150 if(preg_match($regex, $path, $matches)) { 339 if(isset($funcs[$method])) { 340 array_shift($matches); 341 call_user_func_array(array(&$this,$funcs[$method]), $matches); 342 exit(); 343 } else { 344 // only allow what we have handlers for... 345 $this->not_allowed(array_keys($funcs)); 346 } 151 if(isset($funcs[$method])) { 152 153 // authenticate regardless of the operation and set the current 154 // user. each handler will decide if auth is required or not. 155 $this->authenticate(); 156 $u = wp_get_current_user(); 157 if(!isset($u) || $u->ID == 0) { 158 if ($always_authenticate) { 159 $this->auth_required('Credentials required.'); 160 } 161 } 162 163 array_shift($matches); 164 call_user_func_array(array(&$this,$funcs[$method]), $matches); 165 exit(); 166 } else { 167 // only allow what we have handlers for... 168 $this->not_allowed(array_keys($funcs)); 347 169 } 170 } 348 171 } 349 172 350 173 // oops, nothing found … … 353 176 354 177 function get_service() { 355 178 log_app('function','get_service()'); 356 $entries_url = $this->get_entries_url(); 357 $categories_url = $this->get_categories_url(); 358 $media_url = $this->get_attachments_url(); 359 $accepted_content_types = join(',',$this->media_content_types); 360 $introspection = <<<EOD 361 <service xmlns="http://purl.org/atom/app#" xmlns:atom="http://www.w3.org/2005/Atom"> 362 <workspace title="WordPress Workspace"> 363 <collection href="$entries_url" title="Posts"> 364 <atom:title>WordPress Posts</atom:title> 365 <accept>entry</accept> 366 <categories href="$categories_url" /> 367 </collection> 368 <collection href="$media_url" title="Media"> 369 <atom:title>WordPress Media</atom:title> 370 <accept>$accepted_content_types</accept> 371 </collection> 372 </workspace> 179 $entries_url = attribute_escape($this->get_entries_url()); 180 $categories_url = attribute_escape($this->get_categories_url()); 181 $media_url = attribute_escape($this->get_attachments_url()); 182 foreach ($this->media_content_types as $med) { 183 $accepted_media_types = $accepted_media_types . "<accept>" . $med . "</accept>"; 184 } 185 $atom_prefix="atom"; 186 $service_doc = <<<EOD 187 <service xmlns="$this->ATOMPUB_NS" xmlns:$atom_prefix="$this->ATOM_NS"> 188 <workspace> 189 <$atom_prefix:title>WordPress Workspace</$atom_prefix:title> 190 <collection href="$entries_url"> 191 <$atom_prefix:title>WordPress Posts</$atom_prefix:title> 192 <accept>$this->ATOM_CONTENT_TYPE;type=entry</accept> 193 <categories href="$categories_url" /> 194 </collection> 195 <collection href="$media_url"> 196 <$atom_prefix:title>WordPress Media</$atom_prefix:title> 197 $accepted_media_types 198 </collection> 199 </workspace> 373 200 </service> 374 201 375 202 EOD; 376 203 377 $this->output($ introspection, $this->INTROSPECTION_CONTENT_TYPE);204 $this->output($service_doc, $this->SERVICE_CONTENT_TYPE); 378 205 } 379 206 380 function get_categories_xml() { 381 log_app('function','get_categories_xml()'); 382 $home = get_bloginfo_rss('home'); 207 function get_categories_xml() { 383 208 384 $categories = ""; 385 $cats = get_categories("hierarchical=0&hide_empty=0"); 386 foreach ((array) $cats as $cat) { 387 $categories .= " <category term=\"" . attribute_escape($cat->name) . "\" />\n"; 388 } 389 $output = <<<EOD 390 <app:categories xmlns:app="http://purl.org/atom/app#" 391 xmlns="http://www.w3.org/2005/Atom" 209 log_app('function','get_categories_xml()'); 210 $home = attribute_escape(get_bloginfo_rss('home')); 211 212 $categories = ""; 213 $cats = get_categories("hierarchical=0&hide_empty=0"); 214 foreach ((array) $cats as $cat) { 215 $categories .= " <category term=\"" . attribute_escape($cat->cat_name) . "\" />\n"; 216 } 217 $output = <<<EOD 218 <app:categories xmlns:app="$this->ATOMPUB_NS" 219 xmlns="$this->ATOM_NS" 392 220 fixed="yes" scheme="$home"> 393 221 $categories 394 222 </app:categories> … … 400 228 * Create Post (No arguments) 401 229 */ 402 230 function create_post() { 403 global $blog_id ;231 global $blog_id, $wpdb; 404 232 $this->get_accepted_content_type($this->atom_content_types); 405 233 406 234 $parser = new AtomParser(); … … 408 236 $this->client_error(); 409 237 } 410 238 411 $entry = $parser->entry; 239 $entry = array_pop($parser->feed->entries); 240 241 log_app('Received entry:', print_r($entry,true)); 242 243 $catnames = array(); 244 foreach($entry->categories as $cat) 245 array_push($catnames, $cat["term"]); 246 247 $wp_cats = get_categories(array('hide_empty' => false)); 248 log_app('CATEGORIES :', print_r($wp_cats,true)); 249 250 $post_category = array(); 251 252 foreach($wp_cats as $cat) { 253 if(in_array($cat->cat_name, $catnames)) 254 array_push($post_category, $cat->cat_ID); 255 } 412 256 413 257 $publish = (isset($entry->draft) && trim($entry->draft) == 'yes') ? false : true; 414 258 … … 420 264 $blog_ID = (int ) $blog_id; 421 265 $post_status = ($publish) ? 'publish' : 'draft'; 422 266 $post_author = (int) $user->ID; 423 $post_title = $this->escape($entry->title); 424 $post_content = $this->escape($entry->content); 425 $post_excerpt = $this->escape($entry->summary); 426 $post_date = current_time('mysql'); 427 $post_date_gmt = current_time('mysql', 1); 267 $post_title = $entry->title[1]; 268 $post_content = $entry->content[1]; 269 $post_excerpt = $entry->summary[1]; 270 $pubtimes = $this->get_publish_time($entry); 271 $post_date = $pubtimes[0]; 272 $post_date_gmt = $pubtimes[1]; 273 274 if ( isset( $_SERVER['HTTP_SLUG'] ) ) 275 $post_name = $_SERVER['HTTP_SLUG']; 428 276 429 $post_data = compact('blog_ID', 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt' );277 $post_data = compact('blog_ID', 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt', 'post_name'); 430 278 279 $this->escape($post_data); 431 280 log_app('Inserting Post. Data:', print_r($post_data,true)); 432 281 433 282 $postID = wp_insert_post($post_data); … … 436 285 $this->internal_error(__('Sorry, your entry could not be posted. Something wrong happened.')); 437 286 } 438 287 288 // getting warning here about unable to set headers 289 // because something in the cache is printing to the buffer 290 // could we clean up wp_set_post_categories or cache to not print 291 // this could affect our ability to send back the right headers 292 @wp_set_post_categories($postID, $post_category); 293 439 294 $output = $this->get_entry($postID); 440 295 441 296 log_app('function',"create_post($postID)"); … … 453 308 } 454 309 455 310 function put_post($postID) { 311 global $wpdb; 456 312 457 313 // checked for valid content-types (atom+xml) 458 314 // quick check and exit … … 463 319 $this->bad_request(); 464 320 } 465 321 466 $parsed = $parser->entry;322 $parsed = array_pop($parser->feed->entries); 467 323 324 log_app('Received UPDATED entry:', print_r($parsed,true)); 325 468 326 // check for not found 469 327 global $entry; 470 328 $entry = $GLOBALS['entry']; 471 329 $this->set_current_entry($postID); 472 $this->escape($GLOBALS['entry']);473 330 474 331 if(!current_user_can('edit_post', $entry['ID'])) 475 332 $this->auth_required(__('Sorry, you do not have the right to edit this post.')); … … 478 335 479 336 extract($entry); 480 337 481 $post_title = $this->escape($parsed->title); 482 $post_content = $this->escape($parsed->content); 483 $post_excerpt = $this->escape($parsed->summary); 338 $post_title = $parsed->title[1]; 339 $post_content = $parsed->content[1]; 340 $post_excerpt = $parsed->summary[1]; 341 $pubtimes = $this->get_publish_time($entry); 342 $post_date = $pubtimes[0]; 343 $post_date_gmt = $pubtimes[1]; 484 344 485 345 // let's not go backwards and make something draft again. 486 346 if(!$publish && $post_status == 'draft') { 487 347 $post_status = ($publish) ? 'publish' : 'draft'; 348 } elseif($publish) { 349 $post_status = 'publish'; 488 350 } 489 351 490 $postdata = compact('ID', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt'); 352 $postdata = compact('ID', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt', 'post_date', 'post_date_gmt'); 353 $this->escape($postdata); 491 354 355 log_app('UPDATING ENTRY WITH:', print_r($postdata,true)); 356 492 357 $result = wp_update_post($postdata); 493 358 494 359 if (!$result) { … … 595 460 } 596 461 597 462 function put_attachment($postID) { 463 global $wpdb; 598 464 599 465 // checked for valid content-types (atom+xml) 600 466 // quick check and exit … … 605 471 $this->bad_request(); 606 472 } 607 473 608 $parsed = $parser->entry;474 $parsed = array_pop($parser->feed->entries); 609 475 610 476 // check for not found 611 477 global $entry; 612 478 $this->set_current_entry($postID); 613 $this->escape($entry);614 479 615 480 if(!current_user_can('edit_post', $entry['ID'])) 616 481 $this->auth_required(__('Sorry, you do not have the right to edit this post.')); … … 619 484 620 485 extract($entry); 621 486 622 $post_title = $ this->escape($parsed->title);623 $post_content = $ this->escape($parsed->content);487 $post_title = $parsed->title[1]; 488 $post_content = $parsed->content[1]; 624 489 625 490 $postdata = compact('ID', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt'); 491 $this->escape($postdata); 626 492 627 493 $result = wp_update_post($postdata); 628 494 … … 678 544 if(!isset($location) || 'attachment' != $entry['post_type'] || empty($filetype['ext'])) 679 545 $this->internal_error(__('Error ocurred while accessing post metadata for file location.')); 680 546 547 status_header('200'); 681 548 header('Content-Type: ' . $entry['post_mime_type']); 549 header('Connection: close'); 682 550 683 551 $fp = fopen($location, "rb"); 684 552 while(!feof($fp)) { … … 687 555 fclose($fp); 688 556 689 557 log_app('function',"get_file($postID)"); 690 $this->ok();558 exit; 691 559 } 692 560 693 561 function put_file($postID) { … … 721 589 fclose($fp); 722 590 fclose($localfp); 723 591 592 $ID = $entry['ID']; 593 $pubtimes = $this->get_publish_time($entry); 594 $post_date = $pubtimes[0]; 595 $post_date_gmt = $pubtimes[1]; 596 597 $post_data = compact('ID', 'post_date', 'post_date_gmt'); 598 $result = wp_update_post($post_data); 599 600 if (!$result) { 601 $this->internal_error(__('Sorry, your entry could not be posted. Something wrong happened.')); 602 } 603 724 604 log_app('function',"put_file($postID)"); 725 605 $this->ok(); 726 606 } 727 607 728 608 function get_entries_url($page = NULL) { 729 609 global $use_querystring; 610 if($GLOBALS['post_type'] == 'attachment') { 611 $path = $this->MEDIA_PATH; 612 } else { 613 $path = $this->ENTRIES_PATH; 614 } 730 615 $url = get_bloginfo('url') . '/' . $this->script_name; 731 616 if ($use_querystring) { 732 $url .= '?action=/' . $ this->ENTRIES_PATH;617 $url .= '?action=/' . $path; 733 618 if(isset($page) && is_int($page)) { 734 619 $url .= "&eid=$page"; 735 620 } 736 621 } else { 737 $url .= '/' . $ this->ENTRIES_PATH;622 $url .= '/' . $path; 738 623 if(isset($page) && is_int($page)) { 739 624 $url .= "/$page"; 740 625 } … … 761 646 function the_categories_url() { 762 647 $url = $this->get_categories_url(); 763 648 echo $url; 764 }649 } 765 650 766 651 function get_attachments_url($page = NULL) { 767 652 global $use_querystring; … … 785 670 echo $url; 786 671 } 787 672 673 function get_service_url() { 674 global $use_querystring; 675 $url = get_bloginfo('url') . '/' . $this->script_name; 676 if ($use_querystring) { 677 $url .= '?action=/' . $this->SERVICE_PATH; 678 } else { 679 $url .= '/' . $this->SERVICE_PATH; 680 } 681 return $url; 682 } 788 683 789 684 function get_entry_url($postID = NULL) { 790 685 global $use_querystring; … … 816 711 } 817 712 818 713 if ($use_querystring) { 819 $url = get_bloginfo('url') . '/' . $this->script_name . '?action=/' . $this->MEDIA_SINGLE_PATH ." &eid=$postID";714 $url = get_bloginfo('url') . '/' . $this->script_name . '?action=/' . $this->MEDIA_SINGLE_PATH ."/file&eid=$postID"; 820 715 } else { 821 $url = get_bloginfo('url') . '/' . $this->script_name . '/' . $this->MEDIA_SINGLE_PATH ."/ $postID";716 $url = get_bloginfo('url') . '/' . $this->script_name . '/' . $this->MEDIA_SINGLE_PATH ."/file/$postID"; 822 717 } 823 718 824 719 log_app('function',"get_media_url() = $url"); … … 847 742 return; 848 743 } 849 744 850 function get_posts_count() {851 global $wpdb;852 log_app('function',"get_posts_count()");853 return $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->posts WHERE post_date_gmt < '" . gmdate("Y-m-d H:i:s",time()) . "'");854 }855 856 857 745 function get_posts($page = 1, $post_type = 'post') { 858 746 log_app('function',"get_posts($page, '$post_type')"); 859 747 $feed = $this->get_feed($page, $post_type); … … 861 749 } 862 750 863 751 function get_attachments($page = 1, $post_type = 'attachment') { 864 log_app('function',"get_attachments($page, '$post_type')"); 865 $feed = $this->get_feed($page, $post_type); 866 $this->output($feed); 752 log_app('function',"get_attachments($page, '$post_type')"); 753 $GLOBALS['post_type'] = $post_type; 754 $feed = $this->get_feed($page, $post_type); 755 $this->output($feed); 867 756 } 868 757 869 758 function get_feed($page = 1, $post_type = 'post') { … … 877 766 $page = (int) $page; 878 767 879 768 $count = get_option('posts_per_rss'); 880 $query = "paged=$page&posts_per_page=$count&order=DESC"; 881 if($post_type == 'attachment') { 882 $query .= "&post_type=$post_type"; 883 } 884 query_posts($query); 769 770 wp('what_to_show=posts&posts_per_page=' . $count . '&offset=' . ($page-1)); 771 885 772 $post = $GLOBALS['post']; 886 773 $posts = $GLOBALS['posts']; 887 774 $wp = $GLOBALS['wp']; … … 889 776 $wpdb = $GLOBALS['wpdb']; 890 777 $blog_id = (int) $GLOBALS['blog_id']; 891 778 $post_cache = $GLOBALS['post_cache']; 779 log_app('function',"query_posts(# " . print_r($wp_query, true) . "#)"); 892 780 893 894 $total_count = $this->get_posts_count(); 895 $last_page = (int) ceil($total_count / $count); 781 log_app('function',"total_count(# $wp_query->max_num_pages #)"); 782 $last_page = $wp_query->max_num_pages; 896 783 $next_page = (($page + 1) > $last_page) ? NULL : $page + 1; 897 784 $prev_page = ($page - 1) < 1 ? NULL : $page - 1; 898 785 $last_page = ((int)$last_page == 1 || (int)$last_page == 0) ? NULL : (int) $last_page; 899 ?><feed xmlns=" http://www.w3.org/2005/Atom" xmlns:app="http://purl.org/atom/app#" xml:lang="<?php echo get_option('rss_language'); ?>">786 ?><feed xmlns="<?php echo $this->ATOM_NS ?>" xmlns:app="<?php echo $this->ATOMPUB_NS ?>" xml:lang="<?php echo get_option('rss_language'); ?>"> 900 787 <id><?php $this->the_entries_url() ?></id> 901 788 <updated><?php echo mysql2date('Y-m-d\TH:i:s\Z', get_lastpostmodified('GMT')); ?></updated> 902 789 <title type="text"><?php bloginfo_rss('name') ?></title> 903 790 <subtitle type="text"><?php bloginfo_rss("description") ?></subtitle> 904 <link rel="first" type=" application/atom+xml" href="<?php $this->the_entries_url() ?>" />791 <link rel="first" type="<?php echo $this->ATOM_CONTENT_TYPE ?>" href="<?php $this->the_entries_url() ?>" /> 905 792 <?php if(isset($prev_page)): ?> 906 <link rel="previous" type=" application/atom+xml" href="<?php $this->the_entries_url($prev_page) ?>" />793 <link rel="previous" type="<?php echo $this->ATOM_CONTENT_TYPE ?>" href="<?php $this->the_entries_url($prev_page) ?>" /> 907 794 <?php endif; ?> 908 795 <?php if(isset($next_page)): ?> 909 <link rel="next" type=" application/atom+xml" href="<?php $this->the_entries_url($next_page) ?>" />796 <link rel="next" type="<?php echo $this->ATOM_CONTENT_TYPE ?>" href="<?php $this->the_entries_url($next_page) ?>" /> 910 797 <?php endif; ?> 911 <link rel="last" type=" application/atom+xml" href="<?php $this->the_entries_url($last_page) ?>" />912 <link rel="self" type=" application/atom+xml" href="<?php $this->the_entries_url() ?>" />798 <link rel="last" type="<?php echo $this->ATOM_CONTENT_TYPE ?>" href="<?php $this->the_entries_url($last_page) ?>" /> 799 <link rel="self" type="<?php echo $this->ATOM_CONTENT_TYPE ?>" href="<?php $this->the_entries_url() ?>" /> 913 800 <rights type="text">Copyright <?php echo mysql2date('Y', get_lastpostdate('blog')); ?></rights> 914 801 <generator uri="http://wordpress.com/" version="1.0.5-dc">WordPress.com Atom API</generator> 915 802 <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); … … 917 804 ?> 918 805 <entry> 919 806 <id><?php the_guid($post->ID); ?></id> 920 <title type=" html"><![CDATA[<?php the_title() ?>]]></title>807 <title type="text"><![CDATA[<?php the_title_rss() ?>]]></title> 921 808 <updated><?php echo get_post_modified_time('Y-m-d\TH:i:s\Z', true); ?></updated> 922 809 <published><?php echo get_post_time('Y-m-d\TH:i:s\Z', true); ?></published> 810 <app:edited><?php echo get_post_modified_time('Y-m-d\TH:i:s\Z', true); ?></app:edited> 923 811 <app:control> 924 812 <app:draft><?php echo ($GLOBALS['post']->post_status == 'draft' ? 'yes' : 'no') ?></app:draft> 925 813 </app:control> 926 814 <author> 927 815 <name><?php the_author()?></name> 928 816 <email><?php the_author_email()?></email> 929 <?php if (get_the_author_url() && get_the_author_url() != 'http://') { ?>930 <uri><?php the_author_url()?></uri>931 <?php } ?>817 <?php if (get_the_author_url() && get_the_author_url() != 'http://') { ?> 818 <uri><?php the_author_url()?></uri> 819 <?php } ?> 932 820 </author> 933 <?php if($GLOBALS['post']->post_status == 'attachment') { ?> 934 <link rel="edit" href="<?php $this->the_entry_url() ?>" /> 821 <?php if($GLOBALS['post']->post_type == 'attachment') { ?> 935 822 <link rel="edit-media" href="<?php $this->the_media_url() ?>" /> 823 <content type="<?php echo $GLOBALS['post']->post_mime_type ?>" src="<?php the_guid(); ?>"/> 936 824 <?php } else { ?> 937 825 <link href="<?php the_permalink_rss() ?>" /> 938 <link rel="edit" href="<?php $this->the_entry_url() ?>" /> 826 <?php if ( strlen( $GLOBALS['post']->post_content ) ) : ?> 827 <content type="html"><![CDATA[<?php echo get_the_content('', 0, '') ?>]]></content> 828 <?php endif; ?> 939 829 <?php } ?> 830 <link rel="edit" href="<?php $this->the_entry_url() ?>" /> 940 831 <?php foreach(get_the_category() as $category) { ?> 941 <category scheme="<?php bloginfo_rss('home') ?>" term="<?php echo $category->name?>" /> 942
