/** * Get by multiple conditions * Conditions get treated with AND logic * TODO Make this more efficient * @param array $conditions * @param mixed $args * @return array */ public static function getByMultiple($conditions, $args = array()) { if (!Arr::iterable($conditions)) { return self::getWhere($args, $load_terms); } // Extract number if passed in $args // because we don't want to prematurely restrict the result set. $number = array_key_exists('number', $args) ? $args['number'] : null; unset($args['number']); // First, get all the post_ids $term_ids = array(); foreach ($conditions as $k => $condition) { // Conditions can have numeric or named keys: // ['key1', 'val1', '='] // ['key'=>'foo', 'val'=>'bar', '='] $condition_values = array_values($condition); $key = array_key_exists('key', $condition) ? $condition['key'] : $condition_values[0]; $value = array_key_exists('value', $condition) ? $condition['value'] : $condition_values[1]; // Make sure we have a compare $compare = '='; if (array_key_exists('compare', $condition)) { $compare = $condition['compare']; } elseif (array_key_exists(2, $condition_values)) { $compare = $condition_values[2]; } // Get the posts from getBy // Trying to replicate getBy's logic could be significant // b/c it handles both core and meta fields $terms = self::getBy($key, $value, $compare, $args); if (!Arr::iterable($terms)) { continue; } // Using array_intersect here gives us the AND relationship // array_merge would give us OR $new_term_ids = Collection::pluck($terms, 'term_id'); $new_term_ids = array_map('intval', $new_term_ids); $term_ids = Arr::iterable($term_ids) ? array_intersect($term_ids, $new_term_ids) : $new_term_ids; $term_ids = array_unique($term_ids); // After the first conditional, we can start modifying the args // to restrict results to previously matched posts. // // Effectively, this also means that when calling this method // you should put conditions you expect to be more restrictive // earlier in the conditionals array. $args['include'] = $term_ids; } // Reapply numberposts now that we have our desired post_ids if (!is_null($number)) { $args['number'] = $number; } // TODO This should probably use getWhere // but it seems like getWhere may not work with the ordering unset($args['include']); return Arr::iterable($term_ids) ? self::getBy('term_id', $term_ids, 'in', $args) : array(); }
public static function getSubPosts($fieldname, $post_id) { $record = \Taco\Post::find($post_id); $field_ids = explode(',', $record->get($fieldname)); $subposts = self::getSubPostsSafe($fieldname, $post_id); $subpost_ids = Collection::pluck($subposts, 'ID'); $filtered = []; foreach ($field_ids as $fid) { if (!in_array($fid, $subpost_ids)) { continue; } $filtered[$fid] = \Taco\Post::find($fid); } return $filtered; }
/** * Register the taxonomies * WordPress limits calls to register_taxonomy to once per taxonomy * So we need to externalize this from a single TacoPostUtil::load call * @return integer Number of taxonomies registered */ public static function registerTaxonomies() { global $taxonomies_infos; if (!Arr::iterable($taxonomies_infos)) { return 0; } // Start by grouping all taxonomy requests by taxonomy key $count = 0; $grouped = Collection::groupBy($taxonomies_infos, 'key'); foreach ($grouped as $key => $key_taxonomies) { // Now get all the post types $post_types = Collection::pluck($key_taxonomies, 'post_type'); $configs = Collection::pluck($key_taxonomies, 'config'); // Now we can finally register this taxonomy register_taxonomy($key, $post_types, current($configs)); $count++; } return $count; }
/** * Get by multiple conditions * Conditions get treated with AND logic * TODO Make this more efficient * @param array $conditions * @param mixed $args * @param bool $load_terms * @return array */ public static function getByMultiple($conditions, $args = array(), $load_terms = true) { if (!Arr::iterable($conditions)) { return self::getWhere($args, $load_terms); } // Extract numberposts if passed in $args // because we don't want to prematurely restrict the result set. $numberposts = array_key_exists('numberposts', $args) ? $args['numberposts'] : null; unset($args['numberposts']); // First, get all the post_ids $post_ids = array(); foreach ($conditions as $k => $condition) { // Conditions can have numeric or named keys: // ['key1', 'val1', '='] // ['key'=>'foo', 'val'=>'bar', '='] $condition_values = array_values($condition); $key = array_key_exists('key', $condition) ? $condition['key'] : $condition_values[0]; $value = array_key_exists('value', $condition) ? $condition['value'] : $condition_values[1]; // Make sure we have a compare $compare = '='; if (array_key_exists('compare', $condition)) { $compare = $condition['compare']; } elseif (array_key_exists(2, $condition_values)) { $compare = $condition_values[2]; } // Get the posts from getBy // Trying to replicate getBy's logic could be significant // b/c it handles both core and meta fields $posts = self::getBy($key, $value, $compare, $args, false); // If no results, that means we found a condition // that was not met by any posts. // So we need to clear out $post_ids so that // we don't get false positives. if (!Arr::iterable($posts)) { $post_ids = array(); break; } // Using array_intersect here gives us the AND relationship // array_merge would give us OR $new_post_ids = Collection::pluck($posts, 'ID'); $post_ids = Arr::iterable($post_ids) ? array_intersect($post_ids, $new_post_ids) : $new_post_ids; // If no overlap, we're done checking criteria if (count($post_ids) === 0) { break; } } // You can't do this within the loop b/c WordPress treats // post__in as an OR relationship when passed to get_posts if (Arr::iterable($post_ids)) { $args['post__in'] = $post_ids; } // Reapply numberposts now that we have our desired post_ids if (!is_null($numberposts)) { $args['numberposts'] = $numberposts; } return Arr::iterable($post_ids) ? self::getWhere($args, $load_terms) : array(); }
public function testTerms() { // Cleanup Person::deleteAll(); // Set terms $person = new Person(); $person->post_title = 'Term Test'; $person->setTerms(array('term1'), 'irs'); $post_id = $person->save(); // Get terms $person = Person::find($post_id); $terms = $person->getTerms('irs'); $term_names = \Taco\Util\Collection::pluck($terms, 'name'); $this->assertEquals(array('term1'), $term_names); // Has term $term_id = current($terms)->term_id; $this->assertTrue($person->hasTerm($term_id)); }
/** * Check if an array of post or term ids exist in the database * @param array $ids_array comma seperated list of ids * @param bool $is_term are the ids term ids instead of post ids? * @return array */ private static function getItemsIfExists($ids_array, $is_term = false) { global $wpdb; if ($is_term) { $results = $wpdb->get_results(sprintf("SELECT `term_id`\n FROM `%s`", $wpdb->terms), ARRAY_A); $ids = Collection::pluck($results, 'term_id'); } else { $results = $wpdb->get_results(sprintf("SELECT `ID`\n FROM `%s`\n WHERE `post_status` = 'publish'", $wpdb->posts), ARRAY_A); $ids = Collection::pluck($results, 'ID'); } return array_intersect($ids_array, $ids); }