Example #1
0
function search_terms($taxonomy, array $options)
{
    $options += ['hide_empty' => false, 'childless' => false, 'pad_counts' => true, 'level' => null];
    $options['cache_domain'] = md5(serialize($options));
    if ($raw_query = value($options, 'search', null)) {
        $raw_query = trim($raw_query);
        $query = preg_replace('@\\s+@smi', '%', trim($raw_query));
        unset($options['search']);
    } else {
        $query = null;
    }
    if (value($options, 'level', null) === 0) {
        unset($options['level']);
        $options['parent'] = 0;
    }
    return escoped_filters(['terms_clauses' => function ($clauses) use($raw_query, $query, $options, $taxonomy) {
        global $wpdb;
        if (($level_and_above = value($options, 'level_and_above', null)) !== null) {
            $options['level'] = $level_and_above;
        }
        if (value($options, 'level', null)) {
            $join = $level_and_above ? " LEFT JOIN" : " INNER JOIN";
            $clauses["join"] .= " {$join} {$wpdb->term_taxonomy} AS ttl0 ON ttl0.taxonomy = '{$taxonomy}' and ttl0.term_taxonomy_id = tt.parent ";
            for ($i = 1; $i < $options['level']; $i++) {
                $clauses["join"] .= "{$join} {$wpdb->term_taxonomy} AS ttl{$i} ON ttl{$i}.taxonomy = '{$taxonomy}' and ttl{$i}.term_taxonomy_id = ttl" . ($i - 1) . ".parent ";
                if ($level_and_above) {
                    $roots[] = "ttl{$i}.parent";
                }
            }
            if ($level_and_above) {
                $roots[] = "ttl0.parent";
                $roots[] = "ttl" . ($i - 1) . ".parent";
                $roots[] = "tt.parent";
            } else {
                $roots = ["ttl" . ($options['level'] - 1) . ".parent"];
            }
            $clauses["where"] .= " AND 0 IN (" . implode(",", $roots) . ")";
        }
        if ($query) {
            $clauses = ['fields' => "{$clauses['fields']}, " . $wpdb->prepare('CASE
									WHEN t.slug like %s THEN %d
									WHEN t.name = %s THEN %d
									WHEN t.slug like %s THEN %d
									WHEN t.name like %s THEN %d
									WHEN t.slug like %s THEN %d
									WHEN t.name like %s THEN %d
								ELSE
									0
								END as score
							', [$raw_query, 6, $raw_query, 5, "{$raw_query}%", 4, "{$raw_query}%", 3, "{$query}%", 2, "{$query}%", 1]), 'where' => $clauses['where'] . $wpdb->prepare('
						 AND (
								(t.name LIKE %s) OR (t.slug LIKE %s)
							) ', ["{$query}%", "%{$query}%"]), 'orderby' => 'ORDER BY score DESC, tt.count DESC, length(t.name) ASC, t.name '] + $clauses;
        }
        return $clauses;
    }], function () use($options, $taxonomy) {
        return get_terms($taxonomy, $options);
    });
}
 public function setupRender(\WP_Post $post, array $box, \stdClass $taxonomy)
 {
     $labels = get_taxonomy_labels($taxonomy);
     $renderSettings = ['name' => 'tax_input[' . esc_attr($taxonomy->name) . ']', 'delimiter' => _x(',', 'tag delimiter'), 'options' => $this->get_options($post, $box, $taxonomy), 'items' => $this->get_items($post, $box, $taxonomy), 'disabled' => !current_user_can($taxonomy->cap->assign_terms)] + $this->settings;
     if (value($renderSettings, 'label') === true) {
         $renderSettings['label'] = $labels->{value($renderSettings, 'multiple', false) ? "singular_name" : "name"};
     }
     $renderSettings = apply_filters('tf_setup_render', $renderSettings, $post, $box, $taxonomy);
     return apply_filters(sprintf('tf_%s_setup_render', $taxonomy->name), $renderSettings, $post, $box, $taxonomy);
 }
Example #3
0
/**
 * Generates a taxonomy metabox function callback together with seletize
 * @since 0.1.0
 *
 * @global array 	$defaultSettings	Default settings applied to all TSNS fields
 * @global wpdb 	$wpdb							WordPress database abstraction object.
 *
 * @param array $settings {
 * 		Settings to describe how the TSNS fields should work
 *
 *		@type string		$ajax_url					url ajax target. Defaults to `ajaxurl`
 *		@type array 		$selector_setup		Selectize Setup
 *		@type array 		$ajax_data				Aditional data to be served by ajax.
 *																		 	By default, wp_ajax settings are assumed.
 *		@type string		$ajax_query_field	field in ajax data for the query, which
 *																			is overwrited in runtime by current one.
 *
 *		@type	int|bool	$terms_limit		defines how much terms can be assigned to
 *																		the post. Define *false* for no limit.
 *
 * } *
 * @return function Returns a function which should be passed to 'meta_box_cb'
 * 									of {@link register_taxonomy()}'s $args
 *              		if no taxonomy is specified and the term ID exists. Returns
 *              		an array of the term ID and the term taxonomy ID the taxonomy
 *              		is specified and the pairing exists.
 */
function searchNSelectField($settings = [])
{
    global $defaultSettings, $tsns_initiated;
    $settings += ['selector_setup' => [], 'ajax_url' => false, 'ajax_query_field' => 'query', 'terms_limit' => false];
    return function (\WP_Post $post, array $box) use($settings) {
        $tax_name = $box['args']['taxonomy'];
        $taxonomy = get_taxonomy($tax_name);
        $user_can_assign_terms = current_user_can($taxonomy->cap->assign_terms);
        $comma = _x(',', 'tag delimiter');
        $terms = wp_get_object_terms($post->ID, $tax_name);
        $labels = get_taxonomy_labels($taxonomy);
        $new_label = $labels->add_new_item;
        $preload = [];
        if ($preload_length = value($settings, 'preload', 10)) {
            $preload = get_terms($tax_name, ['number' => $preload_length, 'hide_empty' => false, 'orderby' => 'count']);
        }
        /**
         * Filters the selectize settings before its conversion to JSON
         *
         * @since 0.1.0
         *
         * @param array 	$settings	Original settings to passed to selectize.js
         * @param WP_Post $post 		The post currently being edited
         * @param object 	$taxonomy	Taxonomy for the current metabox
         * @param array 	$settings	Options this current fields
         */
        $config = apply_filters('tsns_selector_setup', $settings['selector_setup'] + ['loadThrottle' => 100, 'valueField' => 'term_id', 'labelField' => 'name', 'searchField' => 'name', 'maxOptions' => 10, 'optionsTemplate' => '<div class="option"><%- option.name %></div>', 'createTemplate' => "<div class='create'>{$new_label}: <%- input %></div>", 'itemsTemplate' => '<div class="item"><%- item.name %></div>', 'maxItems' => $settings['terms_limit'], 'delimiter' => $comma, 'options' => $terms + $preload, 'items' => array_map(function ($term) {
            return $term->term_id;
        }, $terms), 'create' => $user_can_assign_terms], $post, $taxonomy, $settings);
        /**
         * Filters the selectize settings before its conversion to JSON specifically
         * to {taxonomy}, after filtered by {@link tsns_selector_setup}
         *
         * @since 0.1.0
         *
         * @param array 	$settings	Original settings to passed to selectize.js
         * @param WP_Post $post 		The post currently being edited
         * @param object 	$taxonomy	Taxonomy for the current metabox
         * @param array 	$settings	Options this current fields
         */
        $config = apply_filters(sprintf('tsns_%s_selector_setup', $tax_name), $config, $post, $taxonomy, $settings);
        /**
         * Filter ajax data to be sent along with the query
         *
         * @since 0.1.0
         *
         * @param array 	$ajax_data	Original ajax data
         * @param WP_Post $post 			The post currently being edited
         * @param object 	$taxonomy		Taxonomy for the current metabox
         * @param array 	$settings		Options this current fields
         */
        $ajax_data = apply_filters('tsns_ajax_data', value($settings, 'ajax_data', ['action' => "tsns_search", 'taxonomy' => $tax_name]), $post, $taxonomy, $settings);
        /**
         * Filter ajax data to be sent along with the query specifically to
         * {taxonomy}, after filtered by {@link tsns_setup_selector}
         *
         * @since 0.1.0
         *
         * @param array 	$settings	Original settings to passed to selectize.js
         * @param WP_Post $post 		The post currently being edited
         * @param object 	$taxonomy	Taxonomy for the current metabox
         * @param array 	$settings	Options this current fields
         */
        $ajax_data = apply_filters(sprintf('tsns_%s_ajax_data', $tax_name), $ajax_data, $post, $taxonomy, $settings);
        if ($ajax_url = value($settings, 'ajax_url', false)) {
            $ajax_url = json_encode($ajax_url);
        } else {
            $ajax_url = 'ajaxurl';
        }
        ?>
    <div class="selectize-taxonomy">
			<textarea
				name="<?php 
        echo "tax_input_tsns[{$tax_name}]";
        ?>
"
				rows="3"
				cols="20"
				class="tsns"
				id="tax-input-<?php 
        echo $tax_name;
        ?>
"
				<?php 
        disabled(!$user_can_assign_terms);
        ?>
			><?php 
        echo str_replace(',', $comma . ' ', get_terms_to_edit($post->ID, $tax_name));
        ?>
</textarea>
			<script type="text/javascript">
				(function($, _) {
					var $el = $("script:last").prev();
					<?php 
        if (value($settings, 'required')) {
            ?>
					$el.closest("form").submit(function(e){
						if (!$el.val())  {
							e.preventDefault();
							e.stopPropagation();

              alert(<?php 
            if (value($settings, 'required') === true) {
                echo 'Required field is empty';
            } else {
                echo json_encode(value($settings, 'required'));
            }
            ?>
);
							return false;
						}
					});
					<?php 
        }
        ?>

					// Settings
					var options = <?php 
        echo json_encode($config);
        ?>
;
					var ajaxData = <?php 
        echo json_encode($ajax_data);
        ?>
;

					if (!options.maxItems)
						delete options.maxItems;

					// Templates
					var optionsTemplate = (options.optionsTemplate && _.template(options.optionsTemplate)) || null;
					var itemsTemplate = (options.itemsTemplate && _.template(options.itemsTemplate)) || null;
					var createTemplate = (options.createTemplate && _.template(options.createTemplate)) || null;

					options.create = options.create && function(input) {
						return {
							term_id: input,
							name: input
						}
					};

					// Methods
					options = $.extend({

						load: function(query, done) {
							ajaxData['query'] = query;

							$.ajax({
								url: <?php 
        echo $ajax_url;
        ?>
,
								type: 'GET',
								dataType: 'json',
								data: ajaxData,
								error: function() { done(); },
								success: function(res) { done(res); }
							});
						},

						render: {
							item: (itemsTemplate && function(item, escape) {
								return itemsTemplate({item:item, escape:escape});
							}) || undefined,
							option: (optionsTemplate && function(option, escape) {
								return optionsTemplate({option: option, escape:escape});
							}) || undefined,
							option_create: (createTemplate && function(query, serialize) {
								query.serialize = serialize;
								return createTemplate(query);
							}) || undefined
						}
					}, options);

					$el.selectize(options);

				})(jQuery, _);
			</script>
		</div>
		<?php 
    };
}