wp/wp-content/plugins/option-tree/includes/class-ot-meta-box.php
changeset 11 bf1778c34b9a
equal deleted inserted replaced
10:372f2766ea20 11:bf1778c34b9a
       
     1 <?php
       
     2 /**
       
     3  * OptionTree Meta Box.
       
     4  *
       
     5  * @package OptionTree
       
     6  */
       
     7 
       
     8 if ( ! defined( 'OT_VERSION' ) ) {
       
     9 	exit( 'No direct script access allowed' );
       
    10 }
       
    11 
       
    12 if ( ! class_exists( 'OT_Meta_Box' ) ) {
       
    13 
       
    14 	/**
       
    15 	 * OptionTree Meta Box class.
       
    16 	 *
       
    17 	 * This class loads all the methods and helpers specific to build a meta box.
       
    18 	 */
       
    19 	class OT_Meta_Box {
       
    20 
       
    21 		/**
       
    22 		 * Stores the meta box config array.
       
    23 		 *
       
    24 		 * @var string
       
    25 		 */
       
    26 		private $meta_box;
       
    27 
       
    28 		/**
       
    29 		 * Class constructor.
       
    30 		 *
       
    31 		 * This method adds other methods of the class to specific hooks within WordPress.
       
    32 		 *
       
    33 		 * @uses add_action()
       
    34 		 *
       
    35 		 * @access public
       
    36 		 * @since  1.0
       
    37 		 *
       
    38 		 * @param array $meta_box Meta box config array.
       
    39 		 */
       
    40 		public function __construct( $meta_box ) {
       
    41 			if ( ! is_admin() ) {
       
    42 				return;
       
    43 			}
       
    44 
       
    45 			global $ot_meta_boxes;
       
    46 
       
    47 			if ( ! isset( $ot_meta_boxes ) ) {
       
    48 				$ot_meta_boxes = array();
       
    49 			}
       
    50 
       
    51 			$ot_meta_boxes[] = $meta_box;
       
    52 
       
    53 			$this->meta_box = $meta_box;
       
    54 
       
    55 			add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
       
    56 
       
    57 			add_action( 'save_post', array( $this, 'save_meta_box' ), 1, 2 );
       
    58 		}
       
    59 
       
    60 		/**
       
    61 		 * Adds meta box to any post type
       
    62 		 *
       
    63 		 * @uses add_meta_box()
       
    64 		 *
       
    65 		 * @access public
       
    66 		 * @since  1.0
       
    67 		 */
       
    68 		public function add_meta_boxes() {
       
    69 			global $wp_version;
       
    70 
       
    71 			$is_wp_5 = version_compare( $wp_version, '5.0', '>=' );
       
    72 
       
    73 			foreach ( (array) $this->meta_box['pages'] as $page ) {
       
    74 				add_meta_box( $this->meta_box['id'], $this->meta_box['title'], array( $this, 'build_meta_box' ), $page, $this->meta_box['context'], $this->meta_box['priority'], $this->meta_box['fields'] );
       
    75 
       
    76 				if ( $is_wp_5 ) {
       
    77 					add_filter(
       
    78 						'postbox_classes_' . $page . '_' . $this->meta_box['id'],
       
    79 						function( $classes ) {
       
    80 							array_push( $classes, 'ot-meta-box' );
       
    81 							return $classes;
       
    82 						}
       
    83 					);
       
    84 				}
       
    85 			}
       
    86 		}
       
    87 
       
    88 		/**
       
    89 		 * Meta box view.
       
    90 		 *
       
    91 		 * @access public
       
    92 		 * @since  1.0
       
    93 		 *
       
    94 		 * @param object $post   The WP_Post object.
       
    95 		 * @param array  $fields The meta box fields.
       
    96 		 */
       
    97 		public function build_meta_box( $post, $fields ) {
       
    98 			unset( $fields ); // @todo Check if the loop can use this param.
       
    99 
       
   100 			echo '<div class="ot-metabox-wrapper">';
       
   101 
       
   102 			// Use nonce for verification.
       
   103 			echo '<input type="hidden" name="' . esc_attr( $this->meta_box['id'] ) . '_nonce" value="' . esc_attr( wp_create_nonce( $this->meta_box['id'] ) ) . '" />';
       
   104 
       
   105 			// Meta box description.
       
   106 			echo isset( $this->meta_box['desc'] ) && ! empty( $this->meta_box['desc'] ) ? '<div class="description" style="padding-top:10px;">' . htmlspecialchars_decode( $this->meta_box['desc'] ) . '</div>' : ''; // phpcs:ignore
       
   107 
       
   108 			// Loop through meta box fields.
       
   109 			foreach ( $this->meta_box['fields'] as $field ) {
       
   110 
       
   111 				// Get current post meta data.
       
   112 				$field_value = get_post_meta( $post->ID, $field['id'], true );
       
   113 
       
   114 				// Set standard value.
       
   115 				if ( isset( $field['std'] ) ) {
       
   116 					$field_value = ot_filter_std_value( $field_value, $field['std'] );
       
   117 				}
       
   118 
       
   119 				// Build the arguments array.
       
   120 				$_args = array(
       
   121 					'type'               => $field['type'],
       
   122 					'field_id'           => $field['id'],
       
   123 					'field_name'         => $field['id'],
       
   124 					'field_value'        => $field_value,
       
   125 					'field_desc'         => isset( $field['desc'] ) ? $field['desc'] : '',
       
   126 					'field_std'          => isset( $field['std'] ) ? $field['std'] : '',
       
   127 					'field_rows'         => isset( $field['rows'] ) && ! empty( $field['rows'] ) ? $field['rows'] : 10,
       
   128 					'field_post_type'    => isset( $field['post_type'] ) && ! empty( $field['post_type'] ) ? $field['post_type'] : 'post',
       
   129 					'field_taxonomy'     => isset( $field['taxonomy'] ) && ! empty( $field['taxonomy'] ) ? $field['taxonomy'] : 'category',
       
   130 					'field_min_max_step' => isset( $field['min_max_step'] ) && ! empty( $field['min_max_step'] ) ? $field['min_max_step'] : '0,100,1',
       
   131 					'field_class'        => isset( $field['class'] ) ? $field['class'] : '',
       
   132 					'field_condition'    => isset( $field['condition'] ) ? $field['condition'] : '',
       
   133 					'field_operator'     => isset( $field['operator'] ) ? $field['operator'] : 'and',
       
   134 					'field_choices'      => isset( $field['choices'] ) ? $field['choices'] : array(),
       
   135 					'field_settings'     => isset( $field['settings'] ) && ! empty( $field['settings'] ) ? $field['settings'] : array(),
       
   136 					'post_id'            => $post->ID,
       
   137 					'meta'               => true,
       
   138 				);
       
   139 
       
   140 				$conditions = '';
       
   141 
       
   142 				// Setup the conditions.
       
   143 				if ( isset( $field['condition'] ) && ! empty( $field['condition'] ) ) {
       
   144 					$conditions  = ' data-condition="' . esc_attr( $field['condition'] ) . '"';
       
   145 					$conditions .= isset( $field['operator'] ) && in_array( $field['operator'], array( 'and', 'AND', 'or', 'OR' ), true ) ? ' data-operator="' . esc_attr( $field['operator'] ) . '"' : '';
       
   146 				}
       
   147 
       
   148 				// Only allow simple textarea due to DOM issues with wp_editor().
       
   149 				if ( false === apply_filters( 'ot_override_forced_textarea_simple', false, $field['id'] ) && 'textarea' === $_args['type'] ) {
       
   150 					$_args['type'] = 'textarea-simple';
       
   151 				}
       
   152 
       
   153 				// Build the setting CSS class.
       
   154 				if ( ! empty( $_args['field_class'] ) ) {
       
   155 
       
   156 					$classes = explode( ' ', $_args['field_class'] );
       
   157 
       
   158 					foreach ( $classes as $key => $value ) {
       
   159 
       
   160 						$classes[ $key ] = $value . '-wrap';
       
   161 
       
   162 					}
       
   163 
       
   164 					$class = 'format-settings ' . implode( ' ', $classes );
       
   165 				} else {
       
   166 
       
   167 					$class = 'format-settings';
       
   168 				}
       
   169 
       
   170 				// Option label.
       
   171 				echo '<div id="setting_' . esc_attr( $field['id'] ) . '" class="' . esc_attr( $class ) . '"' . $conditions . '>'; // phpcs:ignore
       
   172 
       
   173 				echo '<div class="format-setting-wrap">';
       
   174 
       
   175 				// Don't show title with textblocks.
       
   176 				if ( 'textblock' !== $_args['type'] && ! empty( $field['label'] ) ) {
       
   177 					echo '<div class="format-setting-label">';
       
   178 					echo '<label for="' . esc_attr( $field['id'] ) . '" class="label">' . esc_html( $field['label'] ) . '</label>';
       
   179 					echo '</div>';
       
   180 				}
       
   181 
       
   182 				// Get the option HTML.
       
   183 				echo ot_display_by_type( $_args ); // phpcs:ignore
       
   184 
       
   185 				echo '</div>';
       
   186 
       
   187 				echo '</div>';
       
   188 
       
   189 			}
       
   190 
       
   191 			echo '<div class="clear"></div>';
       
   192 
       
   193 			echo '</div>';
       
   194 		}
       
   195 
       
   196 		/**
       
   197 		 * Saves the meta box values
       
   198 		 *
       
   199 		 * @access public
       
   200 		 * @since  1.0
       
   201 		 *
       
   202 		 * @param  int    $post_id The post ID.
       
   203 		 * @param  object $post_object The WP_Post object.
       
   204 		 * @return int|void
       
   205 		 */
       
   206 		public function save_meta_box( $post_id, $post_object ) {
       
   207 			global $pagenow;
       
   208 
       
   209 			// Verify nonce.
       
   210 			if ( isset( $_POST[ $this->meta_box['id'] . '_nonce' ] ) && ! wp_verify_nonce( $_POST[ $this->meta_box['id'] . '_nonce' ], $this->meta_box['id'] ) ) { // phpcs:ignore
       
   211 				return $post_id;
       
   212 			}
       
   213 
       
   214 			// Store the post global for use later.
       
   215 			$post_global = $_POST;
       
   216 
       
   217 			// Don't save if $_POST is empty.
       
   218 			if ( empty( $post_global ) || ( isset( $post_global['vc_inline'] ) && true === $post_global['vc_inline'] ) ) {
       
   219 				return $post_id;
       
   220 			}
       
   221 
       
   222 			// Don't save during quick edit.
       
   223 			if ( 'admin-ajax.php' === $pagenow ) {
       
   224 				return $post_id;
       
   225 			}
       
   226 
       
   227 			// Don't save during autosave.
       
   228 			if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
       
   229 				return $post_id;
       
   230 			}
       
   231 
       
   232 			// Don't save if viewing a revision.
       
   233 			if ( 'revision' === $post_object->post_type || 'revision.php' === $pagenow ) {
       
   234 				return $post_id;
       
   235 			}
       
   236 
       
   237 			// Check permissions.
       
   238 			if ( isset( $post_global['post_type'] ) && 'page' === $post_global['post_type'] ) {
       
   239 				if ( ! current_user_can( 'edit_page', $post_id ) ) {
       
   240 					return $post_id;
       
   241 				}
       
   242 			} else {
       
   243 				if ( ! current_user_can( 'edit_post', $post_id ) ) {
       
   244 					return $post_id;
       
   245 				}
       
   246 			}
       
   247 
       
   248 			foreach ( $this->meta_box['fields'] as $field ) {
       
   249 
       
   250 				$old = get_post_meta( $post_id, $field['id'], true );
       
   251 				$new = '';
       
   252 
       
   253 				// There is data to validate.
       
   254 				if ( isset( $post_global[ $field['id'] ] ) ) {
       
   255 
       
   256 					// Slider and list item.
       
   257 					if ( in_array( $field['type'], array( 'list-item', 'slider' ), true ) ) {
       
   258 
       
   259 						// Required title setting.
       
   260 						$required_setting = array(
       
   261 							array(
       
   262 								'id'        => 'title',
       
   263 								'label'     => __( 'Title', 'option-tree' ),
       
   264 								'desc'      => '',
       
   265 								'std'       => '',
       
   266 								'type'      => 'text',
       
   267 								'rows'      => '',
       
   268 								'class'     => 'option-tree-setting-title',
       
   269 								'post_type' => '',
       
   270 								'choices'   => array(),
       
   271 							),
       
   272 						);
       
   273 
       
   274 						// Convert the settings to an array.
       
   275 						$settings = isset( $post_global[ $field['id'] . '_settings_array' ] ) ? ot_decode( $post_global[ $field['id'] . '_settings_array' ] ) : array();
       
   276 
       
   277 						// Settings are empty for some odd reason get the defaults.
       
   278 						if ( empty( $settings ) ) {
       
   279 							$settings = ( 'slider' === $field['type'] ) ? ot_slider_settings( $field['id'] ) : ot_list_item_settings( $field['id'] );
       
   280 						}
       
   281 
       
   282 						// Merge the two settings array.
       
   283 						$settings = array_merge( $required_setting, $settings );
       
   284 
       
   285 						foreach ( $post_global[ $field['id'] ] as $k => $setting_array ) {
       
   286 
       
   287 							foreach ( $settings as $sub_setting ) {
       
   288 
       
   289 								// Verify sub setting has a type & value.
       
   290 								if ( isset( $sub_setting['type'] ) && isset( $post_global[ $field['id'] ][ $k ][ $sub_setting['id'] ] ) ) {
       
   291 
       
   292 									$post_global[ $field['id'] ][ $k ][ $sub_setting['id'] ] = ot_validate_setting( $post_global[ $field['id'] ][ $k ][ $sub_setting['id'] ], $sub_setting['type'], $sub_setting['id'] );
       
   293 								}
       
   294 							}
       
   295 						}
       
   296 
       
   297 						// Set up new data with validated data.
       
   298 						$new = $post_global[ $field['id'] ];
       
   299 
       
   300 					} elseif ( 'social-links' === $field['type'] ) {
       
   301 
       
   302 						// Convert the settings to an array.
       
   303 						$settings = isset( $post_global[ $field['id'] . '_settings_array' ] ) ? ot_decode( $post_global[ $field['id'] . '_settings_array' ] ) : array();
       
   304 
       
   305 						// Settings are empty get the defaults.
       
   306 						if ( empty( $settings ) ) {
       
   307 							$settings = ot_social_links_settings( $field['id'] );
       
   308 						}
       
   309 
       
   310 						foreach ( $post_global[ $field['id'] ] as $k => $setting_array ) {
       
   311 
       
   312 							foreach ( $settings as $sub_setting ) {
       
   313 
       
   314 								// Verify sub setting has a type & value.
       
   315 								if ( isset( $sub_setting['type'] ) && isset( $post_global[ $field['id'] ][ $k ][ $sub_setting['id'] ] ) ) {
       
   316 									$post_global[ $field['id'] ][ $k ][ $sub_setting['id'] ] = ot_validate_setting( $post_global[ $field['id'] ][ $k ][ $sub_setting['id'] ], $sub_setting['type'], $sub_setting['id'] );
       
   317 								}
       
   318 							}
       
   319 						}
       
   320 
       
   321 						// Set up new data with validated data.
       
   322 						$new = $post_global[ $field['id'] ];
       
   323 					} else {
       
   324 
       
   325 						// Run through validation.
       
   326 						$new = ot_validate_setting( $post_global[ $field['id'] ], $field['type'], $field['id'] );
       
   327 					}
       
   328 
       
   329 					// Insert CSS.
       
   330 					if ( 'css' === $field['type'] ) {
       
   331 
       
   332 						if ( '' !== $new ) {
       
   333 
       
   334 							// insert CSS into dynamic.css.
       
   335 							ot_insert_css_with_markers( $field['id'], $new, true );
       
   336 						} else {
       
   337 
       
   338 							// Remove old CSS from dynamic.css.
       
   339 							ot_remove_old_css( $field['id'] );
       
   340 						}
       
   341 					}
       
   342 				}
       
   343 
       
   344 				if ( isset( $new ) && $new !== $old ) {
       
   345 					update_post_meta( $post_id, $field['id'], $new );
       
   346 				} elseif ( '' === $new && $old ) {
       
   347 					delete_post_meta( $post_id, $field['id'], $old );
       
   348 				}
       
   349 			}
       
   350 		}
       
   351 
       
   352 	}
       
   353 
       
   354 }
       
   355 
       
   356 if ( ! function_exists( 'ot_register_meta_box' ) ) {
       
   357 
       
   358 	/**
       
   359 	 * This method instantiates the meta box class & builds the UI.
       
   360 	 *
       
   361 	 * @uses OT_Meta_Box()
       
   362 	 *
       
   363 	 * @param array $args Meta box arguments.
       
   364 	 *
       
   365 	 * @access public
       
   366 	 * @since  2.0
       
   367 	 */
       
   368 	function ot_register_meta_box( $args ) {
       
   369 		if ( ! $args ) {
       
   370 			return;
       
   371 		}
       
   372 
       
   373 		new OT_Meta_Box( $args );
       
   374 	}
       
   375 }