/**
  * Save and or update the objects meta data
  * based on the action being performed to the object.
  *
  * @access private
  * @since 0.8
  * @param  string $action The action being performed.
  * @param  int    $id     The object ID.
  * @param  array  $fields An array of the registered fields to save and or update.
  *
  * @return void
  */
 private function save($action, $id, $fields)
 {
     foreach ($fields as $field) {
         if (!($id = absint($id))) {
             return FALSE;
         }
         // Quick and dirty hack to prevent the bio and notes fields from being saved in the meta table.
         // @todo Think of something better to do here.
         // There should be some type of flag to check before saving as meta.
         if ($field['id'] === 'bio' || $field['id'] === 'notes') {
             continue;
         }
         $value = $this->sanitize($field['type'], isset($_POST[$field['id']]) ? $_POST[$field['id']] : NULL, isset($field['options']) ? $field['options'] : array(), isset($field['default']) ? $field['default'] : NULL);
         switch ($action) {
             case 'add':
                 cnMeta::add('entry', $id, $field['id'], $value);
                 break;
             case 'copy':
                 cnMeta::add('entry', $id, $field['id'], $value);
                 break;
             case 'update':
                 cnMeta::update('entry', $id, $field['id'], $value);
                 break;
         }
     }
 }
 /**
  * Callback to delete the term meta when when a term is deleted.
  *
  * @access private
  * @since  8.2
  * @static
  *
  * @param int    $term          Term ID.
  * @param int    $tt_id         Term taxonomy ID.
  * @param string $taxonomy      Taxonomy slug.
  * @param mixed  $deleted_term  Copy of the already-deleted term, in the form specified
  *                              by the parent function. WP_Error otherwise.
  */
 public static function deleteTermMeta($term, $tt_id, $taxonomy, $deleted_term)
 {
     if (!is_wp_error($deleted_term)) {
         $meta = cnMeta::get('term', $term);
         if (!empty($meta)) {
             foreach ($meta as $key => $value) {
                 cnMeta::delete('term', $term, $key);
             }
         }
     }
 }
 /**
  * Return the `meta_key` of a term
  *
  * @access public
  * @since  8.5.2
  *
  * @param int $term_id
  *
  * @return array|bool|string
  */
 public function get($term_id = 0)
 {
     return cnMeta::get('term', $term_id, $this->meta_key, TRUE);
 }
Beispiel #4
0
 /**
  * Load meta data for the player.
  */
 protected function loadMeta()
 {
     if ($this->meta !== null) {
         return $this->meta;
     }
     $meta = $this->entry->getMeta();
     if (!is_array($meta)) {
         $myMeta = array();
     } else {
         $myMeta = array();
         foreach ($meta as $key => $values) {
             if (count($values) > 1 && count(array_unique($values)) == 1) {
                 cnMeta::delete('entry', $this->entry->getId(), $key);
                 cnMeta::add('entry', $this->entry->getId(), $key, $values[0]);
             }
             $myMeta[$key] = $values[0];
         }
     }
     $this->meta = $myMeta;
     return $myMeta;
 }
 /**
  * Add, update or delete the meta of the specified entry ID.
  *
  * @access public
  * @since 0.8
  * @param  string $action The action to be performed.
  * @param  int    $id     The entry ID.
  * @param  array  $meta   [optional] An array of meta data the action is to be performed on.
  *
  * @return array          The meta IDs of the meta data the action was performed on.
  */
 public static function meta($action, $id, $meta = array())
 {
     $metaIDs = array();
     switch ($action) {
         case 'add':
             foreach ($meta as $row) {
                 $metaIDs[] = cnMeta::add('entry', $id, $row['key'], $row['value']);
             }
             break;
         case 'update':
             foreach ($meta as $metaID => $row) {
                 cnMeta::update('entry', $id, $row['key'], $row['value']);
                 $metaIDs[] = $metaID;
             }
             break;
         case 'delete':
             if (empty($meta)) {
                 $meta = cnMeta::get('entry', $id);
             }
             if ($meta) {
                 foreach ($meta as $key => $value) {
                     cnMeta::delete('entry', $id, $key);
                     $metaIDs[] = $key;
                 }
             }
             break;
     }
     return $metaIDs;
 }
    /**
     * Callback to render the "Custom Fields" metabox.
     *
     * @access private
     * @since 0.8
     * @param  cnEntry $entry   An instance of the cnEntry object.
     * @param  array  $metabox The metabox attributes array set in self::register().
     * @return void
     */
    public static function meta($entry, $metabox)
    {
        /** @var wpdb $wpdb */
        global $wpdb;
        $results = $wpdb->get_results($wpdb->prepare("SELECT meta_key, meta_value, meta_id, entry_id\n\t\t\tFROM " . CN_ENTRY_TABLE_META . " WHERE entry_id = %d\n\t\t\tORDER BY meta_key,meta_id", $entry->getId()), ARRAY_A);
        $metabox = $metabox['args'];
        $keys = cnMeta::key('entry');
        $options = array();
        // Toss the meta that is saved as part of a custom field.
        if (!empty($results)) {
            foreach ($results as $metaID => $meta) {
                if (cnMeta::isPrivate($meta['meta_key'])) {
                    unset($results[$metaID]);
                }
            }
        }
        // Build the meta key select drop down options.
        if (!empty($keys)) {
            $options = array_combine(array_map('esc_attr', array_keys($keys)), array_map('esc_html', $keys));
            array_walk($options, create_function('&$key', '$key = "<option value=\\"$key\\">$key</option>";'));
        }
        array_unshift($options, '<option value="-1">&mdash; ' . __('Select', 'connections') . ' &mdash;</option>');
        $options = implode($options, PHP_EOL);
        // echo '<input type="hidden" name="wp_meta_box_nonce" value="', wp_create_nonce( basename(__FILE__) ), '" />';
        echo '<div class="cn-metabox-section" id="meta-fields">';
        ?>

		<table id="list-table" style="<?php 
        echo empty($results) ? 'display: none;' : 'display: table;';
        ?>
">
			<thead>
				<tr>
					<th class="left"><?php 
        _e('Name', 'connections');
        ?>
</th>
					<th><?php 
        _e('Value', 'connections');
        ?>
</th>
				</tr>
			</thead>

			<tbody id="the-list">

			<?php 
        if (!empty($results)) {
            foreach ($results as $metaID => $meta) {
                // Class added to alternate tr rows for CSS styling.
                $alternate = !isset($alternate) || $alternate == '' ? 'alternate' : '';
                ?>

					<tr id="meta-<?php 
                echo $meta['meta_id'];
                ?>
" class="<?php 
                echo $alternate;
                ?>
">

						<td class="left">
							<label class="screen-reader-text" for='meta[<?php 
                echo $meta['meta_id'];
                ?>
][key]'><?php 
                _e('Key', 'connections');
                ?>
</label>
							<input name='meta[<?php 
                echo $meta['meta_id'];
                ?>
][key]' id='meta[<?php 
                echo $meta['meta_id'];
                ?>
][key]' type="text" size="20" value="<?php 
                echo esc_textarea($meta['meta_key']);
                ?>
" />
							<div class="submit">
								<input type="submit" name="deletemeta[<?php 
                echo $meta['meta_id'];
                ?>
]" id="deletemeta[<?php 
                echo $meta['meta_id'];
                ?>
]" class="button deletemeta button-small" value="<?php 
                _e('Delete', 'connections');
                ?>
" />
							</div>
						</td>

						<td>
							<label class="screen-reader-text" for='meta[<?php 
                echo $meta['meta_id'];
                ?>
][value]'><?php 
                _e('Value', 'connections');
                ?>
</label>
							<textarea name='meta[<?php 
                echo $meta['meta_id'];
                ?>
][value]' id='meta[<?php 
                echo $meta['meta_id'];
                ?>
][value]' rows="2" cols="30"><?php 
                echo esc_textarea(cnFormatting::maybeJSONencode($meta['meta_value']));
                ?>
</textarea>
						</td>

					</tr>

					<?php 
            }
            ?>

			<?php 
        }
        ?>

			<!-- This is the row that will be cloned via JS when adding a new Custom Field. -->
			<tr style="display: none;">

				<td class="left">
					<label class="screen-reader-text" for='newmeta[0][key]'><?php 
        _e('Key', 'connections');
        ?>
</label>
					<input name='newmeta[0][key]' id='newmeta[0][key]' type="text" size="20" value=""/>
					<div class="submit">
						<input type="submit" name="deletemeta[0]" id="deletemeta[0]" class="button deletemeta button-small" value="<?php 
        _e('Delete', 'connections');
        ?>
" />
						<!-- <input type="submit" name="newmeta-0-submit" id="newmeta-0-submit" class="button updatemeta button-small" value="Update" /> -->
					</div>
					<!-- <input type="hidden" id="_ajax_nonce" name="_ajax_nonce" value="0db0025bba" /> -->
				</td>
				<td>
					<label class="screen-reader-text" for='newmeta[0][value]'><?php 
        _e('Value', 'connections');
        ?>
</label>
					<textarea name='newmeta[0][value]' id='newmeta[0][value]' rows="2" cols="30"></textarea>
				</td>

			</tr>

			</tbody>
		</table>

		<p><strong><?php 
        _e('Add New Custom Field:', 'connections');
        ?>
</strong></p>

		<table id="newmeta">
			<thead>
				<tr>
					<th class="left"><label for="metakeyselect"><?php 
        _e('Name', 'connections');
        ?>
</label></th>
					<th><label for="metavalue"><?php 
        _e('Value', 'connections');
        ?>
</label></th>
				</tr>
			</thead>
			<tbody>

				<tr>

					<td id="newmetaleft" class="left">
						<select id="metakeyselect" name="metakeyselect">
							<?php 
        echo $options;
        ?>
						</select>
						<input class="hide-if-js" type=text id="metakeyinput" name="newmeta[99][key]" value=""/>
						<a href="#postcustomstuff" class="postcustomstuff hide-if-no-js"> <span id="enternew"><?php 
        _e('Enter New', 'connections');
        ?>
</span> <span id="cancelnew" class="hidden"><?php 
        _e('Cancel', 'connections');
        ?>
</span></a>
					</td>

					<td>
						<textarea id="metavalue" name="newmeta[99][value]" rows="2" cols="25"></textarea>
					</td>

				</tr>



			</tbody>
			<tfoot>
				<td colspan="2">
					<div class="submit">
						<input type="submit" name="addmeta" id="newmeta-submit" class="button" value="<?php 
        _e('Add Custom Field', 'connections');
        ?>
" />
					</div>
					<!-- <input type="hidden" id="_ajax_nonce-add-meta" name="_ajax_nonce-add-meta" value="a7f70d2878" /> -->
				</td>
			</tfoot>
		</table>

		<?php 
        if (isset($metabox['desc']) && !empty($metabox['desc'])) {
            printf('<p>%1$s</p>', esc_html($metabox['desc']));
        }
        echo '</div>';
    }
 /**
  * Write the CSV rows for the current step.
  *
  * @access public
  * @since  8.5.1
  */
 public function writeRows()
 {
     $results = $this->getData();
     $rows = '';
     if (!empty($results)) {
         // Go through each entry...
         foreach ($results as $entry) {
             $fieldCount = count($this->fields);
             $row = '';
             // ...and go through each cell the user wants to export, and match it with the cell in the entry...
             for ($i = 0; $i < $fieldCount; $i++) {
                 // ...then find out if it's a breakout cell and process it properly...
                 switch ($this->fields[$i]['type']) {
                     case 1:
                         // Export a standard breakout; just list them all in the order requested...
                         $row .= $this->exportBreakoutCell($this->fields[$i], $entry->id);
                         break;
                     case 2:
                         // Process category table and list all categories in a single cell...
                         $terms = array();
                         $results = $this->getTerms($entry->id, 'category');
                         foreach ($results as $term) {
                             $terms[] = $term->name;
                         }
                         $row .= $this->escapeAndQuote(implode(',', $terms)) . ',';
                         break;
                     case 3:
                         $count = $this->getTermCount('category');
                         $terms = array();
                         // Process the category table by breaking them out in separate cells,
                         // Prepare an empty frame of the category cells...
                         for ($j = 0; $j < $count + 1; $j++) {
                             // Make an array filled with empty cells
                             $terms[$j] = '"",';
                         }
                         // Now start filling in the empty cells with data...
                         $row = $this->getTerms($entry->id, 'category');
                         $j = 0;
                         foreach ($row as $result) {
                             $terms[$j] = $this->escapeAndQuote($result->name) . ',';
                             $j++;
                         }
                         $row .= implode('', $terms);
                         break;
                     case 4:
                         // Export breakout data from the serialized option cell.
                         $row .= $this->exportBreakoutOptionsCell($this->fields[$i], $entry);
                         break;
                     case 5:
                         $data = '';
                         $meta = cnMeta::get('entry', $entry->id, $this->fields[$i]['field'], TRUE);
                         if (!empty($meta)) {
                             $data = cnFormatting::maybeJSONencode($meta);
                         }
                         $row .= $this->escapeAndQuote($data) . ',';
                         break;
                     case 6:
                         $terms = array();
                         $parent = $this->fields[$i]['child_of'];
                         $results = $this->getTerms($entry->id, 'category');
                         foreach ($results as $term) {
                             $terms[] = $parent . ':' . $term->term_id;
                             if (cnTerm::isAncestorOf($parent, $term->term_id, 'category')) {
                                 $terms[] = $term->name;
                             }
                         }
                         $row .= $this->escapeAndQuote(implode(',', $terms)) . ',';
                         break;
                     default:
                         // If no breakout type is defined, only display the cell data...
                         $row .= $this->escapeAndQuote($entry->{$this->fields[$i]['field']}) . ',';
                         break;
                 }
             }
             // Trim the trailing comma and space, then add newline.
             $rows .= rtrim($row, ',') . "\r\n";
         }
         // Now write the data...
         $this->write($rows);
         return $rows;
     }
     return FALSE;
 }
 /**
  * Outputs the data saved in the "Custom Fields" entry metabox.
  * This should not be confused with the fields registered with
  * cnMetaboxAPI. Those fields should be output using a registered
  * action which runs in $this->getMetaBlock().
  *
  * @access private
  * @since 0.8
  * @uses wp_parse_args()
  * @uses apply_filters()
  * @param  array  $metadata The metadata array passed from $this->getMetaBlock(). @see self::getMetaBlock().
  *
  * @return string
  */
 private function renderMetaBlock($metadata)
 {
     $out = '';
     $defaults = array('container_tag' => 'ul', 'item_tag' => 'li', 'key_tag' => 'span', 'value_tag' => 'span', 'separator' => ': ', 'before' => '', 'after' => '');
     $atts = wp_parse_args(apply_filters('cn_output_meta_atts', $defaults), $defaults);
     foreach ((array) $metadata as $key => $value) {
         // Do not render any private keys; ie. ones that begin with an underscore
         // or any fields registered as part of a custom metabox.
         if (cnMeta::isPrivate($key, 'entry')) {
             continue;
         }
         $out .= apply_filters('cn_entry_output_meta_key', sprintf('<%1$s><%2$s class="cn-entry-meta-key">%3$s%4$s</%2$s><%5$s class="cn-entry-meta-value">%6$s</%5$s></%1$s>' . PHP_EOL, $atts['item_tag'], $atts['key_tag'], trim($key), $atts['separator'], $atts['value_tag'], implode(', ', (array) $value)), $atts, $key, $value);
     }
     if (empty($out)) {
         return '';
     }
     $out = apply_filters('cn_entry_output_meta_container', sprintf('<%1$s class="cn-entry-meta">%2$s</%1$s>' . PHP_EOL, $atts['container_tag'], $out), $atts, $metadata);
     echo $atts['before'] . $out . $atts['after'] . PHP_EOL;
 }
 /**
  * Returns the entry meta data.
  *
  * @access public
  * @since  unknown
  *
  * @uses   wp_parse_args()
  * @uses   cnMeta::get()
  *
  * @param array $atts {
  *     Optional. An array of arguments.
  *
  * @type string $key       Metadata key. If not specified, retrieve all metadata for the specified object.
  * @type bool   $single    Default is FALSE. If TRUE, return only the first value of the specified meta_key.
  *                         This parameter has no effect if $key is not specified.
  * }
  *
  * @return mixed array|bool|string Array of the entry meta data.
  *                                 String if $single is set to TRUE.
  *                                 FALSE on failure.
  */
 public function getMeta($atts = array())
 {
     $defaults = array('key' => '', 'single' => FALSE);
     $atts = wp_parse_args($atts, $defaults);
     return cnMeta::get('entry', $this->getId(), $atts['key'], $atts['single']);
 }
 /**
  * Save and or update the objects meta data
  * based on the action being performed to the object.
  *
  * @access private
  * @since  0.8
  *
  * @param  string $action The action being performed.
  * @param  int    $id     The object ID.
  * @param  array  $fields An array of the registered fields to save and or update.
  *
  * @return bool
  */
 private function save($action, $id, $fields)
 {
     foreach ($fields as $field) {
         /**
          * Filter field meta before it is inserted into the database.
          *
          * @since 8.5.14
          *
          * @param array  $field  An array of the registered field attributes.
          * @param int    $id     The object ID.
          * @param string $action The action being performed.
          */
         $field = apply_filters('cn_pre_save_meta', $field, $id, $action);
         if (!($id = absint($id))) {
             return FALSE;
         }
         /**
          * Filter to allow meta to not be saved.
          *
          * The dynamic portion of the filter name is so saving meta can be skipped based on the field ID.
          *
          * @since 8.5.14
          *
          * @param false $false Return TRUE to not save the field meta.
          */
         if (apply_filters('cn_pre_save_meta_skip', FALSE) || apply_filters('cn_pre_save_meta_skip-' . $field['id'], FALSE)) {
             continue;
         }
         $value = $this->sanitize($field['type'], isset($_POST[$field['id']]) ? $_POST[$field['id']] : NULL, isset($field['options']) ? $field['options'] : array(), isset($field['default']) ? $field['default'] : NULL);
         switch ($action) {
             case 'add':
                 cnMeta::add('entry', $id, $field['id'], $value);
                 break;
             case 'copy':
                 cnMeta::add('entry', $id, $field['id'], $value);
                 break;
             case 'update':
                 cnMeta::update('entry', $id, $field['id'], $value);
                 break;
         }
     }
 }
 /**
  * Generates SQL clauses to be added to the query.
  *
  * @access public
  * @since  8.2.5
  *
  * @param string $type              Type of meta, eg 'entry', 'term'.
  * @param string $primary_table     Database table where the object being filtered is stored (eg CN_ENTRY_TABLE).
  * @param string $primary_id_column ID column for the filtered object in $primary_table.
  * @param mixed  $context           object|null Optional. The main query object.
  *
  * @return array {
  *     Array containing JOIN and WHERE SQL clauses to append to the main query.
  *
  *     @type string $join  SQL fragment to append to the main JOIN clause.
  *     @type string $where SQL fragment to append to the main WHERE clause.
  * }
  */
 public function get_sql($type, $primary_table, $primary_id_column, $context = null)
 {
     $this->meta_table = cnMeta::tableName($type);
     $this->meta_id_column = sanitize_key($type . '_id');
     $this->primary_table = $primary_table;
     $this->primary_id_column = $primary_id_column;
     $sql = $this->get_sql_clauses();
     /*
      * If any JOINs are LEFT JOINs (as in the case of NOT EXISTS), then all JOINs should
      * be LEFT. Otherwise posts with no metadata will be excluded from results.
      */
     if (false !== strpos($sql['join'], 'LEFT JOIN')) {
         $sql['join'] = str_replace('INNER JOIN', 'LEFT JOIN', $sql['join']);
     }
     /**
      * Filter the meta query's generated SQL.
      *
      * @since 8.2.5
      *
      * @param array $args {
      *     An array of meta query SQL arguments.
      *
      *     @type array  $clauses           Array containing the query's JOIN and WHERE clauses.
      *     @type array  $queries           Array of meta queries.
      *     @type string $type              Type of meta.
      *     @type string $primary_table     Primary table.
      *     @type string $primary_id_column Primary column ID.
      *     @type object $context           The main query object.
      * }
      */
     return apply_filters_ref_array('cn_get_meta_sql', array($sql, $this->queries, $type, $primary_table, $primary_id_column, $context));
 }
 /**
  * Retrieve the terms in a given taxonomy or list of taxonomies.
  *
  * NOTE: This is the Connections equivalent of @see get_terms() in WordPress core ../wp-includes/taxonomy.php
  *
  * Filters:
  *    cn_get_terms_atts - The method variables.
  *        Passes: (array) $atts, (array) $taxonomies
  *        Return: $atts
  *
  *    cn_get_terms_fields - The fields for the SELECT query clause.
  *        Passes: (array) $select, (array) $atts, (array) $taxonomies
  *        Return: $select
  *
  *    cn_term_inclusions - Query clause which includes terms.
  *        Passes: (string) $inclusions, (array) $atts, (array) $taxonomies
  *        Return: $inclusions
  *
  *    cn_term_exclusions - Query clause which excludes terms.
  *        Passes: (string) $exclusions, (array) $atts, (array) $taxonomies
  *        Return: $exclusions
  *
  *    cn_term_orderby - The ORDER BY query clause.
  *        Passes: (string) $orderBy, (array) $atts, (array) $taxonomies
  *        Return: $orderBy
  *
  *    cn_terms_clauses - An array containing the the query clause segments.
  *        Passes: (array) $pieces, (array) $taxonomies, (array) $atts
  *        Return: $pieces
  *
  * @access public
  * @since  8.1
  * @since  8.5.10 Introduced 'name' and 'childless' parameters.
  *                Introduced the 'meta_query' and 'update_meta_cache' parameters.
  *                Converted to return a list of cnTerm_Object objects.
  * @static
  *
  * @global wpdb $wpdb
  *
  * @param  string|array $taxonomies Taxonomy name or array of taxonomy names.
  * @param  array        $atts {
  *     Optional. Array or string of arguments to get terms.
  *
  *     @type string       $get                    Whether to return terms regardless of ancestry or whether the terms are empty.
  *                                                Accepts: 'all' | ''
  *                                                Default: ''
  *     @type array|string $orderby                Field(s) to order terms by.
  *                                                Use 'include' to match the 'order' of the $include param, or 'none' to skip ORDER BY.
  *                                                Accepts: term_id | name | slug | term_group | parent | count | include | none
  *                                                Default: 'name
  *     @type string       $order                  Whether to order terms in ascending or descending order.
  *                                                Accepts: 'ASC' | 'DESC'
  *                                                Default: 'ASC'
  *     @type bool|int     $hide_empty             Whether to hide terms not assigned to any posts.
  *                                                Accepts: 1|true || 0|false
  *                                                Default: TRUE.
  *     @type array|string $include                Array or comma/space-separated string of term ids to include.
  *                                                Default: array()
  *     @type array|string $exclude                Array or comma/space-separated string of term ids to exclude.
  *                                                If $include is non-empty, $exclude is ignored.
  *                                                Default empty array.
  *     @type array|string $exclude_tree           Array or comma/space-separated string of term ids to exclude
  *                                                along with all of their descendant terms. If $include is
  *                                                non-empty, $exclude_tree is ignored. Default empty array.
  *     @type int|string   $number                 Maximum number of terms to return.
  *                                                Accepts: ''|0 (all) or any positive number.
  *                                                Default: 0
  *     @type int          $offset                 The number by which to offset the terms query.
  *                                                Accepts: integers.
  *                                                Default: 0
  *     @type string       $fields                 Term fields to query for.
  *                                                Accepts: 'all' (returns an array of complete term objects),
  *                                                         'ids' (returns an array of ids),
  *                                                         'id=>parent' (returns an associative array with ids as keys, parent term IDs as values),
  *                                                         'names' (returns an array of term names),
  *                                                         'count' (returns the number of matching terms),
  *                                                         'id=>name' (returns an associative array with ids as keys, term names as values),
  *                                                         'id=>slug' (returns an associative array with ids as keys, term slugs as values).
  *                                                Default: 'all'.
  *     @type string|array $name                   Name or array of names to return term(s) for.
  *                                                Default: ''
  *     @type string|array $slug                   Slug or array of slugs to return term(s) for.
  *                                                Default: ''.
  *     @type bool         $hierarchical           Whether to include terms that have non-empty descendants (even if $hide_empty is set to true).
  *                                                Default: TRUE
  *     @type string       $search                 Search criteria to match terms. Will be SQL-formatted with wildcards before and after.
  *                                                Default: ''
  *     @type string       $name__like             Retrieve terms with criteria by which a term is LIKE $name__like.
  *                                                Default: ''
  *     @type string       $description__like      Retrieve terms where the description is LIKE $description__like.
  *                                                Default: ''
  *     @type int|string   $parent                 Parent term ID to retrieve direct-child terms of.
  *                                                Default: ''
  *     @type bool         $childless              True to limit results to terms that have no children.
  *                                                This parameter has no effect on non-hierarchical taxonomies.
  *                                                Default: FALSE
  *     @type int          $child_of               Term ID to retrieve child terms of.
  *                                                If multiple taxonomies are passed, $child_of is ignored.
  *                                                Default: 0
  *     @type bool         $pad_counts             Whether to pad the quantity of a term's children in the quantity
  *                                                of each term's "count" object variable.
  *                                                Default: FALSE
  *     @type bool         $update_meta_cache      Whether to prime meta caches for matched terms.
  *                                                Default: TRUE
  *     @type array        $meta_query             Meta query clauses to limit retrieved terms by.
  *                                                @see cnMeta_Query.
  *                                                Default: array()
  * }
  *
  * @uses   apply_filters()
  * @uses   wp_parse_args()
  * @uses   wp_parse_id_list()
  * @uses   sanitize_title()
  * @uses   wpdb::prepare()
  * @uses   $wpdb::esc_like()
  * @uses   absint()
  * @uses   wpdb::get_results()
  * @uses   cnTerm::filter()
  * @uses   cnTerm::descendants()
  * @uses   cnTerm::childrenIDs()
  * @uses   cnTerm::padCounts()
  * @uses   cnTerm::children()
  *
  * @return array|int|WP_Error Indexed array of cnTerm_Object objects. Will return WP_Error, if any of $taxonomies do not exist.*
  */
 public static function getTaxonomyTerms($taxonomies = array('category'), $atts = array())
 {
     global $wpdb;
     $select = array();
     $where = array();
     $orderBy = array();
     $orderByClause = '';
     /*
      * @TODO $taxonomies need to be checked against registered taxonomies.
      * Presently $taxonomies only support a string rather than array.
      * Additionally, category is the only supported taxonomy.
      */
     $single_taxonomy = !is_array($taxonomies) || 1 === count($taxonomies);
     if (!is_array($taxonomies)) {
         $taxonomies = array($taxonomies);
     }
     $defaults = array('get' => '', 'orderby' => 'name', 'order' => 'ASC', 'hide_empty' => TRUE, 'include' => array(), 'exclude' => array(), 'exclude_tree' => array(), 'number' => 0, 'offset' => 0, 'fields' => 'all', 'name' => '', 'slug' => '', 'hierarchical' => TRUE, 'search' => '', 'name__like' => '', 'description__like' => '', 'parent' => '', 'childless' => FALSE, 'child_of' => 0, 'pad_counts' => FALSE, 'meta_query' => array(), 'update_meta_cache' => TRUE);
     /**
      * Filter the terms query arguments.
      *
      * @since 8.1
      *
      * @param array        $atts       An array of arguments.
      * @param string|array $taxonomies A taxonomy or array of taxonomies.
      */
     $atts = apply_filters('cn_get_terms_args', $atts, $taxonomies);
     $atts = wp_parse_args($atts, $defaults);
     // @TODO Implement is_taxonomy_hierarchical().
     if (!$single_taxonomy || '' !== $atts['parent'] && 0 !== $atts['parent']) {
         $atts['hierarchical'] = FALSE;
         $atts['pad_counts'] = FALSE;
     }
     // 'parent' overrides 'child_of'.
     if (0 < intval($atts['parent'])) {
         $atts['child_of'] = FALSE;
     }
     if ('all' == $atts['get']) {
         $atts['childless'] = FALSE;
         $atts['child_of'] = 0;
         $atts['hide_empty'] = 0;
         $atts['hierarchical'] = FALSE;
         $atts['pad_counts'] = FALSE;
     }
     if ($atts['child_of']) {
         $hierarchy = self::childrenIDs(reset($taxonomies));
         if (!isset($hierarchy[$atts['child_of']])) {
             return array();
         }
     }
     if ($atts['parent']) {
         $hierarchy = self::childrenIDs(reset($taxonomies));
         if (!isset($hierarchy[$atts['parent']])) {
             return array();
         }
     }
     // $args can be whatever, only use the args defined in defaults to compute the key
     $filter_key = has_filter('cn_term_exclusions') ? serialize($GLOBALS['wp_filter']['cn_term_exclusions']) : '';
     $key = md5(serialize(wp_array_slice_assoc($atts, array_keys($defaults))) . serialize($taxonomies) . $filter_key);
     $last_changed = wp_cache_get('last_changed', 'cn_terms');
     if (!$last_changed) {
         $last_changed = microtime();
         wp_cache_set('last_changed', $last_changed, 'cn_terms');
     }
     $cache_key = "cn_get_terms:{$key}:{$last_changed}";
     $cache = wp_cache_get($cache_key, 'cn_terms');
     if (FALSE !== $cache) {
         /**
          * Filter the given taxonomy's terms cache.
          *
          * @since 8.1.6
          *
          * @param array        $cache      Cached array of terms for the given taxonomy.
          * @param string|array $taxonomies A taxonomy or array of taxonomies.
          * @param array        $args       An array of arguments to get terms.
          */
         $cache = apply_filters('cn_terms', $cache, $taxonomies, $atts);
         return $cache;
     }
     /*
      * Construct the ORDER By query clause.
      */
     if (is_array($atts['orderby'])) {
         foreach ($atts['orderby'] as $i => $value) {
             if (!isset($order)) {
                 $order = 'ASC';
             }
             switch ($value) {
                 case 'name':
                     $orderField = 't.name';
                     break;
                 case 'id':
                 case 'term_id':
                     $orderField = 't.term_id';
                     break;
                 case 'slug':
                     $orderField = 't.slug';
                     break;
                 case 'include':
                     $include = implode(',', wp_parse_id_list($atts['include']));
                     $orderField = "FIELD( t.term_id, {$include} )";
                     break;
                 case 'term_group':
                     $orderField = 't.term_group';
                     break;
                 case 'none':
                     $orderField = '';
                     // If an `none` order field was supplied, break out of both the switch and foreach statements.
                     break 2;
                 case 'parent':
                     $orderField = 'tt.parent';
                     break;
                 case 'count':
                     $orderField = 'tt.count';
                     break;
                 default:
                     $orderField = 't.name';
                     break;
             }
             // Set the $order to align with $atts['orderby'].
             if (is_array($atts['order']) && isset($atts['order'][$i])) {
                 $order = $atts['order'][$i];
                 // If an aligned $atts['order'] does not exist use the last $order set otherwise use $atts['order'].
             } else {
                 $order = is_array($atts['order']) ? $order : $atts['order'];
             }
             $order = strtoupper($order);
             $order = in_array($order, array('ASC', 'DESC')) ? $order : 'ASC';
             $orderBy[] = sprintf('%s %s', $orderField, $order);
         }
         // The @var $value will be set to the last value from the $atts['orderby'] foreach loop.
         // If a `none` $atts['orderby'] was found in the supplied array, no order by clause will be set.
         if (!empty($orderBy) && $value != 'none') {
             $orderByClause = 'ORDER BY ' . implode(', ', $orderBy);
         }
     } else {
         switch ($atts['orderby']) {
             case 'name':
                 $atts['orderby'] = 't.name';
                 break;
             case 'id':
             case 'term_id':
                 $atts['orderby'] = 't.term_id';
                 break;
             case 'slug':
                 $atts['orderby'] = 't.slug';
                 break;
             case 'include':
                 $include = implode(',', wp_parse_id_list($atts['include']));
                 $atts['orderby'] = "FIELD( t.term_id, {$include} )";
                 break;
             case 'term_group':
                 $atts['orderby'] = 't.term_group';
                 break;
             case 'none':
                 $atts['orderby'] = '';
                 break;
             case 'parent':
                 $atts['orderby'] = 'tt.parent';
                 break;
             case 'count':
                 $atts['orderby'] = 'tt.count';
                 break;
             default:
                 $atts['orderby'] = 't.name';
                 break;
         }
         if (is_array($atts['order'])) {
             // $atts['orderby'] was a string but an array was passed for $atts['order'], assume the 0 index.
             $order = $atts['order'][0];
         } else {
             $order = $atts['order'];
         }
         if (!empty($atts['orderby'])) {
             $order = strtoupper($order);
             $order = in_array($order, array('ASC', 'DESC')) ? $order : 'ASC';
             $orderByClause = 'ORDER BY ' . sprintf('%s %s', $atts['orderby'], $order);
         }
     }
     /**
      * Filter the ORDER BY clause of the terms query.
      *
      * @since 8.1
      *
      * @param string       $orderBy    ORDER BY clause of the terms query.
      * @param array        $atts       An array of terms query arguments.
      * @param string|array $taxonomies A taxonomy or array of taxonomies.
      */
     $orderBy = apply_filters('cn_terms_orderby', $orderByClause, $atts, $taxonomies);
     /*
      * Start construct the WHERE query clause.
      */
     $where[] = 'tt.taxonomy IN (\'' . implode('\', \'', $taxonomies) . '\')';
     /*
      * Define the included terms.
      */
     $inclusions = '';
     if (!empty($atts['include'])) {
         $atts['exclude'] = '';
         $atts['exclude_tree'] = '';
         $inclusions = implode(',', wp_parse_id_list($atts['include']));
     }
     if (!empty($inclusions)) {
         $inclusions = 'AND t.term_id IN ( ' . $inclusions . ' )';
     }
     /**
      * Filter the terms to be included in the terms query.
      *
      * @since 8.1
      *
      * @param string       $inclusions IN clause of the terms query.
      * @param array        $atts       An array of terms query arguments.
      * @param string|array $taxonomies A taxonomy or array of taxonomies.
      */
     $inclusions = apply_filters('cn_term_inclusions', $inclusions, $atts, $taxonomies);
     if (!empty($inclusions)) {
         $where[] = $inclusions;
     }
     /*
      * Define the excluded terms.
      */
     $exclusions = array();
     if (!empty($atts['exclude_tree'])) {
         $atts['exclude_tree'] = wp_parse_id_list($atts['exclude_tree']);
         $excluded_children = $atts['exclude_tree'];
         foreach ($atts['exclude_tree'] as $extrunk) {
             $excluded_children = array_merge($excluded_children, (array) cnTerm::getTaxonomyTerms($taxonomies[0], array('child_of' => intval($extrunk), 'fields' => 'ids', 'hide_empty' => 0)));
         }
         $exclusions = array_merge($excluded_children, $exclusions);
     }
     if (!empty($atts['exclude'])) {
         $exclusions = array_merge(wp_parse_id_list($atts['exclude']), $exclusions);
     }
     // 'childless' terms are those without an entry in the flattened term hierarchy.
     $childless = (bool) $atts['childless'];
     if ($childless) {
         foreach ($taxonomies as $_tax) {
             $term_hierarchy = self::childrenIDs($_tax);
             $exclusions = array_merge(array_keys($term_hierarchy), $exclusions);
         }
     }
     if (!empty($exclusions)) {
         $exclusions = ' AND t.term_id NOT IN (' . implode(',', array_map('intval', $exclusions)) . ')';
     } else {
         $exclusions = '';
     }
     /**
      * Filter the terms to exclude from the terms query.
      *
      * @since 8.1
      *
      * @param string       $exclusions NOT IN clause of the terms query.
      * @param array        $atts       An array of terms query arguments.
      * @param string|array $taxonomies A taxonomy or array of taxonomies.
      */
     $exclusions = apply_filters('cn_term_exclusions', $exclusions, $atts, $taxonomies);
     if (!empty($exclusions)) {
         $where[] = $exclusions;
     }
     if (!empty($atts['name'])) {
         $names = (array) $atts['name'];
         foreach ($names as &$_name) {
             $_name = sanitize_term_field('name', $_name, 0, reset($taxonomies), 'db');
         }
         $where[] = "AND t.name IN ('" . implode("', '", array_map('esc_sql', $names)) . "')";
     }
     if (!empty($atts['slug'])) {
         if (is_array($atts['slug'])) {
             $slug = array_map('sanitize_title', $atts['slug']);
             $where[] = " AND t.slug IN ('" . implode("', '", $slug) . "')";
         } else {
             $slug = sanitize_title($atts['slug']);
             $where[] = " AND t.slug = '{$slug}'";
         }
     }
     if (!empty($atts['name__like'])) {
         $where[] = $wpdb->prepare(" AND t.name LIKE %s", '%' . $wpdb->esc_like($atts['name__like']) . '%');
     }
     if (!empty($atts['description__like'])) {
         $where[] = $wpdb->prepare(" AND tt.description LIKE %s", '%' . $wpdb->esc_like($atts['description__like']) . '%');
     }
     if ('' !== $atts['parent']) {
         $where[] = $wpdb->prepare('AND tt.parent = %d', $atts['parent']);
     }
     if ('count' == $atts['fields']) {
         $atts['hierarchical'] = FALSE;
     }
     if ($atts['hide_empty'] && !$atts['hierarchical']) {
         $where[] = 'AND tt.count > 0';
     }
     // Do not limit the query results when we have to descend the family tree.
     if ($atts['number'] && !$atts['hierarchical'] && !$atts['child_of'] && '' === $atts['parent']) {
         $atts['number'] = absint($atts['number']);
         $atts['offset'] = absint($atts['offset']);
         if ($atts['offset']) {
             $limit = $wpdb->prepare('LIMIT %d,%d', $atts['offset'], $atts['number']);
         } else {
             $limit = $wpdb->prepare('LIMIT %d', $atts['number']);
         }
     } else {
         $limit = '';
     }
     if (!empty($atts['search'])) {
         //$atts['search'] = like_escape( $atts['search'] );
         $atts['search'] = $wpdb->esc_like($atts['search']);
         $where[] = $wpdb->prepare('AND ( (t.name LIKE %s) OR (t.slug LIKE %s) )', '%' . $atts['search'] . '%', '%' . $atts['search'] . '%');
     }
     // Meta query support.
     $distinct = '';
     $join = '';
     if (!empty($atts['meta_query'])) {
         $meta_query = new cnMeta_Query($atts['meta_query']);
         $meta_clauses = $meta_query->get_sql('term', 't', 'term_id');
         $distinct .= 'DISTINCT ';
         $join .= $meta_clauses['join'];
         $where[] = $meta_clauses['where'];
     }
     switch ($atts['fields']) {
         case 'all':
             $select = array('t.*', 'tt.*');
             break;
         case 'ids':
         case 'id=>parent':
             $select = array('t.term_id', 'tt.parent', 'tt.count');
             break;
         case 'names':
             $select = array('t.term_id', 'tt.parent', 'tt.count', 't.name');
             break;
         case 'count':
             $orderBy = '';
             //$order   = '';
             $select = array('COUNT(*)');
             break;
         case 'id=>name':
             $select = array('t.term_id', 't.name', 'tt.count', 'tt.taxonomy');
             break;
         case 'id=>slug':
             $select = array('t.term_id', 't.slug', 'tt.count', 'tt.taxonomy');
             break;
     }
     /**
      * Filter the fields to select in the terms query.
      *
      * @since 8.1
      *
      * @param array        $select     An array of fields to select for the terms query.
      * @param array        $atts       An array of term query arguments.
      * @param string|array $taxonomies A taxonomy or array of taxonomies.
      */
     $fields = implode(', ', apply_filters('cn_get_terms_fields', $select, $atts, $taxonomies));
     $join .= 'INNER JOIN ' . CN_TERM_TAXONOMY_TABLE . ' AS tt ON t.term_id = tt.term_id';
     $pieces = array('fields', 'join', 'where', 'distinct', 'orderBy', 'orderby', 'order', 'limit');
     /**
      * Filter the terms query SQL clauses.
      *
      * @since 8.1
      *
      * @param array        $pieces     Terms query SQL clauses.
      * @param string|array $taxonomies A taxonomy or array of taxonomies.
      * @param array        $atts       An array of terms query arguments.
      */
     $clauses = apply_filters('cn_terms_clauses', compact($pieces), $taxonomies, $atts);
     foreach ($pieces as $piece) {
         ${$piece} = isset($clauses[$piece]) ? $clauses[$piece] : '';
     }
     $sql = sprintf('SELECT %1$s FROM %2$s AS t %3$s WHERE %4$s %5$s%6$s', $distinct . $fields, CN_TERMS_TABLE, $join, implode(' ', $where), $orderBy, empty($limit) ? '' : ' ' . $limit);
     if ('count' == $atts['fields']) {
         $term_count = $wpdb->get_var($sql);
         return absint($term_count);
     }
     $terms = $wpdb->get_results($sql);
     if ('all' == $atts['fields']) {
         foreach ($taxonomies as $taxonomy) {
             update_term_cache($terms, 'cn_' . $taxonomy);
         }
     }
     // Prime term meta cache.
     if ($atts['update_meta_cache']) {
         $term_ids = wp_list_pluck($terms, 'term_id');
         cnMeta::updateCache('term', $term_ids);
     }
     if (empty($terms)) {
         wp_cache_add($cache_key, array(), 'cn_terms', DAY_IN_SECONDS);
         $terms = apply_filters('cn_terms', array(), $taxonomies, $atts);
         return $terms;
     }
     if ($atts['child_of']) {
         $children = self::childrenIDs(reset($taxonomies));
         if (!empty($children)) {
             $terms = self::descendants($atts['child_of'], $terms, reset($taxonomies));
         }
     }
     /*
      * @todo Add method to adjust counts based on user visibility permissions.
      */
     // Update term counts to include children.
     if ($atts['pad_counts'] && 'all' == $atts['fields']) {
         foreach ($taxonomies as $_tax) {
             self::padCounts($terms, $_tax);
         }
     }
     // Make sure we show empty categories that have children.
     if ($atts['hierarchical'] && $atts['hide_empty'] && is_array($terms)) {
         foreach ($terms as $k => $term) {
             if (!$term->count) {
                 $children = self::children($term->term_id, $term->taxonomy);
                 if (is_array($children)) {
                     foreach ($children as $child_id) {
                         $child = self::filter($child_id, $term->taxonomy);
                         if ($child->count) {
                             continue 2;
                         }
                     }
                 }
                 // It really is empty
                 unset($terms[$k]);
             }
         }
     }
     $_terms = array();
     if ('id=>parent' == $atts['fields']) {
         foreach ($terms as $term) {
             $_terms[$term->term_id] = $term->parent;
         }
     } elseif ('ids' == $atts['fields']) {
         foreach ($terms as $term) {
             $_terms[] = $term->term_id;
         }
     } elseif ('names' == $atts['fields']) {
         foreach ($terms as $term) {
             $_terms[] = $term->name;
         }
     } elseif ('id=>name' == $atts['fields']) {
         foreach ($terms as $term) {
             $_terms[$term->term_id] = $term->name;
         }
     } elseif ('id=>slug' == $atts['fields']) {
         foreach ($terms as $term) {
             $_terms[$term->term_id] = $term->slug;
         }
     }
     if (!empty($_terms)) {
         $terms = $_terms;
     }
     if ($atts['number'] && is_array($terms) && count($terms) > $atts['number']) {
         $terms = array_slice($terms, $atts['offset'], $atts['number']);
     }
     wp_cache_add($cache_key, $terms, 'cn_terms', DAY_IN_SECONDS);
     if ('all' === $atts['fields']) {
         $terms = array_map(array('cnTerm', 'get'), $terms);
     }
     $terms = apply_filters('cn_terms', $terms, $taxonomies, $atts);
     return $terms;
 }
Beispiel #13
0
 /**
  * Load data from connections for the doubles team.
  */
 protected function load()
 {
     if ($this->cnData === null) {
         global $connections;
         $cnRetrieve = $connections->retrieve;
         $ret = $cnRetrieve->entries(array('family_name' => $this->familyName, 'allow_public_override' => true, 'private_override' => true));
         if (count($ret) == 1) {
             $this->cnData = $ret[0];
             $this->cnMeta = array();
             $allMeta = cnMeta::get('entry', $this->cnData->id);
             if (is_array($allMeta)) {
                 foreach ($allMeta as $key => $values) {
                     $this->cnMeta[$key] = $values[0];
                 }
             }
         } else {
             $this->cnData = new StdClass();
             $this->cnMeta = array();
         }
     }
 }