Exemplo n.º 1
0
 /**
  * @group bp_xprofile_update_meta_cache
  */
 public function test_bp_xprofile_update_meta_cache()
 {
     $u = $this->factory->user->create();
     $g = $this->factory->xprofile_group->create();
     $f = $this->factory->xprofile_field->create(array('field_group_id' => $g));
     $d = new BP_XProfile_ProfileData($f, $u);
     $d->user_id = $u;
     $d->field_id = $f;
     $d->value = 'foo';
     $d->last_updated = bp_core_current_time();
     $d->save();
     bp_xprofile_add_meta($g, 'group', 'group_foo', 'group_bar');
     bp_xprofile_add_meta($f, 'field', 'field_foo', 'field_bar');
     bp_xprofile_add_meta($d->id, 'data', 'data_foo', 'data_bar');
     // prime cache
     bp_xprofile_update_meta_cache(array('group' => array($g), 'field' => array($f), 'data' => array($d->id)));
     $g_expected = array('group_foo' => array('group_bar'));
     $this->assertSame($g_expected, wp_cache_get($g, 'xprofile_group_meta'));
     $f_expected = array('field_foo' => array('field_bar'));
     $this->assertSame($f_expected, wp_cache_get($f, 'xprofile_field_meta'));
     $d_expected = array('data_foo' => array('data_bar'));
     $this->assertSame($d_expected, wp_cache_get($d->id, 'xprofile_data_meta'));
 }
 /**
  * get()
  *
  * Populates the BP_XProfile_Group object with profile field groups, fields, and field data
  *
  * @package BuddyPress XProfile
  *
  * @global $wpdb WordPress DB access object.
  * @global BuddyPress $bp The one true BuddyPress instance
  *
  * @param array $args Takes an array of parameters:
  *		'profile_group_id' - Limit results to a single profile group
  *		'user_id' - Required if you want to load a specific user's data
  *		'hide_empty_groups' - Hide groups without any fields
  *		'hide_empty_fields' - Hide fields where the user has not provided data
  *		'fetch_fields' - Load each group's fields
  *		'fetch_field_data' - Load each field's data. Requires a user_id
  *		'exclude_groups' - Comma-separated list of groups to exclude
  *		'exclude_fields' - Comma-separated list of fields to exclude
  *		'update_meta_cache' - Whether to pre-fetch xprofilemeta
  *		   for all retrieved groups, fields, and data
  *
  * @return array $groups
  */
 public static function get($args = array())
 {
     global $wpdb, $bp;
     $defaults = array('profile_group_id' => false, 'user_id' => bp_displayed_user_id(), 'hide_empty_groups' => false, 'hide_empty_fields' => false, 'fetch_fields' => false, 'fetch_field_data' => false, 'fetch_visibility_level' => false, 'exclude_groups' => false, 'exclude_fields' => false, 'update_meta_cache' => true);
     $r = wp_parse_args($args, $defaults);
     extract($r, EXTR_SKIP);
     // Keep track of object IDs for cache-priming
     $object_ids = array('group' => array(), 'field' => array(), 'data' => array());
     $where_sql = '';
     if (!empty($profile_group_id)) {
         $where_sql = $wpdb->prepare('WHERE g.id = %d', $profile_group_id);
     } elseif ($exclude_groups) {
         $where_sql = $wpdb->prepare("WHERE g.id NOT IN ({$exclude_groups})");
     }
     if (!empty($hide_empty_groups)) {
         $group_ids = $wpdb->get_col("SELECT DISTINCT g.id FROM {$bp->profile->table_name_groups} g INNER JOIN {$bp->profile->table_name_fields} f ON g.id = f.group_id {$where_sql} ORDER BY g.group_order ASC");
     } else {
         $group_ids = $wpdb->get_col("SELECT DISTINCT g.id FROM {$bp->profile->table_name_groups} g {$where_sql} ORDER BY g.group_order ASC");
     }
     $groups = self::get_group_data($group_ids);
     if (empty($fetch_fields)) {
         return $groups;
     }
     // Get the group ids
     $group_ids = array();
     foreach ((array) $groups as $group) {
         $group_ids[] = $group->id;
     }
     // Store for meta cache priming
     $object_ids['group'] = $group_ids;
     $group_ids = implode(',', (array) $group_ids);
     if (empty($group_ids)) {
         return $groups;
     }
     // Support arrays and comma-separated strings
     $exclude_fields_cs = wp_parse_id_list($exclude_fields);
     // Visibility - Handled here so as not to be overridden by sloppy use of the
     // exclude_fields parameter. See bp_xprofile_get_hidden_fields_for_user()
     $exclude_fields_cs = array_merge($exclude_fields_cs, bp_xprofile_get_hidden_fields_for_user($user_id));
     $exclude_fields_cs = implode(',', $exclude_fields_cs);
     if (!empty($exclude_fields_cs)) {
         $exclude_fields_sql = "AND id NOT IN ({$exclude_fields_cs})";
     } else {
         $exclude_fields_sql = '';
     }
     // Fetch the fields
     $fields = $wpdb->get_results("SELECT id, name, description, type, group_id, is_required FROM {$bp->profile->table_name_fields} WHERE group_id IN ( {$group_ids} ) AND parent_id = 0 {$exclude_fields_sql} ORDER BY field_order");
     // Store field IDs for meta cache priming
     $object_ids['field'] = wp_list_pluck($fields, 'id');
     if (empty($fields)) {
         return $groups;
     }
     // Maybe fetch field data
     if (!empty($fetch_field_data)) {
         // Fetch the field data for the user.
         foreach ((array) $fields as $field) {
             $field_ids[] = $field->id;
         }
         $field_ids_sql = implode(',', (array) $field_ids);
         if (!empty($field_ids) && !empty($user_id)) {
             $field_data = BP_XProfile_ProfileData::get_data_for_user($user_id, $field_ids);
         }
         // Remove data-less fields, if necessary
         if (!empty($hide_empty_fields) && !empty($field_ids) && !empty($field_data)) {
             // Loop through the results and find the fields that have data.
             foreach ((array) $field_data as $data) {
                 // Empty fields may contain a serialized empty array
                 $maybe_value = maybe_unserialize($data->value);
                 if (!empty($maybe_value) && false !== ($key = array_search($data->field_id, $field_ids))) {
                     // Fields that have data get removed from the list
                     unset($field_ids[$key]);
                 }
             }
             // The remaining members of $field_ids are empty. Remove them.
             foreach ($fields as $field_key => $field) {
                 if (in_array($field->id, $field_ids)) {
                     unset($fields[$field_key]);
                 }
             }
             // Reset indexes
             $fields = array_values($fields);
         }
         // Field data was found
         if (!empty($fields) && !empty($field_data) && !is_wp_error($field_data)) {
             // Loop through fields
             foreach ((array) $fields as $field_key => $field) {
                 // Loop throught the data in each field
                 foreach ((array) $field_data as $data) {
                     // Assign correct data value to the field
                     if ($field->id == $data->field_id) {
                         $fields[$field_key]->data = new stdClass();
                         $fields[$field_key]->data->value = $data->value;
                         $fields[$field_key]->data->id = $data->id;
                     }
                     // Store for meta cache priming
                     $object_ids['data'][] = $data->id;
                 }
             }
         }
     }
     // Prime the meta cache, if necessary
     if ($update_meta_cache) {
         bp_xprofile_update_meta_cache($object_ids);
     }
     // Maybe fetch visibility levels
     if (!empty($fetch_visibility_level)) {
         $fields = self::fetch_visibility_level($user_id, $fields);
     }
     // Merge the field array back in with the group array
     foreach ((array) $groups as $group) {
         // Indexes may have been shifted after previous deletions, so we get a
         // fresh one each time through the loop
         $index = array_search($group, $groups);
         foreach ((array) $fields as $field) {
             if ($group->id == $field->group_id) {
                 $groups[$index]->fields[] = $field;
             }
         }
         // When we unset fields above, we may have created empty groups.
         // Remove them, if necessary.
         if (empty($group->fields) && $hide_empty_groups) {
             unset($groups[$index]);
         }
         // Reset indexes
         $groups = array_values($groups);
     }
     return $groups;
 }
 /**
  * Populates the BP_XProfile_Group object with profile field groups, fields,
  * and field data
  *
  * @package BuddyPress XProfile
  *
  * @global object $wpdb WordPress DB access object.
  *
  * @param array $args {
  *  Array of optional arguments:
  *      @type int          $profile_group_id  Limit results to a single profile group.
  *      @type int          $user_id           Required if you want to load a specific user's data.
  *                                            Default: displayed user's ID.
  *      @type array|string $member_type       Limit fields by those restricted to a given member type, or array of
  *                                            member types. If `$user_id` is provided, the value of `$member_type`
  *                                            will be overridden by the member types of the provided user. The
  *                                            special value of 'any' will return only those fields that are
  *                                            unrestricted by member type - i.e., those applicable to any type.
  *      @type bool         $hide_empty_groups True to hide groups that don't have any fields. Default: false.
  *      @type bool         $hide_empty_fields True to hide fields where the user has not provided data.
  *                                            Default: false.
  *      @type bool         $fetch_fields      Whether to fetch each group's fields. Default: false.
  *      @type bool         $fetch_field_data  Whether to fetch data for each field. Requires a $user_id.
  *                                            Default: false.
  *      @type array        $exclude_groups    Comma-separated list or array of group IDs to exclude.
  *      @type array        $exclude_fields    Comma-separated list or array of field IDs to exclude.
  *      @type bool         $update_meta_cache Whether to pre-fetch xprofilemeta for all retrieved groups, fields,
  *                                            and data. Default: true.
  * }
  * @return array $groups
  */
 public static function get($args = array())
 {
     global $wpdb;
     // Parse arguments.
     $r = wp_parse_args($args, array('profile_group_id' => false, 'user_id' => bp_displayed_user_id(), 'member_type' => false, 'hide_empty_groups' => false, 'hide_empty_fields' => false, 'fetch_fields' => false, 'fetch_field_data' => false, 'fetch_visibility_level' => false, 'exclude_groups' => false, 'exclude_fields' => false, 'update_meta_cache' => true));
     // Keep track of object IDs for cache-priming.
     $object_ids = array('group' => array(), 'field' => array(), 'data' => array());
     // WHERE.
     if (!empty($r['profile_group_id'])) {
         $where_sql = $wpdb->prepare('WHERE g.id = %d', $r['profile_group_id']);
     } elseif ($r['exclude_groups']) {
         $exclude = join(',', wp_parse_id_list($r['exclude_groups']));
         $where_sql = "WHERE g.id NOT IN ({$exclude})";
     } else {
         $where_sql = '';
     }
     $bp = buddypress();
     // Include or exclude empty groups.
     if (!empty($r['hide_empty_groups'])) {
         $group_ids = $wpdb->get_col("SELECT DISTINCT g.id FROM {$bp->profile->table_name_groups} g INNER JOIN {$bp->profile->table_name_fields} f ON g.id = f.group_id {$where_sql} ORDER BY g.group_order ASC");
     } else {
         $group_ids = $wpdb->get_col("SELECT DISTINCT g.id FROM {$bp->profile->table_name_groups} g {$where_sql} ORDER BY g.group_order ASC");
     }
     // Get all group data.
     $groups = self::get_group_data($group_ids);
     // Bail if not also getting fields.
     if (empty($r['fetch_fields'])) {
         return $groups;
     }
     // Get the group ids from the groups we found.
     $group_ids = wp_list_pluck($groups, 'id');
     // Store for meta cache priming.
     $object_ids['group'] = $group_ids;
     // Bail if no groups found.
     if (empty($group_ids)) {
         return $groups;
     }
     // Setup IN query from group IDs.
     $group_ids_in = implode(',', (array) $group_ids);
     // Support arrays and comma-separated strings.
     $exclude_fields_cs = wp_parse_id_list($r['exclude_fields']);
     // Visibility - Handled here so as not to be overridden by sloppy use of the
     // exclude_fields parameter. See bp_xprofile_get_hidden_fields_for_user().
     $hidden_user_fields = bp_xprofile_get_hidden_fields_for_user($r['user_id']);
     $exclude_fields_cs = array_merge($exclude_fields_cs, $hidden_user_fields);
     $exclude_fields_cs = implode(',', $exclude_fields_cs);
     // Set up NOT IN query for excluded field IDs.
     if (!empty($exclude_fields_cs)) {
         $exclude_fields_sql = "AND id NOT IN ({$exclude_fields_cs})";
     } else {
         $exclude_fields_sql = '';
     }
     // Set up IN query for included field IDs.
     $include_field_ids = array();
     // Member-type restrictions.
     if (bp_get_member_types()) {
         if ($r['user_id'] || false !== $r['member_type']) {
             $member_types = $r['member_type'];
             if ($r['user_id']) {
                 $member_types = bp_get_member_type($r['user_id'], false);
                 if (empty($member_types)) {
                     $member_types = array('null');
                 }
             }
             $member_types_fields = BP_XProfile_Field::get_fields_for_member_type($member_types);
             $include_field_ids += array_keys($member_types_fields);
         }
     }
     $in_sql = '';
     if (!empty($include_field_ids)) {
         $include_field_ids_cs = implode(',', array_map('intval', $include_field_ids));
         $in_sql = " AND id IN ({$include_field_ids_cs}) ";
     }
     // Fetch the fields.
     $field_ids = $wpdb->get_col("SELECT id FROM {$bp->profile->table_name_fields} WHERE group_id IN ( {$group_ids_in} ) AND parent_id = 0 {$exclude_fields_sql} {$in_sql} ORDER BY field_order");
     // Bail if no fields.
     if (empty($field_ids)) {
         return $groups;
     }
     $field_ids = array_map('intval', $field_ids);
     // Prime the field cache.
     $uncached_field_ids = bp_get_non_cached_ids($field_ids, 'bp_xprofile_fields');
     if (!empty($uncached_field_ids)) {
         $_uncached_field_ids = implode(',', array_map('intval', $uncached_field_ids));
         $uncached_fields = $wpdb->get_results("SELECT * FROM {$bp->profile->table_name_fields} WHERE id IN ({$_uncached_field_ids})");
         foreach ($uncached_fields as $uncached_field) {
             $fid = intval($uncached_field->id);
             wp_cache_set($fid, $uncached_field, 'bp_xprofile_fields');
         }
     }
     // Pull field objects from the cache.
     $fields = array();
     foreach ($field_ids as $field_id) {
         $fields[] = xprofile_get_field($field_id);
     }
     // Store field IDs for meta cache priming.
     $object_ids['field'] = $field_ids;
     // Maybe fetch field data.
     if (!empty($r['fetch_field_data'])) {
         // Get field data for user ID.
         if (!empty($field_ids) && !empty($r['user_id'])) {
             $field_data = BP_XProfile_ProfileData::get_data_for_user($r['user_id'], $field_ids);
         }
         // Remove data-less fields, if necessary.
         if (!empty($r['hide_empty_fields']) && !empty($field_ids) && !empty($field_data)) {
             // Loop through the results and find the fields that have data.
             foreach ((array) $field_data as $data) {
                 // Empty fields may contain a serialized empty array.
                 $maybe_value = maybe_unserialize($data->value);
                 // Valid field values of 0 or '0' get caught by empty(), so we have an extra check for these. See #BP5731.
                 if ((!empty($maybe_value) || '0' == $maybe_value) && false !== ($key = array_search($data->field_id, $field_ids))) {
                     // Fields that have data get removed from the list.
                     unset($field_ids[$key]);
                 }
             }
             // The remaining members of $field_ids are empty. Remove them.
             foreach ($fields as $field_key => $field) {
                 if (in_array($field->id, $field_ids)) {
                     unset($fields[$field_key]);
                 }
             }
             // Reset indexes.
             $fields = array_values($fields);
         }
         // Field data was found.
         if (!empty($fields) && !empty($field_data) && !is_wp_error($field_data)) {
             // Loop through fields.
             foreach ((array) $fields as $field_key => $field) {
                 // Loop through the data in each field.
                 foreach ((array) $field_data as $data) {
                     // Assign correct data value to the field.
                     if ($field->id == $data->field_id) {
                         $fields[$field_key]->data = new stdClass();
                         $fields[$field_key]->data->value = $data->value;
                         $fields[$field_key]->data->id = $data->id;
                     }
                     // Store for meta cache priming.
                     $object_ids['data'][] = $data->id;
                 }
             }
         }
     }
     // Prime the meta cache, if necessary.
     if (!empty($r['update_meta_cache'])) {
         bp_xprofile_update_meta_cache($object_ids);
     }
     // Maybe fetch visibility levels.
     if (!empty($r['fetch_visibility_level'])) {
         $fields = self::fetch_visibility_level($r['user_id'], $fields);
     }
     // Merge the field array back in with the group array.
     foreach ((array) $groups as $group) {
         // Indexes may have been shifted after previous deletions, so we get a
         // fresh one each time through the loop.
         $index = array_search($group, $groups);
         foreach ((array) $fields as $field) {
             if ($group->id === $field->group_id) {
                 $groups[$index]->fields[] = $field;
             }
         }
         // When we unset fields above, we may have created empty groups.
         // Remove them, if necessary.
         if (empty($group->fields) && !empty($r['hide_empty_groups'])) {
             unset($groups[$index]);
         }
         // Reset indexes.
         $groups = array_values($groups);
     }
     return $groups;
 }