Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

Need some help from the community as i am new to the plugin development of WordPress.

I like to create a plugin for WordPress where i need a repeatable fields. But whenever i am saving the post the fields are not saving.

I am uploading the file to dropbox so that anyone can checkout the code. Here is the link - https://dl.dropboxusercontent.com/u/34202357/latest-news.zip

And here is the code if anyone don't want to download the zip

latest-news.php

define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
if ( WP_DEBUG ) {
    define ( 'CLRDR_LN_VERSION', '1.3.5-'.time() );
} else {
    define ( 'CLRDR_LN_VERSION', '1.3.5' );
}
define ( 'CLRDR_LN_DIR', plugin_dir_path(__FILE__) );
//define ( 'CLRDR_LN_URL', plugins_url().'/latest-news' );


/**
 * Include files
 *
 * @since 1.0.0
 */

if( is_admin() ) {

    // Load admin code
    require_once( CLRDR_LN_DIR.'includes/custom-post-type-helper-class.php' );

    require_once( CLRDR_LN_DIR.'includes/post-types.php' );

}

require_once( CLRDR_LN_DIR.'includes/scripts.php' );

post-types.php

<?php

$latest_news = new Custom_Post_Type( 'Latest News Ticker',array('supports'=>array('title')) );  

$latest_news->add_meta_box(
        'Default News Items',
        array(
            'custom_meta_fields' => array(
                array(
                    'label' =>  'News Text',
                    'type'  =>  'text'
                ),
                array(
                    'label' =>  'Link',
                    'type'  =>  'text'
                )               
            )
        ),
        'default_meta_box'
);

$latest_news->add_meta_box(
        'Ticker Display',
        array(
            'custom_meta_fields' => array(
                array(
                    'label' =>  'News Text',
                    'type'  =>  'short-code'
                )                   
            )
        ),          
        'side_display_settings',
        'side'
);

custom-post-type-helper-class.php

<?php

class Custom_Post_Type
    {
        public $post_type_name;
        public $post_type_args;
        public $post_type_labels;   

        /* Class constructor */
        public function __construct( $name, $args = array(), $labels = array() )
        {
            // Set some important variables
            $this->post_type_name       = strtolower( str_replace( ' ', '_', $name ) );
            $this->post_type_args       = $args;
            $this->post_type_labels     = $labels;          

            // Add action to register the post type, if the post type doesnt exist
            if( ! post_type_exists( $this->post_type_name ) )
            {
                add_action( 'init', array( &$this, 'register_post_type' ) );
            }

            // Listen for the save post hook
            $this->save();
        }

        /* Method which registers the post type */
        public function register_post_type()
        {       
            //Capitilize the words and make it plural
            $name       = self::beautify( $this->post_type_name );          
            $plural     = self::pluralize( $name );

            // We set the default labels based on the post type name and plural. We overwrite them with the given labels.
            $labels = array_merge(

                // Default
                array(
                    'name'                  => _x( $plural, 'post type general name' ),
                    'singular_name'         => _x( $name, 'post type singular name' ),
                    'add_new'               => _x( 'Add New', strtolower( $name ) ),
                    'add_new_item'          => __( 'Add New ' . $name ),
                    'edit_item'             => __( 'Edit ' . $name ),
                    'new_item'              => __( 'New ' . $name ),
                    'all_items'             => __( 'All ' . $plural ),
                    'view_item'             => __( 'View ' . $name ),
                    'search_items'          => __( 'Search ' . $plural ),
                    'not_found'             => __( 'No ' . strtolower( $plural ) . ' found'),
                    'not_found_in_trash'    => __( 'No ' . strtolower( $plural ) . ' found in Trash'), 
                    'parent_item_colon'     => '',
                    'menu_name'             => $plural
                ),

                // Given labels
                $this->post_type_labels

            );          

            // Same principle as the labels. We set some default and overwite them with the given arguments.
            $args = array_merge(

                // Default
                array(
                    'label'                 => $plural,
                    'labels'                => $labels,
                    'public'                => true,
                    'show_ui'               => true,
                    'supports'              => array( 'title', 'editor' ),
                    'show_in_nav_menus'     => true,
                    '_builtin'              => false,
                ),

                // Given args
                $this->post_type_args

            );

            // Register the post type
            register_post_type( $this->post_type_name, $args );
        }

        /* Method to attach the taxonomy to the post type */
        public function add_taxonomy( $name, $args = array(), $labels = array() )
        {
            if( ! empty( $name ) )
            {           
                // We need to know the post type name, so the new taxonomy can be attached to it.
                $post_type_name = $this->post_type_name;

                // Taxonomy properties
                $taxonomy_name      = strtolower( str_replace( ' ', '_', $name ) );
                $taxonomy_labels    = $labels;
                $taxonomy_args      = $args;

                if( ! taxonomy_exists( $taxonomy_name ) )
                    {
                        //Capitilize the words and make it plural
                            $name       = ucwords( str_replace( '_', ' ', $name ) );
                            $plural     = $name . 's';

                            // Default labels, overwrite them with the given labels.
                            $labels = array_merge(

                                // Default
                                array(
                                    'name'                  => _x( $plural, 'taxonomy general name' ),
                                    'singular_name'         => _x( $name, 'taxonomy singular name' ),
                                    'search_items'          => __( 'Search ' . $plural ),
                                    'all_items'             => __( 'All ' . $plural ),
                                    'parent_item'           => __( 'Parent ' . $name ),
                                    'parent_item_colon'     => __( 'Parent ' . $name . ':' ),
                                    'edit_item'             => __( 'Edit ' . $name ), 
                                    'update_item'           => __( 'Update ' . $name ),
                                    'add_new_item'          => __( 'Add New ' . $name ),
                                    'new_item_name'         => __( 'New ' . $name . ' Name' ),
                                    'menu_name'             => __( $name ),
                                ),

                                // Given labels
                                $taxonomy_labels

                            );

                            // Default arguments, overwitten with the given arguments
                            $args = array_merge(

                                // Default
                                array(
                                    'label'                 => $plural,
                                    'labels'                => $labels,
                                    'public'                => true,
                                    'show_ui'               => true,
                                    'show_in_nav_menus'     => true,
                                    '_builtin'              => false,
                                ),

                                // Given
                                $taxonomy_args

                            );

                            // Add the taxonomy to the post type
                            add_action( 'init',
                                function() use( $taxonomy_name, $post_type_name, $args )
                                {                       
                                    register_taxonomy( $taxonomy_name, $post_type_name, $args );
                                }
                            );
                    }
                    else
                    {
                        add_action( 'init',
                                function() use( $taxonomy_name, $post_type_name )
                                {               
                                    register_taxonomy_for_object_type( $taxonomy_name, $post_type_name );
                                }
                            );
                    }
            }
        }       

        private function default_meta_box( $meta, $custom_fields=array(), $data_id ) 
        {
            // Begin the field table and loop
            echo '<table class="sortable-form-table"><tbody><tr><th></th>';                                     
            /* Loop through $custom_fields */
            foreach( $custom_fields['custom_meta_fields'] as $field )
            {                                                                                                                                                                                                       
                $field_id_name  = self::uglify( $data_id )  . '_' . self::uglify( $field['label'] );                                            

                echo '<th>' . $field['label'] . '</th>';

                //echo '<label for="' . $field_id_name . '">' . $field['label'] . '</label><input type="text" name="custom_meta[' . $field_id_name . ']" id="' . $field_id_name . '" value="' . $meta[$field_id_name][0] . '" />';
            }
            echo '</tr><tr><td><span class="sort hndle">|||</span></td>';
            foreach( $custom_fields['custom_meta_fields'] as $field )
            {                                                                                                                                                                                                       
                $field_id_name  = strtolower( str_replace( ' ', '_', $data_id ) ) . '_' . strtolower( str_replace( ' ', '_', $field['label'] ) );                                           

                echo '<td>';
                echo self::input_fields( $field_id_name, $meta, $field,1 );                         
                echo '</td>';

            }
            echo '<td><a class="repeatable-remove button" href="#">-</a></td><td><a class="repeatable-add button" href="#">+</a></td>';
            echo '</tbody></table>';
        }

        private static function input_fields( $field_id_name, $meta, $field = array(), $repeatable=0 ) 
        {           

            switch($field['type']) {

                // text
                case 'text':
                    if($repeatable) 
                    {
                        $i = 0;
                        $html= '<input type="text" name="'.$field_id_name.'['. $i . ']" id="'.$field_id_name.'" value="'.$meta[$field_id_name][0].'" size="30" />
                            <br /><span class="description">'.$field['desc'].'</span>';
                    }
                    else
                    {
                        $html= '<input type="text" name="custom_meta['.$field_id_name.']" id="'.$field_id_name.'" value="'.$meta[$field_id_name][0].'" size="30" />
                            <br /><span class="description">'.$field['desc'].'</span>';
                    }
                break;

                // textarea
                case 'textarea':
                    $html= '<textarea name="custom_meta['.$field_id_name.']" id="'.$field_id_name.'" rows="4" width="100%">'.$meta[$field_id_name][0].'</textarea>
                            <br /><span class="description">'.$field['desc'].'</span>';
                break;

                // select
                case 'select':
                    if($repeatable) 
                    {
                        $i = 0;
                        echo '<select name="custom_meta['.$field_id_name.']['. $i . ']" id="'.$field_id_name.'">';
                        foreach ($field['options'] as $option) {                        
                            echo '<option', $meta[$field_id_name][0] == $option['value'] ? ' selected="selected"' : '', ' value="'.$option['value'].'">'.$option['label'].'</option>';
                        }
                        echo '</select><br /><span class="description">'.$field['desc'].'</span>';

                    }
                    else
                    {
                        echo '<select name="custom_meta['.$field_id_name.']" id="'.$field_id_name.'">';
                        foreach ($field['options'] as $option) {                        
                            echo '<option', $meta[$field_id_name][0] == $option['value'] ? ' selected="selected"' : '', ' value="'.$option['value'].'">'.$option['label'].'</option>';
                        }
                        echo '</select><br /><span class="description">'.$field['desc'].'</span>';

                    }                                               
                break;                          

            }

            return $html;

        }


        /* Attaches meta boxes to the post type */
        public function add_meta_box( $title, $fields = array(), $boxtype = NULL, $context = 'normal', $priority = 'default' )
        {
            if( ! empty( $title ) )
            {                   
                // We need to know the Post Type name again
                $post_type_name = $this->post_type_name;                

                // Meta variables   
                $box_id         = strtolower( str_replace( ' ', '_', $title ) );
                $box_title      = ucwords( str_replace( '_', ' ', $title ) );
                $box_context    = $context;
                $box_priority   = $priority;            

                // Make the fields global
                global $custom_fields; 

                $custom_fields[$title] = $fields;                   

                add_action( 'admin_init',
                        function() use( $box_id, $box_title, $post_type_name, $box_context, $box_priority, $fields, $boxtype )
                        {               
                            add_meta_box(
                                $box_id,
                                $box_title,
                                function( $post, $data )
                                {                                   
                                    global $post;                                   

                                    // Nonce field for some validation
                                    wp_nonce_field( plugin_basename( __FILE__ ), 'custom_post_type' );                              

                                    // Get all inputs from $data
                                    $custom_fields = $data['args'][0];                                                                          

                                    // Get the saved values
                                    $meta = get_post_custom( $post->ID );

                                    // Check the array and loop through it
                                    if( ! empty( $custom_fields ) )
                                    {
                                        switch($data['args'][1]) {

                                            case 'default_meta_box':
                                                self::default_meta_box( $meta, $custom_fields, $data['id'] );
                                            break;

                                            case 'side_display_settings':
                                                echo '<pre><p>[clrdr_latest_news id="'.$post->ID.'"]</p></pre>';
                                            break;

                                            default:
                                                /* Loop through $custom_fields */
                                                foreach( $custom_fields['custom_meta_fields'] as $field )
                                                {                                                                                                                                                                                                       
                                                    $field_id_name  = strtolower( str_replace( ' ', '_', $data['id'] ) ) . '_' . strtolower( str_replace( ' ', '_', $field['label'] ) );                                            

                                                    echo '<label for="' . $field_id_name . '">' . $field['label'] . '</label><input type="text" name="custom_meta[' . $field_id_name . ']" id="' . $field_id_name . '" value="'. $meta[$field_id_name]. '/>';
                                                }
                                            break;
                                        }                                                                   

                                    }

                                },
                                $post_type_name,
                                $box_context,
                                $box_priority,
                                array( $fields, $boxtype)
                            );
                        }
                    );
            }   
            echo "<pre>";

                //echo $this->post_type_name;
                //print_r($custom_fields);
                foreach($custom_fields as $title=>$fields )
                {                           
                    // Loop through all fields
                    foreach( $fields['custom_meta_fields'] as $field )
                    {
                        $field_id_name  = strtolower( str_replace( ' ', '_', $title ) ) . '_' . strtolower( str_replace( ' ', '_', $field['label'] ) ); 

                        print_r($fields);
                        echo $field_id_name."<br/>";

                        //update_post_meta( $post->ID, $field_id_name, $_POST['custom_meta'][$field_id_name] );
                    }

                }
            echo "</pre>";          
        }



        /* Listens for when the post type being saved */
        public function save()
        {
            // Need the post type name again
            $post_type_name = $this->post_type_name;            

            add_action( 'save_post',
                function() use($post_type_name )
                {
                    // Deny the wordpress autosave function
                    if( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return;

                    if ( ! wp_verify_nonce( $_POST['custom_post_type'], plugin_basename(__FILE__) ) ) return;

                    global $post;                   

                    if( isset( $_POST ) && isset( $post->ID ) && get_post_type( $post->ID ) == $post_type_name )
                    {
                        global $custom_fields;                      

                        // Loop through each meta box
                        foreach($custom_fields as $title=>$fields )
                        {                           
                            // Loop through all fields
                            foreach( $fields['custom_meta_fields'] as $field )
                            {
                                $field_id_name  = strtolower( str_replace( ' ', '_', $title ) ) . '_' . strtolower( str_replace( ' ', '_', $field['label'] ) ); 

                                update_post_meta( $post->ID, $field_id_name, $_POST['custom_meta'][$field_id_name] );
                            }

                        }
                    }
                }
            );
        }

        //add_action('save_post', 'save');

        public static function beautify( $string )  
        {  
            return ucwords( str_replace( '_', ' ', $string ) );  
        }  

        public static function uglify( $string )  
        {  
            return strtolower( str_replace( ' ', '_', $string ) );  
        }  

        public static function pluralize( $string )  
        {  
            $last = $string[strlen( $string ) - 1];  

            if( $last == 'y' )  
            {  
                $cut = substr( $string, 0, -1 );  
                //convert y to ies  
                $plural = $cut . 'ies';  
            }  
            else  
            {  
                // just attach an s  
                $plural = $string . 's';  
            }  

            return $plural;  
        }  

}

?>

scripts.php

<?php

function clrdr_lnt_admin_scripts( $hook ) {

    if(is_admin()) {

        wp_enqueue_script('jquery-ui-slider');  

        wp_enqueue_script('custom-meta-js', plugins_url('js/custom.js', __FILE__));
    }       

}

add_action( 'admin_enqueue_scripts', 'clrdr_lnt_admin_scripts' );

custom.js

jQuery(function(jQuery) {  
jQuery('.repeatable-add').click(function() {  
    field = jQuery(this).closest('tr').clone(true);    
    fieldLocation = jQuery(this).parents('tbody tr');  
    jQuery('input', field).val('').attr('name', function(index, name) {             
        return name.replace(/(\d+)/, function(fullMatch, n) {               
            return Number(n) + 1;  
        });  
    })  
    field.insertAfter(fieldLocation, jQuery(this).closest('td'))  
    return false;  
});  

jQuery('.repeatable-remove').click(function(){      
    if ((jQuery(this).parents('tbody tr').siblings().andSelf().length)!=2)
    {
        jQuery(this).parents('tr').remove();  
        return false;  
    }
});  

jQuery('.sortable-form-table tbody').sortable({  
    opacity: 0.6,  
    revert: true,  
    cursor: 'move',  
    handle: '.sort'  
});  
}); 

Thanks to all in advance.

share|improve this question
2  
Please include relevant code in your question, don't link to a .zip file. –  Rachel Baker Jan 17 at 20:20
    
@RachelBaker i have updated my post with the code. –  Himadri Ganguly Jan 18 at 10:03
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.