/** * Batch has been successfully imported. * * @param Batch $batch */ public function imported(Batch $batch) { $links = array(); $output = ''; $types = array('page', 'post'); // Only keep published posts of type $types. $posts = array_filter($batch->get_posts(), function (Post $post) use($types) { return $post->get_post_status() == 'publish' && in_array($post->get_type(), $types); }); // Create links for each of the posts. foreach ($posts as $post) { $post_id = $this->post_dao->get_id_by_guid($post->get_guid()); $links[] = array('link' => get_permalink($post_id), 'title' => $post->get_title()); } $links = apply_filters('sme_imported_post_links', $links); foreach ($links as $link) { $output .= '<li><a href="' . $link['link'] . '" target="_blank">' . $link['title'] . '</a></li>'; } if ($output !== '') { $output = '<ul>' . $output . '</ul>'; $message = '<h3>Posts deployed to ' . get_bloginfo('name') . ':</h3>' . $output; $this->api->add_deploy_message($batch->get_id(), $message, 'info', 102); } $this->api->add_deploy_message($batch->get_id(), 'Batch has been successfully imported!', 'success', 101); }
/** * Verify that a post is ready for deploy. * * @param Post $post * @param Batch $batch */ public function verify_post(Post $post, Batch $batch) { /* * If more then one post is found when searching posts with a specific * GUID, then add an error message. Two or more posts should never share * the same GUID. */ try { $revision = $this->post_dao->get_by_guid($post->get_guid()); } catch (Exception $e) { $this->api->set_preflight_status($batch->get_id(), 2); $this->api->add_preflight_message($batch->get_id(), $e->getMessage(), 'error'); return; } // Check if parent post exist on production or in batch. if (!$this->parent_post_exists($post, $batch->get_posts())) { // Fail pre-flight. $this->api->set_preflight_status($batch->get_id(), 2); // Admin URL of content stage. $admin_url = $batch->get_custom_data('sme_content_stage_admin_url'); $message = sprintf('Post <a href="%s" target="_blank">%s</a> has a parent post that does not exist on production and is not part of this batch. Include post <a href="%s" target="_blank">%s</a> in this batch to resolve this issue.', $admin_url . 'post.php?post=' . $post->get_id() . '&action=edit', $post->get_title(), $admin_url . 'post.php?post=' . $post->get_parent()->get_id() . '&action=edit', $post->get_parent()->get_title()); $this->api->add_preflight_message($batch->get_id(), $message, 'error'); return; } }
/** * Add diff between stage post and production post. * * @param Post_Env_Diff $diff */ private function add_post_diff(Post_Env_Diff $diff) { // Store diff if it does not already exist. if (!isset($this->post_diffs[$diff->get_stage_id()])) { // Store diff in database. add_post_meta($this->batch->get_id(), 'sme_post_diff', $diff->to_array()); // Store diff in property. $this->post_diffs[$diff->get_stage_id()] = $diff; } }
/** * Create/update a batch based on input data submitted by user from the * Edit Batch page. * * @param Batch $batch * @param array $request_data Input data from the user. Should contain * two array keys: * 'batch_title' - Title of this batch. * 'posts' - Posts to include in this batch. */ private function handle_edit_batch_form_data(Batch $batch, $request_data) { // Check if a title has been set. if (isset($request_data['batch_title']) && $request_data['batch_title']) { $batch->set_title($request_data['batch_title']); } else { $batch->set_title('Batch ' . date('Y-m-d H:i:s')); } if ($batch->get_id() <= 0) { // Create new batch. $this->batch_dao->insert($batch); } else { // Update existing batch. $batch->set_status('publish'); $this->batch_dao->update_batch($batch); } // IDs of posts user has selected to include in this batch. $selected_post_ids = array(); // Check if any posts to include in batch has been selected. if (isset($request_data['post_ids']) && $request_data['post_ids']) { $selected_post_ids = array_map('intval', explode(',', $request_data['post_ids'])); } // Posts that was previously in this batch. $old_post_ids = $this->batch_dao->get_post_meta($batch->get_id(), 'sme_selected_post'); // Post IDs to add to this batch. $add_post_ids = array_diff($selected_post_ids, $old_post_ids); // Post IDs to remove from this batch. $remove_post_ids = array_diff($old_post_ids, $selected_post_ids); // Add post IDs to batch. foreach ($add_post_ids as $post_id) { $this->batch_dao->add_post_meta($batch->get_id(), 'sme_selected_post', $post_id); } // Remove post IDs from batch. foreach ($remove_post_ids as $post_id) { $this->batch_dao->delete_post_meta($batch->get_id(), 'sme_selected_post', $post_id); } }
/** * Take content of a batch (attachments, users, post, custom data) and * inserted into database. * * @param Batch $batch */ private function update_batch_content(Batch $batch) { $content = array('attachments' => $batch->get_attachments(), 'users' => $batch->get_users(), 'posts' => $batch->get_posts(), 'custom_data' => $batch->get_custom_data(), 'post_rel_keys' => $batch->get_post_rel_keys()); $content = base64_encode(serialize($content)); update_post_meta($batch->get_id(), '_sme_batch_content', $content); }
/** * Get post environment diff object for a batch. * * @param Batch $batch * * @return array */ public function get_post_diffs(Batch $batch) { $objects = array(); $diffs = get_post_meta($batch->get_id(), 'sme_post_diff'); if (empty($diffs)) { return $objects; } foreach ($diffs as $diff) { $obj = new Post_Env_Diff($diff['stage_id']); $obj->set_revision_id($diff['revision_id']); $obj->set_prod_id($diff['prod_id']); $obj->set_stage_status($diff['stage_status']); $obj->set_parent_guid($diff['parent_guid']); $objects[$diff['stage_id']] = $obj; } return $objects; }
/** * Generate an import key that can be used in background imports. * * @param Batch $batch * * @return string * * @throws Exception */ public function generate_import_key(Batch $batch) { if (!$batch->get_id() || !$batch->get_modified_gmt()) { throw new Exception('Failed generating batch import key.'); } $key = md5($batch->get_id() . '-' . $batch->get_modified_gmt() . '-' . rand(0, 100000)); update_post_meta($batch->get_id(), '_sme_import_key', $key); return $key; }
/** * Prepare batch with relevant content. * * @param Batch $batch */ public function prepare(Batch $batch) { // Batch not yet created, nothing to prepare. if (!$batch->get_id()) { return; } $post_ids = array(); $batch->set_post_rel_keys(apply_filters('sme_post_relationship_keys', array())); // Clean batch from any old content. $batch->set_attachments(array()); $batch->set_users(array()); $batch->set_posts(array()); // Get IDs of posts user has selected to include in this batch. $meta = $this->batch_dao->get_post_meta($batch->get_id(), 'sme_selected_post'); // Ensure that we got an array back when looking for posts IDs in DB. if (is_array($meta)) { $post_ids = $meta; } $this->add_table_prefix($batch); $this->add_posts($batch, $post_ids); $this->add_users($batch); // Add the admin URL of content stage to the batch. $batch->add_custom_data('sme_content_stage_admin_url', admin_url()); }
/** * Get WordPress options settings. * * @param Batch $batch * @return array Associative array containing string values only. * The following keys will always be available: * - checked * - title * - description */ private function get_wp_options_settings(Batch $batch) { $settings = array('title' => '', 'description' => '', 'checked' => ''); $settings['title'] = __('WordPress Options', 'sme-content-staging'); $settings['description'] = sprintf(wp_kses(__('Include WordPress options in batch. Select what options to sync on the <a href="%s">Content Staging WordPress Options</a> page.', 'sme-content-staging'), array('a' => array('href' => array()))), esc_url(admin_url('admin.php?page=sme-wp-options'))); // Should WordPress options be included in batch. $wp_options_included = get_post_meta($batch->get_id(), '_sme_include_wp_options', true); if ($wp_options_included === 'yes') { $settings['checked'] = 'checked="checked"'; } return $settings; }
/** * Remove posts that has been deleted on content stage. * * Runs on production server after batch has been sent from content stage * and received by the production server. * * @param array $posts * @param Batch $batch */ public function import($posts, Batch $batch) { // No posts provided. if (empty($posts)) { return; } // String of deleted post IDs. $stage_post_ids = array(); foreach ($posts as $post) { if (!isset($post['guid'])) { continue; } $post_id = $this->api->get_post_id_by_guid($post['guid']); wp_delete_post($post_id, true); if (isset($post['id'])) { array_push($stage_post_ids, $post['id']); } } // String of deleted content staging IDs. $str = implode(',', $stage_post_ids); // Current blog ID. $blog_id = get_current_blog_id(); $message = sprintf('Posts deleted on Content Stage has been removed from Production. <span class="hidden" data-blog-id="%d">%s</span>', $blog_id, $str); $this->api->add_deploy_message($batch->get_id(), $message, 'info', 104); }
/** * Display checkbox (e.g. for bulk actions). The checkbox should have the * value of the batch ID. * * @param Batch $batch * * @return string Text to be placed inside the column. */ public function column_cb($batch) { return sprintf('<input type="checkbox" id="sme_select_batch_%s" class="sme-select-batch" name="%s[]" value="%s"/>', $batch->get_id(), $this->_args['plural'], $batch->get_id()); }
/** * Add WordPress options to batch. * * @param Batch $batch */ private function add_options(Batch $batch) { // Check if options should be included with this batch. $include_options = get_post_meta($batch->get_id(), '_sme_include_wp_options', true); if ($include_options !== 'yes') { return; } $options = $this->option_dao->get_options_to_sync(); $batch->set_options($options); }