id = $name;
$this->name = $name . '[]';
$this->title = $title;
$this->args = wp_parse_args( $args, array(
'repeatable' => false,
'std' => '',
'default' => '',
'show_label' => false,
'taxonomy' => '',
'hide_empty' => false,
'data_delegate' => null,
'options' => array(),
'cols' => '12',
'style' => '',
'class' => '',
'readonly' => false,
'disabled' => false
)
);
if ( ! empty( $this->args['std'] ) && empty( $this->args['default'] ) ) {
$this->args['default'] = $this->args['std'];
_deprecated_argument( 'CMB_Field', "'std' is deprecated, use 'default instead'", '0.9' );
}
if ( ! empty( $this->args['options'] ) && is_array( reset( $this->args['options'] ) ) ) {
$re_format = array();
foreach ( $this->args['options'] as $option )
$re_format[$option['value']] = $option['name'];
$this->args['options'] = $re_format;
}
// If the field has a custom value populator callback
if ( ! empty( $args['values_callback'] ) )
$this->values = call_user_func( $args['values_callback'], get_the_id() );
else
$this->values = $values;
$this->value = reset( $this->values );
$this->description = ! empty( $this->args['desc'] ) ? $this->args['desc'] : '';
}
/**
* Enqueue all scripts required by the field.
*
* @uses wp_enqueue_script()
*/
public function enqueue_scripts() {
if ( isset( $this->args['sortable'] ) && $this->args['sortable'] )
wp_enqueue_script( 'jquery-ui-sortable' );
}
/**
* Enqueue all styles required by the field.
*
* @uses wp_enqueue_style()
*/
public function enqueue_styles() {
}
/**
* Output the field input ID attribute.
*
* If multiple inputs are required for a single field,
* use the append parameter to add unique identifier.
*
* @param string $append
* @return null
*/
public function id_attr( $append = null ) {
printf( 'id="%s"', esc_attr( $this->get_the_id_attr( $append ) ) );
}
/**
* Output the for attribute for the field.
*
*
*
* If multiple inputs are required for a single field,
* use the append parameter to add unique identifier.
*
* @param string $append
* @return null
*/
public function get_the_id_attr( $append = null ) {
$id = $this->id;
if ( isset( $this->parent ) ) {
$parent_id = preg_replace( '/cmb\-field\-(\d|x)+/', 'cmb-group-$1', $this->parent->get_the_id_attr() );
$id = $parent_id . '[' . $id . ']';
}
$id .= '-cmb-field-' . $this->field_index;
if ( ! is_null( $append ) )
$id .= '-' . $append;
$id = str_replace( array( '[', ']', '--' ), '-', $id );
return $id;
}
/**
* Return the field input ID attribute value.
*
* If multiple inputs are required for a single field,
* use the append parameter to add unique identifier.
*
* @param string $append
* @return string id attribute value.
*/
public function for_attr( $append = null ) {
printf( 'for="%s"', esc_attr( $this->get_the_id_attr( $append ) ) );
}
public function name_attr( $append = null ) {
printf( 'name="%s"', esc_attr( $this->get_the_name_attr( $append ) ) );
}
public function get_the_name_attr( $append = null ) {
$name = str_replace( '[]', '', $this->name );
if ( isset( $this->parent ) ) {
$parent_name = preg_replace( '/cmb\-field\-(\d+|x)/', 'cmb-group-$1', $this->parent->get_the_name_attr() );
$name = $parent_name . '[' . $name . ']';
}
$name .= "[cmb-field-$this->field_index]";
if ( ! is_null( $append ) )
$name .= $append;
return $name;
}
public function class_attr( $classes = '' ) {
if ( $classes = implode( ' ', array_map( 'sanitize_html_class', array_filter( array_unique( explode( ' ', $classes . ' ' . $this->args['class'] ) ) ) ) ) ) { ?>
class=""
get_the_id_attr() ); // JS friendly ID
}
public function boolean_attr( $attrs = array() ) {
if ( $this->args['readonly'] )
$attrs[] = 'readonly';
if ( $this->args['disabled'] )
$attrs[] = 'disabled';
$attrs = array_filter( array_unique( $attrs ) );
foreach ( $attrs as $attr )
echo esc_html( $attr ) . '="' . esc_attr( $attr ) . '"';
}
/**
* Check if this field has a data delegate set
*
* @return boolean
*/
public function has_data_delegate() {
return (bool) $this->args['data_delegate'];
}
/**
* Get the array of data from the data delegate
*
* @return array mixed
*/
protected function get_delegate_data() {
if ( $this->args['data_delegate'] )
return call_user_func_array( $this->args['data_delegate'], array( $this ) );
return array();
}
public function get_value() {
return ( $this->value || $this->value === '0' ) ? $this->value : $this->args['default'];
}
public function &get_values() {
return $this->values;
}
public function set_values( array $values ) {
$this->values = $values;
unset( $this->value );
}
public function parse_save_values() {}
public function parse_save_value() {}
/**
* @todo this surely only works for posts
* @todo why do values need to be passed in, they can already be passed in on construct
*/
public function save( $post_id, $values ) {
// Don't save readonly values.
if ( $this->args['readonly'] )
return;
$this->values = $values;
$this->parse_save_values();
// Allow override from args
if ( ! empty( $this->args['save_callback'] ) ) {
call_user_func( $this->args['save_callback'], $this->values, $post_id );
return;
}
// If we are not on a post edit screen
if ( ! $post_id )
return;
delete_post_meta( $post_id, $this->id );
foreach( $this->values as $v ) {
$this->value = $v;
$this->parse_save_value();
if ( $this->value || $this->value === '0' )
add_post_meta( $post_id, $this->id, $this->value );
}
}
public function title() {
if ( $this->title ) { ?>
description ) { ?>
description ); ?>
get_values() && ! $this->args['repeatable'] )
$values = array( '' );
else
$values = $this->get_values();
$this->title();
$this->description();
$i = 0;
foreach ( $values as $key => $value ) {
$this->field_index = $i;
$this->value = $value; ?>
args['repeatable'] ) : ?>
html(); ?>
args['repeatable'] ) {
$this->field_index = 'x'; // x used to distinguish hidden fields.
$this->value = ''; ?>
args['repeatable'] ) : ?>
html(); ?>
id_attr(); ?> boolean_attr(); ?> class_attr(); ?> name_attr(); ?> value="get_value() ); ?>" />
args['class'] .= ' cmb_text_small';
parent::html();
}
}
/**
* Field for image upload / file updoad.
*
* @todo ability to set image size (preview image) from caller
*/
class CMB_File_Field extends CMB_Field {
function enqueue_scripts() {
parent::enqueue_scripts();
wp_enqueue_media();
wp_enqueue_script( 'cmb-file-upload', trailingslashit( CMB_URL ) . 'js/file-upload.js', array( 'jquery', 'cmb-scripts' ) );
}
public function html() {
$args = wp_parse_args( $this->args, array(
'library-type' => array( 'video', 'audio', 'text', 'application' )
) );
if ( $this->get_value() ) {
$src = wp_mime_type_icon( $this->get_value() );
$size = getimagesize($src);
$icon_img = '
';
}
$data_type = ( ! empty( $args['library-type'] ) ? implode( ',', $args['library-type'] ) : null );
?>
>
get_value() ) : ?>
get_value() ) ) ); ?>
name_attr(); ?> value="value ); ?>" />
args = wp_parse_args( $this->args, array(
'size' => 'thumbnail',
'library-type' => array( 'image' ),
'show_size' => false
) );
if ( $this->get_value() )
$image = wp_get_attachment_image_src( $this->get_value(), $args['size'], true );
// Convert size arg to array of width, height, crop.
$size = $this->parse_image_size( $args['size'] );
// Inline styles.
$styles = sprintf( 'width: %1$dpx; height: %2$dpx; line-height: %2$dpx', intval( $size['width'] ), intval( $size['height'] ) );
$placeholder_styles = sprintf( 'width: %dpx; height: %dpx;', intval( $size['width'] ) - 8, intval( $size['height'] ) - 8 );
$data_type = ( ! empty( $args['library-type'] ) ? implode( ',', $args['library-type'] ) : null );
?>
name_attr(); ?> value="value ); ?>" />
get_option( $size . '_size_w' ),
'height' => get_option( $size . '_size_h' ),
'crop' => get_option( $size . '_crop' )
);
}
// Handle string for additional image sizes
global $_wp_additional_image_sizes;
if ( is_string( $size ) && isset( $_wp_additional_image_sizes[$size] ) ) {
return array(
'width' => $_wp_additional_image_sizes[$size]['width'],
'height' => $_wp_additional_image_sizes[$size]['height'],
'crop' => $_wp_additional_image_sizes[$size]['crop']
);
}
// Handle default WP size format.
if ( is_array( $size ) && isset( $size[0] ) && isset( $size[1] ) )
$size = array( 'width' => $size[0], 'height' => $size[1] );
return wp_parse_args( $size, array(
'width' => get_option( 'thumbnail_size_w' ),
'height' => get_option( 'thumbnail_size_h' ),
'crop' => get_option( 'thumbnail_crop' )
) );
}
/**
* Ajax callback for outputing an image src based on post data.
*
* @return null
*/
static function request_image_ajax_callback() {
if ( ! ( isset( $_POST['nonce'] ) && wp_verify_nonce( $_POST['nonce'], 'cmb-file-upload-nonce' ) ) )
return;
$id = intval( $_POST['id'] );
$size = array(
intval( $_POST['width'] ),
intval( $_POST['height'] ),
'crop' => (bool) $_POST['crop']
);
$image = wp_get_attachment_image_src( $id, $size );
echo reset( $image );
die(); // this is required to return a proper result
}
}
add_action( 'wp_ajax_cmb_request_image', array( 'CMB_Image_Field', 'request_image_ajax_callback' ) );
/**
* Standard text meta box for a URL.
*
*/
class CMB_URL_Field extends CMB_Field {
public function html() { ?>
id_attr(); ?> boolean_attr(); ?> class_attr( 'cmb_text_url code' ); ?> name_attr(); ?> value="value ) ); ?>" />
id_attr(); ?> boolean_attr(); ?> class_attr( 'cmb_text_small cmb_datepicker' ); ?> type="text" name_attr(); ?> value="value ); ?>" />
id_attr(); ?> boolean_attr(); ?> class_attr( 'cmb_text_small cmb_timepicker' ); ?> type="text" name_attr(); ?> value="value ); ?>"/>
id_attr(); ?> boolean_attr(); ?> class_attr( 'cmb_text_small cmb_datepicker' ); ?> type="text" name_attr(); ?> value="value ? esc_attr( date( 'm\/d\/Y', $this->value ) ) : '' ?>" />
values as &$value )
$value = strtotime( $value );
sort( $this->values );
}
}
/**
* Date picker for date and time (seperate fields) box.
*
*/
class CMB_Datetime_Timestamp_Field extends CMB_Field {
public function enqueue_scripts() {
parent::enqueue_scripts();
wp_enqueue_style( 'cmb-jquery-ui', trailingslashit( CMB_URL ) . 'css/vendor/jquery-ui/jquery-ui.css', '1.10.3' );
wp_enqueue_script( 'cmb-timepicker', trailingslashit( CMB_URL ) . 'js/jquery.timePicker.min.js', array( 'jquery', 'cmb-scripts' ) );
wp_enqueue_script( 'cmb-datetime', trailingslashit( CMB_URL ) . 'js/field.datetime.js', array( 'jquery', 'jquery-ui-core', 'jquery-ui-datepicker', 'cmb-scripts' ) );
}
public function html() { ?>
id_attr('date'); ?> boolean_attr(); ?> class_attr( 'cmb_text_small cmb_datepicker' ); ?> type="text" name_attr( '[date]' ); ?> value="value ? esc_attr( date( 'm\/d\/Y', $this->value ) ) : '' ?>" />
id_attr('time'); ?> boolean_attr(); ?> class_attr( 'cmb_text_small cmb_timepicker' ); ?> type="text" name_attr( '[time]' ); ?> value="value ? esc_attr( date( 'h:i A', $this->value ) ) : '' ?>" />
values as $key => &$value ) {
if ( empty( $value['date'] ) )
unset( $this->values[$key] );
else
$value = strtotime( $value['date'] . ' ' . $value['time'] );
}
$this->values = array_filter( $this->values );
sort( $this->values );
parent::parse_save_values();
}
}
/**
* Standard text field.
*
* Args:
* - int "rows" - number of rows in the