function test_does_set_silent_flag_true_while_importing()
 {
     Jetpack_Sync_Settings::set_importing(true);
     $this->factory->post->create();
     $this->sender->do_sync();
     $this->assertObjectHasAttribute('silent', $this->server_event_storage->get_most_recent_event('wp_insert_post'));
     $this->assertTrue($this->server_event_storage->get_most_recent_event('wp_insert_post')->silent);
 }
 function filter_blacklisted_post_types($args)
 {
     $post = $args[1];
     if (in_array($post->post_type, Jetpack_Sync_Settings::get_setting('post_types_blacklist'))) {
         return false;
     }
     return $args;
 }
 /**
  * Should we allow the meta key to be synced?
  *
  * @param string $meta_key The meta key.
  *
  * @return bool
  */
 function is_meta_key_allowed($meta_key)
 {
     if ('_' === $meta_key[0] && !in_array($meta_key, Jetpack_Sync_Defaults::$default_whitelist_meta_keys) && !wp_startswith($meta_key, '_wpas_skip_')) {
         return false;
     }
     if (in_array($meta_key, Jetpack_Sync_Settings::get_setting('meta_blacklist'))) {
         return false;
     }
     return true;
 }
 function test_settings_disable_enqueue_and_clears_queue()
 {
     $event = $this->server_event_storage->reset();
     // create a post - this will end up in the queue before data is sent
     $post_id = $this->factory->post->create();
     $this->assertTrue($this->listener->get_sync_queue()->size() > 0);
     Jetpack_Sync_Settings::update_settings(array('disable' => 1));
     // generating posts should no longer affect queue size
     $this->assertEquals(0, $this->listener->get_sync_queue()->size());
     $post_id = $this->factory->post->create();
     $this->assertEquals(0, $this->listener->get_sync_queue()->size());
     // syncing sends no data
     $this->sender->do_sync();
     $this->assertFalse($this->server_event_storage->get_most_recent_event('wp_insert_post'));
     Jetpack_Sync_Settings::update_settings(array('disable' => 0));
 }
 function continue_enqueuing($configs = null, $enqueue_status = null)
 {
     if (!$this->is_started() || $this->get_status_option('queue_finished')) {
         return;
     }
     // if full sync queue is full, don't enqueue more items
     $max_queue_size_full_sync = Jetpack_Sync_Settings::get_setting('max_queue_size_full_sync');
     $full_sync_queue = new Jetpack_Sync_Queue('full_sync');
     $available_queue_slots = $max_queue_size_full_sync - $full_sync_queue->size();
     if ($available_queue_slots <= 0) {
         return;
     } else {
         $remaining_items_to_enqueue = min(Jetpack_Sync_Settings::get_setting('max_enqueue_full_sync'), $available_queue_slots);
     }
     if (!$configs) {
         $configs = $this->get_config();
     }
     if (!$enqueue_status) {
         $enqueue_status = $this->get_enqueue_status();
     }
     foreach (Jetpack_Sync_Modules::get_modules() as $module) {
         $module_name = $module->name();
         // skip module if not configured for this sync or module is done
         if (!isset($configs[$module_name]) || !$configs[$module_name] || !$enqueue_status[$module_name] || true === $enqueue_status[$module_name][2]) {
             continue;
         }
         list($items_enqueued, $next_enqueue_state) = $module->enqueue_full_sync_actions($configs[$module_name], $remaining_items_to_enqueue, $enqueue_status[$module_name][2]);
         $enqueue_status[$module_name][2] = $next_enqueue_state;
         // if items were processed, subtract them from the limit
         if (!is_null($items_enqueued) && $items_enqueued > 0) {
             $enqueue_status[$module_name][1] += $items_enqueued;
             $remaining_items_to_enqueue -= $items_enqueued;
         }
         // stop processing if we've reached our limit of items to enqueue
         if (0 >= $remaining_items_to_enqueue) {
             $this->set_enqueue_status($enqueue_status);
             return;
         }
     }
     $this->set_enqueue_status($enqueue_status);
     // setting autoload to true means that it's faster to check whether we should continue enqueuing
     $this->update_status_option('queue_finished', time(), true);
     /**
      * Fires when a full sync ends. This action is serialized
      * and sent to the server with checksums so that we can confirm the
      * sync was successful.
      *
      * @since 4.2.0
      */
     do_action('jetpack_full_sync_end', '');
 }
 public function posts_checksum($min_id = null, $max_id = null)
 {
     global $wpdb;
     return $this->table_checksum($wpdb->posts, Jetpack_Sync_Defaults::$default_post_checksum_columns, 'ID', Jetpack_Sync_Settings::get_blacklisted_post_types_sql(), $min_id, $max_id);
 }
 static function schedule_full_sync($modules = null, $time_offset = 1)
 {
     if (!self::sync_allowed()) {
         return false;
     }
     if (Jetpack_Sync_Settings::get_setting('avoid_wp_cron')) {
         // run queuing inline
         set_time_limit(0);
         self::do_full_sync($modules);
         return false;
     }
     if (self::is_scheduled_full_sync()) {
         self::unschedule_all_full_syncs();
     }
     if ($modules) {
         wp_schedule_single_event(time() + $time_offset, 'jetpack_sync_full', array($modules));
     } else {
         wp_schedule_single_event(time() + $time_offset, 'jetpack_sync_full');
     }
     if ($time_offset === 1) {
         spawn_cron();
     }
     return true;
 }
 public function expand_post_ids($args)
 {
     $post_ids = $args[0];
     $posts = array_filter(array_map(array('WP_Post', 'get_instance'), $post_ids));
     $posts = array_map(array($this, 'filter_post_content_and_add_links'), $posts);
     $posts = array_values($posts);
     // reindex in case posts were deleted
     return array($posts, $this->get_metadata($post_ids, 'post', Jetpack_Sync_Settings::get_setting('post_meta_whitelist')), $this->get_term_relationships($post_ids));
 }
 public function maybe_sync_callables()
 {
     if (!is_admin() || Jetpack_Sync_Settings::is_doing_cron()) {
         return;
     }
     if (get_transient(self::CALLABLES_AWAIT_TRANSIENT_NAME)) {
         return;
     }
     set_transient(self::CALLABLES_AWAIT_TRANSIENT_NAME, microtime(true), Jetpack_Sync_Defaults::$default_sync_callables_wait_time);
     $callables = $this->get_all_callables();
     if (empty($callables)) {
         return;
     }
     $callable_checksums = (array) get_option(self::CALLABLES_CHECKSUM_OPTION_NAME, array());
     // only send the callables that have changed
     foreach ($callables as $name => $value) {
         $checksum = $this->get_check_sum($value);
         // explicitly not using Identical comparison as get_option returns a string
         if (!$this->still_valid_checksum($callable_checksums, $name, $checksum) && !is_null($value)) {
             /**
              * Tells the client to sync a callable (aka function) to the server
              *
              * @since 4.2.0
              *
              * @param string The name of the callable
              * @param mixed The value of the callable
              */
             do_action('jetpack_sync_callable', $name, $value);
             $callable_checksums[$name] = $checksum;
         } else {
             $callable_checksums[$name] = $checksum;
         }
     }
     update_option(self::CALLABLES_CHECKSUM_OPTION_NAME, $callable_checksums);
 }
 static function set_is_sending($is_sending)
 {
     self::$is_sending = $is_sending;
 }
 private function enable_queue_rate_limit()
 {
     $this->queue_rate_limit = Jetpack_Sync_Settings::get_setting('queue_max_writes_sec');
     $this->items_added_since_last_pause = 0;
     $this->last_pause_time = microtime(true);
     add_action('jpsq_item_added', array($this, 'queue_item_added'));
     add_action('jpsq_items_added', array($this, 'queue_items_added'));
 }
Example #12
0
 /**
  * Are likes visible in this context?
  *
  * Some of this code was taken and modified from sharing_display() to ensure
  * similar logic and filters apply here, too.
  */
 function is_likes_visible()
 {
     require_once JETPACK__PLUGIN_DIR . '/sync/class.jetpack-sync-settings.php';
     if (Jetpack_Sync_Settings::is_syncing()) {
         return false;
     }
     global $post, $wp_current_filter;
     // Used to apply 'sharing_show' filter
     // @todo: Remove this block when 4.5 is the minimum
     global $wp_version;
     $comment_popup = false;
     if (version_compare($wp_version, '4.5-alpha', '<=')) {
         $comment_popup = is_comments_popup();
     }
     // End 4.5 conditional block.
     // Never show on feeds or previews
     if (is_feed() || is_preview() || $comment_popup) {
         // @todo: Remove $comment_popup when 4.5 is minimum.
         $enabled = false;
         // Not a feed or preview, so what is it?
     } else {
         if (in_the_loop()) {
             // If in the loop, check if the current post is likeable
             $enabled = $this->is_post_likeable();
         } else {
             // Otherwise, check and see if likes are enabled sitewide
             $enabled = $this->is_enabled_sitewide();
         }
         if (post_password_required()) {
             $enabled = false;
         }
         if (in_array('get_the_excerpt', (array) $wp_current_filter)) {
             $enabled = false;
         }
         // Sharing Setting Overrides ****************************************
         // Single post including custom post types
         if (is_single()) {
             if (!$this->is_single_post_enabled($post->post_type)) {
                 $enabled = false;
             }
             // Single page
         } elseif (is_page() && !is_front_page()) {
             if (!$this->is_single_page_enabled()) {
                 $enabled = false;
             }
             // Attachment
         } elseif (is_attachment()) {
             if (!$this->is_attachment_enabled()) {
                 $enabled = false;
             }
             // All other loops
         } elseif (!$this->is_index_enabled()) {
             $enabled = false;
         }
     }
     if (is_object($post)) {
         // Check that the post is a public, published post.
         if ('attachment' == $post->post_type) {
             $post_status = get_post_status($post->post_parent);
         } else {
             $post_status = $post->post_status;
         }
         if ('publish' != $post_status) {
             $enabled = false;
         }
     }
     // Run through the sharing filters
     /** This filter is documented in modules/sharedaddy/sharing-service.php */
     $enabled = apply_filters('sharing_show', $enabled, $post);
     /**
      * Filters whether the Likes should be visible or not.
      * Allows overwriting the options set in Settings > Sharing.
      *
      * @module likes
      *
      * @since 2.2.0
      *
      * @param bool $enabled Should the Likes be visible?
      */
     return (bool) apply_filters('wpl_is_likes_visible', $enabled);
 }
 function test_full_sync_stops_enqueuing_at_max_queue_size()
 {
     Jetpack_Sync_Settings::update_settings(array('max_queue_size_full_sync' => 2, 'max_enqueue_full_sync' => 10));
     // this should become three items
     $synced_post_ids = $this->factory->post->create_many(25);
     $this->full_sync->start(array('posts' => true));
     // full_sync_start plus 10 posts
     $this->assertEquals(2, $this->sender->get_full_sync_queue()->size());
     // attempting to continue enqueuing shouldn't work because the queue is at max size
     $this->full_sync->continue_enqueuing();
     $this->assertEquals(2, $this->sender->get_full_sync_queue()->size());
     // flush the queue
     $this->sender->do_full_sync();
     $this->assertEquals(0, $this->sender->get_full_sync_queue()->size());
     // continue enqueuing and hit the limit again - 2 more sets of posts (10 and 5)
     $this->full_sync->continue_enqueuing();
     $this->assertEquals(2, $this->sender->get_full_sync_queue()->size());
     $this->sender->do_full_sync();
     // last one - this time just sending full_sync_end
     $this->full_sync->continue_enqueuing();
     $this->assertEquals(1, $this->sender->get_full_sync_queue()->size());
     $this->sender->do_full_sync();
     // full sync is done, continuing should do nothing
     $this->full_sync->continue_enqueuing();
     $this->assertEquals(0, $this->sender->get_full_sync_queue()->size());
 }
 protected function result()
 {
     require_once JETPACK__PLUGIN_DIR . 'sync/class.jetpack-sync-settings.php';
     return Jetpack_Sync_Settings::get_settings();
 }
 static function send_data($data, $codec_name, $sent_timestamp, $queue_id)
 {
     Jetpack::load_xml_rpc_client();
     $query_args = array('sync' => '1', 'codec' => $codec_name, 'timestamp' => $sent_timestamp, 'queue' => $queue_id, 'home' => get_home_url(), 'siteurl' => get_site_url());
     // Has the site opted in to IDC mitigation?
     if (Jetpack::sync_idc_optin()) {
         $query_args['idc'] = true;
     }
     if (Jetpack_Options::get_option('migrate_for_idc', false)) {
         $query_args['migrate_for_idc'] = true;
     }
     $query_args['timeout'] = Jetpack_Sync_Settings::is_doing_cron() ? 30 : 15;
     $url = add_query_arg($query_args, Jetpack::xmlrpc_api_url());
     $rpc = new Jetpack_IXR_Client(array('url' => $url, 'user_id' => JETPACK_MASTER_USER, 'timeout' => $query_args['timeout']));
     $result = $rpc->query('jetpack.syncActions', $data);
     if (!$result) {
         return $rpc->get_jetpack_error();
     }
     $response = $rpc->getResponse();
     // Check if WordPress.com IDC mitigation blocked the sync request
     if (is_array($response) && isset($response['error_code'])) {
         $error_code = $response['error_code'];
         $allowed_idc_error_codes = array('jetpack_url_mismatch', 'jetpack_home_url_mismatch', 'jetpack_site_url_mismatch');
         if (in_array($error_code, $allowed_idc_error_codes)) {
             Jetpack_Options::update_option('sync_error_idc', Jetpack::get_sync_error_idc_option($response));
         }
         return new WP_Error('sync_error_idc', esc_html__('Sync has been blocked from WordPress.com because it would cause an identity crisis', 'jetpack'));
     }
     return $response;
 }
Example #16
0
function sharing_display($text = '', $echo = false)
{
    global $post, $wp_current_filter;
    require_once JETPACK__PLUGIN_DIR . '/sync/class.jetpack-sync-settings.php';
    if (Jetpack_Sync_Settings::is_syncing()) {
        return $text;
    }
    if (empty($post)) {
        return $text;
    }
    if ((is_preview() || is_admin()) && !(defined('DOING_AJAX') && DOING_AJAX)) {
        return $text;
    }
    // Don't output flair on excerpts
    if (in_array('get_the_excerpt', (array) $wp_current_filter)) {
        return $text;
    }
    // Don't allow flair to be added to the_content more than once (prevent infinite loops)
    $done = false;
    foreach ($wp_current_filter as $filter) {
        if ('the_content' == $filter) {
            if ($done) {
                return $text;
            } else {
                $done = true;
            }
        }
    }
    // check whether we are viewing the front page and whether the front page option is checked
    $options = get_option('sharing-options');
    $display_options = $options['global']['show'];
    if (is_front_page() && (is_array($display_options) && !in_array('index', $display_options))) {
        return $text;
    }
    if (is_attachment() && in_array('the_excerpt', (array) $wp_current_filter)) {
        // Many themes run the_excerpt() conditionally on an attachment page, then run the_content().
        // We only want to output the sharing buttons once.  Let's stick with the_content().
        return $text;
    }
    $sharer = new Sharing_Service();
    $global = $sharer->get_global_options();
    $show = false;
    if (!is_feed()) {
        if (is_singular() && in_array(get_post_type(), $global['show'])) {
            $show = true;
        } elseif (in_array('index', $global['show']) && (is_home() || is_front_page() || is_archive() || is_search() || in_array(get_post_type(), $global['show']))) {
            $show = true;
        }
    }
    /**
     * Filter to decide if sharing buttons should be displayed.
     *
     * @module sharedaddy
     *
     * @since 1.1.0
     *
     * @param bool $show Should the sharing buttons be displayed.
     * @param WP_Post $post The post to share.
     */
    $show = apply_filters('sharing_show', $show, $post);
    // Disabled for this post?
    $switched_status = get_post_meta($post->ID, 'sharing_disabled', false);
    if (!empty($switched_status)) {
        $show = false;
    }
    // Private post?
    $post_status = get_post_status($post->ID);
    if ('private' === $post_status) {
        $show = false;
    }
    // Allow to be used on P2 ajax requests for latest posts.
    if (defined('DOING_AJAX') && DOING_AJAX && isset($_REQUEST['action']) && 'get_latest_posts' == $_REQUEST['action']) {
        $show = true;
    }
    $sharing_content = '';
    if ($show) {
        /**
         * Filters the list of enabled Sharing Services.
         *
         * @module sharedaddy
         *
         * @since 2.2.3
         *
         * @param array $sharer->get_blog_services() Array of Sharing Services currently enabled.
         */
        $enabled = apply_filters('sharing_enabled', $sharer->get_blog_services());
        if (count($enabled['all']) > 0) {
            global $post;
            $dir = get_option('text_direction');
            // Wrapper
            $sharing_content .= '<div class="sharedaddy sd-sharing-enabled"><div class="robots-nocontent sd-block sd-social sd-social-' . $global['button_style'] . ' sd-sharing">';
            if ($global['sharing_label'] != '') {
                $sharing_content .= sprintf(apply_filters('jetpack_sharing_headline_html', '<h3 class="sd-title">%s</h3>', $global['sharing_label'], 'sharing'), esc_html($global['sharing_label']));
            }
            $sharing_content .= '<div class="sd-content"><ul>';
            // Visible items
            $visible = '';
            foreach ($enabled['visible'] as $id => $service) {
                // Individual HTML for sharing service
                $visible .= '<li class="share-' . $service->get_class() . '">' . $service->get_display($post) . '</li>';
            }
            $parts = array();
            $parts[] = $visible;
            if (count($enabled['hidden']) > 0) {
                if (count($enabled['visible']) > 0) {
                    $expand = __('More', 'jetpack');
                } else {
                    $expand = __('Share', 'jetpack');
                }
                $parts[] = '<li><a href="#" class="sharing-anchor sd-button share-more"><span>' . $expand . '</span></a></li>';
            }
            if ($dir == 'rtl') {
                $parts = array_reverse($parts);
            }
            $sharing_content .= implode('', $parts);
            $sharing_content .= '<li class="share-end"></li></ul>';
            if (count($enabled['hidden']) > 0) {
                $sharing_content .= '<div class="sharing-hidden"><div class="inner" style="display: none;';
                if (count($enabled['hidden']) == 1) {
                    $sharing_content .= 'width:150px;';
                }
                $sharing_content .= '">';
                if (count($enabled['hidden']) == 1) {
                    $sharing_content .= '<ul style="background-image:none;">';
                } else {
                    $sharing_content .= '<ul>';
                }
                $count = 1;
                foreach ($enabled['hidden'] as $id => $service) {
                    // Individual HTML for sharing service
                    $sharing_content .= '<li class="share-' . $service->get_class() . '">';
                    $sharing_content .= $service->get_display($post);
                    $sharing_content .= '</li>';
                    if ($count % 2 == 0) {
                        $sharing_content .= '<li class="share-end"></li>';
                    }
                    $count++;
                }
                // End of wrapper
                $sharing_content .= '<li class="share-end"></li></ul></div></div>';
            }
            $sharing_content .= '</div></div></div>';
            // Register our JS
            if (defined('JETPACK__VERSION')) {
                $ver = JETPACK__VERSION;
            } else {
                $ver = '20141212';
            }
            wp_register_script('sharing-js', plugin_dir_url(__FILE__) . 'sharing.js', array('jquery'), $ver);
            add_action('wp_footer', 'sharing_add_footer');
        }
    }
    /**
     * Filters the content markup of the Jetpack sharing links
     *
     * @module sharedaddy
     *
     * @since 3.8.0
     *
     * @param string $sharing_content Content markup of the Jetpack sharing links
     */
    $sharing_markup = apply_filters('jetpack_sharing_display_markup', $sharing_content);
    if ($echo) {
        echo $text . $sharing_markup;
    } else {
        return $text . $sharing_markup;
    }
}
 /**
  * Returns the HTML for the related posts section if it's running in the loop or other instances where we don't support related posts.
  *
  * @returns string
  */
 public function get_target_html_unsupported()
 {
     require_once JETPACK__PLUGIN_DIR . '/sync/class.jetpack-sync-settings.php';
     if (Jetpack_Sync_Settings::is_syncing()) {
         return '';
     }
     return "\n\n<!-- Jetpack Related Posts is not supported in this context. -->\n\n";
 }
 static function set_doing_cron($is_doing_cron)
 {
     // set to NULL to revert to WP_IMPORTING, the standard behaviour
     self::$is_doing_cron = $is_doing_cron;
 }
 function test_does_not_publicize_blacklisted_post_types()
 {
     register_post_type('dont_publicize_me', array('public' => true, 'label' => 'Filter Me'));
     $post_id = $this->factory->post->create(array('post_type' => 'dont_publicize_me'));
     $this->assertTrue(apply_filters('publicize_should_publicize_published_post', true, get_post($post_id)));
     Jetpack_Sync_Settings::update_settings(array('post_types_blacklist' => array('dont_publicize_me')));
     $this->assertFalse(apply_filters('publicize_should_publicize_published_post', true, get_post($post_id)));
     $good_post_id = $this->factory->post->create(array('post_type' => 'post'));
     $this->assertTrue(apply_filters('publicize_should_publicize_published_post', true, get_post($good_post_id)));
 }
 public function test_sync_whitelisted_comment_meta()
 {
     Jetpack_Sync_Settings::update_settings(array('comment_meta_whitelist' => array()));
     $this->setSyncClientDefaults();
     // check that these values exists in the whitelist options
     $white_listed_comment_meta = Jetpack_Sync_Defaults::$comment_meta_whitelist;
     $comment_ids = $this->factory->comment->create_post_comments($this->post_id);
     // update all the comment meta
     foreach ($white_listed_comment_meta as $meta_key) {
         add_comment_meta($comment_ids[0], $meta_key, 'foo', 'comment');
     }
     $this->sender->do_sync();
     foreach ($white_listed_comment_meta as $meta_key) {
         $this->assertOptionIsSynced($meta_key, 'foo', 'comment', $comment_ids[0]);
     }
     $whitelist = Jetpack_Sync_Settings::get_setting('comment_meta_whitelist');
     $whitelist_and_option_keys_difference = array_diff($whitelist, $white_listed_comment_meta);
     // Are we testing all the options
     $unique_whitelist = array_unique($whitelist);
     $this->assertEquals(count($unique_whitelist), count($whitelist), 'The duplicate keys are: ' . print_r(array_diff_key($whitelist, array_unique($whitelist)), 1));
     $this->assertTrue(empty($whitelist_and_option_keys_difference), 'Some whitelisted options don\'t have a test: ' . print_r($whitelist_and_option_keys_difference, 1));
 }
 function set_defaults()
 {
     $this->sync_queue = new Jetpack_Sync_Queue('sync');
     $this->full_sync_queue = new Jetpack_Sync_Queue('full_sync');
     $this->set_queue_size_limit(Jetpack_Sync_Settings::get_setting('max_queue_size'));
     $this->set_queue_lag_limit(Jetpack_Sync_Settings::get_setting('max_queue_lag'));
 }
 function filter_post_content_and_add_links($post_object)
 {
     global $post;
     $post = $post_object;
     // return non existant post
     $post_type = get_post_type_object($post->post_type);
     if (empty($post_type) || !is_object($post_type)) {
         $non_existant_post = new stdClass();
         $non_existant_post->ID = $post->ID;
         $non_existant_post->post_modified = $post->post_modified;
         $non_existant_post->post_modified_gmt = $post->post_modified_gmt;
         $non_existant_post->post_status = 'jetpack_sync_non_registered_post_type';
         return $non_existant_post;
     }
     /**
      * Filters whether to prevent sending post data to .com
      *
      * Passing true to the filter will prevent the post data from being sent
      * to the WordPress.com.
      * Instead we pass data that will still enable us to do a checksum against the
      * Jetpacks data but will prevent us from displaying the data on in the API as well as
      * other services.
      * @since 4.2.0
      *
      * @param boolean false prevent post data from being synced to WordPress.com
      * @param mixed $post WP_POST object
      */
     if (apply_filters('jetpack_sync_prevent_sending_post_data', false, $post)) {
         // We only send the bare necessary object to be able to create a checksum.
         $blocked_post = new stdClass();
         $blocked_post->ID = $post->ID;
         $blocked_post->post_modified = $post->post_modified;
         $blocked_post->post_modified_gmt = $post->post_modified_gmt;
         $blocked_post->post_status = 'jetpack_sync_blocked';
         return $blocked_post;
     }
     // lets not do oembed just yet.
     $this->remove_embed();
     if (0 < strlen($post->post_password)) {
         $post->post_password = '******' . wp_generate_password(10, false);
     }
     /** This filter is already documented in core. wp-includes/post-template.php */
     if (Jetpack_Sync_Settings::get_setting('render_filtered_content') && $post_type->public) {
         $post->post_content_filtered = apply_filters('the_content', $post->post_content);
         $post->post_excerpt_filtered = apply_filters('the_excerpt', $post->post_excerpt);
     }
     $this->add_embed();
     if (has_post_thumbnail($post->ID)) {
         $image_attributes = wp_get_attachment_image_src(get_post_thumbnail_id($post->ID), 'full');
         if (is_array($image_attributes) && isset($image_attributes[0])) {
             $post->featured_image = $image_attributes[0];
         }
     }
     $post->permalink = get_permalink($post->ID);
     $post->shortlink = wp_get_shortlink($post->ID);
     $post->dont_email_post_to_subs = Jetpack::is_module_active('subscriptions') ? get_post_meta($post->ID, '_jetpack_dont_email_post_to_subs', true) : true;
     // Don't email subscription if the subscription module is not active.
     return $post;
 }
 /**
  * Returns the HTML for the related posts section if it's running in the loop or other instances where we don't support related posts.
  *
  * @returns string
  */
 public function get_target_html_unsupported()
 {
     if (Jetpack_Sync_Settings::is_syncing()) {
         return '';
     }
     return "\n\n<!-- Jetpack Related Posts is not supported in this context. -->\n\n";
 }
 function checksum_histogram($object_type, $buckets, $start_id = null, $end_id = null, $columns = null, $strip_non_ascii = true)
 {
     global $wpdb;
     $wpdb->queries = array();
     switch ($object_type) {
         case "posts":
             $object_count = $this->post_count(null, $start_id, $end_id);
             $object_table = $wpdb->posts;
             $id_field = 'ID';
             $where_sql = Jetpack_Sync_Settings::get_blacklisted_post_types_sql();
             if (empty($columns)) {
                 $columns = Jetpack_Sync_Defaults::$default_post_checksum_columns;
             }
             break;
         case "post_meta":
             $object_table = $wpdb->postmeta;
             $where_sql = Jetpack_Sync_Settings::get_whitelisted_post_meta_sql();
             $object_count = $this->meta_count($object_table, $where_sql, $start_id, $end_id);
             $id_field = 'meta_id';
             if (empty($columns)) {
                 $columns = Jetpack_Sync_Defaults::$default_post_meta_checksum_columns;
             }
             break;
         case "comments":
             $object_count = $this->comment_count(null, $start_id, $end_id);
             $object_table = $wpdb->comments;
             $id_field = 'comment_ID';
             $where_sql = Jetpack_Sync_Settings::get_comments_filter_sql();
             if (empty($columns)) {
                 $columns = Jetpack_Sync_Defaults::$default_comment_checksum_columns;
             }
             break;
         case "comment_meta":
             $object_table = $wpdb->commentmeta;
             $where_sql = Jetpack_Sync_Settings::get_whitelisted_comment_meta_sql();
             $object_count = $this->meta_count($object_table, $where_sql, $start_id, $end_id);
             $id_field = 'meta_id';
             if (empty($columns)) {
                 $columns = Jetpack_Sync_Defaults::$default_post_meta_checksum_columns;
             }
             break;
         default:
             return false;
     }
     $bucket_size = intval(ceil($object_count / $buckets));
     $previous_max_id = 0;
     $histogram = array();
     $where = '1=1';
     if ($start_id) {
         $where .= " AND {$id_field} >= " . intval($start_id);
     }
     if ($end_id) {
         $where .= " AND {$id_field} <= " . intval($end_id);
     }
     do {
         list($first_id, $last_id) = $wpdb->get_row("SELECT MIN({$id_field}) as min_id, MAX({$id_field}) as max_id FROM ( SELECT {$id_field} FROM {$object_table} WHERE {$where} AND {$id_field} > {$previous_max_id} ORDER BY {$id_field} ASC LIMIT {$bucket_size} ) as ids", ARRAY_N);
         // get the checksum value
         $value = $this->table_checksum($object_table, $columns, $id_field, $where_sql, $first_id, $last_id, $strip_non_ascii);
         if (is_wp_error($value)) {
             return $value;
         }
         if ($first_id === null || $last_id === null) {
             break;
         } elseif ($first_id === $last_id) {
             $histogram[$first_id] = $value;
         } else {
             $histogram["{$first_id}-{$last_id}"] = $value;
         }
         $previous_max_id = $last_id;
     } while (true);
     return $histogram;
 }
 function reset_data()
 {
     $this->reset_sync_queue();
     $this->reset_full_sync_queue();
     foreach (Jetpack_Sync_Modules::get_modules() as $module) {
         $module->reset_data();
     }
     foreach (array('sync', 'full_sync') as $queue_name) {
         delete_option(self::NEXT_SYNC_TIME_OPTION_NAME . '_' . $queue_name);
     }
     Jetpack_Sync_Settings::reset_data();
 }
 function test_only_syncs_if_is_admin_and_not_cron()
 {
     // non-admin
     set_current_screen('front');
     $this->sender->do_sync();
     $this->assertEquals(null, $this->server_replica_storage->get_callable('site_url'));
     set_current_screen('post-user');
     // admin but in cron (for some reason)
     Jetpack_Sync_Settings::set_doing_cron(true);
     $this->sender->do_sync();
     $this->assertEquals(null, $this->server_replica_storage->get_callable('site_url'));
     Jetpack_Sync_Settings::set_doing_cron(false);
     $this->sender->do_sync();
     $this->assertEquals(site_url(), $this->server_replica_storage->get_callable('site_url'));
 }
 static function set_is_importing_true()
 {
     Jetpack_Sync_Settings::set_importing(true);
 }
 static function set_is_importing_true()
 {
     require_once dirname(__FILE__) . '/class.jetpack-sync-settings.php';
     Jetpack_Sync_Settings::set_importing(true);
 }
 /**
  * The contact-form shortcode processor
  *
  * @param array $attributes Key => Value pairs as parsed by shortcode_parse_atts()
  * @param string|null $content The shortcode's inner content: [contact-form]$content[/contact-form]
  * @return string HTML for the concat form.
  */
 static function parse($attributes, $content)
 {
     if (Jetpack_Sync_Settings::is_syncing()) {
         return '';
     }
     // Create a new Grunion_Contact_Form object (this class)
     $form = new Grunion_Contact_Form($attributes, $content);
     $id = $form->get_attribute('id');
     if (!$id) {
         // something terrible has happened
         return '[contact-form]';
     }
     if (is_feed()) {
         return '[contact-form]';
     }
     // Only allow one contact form per post/widget
     if (self::$last && $id == self::$last->get_attribute('id')) {
         // We're processing the same post
         if (self::$last->attributes != $form->attributes || self::$last->content != $form->content) {
             // And we're processing a different shortcode;
             return '';
         }
         // else, we're processing the same shortcode - probably a separate run of do_shortcode() - let it through
     } else {
         self::$last = $form;
     }
     // Enqueue the grunion.css stylesheet if self::$style allows it
     if (self::$style && (empty($_REQUEST['action']) || $_REQUEST['action'] != 'grunion_shortcode_to_json')) {
         // Enqueue the style here instead of printing it, because if some other plugin has run the_post()+rewind_posts(),
         // (like VideoPress does), the style tag gets "printed" the first time and discarded, leaving the contact form unstyled.
         // when WordPress does the real loop.
         wp_enqueue_style('grunion.css');
     }
     $r = '';
     $r .= "<div id='contact-form-{$id}'>\n";
     if (is_wp_error($form->errors) && $form->errors->get_error_codes()) {
         // There are errors.  Display them
         $r .= "<div class='form-error'>\n<h3>" . __('Error!', 'jetpack') . "</h3>\n<ul class='form-errors'>\n";
         foreach ($form->errors->get_error_messages() as $message) {
             $r .= "\t<li class='form-error-message'>" . esc_html($message) . "</li>\n";
         }
         $r .= "</ul>\n</div>\n\n";
     }
     if (isset($_GET['contact-form-id']) && $_GET['contact-form-id'] == self::$last->get_attribute('id') && isset($_GET['contact-form-sent'])) {
         // The contact form was submitted.  Show the success message/results
         $feedback_id = (int) $_GET['contact-form-sent'];
         $back_url = remove_query_arg(array('contact-form-id', 'contact-form-sent', '_wpnonce'));
         $r_success_message = "<h3>" . __('Message Sent', 'jetpack') . ' (<a href="' . esc_url($back_url) . '">' . esc_html__('go back', 'jetpack') . '</a>)' . "</h3>\n\n";
         // Don't show the feedback details unless the nonce matches
         if ($feedback_id && wp_verify_nonce(stripslashes($_GET['_wpnonce']), "contact-form-sent-{$feedback_id}")) {
             $r_success_message .= self::success_message($feedback_id, $form);
         }
         /**
          * Filter the message returned after a successfull contact form submission.
          *
          * @module contact-form
          *
          * @since 1.3.1
          *
          * @param string $r_success_message Success message.
          */
         $r .= apply_filters('grunion_contact_form_success_message', $r_success_message);
     } else {
         // Nothing special - show the normal contact form
         if ($form->get_attribute('widget')) {
             // Submit form to the current URL
             $url = remove_query_arg(array('contact-form-id', 'contact-form-sent', 'action', '_wpnonce'));
         } else {
             // Submit form to the post permalink
             $url = get_permalink();
         }
         // For SSL/TLS page. See RFC 3986 Section 4.2
         $url = set_url_scheme($url);
         // May eventually want to send this to admin-post.php...
         /**
          * Filter the contact form action URL.
          *
          * @module contact-form
          *
          * @since 1.3.1
          *
          * @param string $contact_form_id Contact form post URL.
          * @param $post $GLOBALS['post'] Post global variable.
          * @param int $id Contact Form ID.
          */
         $url = apply_filters('grunion_contact_form_form_action', "{$url}#contact-form-{$id}", $GLOBALS['post'], $id);
         $r .= "<form action='" . esc_url($url) . "' method='post' class='contact-form commentsblock'>\n";
         $r .= $form->body;
         $r .= "\t<p class='contact-submit'>\n";
         $r .= "\t\t<input type='submit' value='" . esc_attr($form->get_attribute('submit_button_text')) . "' class='pushbutton-wide'/>\n";
         if (is_user_logged_in()) {
             $r .= "\t\t" . wp_nonce_field('contact-form_' . $id, '_wpnonce', true, false) . "\n";
             // nonce and referer
         }
         $r .= "\t\t<input type='hidden' name='contact-form-id' value='{$id}' />\n";
         $r .= "\t\t<input type='hidden' name='action' value='grunion-contact-form' />\n";
         $r .= "\t</p>\n";
         $r .= "</form>\n";
     }
     $r .= "</div>";
     return $r;
 }
 protected function result()
 {
     $args = $this->input();
     $queue_name = $this->validate_queue($args['queue']);
     if (is_wp_error($queue_name)) {
         return $queue_name;
     }
     if ($args['number_of_items'] < 1 || $args['number_of_items'] > 100) {
         return new WP_Error('invalid_number_of_items', 'Number of items needs to be an integer that is larger than 0 and less then 100', 400);
     }
     require_once JETPACK__PLUGIN_DIR . 'sync/class.jetpack-sync-queue.php';
     $queue = new Jetpack_Sync_Queue($queue_name);
     if (0 === $queue->size()) {
         return new WP_Error('queue_size', 'The queue is empty and there is nothing to send', 400);
     }
     require_once JETPACK__PLUGIN_DIR . 'sync/class.jetpack-sync-sender.php';
     $sender = Jetpack_Sync_Sender::get_instance();
     // try to give ourselves as much time as possible
     set_time_limit(0);
     // let's delete the checkin state
     if ($args['force']) {
         $queue->unlock();
     }
     $buffer = $this->get_buffer($queue, $args['number_of_items']);
     // Check that the $buffer is not checkout out already
     if (is_wp_error($buffer)) {
         return new WP_Error('buffer_open', "We couldn't get the buffer it is currently checked out", 400);
     }
     if (!is_object($buffer)) {
         return new WP_Error('buffer_non-object', 'Buffer is not an object', 400);
     }
     Jetpack_Sync_Settings::set_is_syncing(true);
     list($items_to_send, $skipped_items_ids, $items) = $sender->get_items_to_send($buffer, $args['encode']);
     Jetpack_Sync_Settings::set_is_syncing(false);
     return array('buffer_id' => $buffer->id, 'items' => $items_to_send, 'skipped_items' => $skipped_items_ids, 'codec' => $args['encode'] ? $sender->get_codec()->name() : null, 'sent_timestamp' => time());
 }