settings = SettingsManager::get_instance(); $this->init_hooks(); } private function get_setting($key, $default = '') { return $this->settings->get('content_tool', $key, $default); } private function init_hooks() { if ($this->get_setting('enable_duplicator')) { add_filter('post_row_actions', [$this, 'duplicate_post_link'], 10, 2); add_filter('page_row_actions', [$this, 'duplicate_post_link'], 10, 2); add_action('admin_action_cdvao_duplicate_post', [$this, 'duplicate_post_handler']); } if ($this->get_setting('enable_auto_excerpt')) { add_filter('excerpt_length', function($len) { return (int) $this->get_setting('auto_excerpt_length', 55); }); } if ($this->get_setting('svg_support')) { add_filter('upload_mimes', [$this, 'enable_svg_upload']); } if ($this->get_setting('enable_image_columns') || $this->get_setting('enable_word_count')) { add_filter('manage_posts_columns', [$this, 'modify_list_columns']); add_filter('manage_pages_columns', [$this, 'modify_list_columns']); add_action('manage_posts_custom_column', [$this, 'render_list_columns'], 10, 2); add_action('manage_pages_custom_column', [$this, 'render_list_columns'], 10, 2); // Sortable Columns add_filter('manage_edit-post_sortable_columns', [$this, 'make_columns_sortable']); add_filter('manage_edit-page_sortable_columns', [$this, 'make_columns_sortable']); add_action('pre_get_posts', [$this, 'handle_column_sorting']); } // Word Count Updater on Save if ($this->get_setting('enable_word_count')) { add_action('save_post', [$this, 'update_word_count_meta'], 10, 2); } } public function make_columns_sortable($columns) { if ($this->get_setting('enable_word_count')) { $columns['cdvao_word_count'] = 'cdvao_word_count'; } return $columns; } public function handle_column_sorting($query) { if (!is_admin() || !$query->is_main_query()) { return; } $orderby = $query->get('orderby'); if ($orderby === 'cdvao_word_count') { $query->set('meta_key', '_cdvao_word_count'); $query->set('orderby', 'meta_value_num'); } } public function duplicate_post_link($actions, $post) { if (current_user_can('edit_posts')) { $actions['duplicate'] = 'Duplicate'; } return $actions; } public function duplicate_post_handler() { if (! ( isset( $_GET['post'] ) || isset( $_POST['post'] ) || ( isset($_REQUEST['action']) && 'cdvao_duplicate_post' == $_REQUEST['action'] ) ) ) { wp_die('No post to duplicate has been supplied!'); } if ( !isset( $_GET['duplicate_nonce'] ) || !wp_verify_nonce( sanitize_key( wp_unslash( $_GET['duplicate_nonce'] ) ), basename( __FILE__ ) ) ) return; $post_id = (isset($_GET['post']) ? absint( $_GET['post'] ) : absint( $_POST['post'] ) ); $post = get_post( $post_id ); $current_user = wp_get_current_user(); $new_post_author = $current_user->ID; if (isset( $post ) && $post != null) { $args = array( 'comment_status' => $post->comment_status, 'ping_status' => $post->ping_status, 'post_author' => $new_post_author, 'post_content' => $post->post_content, 'post_excerpt' => $post->post_excerpt, 'post_name' => $post->post_name, 'post_parent' => $post->post_parent, 'post_password' => $post->post_password, 'post_status' => 'draft', 'post_title' => $post->post_title . ' (Copy)', 'post_type' => $post->post_type, 'to_ping' => $post->to_ping, 'menu_order' => $post->menu_order ); $new_post_id = wp_insert_post( $args ); $taxonomies = get_object_taxonomies($post->post_type); foreach ($taxonomies as $taxonomy) { $post_terms = wp_get_object_terms($post_id, $taxonomy, array('fields' => 'slugs')); wp_set_object_terms($new_post_id, $post_terms, $taxonomy, false); } $post_meta_infos = get_post_meta($post_id); if (count($post_meta_infos)!=0) { foreach ($post_meta_infos as $meta_key => $meta_value) { $meta_value = $meta_value[0]; if ($meta_key != '_edit_lock' && $meta_key != '_edit_last' && $meta_key != '_cdvao_word_count') { update_post_meta($new_post_id, $meta_key, $meta_value); } } } // Calculate word count for new post immediately $this->update_word_count_meta($new_post_id, get_post($new_post_id)); wp_safe_redirect( admin_url( 'edit.php?post_type=' . $post->post_type ) ); exit; } else { wp_die( esc_html__( 'Post creation failed, could not find original post: ', 'admin-menu-optimizer' ) . esc_html( $post_id ) ); } } public function enable_svg_upload($mimes) { $mimes['svg'] = 'image/svg+xml'; return $mimes; } public function modify_list_columns($columns) { if ($this->get_setting('enable_image_columns')) { $columns['cdvao_feature_image'] = __('Featured Image', 'admin-menu-optimizer'); } if ($this->get_setting('enable_word_count')) { $columns['cdvao_word_count'] = __('Post Words', 'admin-menu-optimizer'); } return $columns; } public function render_list_columns($column, $post_id) { if ($column === 'cdvao_feature_image') { if (has_post_thumbnail($post_id)) { echo get_the_post_thumbnail($post_id, [50, 50]); } else { echo '' . esc_html( __('No Image', 'admin-menu-optimizer') ) . ''; } } if ($column === 'cdvao_word_count') { // Check meta first for performance $count = get_post_meta($post_id, '_cdvao_word_count', true); if ($count === '') { // If missing (old post), calculate now and save $post = get_post($post_id); $count = $this->calculate_word_count($post->post_content); update_post_meta($post_id, '_cdvao_word_count', $count); } echo esc_html($count); } } public function update_word_count_meta($post_id, $post) { if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return; if (!$post) return; if (wp_is_post_revision($post_id)) return; $count = $this->calculate_word_count($post->post_content); update_post_meta($post_id, '_cdvao_word_count', $count); } private function calculate_word_count($content) { $text = wp_strip_all_tags($content); // Optimized multi-language word count using regex for Unicode characters // \p{L} matches any unicode letter. // We count consecutive sequences of letters as words. if (preg_match_all('/[\p{L}0-9\'-]+/u', $text, $matches)) { return count($matches[0]); } return 0; } public function render_settings() { $settings = [ 'enable_duplicator' => ['type' => 'checkbox', 'label' => __('Enable Post Duplicator', 'admin-menu-optimizer')], 'enable_auto_excerpt' => ['type' => 'checkbox', 'label' => __('Enable Auto Excerpt', 'admin-menu-optimizer')], 'auto_excerpt_length' => ['type' => 'number', 'label' => __('Excerpt Length (words)', 'admin-menu-optimizer')], 'svg_support' => ['type' => 'checkbox', 'label' => __('Enable SVG Upload Support', 'admin-menu-optimizer')], 'enable_image_columns' => ['type' => 'checkbox', 'label' => __('Show Feature Image Column', 'admin-menu-optimizer')], 'enable_word_count' => ['type' => 'checkbox', 'label' => __('Show Post Words (Word Count)', 'admin-menu-optimizer')], ]; echo '
| ' . esc_html($field['label']) . ' | '; echo ''; if ($field['type'] === 'checkbox') { echo ''; } elseif ($field['type'] === 'number') { echo ''; } echo ' | '; echo '
|---|