0

The permalinks on my website breaks frequently. I found out that it's being caused by a plugin I created.

The plugin basically creates a custom post type with custom fields and stores in the wp-posts and wp-post-meta tables.

I heard that it's occurring because I'm saving them to the wp-post table. So how do I save them to a different table? And how do I fetch them from that table. I can do it by the conventional PHP and MySQL ways but I want to take advantage of the WordPress functions. Can this be done?

Code to create custom post type and taxonomy

function dwwp_register_post_type(){

    $singular = 'Speaker';
    $plural = 'Speakers';

    $labels = array(
        'name'                  => $plural,
        'singular_name'         => $singular,
        'add_name'              => 'Add New',
        'add_new_item'          => 'Add New '.$singular,
        'edit'                  => 'Edit',
        'edit_item'             => 'Edit '.$singular,
        'new_item'              => 'New '.$singular,
        'view'                  => 'View '.$singular,
        'view_item'             => 'View '.$singular,
        'search_term'           => 'Search '.$plural,
        'parent'                => 'Parent '.$singular,
        'not_found'             => 'No '.$plural.' Found',
        'not_found_in_trash'    => 'No '.$plural.' in Trash',
    );


    $args = array(
        'labels'                => $labels,
        'public'                => true,
        'publicly_queryable'    => true,
        'exclude_from_search'   => false,
        'show_in_nav_menus'     => true,
        'show_ui'               => true,
        'show_in_menu'          => true,
        'show_in_admin_bar'     => true,
        'menu_position'         => 6,
        'menu_icon'             => 'dashicons-businessman',
        'can_export'            => true,
        'delete_with_user'      => false,
        'hierarchical'          => false,
        'has_archive'           => true,
        'query_var'             => true,
        'capability_type'       => 'post',
        'map_meta_cap'          => true,
        'rewrite'               => array(
                                    'slug' => 'speakers',
                                    'with_front' => true,
                                    'pages' => true,
                                    'feeds' => true,
                                ),
        'supports'              => array(
                                    'title',
                                    //'editor',
                                    //'author',
                                    //'custom-fields',
                                    'thumbnail'
                                )
        );

    register_post_type('speakers', $args);
}
add_action('init', 'dwwp_register_post_type');

function dwwp_register_taxonomy(){

    $plural = 'Years';
    $singular = 'Year';

    $labels = array(
        'name' => $plural,
        'singular_name' => $singular,
        'search_items' => 'Search '.$plural,
        'popular_items' => 'Popular '.$plural,
        'all_items' => 'All '.$plural,
        'parent_item' => null,
        'parent_item_colon' => null,
        'edit_item' => 'Edit '.$singular,
        'update_item' => 'Update '.$singular,
        'add_new_item' => 'Add New '.$singular,
        'new_item_name' => 'New '.$singular.' Name',
        'separate_items_with_commas' => 'Separate '.$plural.' with commas',
        'add_or_remove_items' => 'Add or Remove '.$plural,
        'choose_from_most_used' => 'Choose from the most used '.$plural,
        'not_found' => 'No '.$plural.' found',
        'menu_name' => $plural,
    );

    $args = array(
        'hierarchical' => true,
        'labels' => $labels,
        'show_ui' => true,
        'show_admin_column' => true,
        'update_count_callback' => '_update_post_term_count',
        'query_var' => true,
        'rewrite' => array(
            'slug' => 'year'
        )
    );

    register_taxonomy('year', 'speakers', $args);

}
add_action('init', 'dwwp_register_taxonomy');

Now I created 3 custom fields for all the speakers: Short description, Full Description and the Year is the custom taxonomy. Code to store in Database From Input Fields

function dwwp_add_custom_metabox(){
    add_meta_box('dwwp_meta', 'Speakers Description', 'dwwp_meta_callback', 'speakers', 'normal', 'core');
}

add_action('add_meta_boxes', 'dwwp_add_custom_metabox');

function dwwp_meta_callback( $post ){

    wp_nonce_field(basename(__FILE__), 'dwwp_speakers_nonce');
    $dwwp_stored_meta = get_post_meta($post->ID);
    ?>
    <div class="meta-th">
        <div class="meta-th">
            <span>Short Description</span>
        </div>
        <div class="meta-editor"></div>
            <?php
            $content = get_post_meta($post->ID, 'short-description', true);
            $editor = 'short-description';
            $settings = array(
                'textarea_rows' => 5,

            );
            wp_editor($content, $editor, $settings);
            ?>
    </div>
    <div class="meta-th">
        <div class="meta-th">
            <span>Long Description</span>
        </div>
        <div class="meta-editor"></div>
            <?php
            $content = get_post_meta($post->ID, 'long-description', true);
            $editor = 'long-description';
            $settings = array(
                'textarea_rows' => 10,

            );
            wp_editor($content, $editor, $settings);
            ?>
    </div>

<?php }

function dwwp_meta_save($post_id){
    $is_autosave = wp_is_post_autosave($post_id);
    $is_revision = wp_is_post_revision($post_id);
    $is_valid_nonce = (isset($_POST['dwwp_speakers_nonce']) && wp_verify_nonce($_POST['dwwp_speakers_nonce'], basename(__FILE__))) ? 'true' : 'false' ;

    if ($is_autosave || $is_revision || !$is_valid_nonce){
        return;
    }

    if (isset($_POST['short-description'])){
        update_post_meta($post_id, 'short-description', sanitize_text_field($_POST['short-description']));
    }

    if (isset($_POST['long-description'])){
        update_post_meta($post_id, 'long-description', sanitize_text_field($_POST['long-description']));
    }
}
add_action('save_post', 'dwwp_meta_save');

Then to display the speakers in a grid and have a popup to display their details in other places. Code to create a shortcode to display in other places

<?php

/*
==============================================
Display the speakers in a grid system
==============================================
*/

function speakers_grid_display($atts, $content = null){

    $atts = shortcode_atts(
        array(
            'years' => array('2018', '2017', '2016')
        ), $atts
    );

    $return_args[] = '<div id="section3">
                        <div class="animation-element slide slide-left testimonial">
                            <div class="row text-center">
                                <h1 class="heading-1">Speakers</h1>
                            </div>
                        </div>
                        <div class="container gal-container">';

    $args = array(
        'post_type' => 'speakers',
        'orderby' => 'menu_order',
        'order' => 'ASC',
        'post_per_page' => -1,
        'tax_query' => array(
            array(
                'taxonomy' => 'year',
                'field' => 'name',
                'terms' => $atts['years']
            ),
        ),
    );

    $speakers_list = new WP_Query($args);

    if ($speakers_list->have_posts()):
        while ($speakers_list->have_posts()): $speakers_list->the_post();

            $return_args[] = '<div class="gal-item show_info">
                                <div class="box" style="background-image: url('.get_the_post_thumbnail_url(get_the_ID()).')">
                                    <div class="overlay">
                                        <div class="text">
                                            <span class="name">'.get_the_title().'</span>
                                            <br />
                                        </div>
                                    </div>
                                </div>
                            </div>';

        endwhile;
    endif;

    $return_args[] = '</div></div>';

    $args = join($return_args);
    return $args;
}
add_shortcode('speakers-grid-display', 'speakers_grid_display');

/*
=============================================================
Display speakers with pop ups
=============================================================
*/

function speakers_popup($atts, $content = null){

    $atts = shortcode_atts(
        array(
            'years' => array('2018', '2017', '2016')
        ), $atts
    );

    $return_args[] = '<div id="section3">
                        <div class="animation-element slide slide-left testimonial">
                            <div class="row text-center">
                                <h1 class="heading-1">Speakers</h1>
                            </div>
                        </div>
                        <div class="container gal-container">';

    $args = array(
        'post_type' => 'speakers',
        'orderby' => 'menu_order',
        'order' => 'ASC',
        'post_per_page' => -1,
        'tax_query' => array(
            array(
                'taxonomy' => 'year',
                'field' => 'name',
                'terms' => $atts['years']
            ),
        ),
    );

    $speakers_list = new WP_Query($args);

    $i = 1;

    if ($speakers_list->have_posts()):
        while ($speakers_list->have_posts()): $speakers_list->the_post();

            $return_args[] = '<a href="#" data-target="#div'.$i.'" class="gal-item show_info">
                                <div class="box" style="background-image: url('.get_the_post_thumbnail_url(get_the_ID()).')">
                                    <div class="overlay">
                                        <div class="text">
                                            <span class="name">'.get_the_title().'</span>
                                            <br />
                                        </div>
                                    </div>
                                </div>
                            </a>';

            $i++;
        endwhile;
    endif;

    $return_args[] = '</div></div>';

    $speakers_list = new WP_Query($args);

    $i = 1;

    if ($speakers_list->have_posts()):
        while ($speakers_list->have_posts()): $speakers_list->the_post();
            $return_args[] = '<div id="div'.$i.'" class="show_speakers_info" style="display:none;">
                                <div class="profile-header-container">
                                    <div class="profile-header-img">
                                        <img src="'.get_the_post_thumbnail_url(get_the_ID()).'" />
                                        <!-- badge -->
                                        <div class="profile-heading">
                                            <h3 class="heading-2">'.get_the_title().'</h3>
                                            <em>'.get_post_meta(get_the_ID(), "short-description", true).'</em>
                                        </div>
                                    </div>
                                </div>
                                <div class="text-justify">
                                    '.get_post_meta(get_the_ID(), "long-description", true).'
                                </div>
                            </div>';

            $i++;

        endwhile;
    endif;

    $return_args = join($return_args);

    return $return_args;




}
add_shortcode('speakers-popup', 'speakers_popup');

And then I created another page to just reorder the list of the speakers

<?php
//Add submenu
function dwwp_add_submenu_page(){
    add_submenu_page(
        'edit.php?post_type=speakers',
        'Reorder Speakers',
        'Reorder Speakers',
        'manage_options',
        'reorder_speakers',
        'reorder_callback'
    );
}
add_action('admin_menu', 'dwwp_add_submenu_page');


//Reorder speakers
function reorder_callback(){

    $args = array(
        'post_type' => 'speakers',
        'orderby' => 'menu_order',
        'order' => 'ASC',
        'no_found_rows' => true,
        'update_post_term_cache' => false,
        'post_per_page' => 50
    );

    $speakers_list = new WP_Query($args);?>

    <div id="speakers-sort" class="sort">
        <div id="icon-job-admin" class="icon32"><br/></div>
        <h2>Reorder Speakers
        <img src = "<?php echo esc_url(admin_url() .'/images/loading.gif'); ?>"  alt="loading.gif" id="loading-animation" ></h2>

        <?php
        if ($speakers_list->have_posts()): ?>
        <ul id="custom-type-list">
            <?php 
            while ($speakers_list->have_posts()): $speakers_list->the_post();
            ?>
            <li id="<?php the_id(); ?>">
                <?php the_title(); ?>
            </li>
        <?php endwhile; ?>
        </ul>
        <?php else: ?>
            <p>No Speakers</p>
        <?php endif; ?>
    </div>


<?php
}

function dwwp_save_reorder(){

    if (!check_ajax_referer('wp-speakers-order', 'security')){
        return wp_send_json_error('Invalid Nonce');
    }

    if (!current_user_can('manage_options')){
        return wp_send_json_error( 'You are not allowed to do this.' );
    }

    $order = $_POST['order'];
    $count = 0;
    foreach( $order as $item_id ){

        $post = array(
            'ID' => (int)$item_id,
            'menu_order' => $count
        );
        wp_update_post($post);
        $count++;
    }

    wp_send_json_success('Post Saved.');

}
add_action('wp_ajax_save_post', 'dwwp_save_reorder');

And then finally in the index page, the code is

<?php
/*
Plugin Name: Speakers
Plugin URI: Speakers
Author: Speakers
Version: 1.0.0
*/

if (!defined('ABSPATH')){
    exit;
}

require ( plugin_dir_path(__FILE__) . 'speakers_custom_post_type.php' );
require ( plugin_dir_path(__FILE__) . 'speakers_custom_meta_box.php' );
require ( plugin_dir_path(__FILE__) . 'speakers_reorder_submenu.php' );
require ( plugin_dir_path(__FILE__) . 'speakers_shortcode.php');

function dwwp_admin_enqueue_scripts(){
    global $pagenow, $typenow;

    if ($typenow == 'speakers'){
        wp_enqueue_style('dwwp-admin-css', plugins_url('css/style.css', __FILE__));
        wp_enqueue_script('dwwp-admin-js', plugins_url('js/style.js', __FILE__), array( 'jquery' , 'jquery-ui-datepicker' ), '1.0.0', true);
    }

    if (($pagenow == 'post.php' || $pagenow == 'post-new.php') && $typenow == 'speakers'){
        wp_enqueue_style('dwwp-admin-css', plugins_url('css/style.css', __FILE__));
        wp_enqueue_script('dwwp-admin-js', plugins_url('js/reorder.js', __FILE__), array( 'jquery' , 'jquery-ui-datepicker' ), '1.0.0', true);
    }

    if ($pagenow == 'edit.php' && $typenow == 'speakers'){
        wp_enqueue_script('dwwp-reorder-admin-js', plugins_url('js/reorder.js', __FILE__), array( 'jquery' , 'jquery-ui-sortable' ), '1.0.0', true);
        wp_localize_script('dwwp-reorder-admin-js', 'WP_SPEAKERS_LISTING', array(
            'security' => wp_create_nonce('wp-speakers-order'),
            'success' => __('Speakers sort order has been saved.'),
            'failure' => __('There was an error saving the sort order, or you do not have priviledges')
        ));
    }
}
add_action('admin_enqueue_scripts', 'dwwp_admin_enqueue_scripts');
  • 3
    This theory that it's because you're saving them to the posts table makes no sense, and is a complete red herring. I also see no code in your answer, nor do I see what this plugin is meant to do. Can you explain what your plugin does in a non-technical manner, followed by how it does it? Edit your question with the info, don't post it as a comment. Also, are you flushing rewrite rules, and if so, where and when do you do so? – Tom J Nowell Apr 21 '18 at 16:49
  • I have added the code and the working. Please have a look. Also, I have no idea about flushing rewrite rules. – Sagnik Paul Apr 21 '18 at 17:30
  • 2
    you need to flush rewrites on plugin activation. – Milo Apr 21 '18 at 18:59
  • @Milo you should post that as an answer – Tom J Nowell Apr 21 '18 at 22:25
0

You need to flush rewrite rules on plugin activation for your custom post type to begin working.

register_deactivation_hook( __FILE__, 'flush_rewrite_rules' );
register_activation_hook( __FILE__, 'myplugin_flush_rewrites' );
function myplugin_flush_rewrites() {
    // call your CPT registration function here
    // (it should also be hooked into 'init')
    dwwp_register_post_type();
    flush_rewrite_rules();
}

You may have noticed it randomly working without having to do this, if some other code flushed rules, such as when you visit the Settings > Permalinks admin page.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.