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'));}}