Subversion Repositories web.creative

Rev

Blame | Last modification | View Log | Download

<?php namespace ProcessWire;

/**
 * An Inputfield for handling "textarea" form inputs
 * 
 * @property int $rows Number of rows for textarea (default=5)
 * @property int $contentType Content type, applicable when used with FieldtypeTextarea. See FieldtypeTextarea contentType constants (default=contentTypeUnknown)
 *
 */
class InputfieldTextarea extends InputfieldText {

  const defaultRows = 5; 

  public static function getModuleInfo() {
    return array(
      'title' => __('Textarea', __FILE__), // Module Title
      'summary' => __('Multiple lines of text', __FILE__), // Module Summary
      'version' => 103,
      'permanent' => true, 
      );
  }


  public function init() {
    parent::init();
    $this->setAttribute('rows', self::defaultRows); 
    $this->setAttribute('maxlength', $this->getDefaultMaxlength()); 
    $this->set('contentType', FieldtypeTextarea::contentTypeUnknown); 
  }

  /**
   * Get the default maxlength attribute value
   *
   * @return mixed
   *
   */
  public function getDefaultMaxlength() {
    return $this->hasFieldtype === false ? 1024*32 : 0;
  }

  /**
   * Get all attributes in an associative array
   *
   * @return array
   *
   */
  public function getAttributes() {
    $attrs = parent::getAttributes();

    if(isset($attrs['maxlength'])) {
      if($attrs['maxlength'] > 0) {
        // we only allow maxlength attribute for use outside of PW fields
        // otherwise we only use data-maxlength attribute
        $attrs['data-maxlength'] = $attrs['maxlength'];
        if($this->hasFieldtype !== false) unset($attrs['maxlength']);
      } else {
        unset($attrs['maxlength']);
      }
    }
    
    return $attrs;
  }

  /**
   * Return the length of the given value (not including markup)
   *
   * @param string $value
   * @param bool $countWords Optionally return a word count rather than character count. 
   * @return int
   *
   */
  protected function getValueLength($value, $countWords = false) {
    if(in_array($this->contentType, array(FieldtypeTextarea::contentTypeHTML, FieldtypeTextarea::contentTypeImageHTML))) {
      $value = strip_tags($value);
    }
    $value = $this->wire('sanitizer')->textarea($value, array('stripTags' => false)); 
    return parent::getValueLength($value, $countWords);
  }

  /**
   * Render Inputfield
   * 
   * @return string
   * 
   */
  public function ___render() {

    $attrs = $this->getAttributes();
    unset($attrs['value'], $attrs['size'], $attrs['type']);

    $out = 
      "<textarea " . $this->getAttributesString($attrs) . ">" . 
        htmlspecialchars($this->value, ENT_QUOTES, "UTF-8") . 
      "</textarea>";
    return $out; 
  }

  /**
   * Prepare the 'value' attribute
   * 
   * @param string $value
   * @return string
   * @throws WireException
   * 
   */
  protected function setAttributeValue($value) {
    $maxlength = $this->attr('maxlength');
    if($maxlength > 0 && $this->hasFieldtype === false) { 
      $value = $this->wire('sanitizer')->textarea($value, array(
        'maxLength' => $maxlength, 
        'maxBytes' => $maxlength*4, 
        'stripTags' => false, 
        'trim' => $this->noTrim ? false : true
        )); 
    } else {
      if(strpos($value, "\r\n") !== false) {
        $value = str_replace("\r\n", "\n", $value); 
      }
    }
    if($this->stripTags) $value = strip_tags($value);
    return $this->noTrim ? $value : trim($value); 
  }

  /**
   * Process input
   * 
   * @param WireInputData $input
   * @return $this
   * 
   */
  public function ___processInput(WireInputData $input) {

    $maxlength = $this->attr('maxlength');
    if($this->hasFieldtype !== false && $maxlength > 0) {
      // we want to apply our own maxlength logic that doesn't truncate
      $this->attr('maxlength', 0);
      $result = parent::___processInput($input);
      $this->attr('maxlength', $maxlength); // restore

      $value = $this->attr('value');
      $length = function_exists('mb_strlen') ? mb_strlen($value) : strlen($value);
      if($length > $maxlength) {
        $this->error(sprintf(
          $this->_('Value exceeds maximum recommended length of %1$d characters (length=%2$d).'),
          $maxlength, $length)
        );
      }
    } else {
      $result = parent::___processInput($input);
    }
    
    return $result; 
  }

  /**
   * Render just the value (not input) in text/markup for presentation purposes
   *
   * @return string of text or markup where applicable
   *
   */
  public function ___renderValue() {
    if($this->contentType == FieldtypeTextarea::contentTypeHTML) {
      $out = "<div class='InputfieldTextareaContentTypeHTML'>" . 
        $this->wire('sanitizer')->purify($this->attr('value')) . "</div>";
    } else {
      $out = nl2br(htmlentities($this->attr('value'), ENT_QUOTES, "UTF-8"));
    } 
    return $out;
  }


  public function ___getConfigInputfields() {
    $inputfields = parent::___getConfigInputfields();
    $inputfields->remove($inputfields->getChildByName('size')); // size is not applicable to textarea
    $inputfields->remove($inputfields->getChildByName('pattern')); // pattern is not applicable to textarea
    //if($this->hasFieldtype !== false) $inputfields->remove($inputfields->get('maxlength')); 

    $field = $this->modules->get('InputfieldInteger'); 
    $field->setAttribute('name', 'rows'); 
    $field->label = $this->_('Rows');
    $field->setAttribute('value', $this->attr('rows') > 0 ? $this->attr('rows') : self::defaultRows); 
    $field->setAttribute('size', 3); 
    $field->description = $this->_('The number of rows initially shown for this field.'); 
    if($field->attr('value') == self::defaultRows) $field->collapsed = Inputfield::collapsedYes; 
    $inputfields->append($field);

    return $inputfields; 
  }
  
  public function ___getConfigAllowContext($field) {
    return array_merge(parent::___getConfigAllowContext($field), array('rows')); 
  }
  
}