/** * Function for handling the widget control in admin panel. * * @access private * @since 1.0 * * @param array $instance * * @return void */ public function form($instance) { // Setup the default widget options. $title = isset($instance['title']) && strlen($instance['title']) > 0 ? esc_html($instance['title']) : __('Hobbies', 'connections_hobbies'); cnHTML::text(array('prefix' => '', 'class' => 'widefat', 'id' => $this->get_field_id('title'), 'name' => $this->get_field_name('title'), 'label' => __('Title:', 'connections_hobbies'), 'before' => '<p>', 'after' => '</p>'), $title); }
/** * Renders the Template admin page. * * @access private * @since unknown */ function connectionsShowTemplatesPage() { /* * Check whether user can edit Settings */ if (!current_user_can('connections_manage_template')) { wp_die('<p id="error-page" style="-moz-background-clip:border; -moz-border-radius:11px; background:#FFFFFF none repeat scroll 0 0; border:1px solid #DFDFDF; color:#333333; display:block; font-size:12px; line-height:18px; margin:25px auto 20px; padding:1em 2em; text-align:center; width:700px">' . __('You do not have sufficient permissions to access this page.', 'connections') . '</p>'); } else { // Grab an instance of the Connections object. $instance = Connections_Directory(); $type = isset($_GET['type']) ? esc_attr($_GET['type']) : 'all'; $templates = cnTemplateFactory::getCatalog($type); $adminURL = self_admin_url('admin.php'); $pageURL = add_query_arg('page', 'connections_templates', $adminURL); $homeID = cnSettingsAPI::get('connections', 'connections_home_page', 'page_id'); $homeURL = get_permalink($homeID); $customizerURL = add_query_arg('cn-customize-template', 'true', $homeURL); ?> <div class="wrap"> <h1>Connections : <?php _e('Templates', 'connections'); ?> <a class="button add-new-h2" href="http://connections-pro.com/templates/" target="_blank"><?php _e('Get More', 'connections'); ?> </a> </h1> <ul class="subsubsub"> <li> <a <?php if ('all' == $type) { echo 'class="current" '; } ?> href="<?php echo esc_url(add_query_arg('type', 'all', $pageURL)); ?> "> <?php _e('All', 'connections'); ?> </a> | </li> <li> <a <?php if ('individual' == $type) { echo 'class="current" '; } ?> href="<?php echo esc_url(add_query_arg('type', 'individual', $pageURL)); ?> "> <?php _e('Individual', 'connections'); ?> </a> | </li> <li> <a <?php if ('organization' == $type) { echo 'class="current" '; } ?> href="<?php echo esc_url(add_query_arg('type', 'organization', $pageURL)); ?> "> <?php _e('Organization', 'connections'); ?> </a> | </li> <li> <a <?php if ('family' == $type) { echo 'class="current" '; } ?> href="<?php echo esc_url(add_query_arg('type', 'family', $pageURL)); ?> "> <?php _e('Family', 'connections'); ?> </a> | </li> <li> <a <?php if ('anniversary' == $type) { echo 'class="current" '; } ?> href="<?php echo esc_url(add_query_arg('type', 'anniversary', $pageURL)); ?> "> <?php _e('Anniversary', 'connections'); ?> </a> | </li> <li> <a <?php if ('birthday' == $type) { echo 'class="current" '; } ?> href="<?php echo esc_url(add_query_arg('type', 'birthday', $pageURL)); ?> "> <?php _e('Birthday', 'connections'); ?> </a> </li> </ul> <br class="clear"> <table cellspacing="0" cellpadding="0" id="currenttheme"> <tbody> <tr> <td class="current_template"> <h2><?php _e('Current Template', 'connections'); ?> </h2> <div id="current-template"> <?php $slug = $instance->options->getActiveTemplate($type); /** @var cnTemplate $activeTemplate */ $activeTemplate = cnTemplateFactory::getTemplate($slug); if ($activeTemplate) { cnTemplateThumbnail($activeTemplate); cnTemplateAuthor($activeTemplate); cnTemplateDescription($activeTemplate); cnTemplateCustomizerButton($activeTemplate, $customizerURL, $pageURL); // Remove the current template so it does not show in the available templates. unset($templates->{$activeTemplate->getSlug()}); } else { echo '<h3 class="error"> Template ', esc_attr($slug), ' can not be found.</h3>'; } ?> </div> <div class="clear"></div> </td> <td class="template_instructions" colspan="2"> <p> <strong><?php _e('Instructions', 'connections'); ?> :</strong> </p> <p> <?php _e('By default the <code><a href="http://connections-pro.com/documentation/connections/shortcodes/shortcode-connections/">[connections]</a></code> shortcode will show all entries types. To change the template used when displaying all entry types, select the "All" tab and activate the template. When the <code><a href="http://connections-pro.com/documentation/connections/shortcodes/shortcode-connections/list_type/">list_type</a></code>shortcode option is used to filter the entries based on the entry type, the template for that entry type will be used. To change the template used for a specific entry type, select the appropriate tab and then activate the template. If multiple entry types are specified in the <code><a href="http://connections-pro.com/documentation/connections/shortcodes/shortcode-connections/list_type/">list_type</a></code> shortcode option, the template for the entry type listed first will be used to display the entry list.', 'connections'); ?> </p> <p> <?php _e('The <code><a href="http://connections-pro.com/documentation/connections/shortcodes/shortcode-upcoming-list/">[upcoming_list]</a></code> shortcode which displays the upcoming anniversaries and birthdays will be displayed with the template that is activated under their respective tabs.', 'connections'); ?> </p> <p> <?php _e('The current active template for each template type can be overridden by using the <code><a href="http://connections-pro.com/documentation/connections/shortcodes/shortcode-connections/template-option/">template</a></code> shortcode option.', 'connections'); ?> </p> </td> </tr> </tbody> </table> <!-- /#currenttheme --> <table cellspacing="0" cellpadding="0" id="availablethemes"> <tbody> <tr> <td class="current_template" colspan="3"> <h2><?php _e('Available Templates', 'connections'); ?> </h2> </td> </tr> <?php $slugs = array_keys((array) $templates); natcasesort($slugs); $table = array(); $rows = ceil(count($slugs) / 3); for ($row = 1; $row <= $rows; $row++) { for ($col = 1; $col <= 3; $col++) { $table[$row][$col] = array_shift($slugs); } } foreach ($table as $row => $cols) { ?> <tr> <?php foreach ($cols as $col => $slug) { if (!isset($templates->{$slug})) { continue; } /** @var cnTemplate $template */ $template = $templates->{$slug}; $class = array('available-theme'); if ($row == 1) { $class[] = 'top'; } if ($row == $rows) { $class[] = 'bottom'; } if ($col == 1) { $class[] = 'left'; } if ($col == 3) { $class[] = 'right'; } ?> <td <?php echo cnHTML::attribute('class', $class); ?> > <?php cnTemplateThumbnail($template); cnTemplateAuthor($template); cnTemplateDescription($template); cnTemplateDeactivateText($template); cnTemplateShortcodeOverride($template); ?> <span class="action-links"> <?php cntemplateActivateButton($template, $type); cnTemplateDeleteButton($template); cnTemplateCustomizerButton($template, $customizerURL, $pageURL); ?> </span> </td> <?php } ?> </tr> <?php } ?> </tbody> </table> <!-- /#availablethemes --> </div> <!-- /.wrap --> <?php } }
/** * Render the fields registered to the metabox. * * The $fields property is an indexed array of fields and their properties. * Accepted option for are: * id (string) The field ID. This value MUST be unique. * desc (string) [optional] The field description. * type (string) The type of field which should be registered. This can be any of the supported field types or a custom field type. * Core supported field types are: * checkbox * checkboxgroup * radio * radio_inline * select * text (input) * textarea * datepicker * slider * quicktag * rte * value (mixed) string | array [optional] The function name or class method to be used retrieve a value for the field. * size (string) [optional] The size if the text input and textarea field types. * NOTE: Only used for the `text` field type. Valid options: small', 'regular' or 'large' * NOTE: Only used for the `textarea` field type. Valid options: small' or 'large' * options (mixed) string | array [optional] Valid value depends on the field type being rendered. * Field type / valid value for options * checkboxgroup (array) An associative array where the key is the checkbox value and the value is the checkbox label. * radio / radio_inline (array) An associative array where the key is the radio value and the value is the radio label. * select (array) An associative array where the key is the option value and the value is the option name. * rte (array) @link http://codex.wordpress.org/Function_Reference/wp_editor#Arguments * slider (array) The slider options. * min (int) The minimum slider step. * max (int) The maximum slider step. * step (int) The step the slider steps at. * default (mixed) The default value to be used. * * @access private * @since 0.8 * @global $wp_version * @param $fields array An indexed array of fields to render.. * * @return string */ private function fields($fields) { global $wp_version; // do_action( 'cn_metabox_table_before', $entry, $meta, $this->metabox ); foreach ($fields as $field) { $defaults = array('before' => '', 'after' => '', 'desc' => ''); $field = wp_parse_args($field, $defaults); // If the meta field has a specific method defined call the method and set the field value. // Otherwise, assume pulling from the meta table of the supplied object. if (isset($field['value']) && !empty($field['value'])) { $value = call_user_func(array($this->object, $field['value'])); } else { $value = $this->object->getMeta(array('key' => $field['id'], 'single' => TRUE)); } if (empty($value)) { $value = isset($field['default']) ? $field['default'] : ''; } /** * Apply custom classes to a metabox table. * * @since 8.3.4 * * @param array $class An indexed array of classes that should applied to the table element. * @param string $type The field type. * @param string $id The field id. */ $class = apply_filters('cn_metabox_table_class', array('cn-metabox-type-' . $field['type']), $field['type'], $field['id']); /** * Apply a custom id to a metabox table. * * @since 8.3.4 * * @param string $id The field id. */ $id = apply_filters('cn_metabox_table_id', 'cn-metabox-id-' . $field['id']); /** * Apply custom classes to a metabox table. * * @since 8.3.4 * * @param array $style An associative array of inline style attributes where the array key is the property and the array value is the property value. * @param string $type The field type. * @param string $id The field id. */ $style = apply_filters('cn_metabox_table_style', array(), $field['type'], $field['id']); $class = cnHTML::attribute('class', $class); $id = cnHTML::attribute('id', $id); $style = cnHTML::attribute('style', $style); echo '<tr' . $class . $id . $style . '>'; // For a label to be rendered the $field['name'] has to be supplied. // Show the label if $field['show_label'] is TRUE, OR, if it is not supplied assume TRUE and show it anyway. // The result will be the label will be shown unless specifically $field['show_label'] is set to FALSE. if (isset($field['name']) && !empty($field['name']) && (!isset($field['show_label']) || $field['show_label'] == TRUE)) { echo '<th class="cn-metabox-label">' . esc_html($field['name']) . '</th>'; } elseif (isset($field['name']) && !empty($field['name']) && (isset($field['show_label']) && $field['show_label'] == TRUE)) { echo '<th class="cn-metabox-label">' . esc_html($field['name']) . '</th>'; } elseif (!isset($field['show_label']) || $field['show_label'] == FALSE) { echo '<th class="cn-metabox-label-empty"> </th>'; } echo '<td>'; echo empty($field['before']) ? '' : $field['before']; /** * Apply custom classes to the field type container element. * * NOTE: The dynamic portion of the hook is the field type. * * @since 8.3.4 * * @param array $class An indexed array of classes that should applied to the element. * @param string $id The field id. */ $class = apply_filters("cn_metabox_{$field['type']}_class", array("cn-meta-field-type-{$field['type']}"), $field['id']); /** * Apply a custom id to the field type container element. * * NOTE: The dynamic portion of the hook is the field type. * * @since 8.3.4 * * @param string $id The field id. */ $id = apply_filters("cn_metabox_{$field['type']}_id", ''); /** * Apply custom classes to a field type container element. * * NOTE: The dynamic portion of the hook is the field type. * * @since 8.3.4 * * @param array $style An associative array of inline style attributes * where the array key is the property and the array value is the property value. * @param string $id The field id. */ $style = apply_filters("cn_metabox_{$field['type']}_style", array(), $field['id']); $class = cnHTML::attribute('class', $class); $id = cnHTML::attribute('id', $id); $style = cnHTML::attribute('style', $style); /** * Chance to manipulate the field value before rendering the field. * * NOTE: The dynamic portion of the hook is the field type. * * @since 0.8 * * @param mixed $value The field value. * @param array $field The field attributes array. */ $value = apply_filters("cn_meta_field_value-{$field['type']}", $value, $field); switch ($field['type']) { case 'checkbox': cnHTML::field(array('type' => 'checkbox', 'prefix' => '', 'class' => 'cn-checkbox', 'id' => $field['id'], 'name' => $field['id'], 'label' => $field['desc'], 'before' => '<div' . $class . $id . $style . '>', 'after' => '</div>'), $value); break; case 'checkboxgroup': case 'checkbox-group': self::fieldDescription($field['desc']); cnHTML::field(array('type' => 'checkbox-group', 'prefix' => '', 'class' => 'cn-checkbox', 'id' => $field['id'], 'name' => $field['id'] . '[]', 'display' => 'block', 'options' => $field['options'], 'before' => '<div' . $class . $id . $style . '>', 'after' => '</div>'), $value); break; case 'radio': self::fieldDescription($field['desc']); cnHTML::field(array('type' => 'radio', 'prefix' => '', 'class' => 'cn-radio-option', 'id' => $field['id'], 'name' => $field['id'] . '[]', 'display' => 'block', 'options' => $field['options'], 'before' => '<div' . $class . $id . $style . '>', 'after' => '</div>'), $value); break; case 'radio_inline': case 'radio-inline': self::fieldDescription($field['desc']); cnHTML::field(array('type' => 'radio', 'prefix' => '', 'class' => 'cn-radio-option', 'id' => $field['id'], 'name' => $field['id'] . '[]', 'display' => 'inline', 'options' => $field['options'], 'before' => '<div' . $class . $id . $style . '>', 'after' => '</div>'), $value); break; case 'select': cnHTML::field(array('type' => 'select', 'prefix' => '', 'class' => 'cn-select', 'id' => $field['id'], 'name' => $field['id'], 'display' => 'inline', 'options' => $field['options'], 'before' => '<div' . $class . $id . $style . '>', 'after' => '</div>'), $value); self::fieldDescription($field['desc']); break; case 'text': $sizes = array('small', 'regular', 'large'); cnHTML::field(array('type' => 'text', 'prefix' => '', 'class' => isset($field['size']) && !empty($field['size']) && in_array($field['size'], $sizes) ? esc_attr($field['size']) . '-text' : 'large-text', 'id' => $field['id'], 'name' => $field['id'], 'before' => '<div' . $class . $id . $style . '>', 'after' => '</div>'), $value); self::fieldDescription($field['desc']); break; case 'textarea': $sizes = array('small', 'large'); self::fieldDescription($field['desc']); cnHTML::field(array('type' => 'textarea', 'prefix' => '', 'class' => isset($field['size']) && !empty($field['size']) && in_array($field['size'], $sizes) ? esc_attr($field['size']) . '-text' : 'small-text', 'id' => $field['id'], 'name' => $field['id'], 'rows' => 10, 'cols' => 50, 'before' => '<div' . $class . $id . $style . '>', 'after' => '</div>'), $value); break; case 'datepicker': printf('<input type="text" class="cn-datepicker" id="%1$s" name="%1$s" value="%2$s"/>', esc_attr($field['id']), !empty($value) ? date('m/d/Y', strtotime($value)) : ''); wp_enqueue_script('jquery-ui-datepicker'); wp_enqueue_style('cn-admin-jquery-datepicker'); add_action('admin_print_footer_scripts', array(__CLASS__, 'datepickerJS')); add_action('wp_footer', array(__CLASS__, 'datepickerJS')); self::fieldDescription($field['desc']); break; case 'colorpicker': self::fieldDescription($field['desc']); printf('<input type="text" class="cn-colorpicker" id="%1$s" name="%1$s" value="%2$s"/>', esc_attr($field['id']), esc_attr($value)); wp_enqueue_style('wp-color-picker'); if (is_admin()) { wp_enqueue_script('wp-color-picker'); add_action('admin_print_footer_scripts', array(__CLASS__, 'colorpickerJS')); } else { /* * WordPress seems to only register the color picker scripts for use in the admin. * So, for the frontend, we must manually register and then enqueue. * @url http://wordpress.stackexchange.com/a/82722/59053 */ wp_enqueue_script('iris', admin_url('js/iris.min.js'), array('jquery-ui-draggable', 'jquery-ui-slider', 'jquery-touch-punch'), FALSE, 1); wp_enqueue_script('wp-color-picker', admin_url('js/color-picker.min.js'), array('iris'), FALSE, 1); $colorpicker_l10n = array('clear' => __('Clear', 'connections'), 'defaultString' => __('Default', 'connections'), 'pick' => __('Select Color', 'connections'), 'current' => __('Current Color', 'connections')); wp_localize_script('wp-color-picker', 'wpColorPickerL10n', $colorpicker_l10n); add_action('wp_footer', array(__CLASS__, 'colorpickerJS')); } break; case 'slider': // Set the slider defaults. $defaults = array('min' => 0, 'max' => 100, 'step' => 1, 'value' => 0); $field['options'] = wp_parse_args(isset($field['options']) ? $field['options'] : array(), $defaults); printf('<div class="cn-slider-container" id="cn-slider-%1$s"></div><input type="text" class="small-text" id="%1$s" name="%1$s" value="%2$s"/>', esc_attr($field['id']), absint($value)); self::fieldDescription($field['desc']); $field['options']['value'] = absint($value); self::$slider[$field['id']] = $field['options']; wp_enqueue_script('jquery-ui-slider'); add_action('admin_print_footer_scripts', array(__CLASS__, 'sliderJS')); add_action('wp_footer', array(__CLASS__, 'sliderJS')); break; case 'quicktag': self::fieldDescription($field['desc']); echo '<div class="wp-editor-container">'; printf('<textarea class="wp-editor-area" rows="20" cols="40" id="%1$s" name="%1$s">%2$s</textarea>', esc_attr($field['id']), wp_kses_data($value)); echo '</div>'; self::$quickTagIDs[] = esc_attr($field['id']); wp_enqueue_script('jquery'); add_action('admin_print_footer_scripts', array(__CLASS__, 'quickTagJS')); add_action('wp_print_footer_scripts', array(__CLASS__, 'quickTagJS')); break; case 'rte': self::fieldDescription($field['desc']); if ($wp_version >= 3.3 && function_exists('wp_editor')) { // Set the rte defaults. $defaults = array('textarea_name' => sprintf('%1$s', $field['id'])); $atts = wp_parse_args(isset($field['options']) ? $field['options'] : array(), $defaults); wp_editor(cnSanitize::html($value), sprintf('%1$s', $field['id']), $atts); } else { /* * If this is pre WP 3.3, lets drop in the quick tag editor instead. */ echo '<div class="wp-editor-container">'; printf('<textarea class="wp-editor-area" rows="20" cols="40" id="%1$s" name="%1$s">%2$s</textarea>', esc_attr($field['id']), cnSanitize::quicktag($value)); echo '</div>'; self::$quickTagIDs[] = esc_attr($field['id']); wp_enqueue_script('jquery'); add_action('admin_print_footer_scripts', array(__CLASS__, 'quickTagJS')); add_action('wp_print_footer_scripts', array(__CLASS__, 'quickTagJS')); } break; case 'repeatable': echo '<table id="' . esc_attr($field['id']) . '-repeatable" class="meta_box_repeatable" cellspacing="0">'; echo '<tbody>'; $i = 0; // create an empty array if ($meta == '' || $meta == array()) { $keys = wp_list_pluck($field['repeatable'], 'id'); $meta = array(array_fill_keys($keys, NULL)); } $meta = array_values($meta); foreach ($meta as $row) { echo '<tr> <td><span class="sort hndle"></span></td><td>'; // foreach ( $field['repeatable'] as $repeatable ) { // if ( ! array_key_exists( $repeatable['id'], $meta[ $field['id'] ] ) ) $meta[ $field['id'] ][ $repeatable['id'] ] = NULL; // echo '<label>' . $repeatable['label'] . '</label><p>'; // self::fields( $repeatable, $meta[ $i ][ $repeatable['id'] ], array( $field['id'], $i ) ); // echo '</p>'; // } self::fields($field['repeatable']); echo '</td><td><a class="meta_box_repeatable_remove" href="#"></a></td></tr>'; $i++; } // end each row echo '</tbody>'; echo ' <tfoot> <tr> <th colspan="4"><a class="meta_box_repeatable_add" href="#"></a></th> </tr> </tfoot>'; echo '</table>'; break; default: do_action('cn_meta_field-' . $field['type'], $field, $value, $this->object); break; } echo empty($field['after']) ? '' : $field['after']; echo '</td>', '</tr>'; } // do_action( 'cn_metabox_table_after', $entry, $meta, $this->metabox ); }
/** * Email log type filter. * * @access protected * @since 8.3 * * @param string $which */ protected function extra_tablenav($which) { if ('top' !== $which) { return; } $emailLogTypes = wp_list_pluck(cnLog_Email::types(), 'name', 'id'); unset($emailLogTypes[cnLog_Email::LOG_TYPE]); cnHTML::select(array('id' => 'type', 'default' => array(-1 => __('View All', 'connections')), 'options' => $emailLogTypes), $this->type); submit_button('Filter', 'secondary', 'filter_action', FALSE, array('id' => 'email-log-query-submit')); }
<?php // Exit if accessed directly if (!defined('ABSPATH')) { exit; } /** * @var cnOutput $entry */ $style = array('background-color' => '#FFF', 'border' => $atts['border_width'] . 'px solid ' . $atts['border_color'], 'border-radius' => $atts['border_radius'] . 'px', 'color' => '#000', 'margin' => '8px 0', 'padding' => '10px', 'position' => 'relative'); $bio = $entry->getBio(); $notes = $entry->getNotes(); ?> <div class="cn-entry" <?php echo cnHTML::attribute('style', $style); ?> > <div class="cn-left" style="width:49%; float:<?php echo is_rtl() ? 'right' : 'left'; ?> "> <?php if ('none' !== $atts['image_type']) { $entry->getImage(array('image' => $atts['image_type'], 'width' => $atts['image_width'], 'height' => $atts['image_height'], 'zc' => $atts['image_crop_mode'], 'fallback' => array('type' => $atts['image_fallback'] ? 'block' : 'none', 'string' => $atts['image_fallback_string']))); } ?> <div style="clear:both;"></div> <div style="margin-bottom: 10px;"> <div style="font-size:larger;font-variant: small-caps"><strong><?php echo $entry->getNameBlock(array('format' => $atts['name_format']));
/** * Renders a radio group. * * This is deprecated method, left in place for backward compatibility only. * * @access private * @deprecated * @since 0.8 * @param string $name The input option id/name value. * @param string $id UNUSED * @param array $options An associative array. Key is the option name and the value is the option value. * @param string $value [optional] The selected option. * * @return string */ public function buildRadio($name, $id, $options, $value = '') { $radio = cnHTML::field(array('type' => 'radio', 'display' => 'block', 'class' => '', 'id' => $name, 'options' => array_flip($options), 'required' => FALSE, 'return' => TRUE), $value); return $radio; }
/** * Display or retrieve the HTML select list of terms. * * This is the Connections equivalent of @see wp_dropdown_categories() in WordPress core ../wp-includes/category-template.php * * @access public * @since 8.2.4 * @static * * @uses wp_parse_args() * @uses cnTerm::getTaxonomyTerms() * @uses esc_attr() * @uses sanitize_html_class() * @uses apply_filters() * @uses Walker::walk() * @uses selected() * * @param array $atts { * Optional. An array of arguments. * NOTE: Additionally, all valid options as supported in @see cnTerm::getTaxonomyTerms(). * * @type string $taxonomy The taxonomy tree to display. * Default: 'category' * @type bool $hierarchical Whether to include terms that have non-empty descendants, even if 'hide_empty' is set to TRUE. * Default: TRUE * @type string $type The output type of the categories. * Default: select * Accepts: select || multiselect * @type bool $group Whether or not to create option groups using the root parent as the group label. * Default: FALSE * @type bool $hide_if_empty Whether or not to show the select if no terms are returned by term query. * Default: FALSE * @type string $name The select name attribute. * Default: 'cn-cat' * @type string $id The select id attribute. * Default: '' * @type array $class An array if classes to applied to the select. * Default: array('cn-category-select') * @type array $style An array of style to applied inline where the key is the style attribute and the value is the style attribute value. * Default: array() * @type bool $enhanced Whether of not apply the required attributes for the Chosen jQuery plugin. * Default: TRUE * @type string $on_change An inline JavaScript on_change event. * Default: '' * Accepts: Any valid inline JavaScript. * @type int $tab_index The tab index of the select. * Default: 0 * @type bool $show_select_all Whether or not to render the $show_option_all option. * Default: TRUE * @type string $show_option_all A non-blank value causes the display of a link to the directory home page. * Default: ''. The default is not to display a link. * Accepts: Any valid string. * @type string $show_option_none Set the text to show when no categories are listed. * Default: 'No Categories' * Accepts: Any valid string. * @type string $option_none_value Value to use when no term is selected. * Default: -1 * Accepts: Any valid int/string for an option value attribute. * @type string $default The default string to show as the first item in the list. * Default: 'Select Category' * @type bool $show_count Whether or not to display the category count. * Default: FALSE * @type bool $hide_empty Whether or not to display empty terms. * Default: FALSE * @type int $depth Controls how many levels in the hierarchy of categories are to be included in the list. * Default: 0 * Accepts: 0 - All categories and child categories. * -1 - All Categories displayed flat, not showing the parent/child relationships. * 1 - Show only top level/root parent categories. * n - Value of n (int) specifies the depth (or level) to descend in displaying the categories. * @type array $parent_id * @type array $selected The selected term IDs. * Default: 0 * @type string $label The label to render with the select. * Default: '' * @type string $before Content to be render before the label and select. * Default: '' * @type string $after Content to be render after the label and select. * Default: '' * @type string $layout Tokens which can be sued to control the order of the label and select. * Default: '%label%%field%' * Accepts: %label% %field% * @type bool $return Whether or not to return or echo the resulting HTML. * Default: FALSE * } * * @return string */ public static function render($atts = array()) { $select = ''; $out = ''; $defaults = array('taxonomy' => 'category', 'hierarchical' => TRUE, 'type' => 'select', 'group' => FALSE, 'hide_if_empty' => FALSE, 'name' => 'cn-cat', 'id' => '', 'class' => array('cn-category-select'), 'style' => array(), 'enhanced' => TRUE, 'on_change' => '', 'tab_index' => 0, 'show_select_all' => TRUE, 'show_option_all' => '', 'show_option_none' => '', 'option_none_value' => -1, 'default' => __('Select Category', 'connections'), 'show_count' => FALSE, 'hide_empty' => FALSE, 'depth' => 0, 'parent_id' => array(), 'selected' => 0, 'label' => '', 'before' => '', 'after' => '', 'layout' => '%label%%field%', 'return' => FALSE); $atts = wp_parse_args($atts, $defaults); if (wp_is_mobile()) { $atts['enhanced'] = FALSE; } // The field parts to be searched for in $atts['layout']. $search = array('%label%', '%field%'); // An array to store the replacement strings for the label and field. $replace = array(); $walker = new self(); $walker->tree_type = $atts['taxonomy']; if (!isset($atts['pad_counts']) && $atts['show_count'] && $atts['hierarchical']) { // Padding the counts is ideal, but really, really, bloats the memory required. $atts['pad_counts'] = FALSE; } if (empty($atts['parent_id'])) { $terms = cnTerm::getTaxonomyTerms($atts['taxonomy'], $atts); } else { $atts['parent_id'] = wp_parse_id_list($atts['parent_id']); $terms = cnTerm::getTaxonomyTerms($atts['taxonomy'], array_merge($atts, array('include' => $atts['parent_id'], 'child_of' => 0))); // If any of the `parent_id` is not a root parent (where $term->parent = 0) set it parent ID to `0` // so the term tree will be properly constructed. foreach ($terms as $term) { if (0 !== $term->parent) { $term->parent = 0; } } foreach ($atts['parent_id'] as $termID) { $children = cnTerm::getTaxonomyTerms($atts['taxonomy'], array_merge($atts, array('child_of' => $termID))); if (!is_wp_error($children)) { $terms = array_merge($terms, $children); } } } if (!$atts['hide_if_empty'] || !empty($terms)) { //$out .= PHP_EOL . "<select name='$name' id='$id' class='$class' $tab_index_attribute>" . PHP_EOL; // Add the 'cn-enhanced-select' class for the jQuery Chosen Plugin will enhance the drop down. if ($atts['enhanced']) { $atts['class'] = array_merge((array) $atts['class'], array('cn-enhanced-select')); } // Create the field label, if supplied. $replace[] = !empty($atts['label']) ? cnHTML::label(array('for' => $atts['id'], 'label' => $atts['label'], 'return' => TRUE)) : ''; $select .= sprintf('<select %1$s %2$s name="%3$s"%4$s%5$sdata-placeholder="%6$s"%7$s%8$s>' . PHP_EOL, empty($atts['class']) ? '' : cnHTML::attribute('class', $atts['class']), empty($atts['id']) ? '' : cnHTML::attribute('id', $atts['id']), $atts['type'] == 'multiselect' ? esc_attr($atts['name']) . '[]' : esc_attr($atts['name']), empty($atts['style']) ? '' : cnHTML::attribute('style', $atts['style']), $atts['type'] == 'multiselect' ? '' : (empty($atts['on_change']) ? '' : sprintf(' onchange="%s" ', esc_js($atts['on_change']))), esc_attr($atts['default']), $atts['type'] == 'multiselect' ? ' MULTIPLE' : '', (int) $atts['tab_index'] > 0 ? " tabindex=\"{$atts['tab_index']}\"" : ''); } else { $select .= ''; } if (empty($terms) && !$atts['hide_if_empty'] && !empty($atts['show_option_none'])) { /** This filter is documented in includes/template/class.template-walker-term-select.php */ $show_option_none = apply_filters('cn_list_cats', $atts['show_option_none']); $select .= "\t<option value='" . esc_attr($atts['option_none_value']) . "' selected='selected'>{$show_option_none}</option>" . PHP_EOL; } if (!empty($terms)) { if ($atts['enhanced']) { $select .= "\t" . '<option value=""></option>'; } if ($atts['show_select_all'] && $atts['show_option_all']) { /** This filter is documented in includes/template/class.template-walker-term-select.php */ $show_option_all = apply_filters('cn_list_cats', $atts['show_option_all']); $selected = !$atts['enhanced'] && is_numeric($atts['selected']) && '0' === strval($atts['selected']) ? " selected='selected'" : ''; $select .= "\t<option value='0'{$selected}>{$show_option_all}</option>" . PHP_EOL; } if ($atts['show_option_none']) { /** This filter is documented in includes/template/class.template-walker-term-select.php */ $show_option_none = apply_filters('cn_list_cats', $atts['show_option_none']); $selected = selected($atts['option_none_value'], $atts['selected'], FALSE); $select .= "\t<option value='" . esc_attr($atts['option_none_value']) . "'{$selected}>{$show_option_none}</option>" . PHP_EOL; } if ($atts['hierarchical']) { $depth = $atts['depth']; // Walk the full depth. } else { $depth = -1; // Flat. } $select .= $walker->walk($terms, $depth, $atts); } if (!$atts['hide_if_empty'] || !empty($terms)) { // If an option group was left open, ensure it is closed before closing the select. if ($walker->close_group) { $select .= "\t" . '</optgroup>' . PHP_EOL; $walker->close_group = FALSE; } $select .= "</select>" . PHP_EOL; $replace[] = $select; $out = str_ireplace($search, $replace, $atts['layout']); $out = (empty($atts['before']) ? '' : $atts['before']) . $out . (empty($atts['after']) ? '' : $atts['after']); } /** * Filter the taxonomy drop-down output. * * @since 8.2.4 * * @param string $out HTML output. * @param array $atts Arguments used to build the drop-down. */ $out = apply_filters('cn_dropdown_cats', $out, $atts); if ($atts['return']) { return $out; } echo $out; }
/** * Callback used to render the log view of the log type being viewed. * * @access private * @since 8.3 * @static * * @uses current_user_can() * @uses wp_list_pluck() * @uses esc_url() * @uses self_admin_url() * @uses cnLog::types() * @uses cnLog_Email::types() * @uses cnHTML::select() * @uses submit_button() * @uses do_action() */ public static function logs() { if (!current_user_can('install_plugins')) { return; } $current = cnLog_Email::LOG_TYPE; $views = wp_list_pluck(cnLog::views(), 'id'); if (isset($_GET['view']) && array_key_exists($_GET['view'], $views)) { $current = $_GET['view']; } ?> <div class="wrap" id="cn-logs"> <form id="cn-log-type" method="get" action="<?php echo esc_url(self_admin_url('admin.php')); ?> "> <input type="hidden" name="page" value="connections_tools"/> <input type="hidden" name="tab" value="logs"/> <?php $allLogTypes = wp_list_pluck(cnLog::types(), 'name', 'id'); $emailLogTypes = wp_list_pluck(cnLog_Email::types(), 'name', 'id'); unset($emailLogTypes[cnLog_Email::LOG_TYPE]); cnHTML::select(array('id' => 'view', 'options' => array_diff_assoc($allLogTypes, $emailLogTypes)), $current); submit_button('Switch', 'secondary', 'action', FALSE, array('id' => 'log-type-submit')); ?> </form> <?php do_action('cn_logs_view_' . $current); ?> </div> <?php }
/** * Renders the social media network field. * * @access private * @since 8.5.11 * * @param stdClass $date * @param string $token */ private static function dateField($date, $token = '::FIELD::') { // Grab an instance of the Connections object. $instance = Connections_Directory(); // Grab the date types. $dateTypes = $instance->options->getDateOptions(); ?> <div class="widget-top"> <div class="widget-title-action"><a class="widget-action"></a></div> <div class="widget-title"> <h4> <?php cnHTML::field(array('type' => 'select', 'class' => '', 'id' => 'date[' . $token . '][type]', 'options' => $dateTypes, 'required' => FALSE, 'label' => __('Type', 'connections'), 'return' => FALSE), isset($date->type) ? $date->type : ''); cnHTML::field(array('type' => 'radio', 'format' => 'inline', 'class' => '', 'id' => 'date[preferred]', 'options' => array($token => __('Preferred', 'connections')), 'required' => FALSE, 'before' => '<span class="preferred">', 'after' => '</span>', 'return' => FALSE), isset($date->preferred) && $date->preferred ? $token : ''); // Only show this if there are visibility options that the user is permitted to see. if (!empty(self::$visibility)) { cnHTML::field(array('type' => 'radio', 'format' => 'inline', 'class' => '', 'id' => 'date[' . $token . '][visibility]', 'options' => self::$visibility, 'required' => FALSE, 'before' => '<span class="visibility">' . __('Visibility', 'connections') . ' ', 'after' => '</span>', 'return' => FALSE), isset($date->visibility) ? $date->visibility : 'public'); } ?> </h4> </div> </div> <div class="widget-inside"> <?php cnHTML::field(array('type' => 'text', 'class' => 'datepicker', 'id' => 'date[' . $token . '][date]', 'required' => FALSE, 'label' => __('Date', 'connections'), 'before' => '', 'after' => '', 'return' => FALSE), isset($date->date) ? date('m/d/Y', strtotime($date->date)) : ''); ?> <?php if (isset($date->id)) { ?> <input type="hidden" name="date[<?php echo $token; ?> ][id]" value="<?php echo $date->id; ?> "> <?php } ?> <p class="cn-remove-button"> <a href="#" class="cn-remove cn-button button cn-button-warning" data-type="date" data-token="<?php echo $token; ?> "><?php esc_html_e('Remove', 'connections'); ?> </a> </p> </div> <?php }
/** * Renders the dates metabox. * * @access public * @since 0.8 * @param object $entry An instance of the cnEntry object. * @param array $metabox The metabox options array from self::register(). * @return string The dates metabox. */ public static function date($entry, $metabox) { // Grab an instance of the Connections object. $instance = Connections_Directory(); // Grab the email types. $dateTypes = $instance->options->getDateOptions(); echo '<div class="widgets-sortables ui-sortable" id="dates">', PHP_EOL; // --> Start template <-- \\ echo '<textarea id="date-template" style="display: none;">', PHP_EOL; echo '<div class="widget-top">', PHP_EOL; echo '<div class="widget-title-action"><a class="widget-action"></a></div>', PHP_EOL; echo '<div class="widget-title"><h4>', PHP_EOL; cnHTML::field(array('type' => 'select', 'class' => '', 'id' => 'date[::FIELD::][type]', 'options' => $dateTypes, 'required' => FALSE, 'label' => __('Type', 'connections'), 'return' => FALSE)); cnHTML::field(array('type' => 'radio', 'format' => 'inline', 'class' => '', 'id' => 'date[preferred]', 'options' => array('::FIELD::' => __('Preferred', 'connections')), 'required' => FALSE, 'before' => '<span class="preferred">', 'after' => '</span>', 'return' => FALSE)); // Only show this if there are visibility options that the user is permitted to see. if (!empty(self::$visibility)) { cnHTML::field(array('type' => 'radio', 'format' => 'inline', 'class' => '', 'id' => 'date[::FIELD::][visibility]', 'options' => self::$visibility, 'required' => FALSE, 'before' => '<span class="visibility">' . __('Visibility', 'connections') . ' ', 'after' => '</span>', 'return' => FALSE), 'public'); } echo '</h4></div>', PHP_EOL; echo '</div>', PHP_EOL; echo '<div class="widget-inside">'; cnHTML::field(array('type' => 'text', 'class' => 'datepicker', 'id' => 'date[::FIELD::][date]', 'required' => FALSE, 'label' => __('Date', 'connections'), 'before' => '', 'after' => '', 'return' => FALSE)); echo '<p class="cn-remove-button"><a href="#" class="cn-remove cn-button button cn-button-warning" data-type="date" data-token="::FIELD::">', __('Remove', 'connections'), '</a></p>'; echo '</div>', PHP_EOL; echo '</textarea>', PHP_EOL; // --> End template <-- \\ $dates = $entry->getDates(array(), FALSE); //print_r($dates); if (!empty($dates)) { foreach ($dates as $date) { $token = str_replace('-', '', cnUtility::getUUID()); $selectName = 'date[' . $token . '][type]'; $preferred = $date->preferred ? $token : ''; echo '<div class="widget date" id="date-row-' . $token . '">', PHP_EOL; echo '<div class="widget-top">', PHP_EOL; echo '<div class="widget-title-action"><a class="widget-action"></a></div>', PHP_EOL; echo '<div class="widget-title"><h4>', PHP_EOL; cnHTML::field(array('type' => 'select', 'class' => '', 'id' => 'date[' . $token . '][type]', 'options' => $dateTypes, 'required' => FALSE, 'label' => __('Type', 'connections'), 'return' => FALSE), $date->type); cnHTML::field(array('type' => 'radio', 'format' => 'inline', 'class' => '', 'id' => 'date[preferred]', 'options' => array($token => __('Preferred', 'connections')), 'required' => FALSE, 'before' => '<span class="preferred">', 'after' => '</span>', 'return' => FALSE), $preferred); // Only show this if there are visibility options that the user is permitted to see. if (!empty(self::$visibility)) { cnHTML::field(array('type' => 'radio', 'format' => 'inline', 'class' => '', 'id' => 'date[' . $token . '][visibility]', 'options' => self::$visibility, 'required' => FALSE, 'before' => '<span class="visibility">' . __('Visibility', 'connections') . ' ', 'after' => '</span>', 'return' => FALSE), $date->visibility); } echo '</h4></div>', PHP_EOL; echo '</div>', PHP_EOL; echo '<div class="widget-inside">', PHP_EOL; cnHTML::field(array('type' => 'text', 'class' => 'datepicker', 'id' => 'date[' . $token . '][date]', 'required' => FALSE, 'label' => __('Date', 'connections'), 'before' => '', 'after' => '', 'return' => FALSE), date('m/d/Y', strtotime($date->date))); echo '<input type="hidden" name="date[', $token, '][id]" value="', $date->id, '">', PHP_EOL; echo '<p class="cn-remove-button"><a href="#" class="cn-remove cn-button button cn-button-warning" data-type="date" data-token="' . $token . '">', __('Remove', 'connections'), '</a></p>', PHP_EOL; echo '</div>', PHP_EOL; echo '</div>', PHP_EOL; } } echo '</div>', PHP_EOL; echo '<p class="add"><a href="#" class="cn-add cn-button button" data-type="date" data-container="dates">', __('Add Date', 'connections'), '</a></p>', PHP_EOL; }
/** * The call back used to render the settings field types. * * Credit to Tareq. Some of the code to render the form fields were pickup from his Settings API * http://tareq.wedevs.com/2012/06/wordpress-settings-api-php-class/ * https://github.com/tareq1988/wordpress-settings-api-class * * @author Steven A. Zahm * @since 0.7.3.0 * @access private * @param array $field * @return string */ public static function field($field) { global $wp_version; $out = ''; if (in_array($field['section'], self::$coreSections)) { $value = get_option($field['id']); //print_r($value); $name = sprintf('%1$s', $field['id']); } else { $values = get_option($field['section']); $value = isset($values[$field['id']]) ? $values[$field['id']] : NULL; //print_r($value); $name = sprintf('%1$s[%2$s]', $field['section'], $field['id']); } switch ($field['type']) { case 'checkbox': $checked = isset($value) ? checked(1, $value, FALSE) : ''; $out .= sprintf('<input type="checkbox" class="checkbox" id="%1$s" name="%1$s" value="1" %2$s/>', $name, $checked); if (isset($field['desc']) && !empty($field['desc'])) { $out .= sprintf('<label for="%1$s"> %2$s</label>', $name, $field['desc']); } break; case 'multicheckbox': if (isset($field['desc']) && !empty($field['desc'])) { $out .= sprintf('<span class="description">%s</span><br />', $field['desc']); } foreach ($field['options'] as $key => $label) { $checked = checked(TRUE, is_array($value) ? in_array($key, $value) : $key == $value, FALSE); $out .= sprintf('<input type="checkbox" class="checkbox" id="%1$s[%2$s]" name="%1$s[]" value="%2$s"%3$s/>', $name, $key, $checked); $out .= sprintf('<label for="%1$s[%2$s]"> %3$s</label><br />', $name, $key, $label); } break; case 'radio': if (isset($field['desc']) && !empty($field['desc'])) { $out .= sprintf('<span class="description">%s</span><br />', $field['desc']); } foreach ($field['options'] as $key => $label) { $out .= sprintf('<input type="radio" class="radio" id="%1$s[%2$s]" name="%1$s" value="%2$s" %3$s/>', $name, $key, checked($value, $key, FALSE)); $out .= sprintf('<label for="%1$s[%3$s]"> %2$s</label><br />', $name, $label, $key); } break; case 'select': if (isset($field['desc']) && !empty($field['desc'])) { $out .= sprintf('<span class="description">%1$s</span><br />', $field['desc']); } $out .= sprintf('<select name="%1$s" id="%1$s">', $name); foreach ($field['options'] as $key => $label) { $out .= sprintf('<option value="%1$s" %2$s>%3$s</option>', $key, selected($value, $key, FALSE), $label); } $out .= '</select>'; break; case 'multiselect': if (isset($field['desc']) && !empty($field['desc'])) { $out .= sprintf('<span class="description">%s</span><br />', $field['desc']); } $out .= '<span style="background-color: white; border-color: #DFDFDF; border-radius: 3px; border-width: 1px; border-style: solid; display: block; height: 90px; padding: 0 3px; overflow: auto; width: 25em;">'; foreach ($field['options'] as $key => $label) { $checked = checked(TRUE, is_array($value) ? in_array($key, $value) : $key == $value, FALSE); $out .= sprintf('<label><input type="checkbox" class="checkbox" id="%1$s[%2$s]" name="%1$s[]" value="%2$s" %3$s/> %4$s</label><br />', $name, $key, $checked, $label); } $out .= "</span>"; break; case 'text': $size = isset($field['size']) && !empty($field['size']) ? $field['size'] : 'regular'; $out .= sprintf('<input type="text" class="%1$s-text" id="%2$s" name="%2$s" value="%3$s"/>', $size, $name, $value); if (isset($field['desc']) && !empty($field['desc'])) { $out .= sprintf('<span class="description"> %1$s</span>', $field['desc']); } break; case 'textarea': if (isset($field['desc']) && !empty($field['desc'])) { $out .= sprintf('<span class="description"> %1$s</span><br />', $field['desc']); } $out .= sprintf('<textarea rows="10" cols="50" class="%1$s-text" id="%2$s" name="%2$s">%3$s</textarea>', 'large', $name, $value); break; case 'quicktag': if (isset($field['desc']) && !empty($field['desc'])) { $out .= sprintf('<span class="description"> %1$s</span><br />', $field['desc']); } $out .= '<div class="wp-editor-container">'; $out .= sprintf('<textarea class="wp-editor-area" rows="20" cols="40" id="%1$s" name="%1$s">%2$s</textarea>', $name, $value); $out .= '</div>'; self::$quickTagIDs[] = $name; add_action('admin_print_footer_scripts', array(__CLASS__, 'quickTagJS')); break; case 'rte': $size = isset($field['size']) && $field['size'] != 'regular' ? $field['size'] : 'regular'; if (isset($field['desc']) && !empty($field['desc'])) { printf('<div class="description"> %1$s</div>', esc_html($field['desc'])); } if ($wp_version >= 3.3 && function_exists('wp_editor')) { // Set the rte defaults. $defaults = array('textarea_name' => sprintf('%1$s', $name)); $atts = wp_parse_args(isset($field['options']) ? $field['options'] : array(), $defaults); wp_editor(wp_kses_post($value), esc_attr($field['id']), $atts); } else { /* * If this is pre WP 3.3, lets drop in the quick tag editor instead. */ echo '<div class="wp-editor-container">'; printf('<textarea class="wp-editor-area" rows="20" cols="40" id="%1$s" name="%1$s">%2$s</textarea>', esc_attr($name), wp_kses_data($value)); echo '</div>'; self::$quickTagIDs[] = esc_attr($name); wp_enqueue_script('jquery'); add_action('admin_print_footer_scripts', array(__CLASS__, 'quickTagJS')); } break; case 'page': $out .= wp_dropdown_pages(array('name' => $name, 'echo' => 0, 'show_option_none' => $field['show_option_none'], 'option_none_value' => $field['option_none_value'], 'selected' => $value)); break; case 'sortable_checklist': // This will be used to store the order of the content blocks. $blocks = array(); if (isset($field['desc']) && !empty($field['desc'])) { $out .= sprintf('<p class="description"> %1$s</p>', esc_html($field['desc'])); } $out .= sprintf('<ul class="cn-sortable-checklist" id="%1$s">', esc_attr($name)); // Create the array to be used to render the output in the correct order. // This will have to take into account content blocks being added and removed. // ref: http://stackoverflow.com/a/9098675 if (isset($value['order']) && !empty($value['order'])) { $order = array(); // Remove any content blocks that no longer exist. $blocks = array_intersect_key($field['options']['items'], array_flip($value['order'])); // Add back in any new content blocks. $blocks = array_merge($blocks, $field['options']['items']); foreach ($value['order'] as $key) { if (isset($blocks[$key])) { $order[] = $key; } } // Order the array as the user has defined in $value['order']. $blocks = array_merge(array_flip($order), $blocks); } else { // No order was set or saved yet, so use the field options order. $blocks = $field['options']['items']; } foreach ($blocks as $key => $label) { if (isset($field['options']['required']) && in_array($key, $field['options']['required'])) { $checkbox = cnHTML::input(array('type' => 'checkbox', 'prefix' => '', 'id' => esc_attr($name) . '[active][' . $key . ']', 'name' => esc_attr($name) . '[active][]', 'checked' => isset($value['active']) ? checked(TRUE, is_array($value['active']) ? in_array($key, $value['active']) : $key == $value['active'], FALSE) : '', 'disabled' => TRUE, 'label' => $label, 'layout' => '%field%%label%', 'return' => TRUE), $key); $checkbox .= cnHTML::input(array('type' => 'hidden', 'prefix' => '', 'id' => esc_attr($name) . '[active][' . $key . ']', 'name' => esc_attr($name) . '[active][]', 'checked' => isset($value['active']) ? checked(TRUE, is_array($value['active']) ? in_array($key, $value['active']) : $key == $value['active'], FALSE) : '', 'layout' => '%field%', 'return' => TRUE), $key); } else { $checkbox = cnHTML::input(array('type' => 'checkbox', 'prefix' => '', 'id' => esc_attr($name) . '[active][' . $key . ']', 'name' => esc_attr($name) . '[active][]', 'checked' => isset($value['active']) ? checked(TRUE, is_array($value['active']) ? in_array($key, $value['active']) : $key == $value['active'], FALSE) : '', 'label' => $label, 'layout' => '%field%%label%', 'return' => TRUE), $key); } $hidden = cnHTML::input(array('type' => 'hidden', 'prefix' => '', 'id' => esc_attr($name) . '[order][' . $key . ']', 'name' => esc_attr($name) . '[order][]', 'label' => '', 'layout' => '%field%', 'return' => TRUE), $key); $out .= sprintf('<li value="%1$s"><i class="fa fa-sort"></i> %2$s%3$s</li>', $key, $hidden, $checkbox); } $out .= '</ul>'; // Add the list to the sortable IDs. self::$sortableIDs[] = $name; // Add the script to the admin footer. add_action('admin_print_footer_scripts', array(__CLASS__, 'sortableJS')); // Enqueue the jQuery UI Sortable Library. wp_enqueue_script('jquery-ui-sortable'); break; default: ob_start(); do_action('cn_settings_field-' . $field['type'], $name, $value, $field); $out .= ob_get_clean(); break; } echo $out; }
/** * The callback used to render the settings field types. * * Credit to Tareq. Some of the code to render the form fields were pickup from his Settings API * http://tareq.wedevs.com/2012/06/wordpress-settings-api-php-class/ * https://github.com/tareq1988/wordpress-settings-api-class * * @author Steven A. Zahm * @since 0.7.3.0 * @access private * @param array $field * @return string */ public static function field($field) { $out = ''; if (in_array($field['section'], self::$coreSections)) { $value = get_option($field['id']); //print_r($value); $name = sprintf('%1$s', $field['id']); } else { $values = get_option($field['section']); $value = isset($values[$field['id']]) ? $values[$field['id']] : NULL; //print_r($value); $name = sprintf('%1$s[%2$s]', $field['section'], $field['id']); } switch ($field['type']) { case 'checkbox': $checked = isset($value) ? checked(1, $value, FALSE) : ''; $out .= sprintf('<input type="checkbox" class="checkbox" id="%1$s" name="%1$s" value="1" %2$s/>', $name, $checked); if (isset($field['desc']) && !empty($field['desc'])) { $out .= sprintf('<label for="%1$s"> %2$s</label>', $name, $field['desc']); } break; case 'checkbox-group': case 'multicheckbox': if (isset($field['desc']) && !empty($field['desc'])) { $out .= sprintf('<span class="description">%s</span><br />', $field['desc']); } foreach ($field['options'] as $key => $label) { $checked = checked(TRUE, is_array($value) ? in_array($key, $value) : $key == $value, FALSE); $out .= sprintf('<input type="checkbox" class="checkbox" id="%1$s[%2$s]" name="%1$s[]" value="%2$s"%3$s/>', $name, $key, $checked); $out .= sprintf('<label for="%1$s[%2$s]"> %3$s</label><br />', $name, $key, $label); } break; case 'number': $size = isset($field['size']) && !empty($field['size']) ? $field['size'] : 'regular'; $out .= sprintf('<input type="number" class="%1$s-text" id="%2$s" name="%2$s" value="%3$s"/>', $size, $name, $value); if (isset($field['desc']) && !empty($field['desc'])) { $out .= sprintf('<span class="description"> %1$s</span>', $field['desc']); } break; /* * Renders a checkbox group with the registered CPT/s. * The options are set here rather than when registering the setting because settings are registered * before CPT/s are registered with WordPress so `get_post_types()` would return `NULL`. * * Once the CTP options are set, this simply loops back and calls itself with the `checkbox-group` * field type. */ /* * Renders a checkbox group with the registered CPT/s. * The options are set here rather than when registering the setting because settings are registered * before CPT/s are registered with WordPress so `get_post_types()` would return `NULL`. * * Once the CTP options are set, this simply loops back and calls itself with the `checkbox-group` * field type. */ case 'cpt-checkbox-group': $postTypes = get_post_types(array('public' => TRUE, 'show_in_menu' => TRUE, '_builtin' => FALSE), 'objects'); $postTypeOptions = array(); foreach ($postTypes as $type) { $postTypeOptions[$type->name] = $type->labels->name; } $field['type'] = 'checkbox-group'; $field['options'] = $postTypeOptions; $out .= self::field($field); break; case 'radio': if (isset($field['desc']) && !empty($field['desc'])) { $out .= sprintf('<span class="description">%s</span><br />', $field['desc']); } foreach ($field['options'] as $key => $label) { $out .= sprintf('<input type="radio" class="radio" id="%1$s[%2$s]" name="%1$s" value="%2$s" %3$s/>', $name, $key, checked($value, $key, FALSE)); $out .= sprintf('<label for="%1$s[%3$s]"> %2$s</label><br />', $name, $label, $key); } break; case 'select': if (isset($field['desc']) && !empty($field['desc'])) { $out .= sprintf('<span class="description">%1$s</span><br />', $field['desc']); } $out .= sprintf('<select name="%1$s" id="%1$s">', $name); foreach ($field['options'] as $key => $label) { $out .= sprintf('<option value="%1$s" %2$s>%3$s</option>', $key, selected($value, $key, FALSE), $label); } $out .= '</select>'; break; case 'multiselect': if (isset($field['desc']) && !empty($field['desc'])) { $out .= sprintf('<span class="description">%s</span><br />', $field['desc']); } $out .= '<span style="background-color: white; border-color: #DFDFDF; border-radius: 3px; border-width: 1px; border-style: solid; display: block; height: 90px; padding: 0 3px; overflow: auto; width: 25em;">'; foreach ($field['options'] as $key => $label) { $checked = checked(TRUE, is_array($value) ? in_array($key, $value) : $key == $value, FALSE); $out .= sprintf('<label><input type="checkbox" class="checkbox" id="%1$s[%2$s]" name="%1$s[]" value="%2$s" %3$s/> %4$s</label><br />', $name, $key, $checked, $label); } $out .= "</span>"; break; case 'text': $size = isset($field['size']) && !empty($field['size']) ? $field['size'] : 'regular'; $out .= sprintf('<input type="text" class="%1$s-text" id="%2$s" name="%2$s" value="%3$s"/>', $size, $name, $value); if (isset($field['desc']) && !empty($field['desc'])) { $out .= sprintf('<span class="description"> %1$s</span>', $field['desc']); } break; case 'textarea': if (isset($field['desc']) && !empty($field['desc'])) { $out .= sprintf('<span class="description"> %1$s</span><br />', $field['desc']); } $out .= sprintf('<textarea rows="10" cols="50" class="%1$s-text" id="%2$s" name="%2$s">%3$s</textarea>', 'large', $name, $value); break; case 'quicktag': if (isset($field['desc']) && !empty($field['desc'])) { $out .= sprintf('<span class="description"> %1$s</span><br />', $field['desc']); } $out .= '<div class="wp-editor-container">'; $out .= sprintf('<textarea class="wp-editor-area" rows="20" cols="40" id="%1$s" name="%1$s">%2$s</textarea>', $name, $value); $out .= '</div>'; self::$quickTagIDs[] = $name; add_action('admin_print_footer_scripts', array(__CLASS__, 'quickTagJS')); break; case 'rte': if (isset($field['desc']) && !empty($field['desc'])) { printf('<div class="description"> %1$s</div>', esc_html($field['desc'])); } // Set the rte defaults. $defaults = array('textarea_name' => sprintf('%1$s', $name)); $atts = wp_parse_args(isset($field['options']) ? $field['options'] : array(), $defaults); wp_editor(wp_kses_post($value), esc_attr($field['id']), $atts); break; case 'page': $out .= wp_dropdown_pages(array('name' => $name, 'echo' => 0, 'show_option_none' => $field['show_option_none'], 'option_none_value' => $field['option_none_value'], 'selected' => $value)); break; case 'cpt-pages': $defaults = array('depth' => 0, 'child_of' => 0, 'selected' => $value, 'echo' => 0, 'name' => $name, 'id' => '', 'class' => '', 'show_option_none' => '', 'show_option_no_change' => '', 'option_none_value' => '', 'value_field' => 'ID'); $atts = wp_parse_args($field, $defaults); $postTypes = get_post_types(array('public' => TRUE, 'show_in_menu' => TRUE), 'objects'); $class = !empty($atts['class']) ? " class='" . esc_attr($atts['class']) . "'" : ''; $select = "<select name='" . esc_attr($atts['name']) . "'" . $class . " id='" . esc_attr($atts['id']) . "'>\n"; if ($atts['show_option_no_change']) { $select .= "\t<option value=\"-1\">" . $atts['show_option_no_change'] . "</option>\n"; } if ($atts['show_option_none']) { $select .= "\t<option value=\"" . esc_attr($atts['option_none_value']) . '">' . $atts['show_option_none'] . "</option>\n"; } foreach ($postTypes as $type) { if (in_array($type->name, $atts['options']['exclude_cpt'])) { continue; } if (!in_array($type->name, $atts['options']['include_cpt'])) { continue; } $select .= '<optgroup label="' . esc_attr($type->labels->name) . '">' . PHP_EOL; $atts['post_type'] = $type->name; $posts = get_pages($atts); if (!empty($posts)) { $select .= walk_page_dropdown_tree($posts, $atts['depth'], $atts); } $select .= '</optgroup>' . PHP_EOL; } $select .= '</select>' . PHP_EOL; $out = $select; break; case 'category': $out .= cnTemplatePart::walker('term-select', array('hide_empty' => 0, 'hide_if_empty' => FALSE, 'name' => $name, 'orderby' => 'name', 'taxonomy' => 'category', 'selected' => $value, 'hierarchical' => TRUE, 'return' => TRUE)); break; case 'sortable_checklist': // This will be used to store the order of the content blocks. $blocks = array(); if (isset($field['desc']) && !empty($field['desc'])) { $out .= sprintf('<p class="description"> %1$s</p>', esc_html($field['desc'])); } $out .= sprintf('<ul class="cn-sortable-checklist" id="%1$s">', esc_attr($name)); // Create the array to be used to render the output in the correct order. // This will have to take into account content blocks being added and removed. // ref: http://stackoverflow.com/a/9098675 if (isset($value['order']) && !empty($value['order'])) { $order = array(); // Remove any content blocks that no longer exist. $blocks = array_intersect_key($field['options']['items'], array_flip($value['order'])); // Add back in any new content blocks. $blocks = array_merge($blocks, $field['options']['items']); foreach ($value['order'] as $key) { if (isset($blocks[$key])) { $order[] = $key; } } // Order the array as the user has defined in $value['order']. $blocks = array_merge(array_flip($order), $blocks); } else { // No order was set or saved yet, so use the field options order. $blocks = $field['options']['items']; } foreach ($blocks as $key => $label) { if (isset($field['options']['required']) && in_array($key, $field['options']['required'])) { $checkbox = cnHTML::input(array('type' => 'checkbox', 'prefix' => '', 'id' => esc_attr($name) . '[active][' . $key . ']', 'name' => esc_attr($name) . '[active][]', 'checked' => isset($value['active']) ? checked(TRUE, is_array($value['active']) ? in_array($key, $value['active']) : $key == $value['active'], FALSE) : '', 'disabled' => TRUE, 'label' => $label, 'layout' => '%field%%label%', 'return' => TRUE), $key); $checkbox .= cnHTML::input(array('type' => 'hidden', 'prefix' => '', 'id' => esc_attr($name) . '[active][' . $key . ']', 'name' => esc_attr($name) . '[active][]', 'checked' => isset($value['active']) ? checked(TRUE, is_array($value['active']) ? in_array($key, $value['active']) : $key == $value['active'], FALSE) : '', 'layout' => '%field%', 'return' => TRUE), $key); } else { $checkbox = cnHTML::input(array('type' => 'checkbox', 'prefix' => '', 'id' => esc_attr($name) . '[active][' . $key . ']', 'name' => esc_attr($name) . '[active][]', 'checked' => isset($value['active']) ? checked(TRUE, is_array($value['active']) ? in_array($key, $value['active']) : $key == $value['active'], FALSE) : '', 'label' => $label, 'layout' => '%field%%label%', 'return' => TRUE), $key); } $hidden = cnHTML::input(array('type' => 'hidden', 'prefix' => '', 'id' => esc_attr($name) . '[order][' . $key . ']', 'name' => esc_attr($name) . '[order][]', 'label' => '', 'layout' => '%field%', 'return' => TRUE), $key); $out .= sprintf('<li value="%1$s"><i class="fa fa-sort"></i> %2$s%3$s</li>', $key, $hidden, $checkbox); } $out .= '</ul>'; // Add the list to the sortable IDs. self::$sortableIDs[] = $name; // Add the script to the admin footer. add_action('admin_print_footer_scripts', array(__CLASS__, 'sortableJS')); // Enqueue the jQuery UI Sortable Library. wp_enqueue_script('jquery-ui-sortable'); break; default: ob_start(); do_action('cn_settings_field-' . $field['type'], $name, $value, $field); $out .= ob_get_clean(); break; } echo $out; }