<!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][12765] trunk/src/bp-members: Administration: add support for multiple member types assignment</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 { white-space: pre-line; 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" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="http://buddypress.trac.wordpress.org/changeset/12765">12765</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"http://buddypress.trac.wordpress.org/changeset/12765","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>imath</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2020-10-24 12:20:39 +0000 (Sat, 24 Oct 2020)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Administration: add support for multiple member types assignment

Community Administrators can now use the multiple select box of the User's Extended Profile Member Type metabox to assign one or more Member Types to the user.

Data for the Member Type column of the WP Users List Table are now displaying a comma separated list of Member Types for Users being assigned to more than one Member Type (which was the original ticket's need).

The bulk removing or assigning member types functionalities have been improved to behave as follows :
- Bulk removing member types is removing all assigned member types.
- Bulk assigning a member type is replacing all assigned member types with the selected member type.

Props etatus, vapvarun

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

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcbpmembersadmincssadminrtlcss">trunk/src/bp-members/admin/css/admin-rtl.css</a></li>
<li><a href="#trunksrcbpmembersadmincssadmincss">trunk/src/bp-members/admin/css/admin.css</a></li>
<li><a href="#trunksrcbpmembersbpmembersfunctionsphp">trunk/src/bp-members/bp-members-functions.php</a></li>
<li><a href="#trunksrcbpmembersclassesclassbpmembersadminphp">trunk/src/bp-members/classes/class-bp-members-admin.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcbpmembersadmincssadminrtlcss"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/bp-members/admin/css/admin-rtl.css</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/bp-members/admin/css/admin-rtl.css      2020-10-24 04:53:08 UTC (rev 12764)
+++ trunk/src/bp-members/admin/css/admin-rtl.css        2020-10-24 12:20:39 UTC (rev 12765)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -21,6 +21,10 @@
</span><span class="cx" style="display: block; padding: 0 10px">        margin-bottom: 1em;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+div#community-profile-page #bp-members-profile-member-type {
+       width: 100%;
+}
+
</ins><span class="cx" style="display: block; padding: 0 10px"> #bp_members_admin_user_stats ul {
</span><span class="cx" style="display: block; padding: 0 10px">        margin-bottom: 0;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="trunksrcbpmembersadmincssadmincss"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/bp-members/admin/css/admin.css</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/bp-members/admin/css/admin.css  2020-10-24 04:53:08 UTC (rev 12764)
+++ trunk/src/bp-members/admin/css/admin.css    2020-10-24 12:20:39 UTC (rev 12765)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -21,6 +21,10 @@
</span><span class="cx" style="display: block; padding: 0 10px">        margin-bottom: 1em;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+div#community-profile-page #bp-members-profile-member-type {
+       width: 100%;
+}
+
</ins><span class="cx" style="display: block; padding: 0 10px"> #bp_members_admin_user_stats ul {
</span><span class="cx" style="display: block; padding: 0 10px">        margin-bottom: 0;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="trunksrcbpmembersbpmembersfunctionsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/bp-members/bp-members-functions.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/bp-members/bp-members-functions.php     2020-10-24 04:53:08 UTC (rev 12764)
+++ trunk/src/bp-members/bp-members-functions.php       2020-10-24 12:20:39 UTC (rev 12765)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2993,17 +2993,25 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * Set type for a member.
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @since 2.2.0
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @since 7.0.0 $member_type parameter also accepts an array of member type names.
</ins><span class="cx" style="display: block; padding: 0 10px">  *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param int    $user_id     ID of the user.
- * @param string $member_type Member type.
- * @param bool   $append      Optional. True to append this to existing types for user,
- *                            false to replace. Default: false.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param int          $user_id     ID of the user.
+ * @param string|array $member_type The member type name or an array of member type names.
+ * @param bool         $append      Optional. True to append this to existing types for user,
+ *                                  false to replace. Default: false.
</ins><span class="cx" style="display: block; padding: 0 10px">  * @return false|array $retval See {@see bp_set_object_terms()}.
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> function bp_set_member_type( $user_id, $member_type, $append = false ) {
</span><span class="cx" style="display: block; padding: 0 10px">        // Pass an empty $member_type to remove a user's type.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        if ( ! empty( $member_type ) && ! bp_get_member_type_object( $member_type ) ) {
-               return false;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ( ! empty( $member_type ) ) {
+               $member_types = (array) $member_type;
+               $valid_types  = array_filter( array_map( 'bp_get_member_type_object', $member_types ) );
+
+               if ( $valid_types ) {
+                       $member_type = wp_list_pluck( $valid_types, 'name' );
+               } else {
+                       return false;
+               }
</ins><span class="cx" style="display: block; padding: 0 10px">         }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        $retval = bp_set_object_terms( $user_id, $member_type, bp_get_member_type_tax_name(), $append );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3017,9 +3025,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">                 *
</span><span class="cx" style="display: block; padding: 0 10px">                 * @since 2.2.0
</span><span class="cx" style="display: block; padding: 0 10px">                 *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                 * @param int    $user_id     ID of the user whose member type has been updated.
-                * @param string $member_type Member type.
-                * @param bool   $append      Whether the type is being appended to existing types.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+          * @param int          $user_id     ID of the user whose member type has been updated.
+                * @param string|array $member_type The member type name or an array of member type names.
+                * @param bool         $append      Whether the type is being appended to existing types.
</ins><span class="cx" style="display: block; padding: 0 10px">                  */
</span><span class="cx" style="display: block; padding: 0 10px">                do_action( 'bp_set_member_type', $user_id, $member_type, $append );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3122,9 +3130,10 @@
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * @since 2.2.0
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * @param string $type    Member type.
-        * @param int    $user_id ID of the user.
-        * @param bool   $single  Whether to return a single type string, or an array.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  * @param string|array|bool $type    a single member type (if $single is true) or an array of member types
+        *                                   (if $single is false) or false on failure.
+        * @param int               $user_id ID of the user.
+        * @param bool              $single  Whether to return a single type string, or an array.
</ins><span class="cx" style="display: block; padding: 0 10px">          */
</span><span class="cx" style="display: block; padding: 0 10px">        return apply_filters( 'bp_get_member_type', $type, $user_id, $single );
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="trunksrcbpmembersclassesclassbpmembersadminphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/bp-members/classes/class-bp-members-admin.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/bp-members/classes/class-bp-members-admin.php   2020-10-24 04:53:08 UTC (rev 12764)
+++ trunk/src/bp-members/classes/class-bp-members-admin.php     2020-10-24 12:20:39 UTC (rev 12765)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1286,26 +1286,29 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        return;
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $types = bp_get_member_types( array(), 'objects' );
-               $current_type = bp_get_member_type( $user->ID );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $types        = bp_get_member_types( array(), 'objects' );
+               $current_type = bp_get_member_type( $user->ID, false );
</ins><span class="cx" style="display: block; padding: 0 10px">                 ?>
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                <label for="bp-members-profile-member-type" class="screen-reader-text"><?php
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         <label for="bp-members-profile-member-type" class="screen-reader-text">
+                       <?php
</ins><span class="cx" style="display: block; padding: 0 10px">                         /* translators: accessibility text */
</span><span class="cx" style="display: block; padding: 0 10px">                        esc_html_e( 'Select member type', 'buddypress' );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                ?></label>
-               <select name="bp-members-profile-member-type" id="bp-members-profile-member-type">
-                       <option value="" <?php selected( '', $current_type ); ?>><?php
-                               /* translators: no option picked in select box */
-                               esc_attr_e( '----', 'buddypress' );
-                       ?></option>
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 ?>
+               </label>
+               <select name="bp-members-profile-member-type[]" id="bp-members-profile-member-type" multiple="multiple">
+                       <option value="" <?php selected( ! $current_type ); ?>>
+                               <?php
+                                       /* translators: no option picked in select box */
+                                       esc_attr_e( '----', 'buddypress' );
+                               ?>
+                       </option>
</ins><span class="cx" style="display: block; padding: 0 10px">                         <?php foreach ( $types as $type ) : ?>
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                <option value="<?php echo esc_attr( $type->name ) ?>" <?php selected( $type->name, $current_type ) ?>><?php echo esc_html( $type->labels['singular_name'] ) ?></option>
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         <option value="<?php echo esc_attr( $type->name ) ?>" <?php selected( in_array( $type->name, (array) $current_type, true ) ) ?>><?php echo esc_html( $type->labels['singular_name'] ) ?></option>
</ins><span class="cx" style="display: block; padding: 0 10px">                         <?php endforeach; ?>
</span><span class="cx" style="display: block; padding: 0 10px">                </select>
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                <?php
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-
</del><span class="cx" style="display: block; padding: 0 10px">                 wp_nonce_field( 'bp-member-type-change-' . $user->ID, 'bp-member-type-nonce' );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1328,11 +1331,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        return;
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                // Member type string must either reference a valid member type, or be empty.
-               $member_type = stripslashes( $_POST['bp-members-profile-member-type'] );
-               if ( ! empty( $member_type ) && ! bp_get_member_type_object( $member_type ) ) {
-                       return;
-               }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // Member type [string] must either reference a valid member type, or be empty.
+               $member_type = wp_parse_slug_list( wp_unslash( $_POST['bp-members-profile-member-type'] ) );
+               $member_type = array_filter( $member_type );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                /*
</span><span class="cx" style="display: block; padding: 0 10px">                 * If an invalid member type is passed, someone's doing something
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2387,25 +2388,22 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        foreach ( (array) $_REQUEST['users'] as $user_id ) {
</span><span class="cx" style="display: block; padding: 0 10px">                                $user_id = (int) $user_id;
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                // Get the old member type to check against.
-                               $member_type = bp_get_member_type( $user_id );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         // Get the old member types to check against.
+                               $current_types = bp_get_member_type( $user_id, false );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                if ( 'remove_member_type' === $new_type ) {
-                                       // Remove the current member type, if there's one to remove.
-                                       if ( $member_type ) {
-                                               $removed = bp_remove_member_type( $user_id, $member_type );
-                                               if ( false === $removed || is_wp_error( $removed ) ) {
-                                                       $error = true;
-                                               }
-                                       }
-                               } else {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         if ( $current_types && 'remove_member_type' === $new_type ) {
+                                       $member_types = array();
+                               } elseif ( ! $current_types || 1 !== count( $current_types ) || $new_type !== $current_types[0] ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                                         // Set the new member type.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                        if ( $new_type !== $member_type ) {
-                                               $set = bp_set_member_type( $user_id, $new_type );
-                                               if ( false === $set || is_wp_error( $set ) ) {
-                                                       $error = true;
-                                               }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 $member_types = array( $new_type );
+                               }
+
+                               if ( isset( $member_types ) ) {
+                                       $set = bp_set_member_type( $user_id, $member_types );
+                                       if ( false === $set || is_wp_error( $set ) ) {
+                                               $error = true;
</ins><span class="cx" style="display: block; padding: 0 10px">                                         }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                        unset( $member_types );
</ins><span class="cx" style="display: block; padding: 0 10px">                                 }
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2477,12 +2475,26 @@
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                // Get the member type.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $type = bp_get_member_type( $user_id );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $member_type = bp_get_member_type( $user_id, false );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                // Output the
-               if ( $type_obj = bp_get_member_type_object( $type ) ) {
-                       $url = add_query_arg( array( 'bp-member-type' => urlencode( $type ) ) );
-                       $retval = '<a href="' . esc_url( $url ) . '">' . esc_html( $type_obj->labels['singular_name'] ) . '</a>';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // Build the Output.
+               if ( $member_type ) {
+                       $member_types = array_filter( array_map( 'bp_get_member_type_object', $member_type ) );
+                       if ( ! $member_types ) {
+                               return $retval;
+                       }
+
+                       $type_links = array();
+                       foreach ( $member_types as $type ) {
+                               $url          = add_query_arg( array( 'bp-member-type' => urlencode( $type->name ) ) );
+                               $type_links[] = sprintf(
+                                       '<a href="%1$s">%2$s</a>',
+                                       esc_url( $url ),
+                                       esc_html( $type->labels['singular_name'] )
+                               );
+                       }
+
+                       $retval = implode( ', ', $type_links );
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                return $retval;
</span></span></pre>
</div>
</div>

</body>
</html>