Ticket #4191: wp-app.patch
File wp-app.patch, 27.3 KB (added by , 18 years ago) |
---|
-
wp-app.php
11 11 12 12 require_once('wp-config.php'); 13 13 require_once('wp-includes/post-template.php'); 14 require_once('wp-includes/atomlib.php'); 14 15 15 16 // Attempt to automatically detect whether to use querystring 16 17 // or PATH_INFO, based on our environment: … … 18 19 19 20 // If using querystring, we need to put the path together manually: 20 21 if ($use_querystring) { 21 $GLOBALS['use_querystring'] = $use_querystring;22 GLOBALS['use_querystring'] = $use_querystring; 22 23 $action = $_GET['action']; 23 24 $eid = (int) $_GET['eid']; 24 25 … … 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; … … 36 37 function log_app($label,$msg) { 37 38 global $app_logging; 38 39 if ($app_logging) { 39 $fp = fopen( ' app.log', 'a+');40 $fp = fopen( 'wp-app.log', 'a+'); 40 41 $date = gmdate( 'Y-m-d H:i:s' ); 41 42 fwrite($fp, "\n\n$date - $label\n$msg\n"); 42 43 fclose($fp); … … 57 58 endif; 58 59 59 60 function wa_posts_where_include_drafts_filter($where) { 60 $where = ereg_replace("post_author = ([0-9]+) AND post_status != 'draft'","post_author = \\1 ANDpost_status = 'draft'", $where);61 61 $where = ereg_replace("post_status = 'publish'","post_status = 'publish' OR post_status = 'future' OR post_status = 'draft'", $where); 62 return $where; 62 63 } 63 64 add_filter('posts_where', 'wa_posts_where_include_drafts_filter'); 64 65 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 66 class AtomServer { 261 67 262 68 var $ATOM_CONTENT_TYPE = 'application/atom+xml'; 263 69 var $CATEGORIES_CONTENT_TYPE = 'application/atomcat+xml'; 264 var $INTROSPECTION_CONTENT_TYPE = 'application/atoms erv+xml';70 var $INTROSPECTION_CONTENT_TYPE = 'application/atomsvc+xml'; 265 71 266 72 var $ENTRIES_PATH = "posts"; 267 73 var $CATEGORIES_PATH = "categories"; 268 74 var $MEDIA_PATH = "attachments"; 269 75 var $ENTRY_PATH = "post"; 76 var $SERVICE_PATH = "service"; 270 77 var $MEDIA_SINGLE_PATH = "attachment"; 271 78 272 79 var $params = array(); … … 284 91 $this->script_name = array_pop(explode('/',$_SERVER['SCRIPT_NAME'])); 285 92 286 93 $this->selectors = array( 287 '@/service @' =>94 '@/service$@' => 288 95 array('GET' => 'get_service'), 289 '@/categories @' =>96 '@/categories$@' => 290 97 array('GET' => 'get_categories_xml'), 291 '@/post/(\d+) @' =>98 '@/post/(\d+)$@' => 292 99 array('GET' => 'get_post', 293 100 'PUT' => 'put_post', 294 101 'DELETE' => 'delete_post'), 295 '@/posts/?( [^/]+)?@' =>102 '@/posts/?(\d+)?$@' => 296 103 array('GET' => 'get_posts', 297 104 'POST' => 'create_post'), 298 '@/attachments/?(\d+)? @' =>105 '@/attachments/?(\d+)?$@' => 299 106 array('GET' => 'get_attachment', 300 107 'POST' => 'create_attachment'), 301 '@/attachment/file/(\d+) @' =>108 '@/attachment/file/(\d+)$@' => 302 109 array('GET' => 'get_file', 303 110 'PUT' => 'put_file', 304 111 'DELETE' => 'delete_file'), 305 '@/attachment/(\d+) @' =>112 '@/attachment/(\d+)$@' => 306 113 array('GET' => 'get_attachment', 307 114 'PUT' => 'put_attachment', 308 115 'DELETE' => 'delete_attachment'), … … 324 131 $method = 'GET'; 325 132 } 326 133 327 // lame.134 // redirect to /service in case no path is found. 328 135 if(strlen($path) == 0 || $path == '/') { 329 $path = '/service';136 $this->redirect($this->get_service_url()); 330 137 } 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 138 336 139 // dispatch 337 140 foreach($this->selectors as $regex => $funcs) { 338 141 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 } 142 if(isset($funcs[$method])) { 143 144 // authenticate regardless of the operation and set the current 145 // user. each handler will decide if auth is required or not. 146 $this->authenticate(); 147 $u = wp_get_current_user(); 148 if(!isset($u) || $u->ID == 0) { 149 $this->auth_required('Credentials required.'); 150 } 151 152 array_shift($matches); 153 call_user_func_array(array(&$this,$funcs[$method]), $matches); 154 exit(); 155 } else { 156 // only allow what we have handlers for... 157 $this->not_allowed(array_keys($funcs)); 347 158 } 159 } 348 160 } 349 161 350 162 // oops, nothing found … … 353 165 354 166 function get_service() { 355 167 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);168 $entries_url = attribute_escape($this->get_entries_url()); 169 $categories_url = attribute_escape($this->get_categories_url()); 170 $media_url = attribute_escape($this->get_attachments_url()); 171 $accepted_content_types = attribute_escape(join(',',$this->media_content_types)); 360 172 $introspection = <<<EOD 361 173 <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> 174 <workspace> 175 <atom:title>WordPress Workspace</atom:title> 176 <collection href="$entries_url"> 177 <atom:title>WordPress Posts</atom:title> 178 <accept>entry</accept> 179 <categories href="$categories_url" /> 180 </collection> 181 <collection href="$media_url"> 182 <atom:title>WordPress Media</atom:title> 183 <accept>$accepted_content_types</accept> 184 </collection> 185 </workspace> 373 186 </service> 374 187 375 188 EOD; … … 377 190 $this->output($introspection, $this->INTROSPECTION_CONTENT_TYPE); 378 191 } 379 192 380 function get_categories_xml() { 381 log_app('function','get_categories_xml()'); 382 $home = get_bloginfo_rss('home'); 193 function get_categories_xml() { 194 195 log_app('function','get_categories_xml()'); 196 $home = attribute_escape(get_bloginfo_rss('home')); 383 197 384 $categories = "";385 $cats = get_categories("hierarchical=0&hide_empty=0");386 foreach ((array) $cats as $cat) {387 $categories .= " <category term=\"" . attribute_escape($cat->cat_name) . "\" />\n";388 }389 198 $categories = ""; 199 $cats = get_categories("hierarchical=0&hide_empty=0"); 200 foreach ((array) $cats as $cat) { 201 $categories .= " <category term=\"" . attribute_escape($cat->cat_name) . "\" />\n"; 202 } 203 $output = <<<EOD 390 204 <app:categories xmlns:app="http://purl.org/atom/app#" 391 205 xmlns="http://www.w3.org/2005/Atom" 392 206 fixed="yes" scheme="$home"> 393 207 $categories 394 208 </app:categories> 395 209 EOD; 396 $this->output($output, $this->CATEGORIES_CONTENT_TYPE);397 }398 210 211 $this->output($output, $this->CATEGORIES_CONTENT_TYPE); 212 } 213 399 214 /* 400 215 * Create Post (No arguments) 401 216 */ … … 408 223 $this->client_error(); 409 224 } 410 225 411 $entry = $parser->entry; 226 $entry = array_pop($parser->feed->entries); 227 228 log_app('Received entry:', print_r($entry,true)); 229 230 $catnames = array(); 231 foreach($entry->categories as $cat) 232 array_push($catnames, $cat["term"]); 233 234 $wp_cats = get_categories(array('hide_empty' => false)); 235 236 $post_categories = array(); 237 238 foreach($wp_cats as $cat) { 239 if(in_array($cat->cat_name, $catnames)) 240 array_push($post_categories, $cat->cat_ID); 241 } 412 242 413 243 $publish = (isset($entry->draft) && trim($entry->draft) == 'yes') ? false : true; 414 244 … … 420 250 $blog_ID = (int ) $blog_id; 421 251 $post_status = ($publish) ? 'publish' : 'draft'; 422 252 $post_author = (int) $user->ID; 423 $post_title = $entry->title; 424 $post_content = $entry->content; 425 $post_excerpt = $entry->summary; 426 $post_date = current_time('mysql'); 427 $post_date_gmt = current_time('mysql', 1); 253 $post_title = $entry->title[1]; 254 $post_content = $entry->content[1]; 255 $post_excerpt = $entry->summary[1]; 256 $pubtimes = $this->get_publish_time($entry); 257 $post_date = $pubtimes[0]; 258 $post_date_gmt = $pubtimes[1]; 259 260 if ( isset( $_SERVER['HTTP_SLUG'] ) ) 261 $post_name = $_SERVER['HTTP_SLUG']; 428 262 429 $post_data = compact('blog_ID', 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt' );263 $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 264 431 265 log_app('Inserting Post. Data:', print_r($post_data,true)); 432 266 … … 436 270 $this->internal_error('Sorry, your entry could not be posted. Something wrong happened.'); 437 271 } 438 272 273 // getting warning here about unable to set headers 274 // because something in the cache is printing to the buffer 275 // could we clean up wp_set_post_categories or cache to not print 276 // this could affect our ability to send back the right headers 277 @wp_set_post_categories($postID, $post_categories); 278 439 279 $output = $this->get_entry($postID); 440 280 441 281 log_app('function',"create_post($postID)"); … … 463 303 $this->bad_request(); 464 304 } 465 305 466 $parsed = $parser->entry;306 $parsed = array_pop($parser->feed->entries); 467 307 468 308 // check for not found 469 309 global $entry; … … 478 318 479 319 extract($entry); 480 320 481 $post_title = $parsed->title; 482 $post_content = $parsed->content; 483 $post_excerpt = $parsed->summary; 321 $post_title = $parsed->title[1]; 322 $post_content = $parsed->content[1]; 323 $post_excerpt = $parsed->summary[1]; 324 $pubtimes = $this->get_publish_time($entry); 325 $post_date = $pubtimes[0]; 326 $post_date_gmt = $pubtimes[1]; 484 327 485 328 // let's not go backwards and make something draft again. 486 329 if(!$publish && $post_status == 'draft') { 487 330 $post_status = ($publish) ? 'publish' : 'draft'; 331 } elseif($publish) { 332 $post_status = 'publish'; 488 333 } 489 334 490 $postdata = compact('ID', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt' );335 $postdata = compact('ID', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt', 'post_date', 'post_date_gmt'); 491 336 492 337 $result = wp_update_post($postdata); 493 338 … … 605 450 $this->bad_request(); 606 451 } 607 452 608 $parsed = $parser->entry;453 $parsed = array_pop($parser->feed->entries); 609 454 610 455 // check for not found 611 456 global $entry; … … 725 570 726 571 function get_entries_url($page = NULL) { 727 572 global $use_querystring; 573 if($GLOBALS['post_type'] == 'attachment') { 574 $path = $this->MEDIA_PATH; 575 } else { 576 $path = $this->ENTRIES_PATH; 577 } 728 578 $url = get_bloginfo('url') . '/' . $this->script_name; 729 579 if ($use_querystring) { 730 $url .= '?action=/' . $ this->ENTRIES_PATH;580 $url .= '?action=/' . $path; 731 581 if(isset($page) && is_int($page)) { 732 582 $url .= "&eid=$page"; 733 583 } 734 584 } else { 735 $url .= '/' . $ this->ENTRIES_PATH;585 $url .= '/' . $path; 736 586 if(isset($page) && is_int($page)) { 737 587 $url .= "/$page"; 738 588 } … … 759 609 function the_categories_url() { 760 610 $url = $this->get_categories_url(); 761 611 echo $url; 762 612 } 763 613 764 614 function get_attachments_url($page = NULL) { 765 615 global $use_querystring; … … 783 633 echo $url; 784 634 } 785 635 636 function get_service_url() { 637 global $use_querystring; 638 $url = get_bloginfo('url') . '/' . $this->script_name; 639 if ($use_querystring) { 640 $url .= '?action=/' . $this->SERVICE_PATH; 641 } else { 642 $url .= '/' . $this->SERVICE_PATH; 643 } 644 return $url; 645 } 786 646 787 647 function get_entry_url($postID = NULL) { 788 648 global $use_querystring; … … 845 705 return; 846 706 } 847 707 848 function get_posts_count() {849 global $wpdb;850 log_app('function',"get_posts_count()");851 return $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->posts WHERE post_date_gmt < '" . gmdate("Y-m-d H:i:s",time()) . "'");852 }853 854 855 708 function get_posts($page = 1, $post_type = 'post') { 856 709 log_app('function',"get_posts($page, '$post_type')"); 857 710 $feed = $this->get_feed($page, $post_type); … … 859 712 } 860 713 861 714 function get_attachments($page = 1, $post_type = 'attachment') { 862 log_app('function',"get_attachments($page, '$post_type')"); 863 $feed = $this->get_feed($page, $post_type); 864 $this->output($feed); 715 log_app('function',"get_attachments($page, '$post_type')"); 716 $GLOBALS['post_type'] = $post_type; 717 $feed = $this->get_feed($page, $post_type); 718 $this->output($feed); 865 719 } 866 720 867 721 function get_feed($page = 1, $post_type = 'post') { … … 875 729 $page = (int) $page; 876 730 877 731 $count = get_option('posts_per_rss'); 878 $query = "paged=$page&posts_per_page=$count&order=DESC"; 879 if($post_type == 'attachment') { 880 $query .= "&post_type=$post_type"; 881 } 882 query_posts($query); 732 733 wp('what_to_show=posts&posts_per_page=' . $count . '&offset=' . ($page-1)); 734 883 735 $post = $GLOBALS['post']; 884 736 $posts = $GLOBALS['posts']; 885 737 $wp = $GLOBALS['wp']; … … 887 739 $wpdb = $GLOBALS['wpdb']; 888 740 $blog_id = (int) $GLOBALS['blog_id']; 889 741 $post_cache = $GLOBALS['post_cache']; 742 log_app('function',"query_posts(# " . print_r($wp_query, true) . "#)"); 890 743 891 892 $total_count = $this->get_posts_count(); 893 $last_page = (int) ceil($total_count / $count); 744 log_app('function',"total_count(# $wp_query->max_num_pages #)"); 745 $last_page = $wp_query->max_num_pages; 894 746 $next_page = (($page + 1) > $last_page) ? NULL : $page + 1; 895 747 $prev_page = ($page - 1) < 1 ? NULL : $page - 1; 896 748 $last_page = ((int)$last_page == 1 || (int)$last_page == 0) ? NULL : (int) $last_page; … … 914 766 $post = $GLOBALS['post']; 915 767 ?> 916 768 <entry> 917 <id><?php the_guid($post->ID); ?></id> 918 <title type="html"><![CDATA[<?php the_title() ?>]]></title> 919 <updated><?php echo get_post_modified_time('Y-m-d\TH:i:s\Z', true); ?></updated> 920 <published><?php echo get_post_time('Y-m-d\TH:i:s\Z', true); ?></published> 921 <app:control> 922 <app:draft><?php echo ($GLOBALS['post']->post_status == 'draft' ? 'yes' : 'no') ?></app:draft> 923 </app:control> 924 <author> 925 <name><?php the_author()?></name> 926 <email><?php the_author_email()?></email> 927 <?php if (get_the_author_url() && get_the_author_url() != 'http://') { ?> 928 <uri><?php the_author_url()?></uri> 929 <?php } ?> 930 </author> 931 <?php if($GLOBALS['post']->post_status == 'attachment') { ?> 932 <link rel="edit" href="<?php $this->the_entry_url() ?>" /> 933 <link rel="edit-media" href="<?php $this->the_media_url() ?>" /> 934 <?php } else { ?> 935 <link href="<?php permalink_single_rss() ?>" /> 936 <link rel="edit" href="<?php $this->the_entry_url() ?>" /> 937 <?php } ?> 938 <?php foreach(get_the_category() as $category) { ?> 939 <category scheme="<?php bloginfo_rss('home') ?>" term="<?php echo $category->cat_name?>" /> 940 <?php } ?> <summary type="html"><![CDATA[<?php the_excerpt_rss(); ?>]]></summary> 941 <?php if ( strlen( $GLOBALS['post']->post_content ) ) : ?> 942 <content type="html"><![CDATA[<?php echo get_the_content('', 0, '') ?>]]></content> 769 <id><?php the_guid($post->ID); ?></id> 770 <title type="text"><![CDATA[<?php the_title() ?>]]></title> 771 <updated><?php echo get_post_modified_time('Y-m-d\TH:i:s\Z', true); ?></updated> 772 <published><?php echo get_post_time('Y-m-d\TH:i:s\Z', true); ?></published> 773 <app:edited><?php echo get_post_modified_time('Y-m-d\TH:i:s\Z', true); ?></app:edited> 774 <app:control> 775 <app:draft><?php echo ($GLOBALS['post']->post_status == 'draft' ? 'yes' : 'no') ?></app:draft> 776 </app:control> 777 <author> 778 <name><?php the_author()?></name> 779 <email><?php the_author_email()?></email> 780 <?php if (get_the_author_url() && get_the_author_url() != 'http://') { ?> 781 <uri><?php the_author_url()?></uri> 782 <?php } ?> 783 </author> 784 <?php if($GLOBALS['post']->post_status == 'attachment') { ?> 785 <link rel="edit" href="<?php $this->the_entry_url() ?>" /> 786 <link rel="edit-media" href="<?php $this->the_media_url() ?>" /> 787 <?php } else { ?> 788 <link href="<?php permalink_single_rss() ?>" /> 789 <?php if (current_user_can('edit_post', $post->ID)) { ?> 790 <link rel="edit" href="<?php $this->the_entry_url() ?>" /> 791 <?php }?> 792 <?php } ?> 793 <?php foreach(get_the_category() as $category) { ?> 794 <category scheme="<?php bloginfo_rss('home') ?>" term="<?php echo $category->cat_name?>" /> 795 <?php } ?> <summary type="html"><![CDATA[<?php the_excerpt_rss(); ?>]]></summary> 796 <?php if ( strlen( $GLOBALS['post']->post_content ) ) : ?> 797 <content type="html"><![CDATA[<?php echo get_the_content('', 0, '') ?>]]></content> 943 798 <?php endif; ?> 944 799 </entry> 945 800 <?php … … 970 825 ?> 971 826 <?php log_app('$post',print_r($GLOBALS['post'],true)); ?> 972 827 <entry xmlns="http://www.w3.org/2005/Atom" xmlns:app="http://purl.org/atom/app#" xml:lang="<?php echo get_option('rss_language'); ?>"> 973 974 <title type="html"><![CDATA[<?php the_title_rss() ?>]]></title>828 <id><?php the_guid($post->ID); ?></id> 829 <title type="text"><![CDATA[<?php the_title_rss() ?>]]></title> 975 830 976 <updated><?php echo get_post_modified_time('Y-m-d\TH:i:s\Z', true); ?></updated> 977 <published><?php echo get_post_time('Y-m-d\TH:i:s\Z', true); ?></published> 978 <app:control> 979 <app:draft><?php echo ($GLOBALS['post']->post_status == 'draft' ? 'yes' : 'no') ?></app:draft> 980 </app:control> 981 <author> 982 <name><?php the_author()?></name> 983 <email><?php the_author_email()?></email> 984 <uri><?php the_author_url()?></uri> 985 </author> 831 <updated><?php echo get_post_modified_time('Y-m-d\TH:i:s\Z', true); ?></updated> 832 <published><?php echo get_post_time('Y-m-d\TH:i:s\Z', true); ?></published> 833 <app:edited><?php echo get_post_modified_time('Y-m-d\TH:i:s\Z', true); ?></app:edited> 834 <app:control> 835 <app:draft><?php echo ($GLOBALS['post']->post_status == 'draft' ? 'yes' : 'no') ?></app:draft> 836 </app:control> 837 <author> 838 <name><?php the_author()?></name> 839 <email><?php the_author_email()?></email> 840 <uri><?php the_author_url()?></uri> 841 </author> 986 842 <?php if($GLOBALS['post']->post_type == 'attachment') { ?> 987 988 989 843 <link rel="edit" href="<?php $this->the_entry_url() ?>" /> 844 <link rel="edit-media" href="<?php $this->the_media_url() ?>" /> 845 <content type="<?php echo $GLOBALS['post']->post_mime_type ?>" src="<?php the_guid(); ?>"/> 990 846 <?php } else { ?> 991 992 847 <link href="<?php permalink_single_rss() ?>" /> 848 <link rel="edit" href="<?php $this->the_entry_url() ?>" /> 993 849 <?php } ?> 994 850 <?php foreach(get_the_category() as $category) { ?> 995 996 851 <category scheme="<?php bloginfo_rss('home') ?>" term="<?php echo $category->cat_name?>" /> 852 <summary type="html"><![CDATA[<?php the_excerpt_rss(); ?>]]></summary> 997 853 <?php } 998 999 854 if ( strlen( $GLOBALS['post']->post_content ) ) : ?> 855 <content type="html"><![CDATA[<?php echo get_the_content('', 0, '') ?>]]></content> 1000 856 <?php endif; ?> 1001 857 </entry> 1002 858 <?php … … 1071 927 exit; 1072 928 } 1073 929 930 function redirect($url) { 931 932 log_app('Status','302: Redirect'); 933 $escaped_url = attribute_escape($url); 934 $content = <<<EOD 935 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> 936 <html> 937 <head> 938 <title>302 Found</title> 939 </head> 940 <body> 941 <h1>Found</h1> 942 <p>The document has moved <a href="$escaped_url">here</a>.</p> 943 </body> 944 </html> 945 946 EOD; 947 header('HTTP/1.1 302 Moved'); 948 header('Content-Type: text/html'); 949 header('Location: ' . $url); 950 echo $content; 951 exit; 952 953 } 954 955 1074 956 function client_error($msg = 'Client Error') { 1075 log_app('Status','400: Client Err ir');957 log_app('Status','400: Client Error'); 1076 958 header('Content-Type: text/plain'); 1077 959 status_header('400'); 1078 960 exit; … … 1107 989 log_app('Status','401: Auth Required'); 1108 990 nocache_headers(); 1109 991 header('WWW-Authenticate: Basic realm="WordPress Atom Protocol"'); 1110 header('WWW-Authenticate: Form action="' . get_option('siteurl') . '/wp-login.php"', false);1111 992 header("HTTP/1.1 401 $msg"); 1112 993 header('Status: ' . $msg); 1113 header('Content-Type: plain/text'); 1114 echo $msg; 994 header('Content-Type: text/html'); 995 $content = <<<EOD 996 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> 997 <html> 998 <head> 999 <title>401 Unauthorized</title> 1000 </head> 1001 <body> 1002 <h1>401 Unauthorized</h1> 1003 <p>$msg</p> 1004 </body> 1005 </html> 1006 1007 EOD; 1008 echo $content; 1115 1009 exit; 1116 1010 } 1117 1011 … … 1251 1145 } 1252 1146 } 1253 1147 1148 1149 function rfc3339_str2time($str) { 1150 1151 $match = false; 1152 if(!preg_match("/(\d{4}-\d{2}-\d{2})T(\d{2}\:\d{2}\:\d{2})\.?\d{0,3}(Z|[+-]+\d{2}\:\d{2})/", $str, $match)) 1153 return false; 1154 1155 if($match[3] == 'Z') 1156 $match[3] == '+0000'; 1157 1158 return strtotime($match[1] . " " . $match[2] . " " . $match[3]); 1159 } 1254 1160 1161 function get_publish_time($entry) { 1162 1163 $pubtime = $this->rfc3339_str2time($entry->published); 1164 1165 if(!$pubtime) { 1166 return array(current_time('mysql'),current_time('mysql',1)); 1167 } else { 1168 return array(date("Y-m-d H:i:s", $pubtime), gmdate("Y-m-d H:i:s", $pubtime)); 1169 } 1170 } 1171 1255 1172 } 1256 1173 1257 1174 $server = new AtomServer();