[ Index ]

PHP Cross Reference of BuddyPress

title

Body

[close]

/src/bp-xprofile/classes/ -> class-bp-xprofile-field-type.php (source)

   1  <?php
   2  /**
   3   * BuddyPress XProfile Classes.
   4   *
   5   * @package BuddyPress
   6   * @subpackage XProfileClasses
   7   * @since 2.0.0
   8   */
   9  
  10  // Exit if accessed directly.
  11  defined( 'ABSPATH' ) || exit;
  12  
  13  /**
  14   * Represents a type of XProfile field and holds meta information about the type of value that it accepts.
  15   *
  16   * @since 2.0.0
  17   */
  18  abstract class BP_XProfile_Field_Type {
  19  
  20      /**
  21       * Validation regex rules for field type.
  22       *
  23       * @since 2.0.0
  24       * @var array Field type validation regexes.
  25       */
  26      protected $validation_regex = array();
  27  
  28      /**
  29       * Whitelisted values for field type.
  30       *
  31       * @since 2.0.0
  32       * @var array Field type whitelisted values.
  33       */
  34      protected $validation_whitelist = array();
  35  
  36      /**
  37       * Name for field type.
  38       *
  39       * @since 2.0.0
  40       * @var string The name of this field type.
  41       */
  42      public $name = '';
  43  
  44      /**
  45       * The name of the category that this field type should be grouped with. Used on the [Users > Profile Fields] screen in wp-admin.
  46       *
  47       * @since 2.0.0
  48       * @var string
  49       */
  50      public $category = '';
  51  
  52      /**
  53       * If allowed to store null/empty values.
  54       *
  55       * @since 2.0.0
  56       * @var bool If this is set, allow BP to store null/empty values for this field type.
  57       */
  58      public $accepts_null_value = false;
  59  
  60      /**
  61       * If this is set, BP will set this field type's validation whitelist from the field's options (e.g checkbox, selectbox).
  62       *
  63       * @since 2.0.0
  64       * @var bool Does this field support options? e.g. selectbox, radio buttons, etc.
  65       */
  66      public $supports_options = false;
  67  
  68      /**
  69       * If allowed to support multiple options as default.
  70       *
  71       * @since 2.0.0
  72       * @var bool Does this field type support multiple options being set as default values? e.g. multiselectbox, checkbox.
  73       */
  74      public $supports_multiple_defaults = false;
  75  
  76      /**
  77       * If the field type supports rich text by default.
  78       *
  79       * @since 2.4.0
  80       * @var bool
  81       */
  82      public $supports_richtext = false;
  83  
  84      /**
  85       * If the field type has a type-specific settings section on the Edit Field panel.
  86       *
  87       * @since 2.7.0
  88       * @var bool|null Boolean if set explicitly by the type object, otherwise null.
  89       */
  90      protected $do_settings_section = null;
  91  
  92      /**
  93       * If object is created by an BP_XProfile_Field object.
  94       *
  95       * @since 2.0.0
  96       * @var BP_XProfile_Field If this object is created by instantiating a {@link BP_XProfile_Field},
  97       *                        this is a reference back to that object.
  98       */
  99      public $field_obj = null;
 100  
 101      /**
 102       * Constructor.
 103       *
 104       * @since 2.0.0
 105       */
 106  	public function __construct() {
 107  
 108          /**
 109           * Fires inside __construct() method for BP_XProfile_Field_Type class.
 110           *
 111           * @since 2.0.0
 112           *
 113           * @param BP_XProfile_Field_Type $this Current instance of
 114           *                                     the field type class.
 115           */
 116          do_action( 'bp_xprofile_field_type', $this );
 117      }
 118  
 119      /**
 120       * Set a regex that profile data will be asserted against.
 121       *
 122       * You can call this method multiple times to set multiple formats. When validation is performed,
 123       * it's successful as long as the new value matches any one of the registered formats.
 124       *
 125       * @since 2.0.0
 126       *
 127       * @param string $format         Regex string.
 128       * @param string $replace_format Optional; if 'replace', replaces the format instead of adding to it.
 129       *                               Defaults to 'add'.
 130       * @return BP_XProfile_Field_Type
 131       */
 132  	public function set_format( $format, $replace_format = 'add' ) {
 133  
 134          /**
 135           * Filters the regex format for the field type.
 136           *
 137           * @since 2.0.0
 138           *
 139           * @param string                 $format         Regex string.
 140           * @param string                 $replace_format Optional replace format If "replace", replaces the
 141           *                                               format instead of adding to it. Defaults to "add".
 142           * @param BP_XProfile_Field_Type $this           Current instance of the BP_XProfile_Field_Type class.
 143           */
 144          $format = apply_filters( 'bp_xprofile_field_type_set_format', $format, $replace_format, $this );
 145  
 146          if ( 'add' === $replace_format ) {
 147              $this->validation_regex[] = $format;
 148          } elseif ( 'replace' === $replace_format ) {
 149              $this->validation_regex = array( $format );
 150          }
 151  
 152          return $this;
 153      }
 154  
 155      /**
 156       * Add a value to this type's whitelist that profile data will be asserted against.
 157       *
 158       * You can call this method multiple times to set multiple formats. When validation is performed,
 159       * it's successful as long as the new value matches any one of the registered formats.
 160       *
 161       * @since 2.0.0
 162       *
 163       * @param string|array $values Whitelisted values.
 164       * @return BP_XProfile_Field_Type
 165       */
 166  	public function set_whitelist_values( $values ) {
 167          foreach ( (array) $values as $value ) {
 168  
 169              /**
 170               * Filters values for field type's whitelist that profile data will be asserted against.
 171               *
 172               * @since 2.0.0
 173               *
 174               * @param string                 $value  Field value.
 175               * @param array                  $values Original array of values.
 176               * @param BP_XProfile_Field_Type $this   Current instance of the BP_XProfile_Field_Type class.
 177               */
 178              $this->validation_whitelist[] = apply_filters( 'bp_xprofile_field_type_set_whitelist_values', $value, $values, $this );
 179          }
 180  
 181          return $this;
 182      }
 183  
 184      /**
 185       * Check the given string against the registered formats for this field type.
 186       *
 187       * This method doesn't support chaining.
 188       *
 189       * @since 2.0.0
 190       *
 191       * @param string|array $values Value to check against the registered formats.
 192       * @return bool True if the value validates
 193       */
 194  	public function is_valid( $values ) {
 195          $validated = false;
 196  
 197          // Some types of field (e.g. multi-selectbox) may have multiple values to check.
 198          foreach ( (array) $values as $value ) {
 199  
 200              // Validate the $value against the type's accepted format(s).
 201              foreach ( $this->validation_regex as $format ) {
 202                  if ( 1 === preg_match( $format, $value ) ) {
 203                      $validated = true;
 204                      continue;
 205  
 206                  } else {
 207                      $validated = false;
 208                  }
 209              }
 210          }
 211  
 212          // Handle field types with accepts_null_value set if $values is an empty array.
 213          if ( ( false === $validated ) && is_array( $values ) && empty( $values ) && $this->accepts_null_value ) {
 214              $validated = true;
 215          }
 216  
 217          // If there's a whitelist set, make sure that each value is a whitelisted value.
 218          if ( ( true === $validated ) && ! empty( $values ) && ! empty( $this->validation_whitelist ) ) {
 219              foreach ( (array) $values as $value ) {
 220                  if ( ! in_array( $value, $this->validation_whitelist, true ) ) {
 221                      $validated = false;
 222                      break;
 223                  }
 224              }
 225          }
 226  
 227          /**
 228           * Filters whether or not field type is a valid format.
 229           *
 230           * @since 2.0.0
 231           *
 232           * @param bool                   $validated Whether or not the field type is valid.
 233           * @param string|array           $values    Value to check against the registered formats.
 234           * @param BP_XProfile_Field_Type $this      Current instance of the BP_XProfile_Field_Type class.
 235           */
 236          return (bool) apply_filters( 'bp_xprofile_field_type_is_valid', $validated, $values, $this );
 237      }
 238  
 239      /**
 240       * Check whether the current field type should have a settings ("options") section on the Edit Field panel.
 241       *
 242       * Falls back on `supports_options` if no value is set by the field type.
 243       *
 244       * @since 2.7.0
 245       *
 246       * @return bool
 247       */
 248  	public function do_settings_section() {
 249          if ( null === $this->do_settings_section ) {
 250              $this->do_settings_section = $this->supports_options;
 251          }
 252  
 253          return (bool) $this->do_settings_section;
 254      }
 255  
 256      /**
 257       * Output the edit field HTML for this field type.
 258       *
 259       * Must be used inside the {@link bp_profile_fields()} template loop.
 260       *
 261       * @since 2.0.0
 262       *
 263       * @param array $raw_properties Optional key/value array of permitted attributes that you want to add.
 264       * @return void
 265       */
 266      abstract public function edit_field_html( array $raw_properties = array() );
 267  
 268      /**
 269       * Output HTML for this field type on the wp-admin Profile Fields screen.
 270       *
 271       * Must be used inside the {@link bp_profile_fields()} template loop.
 272       *
 273       * @since 2.0.0
 274       *
 275       * @param array $raw_properties Optional key/value array of permitted attributes that you want to add.
 276       * @return void
 277       */
 278      abstract public function admin_field_html( array $raw_properties = array() );
 279  
 280      /**
 281       * Output the edit field options HTML for this field type.
 282       *
 283       * BuddyPress considers a field's "options" to be, for example, the items in a selectbox.
 284       * These are stored separately in the database, and their templating is handled separately.
 285       * Populate this method in a child class if it's required. Otherwise, you can leave it out.
 286       *
 287       * This templating is separate from {@link BP_XProfile_Field_Type::edit_field_html()} because
 288       * it's also used in the wp-admin screens when creating new fields, and for backwards compatibility.
 289       *
 290       * Must be used inside the {@link bp_profile_fields()} template loop.
 291       *
 292       * @since 2.0.0
 293       *
 294       * @param array $args Optional. The arguments passed to {@link bp_the_profile_field_options()}.
 295       */
 296  	public function edit_field_options_html( array $args = array() ) {}
 297  
 298      /**
 299       * Output HTML for this field type's children options on the wp-admin Profile Fields "Add Field" and "Edit Field" screens.
 300       *
 301       * You don't need to implement this method for all field types. It's used in core by the
 302       * selectbox, multi selectbox, checkbox, and radio button fields, to allow the admin to
 303       * enter the child option values (e.g. the choices in a select box).
 304       *
 305       * Must be used inside the {@link bp_profile_fields()} template loop.
 306       *
 307       * @since 2.0.0
 308       *
 309       * @param BP_XProfile_Field $current_field The current profile field on the add/edit screen.
 310       * @param string            $control_type  Optional. HTML input type used to render the current
 311       *                          field's child options.
 312       */
 313  	public function admin_new_field_html( BP_XProfile_Field $current_field, $control_type = '' ) {
 314          $type = array_search( get_class( $this ), bp_xprofile_get_field_types() );
 315          if ( false === $type ) {
 316              return;
 317          }
 318  
 319          $class            = $current_field->type != $type ? 'display: none;' : '';
 320          $current_type_obj = bp_xprofile_create_field_type( $type );
 321          ?>
 322  
 323          <div id="<?php echo esc_attr( $type ); ?>" class="postbox bp-options-box" style="<?php echo esc_attr( $class ); ?> margin-top: 15px;">
 324              <h3><?php esc_html_e( 'Please enter options for this Field:', 'buddypress' ); ?></h3>
 325              <div class="inside" aria-live="polite" aria-atomic="true" aria-relevant="all">
 326                  <p>
 327                      <label for="sort_order_<?php echo esc_attr( $type ); ?>"><?php esc_html_e( 'Sort Order:', 'buddypress' ); ?></label>
 328                      <select name="sort_order_<?php echo esc_attr( $type ); ?>" id="sort_order_<?php echo esc_attr( $type ); ?>" >
 329                          <option value="custom" <?php selected( 'custom', $current_field->order_by ); ?>><?php esc_html_e( 'Custom',     'buddypress' ); ?></option>
 330                          <option value="asc"    <?php selected( 'asc',    $current_field->order_by ); ?>><?php esc_html_e( 'Ascending',  'buddypress' ); ?></option>
 331                          <option value="desc"   <?php selected( 'desc',   $current_field->order_by ); ?>><?php esc_html_e( 'Descending', 'buddypress' ); ?></option>
 332                      </select>
 333                  </p>
 334  
 335                  <?php
 336  
 337                  // Does option have children?
 338                  $options = $current_field->get_children( true );
 339  
 340                  // If no children options exists for this field, check in $_POST
 341                  // for a submitted form (e.g. on the "new field" screen).
 342                  if ( empty( $options ) ) {
 343  
 344                      $options = array();
 345                      $i       = 1;
 346  
 347                      while ( isset( $_POST[$type . '_option'][$i] ) ) {
 348  
 349                          // Multiselectbox and checkboxes support MULTIPLE default options; all other core types support only ONE.
 350                          if ( $current_type_obj->supports_options && ! $current_type_obj->supports_multiple_defaults && isset( $_POST["isDefault_{$type}_option"][$i] ) && (int) $_POST["isDefault_{$type}_option"] === $i ) {
 351                              $is_default_option = true;
 352                          } elseif ( isset( $_POST["isDefault_{$type}_option"][$i] ) ) {
 353                              $is_default_option = (bool) $_POST["isDefault_{$type}_option"][$i];
 354                          } else {
 355                              $is_default_option = false;
 356                          }
 357  
 358                          // Grab the values from $_POST to use as the form's options.
 359                          $options[] = (object) array(
 360                              'id'                => -1,
 361                              'is_default_option' => $is_default_option,
 362                              'name'              => sanitize_text_field( stripslashes( $_POST[$type . '_option'][$i] ) ),
 363                          );
 364  
 365                          ++$i;
 366                      }
 367  
 368                      // If there are still no children options set, this must be the "new field" screen, so add one new/empty option.
 369                      if ( empty( $options ) ) {
 370                          $options[] = (object) array(
 371                              'id'                => -1,
 372                              'is_default_option' => false,
 373                              'name'              => '',
 374                          );
 375                      }
 376                  }
 377  
 378                  // Render the markup for the children options.
 379                  if ( ! empty( $options ) ) {
 380                      $default_name = '';
 381  
 382                      for ( $i = 0, $count = count( $options ); $i < $count; ++$i ) :
 383                          $j = $i + 1;
 384  
 385                          // Multiselectbox and checkboxes support MULTIPLE default options; all other core types support only ONE.
 386                          if ( $current_type_obj->supports_options && $current_type_obj->supports_multiple_defaults ) {
 387                              $default_name = '[' . $j . ']';
 388                          }
 389                          ?>
 390  
 391                          <div id="<?php echo esc_attr( "{$type}_div{$j}" ); ?>" class="bp-option sortable">
 392                              <span class="bp-option-icon grabber"></span>
 393                              <label for="<?php echo esc_attr( "{$type}_option{$j}" ); ?>" class="screen-reader-text"><?php
 394                                  /* translators: accessibility text */
 395                                  esc_html_e( 'Add an option', 'buddypress' );
 396                              ?></label>
 397                              <input type="text" name="<?php echo esc_attr( "{$type}_option[{$j}]" ); ?>" id="<?php echo esc_attr( "{$type}_option{$j}" ); ?>" value="<?php echo esc_attr( stripslashes( $options[$i]->name ) ); ?>" />
 398                              <label for="<?php echo esc_attr( "{$type}_option{$default_name}" ); ?>">
 399                                  <input type="<?php echo esc_attr( $control_type ); ?>" id="<?php echo esc_attr( "{$type}_option{$default_name}" ); ?>" name="<?php echo esc_attr( "isDefault_{$type}_option{$default_name}" ); ?>" <?php checked( $options[$i]->is_default_option, true ); ?> value="<?php echo esc_attr( $j ); ?>" />
 400                                  <?php _e( 'Default Value', 'buddypress' ); ?>
 401                              </label>
 402  
 403                              <?php if ( 1 !== $j ) : ?>
 404                                  <div class ="delete-button">
 405                                      <a href='javascript:hide("<?php echo esc_attr( "{$type}_div{$j}" ); ?>")' class="delete"><?php esc_html_e( 'Delete', 'buddypress' ); ?></a>
 406                                  </div>
 407                              <?php endif; ?>
 408  
 409                          </div>
 410  
 411                      <?php endfor; ?>
 412  
 413                      <input type="hidden" name="<?php echo esc_attr( "{$type}_option_number" ); ?>" id="<?php echo esc_attr( "{$type}_option_number" ); ?>" value="<?php echo esc_attr( $j + 1 ); ?>" />
 414                  <?php } ?>
 415  
 416                  <div id="<?php echo esc_attr( "{$type}_more" ); ?>"></div>
 417                  <p><a href="javascript:add_option('<?php echo esc_js( $type ); ?>')"><?php esc_html_e( 'Add Another Option', 'buddypress' ); ?></a></p>
 418  
 419                  <?php
 420  
 421                  /**
 422                   * Fires at the end of the new field additional settings area.
 423                   *
 424                   * @since 2.3.0
 425                   *
 426                   * @param BP_XProfile_Field $current_field Current field being rendered.
 427                   */
 428                  do_action( 'bp_xprofile_admin_new_field_additional_settings', $current_field ) ?>
 429              </div>
 430          </div>
 431  
 432          <?php
 433      }
 434  
 435      /**
 436       * Allow field types to modify submitted values before they are validated.
 437       *
 438       * In some cases, it may be appropriate for a field type to catch
 439       * submitted values and modify them before they are passed to the
 440       * is_valid() method. For example, URL validation requires the
 441       * 'http://' scheme (so that the value saved in the database is always
 442       * a fully-formed URL), but in order to allow users to enter a URL
 443       * without this scheme, BP_XProfile_Field_Type_URL prepends 'http://'
 444       * when it's not present.
 445       *
 446       * By default, this is a pass-through method that does nothing. Only
 447       * override in your own field type if you need this kind of pre-
 448       * validation filtering.
 449       *
 450       * @since 2.1.0
 451       * @since 2.4.0 Added the `$field_id` parameter.
 452       *
 453       * @param mixed      $field_value Submitted field value.
 454       * @param string|int $field_id    Optional. ID of the field.
 455       * @return mixed
 456       */
 457  	public static function pre_validate_filter( $field_value, $field_id = '' ) {
 458          return $field_value;
 459      }
 460  
 461      /**
 462       * Allow field types to modify the appearance of their values.
 463       *
 464       * By default, this is a pass-through method that does nothing. Only
 465       * override in your own field type if you need to provide custom
 466       * filtering for output values.
 467       *
 468       * @since 2.1.0
 469       * @since 2.4.0 Added `$field_id` parameter.
 470       *
 471       * @param mixed      $field_value Field value.
 472       * @param string|int $field_id    ID of the field.
 473       * @return mixed
 474       */
 475  	public static function display_filter( $field_value, $field_id = '' ) {
 476          return $field_value;
 477      }
 478  
 479      /**
 480       * Save miscellaneous settings related to this field type.
 481       *
 482       * Override in a specific field type if it requires an admin save routine.
 483       *
 484       * @since 2.7.0
 485       *
 486       * @param int   $field_id Field ID.
 487       * @param array $settings Array of settings.
 488       */
 489  	public function admin_save_settings( $field_id, $settings ) {}
 490  
 491      /** Protected *************************************************************/
 492  
 493      /**
 494       * Get a sanitised and escaped string of the edit field's HTML elements and attributes.
 495       *
 496       * Must be used inside the {@link bp_profile_fields()} template loop.
 497       * This method was intended to be static but couldn't be because php.net/lsb/ requires PHP >= 5.3.
 498       *
 499       * @since 2.0.0
 500       *
 501       * @param array $properties Optional key/value array of attributes for this edit field.
 502       * @return string
 503       */
 504  	protected function get_edit_field_html_elements( array $properties = array() ) {
 505  
 506          $r = bp_parse_args( $properties, array(
 507              'id'   => bp_get_the_profile_field_input_name(),
 508              'name' => bp_get_the_profile_field_input_name(),
 509          ) );
 510  
 511          if ( bp_get_the_profile_field_is_required() ) {
 512              $r['aria-required'] = 'true';
 513  
 514              // Moderators can bypass field requirements.
 515              if ( ! bp_current_user_can( 'bp_moderate' ) ) {
 516                  $r[] = 'required';
 517              }
 518          }
 519  
 520          /**
 521           * Filters the edit html elements and attributes.
 522           *
 523           * @since 2.0.0
 524           *
 525           * @param array  $r     Array of parsed arguments.
 526           * @param string $value Class name for the current class instance.
 527           */
 528          $r = (array) apply_filters( 'bp_xprofile_field_edit_html_elements', $r, get_class( $this ) );
 529  
 530          return bp_get_form_field_attributes( sanitize_key( bp_get_the_profile_field_name() ), $r );
 531      }
 532  }


Generated: Mon Nov 11 01:01:38 2019 Cross-referenced by PHPXref 0.7.1