tripl3inf
8/27/2014 - 12:18 AM

PiklistHelper.php

<?php

/**
 * Adds useful validations and such to Piklist as well as
 * expands on it's capabilities
 *
 * Included Validations
 *    > youtube-urls
 *    > date-range
 *    > number
 *
 * @version 0.1.0
 */
class PiklistHelper {
  /**
   * Adds all the included validations and additiions to Piklist.
   * Make sure you call this after including the file: PiklistHelper::Initiate();
   */
  public static function Initiate() {
    if ( !class_exists('Piklist') ) return;

    // Validations
    add_filter('piklist_validation_rules', array(__CLASS__, 'add_youtube_validation'), 11);
    add_filter('piklist_validation_rules', array(__CLASS__, 'add_number_validation'), 11);
    add_filter('piklist_validation_rules', array(__CLASS__, 'add_date_range_validation'), 11);

    // Add constant type support to post types
    add_filter( 'piklist_add_part', array(__CLASS__, 'add_constant_support') );
  }



  /*****************************************************/
  /************* GENERAL PURPOSE FUNCTIONS *************/
  /*****************************************************/

  /**
   * Parses a piklist group into better format for iteration
   * @param array $array
   * @return array
   */
  public static function parse_array($array) {
    if ( empty($array) )
      return array();

    $keys = array_keys($array);
    if ( empty($keys) )
      return array();

    $results = $values = array();
    $count = count($array[$keys[0]]);
    for ($index = 0; $index < $count; $index++) {
      foreach($keys as $key_index => $key) {
        $value = ( isset($array[$key][$index]) ) ? $array[$key][$index] : null;
        if ( is_array($value) && !( isset($value[0][0]) || empty($value[0]) ) ) {
          $values[$key] = self::parse_array($value, true);
        } else
          $values[$key] = $value;
      }

      $results[] = $values;
    }

    return $results;
  }



  /*****************************************************/
  /************ VALIDATION FILTER FUNCTIONS ************/
  /*****************************************************/

  /**
   * Filter Only, not to be called directly.
   * Validation for youtube long and short forms
   */
  public static function add_youtube_validation() {
    $validation_rules = array(
      'youtube-url' => array(
        'rule' =>  '/^https?:\/\/(www.)?youtu(be\.com|\.be)\/(watch\?v=)?([[:alnum:]_-]+)$/',
        'message' => __('is not a valid youtube url')
      )
    );

    return $validation_rules;
  }

  /**
   * Filter Only, not to be called directly.
   * Validation for whether text is numeric or not
   */
  public static function add_number_validation() {
    $validation_rules = array(
      'number' => array(
        'callback'  => array(__CLASS__, 'check_number'),
      )
    );

    return $validation_rules;
  }

  /**
   * Filter Only, not to be called directly.
   * To be used for a group of two datepicker fields
   */
  public static function add_date_range_validation() {
    $validation_rules = array(
      'date-range' => array(
        'callback'  => array(__CLASS__, 'check_date_range'),
      )
    );

    return $validation_rules;
  }



  /*****************************************************/
  /*********** VALIDATION CALLBACK FUNCTIONS ***********/
  /*****************************************************/

  /**
   * Callback function for add_number_validation
   * @see PiklistHelper::add_number_validation
   */
  public static function check_number($value, $field, $options) {
    if ( !is_numeric($value) )
      return __('must be a number');

    if ( !empty($options) ) {
      foreach($options as $key => $option) {
        switch($option) {
          case 'integer':
            if ( (int) $value != $value )
              return __('must be an integer');
            break;

          case 'positive':
            if ( $value <= 0 )
              return __('must be a positive number');
            break;

          case 'negative':
            if ( $value >= 0 )
              return __('must be a negative number');
            break;
        }
      }
    }

    return true;
  }

  /**
   * Callback function for add_date_range_validation
   * @see PiklistHelper::add_date_range_validation
   */
  public static function check_date_range($values, $fields, $options) {
    if ( !is_array($values) || !isset($values[0]) )
      return __('is intended to be used for a group of datepickers');

    $dates = $values[0];

    if ( !isset($dates['end-date']) || !isset($dates['start-date']) )
      return __('requires start-date and end-date fields to work');

    if ( empty($dates['end-date']) )
      return __('must have an end date');

    if ( empty($dates['start-date']) )
      return __('must have a start date');

    $start_date = strtotime($dates['start-date']);
    $end_date = strtotime($dates['end-date']);

    if ( false === $start_date )
      return __('must have a valid date format for the start date');

    if ( false === $end_date )
      return __('must have a valid date format for the end date');

    if ( $start_date >= $end_date )
      return __('must have a start date before the end date');

    return true;
  }



  /*****************************************************/
  /************ PIKLIST EXTENSION FUNCTIONS ************/
  /*****************************************************/

  /**
   * Filter Only, not to be called directly.
   * Adds constant support to the post type. To use wrap
   * the name in square brackets. Example: [POST_CONSTANT]
   */
  public static function add_constant_support($data) {
    if ( empty($data['type']) )
      return $data;

    $match = array();
    if (preg_match( '/^\[(\w+)\]$/', $data['type'], $match )) {
      $data['type'] = constant($match[1]);
    }

    return $data;
  }
}

?>