From 3a4570b0fc8b3d6339bef71d17d7701554e0bbf7 Mon Sep 17 00:00:00 2001 From: donncha Date: Fri, 12 Oct 2007 16:21:15 +0000 Subject: Merge with WP 2.3 - testing use only! Move pluggable functions out of wpmu-functions and into pluggable.php, fixes #439 git-svn-id: http://svn.automattic.com/wordpress-mu/trunk@1069 7be80a69-a1ef-0310-a953-fb0f7c49ff36 --- wp-app.php | 799 ++++++++++++++++++++++++++----------------------------------- 1 file changed, 341 insertions(+), 458 deletions(-) (limited to 'wp-app.php') diff --git a/wp-app.php b/wp-app.php index aa1fff3..44846a7 100644 --- a/wp-app.php +++ b/wp-app.php @@ -1,5 +1,5 @@ entry = new AtomEntry(); - $this->map_attrs_func = create_function('$k,$v', 'return "$k=\"$v\"";'); - $this->map_xmlns_func = create_function('$p,$n', '$xd = "xmlns"; if(strlen($n[0])>0) $xd .= ":{$n[0]}"; return "{$xd}=\"{$n[1]}\"";'); - } - - function parse() { - - global $app_logging; - array_unshift($this->ns_contexts, array()); - - $parser = xml_parser_create_ns(); - xml_set_object($parser, $this); - xml_set_element_handler($parser, "start_element", "end_element"); - xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0); - xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,0); - xml_set_character_data_handler($parser, "cdata"); - xml_set_default_handler($parser, "_default"); - xml_set_start_namespace_decl_handler($parser, "start_ns"); - xml_set_end_namespace_decl_handler($parser, "end_ns"); - - $contents = ""; - - $fp = fopen("php://input", "r"); - while(!feof($fp)) { - $line = fgets($fp, 4096); - - if($app_logging) $contents .= $line; - - if(!xml_parse($parser, $line)) { - log_app("xml_parse_error", "line: $line"); - $this->error = sprintf(__('XML error: %s at line %d')."\n", - xml_error_string(xml_get_error_code($xml_parser)), - xml_get_current_line_number($xml_parser)); - log_app("xml_parse_error", $this->error); - return false; - } - } - fclose($fp); - - xml_parser_free($parser); - - log_app("AtomParser->parse()",trim($contents)); - - return true; - } - - function start_element($parser, $name, $attrs) { - - $tag = array_pop(split(":", $name)); - - array_unshift($this->ns_contexts, $this->ns_decls); - - $this->depth++; - - #print str_repeat(" ", $this->depth * $this->indent) . "start_element('$name')" ."\n"; - #print str_repeat(" ", $this->depth+1 * $this->indent) . print_r($this->ns_contexts,true) ."\n"; - - if(!empty($this->in_content)) { - $attrs_prefix = array(); - - // resolve prefixes for attributes - foreach($attrs as $key => $value) { - $attrs_prefix[$this->ns_to_prefix($key)] = $this->xml_escape($value); - } - $attrs_str = join(' ', array_map($this->map_attrs_func, array_keys($attrs_prefix), array_values($attrs_prefix))); - if(strlen($attrs_str) > 0) { - $attrs_str = " " . $attrs_str; - } - - $xmlns_str = join(' ', array_map($this->map_xmlns_func, array_keys($this->ns_contexts[0]), array_values($this->ns_contexts[0]))); - if(strlen($xmlns_str) > 0) { - $xmlns_str = " " . $xmlns_str; - } - - // handle self-closing tags (case: a new child found right-away, no text node) - if(count($this->in_content) == 2) { - array_push($this->in_content, ">"); - } - - array_push($this->in_content, "<". $this->ns_to_prefix($name) ."{$xmlns_str}{$attrs_str}"); - } else if(in_array($tag, $this->ATOM_CONTENT_ELEMENTS) || in_array($tag, $this->ATOM_SIMPLE_ELEMENTS)) { - $this->in_content = array(); - $this->is_xhtml = $attrs['type'] == 'xhtml'; - array_push($this->in_content, array($tag,$this->depth)); - } else if($tag == 'link') { - array_push($this->entry->links, $attrs); - } else if($tag == 'category') { - array_push($this->entry->categories, $attrs); - } - - $this->ns_decls = array(); - } - - function end_element($parser, $name) { - - $tag = array_pop(split(":", $name)); - - if(!empty($this->in_content)) { - if($this->in_content[0][0] == $tag && - $this->in_content[0][1] == $this->depth) { - array_shift($this->in_content); - if($this->is_xhtml) { - $this->in_content = array_slice($this->in_content, 2, count($this->in_content)-3); - } - $this->entry->$tag = join('',$this->in_content); - $this->in_content = array(); - } else { - $endtag = $this->ns_to_prefix($name); - if (strpos($this->in_content[count($this->in_content)-1], '<' . $endtag) !== false) { - array_push($this->in_content, "/>"); - } else { - array_push($this->in_content, ""); - } - } - } - - array_shift($this->ns_contexts); - - #print str_repeat(" ", $this->depth * $this->indent) . "end_element('$name')" ."\n"; - - $this->depth--; - } - - function start_ns($parser, $prefix, $uri) { - #print str_repeat(" ", $this->depth * $this->indent) . "starting: " . $prefix . ":" . $uri . "\n"; - array_push($this->ns_decls, array($prefix,$uri)); - } - - function end_ns($parser, $prefix) { - #print str_repeat(" ", $this->depth * $this->indent) . "ending: #" . $prefix . "#\n"; - } - - function cdata($parser, $data) { - #print str_repeat(" ", $this->depth * $this->indent) . "data: #" . $data . "#\n"; - if(!empty($this->in_content)) { - // handle self-closing tags (case: text node found, need to close element started) - if (strpos($this->in_content[count($this->in_content)-1], '<') !== false) { - array_push($this->in_content, ">"); - } - array_push($this->in_content, $this->xml_escape($data)); - } - } - - function _default($parser, $data) { - # when does this gets called? - } - - - function ns_to_prefix($qname) { - $components = split(":", $qname); - $name = array_pop($components); - - if(!empty($components)) { - $ns = join(":",$components); - foreach($this->ns_contexts as $context) { - foreach($context as $mapping) { - if($mapping[1] == $ns && strlen($mapping[0]) > 0) { - return "$mapping[0]:$name"; - } - } - } - } - return $name; - } - - function xml_escape($string) - { - return str_replace(array('&','"',"'",'<','>'), - array('&','"',''','<','>'), - $string ); - } } +add_filter('posts_where', 'wa_posts_where_include_drafts_filter'); class AtomServer { var $ATOM_CONTENT_TYPE = 'application/atom+xml'; var $CATEGORIES_CONTENT_TYPE = 'application/atomcat+xml'; - var $INTROSPECTION_CONTENT_TYPE = 'application/atomserv+xml'; + var $SERVICE_CONTENT_TYPE = 'application/atomsvc+xml'; + + var $ATOM_NS = 'http://www.w3.org/2005/Atom'; + var $ATOMPUB_NS = 'http://www.w3.org/2007/app'; var $ENTRIES_PATH = "posts"; var $CATEGORIES_PATH = "categories"; var $MEDIA_PATH = "attachments"; var $ENTRY_PATH = "post"; + var $SERVICE_PATH = "service"; var $MEDIA_SINGLE_PATH = "attachment"; var $params = array(); @@ -284,38 +81,40 @@ class AtomServer { $this->script_name = array_pop(explode('/',$_SERVER['SCRIPT_NAME'])); $this->selectors = array( - '@/service@' => + '@/service$@' => array('GET' => 'get_service'), - '@/categories@' => + '@/categories$@' => array('GET' => 'get_categories_xml'), - '@/post/(\d+)@' => - array('GET' => 'get_post', - 'PUT' => 'put_post', + '@/post/(\d+)$@' => + array('GET' => 'get_post', + 'PUT' => 'put_post', 'DELETE' => 'delete_post'), - '@/posts/?([^/]+)?@' => - array('GET' => 'get_posts', + '@/posts/?(\d+)?$@' => + array('GET' => 'get_posts', 'POST' => 'create_post'), - '@/attachments/?(\d+)?@' => - array('GET' => 'get_attachment', + '@/attachments/?(\d+)?$@' => + array('GET' => 'get_attachment', 'POST' => 'create_attachment'), - '@/attachment/file/(\d+)@' => - array('GET' => 'get_file', - 'PUT' => 'put_file', + '@/attachment/file/(\d+)$@' => + array('GET' => 'get_file', + 'PUT' => 'put_file', 'DELETE' => 'delete_file'), - '@/attachment/(\d+)@' => - array('GET' => 'get_attachment', - 'PUT' => 'put_attachment', + '@/attachment/(\d+)$@' => + array('GET' => 'get_attachment', + 'PUT' => 'put_attachment', 'DELETE' => 'delete_attachment'), ); } function handle_request() { + global $always_authenticate; $path = $_SERVER['PATH_INFO']; $method = $_SERVER['REQUEST_METHOD']; log_app('REQUEST',"$method $path\n================"); + $this->process_conditionals(); //$this->process_conditionals(); // exception case for HEAD (treat exactly as GET, but don't output) @@ -324,26 +123,33 @@ class AtomServer { $method = 'GET'; } - // lame. + // redirect to /service in case no path is found. if(strlen($path) == 0 || $path == '/') { - $path = '/service'; + $this->redirect($this->get_service_url()); } - // authenticate regardless of the operation and set the current - // user. each handler will decide if auth is required or not. - $this->authenticate(); - // dispatch foreach($this->selectors as $regex => $funcs) { if(preg_match($regex, $path, $matches)) { - if(isset($funcs[$method])) { - array_shift($matches); - call_user_func_array(array(&$this,$funcs[$method]), $matches); - exit(); - } else { - // only allow what we have handlers for... - $this->not_allowed(array_keys($funcs)); + if(isset($funcs[$method])) { + + // authenticate regardless of the operation and set the current + // user. each handler will decide if auth is required or not. + $this->authenticate(); + $u = wp_get_current_user(); + if(!isset($u) || $u->ID == 0) { + if ($always_authenticate) { + $this->auth_required('Credentials required.'); + } } + + array_shift($matches); + call_user_func_array(array(&$this,$funcs[$method]), $matches); + exit(); + } else { + // only allow what we have handlers for... + $this->not_allowed(array_keys($funcs)); + } } } @@ -353,54 +159,59 @@ class AtomServer { function get_service() { log_app('function','get_service()'); - $entries_url = $this->get_entries_url(); - $categories_url = $this->get_categories_url(); - $media_url = $this->get_attachments_url(); - $accepted_content_types = join(',',$this->media_content_types); - $introspection = << - - - WordPress Posts - entry - - - - WordPress Media - $accepted_content_types - - + $entries_url = attribute_escape($this->get_entries_url()); + $categories_url = attribute_escape($this->get_categories_url()); + $media_url = attribute_escape($this->get_attachments_url()); + foreach ($this->media_content_types as $med) { + $accepted_media_types = $accepted_media_types . "" . $med . ""; + } + $atom_prefix="atom"; + $service_doc = << + + <$atom_prefix:title>WordPress Workspace + + <$atom_prefix:title>WordPress Posts + $this->ATOM_CONTENT_TYPE;type=entry + + + + <$atom_prefix:title>WordPress Media + $accepted_media_types + + EOD; - $this->output($introspection, $this->INTROSPECTION_CONTENT_TYPE); + $this->output($service_doc, $this->SERVICE_CONTENT_TYPE); } -function get_categories_xml() { - log_app('function','get_categories_xml()'); - $home = get_bloginfo_rss('home'); + function get_categories_xml() { - $categories = ""; - $cats = get_categories("hierarchical=0&hide_empty=0"); - foreach ((array) $cats as $cat) { - $categories .= " cat_name) . "\" />\n"; - } - $output = <<name) . "\" />\n"; +} + $output = << $categories EOD; - $this->output($output, $this->CATEGORIES_CONTENT_TYPE); + $this->output($output, $this->CATEGORIES_CONTENT_TYPE); } /* * Create Post (No arguments) */ function create_post() { - global $blog_id; + global $blog_id, $wpdb; $this->get_accepted_content_type($this->atom_content_types); $parser = new AtomParser(); @@ -408,34 +219,62 @@ EOD; $this->client_error(); } - $entry = $parser->entry; + $entry = array_pop($parser->feed->entries); + + log_app('Received entry:', print_r($entry,true)); + + $catnames = array(); + foreach($entry->categories as $cat) + array_push($catnames, $cat["term"]); + + $wp_cats = get_categories(array('hide_empty' => false)); + + $post_category = array(); + + foreach($wp_cats as $cat) { + if(in_array($cat->name, $catnames)) + array_push($post_category, $cat->term_id); + } $publish = (isset($entry->draft) && trim($entry->draft) == 'yes') ? false : true; $cap = ($publish) ? 'publish_posts' : 'edit_posts'; if(!current_user_can($cap)) - $this->auth_required('Sorry, you do not have the right to edit/publish new posts.'); + $this->auth_required(__('Sorry, you do not have the right to edit/publish new posts.')); $blog_ID = (int ) $blog_id; $post_status = ($publish) ? 'publish' : 'draft'; $post_author = (int) $user->ID; - $post_title = $entry->title; - $post_content = $entry->content; - $post_excerpt = $entry->summary; - $post_date = current_time('mysql'); - $post_date_gmt = current_time('mysql', 1); + $post_title = $entry->title[1]; + $post_content = $entry->content[1]; + $post_excerpt = $entry->summary[1]; + $pubtimes = $this->get_publish_time($entry); + $post_date = $pubtimes[0]; + $post_date_gmt = $pubtimes[1]; - $post_data = compact('blog_ID', 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt'); + if ( isset( $_SERVER['HTTP_SLUG'] ) ) + $post_name = $_SERVER['HTTP_SLUG']; + + $post_data = compact('blog_ID', 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt', 'post_name'); + $this->escape($post_data); log_app('Inserting Post. Data:', print_r($post_data,true)); $postID = wp_insert_post($post_data); + if ( is_wp_error( $postID ) ) + $this->internal_error($postID->get_error_message()); if (!$postID) { - $this->internal_error('Sorry, your entry could not be posted. Something wrong happened.'); + $this->internal_error(__('Sorry, your entry could not be posted. Something wrong happened.')); } + // getting warning here about unable to set headers + // because something in the cache is printing to the buffer + // could we clean up wp_set_post_categories or cache to not print + // this could affect our ability to send back the right headers + @wp_set_post_categories($postID, $post_category); + $output = $this->get_entry($postID); log_app('function',"create_post($postID)"); @@ -453,6 +292,7 @@ EOD; } function put_post($postID) { + global $wpdb; // checked for valid content-types (atom+xml) // quick check and exit @@ -463,36 +303,43 @@ EOD; $this->bad_request(); } - $parsed = $parser->entry; + $parsed = array_pop($parser->feed->entries); + + log_app('Received UPDATED entry:', print_r($parsed,true)); // check for not found global $entry; $entry = $GLOBALS['entry']; $this->set_current_entry($postID); - $this->escape($GLOBALS['entry']); if(!current_user_can('edit_post', $entry['ID'])) - $this->auth_required('Sorry, you do not have the right to edit this post.'); + $this->auth_required(__('Sorry, you do not have the right to edit this post.')); $publish = (isset($parsed->draft) && trim($parsed->draft) == 'yes') ? false : true; extract($entry); - $post_title = $parsed->title; - $post_content = $parsed->content; - $post_excerpt = $parsed->summary; + $post_title = $parsed->title[1]; + $post_content = $parsed->content[1]; + $post_excerpt = $parsed->summary[1]; + $pubtimes = $this->get_publish_time($entry); + $post_date = $pubtimes[0]; + $post_date_gmt = $pubtimes[1]; // let's not go backwards and make something draft again. if(!$publish && $post_status == 'draft') { $post_status = ($publish) ? 'publish' : 'draft'; + } elseif($publish) { + $post_status = 'publish'; } - $postdata = compact('ID', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt'); + $postdata = compact('ID', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt', 'post_date', 'post_date_gmt'); + $this->escape($postdata); $result = wp_update_post($postdata); if (!$result) { - $this->internal_error('For some strange yet very annoying reason, this post could not be edited.'); + $this->internal_error(__('For some strange yet very annoying reason, this post could not be edited.')); } log_app('function',"put_post($postID)"); @@ -506,7 +353,7 @@ EOD; $this->set_current_entry($postID); if(!current_user_can('edit_post', $postID)) { - $this->auth_required('Sorry, you do not have the right to delete this post.'); + $this->auth_required(__('Sorry, you do not have the right to delete this post.')); } if ($entry['post_type'] == 'attachment') { @@ -515,7 +362,7 @@ EOD; $result = wp_delete_post($postID); if (!$result) { - $this->internal_error('For some strange yet very annoying reason, this post could not be deleted.'); + $this->internal_error(__('For some strange yet very annoying reason, this post could not be deleted.')); } log_app('function',"delete_post($postID)"); @@ -543,7 +390,7 @@ EOD; $type = $this->get_accepted_content_type(); if(!current_user_can('upload_files')) - $this->auth_required('You do not have permission to upload files.'); + $this->auth_required(__('You do not have permission to upload files.')); $fp = fopen("php://input", "rb"); $bits = NULL; @@ -595,6 +442,7 @@ EOD; } function put_attachment($postID) { + global $wpdb; // checked for valid content-types (atom+xml) // quick check and exit @@ -605,12 +453,11 @@ EOD; $this->bad_request(); } - $parsed = $parser->entry; + $parsed = array_pop($parser->feed->entries); // check for not found global $entry; $this->set_current_entry($postID); - $this->escape($entry); if(!current_user_can('edit_post', $entry['ID'])) $this->auth_required(__('Sorry, you do not have the right to edit this post.')); @@ -619,10 +466,11 @@ EOD; extract($entry); - $post_title = $parsed->title; - $post_content = $parsed->content; + $post_title = $parsed->title[1]; + $post_content = $parsed->content[1]; $postdata = compact('ID', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt'); + $this->escape($postdata); $result = wp_update_post($postdata); @@ -678,7 +526,9 @@ EOD; if(!isset($location) || 'attachment' != $entry['post_type'] || empty($filetype['ext'])) $this->internal_error(__('Error ocurred while accessing post metadata for file location.')); + status_header('200'); header('Content-Type: ' . $entry['post_mime_type']); + header('Connection: close'); $fp = fopen($location, "rb"); while(!feof($fp)) { @@ -687,7 +537,7 @@ EOD; fclose($fp); log_app('function',"get_file($postID)"); - $this->ok(); + exit; } function put_file($postID) { @@ -721,23 +571,31 @@ EOD; fclose($fp); fclose($localfp); + $ID = $entry['ID']; + $pubtimes = $this->get_publish_time($entry); + $post_date = $pubtimes[0]; + $post_date_gmt = $pubtimes[1]; + + $post_data = compact('ID', 'post_date', 'post_date_gmt'); + $result = wp_update_post($post_data); + + if (!$result) { + $this->internal_error(__('Sorry, your entry could not be posted. Something wrong happened.')); + } + log_app('function',"put_file($postID)"); $this->ok(); } function get_entries_url($page = NULL) { - global $use_querystring; - $url = get_bloginfo('url') . '/' . $this->script_name; - if ($use_querystring) { - $url .= '?action=/' . $this->ENTRIES_PATH; - if(isset($page) && is_int($page)) { - $url .= "&eid=$page"; - } + if($GLOBALS['post_type'] == 'attachment') { + $path = $this->MEDIA_PATH; } else { - $url .= '/' . $this->ENTRIES_PATH; - if(isset($page) && is_int($page)) { - $url .= "/$page"; - } + $path = $this->ENTRIES_PATH; + } + $url = get_bloginfo('url') . '/' . $this->script_name . '/' . $path; + if(isset($page) && is_int($page)) { + $url .= "/$page"; } return $url; } @@ -748,34 +606,18 @@ EOD; } function get_categories_url($page = NULL) { - global $use_querystring; - $url = get_bloginfo('url') . '/' . $this->script_name; - if ($use_querystring) { - $url .= '?action=/' . $this->CATEGORIES_PATH; - } else { - $url .= '/' . $this->CATEGORIES_PATH; - } - return $url; + return get_bloginfo('url') . '/' . $this->script_name . '/' . $this->CATEGORIES_PATH; } function the_categories_url() { $url = $this->get_categories_url(); echo $url; - } + } function get_attachments_url($page = NULL) { - global $use_querystring; - $url = get_bloginfo('url') . '/' . $this->script_name; - if ($use_querystring) { - $url .= '?action=/' . $this->MEDIA_PATH; - if(isset($page) && is_int($page)) { - $url .= "&eid=$page"; - } - } else { - $url .= '/' . $this->MEDIA_PATH; - if(isset($page) && is_int($page)) { - $url .= "/$page"; - } + $url = get_bloginfo('url') . '/' . $this->script_name . '/' . $this->MEDIA_PATH; + if(isset($page) && is_int($page)) { + $url .= "/$page"; } return $url; } @@ -785,19 +627,17 @@ EOD; echo $url; } + function get_service_url() { + return get_bloginfo('url') . '/' . $this->script_name . '/' . $this->SERVICE_PATH; + } function get_entry_url($postID = NULL) { - global $use_querystring; if(!isset($postID)) { global $post; $postID = (int) $GLOBALS['post']->ID; } - if ($use_querystring) { - $url = get_bloginfo('url') . '/' . $this->script_name . '?action=/' . $this->ENTRY_PATH . "&eid=$postID"; - } else { - $url = get_bloginfo('url') . '/' . $this->script_name . '/' . $this->ENTRY_PATH . "/$postID"; - } + $url = get_bloginfo('url') . '/' . $this->script_name . '/' . $this->ENTRY_PATH . "/$postID"; log_app('function',"get_entry_url() = $url"); return $url; @@ -809,17 +649,12 @@ EOD; } function get_media_url($postID = NULL) { - global $use_querystring; if(!isset($postID)) { global $post; $postID = (int) $GLOBALS['post']->ID; } - if ($use_querystring) { - $url = get_bloginfo('url') . '/' . $this->script_name . '?action=/' . $this->MEDIA_SINGLE_PATH ."&eid=$postID"; - } else { - $url = get_bloginfo('url') . '/' . $this->script_name . '/' . $this->MEDIA_SINGLE_PATH ."/$postID"; - } + $url = get_bloginfo('url') . '/' . $this->script_name . '/' . $this->MEDIA_SINGLE_PATH ."/file/$postID"; log_app('function',"get_media_url() = $url"); return $url; @@ -847,13 +682,6 @@ EOD; return; } - function get_posts_count() { - global $wpdb; - log_app('function',"get_posts_count()"); - return $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->posts WHERE post_date_gmt < '" . gmdate("Y-m-d H:i:s",time()) . "'"); - } - - function get_posts($page = 1, $post_type = 'post') { log_app('function',"get_posts($page, '$post_type')"); $feed = $this->get_feed($page, $post_type); @@ -861,9 +689,10 @@ EOD; } function get_attachments($page = 1, $post_type = 'attachment') { - log_app('function',"get_attachments($page, '$post_type')"); - $feed = $this->get_feed($page, $post_type); - $this->output($feed); + log_app('function',"get_attachments($page, '$post_type')"); + $GLOBALS['post_type'] = $post_type; + $feed = $this->get_feed($page, $post_type); + $this->output($feed); } function get_feed($page = 1, $post_type = 'post') { @@ -877,11 +706,9 @@ EOD; $page = (int) $page; $count = get_option('posts_per_rss'); - $query = "paged=$page&posts_per_page=$count&order=DESC"; - if($post_type == 'attachment') { - $query .= "&post_type=$post_type"; - } - query_posts($query); + + wp('what_to_show=posts&posts_per_page=' . $count . '&offset=' . ($count * ($page-1) )); + $post = $GLOBALS['post']; $posts = $GLOBALS['posts']; $wp = $GLOBALS['wp']; @@ -889,66 +716,38 @@ EOD; $wpdb = $GLOBALS['wpdb']; $blog_id = (int) $GLOBALS['blog_id']; $post_cache = $GLOBALS['post_cache']; + log_app('function',"query_posts(# " . print_r($wp_query, true) . "#)"); - - $total_count = $this->get_posts_count(); - $last_page = (int) ceil($total_count / $count); + log_app('function',"total_count(# $wp_query->max_num_pages #)"); + $last_page = $wp_query->max_num_pages; $next_page = (($page + 1) > $last_page) ? NULL : $page + 1; - $prev_page = ($page - 1) < 1 ? NULL : $page - 1; + $prev_page = ($page - 1) < 1 ? NULL : $page - 1; $last_page = ((int)$last_page == 1 || (int)$last_page == 0) ? NULL : (int) $last_page; -?> + $self_page = $page > 1 ? $page : NULL; +?> the_entries_url() ?> <?php bloginfo_rss('name') ?> - + - + - + - - + + Copyright WordPress.com Atom API - - - ID); ?> - <![CDATA[<?php the_title() ?>]]> - - - - post_status == 'draft' ? 'yes' : 'no') ?> - - - - - - - - - post_status == 'attachment') { ?> - - - - - - - - - ]]> - post_content ) ) : ?> - ]]> - - -echo_entry(); + } + } ?> - - - - ID); ?> - <![CDATA[<?php the_title_rss() ?>]]> + if ( have_posts() ) { + while ( have_posts() ) { + the_post(); + $this->echo_entry(); + log_app('$post',print_r($GLOBALS['post'],true)); + $entry = ob_get_contents(); + break; + } + } + ob_end_clean(); + + log_app('get_entry returning:',$entry); + return $entry; + } + function echo_entry() { ?> + + ID); ?> +prep_content(get_the_title()); ?> + <?php echo $content ?> + post_status == 'draft' ? 'yes' : 'no') ?> + + post_type == 'attachment') { ?> - - - + +post_content ) ) : +list($content_type, $content) = $this->prep_content(get_the_content()); ?> + + + - - ]]> -post_content ) ) : ?> - ]]> - + + +prep_content(get_the_excerpt()); ?> + -auth_required(__("Access Denied.")); - endif; - ob_end_clean(); +' . $data . '', true); + $code = xml_get_error_code($parser); + xml_parser_free($parser); + + if (!$code) { + if (strpos($data, '<') === false) { + return array('text', $data); + } else { + $data = "
$data
"; + return array('xhtml', $data); + } + } + + if (strpos($data, ']]>') == false) { + return array('html', ""); + } else { + return array('html', htmlspecialchars($data)); + } } - function ok() { + function ok() { log_app('Status','200: OK'); header('Content-Type: text/plain'); status_header('200'); exit; } - function no_content() { + function no_content() { log_app('Status','204: No Content'); header('Content-Type: text/plain'); status_header('204'); @@ -1073,15 +904,40 @@ $post = $GLOBALS['post']; exit; } + function redirect($url) { + + log_app('Status','302: Redirect'); + $escaped_url = attribute_escape($url); + $content = << + + + 302 Found + + +

Found

+

The document has moved here.

+ + + +EOD; + header('HTTP/1.1 302 Moved'); + header('Content-Type: text/html'); + header('Location: ' . $url); + echo $content; + exit; + + } + + function client_error($msg = 'Client Error') { - log_app('Status','400: Client Errir'); + log_app('Status','400: Client Error'); header('Content-Type: text/plain'); status_header('400'); exit; } function created($post_ID, $content, $post_type = 'post') { - global $use_querystring; log_app('created()::$post_ID',"$post_ID, $post_type"); $edit = $this->get_entry_url($post_ID); switch($post_type) { @@ -1089,14 +945,10 @@ $post = $GLOBALS['post']; $ctloc = $this->get_entry_url($post_ID); break; case 'attachment': - if ($use_querystring) { - $edit = get_bloginfo('url') . '/' . $this->script_name . "?action=/attachments&eid=$post_ID"; - } else { - $edit = get_bloginfo('url') . '/' . $this->script_name . "/attachments/$post_ID"; - } + $edit = get_bloginfo('url') . '/' . $this->script_name . "/attachments/$post_ID"; break; } - header('Content-Type: application/atom+xml'); + header("Content-Type: $this->ATOM_CONTENT_TYPE"); if(isset($ctloc)) header('Content-Location: ' . $ctloc); header('Location: ' . $edit); @@ -1109,15 +961,27 @@ $post = $GLOBALS['post']; log_app('Status','401: Auth Required'); nocache_headers(); header('WWW-Authenticate: Basic realm="WordPress Atom Protocol"'); - header('WWW-Authenticate: Form action="' . get_option('siteurl') . '/wp-login.php"', false); header("HTTP/1.1 401 $msg"); header('Status: ' . $msg); - header('Content-Type: plain/text'); - echo $msg; + header('Content-Type: text/html'); + $content = << + + + 401 Unauthorized + + +

401 Unauthorized

+

$msg

+ + + +EOD; + echo $content; exit; } - function output($xml, $ctype = "application/atom+xml") { + function output($xml, $ctype = 'application/atom+xml') { status_header('200'); $xml = ''."\n".$xml; header('Connection: close'); @@ -1145,8 +1009,6 @@ $post = $GLOBALS['post']; } } - - /* * Access credential through various methods and perform login */ @@ -1159,13 +1021,14 @@ $post = $GLOBALS['post']; // if using mod_rewrite/ENV hack // http://www.besthostratings.com/articles/http-auth-php-cgi.html if(isset($_SERVER['HTTP_AUTHORIZATION'])) { - list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = + list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6))); } // If Basic Auth is working... if(isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) { $login_data = array('login' => $_SERVER['PHP_AUTH_USER'], 'password' => $_SERVER['PHP_AUTH_PW']); + log_app("Basic Auth",$login_data['login']); } else { // else, do cookie-based authentication if (function_exists('wp_get_cookie_login')) { @@ -1198,18 +1061,16 @@ $post = $GLOBALS['post']; log_app("get_accepted_content_type", "type=$type, subtype=$subtype"); foreach($types as $t) { - list($acceptedType,$acceptedSubtype) = explode('/',$t); + list($acceptedType,$acceptedSubtype) = explode('/',$t); if($acceptedType == '*' || $acceptedType == $type) { if($acceptedSubtype == '*' || $acceptedSubtype == $subtype) - return $type; + return $type . "/" . $subtype; } } $this->invalid_media(); } - - function process_conditionals() { if(empty($this->params)) return; @@ -1233,9 +1094,9 @@ $post = $GLOBALS['post']; @header("ETag: $wp_etag"); // Support for Conditional GET - if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) + if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) $client_etag = stripslashes($_SERVER['HTTP_IF_NONE_MATCH']); - else + else $client_etag = false; $client_last_modified = trim( $_SERVER['HTTP_IF_MODIFIED_SINCE']); @@ -1253,6 +1114,28 @@ $post = $GLOBALS['post']; } } + function rfc3339_str2time($str) { + + $match = false; + 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)) + return false; + + if($match[3] == 'Z') + $match[3] == '+0000'; + + return strtotime($match[1] . " " . $match[2] . " " . $match[3]); + } + + function get_publish_time($entry) { + + $pubtime = $this->rfc3339_str2time($entry->published); + + if(!$pubtime) { + return array(current_time('mysql'),current_time('mysql',1)); + } else { + return array(date("Y-m-d H:i:s", $pubtime), gmdate("Y-m-d H:i:s", $pubtime)); + } + } } -- cgit