/** * SyndicatedPost::freshness: check whether post is a new post to be * inserted, a previously syndicated post that needs to be updated to * match the latest revision, or a previously syndicated post that is * still up-to-date. * * @return int A status code representing the freshness of the post * -1 = post already syndicated; has a revision that needs to be stored, but not updated to * 0 = post already syndicated; no update needed * 1 = post already syndicated, but needs to be updated to latest * 2 = post has not yet been syndicated; needs to be created */ function freshness($format = 'number') { global $wpdb; if ($this->filtered()) { // This should never happen. FeedWordPress::critical_bug('SyndicatedPost', $this, __LINE__, __FILE__); } if (is_null($this->_freshness)) { // Not yet checked and cached. $guid = $this->post['guid']; $eguid = esc_sql($this->post['guid']); $q = new WP_Query(array('fields' => '_synfresh', 'ignore_sticky_posts' => true, 'guid' => $guid)); $old_post = NULL; if ($q->have_posts()) { while ($q->have_posts()) { $q->the_post(); $old_post = $q->post; } } if (is_null($old_post)) { // No post with this guid FeedWordPress::diagnostic('feed_items:freshness', 'Item [' . $guid . '] "' . $this->entry->get_title() . '" is a NEW POST.'); $this->_wp_id = NULL; $this->_freshness = 2; // New content } else { // Presume there is nothing new until we find // something new. $updated = false; $live = false; // Pull the list of existing revisions to get // timestamps. $revisions = wp_get_post_revisions($old_post->ID); foreach ($revisions as $rev) { $revisions_ts[] = mysql2date('G', $rev->post_modified_gmt); } $revisions_ts[] = mysql2date('G', $old_post->post_modified_gmt); $last_rev_ts = end($revisions_ts); $updated_ts = $this->updated(true, NULL); // If we have an explicit updated timestamp, // check that against existing stamps. if (!is_null($updated_ts)) { $updated = !in_array($updated_ts, $revisions_ts); // If this a newer revision, make it go // live. If an older one, just record // the contents. $live = ($updated and $updated_ts > $last_rev_ts); } // This is a revision we haven't seen before, judging by the date. $updatedReason = NULL; if ($updated) { $updatedReason = preg_replace("/\\s+/", " ", 'has been marked with a new timestamp (' . date('Y-m-d H:i:s', $updated_ts) . " > " . date('Y-m-d H:i:s', $last_rev_ts) . ')'); // The date does not indicate a new revision, so // let's check the hash. } else { // Or the hash... $hash = $this->update_hash(); $seen = $this->stored_hashes($old_post->ID); if (count($seen) > 0) { $updated = !in_array($hash, $seen); // Not seen yet? } else { $updated = true; // Can't find syndication meta-data } if ($updated and FeedWordPress::diagnostic_on('feed_items:freshness:reasons')) { // In the absence of definitive // timestamp information, we // just have to assume that a // hash we haven't seen before // is a newer version. $live = true; $updatedReason = ' has a not-yet-seen update hash: ' . MyPHP::val($hash) . ' not in {' . implode(", ", array_map(array('FeedWordPress', 'val'), $seen)) . '}. Basis: ' . MyPHP::val(array_keys($this->update_hash(false))); } } $frozen = false; if ($updated) { // Ignore if the post is frozen $frozen = 'yes' == $this->link->setting('freeze updates', 'freeze_updates', NULL); if (!$frozen) { $frozen_values = get_post_custom_values('_syndication_freeze_updates', $old_post->ID); $frozen = (count($frozen_values) > 0 and 'yes' == $frozen_values[0]); if ($frozen) { $updatedReason = ' IS BLOCKED FROM BEING UPDATED BY A UPDATE LOCK ON THIS POST, EVEN THOUGH IT ' . $updatedReason; } } else { $updatedReason = ' IS BLOCKED FROM BEING UPDATED BY A FEEDWORDPRESS UPDATE LOCK, EVEN THOUGH IT ' . $updatedReason; } } $live = ($live and !$frozen); if ($updated) { FeedWordPress::diagnostic('feed_items:freshness', 'Item [' . $guid . '] "' . $this->entry->get_title() . '" is an update of an existing post.'); if (!is_null($updatedReason)) { $updatedReason = preg_replace('/\\s+/', ' ', $updatedReason); FeedWordPress::diagnostic('feed_items:freshness:reasons', 'Item [' . $guid . '] "' . $this->entry->get_title() . '" ' . $updatedReason); } $this->_freshness = apply_filters('syndicated_item_freshness', $live ? 1 : -1, $updated, $frozen, $updated_ts, $last_rev_ts, $this); $this->_wp_id = $old_post->ID; $this->_wp_post = $old_post; // We want this to keep a running list of all the // processed update hashes. $this->post['meta']['syndication_item_hash'] = array_merge($this->stored_hashes(), array($this->update_hash())); } else { FeedWordPress::diagnostic('feed_items:freshness', 'Item [' . $guid . '] "' . $this->entry->get_title() . '" is a duplicate of an existing post.'); $this->_freshness = 0; // Same old, same old $this->_wp_id = $old_post->ID; } } } switch ($format) { case 'status': switch ($this->_freshness) { case -1: $ret = 'stored'; break; case 0: $ret = NULL; break; case 1: $ret = 'updated'; break; case 2: default: $ret = 'new'; break; } break; case 'number': default: $ret = $this->_freshness; } return $ret; }
function diagnostic($level, $out, $persist = NULL, $since = NULL, $mostRecent = NULL) { global $feedwordpress_admin_footer; $output = get_option('feedwordpress_diagnostics_output', array()); $dlog = get_option('feedwordpress_diagnostics_log', array()); $diagnostic_nesting = count(explode(":", $level)); if (FeedWordPress::diagnostic_on($level)) { foreach ($output as $method) { switch ($method) { case 'echo': if (!FeedWordPress::update_requested()) { echo "<div><pre><strong>Diag" . str_repeat('====', $diagnostic_nesting - 1) . '|</strong> ' . $out . "</pre></div>"; } break; case 'echo_in_cronjob': if (FeedWordPress::update_requested()) { echo FeedWordPress::log_prefix() . " " . $out . "\n"; } break; case 'admin_footer': $feedwordpress_admin_footer[] = $out; break; case 'error_log': error_log(FeedWordPress::log_prefix() . ' ' . $out); break; case 'email': if (is_null($persist)) { $sect = 'occurrent'; $hook = isset($dlog['mesg'][$sect]) ? count($dlog['mesg'][$sect]) : 0; $line = array("Time" => time(), "Message" => $out); } else { $sect = 'persistent'; $hook = md5($level . "\n" . $persist); $line = array("Since" => $since, "Message" => $out, "Most Recent" => $mostRecent); } if (!isset($dlog['mesg'])) { $dlog['mesg'] = array(); } if (!isset($dlog['mesg'][$sect])) { $dlog['mesg'][$sect] = array(); } $dlog['mesg'][$sect][$hook] = $line; } } } update_option('feedwordpress_diagnostics_log', $dlog); }
function diagnostic($level, $out) { global $feedwordpress_admin_footer; $output = get_option('feedwordpress_diagnostics_output', array()); $diagnostic_nesting = count(explode(":", $level)); if (FeedWordPress::diagnostic_on($level)) { foreach ($output as $method) { switch ($method) { case 'echo': echo "<div><pre><strong>Diag" . str_repeat('====', $diagnostic_nesting - 1) . '|</strong> ' . esc_html($out) . "</pre></div>"; break; case 'admin_footer': $feedwordpress_admin_footer[] = $out; break; case 'error_log': // error_log('[feedwordpress]' . $out); break; } } } }
/** * SyndicatedPost::freshness: check whether post is a new post to be * inserted, a previously syndicated post that needs to be updated to * match the latest revision, or a previously syndicated post that is * still up-to-date. * * @return int A status code representing the freshness of the post * 0 = post already syndicated; no update needed * 1 = post already syndicated, but needs to be updated to latest * 2 = post has not yet been syndicated; needs to be created */ function freshness() { global $wpdb; if ($this->filtered()) { // This should never happen. FeedWordPress::critical_bug('SyndicatedPost', $this, __LINE__, __FILE__); } if (is_null($this->_freshness)) { // Not yet checked and cached. $guid = $this->post['guid']; $eguid = $wpdb->escape($this->post['guid']); $q = new WP_Query(array('fields' => '_synfresh', 'ignore_sticky_posts' => true, 'guid' => $guid)); $old_post = NULL; if ($q->have_posts()) { while ($q->have_posts()) { $q->the_post(); $old_post = $q->post; } } if (is_null($old_post)) { // No post with this guid FeedWordPress::diagnostic('feed_items:freshness', 'Item [' . $guid . '] "' . $this->entry->get_title() . '" is a NEW POST.'); $this->_wp_id = NULL; $this->_freshness = 2; // New content } else { preg_match('/([0-9]+)-([0-9]+)-([0-9]+) ([0-9]+):([0-9]+):([0-9]+)/', $old_post->post_modified_gmt, $backref); $last_rev_ts = gmmktime($backref[4], $backref[5], $backref[6], $backref[2], $backref[3], $backref[1]); $updated_ts = $this->updated(true, NULL); // Check timestamps... $updated = (!is_null($updated_ts) and $updated_ts > $last_rev_ts); $updatedReason = NULL; if ($updated) { $updatedReason = preg_replace("/\\s+/", " ", 'has been marked with a new timestamp (' . date('Y-m-d H:i:s', $updated_ts) . " > " . date('Y-m-d H:i:s', $last_rev_ts) . ')'); } else { // Or the hash... $hash = $this->update_hash(); $seen = $this->stored_hashes($old_post->ID); if (count($seen) > 0) { $updated = !in_array($hash, $seen); // Not seen yet? } else { $updated = true; // Can't find syndication meta-data } if ($updated and FeedWordPress::diagnostic_on('feed_items:freshness:reasons')) { $updatedReason = ' has a not-yet-seen update hash: ' . FeedWordPress::val($hash) . ' not in {' . implode(", ", array_map(array('FeedWordPress', 'val'), $seen)) . '}. Basis: ' . FeedWordPress::val(array_keys($this->update_hash(false))); } } $frozen = false; if ($updated) { // Ignore if the post is frozen $frozen = 'yes' == $this->link->setting('freeze updates', 'freeze_updates', NULL); if (!$frozen) { $frozen_values = get_post_custom_values('_syndication_freeze_updates', $old_post->ID); $frozen = (count($frozen_values) > 0 and 'yes' == $frozen_values[0]); if ($frozen) { $updatedReason = ' IS BLOCKED FROM BEING UPDATED BY A UPDATE LOCK ON THIS POST, EVEN THOUGH IT ' . $updatedReason; } } else { $updatedReason = ' IS BLOCKED FROM BEING UPDATED BY A FEEDWORDPRESS UPDATE LOCK, EVEN THOUGH IT ' . $updatedReason; } } $updated = ($updated and !$frozen); if ($updated) { FeedWordPress::diagnostic('feed_items:freshness', 'Item [' . $guid . '] "' . $this->entry->get_title() . '" is an update of an existing post.'); if (!is_null($updatedReason)) { $updatedReason = preg_replace('/\\s+/', ' ', $updatedReason); FeedWordPress::diagnostic('feed_items:freshness:reasons', 'Item [' . $guid . '] "' . $this->entry->get_title() . '" ' . $updatedReason); } $this->_freshness = 1; // Updated content $this->_wp_id = $old_post->ID; $this->_wp_post = $old_post; // We want this to keep a running list of all the // processed update hashes. $this->post['meta']['syndication_item_hash'] = array_merge($this->stored_hashes(), array($this->update_hash())); } else { FeedWordPress::diagnostic('feed_items:freshness', 'Item [' . $guid . '] "' . $this->entry->get_title() . '" is a duplicate of an existing post.'); $this->_freshness = 0; // Same old, same old $this->_wp_id = $old_post->ID; } } } return $this->_freshness; }
function feedwordpress_add_post_edit_controls() { global $feedwordpress; global $inspectPostMeta; // Put in Manual Editing checkbox add_action('add_meta_boxes', 'feedwordpress_post_add_meta_boxes', 10, 2); add_filter('user_can_richedit', array($feedwordpress, 'user_can_richedit'), 1000, 1); if (FeedWordPress::diagnostic_on('syndicated_posts:static_meta_data')) { $inspectPostMeta = new InspectPostMeta(); } }