active = get_post_meta($postId, '_active_post_deleting', true); echo ''; } else if($columnName == 'counts') { $allCounts = Factory::postService()->getUrlTableCounts(); if(!isset($allCounts[$postId])) { echo "-"; } else { $counts = $allCounts[$postId]; $s = '%1$s: %2$d'; echo sprintf($s, _wpcc("Queue"), $counts["count_queue"]) . "
" . sprintf($s, _wpcc("Saved"), $counts["count_saved"]) . "
" . sprintf($s, _wpcc("Updated"), $counts["count_updated"]) . "
" . sprintf($s, _wpcc("Deleted"), $counts["count_deleted"]) . "
" . sprintf($s, _wpcc("Other"), $counts["count_other"]) . "
" . sprintf($s, _wpcc("Total"), $counts["count_total"]) ; } } else if($columnName == 'last_checked') { $date = get_post_meta($postId, '_cron_last_checked_at', true); echo Utils::getDateFormatted($date); } else if($columnName == 'last_crawled') { $date = get_post_meta($postId, '_cron_last_crawled_at', true); echo Utils::getDateFormatted($date); } else if($columnName == 'last_recrawled') { $date = get_post_meta($postId, '_cron_recrawl_last_crawled_at', true); echo Utils::getDateFormatted($date); } else if($columnName == 'last_deleted') { $date = get_post_meta($postId, Factory::schedulingService()->metaKeyCronLastDeleted, true); echo Utils::getDateFormatted($date); } }, 10, 2); // Remove quick edit button add_filter('post_row_actions', function ($actions) { $currentScreen = get_current_screen(); if(!isset($currentScreen->post_type) || $currentScreen->post_type != Constants::$POST_TYPE) return $actions; unset($actions['inline hide-if-no-js']); return $actions; }, 10, 1); // Set interaction messages add_filter('post_updated_messages', function ($messages) { $post = get_post(); $messages[Constants::$POST_TYPE] = array( 0 => '', 1 => _wpcc('Site updated.'), 2 => _wpcc('Custom field updated.'), 3 => _wpcc('Custom field deleted.'), 4 => _wpcc('Site updated.'), 5 => isset($_GET['revision']) ? sprintf(_wpcc('Site restored to revision from %s'), wp_post_revision_title((int)$_GET['revision'], false)) : false, 6 => _wpcc('Site published.'), 7 => _wpcc('Site saved.'), 8 => _wpcc('Site submitted.'), 9 => sprintf( _wpcc('Site scheduled for: %1$s.'), date_i18n('M j, Y @ G:i', strtotime($post->post_date)) ), 10 => _wpcc('Site draft updated.'), ); return $messages; }); add_filter('enter_title_here', function($title) { if(get_current_screen()->post_type == Constants::$POST_TYPE) { $title = _wpcc('Enter site name here'); } return $title; }); // Create help tabs add_filter('admin_head', function () { $screen = get_current_screen(); // Stop if we are not in the custom post type screen we created. if (!isset($screen->post_type) || $screen->post_type != Constants::$POST_TYPE) return; // $basics = array( // 'id' => 'wcc_site_basics', // 'title' => 'Site Basics', // 'content' => 'Basic content for help tab here' // ); // // $formatting = array( // 'id' => 'wcc_site_formatting', // 'title' => 'Site Formatting', // 'content' => 'Content for help tab here' // ); // // $screen->add_help_tab($basics); // $screen->add_help_tab($formatting); // ADD NONCE // This will add the nonce after "All" link above the table (near "Published" link). This is the best // place I can come up with. add_filter('views_' . $screen->id, function($views) { $views['all'] = $views['all'] . wp_nonce_field('wcc-site-list', Constants::$NONCE_NAME); return $views; }); }); // Add the meta box. It will hold all settings. add_action('add_meta_boxes', function () { add_meta_box( Constants::$SITE_SETTINGS_META_BOX_ID, _wpcc('Settings'), function () { echo Factory::postService()->getSettingsMetaBox(); }, Constants::$POST_TYPE, 'normal', 'high' ); // Also add a meta box for keeping simple notes. add_meta_box( Constants::$SITE_SETTINGS_NOTES_META_BOX_ID, _wpcc('Simple Notes'), function() { echo Factory::postService()->getNotesMetaBox(); }, Constants::$POST_TYPE, 'side' ); }); // Add a class to the meta box to be able to differentiate it from other meta boxes. In this case, we want // the meta box not sortable, because WYSIWYG editor does not like being moved around, and the meta box will // have several WYSIWYG editors inside. add_filter(sprintf('postbox_classes_%s_%s', Constants::$POST_TYPE, Constants::$SITE_SETTINGS_META_BOX_ID), function($classes) { $classes[] = 'not-sortable'; return $classes; } ); // Add styles and scripts for post settings add_action('admin_enqueue_scripts', function ($hook) { // Check if we are on the custom post page. global $post; $valid = ($hook == 'post-new.php' && isset($_GET["post_type"]) && $_GET["post_type"] == Constants::$POST_TYPE) || ($hook == 'post.php' && $post && $post->post_type == Constants::$POST_TYPE); if(!$valid) return; Factory::assetManager()->addPostSettings(); $settings = $post && isset($post->ID) ? get_post_meta($post->ID) : []; // Add assets of the registered post details PostDetailsService::getInstance()->addSiteSettingsAssets($settings); Factory::assetManager()->addTooltip(); Factory::assetManager()->addClipboard(); Factory::assetManager()->addDevTools(); Factory::assetManager()->addOptionsBox(); Factory::assetManager()->addAnimate(); }); // Add styles and scripts for site list add_action('admin_enqueue_scripts', function($hook) { // Check if we are on the site list page $valid = $hook == 'edit.php' && isset($_GET["post_type"]) && $_GET["post_type"] == Constants::$POST_TYPE; if(!$valid) return; Factory::assetManager()->addPostList(); }); // Save options when the post is saved add_action('post_updated', function($postId, $postAfter, $postBefore) { Factory::postService()->postSettingsMetaBox($postId, $postAfter, $postBefore); }, 10, 3); // Delete all URLs when the site is permanently deleted add_action('admin_init', function() { add_action('delete_post', function($postId) { global $post_type; if ($post_type != Constants::$POST_TYPE) return; Factory::databaseService()->deleteUrlsBySiteId($postId); }); }); // Show notices when there is an error add_action('admin_notices', function() { $message = get_option('_wpcc_site_notice'); if($message) { echo Utils::view('partials/alert')->with([ 'message' => $message, 'type' => 'error' ])->render(); update_option('_wpcc_site_notice', false); } }); } /** * Get counts of URLs grouped by site ID and whether they are saved or not. * * @return array An array with keys being site IDs and values being an array containing post counts. Each value * array has count_saved, count_updated, count_queue, count_deleted, count_other, count_total. * These values are either integer or null. */ public function getUrlTableCounts() { // If it is already found before, return it. if(static::$urlCounts) return static::$urlCounts; // Find URL counts global $wpdb; $tableUrls = Factory::databaseService()->getDbTableUrlsName(); $query = "SELECT t_total.post_id, count_saved, count_updated, count_queue, count_deleted, (IFNULL(count_total, 0) - IFNULL(count_saved, 0) - IFNULL(count_queue, 0) - IFNULL(count_deleted, 0)) as count_other, count_total FROM (SELECT post_id, count(*) as count_total FROM {$tableUrls} GROUP BY post_id) t_total LEFT JOIN ( SELECT post_id, count(*) as count_queue FROM {$tableUrls} WHERE saved_post_id IS NULL AND is_saved = FALSE GROUP BY post_id) t_queue ON t_total.post_id = t_queue.post_id LEFT JOIN ( SELECT post_id, count(*) as count_saved FROM {$tableUrls} WHERE saved_post_id IS NOT NULL AND is_saved = TRUE GROUP BY post_id) t_saved ON t_total.post_id = t_saved.post_id LEFT JOIN ( SELECT post_id, count(*) as count_updated FROM {$tableUrls} WHERE saved_post_id IS NOT NULL AND is_saved = TRUE AND update_count > 0 GROUP BY post_id) t_updated ON t_total.post_id = t_updated.post_id LEFT JOIN ( SELECT post_id, count(*) as count_deleted FROM {$tableUrls} WHERE saved_post_id IS NULL AND deleted_at IS NOT NULL GROUP BY post_id) t_deleted ON t_total.post_id = t_deleted.post_id"; $results = $wpdb->get_results($query, ARRAY_A); $data = []; foreach($results as $result) { // Get post id from current result $currentPostId = $result["post_id"]; // Unset the post id unset($result["post_id"]); // Add the result to the data under post ID key. $data[$currentPostId] = $result; } static::$urlCounts = $data; return static::$urlCounts; } /* * EDITOR BUTTONS */ private function getEditorButtonsMain() { if(!$this->editorButtonsMain) $this->editorButtonsMain = [ $this->createButtonInfo(ShortCodeName::WCC_MAIN_TITLE, _wpcc("Prepared post title"), true), $this->createButtonInfo(ShortCodeName::WCC_MAIN_EXCERPT, _wpcc("Prepared post excerpt"), true), $this->createButtonInfo(ShortCodeName::WCC_MAIN_CONTENT, _wpcc("Main post content")), $this->createButtonInfo(ShortCodeName::WCC_MAIN_LIST, _wpcc("List items")), $this->createButtonInfo(ShortCodeName::WCC_MAIN_GALLERY, _wpcc("Gallery items")), $this->createButtonInfo(ShortCodeName::WCC_SOURCE_URL, sprintf(_wpcc('Full URL of the target page. You can use this to reference the source page. E.g. Source'), '[' . ShortCodeName::WCC_SOURCE_URL .']')), ]; return $this->editorButtonsMain; } private function getEditorButtonsTitle() { if(!$this->editorButtonsTitle) $this->editorButtonsTitle = [ $this->createButtonInfo(ShortCodeName::WCC_MAIN_TITLE, _wpcc("Original post title"), true), ]; return $this->editorButtonsTitle; } private function getEditorButtonsExcerpt() { if(!$this->editorButtonsExcerpt) $this->editorButtonsExcerpt = [ $this->createButtonInfo(ShortCodeName::WCC_MAIN_TITLE, _wpcc("Prepared post title"), true), $this->createButtonInfo(ShortCodeName::WCC_MAIN_EXCERPT, _wpcc("Original post excerpt"), true), ]; return $this->editorButtonsExcerpt; } private function getEditorButtonsList() { if(!$this->editorButtonsList) $this->editorButtonsList = [ $this->createButtonInfo(ShortCodeName::WCC_LIST_ITEM_TITLE, _wpcc("List item title")), $this->createButtonInfo(ShortCodeName::WCC_LIST_ITEM_CONTENT, _wpcc("List item content")), $this->createButtonInfo(ShortCodeName::WCC_LIST_ITEM_POSITION, _wpcc("The position of the item.")), ]; return $this->editorButtonsList; } private function getEditorButtonsGallery() { if(!$this->editorButtonsGallery) $this->editorButtonsGallery = [ $this->createButtonInfo(ShortCodeName::WCC_GALLERY_ITEM_URL, _wpcc("Gallery item URL")) ]; return $this->editorButtonsGallery; } private function getEditorButtonsOptionsBoxTemplates() { if (!$this->editorButtonsOptionsBoxTemplates) { $this->editorButtonsOptionsBoxTemplates = array_merge([ $this->createButtonInfo(ShortCodeName::WCC_ITEM, _wpcc("Found item")) ], $this->getEditorButtonsMain()); } return $this->editorButtonsOptionsBoxTemplates; } /** * @param string $code Short code without square brackets * @param string $description Description for what the short code does * @param bool $fresh True if a fresh instance should be returned. Otherwise, if the code created before, * the previously-created instance will be returned. * @return ShortCodeButton Short code button */ private function createButtonInfo($code, $description = '', $fresh = false) { return ShortCodeButton::getShortCodeButton($code, $description, $fresh); } /** * Get an array of all predefined short codes * @return array An array of short codes with square brackets */ public function getPredefinedShortCodes() { if(!$this->allPredefinedShortCodes) { $combinedButtons = array_merge( $this->getEditorButtonsMain(), $this->getEditorButtonsTitle(), $this->getEditorButtonsExcerpt(), $this->getEditorButtonsList(), $this->getEditorButtonsGallery() ); $result = []; foreach ($combinedButtons as $btn) { /** @var ShortCodeButton $btn */ $result[] = $btn->getCodeWithBrackets(); } $this->allPredefinedShortCodes = $result; } return $this->allPredefinedShortCodes; } /* * */ /** * Get single meta keys * * @return array An array of keys */ public function getSingleMetaKeys() { return $this->singleMetaKeys; } }