[ Index ]

PHP Cross Reference of BuddyPress

title

Body

[close]

/src/bp-xprofile/ -> bp-xprofile-cache.php (source)

   1  <?php
   2  /**
   3   * BuddyPress XProfile Caching Functions.
   4   *
   5   * Caching functions handle the clearing of cached objects and pages on specific
   6   * actions throughout BuddyPress.
   7   *
   8   * @package BuddyPress
   9   * @subpackage XProfileCache
  10   * @since 1.5.0
  11   */
  12  
  13  // Exit if accessed directly.
  14  defined( 'ABSPATH' ) || exit;
  15  
  16  /**
  17   * Determine which xprofile fields do not have cached values for a user.
  18   *
  19   * @since 2.2.0
  20   *
  21   * @param int   $user_id   User ID to check.
  22   * @param array $field_ids XProfile field IDs.
  23   * @return array
  24   */
  25  function bp_xprofile_get_non_cached_field_ids( $user_id = 0, $field_ids = array() ) {
  26      $uncached_fields = array();
  27  
  28      foreach ( $field_ids as $field_id ) {
  29          $field_id  = (int) $field_id;
  30          $cache_key = "{$user_id}:{$field_id}";
  31          if ( false === wp_cache_get( $cache_key, 'bp_xprofile_data' ) ) {
  32              $uncached_fields[] = $field_id;
  33          }
  34      }
  35  
  36      return $uncached_fields;
  37  }
  38  
  39  /**
  40   * Slurp up xprofilemeta for a specified set of profile objects.
  41   *
  42   * We do not use bp_update_meta_cache() for the xprofile component. This is
  43   * because the xprofile component has three separate object types (group,
  44   * field, and data) and three corresponding cache groups. Using the technique
  45   * in bp_update_meta_cache(), pre-fetching would take three separate database
  46   * queries. By grouping them together, we can reduce the required queries to
  47   * one.
  48   *
  49   * This function is called within a bp_has_profile() loop.
  50   *
  51   * @since 2.0.0
  52   *
  53   * @param array $object_ids Multi-dimensional array of object_ids, keyed by
  54   *                          object type ('group', 'field', 'data').
  55   * @return bool
  56   */
  57  function bp_xprofile_update_meta_cache( $object_ids = array() ) {
  58      global $wpdb;
  59  
  60      // Bail if no objects.
  61      if ( empty( $object_ids ) ) {
  62          return false;
  63      }
  64  
  65      $bp = buddypress();
  66  
  67      // Define the array where uncached object IDs will be stored.
  68      $uncached_object_ids = array(
  69          'group',
  70          'field',
  71          'data'
  72      );
  73  
  74      // Define the cache groups for the 3 types of XProfile metadata.
  75      $cache_groups = array(
  76          'group' => 'xprofile_group_meta',
  77          'field' => 'xprofile_field_meta',
  78          'data'  => 'xprofile_data_meta',
  79      );
  80  
  81      // No reason to query yet.
  82      $do_query = false;
  83  
  84      // Loop through object types and look for uncached data.
  85      foreach ( $uncached_object_ids as $object_type ) {
  86  
  87          // Skip if empty object type.
  88          if ( empty( $object_ids[ $object_type ] ) ) {
  89              continue;
  90          }
  91  
  92          // Sanitize $object_ids passed to the function.
  93          $object_type_ids = wp_parse_id_list( $object_ids[ $object_type ] );
  94  
  95          // Get non-cached IDs for each object type.
  96          $uncached_object_ids[ $object_type ] = bp_get_non_cached_ids( $object_type_ids, $cache_groups[ $object_type ] );
  97  
  98          // Set the flag to do the meta query.
  99          if ( ! empty( $uncached_object_ids[ $object_type ] ) && ( false === $do_query ) ) {
 100              $do_query = true;
 101          }
 102      }
 103  
 104      // Bail if no uncached items.
 105      if ( false === $do_query ) {
 106          return;
 107      }
 108  
 109      // Setup where conditions for query.
 110      $where_sql        = '';
 111      $where_conditions = array();
 112  
 113      // Loop through uncached objects and prepare to query for them.
 114      foreach ( $uncached_object_ids as $otype => $oids ) {
 115  
 116          // Skip empty object IDs.
 117          if ( empty( $oids ) ) {
 118              continue;
 119          }
 120  
 121          // Compile WHERE query conditions for uncached metadata.
 122          $oids_sql           = implode( ',', wp_parse_id_list( $oids ) );
 123          $where_conditions[] = $wpdb->prepare( "( object_type = %s AND object_id IN ({$oids_sql}) )", $otype );
 124      }
 125  
 126      // Bail if no where conditions.
 127      if ( empty( $where_conditions ) ) {
 128          return;
 129      }
 130  
 131      // Setup the WHERE query part.
 132      $where_sql = implode( " OR ", $where_conditions );
 133  
 134      // Attempt to query meta values.
 135      $meta_list = $wpdb->get_results( "SELECT object_id, object_type, meta_key, meta_value FROM {$bp->profile->table_name_meta} WHERE {$where_sql}" );
 136  
 137      // Bail if no results found.
 138      if ( empty( $meta_list ) || is_wp_error( $meta_list ) ) {
 139          return;
 140      }
 141  
 142      // Setup empty cache array.
 143      $cache = array();
 144  
 145      // Loop through metas.
 146      foreach ( $meta_list as $meta ) {
 147          $oid    = $meta->object_id;
 148          $otype  = $meta->object_type;
 149          $okey   = $meta->meta_key;
 150          $ovalue = $meta->meta_value;
 151  
 152          // Force subkeys to be array type.
 153          if ( ! isset( $cache[ $otype ][ $oid ] ) || ! is_array( $cache[ $otype ][ $oid ] ) ) {
 154              $cache[ $otype ][ $oid ] = array();
 155          }
 156  
 157          if ( ! isset( $cache[ $otype ][ $oid ][ $okey ] ) || ! is_array( $cache[ $otype ][ $oid ][ $okey ] ) ) {
 158              $cache[ $otype ][ $oid ][ $okey ] = array();
 159          }
 160  
 161          // Add to the cache array.
 162          $cache[ $otype ][ $oid ][ $okey ][] = maybe_unserialize( $ovalue );
 163      }
 164  
 165      // Loop through data and cache to the appropriate object.
 166      foreach ( $cache as $object_type => $object_caches ) {
 167  
 168          // Determine the cache group for this data.
 169          $cache_group = $cache_groups[ $object_type ];
 170  
 171          // Loop through objects and cache appropriately.
 172          foreach ( $object_caches as $object_id => $object_cache ) {
 173              wp_cache_set( $object_id, $object_cache, $cache_group );
 174          }
 175      }
 176  }
 177  
 178  /**
 179   * Clear cached XProfile field group data.
 180   *
 181   * @since 2.1.0
 182   *
 183   * @param object $group_obj Groub object to clear.
 184   */
 185  function xprofile_clear_profile_groups_object_cache( $group_obj ) {
 186      wp_cache_delete( 'all',          'bp_xprofile_groups' );
 187      wp_cache_delete( $group_obj->id, 'bp_xprofile_groups' );
 188  }
 189  add_action( 'xprofile_group_after_delete', 'xprofile_clear_profile_groups_object_cache' );
 190  add_action( 'xprofile_group_after_save',   'xprofile_clear_profile_groups_object_cache' );
 191  
 192  /**
 193   * Clear caches when a field object is modified.
 194   *
 195   * @since 2.0.0
 196   *
 197   * @param BP_XProfile_Field $field_obj Field object cache to delete.
 198   */
 199  function xprofile_clear_profile_field_object_cache( $field_obj ) {
 200  
 201      // Clear default visibility level cache.
 202      wp_cache_delete( 'default_visibility_levels', 'bp_xprofile' );
 203  
 204      // Modified fields can alter parent group status, in particular when
 205      // the group goes from empty to non-empty. Bust its cache, as well as
 206      // the global 'all' cache.
 207      wp_cache_delete( 'all',                'bp_xprofile_groups' );
 208      wp_cache_delete( $field_obj->group_id, 'bp_xprofile_groups' );
 209  }
 210  add_action( 'xprofile_fields_saved_field',   'xprofile_clear_profile_field_object_cache' );
 211  add_action( 'xprofile_fields_deleted_field', 'xprofile_clear_profile_field_object_cache' );
 212  
 213  /**
 214   * Clears member_type cache when a field's member types are updated.
 215   *
 216   * @since 2.4.0
 217   */
 218  function bp_xprofile_clear_member_type_cache() {
 219      wp_cache_delete( 'field_member_types', 'bp_xprofile' );
 220  }
 221  add_action( 'bp_xprofile_field_set_member_type', 'bp_xprofile_clear_member_type_cache' );
 222  
 223  /**
 224   * Clear caches when a user's updates a field data object.
 225   *
 226   * @since 2.0.0
 227   *
 228   * @param BP_XProfile_ProfileData $data_obj Field data object to delete.
 229   */
 230  function xprofile_clear_profiledata_object_cache( $data_obj ) {
 231      wp_cache_delete( "{$data_obj->user_id}:{$data_obj->field_id}", 'bp_xprofile_data' );
 232  }
 233  add_action( 'xprofile_data_after_save',   'xprofile_clear_profiledata_object_cache' );
 234  add_action( 'xprofile_data_after_delete', 'xprofile_clear_profiledata_object_cache' );
 235  
 236  /**
 237   * Clear fullname_field_id cache when bp-xprofile-fullname-field-name is updated.
 238   *
 239   * Note for future developers: Dating from an early version of BuddyPress where
 240   * the fullname field (field #1) did not have a title that was editable in the
 241   * normal Profile Fields admin interface, we have the bp-xprofile-fullname-field-name
 242   * option. In many places throughout BuddyPress, the ID of the fullname field
 243   * is queried using this setting. However, this is no longer strictly necessary,
 244   * because we essentially hardcode (in the xprofile admin save routine, as well
 245   * as the xprofile schema definition) that the fullname field will be 1. The
 246   * presence of the non-hardcoded versions (and thus this bit of cache
 247   * invalidation) is thus for backward compatibility only.
 248   *
 249   * @since 2.0.0
 250   */
 251  function xprofile_clear_fullname_field_id_cache() {
 252      wp_cache_delete( 'fullname_field_id', 'bp_xprofile' );
 253  }
 254  add_action( 'update_option_bp-xprofile-fullname-field-name', 'xprofile_clear_fullname_field_id_cache' );
 255  
 256  /**
 257   * Clear a field's caches.
 258   *
 259   * @since 2.4.0
 260   *
 261   * @param int|BP_XProfile_Field $field A field ID or a field object.
 262   * @return bool False on failure.
 263   */
 264  function bp_xprofile_clear_field_cache( $field ) {
 265      if ( is_numeric( $field ) ) {
 266          $field_id = (int) $field;
 267      } elseif ( $field instanceof BP_XProfile_Field ) {
 268          $field_id = (int) $field->id;
 269      }
 270  
 271      if ( ! isset( $field_id ) ) {
 272          return false;
 273      }
 274  
 275      wp_cache_delete( $field_id, 'bp_xprofile_fields' );
 276      wp_cache_delete( $field_id, 'xprofile_meta' );
 277  }
 278  add_action( 'xprofile_field_after_save', 'bp_xprofile_clear_field_cache' );
 279  
 280  /**
 281   * Clear the field-name cache.
 282   *
 283   * @since 2.8.0
 284   */
 285  function bp_xprofile_reset_fields_by_name_cache_incrementor() {
 286      bp_core_reset_incrementor( 'bp_xprofile_fields_by_name' );
 287  }
 288  add_action( 'xprofile_field_before_save', 'bp_xprofile_reset_fields_by_name_cache_incrementor' );
 289  
 290  /**
 291   * Resets all incremented bp_xprofile_groups caches.
 292   *
 293   * @since 5.0.0
 294   */
 295  function bp_xprofile_reset_groups_cache_incrementor() {
 296      bp_core_reset_incrementor( 'bp_xprofile_groups' );
 297  }
 298  add_action( 'xprofile_group_after_delete', 'bp_xprofile_reset_groups_cache_incrementor' );
 299  add_action( 'xprofile_group_after_save', 'bp_xprofile_reset_groups_cache_incrementor' );
 300  add_action( 'xprofile_field_after_delete', 'bp_xprofile_reset_groups_cache_incrementor' );
 301  add_action( 'xprofile_field_after_save', 'bp_xprofile_reset_groups_cache_incrementor' );
 302  
 303  // List actions to clear super cached pages on, if super cache is installed.
 304  add_action( 'xprofile_updated_profile', 'bp_core_clear_cache' );


Generated: Thu Dec 12 01:01:36 2019 Cross-referenced by PHPXref 0.7.1