├── images └── ajax-loader.gif ├── readme.txt ├── wordpress-creation-kit.css ├── wordpress-creation-kit.js └── wordpress-creation-kit.php /images/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madalinungureanu/wordpress-creation-kit-api/18a89535b9e76476ac3bf03d4a1d1305c647df76/images/ajax-loader.gif -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | Usage Example 1 2 | 3 | 'text', 'title' => 'Title', 'description' => 'Description for this input' ), 7 | array( 'type' => 'textarea', 'title' => 'Description' ), 8 | array( 'type' => 'upload', 'title' => 'Image', 'description' => 'Upload a image' ), 9 | array( 'type' => 'select', 'title' => 'Select This', 'options' => array( 'Option 1', 'Option 2', 'Option 3' ) ), 10 | 11 | array( 'type' => 'checkbox', 'title' => 'Check This', 'options' => array( 'Option 1', 'Option 2', 'Option 3' ) ), 12 | 13 | array( 'type' => 'radio', 'title' => 'Radio This', 'options' => array( 'Radio 1', 'Radio 2', 'Radio 3' ) ), 14 | ); 15 | 16 | $args = array( 17 | 'metabox_id' => 'rm_slider_content', 18 | 'metabox_title' => 'Slideshow Class', 19 | 'post_type' => 'slideshows', 20 | 'meta_name' => 'rmscontent', 21 | 'meta_array' => $fint 22 | ); 23 | 24 | new Wordpress_Creation_Kit( $args ); 25 | 26 | ?> 27 | 28 | For Frontend use like this: 29 | 30 | ID, 'rmscontent', true ); ?> 31 | 32 | 33 | 34 | 35 | Default Parameters 36 | 37 | '', 39 | 'metabox_title' => 'Meta Box', 40 | 'post_type' => 'post', 41 | 'meta_name' => '', 42 | 'meta_array' => array(), 43 | 'page_template' => '', 44 | 'post_id' => '', 45 | 'single' => false, 46 | 'wpml_compatibility' => false, 47 | 'sortable' => true, 48 | 'context' => 'post_meta' 49 | ) 50 | ?> 51 | 52 | Parameters 53 | 54 | $metabox_id 55 | (string) (required) HTML 'id' attribute of the edit screen section 56 | 57 | Default: None 58 | 59 | $metabox_title 60 | (string) (required) Title of the edit screen section, visible to user 61 | 62 | Default: 'Meta Box' 63 | 64 | $post_type 65 | (string) (required) The type of Write screen on which to show the edit screen section ('post', 'page', 'link', or 'custom_post_type' where custom_post_type is the custom post type slug) 66 | 67 | Default: 'post' 68 | 69 | $meta_name 70 | (string) (required) The name of the meta key used to query for data 71 | 72 | Default: None 73 | 74 | $meta_array 75 | (array) (required) The array of fields used to create the form. See example above. Must be array( array() ). Type and Title are required. 76 | 77 | Default: None 78 | 79 | $page_template 80 | (string) (optional) The name of the page template on wich you want the meta box to appear. If this is set than $post_type can be omitted. 81 | 82 | Default: None 83 | 84 | $post_id 85 | (string) (optional) The id of the post you want the meta box to appear. If this is set than $post_type can be omitted. 86 | 87 | Default: None 88 | 89 | $single 90 | (boolean) (optional) Set this to true if you don't want a repeater box and you will be able to enter just one value. 91 | 92 | Default: false 93 | 94 | $wpml_compatibility 95 | (boolean) (optional) Set this to true if you want to enable wpml compatibility 96 | 97 | $sortable 98 | (boolean) (optional) Wheater or not the fields in a repeater box are sortable. 99 | 100 | Default: true 101 | 102 | $context 103 | (string) (optional) WCK API can add data as meta or as option depending on the context. Using 'post_meta' will add data as post meta and using 'option' will add data as option 104 | 105 | Default: 'post_meta' 106 | 107 | Parameters for meta_array 108 | 109 | 'title' (string) Title of the field. 110 | 'type' (string) The field type. Possible values: 'text', 'textarea', 'select', 'checkbox', 'radio', 'upload'. 111 | 'description' (string) The description of the field. 112 | 'required' (boolean) true if the field is required. 113 | 'default' (string) If you want the string to have a default value enter it here. For Checkboxes if there are multiple 114 | values separete them with a ",". 115 | 'default-option' (boolean) true if you want Select to have a default option. 116 | 'options' (array) Options for field types "select", "checkbox" and "radio". 117 | 118 | 119 | How to add into a plugin: 120 | 121 | 1. Copy the foldder "wordpress-creation-kit-api" into the plugin dir 122 | 2. Change the class name "Wordpress_Creation_Kit" if multiple plugins use wordpress-creation-kit-api on the same site. 123 | 3. Include "wordpress-creation-kit.php" into the plugin file 124 | 125 | /* include Custom Fields Creator API */ 126 | require_once('wordpress-creation-kit/wordpress-creation-kit.php'); 127 | 128 | 4. Use the API as in Exampe 1, in your plugin file or functions or whatever fits the situation. 129 | 130 | 131 | WPML Compatibility 132 | 133 | When wpml_compatibility is true on a meta box, besides saving the contents of the box in one serialized custom field, we create automatically a custom field for every field in every entry. We do this because WPML can't handle serialized custom fields and also we will get good control on what actions we want to perform (don't translate, copy, translate ) on each of the fields. 134 | 135 | After the fields are translated with Icanlcalize and we have the translated post in our system, we can go on the translated post and press the "Syncronize WCK Translation" button which will create the serialized array from the individual custom fields. -------------------------------------------------------------------------------- /wordpress-creation-kit.css: -------------------------------------------------------------------------------- 1 | .mb-list-entry-fields li{ 2 | margin-bottom:15px; 3 | clear:both; 4 | overflow:hidden; 5 | } 6 | 7 | .mb-right-column{ 8 | overflow:hidden; 9 | } 10 | 11 | .field-label{ 12 | width:190px; 13 | float:left; 14 | min-height:30px; 15 | font-weight:bold; 16 | padding-right:10px; 17 | } 18 | 19 | .field-label.error{ 20 | color:#ff0000; 21 | } 22 | 23 | .field-label .required{ 24 | color:#ff0000; 25 | padding:0 2px; 26 | } 27 | 28 | .mb-right-column label{ 29 | padding:0 6px 0 3px; 30 | } 31 | 32 | #mb-ajax-loading{ 33 | position:absolute; 34 | top:0; 35 | left:0; 36 | width:100%; 37 | height:100%; 38 | background:url(images/ajax-loader.gif) center center no-repeat; z-index:999; 39 | } 40 | 41 | .mb-table-container pre{ 42 | display:inline-block; 43 | vertical-align:top; 44 | margin:0; 45 | white-space: -moz-pre-wrap; 46 | white-space: -pre-wrap; 47 | white-space: -o-pre-wrap; 48 | white-space: pre-wrap; 49 | word-wrap: break-word; 50 | } 51 | 52 | .wck-edit, .wck-delete, .wck-number{ 53 | width:50px; 54 | text-align:center !important; 55 | } 56 | 57 | td.wck-number{ 58 | cursor:move; 59 | } 60 | 61 | .not-sortable td.wck-number{ 62 | cursor:auto; 63 | } 64 | 65 | .wck-edit .button-secondary{ 66 | padding:3px 15px; 67 | } 68 | 69 | .mbdelete{ 70 | color:#BC0B0B; 71 | } 72 | 73 | .mbdelete:hover{ 74 | color:#FF0000; 75 | } 76 | 77 | .mb-list-entry-fields{ 78 | list-style:none; 79 | } 80 | 81 | .mb-table-container tr:nth-child(2n+1) { 82 | background-color:#FCFCFC; 83 | } 84 | 85 | .mb-table-container tr:last-child td { 86 | border-bottom: 0 none; 87 | } 88 | 89 | .mb-table-container tr td { 90 | background: none repeat scroll 0 0 transparent; 91 | border-bottom: 1px solid #EDEDED; 92 | border-right: 1px solid #EDEDED; 93 | padding: 8px; 94 | position: relative; 95 | } 96 | 97 | .mb-table-container tr td:last-child { 98 | border-right: 0 none; 99 | } 100 | 101 | .mb-table-container thead > tr > th { 102 | border-right: 1px solid #E1E1E1; 103 | } 104 | 105 | .mb-table-container tr > th:last-child { 106 | border-right: 0 none; 107 | } 108 | 109 | .mb-textarea{ 110 | width:60%; 111 | max-width:600px; 112 | height:130px; 113 | } 114 | .mb-text-input{ 115 | width:40%; 116 | max-width:400px; 117 | } 118 | 119 | .mb-select{ 120 | min-width:150px; 121 | } 122 | 123 | /* Settings page. */ 124 | .side .form-table th { 125 | width: 20%; 126 | font-weight: bold; 127 | text-align: left; 128 | padding-left: 0; 129 | } 130 | 131 | .wck-post-body{ 132 | clear: left; 133 | float: left; 134 | margin-right: -2000px; 135 | width: 100%; 136 | } 137 | 138 | .metabox-holder .column-1 { 139 | margin-right:300px; 140 | } 141 | .metabox-holder .column-2 { 142 | float: right; 143 | width: 280px; 144 | clear:right; 145 | position:relative; 146 | } 147 | .metabox-holder .column-3 { 148 | clear: both; 149 | margin-right:300px; 150 | } -------------------------------------------------------------------------------- /wordpress-creation-kit.js: -------------------------------------------------------------------------------- 1 | /* Add width to elements at startup */ 2 | jQuery(function(){ 3 | jQuery('.mb-table-container tbody td').css('width', function(){ return jQuery(this).width() }); 4 | 5 | 6 | 7 | }); 8 | 9 | /* add reccord to the meta */ 10 | function addMeta(value, id, nonce){ 11 | jQuery('#'+value).parent().css({'opacity':'0.4', 'position':'relative'}).append('
'); 12 | /*object to hold the values */ 13 | var values = {}; 14 | 15 | jQuery('#'+value+' .mb-field').each(function(){ 16 | 17 | var key = jQuery(this).attr('name'); 18 | 19 | if(jQuery(this).attr('type') == 'checkbox' || jQuery(this).attr('type') == 'radio' ) { 20 | 21 | if( typeof values[key.toString()] === "undefined" ) 22 | values[key.toString()] = ''; 23 | 24 | if(jQuery(this).is(':checked')){ 25 | if( values[key.toString()] == '' ) 26 | values[key.toString()] += jQuery(this).val().toString(); 27 | else 28 | values[key.toString()] += ', ' + jQuery(this).val().toString(); 29 | } 30 | } 31 | 32 | else 33 | values[key.toString()] = jQuery(this).val().toString(); 34 | }); 35 | 36 | 37 | jQuery.post( ajaxurl , { action:"wck_add_meta"+value, meta:value, id:id, values:values, _ajax_nonce:nonce}, function(response) { 38 | 39 | jQuery( '#'+value+' .field-label').removeClass('error'); 40 | 41 | if( response.error ){ 42 | jQuery('#'+value).parent().css('opacity','1'); 43 | jQuery('#mb-ajax-loading').remove(); 44 | 45 | for( var i in response.errorfields ){ 46 | jQuery( '#'+value+' .field-label[for="' + response.errorfields[i] + '"]' ).addClass('error'); 47 | } 48 | 49 | alert( response.error ); 50 | } 51 | else{ 52 | /* refresh the list */ 53 | jQuery.post( ajaxurl , { action:"wck_refresh_list"+value, meta:value, id:id}, function(response) { 54 | 55 | jQuery('#container_'+value).replaceWith(response); 56 | 57 | jQuery('.mb-table-container tbody td').css('width', function(){ return jQuery(this).width() }); 58 | 59 | if( !jQuery( '#'+value ).hasClass('single') ) 60 | mb_sortable_elements(); 61 | 62 | jQuery('#'+value+' .mb-field').each(function(){ 63 | if(jQuery(this).attr('type') == 'checkbox' || jQuery(this).attr('type') == 'radio' ) 64 | jQuery(this).removeAttr( 'checked' ); 65 | else 66 | jQuery(this).val(''); 67 | }); 68 | jQuery('#'+value).parent().css('opacity','1'); 69 | 70 | /* Remove form if is single */ 71 | if( jQuery( '#'+value ).hasClass('single') ) 72 | jQuery( '#'+value ).remove(); 73 | 74 | jQuery('#mb-ajax-loading').remove(); 75 | }); 76 | } 77 | }); 78 | } 79 | 80 | /* remove reccord from the meta */ 81 | function removeMeta(value, id, element_id, nonce){ 82 | 83 | var response = confirm( "Delete this item ?" ); 84 | 85 | if( response == true ){ 86 | 87 | jQuery('#'+value).parent().css({'opacity':'0.4', 'position':'relative'}).append('
'); 88 | jQuery.post( ajaxurl , { action:"wck_remove_meta"+value, meta:value, id:id, element_id:element_id, _ajax_nonce:nonce}, function(response) { 89 | 90 | /* If single add the form */ 91 | if( jQuery( '#container_'+value ).hasClass('single') ){ 92 | jQuery.post( ajaxurl , { action:"wck_add_form"+value, meta:value, id:id }, function(response) { 93 | jQuery( '#container_'+value ).before( response ); 94 | jQuery( '#'+value ).addClass('single'); 95 | }); 96 | } 97 | 98 | /* refresh the list */ 99 | jQuery.post( ajaxurl , { action:"wck_refresh_list"+value, meta:value, id:id}, function(response) { 100 | jQuery('#container_'+value).replaceWith(response); 101 | 102 | jQuery('.mb-table-container tbody td').css('width', function(){ return jQuery(this).width() }); 103 | 104 | mb_sortable_elements(); 105 | jQuery('#'+value).parent().css('opacity','1'); 106 | jQuery('#mb-ajax-loading').remove(); 107 | }); 108 | 109 | }); 110 | } 111 | } 112 | 113 | /* swap two reccords */ 114 | /*function swapMetaMb(value, id, element_id, swap_with){ 115 | jQuery('#'+value).parent().css({'opacity':'0.4', 'position':'relative'}).append('
'); 116 | jQuery.post( ajaxurl , { action:"swap_meta_mb", meta:value, id:id, element_id:element_id, swap_with:swap_with}, function(response) { 117 | 118 | jQuery.post( ajaxurl , { action:"refresh_list", meta:value, id:id}, function(response) { 119 | jQuery('#container_'+value).replaceWith(response); jQuery('#'+value).parent().css('opacity','1'); jQuery('#mb-ajax-loading').remove(); 120 | }); 121 | 122 | }); 123 | } 124 | */ 125 | 126 | /* reorder elements through drag and drop */ 127 | function mb_sortable_elements() { 128 | jQuery( ".mb-table-container tbody" ).not( jQuery( ".mb-table-container.single tbody, .mb-table-container.not-sortable tbody" ) ).sortable({ 129 | update: function(event, ui){ 130 | 131 | var value = jQuery(this).parent().prev().attr('id'); 132 | var id = jQuery(this).parent().attr('post'); 133 | 134 | var result = jQuery(this).sortable('toArray'); 135 | 136 | var values = {}; 137 | for(var i in result) 138 | { 139 | values[i] = result[i].replace('element_',''); 140 | } 141 | 142 | jQuery('#'+value).parent().css({'opacity':'0.4', 'position':'relative'}).append('
'); 143 | 144 | jQuery.post( ajaxurl , { action:"wck_reorder_meta"+value, meta:value, id:id, values:values}, function(response) { 145 | jQuery.post( ajaxurl , { action:"wck_refresh_list"+value, meta:value, id:id}, function(response) { 146 | jQuery('#container_'+value).replaceWith(response); 147 | 148 | jQuery('.mb-table-container tbody td').css('width', function(){ return jQuery(this).width() }); 149 | 150 | mb_sortable_elements(); 151 | jQuery('#'+value).parent().css('opacity','1'); 152 | jQuery('#mb-ajax-loading').remove(); 153 | }); 154 | 155 | }); 156 | } 157 | }); 158 | jQuery( "#sortable" ).disableSelection(); 159 | 160 | 161 | jQuery('.mb-table-container ul').mousedown( function(e){ 162 | e.stopPropagation(); 163 | }); 164 | } 165 | jQuery(mb_sortable_elements); 166 | 167 | 168 | 169 | /* show the update form */ 170 | function showUpdateFormMeta(value, id, element_id, nonce){ 171 | if( jQuery( '#update_container_' + value + '_' + element_id ).length == 0 ){ 172 | jQuery('#container_'+value).parent().css({'opacity':'0.4', 'position':'relative'}).append('
'); 173 | 174 | jQuery( '#container_' + value + " tbody" ).sortable("disable"); 175 | 176 | jQuery.post( ajaxurl , { action:"wck_show_update"+value, meta:value, id:id, element_id:element_id, _ajax_nonce:nonce}, function(response) { 177 | //jQuery('#container_'+value+' #element_'+element_id).append(response); 178 | jQuery(response).insertAfter('#container_'+value+' #element_'+element_id); 179 | jQuery('#container_'+value).parent().css('opacity','1'); 180 | jQuery('#mb-ajax-loading').remove(); 181 | wckGoToByScroll('update_container_' + value + '_' + element_id); 182 | }); 183 | } 184 | } 185 | 186 | /* remove the update form */ 187 | function removeUpdateForm( id ){ 188 | jQuery( '#'+id ).remove(); 189 | } 190 | 191 | /* update reccord */ 192 | function updateMeta(value, id, element_id, nonce){ 193 | jQuery('#container_'+value).parent().css({'opacity':'0.4', 'position':'relative'}).append('
'); 194 | var values = {}; 195 | jQuery('#update_container_'+value+'_'+element_id+' .mb-field').each(function(){ 196 | var key = jQuery(this).attr('name'); 197 | 198 | if(jQuery(this).attr('type') == 'checkbox' || jQuery(this).attr('type') == 'radio' ) { 199 | 200 | if( typeof values[key.toString()] === "undefined" ) 201 | values[key.toString()] = ''; 202 | 203 | if(jQuery(this).is(':checked')){ 204 | if( values[key.toString()] == '' ) 205 | values[key.toString()] += jQuery(this).val().toString(); 206 | else 207 | values[key.toString()] += ', ' + jQuery(this).val().toString(); 208 | } 209 | } 210 | 211 | else 212 | values[key.toString()] = jQuery(this).val().toString(); 213 | 214 | }); 215 | 216 | jQuery.post( ajaxurl , { action:"wck_update_meta"+value, meta:value, id:id, element_id:element_id, values:values, _ajax_nonce:nonce}, function(response) { 217 | 218 | jQuery( '#update_container_'+value+'_'+element_id + ' .field-label').removeClass('error'); 219 | 220 | if( response.error ){ 221 | jQuery('#container_'+value).parent().css('opacity','1'); 222 | jQuery('#mb-ajax-loading').remove(); 223 | 224 | for( var i in response.errorfields ){ 225 | jQuery( '#update_container_'+value+'_'+element_id + ' .field-label[for="' + response.errorfields[i] + '"]' ).addClass('error'); 226 | } 227 | 228 | alert( response.error ); 229 | } 230 | else{ 231 | jQuery('#update_container_'+value+'_'+element_id).remove(); 232 | /* refresh the list */ 233 | jQuery.post( ajaxurl , { action:"wck_refresh_entry"+value, meta:value, id:id, element_id:element_id}, function(response) { 234 | jQuery('#container_'+value+' #element_'+element_id).replaceWith(response); 235 | 236 | jQuery('.mb-table-container tbody td').css('width', function(){ return jQuery(this).width() }); 237 | 238 | jQuery( '#container_' + value + " tbody" ).sortable("enable"); 239 | 240 | jQuery('#container_'+value).parent().css('opacity','1'); 241 | jQuery('#mb-ajax-loading').remove(); 242 | }); 243 | } 244 | }); 245 | } 246 | 247 | /* function syncs the translation */ 248 | function wckSyncTranslation(id){ 249 | jQuery.post( ajaxurl , { action:"wck_sync_translation", id:id}, function(response) { 250 | if( response == 'syncsuccess' ) 251 | window.location.reload(); 252 | }); 253 | } 254 | 255 | function wckGoToByScroll(id){ 256 | jQuery('html,body').animate({scrollTop: jQuery("#"+id).offset().top - 28},'slow'); 257 | } -------------------------------------------------------------------------------- /wordpress-creation-kit.php: -------------------------------------------------------------------------------- 1 | 'text', 'title' => 'Title', 'description' => 'Description for this input' ), 23 | array( 'type' => 'textarea', 'title' => 'Description' ), 24 | array( 'type' => 'upload', 'title' => 'Image', 'description' => 'Upload a image' ), 25 | array( 'type' => 'select', 'title' => 'Select This', 'options' => array( 'Option 1', 'Option 2', 'Option 3' ) ), 26 | array( 'type' => 'checkbox', 'title' => 'Check This', 'options' => array( 'Option 1', 'Option 2', 'Option 3' ) ), 27 | array( 'type' => 'radio', 'title' => 'Radio This', 'options' => array( 'Radio 1', 'Radio 2', 'Radio 3' ) ), 28 | ); 29 | 30 | $args = array( 31 | 'metabox_id' => 'rm_slider_content', 32 | 'metabox_title' => 'Slideshow Class', 33 | 'post_type' => 'slideshows', 34 | 'meta_name' => 'rmscontent', 35 | 'meta_array' => $fint 36 | ); 37 | 38 | new Wordpress_Creation_Kit( $args ); 39 | 40 | 41 | On the frontend: 42 | 43 | $meta = get_post_meta( $post->ID, 'rmscontent', true ); 44 | 45 | */ 46 | 47 | class WCK_CFC_Wordpress_Creation_Kit{ 48 | 49 | private $defaults = array( 50 | 'metabox_id' => '', 51 | 'metabox_title' => 'Meta Box', 52 | 'post_type' => 'post', 53 | 'meta_name' => '', 54 | 'meta_array' => array(), 55 | 'page_template' => '', 56 | 'post_id' => '', 57 | 'single' => false, 58 | 'wpml_compatibility' => false, 59 | 'sortable' => true, 60 | 'context' => 'post_meta' 61 | ); 62 | private $args; 63 | 64 | 65 | /* Constructor method for the class. */ 66 | function __construct( $args ) { 67 | 68 | /* Global that will hold all the arguments for all the custom boxes */ 69 | global $wck_objects; 70 | 71 | /* Merge the input arguments and the defaults. */ 72 | $this->args = wp_parse_args( $args, $this->defaults ); 73 | 74 | /* Add the settings for this box to the global object */ 75 | $wck_objects[$this->args['metabox_id']] = $this->args; 76 | 77 | /*print scripts*/ 78 | add_action('admin_enqueue_scripts', array( &$this, 'wck_print_scripts' )); 79 | 80 | // Set up the AJAX hooks 81 | add_action("wp_ajax_wck_add_meta".$this->args['meta_name'], array( &$this, 'wck_add_meta') ); 82 | add_action("wp_ajax_wck_update_meta".$this->args['meta_name'], array( &$this, 'wck_update_meta') ); 83 | add_action("wp_ajax_wck_show_update".$this->args['meta_name'], array( &$this, 'wck_show_update_form') ); 84 | add_action("wp_ajax_wck_refresh_list".$this->args['meta_name'], array( &$this, 'wck_refresh_list') ); 85 | add_action("wp_ajax_wck_refresh_entry".$this->args['meta_name'], array( &$this, 'wck_refresh_entry') ); 86 | add_action("wp_ajax_wck_add_form".$this->args['meta_name'], array( &$this, 'wck_add_form') ); 87 | add_action("wp_ajax_wck_remove_meta".$this->args['meta_name'], array( &$this, 'wck_remove_meta') ); 88 | //add_action("wp_ajax_swap_meta_mb", array( & $this, 'mb_swap_meta') ); 89 | add_action("wp_ajax_wck_reorder_meta".$this->args['meta_name'], array( &$this, 'wck_reorder_meta') ); 90 | 91 | /* modify Insert into post button */ 92 | add_action('admin_head-media-upload-popup', array( &$this, 'wck_media_upload_popup_head') ); 93 | 94 | /* custom functionality for upload video */ 95 | add_filter('media_send_to_editor', array( &$this, 'wck_media_send_to_editor' ), 15, 2 ); 96 | 97 | add_action('add_meta_boxes', array( &$this, 'wck_add_metabox') ); 98 | 99 | /* hook to add a side metabox with the Syncronize translation button */ 100 | add_action('add_meta_boxes', array( &$this, 'wck_add_sync_translation_metabox' ) ); 101 | 102 | /* ajax hook the syncronization function */ 103 | add_action("wp_ajax_wck_sync_translation", array( &$this, 'wck_sync_translation_ajax' ) ); 104 | 105 | } 106 | 107 | 108 | //add metabox using wordpress api 109 | 110 | function wck_add_metabox() { 111 | 112 | global $wck_pages_hooknames; 113 | 114 | if( $this->args['context'] == 'post_meta' ){ 115 | if( $this->args['post_id'] == '' && $this->args['page_template'] == '' ) 116 | add_meta_box($this->args['metabox_id'], $this->args['metabox_title'], array( &$this, 'wck_content' ), $this->args['post_type'], 'normal', 'low', array( 'meta_name' => $this->args['meta_name'], 'meta_array' => $this->args['meta_array']) ); 117 | else{ 118 | $post_id = $_GET['post'] ? $_GET['post'] : $_POST['post_ID'] ; 119 | 120 | if( $this->args['post_id'] != '' && $this->args['page_template'] != '' ){ 121 | $template_file = get_post_meta($post_id,'_wp_page_template',TRUE); 122 | if( $this->args['post_id'] == $post_id && $template_file == $this->args['page_template'] ) 123 | add_meta_box($this->args['metabox_id'], $this->args['metabox_title'], array( &$this, 'wck_content' ), 'page', 'normal', 'low', array( 'meta_name' => $this->args['meta_name'], 'meta_array' => $this->args['meta_array'] ) ); 124 | } 125 | else{ 126 | 127 | if( $this->args['post_id'] != '' ){ 128 | if( $this->args['post_id'] == $post_id ){ 129 | $post_type = get_post_type( $post_id ); 130 | add_meta_box($this->args['metabox_id'], $this->args['metabox_title'], array( &$this, 'wck_content' ), $post_type, 'normal', 'low', array( 'meta_name' => $this->args['meta_name'], 'meta_array' => $this->args['meta_array'] ) ); 131 | } 132 | } 133 | 134 | if( $this->args['page_template'] != '' ){ 135 | $template_file = get_post_meta($post_id,'_wp_page_template',TRUE); 136 | if ( $template_file == $this->args['page_template'] ) 137 | add_meta_box($this->args['metabox_id'], $this->args['metabox_title'], array( &$this, 'wck_content' ), 'page', 'normal', 'low', array( 'meta_name' => $this->args['meta_name'], 'meta_array' => $this->args['meta_array']) ); 138 | } 139 | 140 | } 141 | 142 | } 143 | } 144 | else if( $this->args['context'] == 'option' ){ 145 | add_meta_box($this->args['metabox_id'], $this->args['metabox_title'], array( &$this, 'wck_content' ), $wck_pages_hooknames[$this->args['post_type']], 'normal', 'low', array( 'meta_name' => $this->args['meta_name'], 'meta_array' => $this->args['meta_array']) ); 146 | } 147 | } 148 | 149 | function wck_content($post, $metabox){ 150 | //output the add form 151 | if( $this->args['single'] ){ 152 | 153 | if( $this->args['context'] == 'post_meta' ) 154 | $meta_val = get_post_meta( $post->ID, $metabox['args']['meta_name'], true ); 155 | else if ( $this->args['context'] == 'option' ) 156 | $meta_val = get_option( $metabox['args']['meta_name'] ); 157 | 158 | if( empty( $meta_val ) ) 159 | self::create_add_form($metabox['args']['meta_array'], $metabox['args']['meta_name'], $post); 160 | } 161 | else 162 | self::create_add_form($metabox['args']['meta_array'], $metabox['args']['meta_name'], $post); 163 | //output the entries 164 | echo self::wck_output_meta_content($metabox['args']['meta_name'], $post->ID, $metabox['args']['meta_array']); 165 | } 166 | 167 | /** 168 | * The function used to create a form element 169 | * 170 | * @since 1.0.0 171 | * 172 | * @param string $meta Meta name. 173 | * @param array $details Contains the details for the field. 174 | * @param string $value Contains input value; 175 | * @param string $context Context where the function is used. Depending on it some actions are preformed.; 176 | * @return string $element input element html string. 177 | */ 178 | 179 | function wck_output_form_field( $meta, $details, $value = '', $context = '' ){ 180 | $element = ''; 181 | 182 | if( $context == 'edit_form' ){ 183 | $edit_class = '.mb-table-container '; 184 | $var_prefix = 'edit'; 185 | } 186 | else{ 187 | if( !empty( $details['default'] ) ) 188 | $value = $details['default']; 189 | } 190 | 191 | 192 | $element .= ''; 196 | 197 | $element .= '
'; 198 | 199 | if($details['type'] == 'text'){ 200 | $element .= ''; 201 | } 202 | 203 | if($details['type'] == 'textarea'){ 204 | $element .= ''; 205 | } 206 | 207 | if($details['type'] == 'select'){ 208 | $element .= ''; 220 | } 221 | 222 | if($details['type'] == 'checkbox'){ 223 | 224 | if( !empty( $details['options'] ) ){ 225 | foreach( $details['options'] as $option ){ 226 | $found = false; 227 | 228 | if ( strpos($value, $option) !== false ) 229 | $found = true; 230 | $element .= '
' ; 231 | } 232 | } 233 | 234 | } 235 | 236 | if($details['type'] == 'radio'){ 237 | 238 | if( !empty( $details['options'] ) ){ 239 | foreach( $details['options'] as $option ){ 240 | $found = false; 241 | 242 | if ( strpos($value, $option) !== false ) 243 | $found = true; 244 | $element .= '
'; 245 | } 246 | } 247 | 248 | } 249 | 250 | 251 | if($details['type'] == 'upload'){ 252 | $element .= ''; 253 | $element .= 'Upload '. $details['title'] .' '; 254 | $element .= ''; 257 | } 258 | 259 | if( !empty( $details['description'] ) ){ 260 | $element .= '

'. $details['description'].'

'; 261 | } 262 | 263 | $element .= '
'; 264 | 265 | return $element; 266 | 267 | } 268 | 269 | 270 | /** 271 | * The function used to create the form for adding records 272 | * 273 | * @since 1.0.0 274 | * 275 | * @param array $fields Contains the desired inputs in the repeater field. Must be like: array('Key:type'). 276 | * Key is used for the name attribute of the field, label of the field and as the meta_key. 277 | * Supported types: input, textarea, upload 278 | * @param string $meta It is used in update_post_meta($id, $meta, $results);. Use '_' prefix if you don't want 279 | * the meta to apear in custom fields box. 280 | * @param object $post Post object 281 | */ 282 | function create_add_form($fields, $meta, $post){ 283 | $nonce = wp_create_nonce( 'wck-add-meta' ); 284 | ?> 285 |
args['single'] ) echo 'class="single"' ?>> 286 | 308 |
309 | args['context'] == 'post_meta' ) 327 | $results = get_post_meta($id, $meta, true); 328 | else if ( $this->args['context'] == 'option' ) 329 | $results = get_option( $meta ); 330 | 331 | $form = ''; 332 | $form .= ''; 333 | 334 | if($results != null){ 335 | $i = 0; 336 | $form .= ''; 360 | } 361 | //var_dump($$fields); 362 | $form .= ''; 363 | 364 | 365 | return $form; 366 | } 367 | 368 | 369 | /** 370 | * The function used to output the content of a meta 371 | * 372 | * @since 1.0.0 373 | * 374 | * @param string $meta It is used in get_post_meta($id, $meta, $results);. Use '_' prefix if you don't want 375 | * the meta to apear in custom fields box. 376 | * @param int $id Post id 377 | */ 378 | function wck_output_meta_content($meta, $id, $fields){ 379 | 380 | if( $this->args['context'] == 'post_meta' ) 381 | $results = get_post_meta($id, $meta, true); 382 | else if ( $this->args['context'] == 'option' ) 383 | $results = get_option( $meta ); 384 | 385 | $list = ''; 386 | $list .= ''; 392 | 393 | 394 | if($results != null){ 395 | $list .= ''; 396 | $i=0; 397 | foreach ($results as $result){ 398 | 399 | $list .= self::wck_output_entry_content( $meta, $id, $fields, $results, $i ); 400 | 401 | $i++; 402 | } 403 | } 404 | $list .= '
#ContentEditDelete
'; 405 | return $list; 406 | } 407 | 408 | function wck_output_entry_content( $meta, $id, $fields, $results, $element_id ){ 409 | $edit_nonce = wp_create_nonce( 'wck-edit-entry' ); 410 | $delete_nonce = wp_create_nonce( 'wck-delete-entry' ); 411 | $entry_nr = $element_id +1; 412 | 413 | $list = ''; 414 | $list .= ''; 415 | $list .= ''. $entry_nr .''; 416 | $list .= ''; 434 | $list .= 'Edit'; 435 | $list .= 'Delete'; 436 | 437 | $list .= ''; 438 | 439 | return $list; 440 | } 441 | 442 | /* enque the js*/ 443 | function wck_print_scripts($hook){ 444 | global $wck_pages_hooknames; 445 | 446 | if( $this->args['context'] == 'post_meta' ) { 447 | if( 'post.php' == $hook || 'post-new.php' == $hook){ 448 | wp_enqueue_script( 'jquery-ui-draggable' ); 449 | wp_enqueue_script( 'jquery-ui-droppable' ); 450 | wp_enqueue_script( 'jquery-ui-sortable' ); 451 | wp_enqueue_script('wordpress-creation-kit', plugins_url('/wordpress-creation-kit.js', __FILE__), array('jquery') ); 452 | wp_register_style('wordpress-creation-kit-css', plugins_url('/wordpress-creation-kit.css', __FILE__)); 453 | wp_enqueue_style('wordpress-creation-kit-css'); 454 | } 455 | } 456 | elseif( $this->args['context'] == 'option' ){ 457 | if( $wck_pages_hooknames[$this->args['post_type']] == $hook ){ 458 | wp_enqueue_script( 'jquery-ui-draggable' ); 459 | wp_enqueue_script( 'jquery-ui-droppable' ); 460 | wp_enqueue_script( 'jquery-ui-sortable' ); 461 | wp_enqueue_script('wordpress-creation-kit', plugins_url('/wordpress-creation-kit.js', __FILE__), array('jquery', 'jquery-ui-draggable', 'jquery-ui-droppable', 'jquery-ui-sortable' ) ); 462 | wp_register_style('wordpress-creation-kit-css', plugins_url('/wordpress-creation-kit.css', __FILE__)); 463 | wp_enqueue_style('wordpress-creation-kit-css'); 464 | } 465 | } 466 | } 467 | 468 | /* Helper function for required fields */ 469 | function wck_test_required( $meta, $values, $id ){ 470 | $fields = $this->args['meta_array']; 471 | $required_fields = array(); 472 | $required_fields_with_errors = array(); 473 | $required_message = ''; 474 | 475 | foreach( $fields as $field ){ 476 | if( $field['required'] ) 477 | $required_fields[sanitize_title_with_dashes( remove_accents ( $field['title'] ) )] = $field['title']; 478 | } 479 | 480 | foreach( $values as $key => $value ){ 481 | if( array_key_exists( $key, $required_fields ) && apply_filters( "wck_required_test_{$meta}_{$key}", empty( $value ), $value, $id ) ){ 482 | $required_message .= apply_filters( "wck_required_message_{$meta}_{$key}", "Please enter a value for the required field $required_fields[$key] \n", $value ); 483 | $required_fields_with_errors[] = $key; 484 | } 485 | } 486 | 487 | if( $required_message != '' ){ 488 | header( 'Content-type: application/json' ); 489 | die( json_encode( array( 'error' => $required_message, 'errorfields' => $required_fields_with_errors ) ) ); 490 | } 491 | 492 | } 493 | 494 | 495 | /* ajax add a reccord to the meta */ 496 | function wck_add_meta(){ 497 | check_ajax_referer( "wck-add-meta" ); 498 | $meta = $_POST['meta']; 499 | $id = absint($_POST['id']); 500 | $values = $_POST['values']; 501 | 502 | $values = apply_filters( "wck_add_meta_filter_values_{$meta}", $values ); 503 | 504 | /* check required fields */ 505 | self::wck_test_required( $meta, $values, $id ); 506 | 507 | if( $this->args['context'] == 'post_meta' ) 508 | $results = get_post_meta($id, $meta, true); 509 | else if ( $this->args['context'] == 'option' ) 510 | $results = get_option( $meta ); 511 | 512 | $results[] = $values; 513 | 514 | do_action( 'wck_before_add_meta', $meta, $id, $values ); 515 | 516 | if( $this->args['context'] == 'post_meta' ) 517 | update_post_meta($id, $meta, $results); 518 | else if ( $this->args['context'] == 'option' ) 519 | update_option( $meta, $results ); 520 | 521 | /* if wpml_compatibility is true add for each entry separete post meta for every element of the form */ 522 | if( $this->args['wpml_compatibility'] && $this->args['context'] == 'post_meta' ){ 523 | 524 | $meta_suffix = count( $results ); 525 | $i=1; 526 | foreach( $values as $name => $value ){ 527 | update_post_meta($id, 'wckwpml_'.$meta.'_'.$name.'_'.$meta_suffix.'_'.$i, $value); 528 | $i++; 529 | } 530 | } 531 | 532 | exit; 533 | } 534 | 535 | /* ajax update a reccord in the meta */ 536 | function wck_update_meta(){ 537 | check_ajax_referer( "wck-update-entry" ); 538 | $meta = $_POST['meta']; 539 | $id = absint($_POST['id']); 540 | $element_id = $_POST['element_id']; 541 | $values = $_POST['values']; 542 | 543 | $values = apply_filters( "wck_update_meta_filter_values_{$meta}", $values, $element_id ); 544 | 545 | /* check required fields */ 546 | self::wck_test_required( $meta, $values, $id ); 547 | 548 | if( $this->args['context'] == 'post_meta' ) 549 | $results = get_post_meta($id, $meta, true); 550 | else if ( $this->args['context'] == 'option' ) 551 | $results = get_option( $meta ); 552 | 553 | $results[$element_id] = $values; 554 | 555 | do_action( 'wck_before_update_meta', $meta, $id, $values, $element_id ); 556 | 557 | if( $this->args['context'] == 'post_meta' ) 558 | update_post_meta($id, $meta, $results); 559 | else if ( $this->args['context'] == 'option' ) 560 | update_option( $meta, $results ); 561 | 562 | /* if wpml_compatibility is true update the coresponding post metas for every element of the form */ 563 | if( $this->args['wpml_compatibility'] && $this->args['context'] == 'post_meta' ){ 564 | 565 | $meta_suffix = $element_id + 1; 566 | $i = 1; 567 | foreach( $values as $name => $value ){ 568 | update_post_meta($id, 'wckwpml_'.$meta.'_'.$name.'_'.$meta_suffix.'_'.$i, $value); 569 | $i++; 570 | } 571 | } 572 | 573 | exit; 574 | } 575 | 576 | /* ajax to refresh the meta content */ 577 | function wck_refresh_list(){ 578 | $meta = $_POST['meta']; 579 | $id = absint($_POST['id']); 580 | echo self::wck_output_meta_content($meta, $id, $this->args['meta_array']); 581 | 582 | do_action( "wck_refresh_list_{$meta}" ); 583 | 584 | exit; 585 | } 586 | 587 | /* ajax to refresh an entry content */ 588 | function wck_refresh_entry(){ 589 | $meta = $_POST['meta']; 590 | $id = absint($_POST['id']); 591 | $element_id = $_POST['element_id']; 592 | 593 | if( $this->args['context'] == 'post_meta' ) 594 | $results = get_post_meta($id, $meta, true); 595 | else if ( $this->args['context'] == 'option' ) 596 | $results = get_option( $meta ); 597 | 598 | echo self::wck_output_entry_content( $meta, $id, $this->args['meta_array'], $results, $element_id ); 599 | 600 | do_action( "wck_refresh_entry_{$meta}" ); 601 | 602 | exit; 603 | } 604 | 605 | /* ajax to add the form for single */ 606 | function wck_add_form(){ 607 | $meta = $_POST['meta']; 608 | $id = absint( $_POST['id'] ); 609 | $post = get_post($id); 610 | self::create_add_form($this->args['meta_array'], $meta, $post ); 611 | exit; 612 | } 613 | 614 | 615 | /* ajax to show the update form */ 616 | function wck_show_update_form(){ 617 | check_ajax_referer( "wck-edit-entry" ); 618 | $meta = $_POST['meta']; 619 | $id = absint($_POST['id']); 620 | $element_id = $_POST['element_id']; 621 | echo self::mb_update_form($this->args['meta_array'], $meta, $id, $element_id); 622 | exit; 623 | } 624 | 625 | /* ajax to remove a reccord from the meta */ 626 | function wck_remove_meta(){ 627 | check_ajax_referer( "wck-delete-entry" ); 628 | $meta = $_POST['meta']; 629 | $id = absint($_POST['id']); 630 | $element_id = absint($_POST['element_id']); 631 | 632 | if( $this->args['context'] == 'post_meta' ) 633 | $results = get_post_meta($id, $meta, true); 634 | else if ( $this->args['context'] == 'option' ) 635 | $results = get_option( $meta ); 636 | 637 | $old_results = $results; 638 | unset($results[$element_id]); 639 | /* reset the keys for the array */ 640 | $results = array_values($results); 641 | 642 | do_action( 'wck_before_remove_meta', $meta, $id, $element_id ); 643 | 644 | if( $this->args['context'] == 'post_meta' ) 645 | update_post_meta($id, $meta, $results); 646 | else if ( $this->args['context'] == 'option' ) 647 | update_option( $meta, $results ); 648 | 649 | 650 | 651 | /* TODO: optimize so that it updates from the deleted element forward */ 652 | /* if wpml_compatibility is true delete the coresponding post metas */ 653 | if( $this->args['wpml_compatibility'] && $this->args['context'] == 'post_meta' ){ 654 | 655 | $meta_suffix = 1; 656 | 657 | foreach( $results as $result ){ 658 | $i = 1; 659 | foreach ( $result as $name => $value){ 660 | update_post_meta($id, 'wckwpml_'.$meta.'_'.$name.'_'.$meta_suffix.'_'.$i, $value); 661 | $i++; 662 | } 663 | $meta_suffix++; 664 | } 665 | 666 | if( count( $results ) == 0 ) 667 | $results = $old_results; 668 | 669 | foreach( $results as $result ){ 670 | $i = 1; 671 | foreach ( $result as $name => $value){ 672 | delete_post_meta( $id, 'wckwpml_'.$meta.'_'.$name.'_'.$meta_suffix.'_'.$i ); 673 | $i++; 674 | } 675 | break; 676 | } 677 | } 678 | 679 | exit; 680 | } 681 | 682 | 683 | /* ajax to reorder records */ 684 | function wck_reorder_meta(){ 685 | $meta = $_POST['meta']; 686 | $id = absint($_POST['id']); 687 | $elements_id = $_POST['values']; 688 | 689 | if( $this->args['context'] == 'post_meta' ) 690 | $results = get_post_meta($id, $meta, true); 691 | else if ( $this->args['context'] == 'option' ) 692 | $results = get_option( $meta ); 693 | 694 | $new_results = array(); 695 | foreach($elements_id as $element_id){ 696 | $new_results[] = $results[$element_id]; 697 | } 698 | 699 | $results = $new_results; 700 | 701 | if( $this->args['context'] == 'post_meta' ) 702 | update_post_meta($id, $meta, $results); 703 | else if ( $this->args['context'] == 'option' ) 704 | update_option( $meta, $results ); 705 | 706 | 707 | /* if wpml_compatibility is true reorder all the coresponding post metas */ 708 | if( $this->args['wpml_compatibility'] && $this->args['context'] == 'post_meta' ){ 709 | 710 | $meta_suffix = 1; 711 | foreach( $new_results as $result ){ 712 | $i = 1; 713 | foreach ( $result as $name => $value){ 714 | update_post_meta($id, 'wckwpml_'.$meta.'_'.$name.'_'.$meta_suffix.'_'.$i, $value); 715 | $i++; 716 | } 717 | $meta_suffix++; 718 | } 719 | 720 | } 721 | 722 | exit; 723 | } 724 | 725 | /* modify Insert into post button */ 726 | function wck_media_upload_popup_head() 727 | { 728 | if( ( isset( $_GET["mb_type"] ) ) ) 729 | { 730 | ?> 731 | 756 | 776 | 791 | 798 | ID ); 822 | foreach( $custom_field_keys as $custom_field_key ){ 823 | $custom_field_key = explode( '_', $custom_field_key ); 824 | if( $custom_field_key[0] == 'wckwpml' ){ 825 | $has_wck_with_wpml_compatibility = true; 826 | break; 827 | } 828 | } 829 | 830 | if($has_wck_with_wpml_compatibility){ 831 | add_meta_box( 'wck_sync_translation', 'Syncronize WCK', array( &$this, 'wck_add_sync_box' ), $post->post_type, 'side', 'low' ); 832 | } 833 | 834 | } 835 | } 836 | 837 | /** 838 | * Callback for the add_meta_box function that ads the "Syncronize WCK Translation" button. 839 | */ 840 | function wck_add_sync_box(){ 841 | global $post; 842 | ?> 843 | 844 | = 5 ){ 870 | 871 | $cf_name = implode( '_', array_slice( $cf_name_array, 1, -3 ) ); 872 | 873 | if( $cf_name_array[0] == 'wckwpml' ){ 874 | 875 | $wck_key = $cf_name_array[ count($cf_name_array) -3 ]; 876 | $wck_position = $cf_name_array[ count($cf_name_array) -2 ]; 877 | $wck_field_position = $cf_name_array[ count($cf_name_array) -1 ]; 878 | 879 | /* "$wck_position - 1" is required because fields in wck by default start at 0 and the additional 880 | translation fields start at 1 */ 881 | $wck_array[$cf_name][$wck_position - 1][$wck_field_position][$wck_key] = get_post_meta($post_id,$cf,true); 882 | 883 | } 884 | } 885 | } 886 | 887 | 888 | 889 | if( !empty( $wck_array ) ){ 890 | /* sort the array so that the entry order and fields order are synced */ 891 | self::deep_ksort( $wck_array ); 892 | 893 | /* remove the field position level in the array because it was added just so we could keep the field 894 | order in place */ 895 | $wck_array = self::wck_reconstruct_array($wck_array); 896 | 897 | /* add the translated meta to the post */ 898 | foreach( $wck_array as $wck_key => $wck_meta ){ 899 | update_post_meta( $post_id, $wck_key, $wck_meta ); 900 | } 901 | echo('syncsuccess'); 902 | } 903 | 904 | exit; 905 | } 906 | 907 | /** 908 | * Function that deep sorts a multy array by numeric key 909 | */ 910 | function deep_ksort(&$arr) { 911 | ksort($arr); 912 | foreach ($arr as &$a) { 913 | if (is_array($a) && !empty($a)) { 914 | self::deep_ksort($a); 915 | } 916 | } 917 | } 918 | 919 | /** 920 | * Function that removes the field position level 921 | */ 922 | function wck_reconstruct_array($wck_array){ 923 | foreach( $wck_array as $wck_array_key => $wck_meta ){ 924 | foreach( $wck_meta as $wck_meta_key => $wck_entry ){ 925 | foreach( $wck_entry as $wck_entry_key => $wck_field ){ 926 | $wck_array[$wck_array_key][$wck_meta_key][key($wck_field)] = current($wck_field); 927 | unset($wck_array[$wck_array_key][$wck_meta_key][$wck_entry_key]); 928 | } 929 | } 930 | } 931 | return $wck_array; 932 | } 933 | 934 | 935 | function wck_get_meta_boxes( $screen = null ){ 936 | global $wp_meta_boxes, $wck_objects; 937 | 938 | if ( empty( $screen ) ) 939 | $screen = get_current_screen(); 940 | elseif ( is_string( $screen ) ) 941 | $screen = convert_to_screen( $screen ); 942 | 943 | $page = $screen->id; 944 | 945 | $wck_meta_boxes = array(); 946 | 947 | if( !empty( $wck_objects ) && !empty( $wp_meta_boxes[$page]['normal']['low'] ) ){ 948 | foreach( $wck_objects as $key => $wck_object ){ 949 | if( array_key_exists( $key, $wp_meta_boxes[$page]['normal']['low'] ) ) 950 | $wck_meta_boxes[] = $key; 951 | } 952 | } 953 | 954 | return $wck_meta_boxes; 955 | } 956 | } 957 | 958 | 959 | /* 960 | Helper class that creates admin menu pages ( both top level menu pages and submenu pages ) 961 | Default Usage: 962 | 963 | $args = array( 964 | 'page_type' => 'menu_page', 965 | 'page_title' => '', 966 | 'menu_title' => '', 967 | 'capability' => '', 968 | 'menu_slug' => '', 969 | 'icon_url' => '', 970 | 'position' => '', 971 | 'parent_slug' => '' 972 | ); 973 | 974 | 'page_type' (string) (required) The type of page you want to add. Possible values: 'menu_page', 'submenu_page' 975 | 'page_title' (string) (required) The text to be displayed in the title tags and header of 976 | the page when the menu is selected 977 | 'menu_title' (string) (required) The on-screen name text for the menu 978 | 'capability' (string) (required) The capability required for this menu to be displayed to 979 | the user. 980 | 'menu_slug' (string) (required) The slug name to refer to this menu by (should be unique 981 | for this menu). 982 | 'icon_url' (string) (optional for 'page_type' => 'menu_page') The url to the icon to be used for this menu. 983 | This parameter is optional. Icons should be fairly small, around 16 x 16 pixels 984 | for best results. 985 | 'position' (integer) (optional for 'page_type' => 'menu_page') The position in the menu order this menu 986 | should appear. 987 | By default, if this parameter is omitted, the menu will appear at the bottom 988 | of the menu structure. The higher the number, the lower its position in the menu. 989 | WARNING: if 2 menu items use the same position attribute, one of the items may be 990 | overwritten so that only one item displays! 991 | 'parent_slug' (string) (required for 'page_type' => 'submenu_page' ) The slug name for the parent menu 992 | (or the file name of a standard WordPress admin page) For examples see http://codex.wordpress.org/Function_Reference/add_submenu_page $parent_slug parameter 993 | 'priority' (int) (optional) How important your function is. Alter this to make your function 994 | be called before or after other functions. The default is 10, so (for example) setting it to 5 would make it run earlier and setting it to 12 would make it run later. 995 | 996 | public $hookname ( for required for 'page_type' => 'menu_page' ) string used internally to 997 | track menu page callbacks for outputting the page inside the global $menu array 998 | ( for required for 'page_type' => 'submenu_page' ) The resulting page's hook_suffix, 999 | or false if the user does not have the capability required. 1000 | */ 1001 | 1002 | class WCK_CFC_WCK_Page_Creator{ 1003 | 1004 | private $defaults = array( 1005 | 'page_type' => 'menu_page', 1006 | 'page_title' => '', 1007 | 'menu_title' => '', 1008 | 'capability' => '', 1009 | 'menu_slug' => '', 1010 | 'icon_url' => '', 1011 | 'position' => '', 1012 | 'parent_slug' => '', 1013 | 'priority' => 10, 1014 | 'network_page' => false 1015 | ); 1016 | private $args; 1017 | public $hookname; 1018 | 1019 | 1020 | /* Constructor method for the class. */ 1021 | function __construct( $args ) { 1022 | 1023 | /* Global that will hold all the arguments for all the menu pages */ 1024 | global $wck_pages; 1025 | 1026 | /* Merge the input arguments and the defaults. */ 1027 | $this->args = wp_parse_args( $args, $this->defaults ); 1028 | 1029 | /* Add the settings for this page to the global object */ 1030 | $wck_pages[$this->args['page_title']] = $this->args; 1031 | 1032 | if( !$this->args['network_page'] ){ 1033 | /* Hook the page function to 'admin_menu'. */ 1034 | add_action( 'admin_menu', array( &$this, 'wck_page_init' ), $this->args['priority'] ); 1035 | } 1036 | else{ 1037 | /* Hook the page function to 'admin_menu'. */ 1038 | add_action( 'network_admin_menu', array( &$this, 'wck_page_init' ), $this->args['priority'] ); 1039 | } 1040 | } 1041 | 1042 | /** 1043 | * Function that creates the admin page 1044 | */ 1045 | function wck_page_init(){ 1046 | global $wck_pages_hooknames; 1047 | 1048 | /* Create the page using either add_menu_page or add_submenu_page functions depending on the 'page_type' parameter. */ 1049 | if( $this->args['page_type'] == 'menu_page' ){ 1050 | $this->hookname = add_menu_page( $this->args['page_title'], $this->args['menu_title'], $this->args['capability'], $this->args['menu_slug'], array( &$this, 'wck_page_template' ), $this->args['icon_url'], $this->args['position'] ); 1051 | 1052 | $wck_pages_hooknames[$this->args['menu_slug']] = $this->hookname; 1053 | } 1054 | else if( $this->args['page_type'] == 'submenu_page' ){ 1055 | $this->hookname = add_submenu_page( $this->args['parent_slug'], $this->args['page_title'], $this->args['menu_title'], $this->args['capability'], $this->args['menu_slug'], array( &$this, 'wck_page_template' ) ); 1056 | 1057 | $wck_pages_hooknames[$this->args['menu_slug']] = $this->hookname; 1058 | } 1059 | 1060 | /* Create a hook for adding meta boxes. */ 1061 | add_action( "load-{$this->hookname}", array( &$this, 'wck_settings_page_add_meta_boxes' ) ); 1062 | /* Load the JavaScript needed for the screen. */ 1063 | add_action( 'admin_enqueue_scripts', array( &$this, 'wck_page_enqueue_scripts' ) ); 1064 | add_action( "admin_head-{$this->hookname}", array( &$this, 'wck_page_load_scripts' ) ); 1065 | } 1066 | 1067 | /** 1068 | * Do action 'add_meta_boxes'. This hook isn't executed bu default on a admin page so we have ot add it. 1069 | */ 1070 | function wck_settings_page_add_meta_boxes() { 1071 | do_action( 'add_meta_boxes', $this->hookname ); 1072 | } 1073 | 1074 | /** 1075 | * Loads the JavaScript files required for managing the meta boxes on the theme settings 1076 | * page, which allows users to arrange the boxes to their liking. 1077 | * 1078 | * @global string $bareskin_settings_page. The global setting page (returned by add_theme_page in function 1079 | * bareskin_settings_page_init ). 1080 | * @since 1.0.0 1081 | * @param string $hook The current page being viewed. 1082 | */ 1083 | function wck_page_enqueue_scripts( $hook ) { 1084 | if ( $hook == $this->hookname ) { 1085 | wp_enqueue_script( 'common' ); 1086 | wp_enqueue_script( 'wp-lists' ); 1087 | wp_enqueue_script( 'postbox' ); 1088 | } 1089 | } 1090 | 1091 | /** 1092 | * Loads the JavaScript required for toggling the meta boxes on the theme settings page. 1093 | * 1094 | * @global string $bareskin_settings_page. The global setting page (returned by add_theme_page in function 1095 | * bareskin_settings_page_init ). 1096 | * @since 1.0.0 1097 | */ 1098 | function wck_page_load_scripts() { 1099 | ?> 1100 | 1116 |
1117 | 1118 |

args['page_title'] ?>

1119 | 1120 |
1121 | 1122 | 1123 | 1124 | 1125 | hookname ); ?> 1126 | 1127 |
1128 |
hookname, 'side', null ); ?>
1129 |
1130 |
hookname, 'normal', null ); ?>
1131 |
hookname, 'advanced', null ); ?>
1132 | 1133 |
1134 | 1135 | hookname ); ?> 1136 | 1137 |
1138 | 1139 |
1140 | --------------------------------------------------------------------------------