<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[BuddyPress][7812] trunk: Introduce bp_xprofile_fullname_field_id() and use in query building throughout BP</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://buddypress.trac.wordpress.org/changeset/7812">7812</a></dd>
<dt>Author</dt> <dd>boonebgorges</dd>
<dt>Date</dt> <dd>2014-02-06 19:38:35 +0000 (Thu, 06 Feb 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Introduce bp_xprofile_fullname_field_id() and use in query building throughout BP

There are many places throughout BuddyPress where it's necessary to query for
user fullnames. When XProfile is active, part of this process involves
determining the ID of the fullname field. Historically, this has been done by
querying for the ID of a field corresponding to the 'name' bp_xprofile_fullname_field_name().
Creating a standalone function for this allows us to centralize persistent
caching for the field ID.

As a side note, the fact that we do this query at all is a little farcical.
The fullname field is essentially necessarily tied to field <a href="http://buddypress.trac.wordpress.org/ticket/1">#1</a> (due to some
hardcoding in the xprofile schema definition as well as bp-xprofile-admin.php).
We rely on the Name setting only for historical reasons, which probably didn't
even make all that much sense at the time. At some point, a serious review
should be done, and references to the fullname field id standardized (either
all hardcoded, or all not hardcoded).

See <a href="http://buddypress.trac.wordpress.org/ticket/5362">#5362</a></pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkbpcorebpcoreclassesphp">trunk/bp-core/bp-core-classes.php</a></li>
<li><a href="#trunkbpxprofilebpxprofilecachephp">trunk/bp-xprofile/bp-xprofile-cache.php</a></li>
<li><a href="#trunkbpxprofilebpxprofileclassesphp">trunk/bp-xprofile/bp-xprofile-classes.php</a></li>
<li><a href="#trunkbpxprofilebpxprofilefiltersphp">trunk/bp-xprofile/bp-xprofile-filters.php</a></li>
<li><a href="#trunkbpxprofilebpxprofilefunctionsphp">trunk/bp-xprofile/bp-xprofile-functions.php</a></li>
<li><a href="#trunkteststestcasesxprofilefunctionsphp">trunk/tests/testcases/xprofile/functions.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkbpcorebpcoreclassesphp"></a>
<div class="modfile"><h4>Modified: trunk/bp-core/bp-core-classes.php (7811 => 7812)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/bp-core/bp-core-classes.php        2014-02-06 19:35:15 UTC (rev 7811)
+++ trunk/bp-core/bp-core-classes.php   2014-02-06 19:38:35 UTC (rev 7812)
</span><span class="lines">@@ -301,11 +301,9 @@
</span><span class="cx">                          // When profile sync is disabled, alphabetical sorts must happen against
</span><span class="cx">                          // the xprofile table
</span><span class="cx">                          } else {
</span><del>-                                       $fullname_field_id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->profile->table_name_fields} WHERE name = %s", bp_xprofile_fullname_field_name() ) );
-
</del><span class="cx">                                   $this->uid_name = 'user_id';
</span><span class="cx">                                  $sql['select']  = "SELECT u.{$this->uid_name} as id FROM {$bp->profile->table_name_data} u";
</span><del>-                                       $sql['where'][] = "u.field_id = {$fullname_field_id}";
</del><ins>+                                        $sql['where'][] = $wpdb->prepare( "u.field_id = %d", bp_xprofile_fullname_field_id() );
</ins><span class="cx">                                   $sql['orderby'] = "ORDER BY u.value";
</span><span class="cx">                                  $sql['order']   = "ASC";
</span><span class="cx">                          }
</span></span></pre></div>
<a id="trunkbpxprofilebpxprofilecachephp"></a>
<div class="modfile"><h4>Modified: trunk/bp-xprofile/bp-xprofile-cache.php (7811 => 7812)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/bp-xprofile/bp-xprofile-cache.php  2014-02-06 19:35:15 UTC (rev 7811)
+++ trunk/bp-xprofile/bp-xprofile-cache.php     2014-02-06 19:38:35 UTC (rev 7812)
</span><span class="lines">@@ -58,5 +58,25 @@
</span><span class="cx"> add_action( 'xprofile_data_after_save', 'xprofile_clear_profiledata_object_cache' );
</span><span class="cx"> add_action( 'xprofile_data_after_delete', 'xprofile_clear_profiledata_object_cache' );
</span><span class="cx"> 
</span><ins>+/**
+ * Clear fullname_field_id cache when bp-xprofile-fullname-field-name is updated.
+ *
+ * Note for future developers: Dating from an early version of BuddyPress where
+ * the fullname field (field #1) did not have a title that was editable in the
+ * normal Profile Fields admin interface, we have the bp-xprofile-fullname-field-name
+ * option. In many places throughout BuddyPress, the ID of the fullname field
+ * is queried using this setting. However, this is no longer strictly necessary,
+ * because we essentially hardcode (in the xprofile admin save routine, as well
+ * as the xprofile schema definition) that the fullname field will be 1. The
+ * presence of the non-hardcoded versions (and thus this bit of cache
+ * invalidation) is thus for backward compatibility only.
+ *
+ * @since BuddyPress (2.0.0)
+ */
+function xprofile_clear_fullname_field_id_cache() {
+       wp_cache_delete( 'fullname_field_id', 'bp_xprofile' );
+}
+add_action( 'update_option_bp-xprofile-fullname-field-name', 'xprofile_clear_fullname_field_id_cache' );
+
</ins><span class="cx"> // List actions to clear super cached pages on, if super cache is installed
</span><span class="cx"> add_action( 'xprofile_updated_profile', 'bp_core_clear_cache' );
</span></span></pre></div>
<a id="trunkbpxprofilebpxprofileclassesphp"></a>
<div class="modfile"><h4>Modified: trunk/bp-xprofile/bp-xprofile-classes.php (7811 => 7812)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/bp-xprofile/bp-xprofile-classes.php        2014-02-06 19:35:15 UTC (rev 7811)
+++ trunk/bp-xprofile/bp-xprofile-classes.php   2014-02-06 19:38:35 UTC (rev 7812)
</span><span class="lines">@@ -1491,8 +1491,7 @@
</span><span class="cx">          if ( empty( $user_id ) )
</span><span class="cx">                  $user_id = bp_displayed_user_id();
</span><span class="cx"> 
</span><del>-               $field_name = bp_xprofile_fullname_field_name();
-               $data       = xprofile_get_field_data( $field_name, $user_id );
</del><ins>+                $data = xprofile_get_field_data( bp_xprofile_fullname_field_id(), $user_id );
</ins><span class="cx"> 
</span><span class="cx">          return $data[$field_name];
</span><span class="cx">  }
</span></span></pre></div>
<a id="trunkbpxprofilebpxprofilefiltersphp"></a>
<div class="modfile"><h4>Modified: trunk/bp-xprofile/bp-xprofile-filters.php (7811 => 7812)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/bp-xprofile/bp-xprofile-filters.php        2014-02-06 19:35:15 UTC (rev 7811)
+++ trunk/bp-xprofile/bp-xprofile-filters.php   2014-02-06 19:38:35 UTC (rev 7812)
</span><span class="lines">@@ -251,8 +251,7 @@
</span><span class="cx">          return;
</span><span class="cx">  }
</span><span class="cx"> 
</span><del>-       $fullname_field_id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->profile->table_name_fields} WHERE name = %s", bp_xprofile_fullname_field_name() ) );
-       $user_id_names     = BP_XProfile_ProfileData::get_value_byid( $fullname_field_id, $user_query->user_ids );
</del><ins>+        $user_id_names = BP_XProfile_ProfileData::get_value_byid( bp_xprofile_fullname_field_id(), $user_query->user_ids );
</ins><span class="cx"> 
</span><span class="cx">  // Loop through names and override each user's fullname
</span><span class="cx">  foreach ( $user_id_names as $user ) {
</span></span></pre></div>
<a id="trunkbpxprofilebpxprofilefunctionsphp"></a>
<div class="modfile"><h4>Modified: trunk/bp-xprofile/bp-xprofile-functions.php (7811 => 7812)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/bp-xprofile/bp-xprofile-functions.php      2014-02-06 19:35:15 UTC (rev 7811)
+++ trunk/bp-xprofile/bp-xprofile-functions.php 2014-02-06 19:38:35 UTC (rev 7812)
</span><span class="lines">@@ -437,7 +437,7 @@
</span><span class="cx">  if ( empty( $user_id ) )
</span><span class="cx">          return false;
</span><span class="cx"> 
</span><del>-       $fullname = xprofile_get_field_data( bp_xprofile_fullname_field_name(), $user_id );
</del><ins>+        $fullname = xprofile_get_field_data( bp_xprofile_fullname_field_id(), $user_id );
</ins><span class="cx">   $space    = strpos( $fullname, ' ' );
</span><span class="cx"> 
</span><span class="cx">  if ( false === $space ) {
</span><span class="lines">@@ -473,7 +473,7 @@
</span><span class="cx">  if ( ( !empty( $bp->site_options['bp-disable-profile-sync'] ) && (int) $bp->site_options['bp-disable-profile-sync'] ) || !$update || $errors->get_error_codes() )
</span><span class="cx">          return;
</span><span class="cx"> 
</span><del>-       xprofile_set_field_data( bp_xprofile_fullname_field_name(), $user->ID, $user->display_name );
</del><ins>+        xprofile_set_field_data( bp_xprofile_fullname_field_id(), $user->ID, $user->display_name );
</ins><span class="cx"> }
</span><span class="cx"> add_action( 'user_profile_update_errors', 'xprofile_sync_bp_profile', 10, 3 );
</span><span class="cx"> 
</span><span class="lines">@@ -625,6 +625,28 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> /**
</span><ins>+ * Return the field ID for the Full Name xprofile field.
+ *
+ * @since BuddyPress (2.0.0)
+ *
+ * @return int Field ID.
+ */
+function bp_xprofile_fullname_field_id() {
+       $id = wp_cache_get( 'fullname_field_id', 'bp_xprofile' );
+
+       if ( false === $id ) {
+               global $wpdb;
+
+               $bp = buddypress();
+               $id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->profile->table_name_fields} WHERE name = %s", bp_xprofile_fullname_field_name() ) );
+
+               wp_cache_set( 'fullname_field_id', $id, 'bp_xprofile' );
+       }
+
+       return absint( $id );
+}
+
+/**
</ins><span class="cx">  * Return the field name for the Full Name xprofile field
</span><span class="cx">  *
</span><span class="cx">  * @package BuddyPress
</span></span></pre></div>
<a id="trunkteststestcasesxprofilefunctionsphp"></a>
<div class="modfile"><h4>Modified: trunk/tests/testcases/xprofile/functions.php (7811 => 7812)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/tests/testcases/xprofile/functions.php     2014-02-06 19:35:15 UTC (rev 7811)
+++ trunk/tests/testcases/xprofile/functions.php        2014-02-06 19:38:35 UTC (rev 7812)
</span><span class="lines">@@ -80,4 +80,16 @@
</span><span class="cx">          bp_xprofile_update_meta( $f->id, 'field', 'linebreak_field', $meta_value );
</span><span class="cx">          $this->assertEquals( $meta_value, bp_xprofile_get_meta( $f->id, 'field', 'linebreak_field' ) );
</span><span class="cx">  }
</span><ins>+
+       /**
+        * @group bp_xprofile_fullname_field_id
+        */
+       public function test_bp_xprofile_fullname_field_id_invalidation() {
+               // Prime the cache
+               $id = bp_xprofile_fullname_field_id();
+
+               bp_update_option( 'bp-xprofile-fullname-field-name', 'foo' );
+
+               $this->assertFalse( wp_cache_get( 'fullname_field_id', 'bp_xprofile' ) );
+       }
</ins><span class="cx"> }
</span></span></pre>
</div>
</div>

</body>
</html>