Subversion Repositories web.creative

Rev

Blame | Last modification | View Log | Download

<?php namespace ProcessWire;

/**
 * ProcessWire Float Fieldtype
 *
 * Field that stores a floating point number. 
 *
 * For documentation about the fields used in this class, please see:  
 * /wire/core/Fieldtype.php
 * 
 * ProcessWire 3.x, Copyright 2020 by Ryan Cramer
 * https://processwire.com
 *
 */

class FieldtypeFloat extends Fieldtype {

  public static function getModuleInfo() {
    return array(
      'title' => __('Float', __FILE__),
      'summary' => __('Field that stores a floating point (decimal) number', __FILE__),
      'version' => 106,
      'permanent' => true, 
    );
  }

  /**
   * Get compatible Fieldtypes
   * 
   * @param Field $field
   * @return null|Fieldtypes
   * 
   */
  public function ___getCompatibleFieldtypes(Field $field) {
    $fieldtypes = parent::___getCompatibleFieldtypes($field); 
    foreach($fieldtypes as $type) {
      if(!$type instanceof FieldtypeInteger && !$type instanceof FieldtypeFloat && $type != 'FieldtypeText') {
        $fieldtypes->remove($type); 
      }
    }
    return $fieldtypes; 
  }

  /**
   * Get blank value
   * 
   * @param Page $page
   * @param Field $field
   * @return string
   * 
   */
  public function getBlankValue(Page $page, Field $field) {
    return ''; 
  }

  /**
   * Is given value considered empty to this Fieldtype?
   * 
   * @param Field $field
   * @param mixed $value
   * @return bool
   * 
   */
  public function isEmptyValue(Field $field, $value) {
    if($value === "0" || $value === 0 || $value === "0.0" || $value === 0.0) {
      // when zeroNotEmpty option is set, we don't count a literal "0" is being a blank value
      if($field->get('zeroNotEmpty')) return false;
    }
    return empty($value);
  }

  /**
   * Sanitize value
   * 
   * @param Page $page
   * @param Field $field
   * @param float|int|string $value
   * @return float|string
   * 
   */
  public function sanitizeValue(Page $page, Field $field, $value) {
    if(!strlen("$value")) return '';
    if(!is_float($value) && !is_int($value)) {
      $value = $this->wire()->sanitizer->float((string) $value, array('blankValue' => ''));
    }
    $precision = $field->get('precision');
    if($precision === null || $precision === '') {
      $value = (float) $value;
    } else {
      $value = round((float) $value, $precision);
    }
    return $value; 
  }

  /**
   * Get Inputfield for this Fieldtype
   * 
   * @param Page $page
   * @param Field $field
   * @return Inputfield
   * 
   */
  public function getInputfield(Page $page, Field $field) {
    /** @var InputfieldFloat $inputfield */
    $inputfield = $this->wire()->modules->get('InputfieldFloat'); 
    $inputfield->addClass($this->className());
    $inputfield->precision = $field->get('precision'); 
    return $inputfield; 
  }

  /**
   * Sleep value for DB storage
   * 
   * @param Page $page
   * @param Field $field
   * @param string|float|int
   * @return string
   * 
   */
  public function ___sleepValue(Page $page, Field $field, $value) {
    $precision = $field->get('precision'); 
    if(is_null($precision) || $precision === '') $precision = self::getPrecision($value); 
    if(!is_string($value)) $value = number_format($value, $precision, '.', '');
    return $value; 
  }

  /**
   * Get precision of given value 
   * 
   * @param string|float $value
   * @return int
   * 
   */
  public static function getPrecision($value) {
    $value = (float) $value;
    $remainder = ceil($value) - $value;
    $precision = strlen(ltrim($remainder, '0., '));
    if(!$precision) $precision = 1; 
    return $precision;
  }

  /**
   * Get DB schema for this Fieldtype
   * 
   * @param Field $field
   * @return array
   * 
   */
  public function getDatabaseSchema(Field $field) {
    $schema = parent::getDatabaseSchema($field); 
    $schema['data'] = 'float NOT NULL';
    return $schema;
  }

  /**
   * Get field configuration
   * 
   * @param Field $field
   * @return InputfieldWrapper
   * 
   */
  public function ___getConfigInputfields(Field $field) {
    $inputfields = parent::___getConfigInputfields($field);
    $precision = $field->get('precision');
    if($precision === null) $precision = 2; 

    /** @var InputfieldInteger $f */
    $f = $this->wire()->modules->get('InputfieldInteger');
    $f->attr('name', 'precision'); 
    $f->label = $this->_('Number of decimal digits to round to');
    if($precision !== '') $f->val($precision); 
    $f->attr('size', 8); 
    $inputfields->append($f);
  
    /** @var FieldtypeInteger $ft */
    $ft = $this->wire()->modules->get('FieldtypeInteger');
    // use the same 'zeroNotEmpty' setting as FieldtypeInteger
    $f = $ft->___getConfigInputfields($field)->getChildByName('zeroNotEmpty'); 
    if($f) $inputfields->add($f); 

    return $inputfields; 
  }

  /**
   * Convert float string with commas to float value
   * 
   * @param string $str
   * @return float|string
   * @deprecated Use $sanitizer->float($value, [ 'blankValue' = '' ]) instead
   * 
   */
  public static function strToFloat($str) { 
    return wire('sanitizer')->float($str, array('blankValue' => ''));
  }
  
  /*
  public function formatValue(Page $page, Field $field, $value) {
    // @todo add support for number_format options
    return $value;  
  }
  */

  /*
  public function getMatchQuery($query, $table, $subfield, $operator, $value) {
    if(!is_int($value) && !is_float($value)) {
      $value = self::strToFloat((string) $value);
    }
    return parent::getMatchQuery($query, $table, $subfield, $operator, $value); 
  }
  */


}