[44] | 1 | <?php
|
---|
| 2 | /**
|
---|
| 3 | * Atom Publishing Protocol support for WordPress
|
---|
| 4 | *
|
---|
| 5 | * @author Original by Elias Torres <http://torrez.us/archives/2006/08/31/491/>
|
---|
| 6 | * @author Modified by Dougal Campbell <http://dougal.gunters.org/>
|
---|
| 7 | * @version 1.0.5-dc
|
---|
| 8 | */
|
---|
| 9 |
|
---|
| 10 | /**
|
---|
| 11 | * WordPress is handling an Atom Publishing Protocol request.
|
---|
| 12 | *
|
---|
| 13 | * @var bool
|
---|
| 14 | */
|
---|
| 15 | define('APP_REQUEST', true);
|
---|
| 16 |
|
---|
| 17 | /** Set up WordPress environment */
|
---|
| 18 | require_once('./wp-load.php');
|
---|
| 19 |
|
---|
| 20 | /** Post Template API */
|
---|
| 21 | require_once(ABSPATH . WPINC . '/post-template.php');
|
---|
| 22 |
|
---|
| 23 | /** Atom Publishing Protocol Class */
|
---|
| 24 | require_once(ABSPATH . WPINC . '/atomlib.php');
|
---|
| 25 |
|
---|
| 26 | /** Feed Handling API */
|
---|
| 27 | require_once(ABSPATH . WPINC . '/feed.php');
|
---|
| 28 |
|
---|
| 29 | /** Admin Image API for metadata updating */
|
---|
| 30 | require_once(ABSPATH . '/wp-admin/includes/image.php');
|
---|
| 31 |
|
---|
| 32 | $_SERVER['PATH_INFO'] = preg_replace( '/.*\/wp-app\.php/', '', $_SERVER['REQUEST_URI'] );
|
---|
| 33 |
|
---|
| 34 | /**
|
---|
| 35 | * Whether to enable Atom Publishing Protocol Logging.
|
---|
| 36 | *
|
---|
| 37 | * @name app_logging
|
---|
| 38 | * @var int|bool
|
---|
| 39 | */
|
---|
| 40 | $app_logging = 0;
|
---|
| 41 |
|
---|
| 42 | /**
|
---|
| 43 | * Whether to always authenticate user. Permanently set to true.
|
---|
| 44 | *
|
---|
| 45 | * @name always_authenticate
|
---|
| 46 | * @var int|bool
|
---|
| 47 | * @todo Should be an option somewhere
|
---|
| 48 | */
|
---|
| 49 | $always_authenticate = 1;
|
---|
| 50 |
|
---|
| 51 | /**
|
---|
| 52 | * Writes logging info to a file.
|
---|
| 53 | *
|
---|
| 54 | * @since 2.2.0
|
---|
| 55 | * @uses $app_logging
|
---|
| 56 | * @package WordPress
|
---|
| 57 | * @subpackage Logging
|
---|
| 58 | *
|
---|
| 59 | * @param string $label Type of logging
|
---|
| 60 | * @param string $msg Information describing logging reason.
|
---|
| 61 | */
|
---|
| 62 | function log_app($label,$msg) {
|
---|
| 63 | global $app_logging;
|
---|
| 64 | if ($app_logging) {
|
---|
| 65 | $fp = fopen( 'wp-app.log', 'a+');
|
---|
| 66 | $date = gmdate( 'Y-m-d H:i:s' );
|
---|
| 67 | fwrite($fp, "\n\n$date - $label\n$msg\n");
|
---|
| 68 | fclose($fp);
|
---|
| 69 | }
|
---|
| 70 | }
|
---|
| 71 |
|
---|
| 72 | if ( !function_exists('wp_set_current_user') ) :
|
---|
| 73 | /**
|
---|
| 74 | * @ignore
|
---|
| 75 | */
|
---|
| 76 | function wp_set_current_user($id, $name = '') {
|
---|
| 77 | global $current_user;
|
---|
| 78 |
|
---|
| 79 | if ( isset($current_user) && ($id == $current_user->ID) )
|
---|
| 80 | return $current_user;
|
---|
| 81 |
|
---|
| 82 | $current_user = new WP_User($id, $name);
|
---|
| 83 |
|
---|
| 84 | return $current_user;
|
---|
| 85 | }
|
---|
| 86 | endif;
|
---|
| 87 |
|
---|
| 88 | /**
|
---|
| 89 | * Filter to add more post statuses.
|
---|
| 90 | *
|
---|
| 91 | * @since 2.2.0
|
---|
| 92 | *
|
---|
| 93 | * @param string $where SQL statement to filter.
|
---|
| 94 | * @return string Filtered SQL statement with added post_status for where clause.
|
---|
| 95 | */
|
---|
| 96 | function wa_posts_where_include_drafts_filter($where) {
|
---|
| 97 | $where = str_replace("post_status = 'publish'","post_status = 'publish' OR post_status = 'future' OR post_status = 'draft' OR post_status = 'inherit'", $where);
|
---|
| 98 | return $where;
|
---|
| 99 |
|
---|
| 100 | }
|
---|
| 101 | add_filter('posts_where', 'wa_posts_where_include_drafts_filter');
|
---|
| 102 |
|
---|
| 103 | /**
|
---|
| 104 | * WordPress AtomPub API implementation.
|
---|
| 105 | *
|
---|
| 106 | * @package WordPress
|
---|
| 107 | * @subpackage Publishing
|
---|
| 108 | * @since 2.2.0
|
---|
| 109 | */
|
---|
| 110 | class AtomServer {
|
---|
| 111 |
|
---|
| 112 | /**
|
---|
| 113 | * ATOM content type.
|
---|
| 114 | *
|
---|
| 115 | * @since 2.2.0
|
---|
| 116 | * @var string
|
---|
| 117 | */
|
---|
| 118 | var $ATOM_CONTENT_TYPE = 'application/atom+xml';
|
---|
| 119 |
|
---|
| 120 | /**
|
---|
| 121 | * Categories ATOM content type.
|
---|
| 122 | *
|
---|
| 123 | * @since 2.2.0
|
---|
| 124 | * @var string
|
---|
| 125 | */
|
---|
| 126 | var $CATEGORIES_CONTENT_TYPE = 'application/atomcat+xml';
|
---|
| 127 |
|
---|
| 128 | /**
|
---|
| 129 | * Service ATOM content type.
|
---|
| 130 | *
|
---|
| 131 | * @since 2.3.0
|
---|
| 132 | * @var string
|
---|
| 133 | */
|
---|
| 134 | var $SERVICE_CONTENT_TYPE = 'application/atomsvc+xml';
|
---|
| 135 |
|
---|
| 136 | /**
|
---|
| 137 | * ATOM XML namespace.
|
---|
| 138 | *
|
---|
| 139 | * @since 2.3.0
|
---|
| 140 | * @var string
|
---|
| 141 | */
|
---|
| 142 | var $ATOM_NS = 'http://www.w3.org/2005/Atom';
|
---|
| 143 |
|
---|
| 144 | /**
|
---|
| 145 | * ATOMPUB XML namespace.
|
---|
| 146 | *
|
---|
| 147 | * @since 2.3.0
|
---|
| 148 | * @var string
|
---|
| 149 | */
|
---|
| 150 | var $ATOMPUB_NS = 'http://www.w3.org/2007/app';
|
---|
| 151 |
|
---|
| 152 | /**
|
---|
| 153 | * Entries path.
|
---|
| 154 | *
|
---|
| 155 | * @since 2.2.0
|
---|
| 156 | * @var string
|
---|
| 157 | */
|
---|
| 158 | var $ENTRIES_PATH = "posts";
|
---|
| 159 |
|
---|
| 160 | /**
|
---|
| 161 | * Categories path.
|
---|
| 162 | *
|
---|
| 163 | * @since 2.2.0
|
---|
| 164 | * @var string
|
---|
| 165 | */
|
---|
| 166 | var $CATEGORIES_PATH = "categories";
|
---|
| 167 |
|
---|
| 168 | /**
|
---|
| 169 | * Media path.
|
---|
| 170 | *
|
---|
| 171 | * @since 2.2.0
|
---|
| 172 | * @var string
|
---|
| 173 | */
|
---|
| 174 | var $MEDIA_PATH = "attachments";
|
---|
| 175 |
|
---|
| 176 | /**
|
---|
| 177 | * Entry path.
|
---|
| 178 | *
|
---|
| 179 | * @since 2.2.0
|
---|
| 180 | * @var string
|
---|
| 181 | */
|
---|
| 182 | var $ENTRY_PATH = "post";
|
---|
| 183 |
|
---|
| 184 | /**
|
---|
| 185 | * Service path.
|
---|
| 186 | *
|
---|
| 187 | * @since 2.2.0
|
---|
| 188 | * @var string
|
---|
| 189 | */
|
---|
| 190 | var $SERVICE_PATH = "service";
|
---|
| 191 |
|
---|
| 192 | /**
|
---|
| 193 | * Media single path.
|
---|
| 194 | *
|
---|
| 195 | * @since 2.2.0
|
---|
| 196 | * @var string
|
---|
| 197 | */
|
---|
| 198 | var $MEDIA_SINGLE_PATH = "attachment";
|
---|
| 199 |
|
---|
| 200 | /**
|
---|
| 201 | * ATOMPUB parameters.
|
---|
| 202 | *
|
---|
| 203 | * @since 2.2.0
|
---|
| 204 | * @var array
|
---|
| 205 | */
|
---|
| 206 | var $params = array();
|
---|
| 207 |
|
---|
| 208 | /**
|
---|
| 209 | * Supported ATOMPUB media types.
|
---|
| 210 | *
|
---|
| 211 | * @since 2.3.0
|
---|
| 212 | * @var array
|
---|
| 213 | */
|
---|
| 214 | var $media_content_types = array('image/*','audio/*','video/*');
|
---|
| 215 |
|
---|
| 216 | /**
|
---|
| 217 | * ATOMPUB content type(s).
|
---|
| 218 | *
|
---|
| 219 | * @since 2.2.0
|
---|
| 220 | * @var array
|
---|
| 221 | */
|
---|
| 222 | var $atom_content_types = array('application/atom+xml');
|
---|
| 223 |
|
---|
| 224 | /**
|
---|
| 225 | * ATOMPUB methods.
|
---|
| 226 | *
|
---|
| 227 | * @since 2.2.0
|
---|
| 228 | * @var unknown_type
|
---|
| 229 | */
|
---|
| 230 | var $selectors = array();
|
---|
| 231 |
|
---|
| 232 | /**
|
---|
| 233 | * Whether to do output.
|
---|
| 234 | *
|
---|
| 235 | * Support for head.
|
---|
| 236 | *
|
---|
| 237 | * @since 2.2.0
|
---|
| 238 | * @var bool
|
---|
| 239 | */
|
---|
| 240 | var $do_output = true;
|
---|
| 241 |
|
---|
| 242 | /**
|
---|
| 243 | * PHP4 constructor - Sets up object properties.
|
---|
| 244 | *
|
---|
| 245 | * @since 2.2.0
|
---|
| 246 | * @return AtomServer
|
---|
| 247 | */
|
---|
| 248 | function AtomServer() {
|
---|
| 249 |
|
---|
| 250 | $this->script_name = array_pop(explode('/',$_SERVER['SCRIPT_NAME']));
|
---|
| 251 | $this->app_base = get_bloginfo('url') . '/' . $this->script_name . '/';
|
---|
| 252 | if ( isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on' ) {
|
---|
| 253 | $this->app_base = preg_replace( '/^http:\/\//', 'https://', $this->app_base );
|
---|
| 254 | }
|
---|
| 255 |
|
---|
| 256 | $this->selectors = array(
|
---|
| 257 | '@/service$@' =>
|
---|
| 258 | array('GET' => 'get_service'),
|
---|
| 259 | '@/categories$@' =>
|
---|
| 260 | array('GET' => 'get_categories_xml'),
|
---|
| 261 | '@/post/(\d+)$@' =>
|
---|
| 262 | array('GET' => 'get_post',
|
---|
| 263 | 'PUT' => 'put_post',
|
---|
| 264 | 'DELETE' => 'delete_post'),
|
---|
| 265 | '@/posts/?(\d+)?$@' =>
|
---|
| 266 | array('GET' => 'get_posts',
|
---|
| 267 | 'POST' => 'create_post'),
|
---|
| 268 | '@/attachments/?(\d+)?$@' =>
|
---|
| 269 | array('GET' => 'get_attachment',
|
---|
| 270 | 'POST' => 'create_attachment'),
|
---|
| 271 | '@/attachment/file/(\d+)$@' =>
|
---|
| 272 | array('GET' => 'get_file',
|
---|
| 273 | 'PUT' => 'put_file',
|
---|
| 274 | 'DELETE' => 'delete_file'),
|
---|
| 275 | '@/attachment/(\d+)$@' =>
|
---|
| 276 | array('GET' => 'get_attachment',
|
---|
| 277 | 'PUT' => 'put_attachment',
|
---|
| 278 | 'DELETE' => 'delete_attachment'),
|
---|
| 279 | );
|
---|
| 280 | }
|
---|
| 281 |
|
---|
| 282 | /**
|
---|
| 283 | * Handle ATOMPUB request.
|
---|
| 284 | *
|
---|
| 285 | * @since 2.2.0
|
---|
| 286 | */
|
---|
| 287 | function handle_request() {
|
---|
| 288 | global $always_authenticate;
|
---|
| 289 |
|
---|
| 290 | if( !empty( $_SERVER['ORIG_PATH_INFO'] ) )
|
---|
| 291 | $path = $_SERVER['ORIG_PATH_INFO'];
|
---|
| 292 | else
|
---|
| 293 | $path = $_SERVER['PATH_INFO'];
|
---|
| 294 |
|
---|
| 295 | $method = $_SERVER['REQUEST_METHOD'];
|
---|
| 296 |
|
---|
| 297 | log_app('REQUEST',"$method $path\n================");
|
---|
| 298 |
|
---|
| 299 | $this->process_conditionals();
|
---|
| 300 | //$this->process_conditionals();
|
---|
| 301 |
|
---|
| 302 | // exception case for HEAD (treat exactly as GET, but don't output)
|
---|
| 303 | if($method == 'HEAD') {
|
---|
| 304 | $this->do_output = false;
|
---|
| 305 | $method = 'GET';
|
---|
| 306 | }
|
---|
| 307 |
|
---|
| 308 | // redirect to /service in case no path is found.
|
---|
| 309 | if(strlen($path) == 0 || $path == '/') {
|
---|
| 310 | $this->redirect($this->get_service_url());
|
---|
| 311 | }
|
---|
| 312 |
|
---|
| 313 | // check to see if AtomPub is enabled
|
---|
| 314 | if( !get_option( 'enable_app' ) )
|
---|
| 315 | $this->forbidden( sprintf( __( 'AtomPub services are disabled on this blog. An admin user can enable them at %s' ), admin_url('options-writing.php') ) );
|
---|
| 316 |
|
---|
| 317 | // dispatch
|
---|
| 318 | foreach($this->selectors as $regex => $funcs) {
|
---|
| 319 | if(preg_match($regex, $path, $matches)) {
|
---|
| 320 | if(isset($funcs[$method])) {
|
---|
| 321 |
|
---|
| 322 | // authenticate regardless of the operation and set the current
|
---|
| 323 | // user. each handler will decide if auth is required or not.
|
---|
| 324 | if(!$this->authenticate()) {
|
---|
| 325 | if ($always_authenticate) {
|
---|
| 326 | $this->auth_required('Credentials required.');
|
---|
| 327 | }
|
---|
| 328 | }
|
---|
| 329 |
|
---|
| 330 | array_shift($matches);
|
---|
| 331 | call_user_func_array(array(&$this,$funcs[$method]), $matches);
|
---|
| 332 | exit();
|
---|
| 333 | } else {
|
---|
| 334 | // only allow what we have handlers for...
|
---|
| 335 | $this->not_allowed(array_keys($funcs));
|
---|
| 336 | }
|
---|
| 337 | }
|
---|
| 338 | }
|
---|
| 339 |
|
---|
| 340 | // oops, nothing found
|
---|
| 341 | $this->not_found();
|
---|
| 342 | }
|
---|
| 343 |
|
---|
| 344 | /**
|
---|
| 345 | * Retrieve XML for ATOMPUB service.
|
---|
| 346 | *
|
---|
| 347 | * @since 2.2.0
|
---|
| 348 | */
|
---|
| 349 | function get_service() {
|
---|
| 350 | log_app('function','get_service()');
|
---|
| 351 |
|
---|
| 352 | if( !current_user_can( 'edit_posts' ) )
|
---|
| 353 | $this->auth_required( __( 'Sorry, you do not have the right to access this blog.' ) );
|
---|
| 354 |
|
---|
| 355 | $entries_url = esc_attr($this->get_entries_url());
|
---|
| 356 | $categories_url = esc_attr($this->get_categories_url());
|
---|
| 357 | $media_url = esc_attr($this->get_attachments_url());
|
---|
| 358 | foreach ($this->media_content_types as $med) {
|
---|
| 359 | $accepted_media_types = $accepted_media_types . "<accept>" . $med . "</accept>";
|
---|
| 360 | }
|
---|
| 361 | $atom_prefix="atom";
|
---|
| 362 | $atom_blogname=get_bloginfo('name');
|
---|
| 363 | $service_doc = <<<EOD
|
---|
| 364 | <service xmlns="$this->ATOMPUB_NS" xmlns:$atom_prefix="$this->ATOM_NS">
|
---|
| 365 | <workspace>
|
---|
| 366 | <$atom_prefix:title>$atom_blogname Workspace</$atom_prefix:title>
|
---|
| 367 | <collection href="$entries_url">
|
---|
| 368 | <$atom_prefix:title>$atom_blogname Posts</$atom_prefix:title>
|
---|
| 369 | <accept>$this->ATOM_CONTENT_TYPE;type=entry</accept>
|
---|
| 370 | <categories href="$categories_url" />
|
---|
| 371 | </collection>
|
---|
| 372 | <collection href="$media_url">
|
---|
| 373 | <$atom_prefix:title>$atom_blogname Media</$atom_prefix:title>
|
---|
| 374 | $accepted_media_types
|
---|
| 375 | </collection>
|
---|
| 376 | </workspace>
|
---|
| 377 | </service>
|
---|
| 378 |
|
---|
| 379 | EOD;
|
---|
| 380 |
|
---|
| 381 | $this->output($service_doc, $this->SERVICE_CONTENT_TYPE);
|
---|
| 382 | }
|
---|
| 383 |
|
---|
| 384 | /**
|
---|
| 385 | * Retrieve categories list in XML format.
|
---|
| 386 | *
|
---|
| 387 | * @since 2.2.0
|
---|
| 388 | */
|
---|
| 389 | function get_categories_xml() {
|
---|
| 390 | log_app('function','get_categories_xml()');
|
---|
| 391 |
|
---|
| 392 | if( !current_user_can( 'edit_posts' ) )
|
---|
| 393 | $this->auth_required( __( 'Sorry, you do not have the right to access this blog.' ) );
|
---|
| 394 |
|
---|
| 395 | $home = esc_attr(get_bloginfo_rss('home'));
|
---|
| 396 |
|
---|
| 397 | $categories = "";
|
---|
| 398 | $cats = get_categories("hierarchical=0&hide_empty=0");
|
---|
| 399 | foreach ((array) $cats as $cat) {
|
---|
| 400 | $categories .= " <category term=\"" . esc_attr($cat->name) . "\" />\n";
|
---|
| 401 | }
|
---|
| 402 | $output = <<<EOD
|
---|
| 403 | <app:categories xmlns:app="$this->ATOMPUB_NS"
|
---|
| 404 | xmlns="$this->ATOM_NS"
|
---|
| 405 | fixed="yes" scheme="$home">
|
---|
| 406 | $categories
|
---|
| 407 | </app:categories>
|
---|
| 408 | EOD;
|
---|
| 409 | $this->output($output, $this->CATEGORIES_CONTENT_TYPE);
|
---|
| 410 | }
|
---|
| 411 |
|
---|
| 412 | /**
|
---|
| 413 | * Create new post.
|
---|
| 414 | *
|
---|
| 415 | * @since 2.2.0
|
---|
| 416 | */
|
---|
| 417 | function create_post() {
|
---|
| 418 | global $blog_id, $user_ID;
|
---|
| 419 | $this->get_accepted_content_type($this->atom_content_types);
|
---|
| 420 |
|
---|
| 421 | $parser = new AtomParser();
|
---|
| 422 | if(!$parser->parse()) {
|
---|
| 423 | $this->client_error();
|
---|
| 424 | }
|
---|
| 425 |
|
---|
| 426 | $entry = array_pop($parser->feed->entries);
|
---|
| 427 |
|
---|
| 428 | log_app('Received entry:', print_r($entry,true));
|
---|
| 429 |
|
---|
| 430 | $catnames = array();
|
---|
| 431 | foreach($entry->categories as $cat)
|
---|
| 432 | array_push($catnames, $cat["term"]);
|
---|
| 433 |
|
---|
| 434 | $wp_cats = get_categories(array('hide_empty' => false));
|
---|
| 435 |
|
---|
| 436 | $post_category = array();
|
---|
| 437 |
|
---|
| 438 | foreach($wp_cats as $cat) {
|
---|
| 439 | if(in_array($cat->name, $catnames))
|
---|
| 440 | array_push($post_category, $cat->term_id);
|
---|
| 441 | }
|
---|
| 442 |
|
---|
| 443 | $publish = (isset($entry->draft) && trim($entry->draft) == 'yes') ? false : true;
|
---|
| 444 |
|
---|
| 445 | $cap = ($publish) ? 'publish_posts' : 'edit_posts';
|
---|
| 446 |
|
---|
| 447 | if(!current_user_can($cap))
|
---|
| 448 | $this->auth_required(__('Sorry, you do not have the right to edit/publish new posts.'));
|
---|
| 449 |
|
---|
| 450 | $blog_ID = (int ) $blog_id;
|
---|
| 451 | $post_status = ($publish) ? 'publish' : 'draft';
|
---|
| 452 | $post_author = (int) $user_ID;
|
---|
| 453 | $post_title = $entry->title[1];
|
---|
| 454 | $post_content = $entry->content[1];
|
---|
| 455 | $post_excerpt = $entry->summary[1];
|
---|
| 456 | $pubtimes = $this->get_publish_time($entry->published);
|
---|
| 457 | $post_date = $pubtimes[0];
|
---|
| 458 | $post_date_gmt = $pubtimes[1];
|
---|
| 459 |
|
---|
| 460 | if ( isset( $_SERVER['HTTP_SLUG'] ) )
|
---|
| 461 | $post_name = $_SERVER['HTTP_SLUG'];
|
---|
| 462 |
|
---|
| 463 | $post_data = compact('blog_ID', 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt', 'post_name');
|
---|
| 464 |
|
---|
| 465 | $this->escape($post_data);
|
---|
| 466 | log_app('Inserting Post. Data:', print_r($post_data,true));
|
---|
| 467 |
|
---|
| 468 | $postID = wp_insert_post($post_data);
|
---|
| 469 | if ( is_wp_error( $postID ) )
|
---|
| 470 | $this->internal_error($postID->get_error_message());
|
---|
| 471 |
|
---|
| 472 | if (!$postID)
|
---|
| 473 | $this->internal_error(__('Sorry, your entry could not be posted. Something wrong happened.'));
|
---|
| 474 |
|
---|
| 475 | // getting warning here about unable to set headers
|
---|
| 476 | // because something in the cache is printing to the buffer
|
---|
| 477 | // could we clean up wp_set_post_categories or cache to not print
|
---|
| 478 | // this could affect our ability to send back the right headers
|
---|
| 479 | @wp_set_post_categories($postID, $post_category);
|
---|
| 480 |
|
---|
| 481 | do_action( 'atompub_create_post', $postID, $entry );
|
---|
| 482 |
|
---|
| 483 | $output = $this->get_entry($postID);
|
---|
| 484 |
|
---|
| 485 | log_app('function',"create_post($postID)");
|
---|
| 486 | $this->created($postID, $output);
|
---|
| 487 | }
|
---|
| 488 |
|
---|
| 489 | /**
|
---|
| 490 | * Retrieve post.
|
---|
| 491 | *
|
---|
| 492 | * @since 2.2.0
|
---|
| 493 | *
|
---|
| 494 | * @param int $postID Post ID.
|
---|
| 495 | */
|
---|
| 496 | function get_post($postID) {
|
---|
| 497 | global $entry;
|
---|
| 498 |
|
---|
| 499 | if( !current_user_can( 'edit_post', $postID ) )
|
---|
| 500 | $this->auth_required( __( 'Sorry, you do not have the right to access this post.' ) );
|
---|
| 501 |
|
---|
| 502 | $this->set_current_entry($postID);
|
---|
| 503 | $output = $this->get_entry($postID);
|
---|
| 504 | log_app('function',"get_post($postID)");
|
---|
| 505 | $this->output($output);
|
---|
| 506 |
|
---|
| 507 | }
|
---|
| 508 |
|
---|
| 509 | /**
|
---|
| 510 | * Update post.
|
---|
| 511 | *
|
---|
| 512 | * @since 2.2.0
|
---|
| 513 | *
|
---|
| 514 | * @param int $postID Post ID.
|
---|
| 515 | */
|
---|
| 516 | function put_post($postID) {
|
---|
| 517 | // checked for valid content-types (atom+xml)
|
---|
| 518 | // quick check and exit
|
---|
| 519 | $this->get_accepted_content_type($this->atom_content_types);
|
---|
| 520 |
|
---|
| 521 | $parser = new AtomParser();
|
---|
| 522 | if(!$parser->parse()) {
|
---|
| 523 | $this->bad_request();
|
---|
| 524 | }
|
---|
| 525 |
|
---|
| 526 | $parsed = array_pop($parser->feed->entries);
|
---|
| 527 |
|
---|
| 528 | log_app('Received UPDATED entry:', print_r($parsed,true));
|
---|
| 529 |
|
---|
| 530 | // check for not found
|
---|
| 531 | global $entry;
|
---|
| 532 | $this->set_current_entry($postID);
|
---|
| 533 |
|
---|
| 534 | if(!current_user_can('edit_post', $entry['ID']))
|
---|
| 535 | $this->auth_required(__('Sorry, you do not have the right to edit this post.'));
|
---|
| 536 |
|
---|
| 537 | $publish = (isset($parsed->draft) && trim($parsed->draft) == 'yes') ? false : true;
|
---|
| 538 | $post_status = ($publish) ? 'publish' : 'draft';
|
---|
| 539 |
|
---|
| 540 | extract($entry);
|
---|
| 541 |
|
---|
| 542 | $post_title = $parsed->title[1];
|
---|
| 543 | $post_content = $parsed->content[1];
|
---|
| 544 | $post_excerpt = $parsed->summary[1];
|
---|
| 545 | $pubtimes = $this->get_publish_time($entry->published);
|
---|
| 546 | $post_date = $pubtimes[0];
|
---|
| 547 | $post_date_gmt = $pubtimes[1];
|
---|
| 548 | $pubtimes = $this->get_publish_time($parsed->updated);
|
---|
| 549 | $post_modified = $pubtimes[0];
|
---|
| 550 | $post_modified_gmt = $pubtimes[1];
|
---|
| 551 |
|
---|
| 552 | $postdata = compact('ID', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt', 'post_date', 'post_date_gmt', 'post_modified', 'post_modified_gmt');
|
---|
| 553 | $this->escape($postdata);
|
---|
| 554 |
|
---|
| 555 | $result = wp_update_post($postdata);
|
---|
| 556 |
|
---|
| 557 | if (!$result) {
|
---|
| 558 | $this->internal_error(__('For some strange yet very annoying reason, this post could not be edited.'));
|
---|
| 559 | }
|
---|
| 560 |
|
---|
| 561 | do_action( 'atompub_put_post', $ID, $parsed );
|
---|
| 562 |
|
---|
| 563 | log_app('function',"put_post($postID)");
|
---|
| 564 | $this->ok();
|
---|
| 565 | }
|
---|
| 566 |
|
---|
| 567 | /**
|
---|
| 568 | * Remove post.
|
---|
| 569 | *
|
---|
| 570 | * @since 2.2.0
|
---|
| 571 | *
|
---|
| 572 | * @param int $postID Post ID.
|
---|
| 573 | */
|
---|
| 574 | function delete_post($postID) {
|
---|
| 575 |
|
---|
| 576 | // check for not found
|
---|
| 577 | global $entry;
|
---|
| 578 | $this->set_current_entry($postID);
|
---|
| 579 |
|
---|
| 580 | if(!current_user_can('edit_post', $postID)) {
|
---|
| 581 | $this->auth_required(__('Sorry, you do not have the right to delete this post.'));
|
---|
| 582 | }
|
---|
| 583 |
|
---|
| 584 | if ($entry['post_type'] == 'attachment') {
|
---|
| 585 | $this->delete_attachment($postID);
|
---|
| 586 | } else {
|
---|
| 587 | $result = wp_delete_post($postID);
|
---|
| 588 |
|
---|
| 589 | if (!$result) {
|
---|
| 590 | $this->internal_error(__('For some strange yet very annoying reason, this post could not be deleted.'));
|
---|
| 591 | }
|
---|
| 592 |
|
---|
| 593 | log_app('function',"delete_post($postID)");
|
---|
| 594 | $this->ok();
|
---|
| 595 | }
|
---|
| 596 |
|
---|
| 597 | }
|
---|
| 598 |
|
---|
| 599 | /**
|
---|
| 600 | * Retrieve attachment.
|
---|
| 601 | *
|
---|
| 602 | * @since 2.2.0
|
---|
| 603 | *
|
---|
| 604 | * @param int $postID Optional. Post ID.
|
---|
| 605 | */
|
---|
| 606 | function get_attachment($postID = null) {
|
---|
| 607 | if( !current_user_can( 'upload_files' ) )
|
---|
| 608 | $this->auth_required( __( 'Sorry, you do not have permission to upload files.' ) );
|
---|
| 609 |
|
---|
| 610 | if (!isset($postID)) {
|
---|
| 611 | $this->get_attachments();
|
---|
| 612 | } else {
|
---|
| 613 | $this->set_current_entry($postID);
|
---|
| 614 | $output = $this->get_entry($postID, 'attachment');
|
---|
| 615 | log_app('function',"get_attachment($postID)");
|
---|
| 616 | $this->output($output);
|
---|
| 617 | }
|
---|
| 618 | }
|
---|
| 619 |
|
---|
| 620 | /**
|
---|
| 621 | * Create new attachment.
|
---|
| 622 | *
|
---|
| 623 | * @since 2.2.0
|
---|
| 624 | */
|
---|
| 625 | function create_attachment() {
|
---|
| 626 |
|
---|
| 627 | $type = $this->get_accepted_content_type();
|
---|
| 628 |
|
---|
| 629 | if(!current_user_can('upload_files'))
|
---|
| 630 | $this->auth_required(__('You do not have permission to upload files.'));
|
---|
| 631 |
|
---|
| 632 | $fp = fopen("php://input", "rb");
|
---|
| 633 | $bits = null;
|
---|
| 634 | while(!feof($fp)) {
|
---|
| 635 | $bits .= fread($fp, 4096);
|
---|
| 636 | }
|
---|
| 637 | fclose($fp);
|
---|
| 638 |
|
---|
| 639 | $slug = '';
|
---|
| 640 | if ( isset( $_SERVER['HTTP_SLUG'] ) )
|
---|
| 641 | $slug = sanitize_file_name( $_SERVER['HTTP_SLUG'] );
|
---|
| 642 | elseif ( isset( $_SERVER['HTTP_TITLE'] ) )
|
---|
| 643 | $slug = sanitize_file_name( $_SERVER['HTTP_TITLE'] );
|
---|
| 644 | elseif ( empty( $slug ) ) // just make a random name
|
---|
| 645 | $slug = substr( md5( uniqid( microtime() ) ), 0, 7);
|
---|
| 646 | $ext = preg_replace( '|.*/([a-z0-9]+)|', '$1', $_SERVER['CONTENT_TYPE'] );
|
---|
| 647 | $slug = "$slug.$ext";
|
---|
| 648 | $file = wp_upload_bits( $slug, NULL, $bits);
|
---|
| 649 |
|
---|
| 650 | log_app('wp_upload_bits returns:',print_r($file,true));
|
---|
| 651 |
|
---|
| 652 | $url = $file['url'];
|
---|
| 653 | $file = $file['file'];
|
---|
| 654 |
|
---|
| 655 | do_action('wp_create_file_in_uploads', $file); // replicate
|
---|
| 656 |
|
---|
| 657 | // Construct the attachment array
|
---|
| 658 | $attachment = array(
|
---|
| 659 | 'post_title' => $slug,
|
---|
| 660 | 'post_content' => $slug,
|
---|
| 661 | 'post_status' => 'attachment',
|
---|
| 662 | 'post_parent' => 0,
|
---|
| 663 | 'post_mime_type' => $type,
|
---|
| 664 | 'guid' => $url
|
---|
| 665 | );
|
---|
| 666 |
|
---|
| 667 | // Save the data
|
---|
| 668 | $postID = wp_insert_attachment($attachment, $file);
|
---|
| 669 |
|
---|
| 670 | if (!$postID)
|
---|
| 671 | $this->internal_error(__('Sorry, your entry could not be posted. Something wrong happened.'));
|
---|
| 672 |
|
---|
| 673 | $output = $this->get_entry($postID, 'attachment');
|
---|
| 674 |
|
---|
| 675 | $this->created($postID, $output, 'attachment');
|
---|
| 676 | log_app('function',"create_attachment($postID)");
|
---|
| 677 | }
|
---|
| 678 |
|
---|
| 679 | /**
|
---|
| 680 | * Update attachment.
|
---|
| 681 | *
|
---|
| 682 | * @since 2.2.0
|
---|
| 683 | *
|
---|
| 684 | * @param int $postID Post ID.
|
---|
| 685 | */
|
---|
| 686 | function put_attachment($postID) {
|
---|
| 687 | // checked for valid content-types (atom+xml)
|
---|
| 688 | // quick check and exit
|
---|
| 689 | $this->get_accepted_content_type($this->atom_content_types);
|
---|
| 690 |
|
---|
| 691 | $parser = new AtomParser();
|
---|
| 692 | if(!$parser->parse()) {
|
---|
| 693 | $this->bad_request();
|
---|
| 694 | }
|
---|
| 695 |
|
---|
| 696 | $parsed = array_pop($parser->feed->entries);
|
---|
| 697 |
|
---|
| 698 | // check for not found
|
---|
| 699 | global $entry;
|
---|
| 700 | $this->set_current_entry($postID);
|
---|
| 701 |
|
---|
| 702 | if(!current_user_can('edit_post', $entry['ID']))
|
---|
| 703 | $this->auth_required(__('Sorry, you do not have the right to edit this post.'));
|
---|
| 704 |
|
---|
| 705 | extract($entry);
|
---|
| 706 |
|
---|
| 707 | $post_title = $parsed->title[1];
|
---|
| 708 | $post_content = $parsed->summary[1];
|
---|
| 709 | $pubtimes = $this->get_publish_time($parsed->updated);
|
---|
| 710 | $post_modified = $pubtimes[0];
|
---|
| 711 | $post_modified_gmt = $pubtimes[1];
|
---|
| 712 |
|
---|
| 713 | $postdata = compact('ID', 'post_content', 'post_title', 'post_category', 'post_status', 'post_excerpt', 'post_modified', 'post_modified_gmt');
|
---|
| 714 | $this->escape($postdata);
|
---|
| 715 |
|
---|
| 716 | $result = wp_update_post($postdata);
|
---|
| 717 |
|
---|
| 718 | if (!$result) {
|
---|
| 719 | $this->internal_error(__('For some strange yet very annoying reason, this post could not be edited.'));
|
---|
| 720 | }
|
---|
| 721 |
|
---|
| 722 | log_app('function',"put_attachment($postID)");
|
---|
| 723 | $this->ok();
|
---|
| 724 | }
|
---|
| 725 |
|
---|
| 726 | /**
|
---|
| 727 | * Remove attachment.
|
---|
| 728 | *
|
---|
| 729 | * @since 2.2.0
|
---|
| 730 | *
|
---|
| 731 | * @param int $postID Post ID.
|
---|
| 732 | */
|
---|
| 733 | function delete_attachment($postID) {
|
---|
| 734 | log_app('function',"delete_attachment($postID). File '$location' deleted.");
|
---|
| 735 |
|
---|
| 736 | // check for not found
|
---|
| 737 | global $entry;
|
---|
| 738 | $this->set_current_entry($postID);
|
---|
| 739 |
|
---|
| 740 | if(!current_user_can('edit_post', $postID)) {
|
---|
| 741 | $this->auth_required(__('Sorry, you do not have the right to delete this post.'));
|
---|
| 742 | }
|
---|
| 743 |
|
---|
| 744 | $location = get_post_meta($entry['ID'], '_wp_attached_file', true);
|
---|
| 745 | $filetype = wp_check_filetype($location);
|
---|
| 746 |
|
---|
| 747 | if(!isset($location) || 'attachment' != $entry['post_type'] || empty($filetype['ext']))
|
---|
| 748 | $this->internal_error(__('Error ocurred while accessing post metadata for file location.'));
|
---|
| 749 |
|
---|
| 750 | // delete file
|
---|
| 751 | @unlink($location);
|
---|
| 752 |
|
---|
| 753 | // delete attachment
|
---|
| 754 | $result = wp_delete_post($postID);
|
---|
| 755 |
|
---|
| 756 | if (!$result) {
|
---|
| 757 | $this->internal_error(__('For some strange yet very annoying reason, this post could not be deleted.'));
|
---|
| 758 | }
|
---|
| 759 |
|
---|
| 760 | log_app('function',"delete_attachment($postID). File '$location' deleted.");
|
---|
| 761 | $this->ok();
|
---|
| 762 | }
|
---|
| 763 |
|
---|
| 764 | /**
|
---|
| 765 | * Retrieve attachment from post.
|
---|
| 766 | *
|
---|
| 767 | * @since 2.2.0
|
---|
| 768 | *
|
---|
| 769 | * @param int $postID Post ID.
|
---|
| 770 | */
|
---|
| 771 | function get_file($postID) {
|
---|
| 772 |
|
---|
| 773 | // check for not found
|
---|
| 774 | global $entry;
|
---|
| 775 | $this->set_current_entry($postID);
|
---|
| 776 |
|
---|
| 777 | // then whether user can edit the specific post
|
---|
| 778 | if(!current_user_can('edit_post', $postID)) {
|
---|
| 779 | $this->auth_required(__('Sorry, you do not have the right to edit this post.'));
|
---|
| 780 | }
|
---|
| 781 |
|
---|
| 782 | $location = get_post_meta($entry['ID'], '_wp_attached_file', true);
|
---|
| 783 | $filetype = wp_check_filetype($location);
|
---|
| 784 |
|
---|
| 785 | if(!isset($location) || 'attachment' != $entry['post_type'] || empty($filetype['ext']))
|
---|
| 786 | $this->internal_error(__('Error ocurred while accessing post metadata for file location.'));
|
---|
| 787 |
|
---|
| 788 | status_header('200');
|
---|
| 789 | header('Content-Type: ' . $entry['post_mime_type']);
|
---|
| 790 | header('Connection: close');
|
---|
| 791 |
|
---|
| 792 | $fp = fopen($location, "rb");
|
---|
| 793 | while(!feof($fp)) {
|
---|
| 794 | echo fread($fp, 4096);
|
---|
| 795 | }
|
---|
| 796 | fclose($fp);
|
---|
| 797 |
|
---|
| 798 | log_app('function',"get_file($postID)");
|
---|
| 799 | exit;
|
---|
| 800 | }
|
---|
| 801 |
|
---|
| 802 | /**
|
---|
| 803 | * Upload file to blog and add attachment to post.
|
---|
| 804 | *
|
---|
| 805 | * @since 2.2.0
|
---|
| 806 | *
|
---|
| 807 | * @param int $postID Post ID.
|
---|
| 808 | */
|
---|
| 809 | function put_file($postID) {
|
---|
| 810 |
|
---|
| 811 | // first check if user can upload
|
---|
| 812 | if(!current_user_can('upload_files'))
|
---|
| 813 | $this->auth_required(__('You do not have permission to upload files.'));
|
---|
| 814 |
|
---|
| 815 | // check for not found
|
---|
| 816 | global $entry;
|
---|
| 817 | $this->set_current_entry($postID);
|
---|
| 818 |
|
---|
| 819 | // then whether user can edit the specific post
|
---|
| 820 | if(!current_user_can('edit_post', $postID)) {
|
---|
| 821 | $this->auth_required(__('Sorry, you do not have the right to edit this post.'));
|
---|
| 822 | }
|
---|
| 823 |
|
---|
| 824 | $upload_dir = wp_upload_dir( );
|
---|
| 825 | $location = get_post_meta($entry['ID'], '_wp_attached_file', true);
|
---|
| 826 | $filetype = wp_check_filetype($location);
|
---|
| 827 |
|
---|
| 828 | $location = "{$upload_dir['basedir']}/{$location}";
|
---|
| 829 |
|
---|
| 830 | if(!isset($location) || 'attachment' != $entry['post_type'] || empty($filetype['ext']))
|
---|
| 831 | $this->internal_error(__('Error ocurred while accessing post metadata for file location.'));
|
---|
| 832 |
|
---|
| 833 | $fp = fopen("php://input", "rb");
|
---|
| 834 | $localfp = fopen($location, "w+");
|
---|
| 835 | while(!feof($fp)) {
|
---|
| 836 | fwrite($localfp,fread($fp, 4096));
|
---|
| 837 | }
|
---|
| 838 | fclose($fp);
|
---|
| 839 | fclose($localfp);
|
---|
| 840 |
|
---|
| 841 | $ID = $entry['ID'];
|
---|
| 842 | $pubtimes = $this->get_publish_time($entry->published);
|
---|
| 843 | $post_date = $pubtimes[0];
|
---|
| 844 | $post_date_gmt = $pubtimes[1];
|
---|
| 845 | $pubtimes = $this->get_publish_time($parsed->updated);
|
---|
| 846 | $post_modified = $pubtimes[0];
|
---|
| 847 | $post_modified_gmt = $pubtimes[1];
|
---|
| 848 |
|
---|
| 849 | $post_data = compact('ID', 'post_date', 'post_date_gmt', 'post_modified', 'post_modified_gmt');
|
---|
| 850 | $result = wp_update_post($post_data);
|
---|
| 851 |
|
---|
| 852 | if (!$result) {
|
---|
| 853 | $this->internal_error(__('Sorry, your entry could not be posted. Something wrong happened.'));
|
---|
| 854 | }
|
---|
| 855 |
|
---|
| 856 | wp_update_attachment_metadata( $postID, wp_generate_attachment_metadata( $postID, $location ) );
|
---|
| 857 |
|
---|
| 858 | log_app('function',"put_file($postID)");
|
---|
| 859 | $this->ok();
|
---|
| 860 | }
|
---|
| 861 |
|
---|
| 862 | /**
|
---|
| 863 | * Retrieve entries URL.
|
---|
| 864 | *
|
---|
| 865 | * @since 2.2.0
|
---|
| 866 | *
|
---|
| 867 | * @param int $page Page ID.
|
---|
| 868 | * @return string
|
---|
| 869 | */
|
---|
| 870 | function get_entries_url($page = null) {
|
---|
| 871 | if($GLOBALS['post_type'] == 'attachment') {
|
---|
| 872 | $path = $this->MEDIA_PATH;
|
---|
| 873 | } else {
|
---|
| 874 | $path = $this->ENTRIES_PATH;
|
---|
| 875 | }
|
---|
| 876 | $url = $this->app_base . $path;
|
---|
| 877 | if(isset($page) && is_int($page)) {
|
---|
| 878 | $url .= "/$page";
|
---|
| 879 | }
|
---|
| 880 | return $url;
|
---|
| 881 | }
|
---|
| 882 |
|
---|
| 883 | /**
|
---|
| 884 | * Display entries URL.
|
---|
| 885 | *
|
---|
| 886 | * @since 2.2.0
|
---|
| 887 | *
|
---|
| 888 | * @param int $page Page ID.
|
---|
| 889 | */
|
---|
| 890 | function the_entries_url($page = null) {
|
---|
| 891 | echo $this->get_entries_url($page);
|
---|
| 892 | }
|
---|
| 893 |
|
---|
| 894 | /**
|
---|
| 895 | * Retrieve categories URL.
|
---|
| 896 | *
|
---|
| 897 | * @since 2.2.0
|
---|
| 898 | *
|
---|
| 899 | * @param mixed $deprecated Optional, not used.
|
---|
| 900 | * @return string
|
---|
| 901 | */
|
---|
| 902 | function get_categories_url($deprecated = '') {
|
---|
| 903 | return $this->app_base . $this->CATEGORIES_PATH;
|
---|
| 904 | }
|
---|
| 905 |
|
---|
| 906 | /**
|
---|
| 907 | * Display category URL.
|
---|
| 908 | *
|
---|
| 909 | * @since 2.2.0
|
---|
| 910 | */
|
---|
| 911 | function the_categories_url() {
|
---|
| 912 | echo $this->get_categories_url();
|
---|
| 913 | }
|
---|
| 914 |
|
---|
| 915 | /**
|
---|
| 916 | * Retrieve attachment URL.
|
---|
| 917 | *
|
---|
| 918 | * @since 2.2.0
|
---|
| 919 | *
|
---|
| 920 | * @param int $page Page ID.
|
---|
| 921 | * @return string
|
---|
| 922 | */
|
---|
| 923 | function get_attachments_url($page = null) {
|
---|
| 924 | $url = $this->app_base . $this->MEDIA_PATH;
|
---|
| 925 | if(isset($page) && is_int($page)) {
|
---|
| 926 | $url .= "/$page";
|
---|
| 927 | }
|
---|
| 928 | return $url;
|
---|
| 929 | }
|
---|
| 930 |
|
---|
| 931 | /**
|
---|
| 932 | * Display attachment URL.
|
---|
| 933 | *
|
---|
| 934 | * @since 2.2.0
|
---|
| 935 | *
|
---|
| 936 | * @param int $page Page ID.
|
---|
| 937 | */
|
---|
| 938 | function the_attachments_url($page = null) {
|
---|
| 939 | echo $this->get_attachments_url($page);
|
---|
| 940 | }
|
---|
| 941 |
|
---|
| 942 | /**
|
---|
| 943 | * Retrieve service URL.
|
---|
| 944 | *
|
---|
| 945 | * @since 2.3.0
|
---|
| 946 | *
|
---|
| 947 | * @return string
|
---|
| 948 | */
|
---|
| 949 | function get_service_url() {
|
---|
| 950 | return $this->app_base . $this->SERVICE_PATH;
|
---|
| 951 | }
|
---|
| 952 |
|
---|
| 953 | /**
|
---|
| 954 | * Retrieve entry URL.
|
---|
| 955 | *
|
---|
| 956 | * @since 2.7.0
|
---|
| 957 | *
|
---|
| 958 | * @param int $postID Post ID.
|
---|
| 959 | * @return string
|
---|
| 960 | */
|
---|
| 961 | function get_entry_url($postID = null) {
|
---|
| 962 | if(!isset($postID)) {
|
---|
| 963 | global $post;
|
---|
| 964 | $postID = (int) $post->ID;
|
---|
| 965 | }
|
---|
| 966 |
|
---|
| 967 | $url = $this->app_base . $this->ENTRY_PATH . "/$postID";
|
---|
| 968 |
|
---|
| 969 | log_app('function',"get_entry_url() = $url");
|
---|
| 970 | return $url;
|
---|
| 971 | }
|
---|
| 972 |
|
---|
| 973 | /**
|
---|
| 974 | * Display entry URL.
|
---|
| 975 | *
|
---|
| 976 | * @since 2.7.0
|
---|
| 977 | *
|
---|
| 978 | * @param int $postID Post ID.
|
---|
| 979 | */
|
---|
| 980 | function the_entry_url($postID = null) {
|
---|
| 981 | echo $this->get_entry_url($postID);
|
---|
| 982 | }
|
---|
| 983 |
|
---|
| 984 | /**
|
---|
| 985 | * Retrieve media URL.
|
---|
| 986 | *
|
---|
| 987 | * @since 2.2.0
|
---|
| 988 | *
|
---|
| 989 | * @param int $postID Post ID.
|
---|
| 990 | * @return string
|
---|
| 991 | */
|
---|
| 992 | function get_media_url($postID = null) {
|
---|
| 993 | if(!isset($postID)) {
|
---|
| 994 | global $post;
|
---|
| 995 | $postID = (int) $post->ID;
|
---|
| 996 | }
|
---|
| 997 |
|
---|
| 998 | $url = $this->app_base . $this->MEDIA_SINGLE_PATH ."/file/$postID";
|
---|
| 999 |
|
---|
| 1000 | log_app('function',"get_media_url() = $url");
|
---|
| 1001 | return $url;
|
---|
| 1002 | }
|
---|
| 1003 |
|
---|
| 1004 | /**
|
---|
| 1005 | * Display the media URL.
|
---|
| 1006 | *
|
---|
| 1007 | * @since 2.2.0
|
---|
| 1008 | *
|
---|
| 1009 | * @param int $postID Post ID.
|
---|
| 1010 | */
|
---|
| 1011 | function the_media_url($postID = null) {
|
---|
| 1012 | echo $this->get_media_url($postID);
|
---|
| 1013 | }
|
---|
| 1014 |
|
---|
| 1015 | /**
|
---|
| 1016 | * Set the current entry to post ID.
|
---|
| 1017 | *
|
---|
| 1018 | * @since 2.2.0
|
---|
| 1019 | *
|
---|
| 1020 | * @param int $postID Post ID.
|
---|
| 1021 | */
|
---|
| 1022 | function set_current_entry($postID) {
|
---|
| 1023 | global $entry;
|
---|
| 1024 | log_app('function',"set_current_entry($postID)");
|
---|
| 1025 |
|
---|
| 1026 | if(!isset($postID)) {
|
---|
| 1027 | // $this->bad_request();
|
---|
| 1028 | $this->not_found();
|
---|
| 1029 | }
|
---|
| 1030 |
|
---|
| 1031 | $entry = wp_get_single_post($postID,ARRAY_A);
|
---|
| 1032 |
|
---|
| 1033 | if(!isset($entry) || !isset($entry['ID']))
|
---|
| 1034 | $this->not_found();
|
---|
| 1035 |
|
---|
| 1036 | return;
|
---|
| 1037 | }
|
---|
| 1038 |
|
---|
| 1039 | /**
|
---|
| 1040 | * Display posts XML.
|
---|
| 1041 | *
|
---|
| 1042 | * @since 2.2.0
|
---|
| 1043 | *
|
---|
| 1044 | * @param int $page Optional. Page ID.
|
---|
| 1045 | * @param string $post_type Optional, default is 'post'. Post Type.
|
---|
| 1046 | */
|
---|
| 1047 | function get_posts($page = 1, $post_type = 'post') {
|
---|
| 1048 | log_app('function',"get_posts($page, '$post_type')");
|
---|
| 1049 | $feed = $this->get_feed($page, $post_type);
|
---|
| 1050 | $this->output($feed);
|
---|
| 1051 | }
|
---|
| 1052 |
|
---|
| 1053 | /**
|
---|
| 1054 | * Display attachment XML.
|
---|
| 1055 | *
|
---|
| 1056 | * @since 2.2.0
|
---|
| 1057 | *
|
---|
| 1058 | * @param int $page Page ID.
|
---|
| 1059 | * @param string $post_type Optional, default is 'attachment'. Post type.
|
---|
| 1060 | */
|
---|
| 1061 | function get_attachments($page = 1, $post_type = 'attachment') {
|
---|
| 1062 | log_app('function',"get_attachments($page, '$post_type')");
|
---|
| 1063 | $GLOBALS['post_type'] = $post_type;
|
---|
| 1064 | $feed = $this->get_feed($page, $post_type);
|
---|
| 1065 | $this->output($feed);
|
---|
| 1066 | }
|
---|
| 1067 |
|
---|
| 1068 | /**
|
---|
| 1069 | * Retrieve feed XML.
|
---|
| 1070 | *
|
---|
| 1071 | * @since 2.2.0
|
---|
| 1072 | *
|
---|
| 1073 | * @param int $page Page ID.
|
---|
| 1074 | * @param string $post_type Optional, default is post. Post type.
|
---|
| 1075 | * @return string
|
---|
| 1076 | */
|
---|
| 1077 | function get_feed($page = 1, $post_type = 'post') {
|
---|
| 1078 | global $post, $wp, $wp_query, $posts, $wpdb, $blog_id;
|
---|
| 1079 | log_app('function',"get_feed($page, '$post_type')");
|
---|
| 1080 | ob_start();
|
---|
| 1081 |
|
---|
| 1082 | $this->ENTRY_PATH = $post_type;
|
---|
| 1083 |
|
---|
| 1084 | if(!isset($page)) {
|
---|
| 1085 | $page = 1;
|
---|
| 1086 | }
|
---|
| 1087 | $page = (int) $page;
|
---|
| 1088 |
|
---|
| 1089 | $count = get_option('posts_per_rss');
|
---|
| 1090 |
|
---|
| 1091 | wp('posts_per_page=' . $count . '&offset=' . ($count * ($page-1) . '&orderby=modified'));
|
---|
| 1092 |
|
---|
| 1093 | $post = $GLOBALS['post'];
|
---|
| 1094 | $posts = $GLOBALS['posts'];
|
---|
| 1095 | $wp = $GLOBALS['wp'];
|
---|
| 1096 | $wp_query = $GLOBALS['wp_query'];
|
---|
| 1097 | $wpdb = $GLOBALS['wpdb'];
|
---|
| 1098 | $blog_id = (int) $GLOBALS['blog_id'];
|
---|
| 1099 | log_app('function',"query_posts(# " . print_r($wp_query, true) . "#)");
|
---|
| 1100 |
|
---|
| 1101 | log_app('function',"total_count(# $wp_query->max_num_pages #)");
|
---|
| 1102 | $last_page = $wp_query->max_num_pages;
|
---|
| 1103 | $next_page = (($page + 1) > $last_page) ? NULL : $page + 1;
|
---|
| 1104 | $prev_page = ($page - 1) < 1 ? NULL : $page - 1;
|
---|
| 1105 | $last_page = ((int)$last_page == 1 || (int)$last_page == 0) ? NULL : (int) $last_page;
|
---|
| 1106 | $self_page = $page > 1 ? $page : NULL;
|
---|
| 1107 | ?><feed xmlns="<?php echo $this->ATOM_NS ?>" xmlns:app="<?php echo $this->ATOMPUB_NS ?>" xml:lang="<?php echo get_option('rss_language'); ?>">
|
---|
| 1108 | <id><?php $this->the_entries_url() ?></id>
|
---|
| 1109 | <updated><?php echo mysql2date('Y-m-d\TH:i:s\Z', get_lastpostmodified('GMT'), false); ?></updated>
|
---|
| 1110 | <title type="text"><?php bloginfo_rss('name') ?></title>
|
---|
| 1111 | <subtitle type="text"><?php bloginfo_rss("description") ?></subtitle>
|
---|
| 1112 | <link rel="first" type="<?php echo $this->ATOM_CONTENT_TYPE ?>" href="<?php $this->the_entries_url() ?>" />
|
---|
| 1113 | <?php if(isset($prev_page)): ?>
|
---|
| 1114 | <link rel="previous" type="<?php echo $this->ATOM_CONTENT_TYPE ?>" href="<?php $this->the_entries_url($prev_page) ?>" />
|
---|
| 1115 | <?php endif; ?>
|
---|
| 1116 | <?php if(isset($next_page)): ?>
|
---|
| 1117 | <link rel="next" type="<?php echo $this->ATOM_CONTENT_TYPE ?>" href="<?php $this->the_entries_url($next_page) ?>" />
|
---|
| 1118 | <?php endif; ?>
|
---|
| 1119 | <link rel="last" type="<?php echo $this->ATOM_CONTENT_TYPE ?>" href="<?php $this->the_entries_url($last_page) ?>" />
|
---|
| 1120 | <link rel="self" type="<?php echo $this->ATOM_CONTENT_TYPE ?>" href="<?php $this->the_entries_url($self_page) ?>" />
|
---|
| 1121 | <rights type="text">Copyright <?php echo date('Y'); ?></rights>
|
---|
| 1122 | <?php the_generator( 'atom' ); ?>
|
---|
| 1123 | <?php if ( have_posts() ) {
|
---|
| 1124 | while ( have_posts() ) {
|
---|
| 1125 | the_post();
|
---|
| 1126 | $this->echo_entry();
|
---|
| 1127 | }
|
---|
| 1128 | }
|
---|
| 1129 | ?></feed>
|
---|
| 1130 | <?php
|
---|
| 1131 | $feed = ob_get_contents();
|
---|
| 1132 | ob_end_clean();
|
---|
| 1133 | return $feed;
|
---|
| 1134 | }
|
---|
| 1135 |
|
---|
| 1136 | /**
|
---|
| 1137 | * Display entry XML.
|
---|
| 1138 | *
|
---|
| 1139 | * @since 2.2.0
|
---|
| 1140 | *
|
---|
| 1141 | * @param int $postID Post ID.
|
---|
| 1142 | * @param string $post_type Optional, default is post. Post type.
|
---|
| 1143 | * @return string.
|
---|
| 1144 | */
|
---|
| 1145 | function get_entry($postID, $post_type = 'post') {
|
---|
| 1146 | log_app('function',"get_entry($postID, '$post_type')");
|
---|
| 1147 | ob_start();
|
---|
| 1148 | switch($post_type) {
|
---|
| 1149 | case 'post':
|
---|
| 1150 | $varname = 'p';
|
---|
| 1151 | break;
|
---|
| 1152 | case 'attachment':
|
---|
| 1153 | $this->ENTRY_PATH = 'attachment';
|
---|
| 1154 | $varname = 'attachment_id';
|
---|
| 1155 | break;
|
---|
| 1156 | }
|
---|
| 1157 | query_posts($varname . '=' . $postID);
|
---|
| 1158 | if ( have_posts() ) {
|
---|
| 1159 | while ( have_posts() ) {
|
---|
| 1160 | the_post();
|
---|
| 1161 | $this->echo_entry();
|
---|
| 1162 | log_app('$post',print_r($GLOBALS['post'],true));
|
---|
| 1163 | $entry = ob_get_contents();
|
---|
| 1164 | break;
|
---|
| 1165 | }
|
---|
| 1166 | }
|
---|
| 1167 | ob_end_clean();
|
---|
| 1168 |
|
---|
| 1169 | log_app('get_entry returning:',$entry);
|
---|
| 1170 | return $entry;
|
---|
| 1171 | }
|
---|
| 1172 |
|
---|
| 1173 | /**
|
---|
| 1174 | * Display post content XML.
|
---|
| 1175 | *
|
---|
| 1176 | * @since 2.3.0
|
---|
| 1177 | */
|
---|
| 1178 | function echo_entry() { ?>
|
---|
| 1179 | <entry xmlns="<?php echo $this->ATOM_NS ?>"
|
---|
| 1180 | xmlns:app="<?php echo $this->ATOMPUB_NS ?>" xml:lang="<?php echo get_option('rss_language'); ?>">
|
---|
| 1181 | <id><?php the_guid($GLOBALS['post']->ID); ?></id>
|
---|
| 1182 | <?php list($content_type, $content) = prep_atom_text_construct(get_the_title()); ?>
|
---|
| 1183 | <title type="<?php echo $content_type ?>"><?php echo $content ?></title>
|
---|
| 1184 | <updated><?php echo get_post_modified_time('Y-m-d\TH:i:s\Z', true); ?></updated>
|
---|
| 1185 | <published><?php echo get_post_time('Y-m-d\TH:i:s\Z', true); ?></published>
|
---|
| 1186 | <app:edited><?php echo get_post_modified_time('Y-m-d\TH:i:s\Z', true); ?></app:edited>
|
---|
| 1187 | <app:control>
|
---|
| 1188 | <app:draft><?php echo ($GLOBALS['post']->post_status == 'draft' ? 'yes' : 'no') ?></app:draft>
|
---|
| 1189 | </app:control>
|
---|
| 1190 | <author>
|
---|
| 1191 | <name><?php the_author()?></name>
|
---|
| 1192 | <?php if ( get_the_author_meta('url') && get_the_author_meta('url') != 'http://' ) { ?>
|
---|
| 1193 | <uri><?php the_author_meta('url') ?></uri>
|
---|
| 1194 | <?php } ?>
|
---|
| 1195 | </author>
|
---|
| 1196 | <?php if($GLOBALS['post']->post_type == 'attachment') { ?>
|
---|
| 1197 | <link rel="edit-media" href="<?php $this->the_media_url() ?>" />
|
---|
| 1198 | <content type="<?php echo $GLOBALS['post']->post_mime_type ?>" src="<?php the_guid(); ?>"/>
|
---|
| 1199 | <?php } else { ?>
|
---|
| 1200 | <link href="<?php the_permalink_rss() ?>" />
|
---|
| 1201 | <?php if ( strlen( $GLOBALS['post']->post_content ) ) :
|
---|
| 1202 | list($content_type, $content) = prep_atom_text_construct(get_the_content()); ?>
|
---|
| 1203 | <content type="<?php echo $content_type ?>"><?php echo $content ?></content>
|
---|
| 1204 | <?php endif; ?>
|
---|
| 1205 | <?php } ?>
|
---|
| 1206 | <link rel="edit" href="<?php $this->the_entry_url() ?>" />
|
---|
| 1207 | <?php the_category_rss( 'atom' ); ?>
|
---|
| 1208 | <?php list($content_type, $content) = prep_atom_text_construct(get_the_excerpt()); ?>
|
---|
| 1209 | <summary type="<?php echo $content_type ?>"><?php echo $content ?></summary>
|
---|
| 1210 | </entry>
|
---|
| 1211 | <?php }
|
---|
| 1212 |
|
---|
| 1213 | /**
|
---|
| 1214 | * Set 'OK' (200) status header.
|
---|
| 1215 | *
|
---|
| 1216 | * @since 2.2.0
|
---|
| 1217 | */
|
---|
| 1218 | function ok() {
|
---|
| 1219 | log_app('Status','200: OK');
|
---|
| 1220 | header('Content-Type: text/plain');
|
---|
| 1221 | status_header('200');
|
---|
| 1222 | exit;
|
---|
| 1223 | }
|
---|
| 1224 |
|
---|
| 1225 | /**
|
---|
| 1226 | * Set 'No Content' (204) status header.
|
---|
| 1227 | *
|
---|
| 1228 | * @since 2.2.0
|
---|
| 1229 | */
|
---|
| 1230 | function no_content() {
|
---|
| 1231 | log_app('Status','204: No Content');
|
---|
| 1232 | header('Content-Type: text/plain');
|
---|
| 1233 | status_header('204');
|
---|
| 1234 | echo "Deleted.";
|
---|
| 1235 | exit;
|
---|
| 1236 | }
|
---|
| 1237 |
|
---|
| 1238 | /**
|
---|
| 1239 | * Display 'Internal Server Error' (500) status header.
|
---|
| 1240 | *
|
---|
| 1241 | * @since 2.2.0
|
---|
| 1242 | *
|
---|
| 1243 | * @param string $msg Optional. Status string.
|
---|
| 1244 | */
|
---|
| 1245 | function internal_error($msg = 'Internal Server Error') {
|
---|
| 1246 | log_app('Status','500: Server Error');
|
---|
| 1247 | header('Content-Type: text/plain');
|
---|
| 1248 | status_header('500');
|
---|
| 1249 | echo $msg;
|
---|
| 1250 | exit;
|
---|
| 1251 | }
|
---|
| 1252 |
|
---|
| 1253 | /**
|
---|
| 1254 | * Set 'Bad Request' (400) status header.
|
---|
| 1255 | *
|
---|
| 1256 | * @since 2.2.0
|
---|
| 1257 | */
|
---|
| 1258 | function bad_request() {
|
---|
| 1259 | log_app('Status','400: Bad Request');
|
---|
| 1260 | header('Content-Type: text/plain');
|
---|
| 1261 | status_header('400');
|
---|
| 1262 | exit;
|
---|
| 1263 | }
|
---|
| 1264 |
|
---|
| 1265 | /**
|
---|
| 1266 | * Set 'Length Required' (411) status header.
|
---|
| 1267 | *
|
---|
| 1268 | * @since 2.2.0
|
---|
| 1269 | */
|
---|
| 1270 | function length_required() {
|
---|
| 1271 | log_app('Status','411: Length Required');
|
---|
| 1272 | header("HTTP/1.1 411 Length Required");
|
---|
| 1273 | header('Content-Type: text/plain');
|
---|
| 1274 | status_header('411');
|
---|
| 1275 | exit;
|
---|
| 1276 | }
|
---|
| 1277 |
|
---|
| 1278 | /**
|
---|
| 1279 | * Set 'Unsupported Media Type' (415) status header.
|
---|
| 1280 | *
|
---|
| 1281 | * @since 2.2.0
|
---|
| 1282 | */
|
---|
| 1283 | function invalid_media() {
|
---|
| 1284 | log_app('Status','415: Unsupported Media Type');
|
---|
| 1285 | header("HTTP/1.1 415 Unsupported Media Type");
|
---|
| 1286 | header('Content-Type: text/plain');
|
---|
| 1287 | exit;
|
---|
| 1288 | }
|
---|
| 1289 |
|
---|
| 1290 | /**
|
---|
| 1291 | * Set 'Forbidden' (403) status header.
|
---|
| 1292 | *
|
---|
| 1293 | * @since 2.6.0
|
---|
| 1294 | */
|
---|
| 1295 | function forbidden($reason='') {
|
---|
| 1296 | log_app('Status','403: Forbidden');
|
---|
| 1297 | header('Content-Type: text/plain');
|
---|
| 1298 | status_header('403');
|
---|
| 1299 | echo $reason;
|
---|
| 1300 | exit;
|
---|
| 1301 | }
|
---|
| 1302 |
|
---|
| 1303 | /**
|
---|
| 1304 | * Set 'Not Found' (404) status header.
|
---|
| 1305 | *
|
---|
| 1306 | * @since 2.2.0
|
---|
| 1307 | */
|
---|
| 1308 | function not_found() {
|
---|
| 1309 | log_app('Status','404: Not Found');
|
---|
| 1310 | header('Content-Type: text/plain');
|
---|
| 1311 | status_header('404');
|
---|
| 1312 | exit;
|
---|
| 1313 | }
|
---|
| 1314 |
|
---|
| 1315 | /**
|
---|
| 1316 | * Set 'Not Allowed' (405) status header.
|
---|
| 1317 | *
|
---|
| 1318 | * @since 2.2.0
|
---|
| 1319 | */
|
---|
| 1320 | function not_allowed($allow) {
|
---|
| 1321 | log_app('Status','405: Not Allowed');
|
---|
| 1322 | header('Allow: ' . join(',', $allow));
|
---|
| 1323 | status_header('405');
|
---|
| 1324 | exit;
|
---|
| 1325 | }
|
---|
| 1326 |
|
---|
| 1327 | /**
|
---|
| 1328 | * Display Redirect (302) content and set status headers.
|
---|
| 1329 | *
|
---|
| 1330 | * @since 2.3.0
|
---|
| 1331 | */
|
---|
| 1332 | function redirect($url) {
|
---|
| 1333 |
|
---|
| 1334 | log_app('Status','302: Redirect');
|
---|
| 1335 | $escaped_url = esc_attr($url);
|
---|
| 1336 | $content = <<<EOD
|
---|
| 1337 | <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
|
---|
| 1338 | <html>
|
---|
| 1339 | <head>
|
---|
| 1340 | <title>302 Found</title>
|
---|
| 1341 | </head>
|
---|
| 1342 | <body>
|
---|
| 1343 | <h1>Found</h1>
|
---|
| 1344 | <p>The document has moved <a href="$escaped_url">here</a>.</p>
|
---|
| 1345 | </body>
|
---|
| 1346 | </html>
|
---|
| 1347 |
|
---|
| 1348 | EOD;
|
---|
| 1349 | header('HTTP/1.1 302 Moved');
|
---|
| 1350 | header('Content-Type: text/html');
|
---|
| 1351 | header('Location: ' . $url);
|
---|
| 1352 | echo $content;
|
---|
| 1353 | exit;
|
---|
| 1354 |
|
---|
| 1355 | }
|
---|
| 1356 |
|
---|
| 1357 | /**
|
---|
| 1358 | * Set 'Client Error' (400) status header.
|
---|
| 1359 | *
|
---|
| 1360 | * @since 2.2.0
|
---|
| 1361 | */
|
---|
| 1362 | function client_error($msg = 'Client Error') {
|
---|
| 1363 | log_app('Status','400: Client Error');
|
---|
| 1364 | header('Content-Type: text/plain');
|
---|
| 1365 | status_header('400');
|
---|
| 1366 | exit;
|
---|
| 1367 | }
|
---|
| 1368 |
|
---|
| 1369 | /**
|
---|
| 1370 | * Set created status headers (201).
|
---|
| 1371 | *
|
---|
| 1372 | * Sets the 'content-type', 'content-location', and 'location'.
|
---|
| 1373 | *
|
---|
| 1374 | * @since 2.2.0
|
---|
| 1375 | */
|
---|
| 1376 | function created($post_ID, $content, $post_type = 'post') {
|
---|
| 1377 | log_app('created()::$post_ID',"$post_ID, $post_type");
|
---|
| 1378 | $edit = $this->get_entry_url($post_ID);
|
---|
| 1379 | switch($post_type) {
|
---|
| 1380 | case 'post':
|
---|
| 1381 | $ctloc = $this->get_entry_url($post_ID);
|
---|
| 1382 | break;
|
---|
| 1383 | case 'attachment':
|
---|
| 1384 | $edit = $this->app_base . "attachments/$post_ID";
|
---|
| 1385 | break;
|
---|
| 1386 | }
|
---|
| 1387 | header("Content-Type: $this->ATOM_CONTENT_TYPE");
|
---|
| 1388 | if(isset($ctloc))
|
---|
| 1389 | header('Content-Location: ' . $ctloc);
|
---|
| 1390 | header('Location: ' . $edit);
|
---|
| 1391 | status_header('201');
|
---|
| 1392 | echo $content;
|
---|
| 1393 | exit;
|
---|
| 1394 | }
|
---|
| 1395 |
|
---|
| 1396 | /**
|
---|
| 1397 | * Set 'Auth Required' (401) headers.
|
---|
| 1398 | *
|
---|
| 1399 | * @since 2.2.0
|
---|
| 1400 | *
|
---|
| 1401 | * @param string $msg Status header content and HTML content.
|
---|
| 1402 | */
|
---|
| 1403 | function auth_required($msg) {
|
---|
| 1404 | log_app('Status','401: Auth Required');
|
---|
| 1405 | nocache_headers();
|
---|
| 1406 | header('WWW-Authenticate: Basic realm="WordPress Atom Protocol"');
|
---|
| 1407 | header("HTTP/1.1 401 $msg");
|
---|
| 1408 | header('Status: 401 ' . $msg);
|
---|
| 1409 | header('Content-Type: text/html');
|
---|
| 1410 | $content = <<<EOD
|
---|
| 1411 | <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
|
---|
| 1412 | <html>
|
---|
| 1413 | <head>
|
---|
| 1414 | <title>401 Unauthorized</title>
|
---|
| 1415 | </head>
|
---|
| 1416 | <body>
|
---|
| 1417 | <h1>401 Unauthorized</h1>
|
---|
| 1418 | <p>$msg</p>
|
---|
| 1419 | </body>
|
---|
| 1420 | </html>
|
---|
| 1421 |
|
---|
| 1422 | EOD;
|
---|
| 1423 | echo $content;
|
---|
| 1424 | exit;
|
---|
| 1425 | }
|
---|
| 1426 |
|
---|
| 1427 | /**
|
---|
| 1428 | * Display XML and set headers with content type.
|
---|
| 1429 | *
|
---|
| 1430 | * @since 2.2.0
|
---|
| 1431 | *
|
---|
| 1432 | * @param string $xml Display feed content.
|
---|
| 1433 | * @param string $ctype Optional, default is 'atom+xml'. Feed content type.
|
---|
| 1434 | */
|
---|
| 1435 | function output($xml, $ctype = 'application/atom+xml') {
|
---|
| 1436 | status_header('200');
|
---|
| 1437 | $xml = '<?xml version="1.0" encoding="' . strtolower(get_option('blog_charset')) . '"?>'."\n".$xml;
|
---|
| 1438 | header('Connection: close');
|
---|
| 1439 | header('Content-Length: '. strlen($xml));
|
---|
| 1440 | header('Content-Type: ' . $ctype);
|
---|
| 1441 | header('Content-Disposition: attachment; filename=atom.xml');
|
---|
| 1442 | header('Date: '. date('r'));
|
---|
| 1443 | if($this->do_output)
|
---|
| 1444 | echo $xml;
|
---|
| 1445 | log_app('function', "output:\n$xml");
|
---|
| 1446 | exit;
|
---|
| 1447 | }
|
---|
| 1448 |
|
---|
| 1449 | /**
|
---|
| 1450 | * Sanitize content for database usage.
|
---|
| 1451 | *
|
---|
| 1452 | * @since 2.2.0
|
---|
| 1453 | *
|
---|
| 1454 | * @param array $array Sanitize array and multi-dimension array.
|
---|
| 1455 | */
|
---|
| 1456 | function escape(&$array) {
|
---|
| 1457 | global $wpdb;
|
---|
| 1458 |
|
---|
| 1459 | foreach ($array as $k => $v) {
|
---|
| 1460 | if (is_array($v)) {
|
---|
| 1461 | $this->escape($array[$k]);
|
---|
| 1462 | } else if (is_object($v)) {
|
---|
| 1463 | //skip
|
---|
| 1464 | } else {
|
---|
| 1465 | $array[$k] = $wpdb->escape($v);
|
---|
| 1466 | }
|
---|
| 1467 | }
|
---|
| 1468 | }
|
---|
| 1469 |
|
---|
| 1470 | /**
|
---|
| 1471 | * Access credential through various methods and perform login.
|
---|
| 1472 | *
|
---|
| 1473 | * @since 2.2.0
|
---|
| 1474 | *
|
---|
| 1475 | * @return bool
|
---|
| 1476 | */
|
---|
| 1477 | function authenticate() {
|
---|
| 1478 | log_app("authenticate()",print_r($_ENV, true));
|
---|
| 1479 |
|
---|
| 1480 | // if using mod_rewrite/ENV hack
|
---|
| 1481 | // http://www.besthostratings.com/articles/http-auth-php-cgi.html
|
---|
| 1482 | if(isset($_SERVER['HTTP_AUTHORIZATION'])) {
|
---|
| 1483 | list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) =
|
---|
| 1484 | explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));
|
---|
| 1485 | } else if (isset($_SERVER['REDIRECT_REMOTE_USER'])) {
|
---|
| 1486 | // Workaround for setups that do not forward HTTP_AUTHORIZATION
|
---|
| 1487 | // See http://trac.wordpress.org/ticket/7361
|
---|
| 1488 | list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) =
|
---|
| 1489 | explode(':', base64_decode(substr($_SERVER['REDIRECT_REMOTE_USER'], 6)));
|
---|
| 1490 | }
|
---|
| 1491 |
|
---|
| 1492 | // If Basic Auth is working...
|
---|
| 1493 | if(isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
|
---|
| 1494 | log_app("Basic Auth",$_SERVER['PHP_AUTH_USER']);
|
---|
| 1495 | }
|
---|
| 1496 |
|
---|
| 1497 | $user = wp_authenticate($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']);
|
---|
| 1498 | if ( $user && !is_wp_error($user) ) {
|
---|
| 1499 | wp_set_current_user($user->ID);
|
---|
| 1500 | log_app("authenticate()", $user->user_login);
|
---|
| 1501 | return true;
|
---|
| 1502 | }
|
---|
| 1503 |
|
---|
| 1504 | return false;
|
---|
| 1505 | }
|
---|
| 1506 |
|
---|
| 1507 | /**
|
---|
| 1508 | * Retrieve accepted content types.
|
---|
| 1509 | *
|
---|
| 1510 | * @since 2.2.0
|
---|
| 1511 | *
|
---|
| 1512 | * @param array $types Optional. Content Types.
|
---|
| 1513 | * @return string
|
---|
| 1514 | */
|
---|
| 1515 | function get_accepted_content_type($types = null) {
|
---|
| 1516 |
|
---|
| 1517 | if(!isset($types)) {
|
---|
| 1518 | $types = $this->media_content_types;
|
---|
| 1519 | }
|
---|
| 1520 |
|
---|
| 1521 | if(!isset($_SERVER['CONTENT_LENGTH']) || !isset($_SERVER['CONTENT_TYPE'])) {
|
---|
| 1522 | $this->length_required();
|
---|
| 1523 | }
|
---|
| 1524 |
|
---|
| 1525 | $type = $_SERVER['CONTENT_TYPE'];
|
---|
| 1526 | list($type,$subtype) = explode('/',$type);
|
---|
| 1527 | list($subtype) = explode(";",$subtype); // strip MIME parameters
|
---|
| 1528 | log_app("get_accepted_content_type", "type=$type, subtype=$subtype");
|
---|
| 1529 |
|
---|
| 1530 | foreach($types as $t) {
|
---|
| 1531 | list($acceptedType,$acceptedSubtype) = explode('/',$t);
|
---|
| 1532 | if($acceptedType == '*' || $acceptedType == $type) {
|
---|
| 1533 | if($acceptedSubtype == '*' || $acceptedSubtype == $subtype)
|
---|
| 1534 | return $type . "/" . $subtype;
|
---|
| 1535 | }
|
---|
| 1536 | }
|
---|
| 1537 |
|
---|
| 1538 | $this->invalid_media();
|
---|
| 1539 | }
|
---|
| 1540 |
|
---|
| 1541 | /**
|
---|
| 1542 | * Process conditionals for posts.
|
---|
| 1543 | *
|
---|
| 1544 | * @since 2.2.0
|
---|
| 1545 | */
|
---|
| 1546 | function process_conditionals() {
|
---|
| 1547 |
|
---|
| 1548 | if(empty($this->params)) return;
|
---|
| 1549 | if($_SERVER['REQUEST_METHOD'] == 'DELETE') return;
|
---|
| 1550 |
|
---|
| 1551 | switch($this->params[0]) {
|
---|
| 1552 | case $this->ENTRY_PATH:
|
---|
| 1553 | global $post;
|
---|
| 1554 | $post = wp_get_single_post($this->params[1]);
|
---|
| 1555 | $wp_last_modified = get_post_modified_time('D, d M Y H:i:s', true);
|
---|
| 1556 | $post = NULL;
|
---|
| 1557 | break;
|
---|
| 1558 | case $this->ENTRIES_PATH:
|
---|
| 1559 | $wp_last_modified = mysql2date('D, d M Y H:i:s', get_lastpostmodified('GMT'), 0).' GMT';
|
---|
| 1560 | break;
|
---|
| 1561 | default:
|
---|
| 1562 | return;
|
---|
| 1563 | }
|
---|
| 1564 | $wp_etag = md5($wp_last_modified);
|
---|
| 1565 | @header("Last-Modified: $wp_last_modified");
|
---|
| 1566 | @header("ETag: $wp_etag");
|
---|
| 1567 |
|
---|
| 1568 | // Support for Conditional GET
|
---|
| 1569 | if (isset($_SERVER['HTTP_IF_NONE_MATCH']))
|
---|
| 1570 | $client_etag = stripslashes($_SERVER['HTTP_IF_NONE_MATCH']);
|
---|
| 1571 | else
|
---|
| 1572 | $client_etag = false;
|
---|
| 1573 |
|
---|
| 1574 | $client_last_modified = trim( $_SERVER['HTTP_IF_MODIFIED_SINCE']);
|
---|
| 1575 | // If string is empty, return 0. If not, attempt to parse into a timestamp
|
---|
| 1576 | $client_modified_timestamp = $client_last_modified ? strtotime($client_last_modified) : 0;
|
---|
| 1577 |
|
---|
| 1578 | // Make a timestamp for our most recent modification...
|
---|
| 1579 | $wp_modified_timestamp = strtotime($wp_last_modified);
|
---|
| 1580 |
|
---|
| 1581 | if ( ($client_last_modified && $client_etag) ?
|
---|
| 1582 | (($client_modified_timestamp >= $wp_modified_timestamp) && ($client_etag == $wp_etag)) :
|
---|
| 1583 | (($client_modified_timestamp >= $wp_modified_timestamp) || ($client_etag == $wp_etag)) ) {
|
---|
| 1584 | status_header( 304 );
|
---|
| 1585 | exit;
|
---|
| 1586 | }
|
---|
| 1587 | }
|
---|
| 1588 |
|
---|
| 1589 | /**
|
---|
| 1590 | * Convert RFC3339 time string to timestamp.
|
---|
| 1591 | *
|
---|
| 1592 | * @since 2.3.0
|
---|
| 1593 | *
|
---|
| 1594 | * @param string $str String to time.
|
---|
| 1595 | * @return bool|int false if format is incorrect.
|
---|
| 1596 | */
|
---|
| 1597 | function rfc3339_str2time($str) {
|
---|
| 1598 |
|
---|
| 1599 | $match = false;
|
---|
| 1600 | 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))
|
---|
| 1601 | return false;
|
---|
| 1602 |
|
---|
| 1603 | if($match[3] == 'Z')
|
---|
| 1604 | $match[3] == '+0000';
|
---|
| 1605 |
|
---|
| 1606 | return strtotime($match[1] . " " . $match[2] . " " . $match[3]);
|
---|
| 1607 | }
|
---|
| 1608 |
|
---|
| 1609 | /**
|
---|
| 1610 | * Retrieve published time to display in XML.
|
---|
| 1611 | *
|
---|
| 1612 | * @since 2.3.0
|
---|
| 1613 | *
|
---|
| 1614 | * @param string $published Time string.
|
---|
| 1615 | * @return string
|
---|
| 1616 | */
|
---|
| 1617 | function get_publish_time($published) {
|
---|
| 1618 |
|
---|
| 1619 | $pubtime = $this->rfc3339_str2time($published);
|
---|
| 1620 |
|
---|
| 1621 | if(!$pubtime) {
|
---|
| 1622 | return array(current_time('mysql'),current_time('mysql',1));
|
---|
| 1623 | } else {
|
---|
| 1624 | return array(date("Y-m-d H:i:s", $pubtime), gmdate("Y-m-d H:i:s", $pubtime));
|
---|
| 1625 | }
|
---|
| 1626 | }
|
---|
| 1627 |
|
---|
| 1628 | }
|
---|
| 1629 |
|
---|
| 1630 | /**
|
---|
| 1631 | * AtomServer
|
---|
| 1632 | * @var AtomServer
|
---|
| 1633 | * @global object $server
|
---|
| 1634 | */
|
---|
| 1635 | $server = new AtomServer();
|
---|
| 1636 | $server->handle_request();
|
---|
| 1637 |
|
---|
| 1638 | ?>
|
---|