<?php
/**
 * Name: Duplicate Posts/Pages
 * Description: Add duplicate button to quickly clone posts and pages with all content, metadata, taxonomies, and custom fields for faster content creation workflows
 * Category: Content
 * Icon: -
 * UseCases: [
 *   {
 *     "title": "Template-Based Content",
 *     "description": "Duplicate product template post to create 50 similar products with same structure, changing only specific details."
 *   },
 *   {
 *     "title": "Weekly Newsletter",
 *     "description": "Clone last week's newsletter post to maintain same structure and sections, just updating content and images."
 *   },
 *   {
 *     "title": "Landing Page Variations",
 *     "description": "Duplicate high-converting landing page to create A/B test variations with slight copy or design changes."
 *   }
 * ]
 * Added: 2025-10-06
 * Tags: duplicate, clone, copy, post, page, productivity
 * WhereToFind: {
 *   "location": "Posts and pages list",
 *   "url": "edit.php",
 *   "instructions": "Hover over any post to see Duplicate action",
 *   "newTab": false
 * }
 */

// Prevent direct access
if (!defined('ABSPATH')) exit;

class SwitchboardDuplicatePostButton {

    public function __construct() {
        add_filter('post_row_actions', [$this, 'add_duplicate_link'], 10, 2);
        add_filter('page_row_actions', [$this, 'add_duplicate_link'], 10, 2);
        add_action('admin_action_duplicate_post', [$this, 'duplicate_post']);
    }

    /**
     * Get default settings
     */
    public function get_default_settings() {
        return [];
    }

    /**
     * Render settings UI
     */
    public function render_settings($settings = []) {
        // Handle both comma-separated string and array formats
        $post_types_setting = isset($settings['post_types']) ? $settings['post_types'] : 'post,page';
        if (is_string($post_types_setting) && !empty($post_types_setting)) {
            $selected_post_types = array_map('trim', explode(',', $post_types_setting));
        } elseif (is_array($post_types_setting)) {
            $selected_post_types = $post_types_setting;
        } else {
            $selected_post_types = ['post', 'page'];
        }

        // Exclude media and system post types
        $all_post_types = get_post_types(['public' => true], 'objects');
        $exclude_types = ['attachment', 'wp_block', 'wp_template', 'wp_template_part', 'wp_navigation'];
        $all_post_types = array_diff_key($all_post_types, array_flip($exclude_types));
        ?>
        <input type="hidden" name="module" value="duplicate-post-button">
        <input type="hidden" name="setting_post_types" id="setting_post_types" value="<?php echo esc_attr(implode(',', $selected_post_types)); ?>">

        <div class="sb-sp-group">
            <label class="sb-sp-label"><?php echo esc_html__('Select Post Types', 'wpswitchboard'); ?></label>
            <div class="switchboard-tag-selector" data-input-id="setting_post_types">
                <div class="switchboard-selected-tags" id="selected-post-types">
                    <?php foreach ($selected_post_types as $pt_slug):
                        if (isset($all_post_types[$pt_slug])): ?>
                            <span class="switchboard-tag" data-value="<?php echo esc_attr($pt_slug); ?>">
                                <?php echo esc_html($all_post_types[$pt_slug]->label); ?>
                                <span class="remove-tag">×</span>
                            </span>
                        <?php endif;
                    endforeach; ?>
                </div>
                <div class="switchboard-available-tags">
                    <?php foreach ($all_post_types as $pt_slug => $pt_obj):
                        $is_selected = in_array($pt_slug, $selected_post_types) ? 'selected' : ''; ?>
                        <span class="switchboard-tag-option <?php echo esc_attr($is_selected); ?>" data-value="<?php echo esc_attr($pt_slug); ?>">
                            <?php echo esc_html($pt_obj->label); ?>
                        </span>
                    <?php endforeach; ?>
                </div>
            </div>
            <p class="sb-sp-description"><?php echo esc_html__('Show duplicate link for these post types. A "Duplicate" action will appear in the row actions on the posts/pages list.', 'wpswitchboard'); ?></p>
        </div>

        <div class="sb-sp-info-box sb-sp-info-box-info">
            <h4 class="sb-sp-heading-sm"><?php esc_html_e('What Gets Duplicated', 'wpswitchboard'); ?></h4>
            <ul class="sb-sp-list">
                <li class="sb-sp-list-item"><?php esc_html_e('Post title (with "(Copy)" appended)', 'wpswitchboard'); ?></li>
                <li class="sb-sp-list-item"><?php esc_html_e('Post content and excerpt', 'wpswitchboard'); ?></li>
                <li class="sb-sp-list-item"><?php esc_html_e('All custom fields and post meta', 'wpswitchboard'); ?></li>
                <li class="sb-sp-list-item"><?php esc_html_e('Categories, tags, and custom taxonomies', 'wpswitchboard'); ?></li>
                <li class="sb-sp-list-item"><?php esc_html_e('Duplicated post is saved as draft', 'wpswitchboard'); ?></li>
            </ul>
        </div>

        <div class="sb-sp-info-box sb-sp-info-box-tip">
            <h4 class="sb-sp-heading-sm"><?php esc_html_e('How to Use', 'wpswitchboard'); ?></h4>
            <ul class="sb-sp-list">
                <li class="sb-sp-list-item"><?php esc_html_e('Go to Posts → All Posts (or Pages → All Pages)', 'wpswitchboard'); ?></li>
                <li class="sb-sp-list-item"><?php esc_html_e('Hover over any post to see row actions', 'wpswitchboard'); ?></li>
                <li class="sb-sp-list-item"><?php esc_html_e('Click "Duplicate" to create a copy', 'wpswitchboard'); ?></li>
                <li class="sb-sp-list-item"><?php esc_html_e('Edit the duplicated post and publish when ready', 'wpswitchboard'); ?></li>
            </ul>
        </div>
        <?php
    }
    
    public function add_duplicate_link($actions, $post) {
        // Get settings to check enabled post types
        $settings = get_option('switchboard_duplicate-post-button_settings', []);
        // Handle both comma-separated string and array formats
        $post_types_setting = isset($settings['post_types']) ? $settings['post_types'] : 'post,page';
        if (is_string($post_types_setting) && !empty($post_types_setting)) {
            $enabled_post_types = array_map('trim', explode(',', $post_types_setting));
        } elseif (is_array($post_types_setting)) {
            $enabled_post_types = $post_types_setting;
        } else {
            $enabled_post_types = ['post', 'page'];
        }

        // Only show duplicate link for enabled post types
        if (!in_array($post->post_type, $enabled_post_types)) {
            return $actions;
        }

        if (current_user_can('edit_posts')) {
            $url = wp_nonce_url(
                admin_url('admin.php?action=duplicate_post&post=' . $post->ID),
                'duplicate_post_' . $post->ID
            );
            $actions['duplicate'] = '<a href="' . esc_url($url) . '">' . esc_html__('Duplicate', 'wpswitchboard') . '</a>';
        }
        return $actions;
    }

    public function duplicate_post() {
        if (empty($_GET['post'])) {
            wp_die(esc_html__('No post to duplicate', 'wpswitchboard'));
        }

        $post_id = absint($_GET['post']);
        check_admin_referer('duplicate_post_' . $post_id);

        $post = get_post($post_id);

        if (!$post) {
            wp_die(esc_html__('Post not found', 'wpswitchboard'));
        }

        if (!current_user_can('edit_post', $post_id)) {
            wp_die(esc_html__('You do not have permission to duplicate this post', 'wpswitchboard'));
        }

        $new_post = [
            /* translators: %s: original post title */
            'post_title' => sprintf(__('%s (Copy)', 'wpswitchboard'), $post->post_title),
            'post_content' => $post->post_content,
            'post_excerpt' => $post->post_excerpt,
            'post_status' => 'draft',
            'post_type' => $post->post_type,
            'post_author' => get_current_user_id(),
            'post_parent' => $post->post_parent,
            'menu_order' => $post->menu_order
        ];
        
        $new_post_id = wp_insert_post($new_post);
        
        // Copy taxonomies
        $taxonomies = get_object_taxonomies($post->post_type);
        foreach ($taxonomies as $taxonomy) {
            $terms = wp_get_post_terms($post_id, $taxonomy, ['fields' => 'ids']);
            wp_set_object_terms($new_post_id, $terms, $taxonomy);
        }
        
        // Copy post meta
        $post_meta = get_post_meta($post_id);
        if (is_array($post_meta)) {
            foreach ($post_meta as $key => $values) {
                if (is_array($values)) {
                    foreach ($values as $value) {
                        add_post_meta($new_post_id, $key, maybe_unserialize($value));
                    }
                }
            }
        }
        
        wp_safe_redirect(admin_url('post.php?action=edit&post=' . $new_post_id));
        exit;
    }

    /**
     * Register data locations for cleanup system
     */
    public function register_data_locations() {
        // This module duplicates posts but doesn't store any custom meta
        return [
            'options' => [],
            'option_patterns' => [],
            'tables' => [],
            'post_meta' => [],
            'user_meta' => [],
        ];
    }
}

$switchboard_instance = new SwitchboardDuplicatePostButton();
Switchboard_Data_Registry::get_instance()->auto_register($switchboard_instance, __FILE__);
