1
0
mirror of https://github.com/processwire/processwire.git synced 2025-08-17 20:11:46 +02:00

Various minor Inputfield code and phpdoc improvements

This commit is contained in:
Ryan Cramer
2022-01-05 10:08:43 -05:00
parent 49de9483ce
commit d1a6e2303d
13 changed files with 349 additions and 103 deletions

View File

@@ -3,6 +3,9 @@
/**
* An Inputfield for handling "button" buttons
*
* ProcessWire 3.x, Copyright 2022 by Ryan Cramer
* https://processwire.com
*
* @property string $href URL to link to
* @property string $aclass Optional class name(s) for <a> element (if href is used).
* @property string $target Link target
@@ -17,7 +20,7 @@ class InputfieldButton extends InputfieldSubmit {
'summary' => __('Form button element that you can optionally pass an href attribute to.', __FILE__), // Module Summary
'version' => 100,
'permanent' => true,
);
);
}
public function init() {

View File

@@ -3,7 +3,7 @@
/**
* An Inputfield for handling email addresses
*
* ProcessWire 3.x, Copyright 2020 by Ryan Cramer
* ProcessWire 3.x, Copyright 2022 by Ryan Cramer
* https://processwire.com
*
* @property int $confirm Specify 1 to make it include a second input for confirmation

View File

@@ -1,16 +1,41 @@
<?php namespace ProcessWire;
/**
* Fieldset Inputfield
*
* ProcessWire 3.x, Copyright 2022 by Ryan Cramer
* https://processwire.com
*
* @property string|int $defaultValue
* @property array|string $options Get or set options, array of [value => label], or use options string.
* @property array $optionAttributes
* @property bool $valueAddOption If value attr set from API (only) that is not an option, add it as an option? (default=false) 3.0.171+
*
*/
class InputfieldFieldset extends InputfieldWrapper {
/**
* Get module info
*
* @return array
*
*/
public static function getModuleInfo() {
return array(
'title' => __('Fieldset', __FILE__), // Module Title
'summary' => __('Groups one or more fields together in a container', __FILE__), // Module Summary
'version' => 101,
'permanent' => true,
);
);
}
/**
* Render
*
* @return string
*
*/
public function ___render() {
// Note the extra "\n" is required in order to prevent InputfieldWrapper from
// skipping over an empty fieldset. Empty fieldsets are used by InputfieldRepeater

View File

@@ -3,7 +3,7 @@
/**
* Inputfield for floating point numbers
*
* ProcessWire 3.x, Copyright 2020 by Ryan Cramer
* ProcessWire 3.x, Copyright 2022 by Ryan Cramer
* https://processwire.com
*
* @property int $precision Decimals precision

View File

@@ -3,7 +3,7 @@
/**
* InputfieldForm: An Inputfield for containing form elements
*
* ProcessWire 3.x, Copyright 2021 by Ryan Cramer
* ProcessWire 3.x, Copyright 2022 by Ryan Cramer
* https://processwire.com
*
* @property string $prependMarkup Optional markup to prepend to the form output
@@ -75,7 +75,7 @@ class InputfieldForm extends InputfieldWrapper {
'summary' => __('Contains one or more fields in a form', __FILE__), // Module Summary
'version' => 107,
'permanent' => true,
);
);
}
const debug = false; // set to true to enable debug mode for field dependencies
@@ -233,6 +233,8 @@ class InputfieldForm extends InputfieldWrapper {
}
if(self::debug) $this->debugNote("showIf selector: $selectorString");
/** @var Selectors $selectors */
$selectors = $this->wire(new Selectors($selectorString));
// whether we should process $child now or not
@@ -387,7 +389,8 @@ class InputfieldForm extends InputfieldWrapper {
if(strlen($selectorString)) {
if(self::debug) $this->debugNote("requiredIf selector: $selectorString");
/** @var Selectors $selectors */
$selectors = $this->wire(new Selectors($selectorString));
foreach($selectors as $selector) {

View File

@@ -3,6 +3,9 @@
/**
* An Inputfield for handling HTML “hidden” form inputs
*
* ProcessWire 3.x, Copyright 2021 by Ryan Cramer
* https://processwire.com
*
* @property bool $renderValueAsInput Render the hidden input, even when in renderValue mode (default=false)
* @property string $initValue Initial populated value if value attribute not separately populated (default='')
*
@@ -18,6 +21,10 @@ class InputfieldHidden extends Inputfield {
);
}
/**
* Construct
*
*/
public function __construct() {
parent::__construct();
$this->setAttribute('type', 'hidden');
@@ -25,10 +32,22 @@ class InputfieldHidden extends Inputfield {
$this->initValue = '';
}
/**
* Render
*
* @return string
*
*/
public function ___render() {
return "<input " . $this->getAttributesString() . " />";
}
/**
* Render value
*
* @return string
*
*/
public function ___renderValue() {
if($this->renderValueAsInput) {
return $this->render();
@@ -37,12 +56,24 @@ class InputfieldHidden extends Inputfield {
}
}
/**
* Get attributes
*
* @return array
*
*/
public function getAttributes() {
$attrs = parent::getAttributes();
if(!strlen("$attrs[value]") && $this->initValue) $attrs['value'] = (string) $this->initValue;
return $attrs;
}
/**
* Configure Inputfield
*
* @return InputfieldWrapper
*
*/
public function ___getConfigInputfields() {
$inputfields = parent::___getConfigInputfields();
@@ -54,7 +85,7 @@ class InputfieldHidden extends Inputfield {
$inputfields->remove($f);
/** @var InputfieldText $field */
$field = $this->modules->get('InputfieldText');
$field = $this->wire()->modules->get('InputfieldText');
$field->setAttribute('name', 'initValue');
$field->label = $this->_('Value');
$field->description = $this->_('Value to be populated in this hidden field.');

View File

@@ -3,7 +3,7 @@
/**
* Integer Inputfield
*
* ProcessWire 3.x, Copyright 2020 by Ryan Cramer
* ProcessWire 3.x, Copyright 2022 by Ryan Cramer
* https://processwire.com
*
* @property string $inputType Input type to use, one of "text" or "number"

View File

@@ -3,6 +3,9 @@
/**
* Intended just for outputting markup as help or commentary among other Inputfields
*
* ProcessWire 3.x, Copyright 2021 by Ryan Cramer
* https://processwire.com
*
* @property callable|string|null $markupFunction
* @property array $textformatters
* @property string $markupText
@@ -11,25 +14,49 @@
class InputfieldMarkup extends InputfieldWrapper {
/**
* Get module info
*
* @return array
*
*/
public static function getModuleInfo() {
return array(
'title' => __('Markup', __FILE__),
'summary' => __('Contains any other markup and optionally child Inputfields', __FILE__),
'version' => 102,
'permanent' => true,
);
);
}
/**
* Whether render() has been called from renderValue()
*
* @var bool
*
*/
protected $renderValueMode = false;
/**
* Init
*
*/
public function init() {
$this->set('markupText', '');
$this->set('markupFunction', null); // closure or name of function that returns markup, receives $this as arg0.
$this->set('textformatters', array());
$this->skipLabel = Inputfield::skipLabelBlank;
parent::init();
}
}
/**
* Render ready
*
* @param Inputfield|null $parent
* @param bool $renderValueMode
* @return bool
*
*/
public function renderReady(Inputfield $parent = null, $renderValueMode = false) {
$label = $this->getSetting('label');
@@ -39,8 +66,15 @@ class InputfieldMarkup extends InputfieldWrapper {
return parent::renderReady($parent, $renderValueMode);
}
/**
* Render
*
* @return string
*
*/
public function ___render() {
$modules = $this->wire()->modules;
$out = '';
$value = (string) $this->attr('value');
@@ -63,7 +97,8 @@ class InputfieldMarkup extends InputfieldWrapper {
if(wireCount($textformatters)) {
foreach($textformatters as $className) {
$t = $this->wire()->modules->get($className);
/** @var Textformatter $t */
$t = $modules->get($className);
if(!$t) continue;
$t->formatValue($this->wire()->page, $this->wire(new Field()), $out);
}
@@ -74,7 +109,7 @@ class InputfieldMarkup extends InputfieldWrapper {
if($this->getSetting('entityEncodeText') !== false && $textFormat != Inputfield::textFormatNone) {
if($textFormat == Inputfield::textFormatBasic) {
$description = $this->entityEncode($description, Inputfield::textFormatBasic);
$out = "<p class='description'>{$description}</p>$out";
$out = "<p class='description'>$description</p>$out";
} else if($textFormat == Inputfield::textFormatMarkdown) {
$out = "<div class='description'>" . $this->entityEncode($description, Inputfield::textFormatMarkdown) . "</div>$out";
}
@@ -93,13 +128,25 @@ class InputfieldMarkup extends InputfieldWrapper {
return $out;
}
/**
* Render value
*
* @return string
*
*/
public function ___renderValue() {
$this->renderValueMode = true;
$out = $this->render();
$this->renderValueMode = false;
return $out;
}
/**
* Configure Inputfield
*
* @return InputfieldWrapper
*
*/
public function ___getConfigInputfields() {
$modules = $this->wire()->modules;
@@ -119,13 +166,13 @@ class InputfieldMarkup extends InputfieldWrapper {
$f->attr('id+name', 'textformatters');
$f->label = $this->_('Text Formatters');
foreach($modules->find("className^=Textformatter") as $textformatter) {
$info = $textformatter->getModuleInfo();
$f->addOption($textformatter->className(), "$info[title]");
foreach($modules->findByPrefix('Textformatter') as $moduleName) {
$info = $modules->getModuleInfo($moduleName);
$title = $info['title'] ? $info['title'] : $moduleName;
$f->addOption($moduleName, $title);
}
$f->attr('value', $this->textformatters);
$f->description = $this->_('Select the format that your Markup Text is in, or the formatters that you want to be applied to it, in the order you want them applied.');
$f->notes = $this->_('If your Markup Text is plain HTML, you may not want to select any Text Formatters.');
$inputfields->add($f);

View File

@@ -3,6 +3,9 @@
/**
* An Inputfield for handling ProcessWire "name" fields
*
* ProcessWire 3.x, Copyright 2021 by Ryan Cramer
* https://processwire.com
*
* @property string $sanitizeMethod
*
*/
@@ -14,7 +17,7 @@ class InputfieldName extends InputfieldText {
'version' => 100,
'summary' => __('Text input validated as a ProcessWire name field', __FILE__), // Module Summary
'permanent' => true,
);
);
}
public function __construct() {
@@ -37,9 +40,11 @@ class InputfieldName extends InputfieldText {
protected function setAttributeValue($value) {
$sanitizeMethod = $this->sanitizeMethod;
if($this->isWired()) {
$value = call_user_func(array($this->wire('sanitizer'), $sanitizeMethod), $value);
$sanitizer = $this->wire()->sanitizer;
$value = call_user_func(array($sanitizer, $sanitizeMethod), $value);
} else {
$value = wire('sanitizer')->$sanitizeMethod($value);
$sanitizer = wire()->sanitizer;
$value = $sanitizer->$sanitizeMethod($value);
}
return $value;
}

View File

@@ -8,7 +8,7 @@
* Sublcasses will want to override the render method, but it's not necessary to override processInput().
* Subclasses that select multiple values should implement the InputfieldHasArrayValue interface.
*
* ProcessWire 3.x, Copyright 2021 by Ryan Cramer
* ProcessWire 3.x, Copyright 2022 by Ryan Cramer
* https://processwire.com
*
* @property string|int $defaultValue
@@ -164,8 +164,10 @@ class InputfieldSelect extends Inputfield implements InputfieldHasSelectableOpti
*
*/
public function optionLanguageLabel($language, $key = null, $label = null) {
$languages = $this->wire()->languages;
if(!$languages) return $this;
if(is_string($language) && !ctype_digit("$language")) {
$language = $this->wire('languages')->get($language);
$language = $languages->get($language);
}
$languageID = (int) "$language"; // converts Page or string to id
if(!isset($this->optionLanguageLabels[$languageID])) {
@@ -676,17 +678,20 @@ class InputfieldSelect extends Inputfield implements InputfieldHasSelectableOpti
*
*/
public function renderReady(Inputfield $parent = null, $renderValueMode = false) {
if(!empty($this->optionLanguageLabels) && $this->wire('languages') && $this->hasFieldtype === false) {
// make option labels use use language where available
$language = $this->wire('user')->language;
$defaultLanguage = $this->wire('languages')->getDefault();
if(!empty($this->optionLanguageLabels[$language->id])) {
$labels = $this->optionLanguageLabels[$language->id];
foreach($this->options as $key => $defaultLabel) {
if(empty($labels[$key])) continue;
$this->options[$key] = $labels[$key];
if($language->id != $defaultLanguage->id) {
$this->optionLanguageLabel($defaultLanguage, $key, $defaultLabel);
if(!empty($this->optionLanguageLabels) && $this->hasFieldtype === false) {
$languages = $this->wire()->languages;
if($languages) {
// make option labels use use language where available
$language = $this->wire()->user->language;
$defaultLanguage = $languages->getDefault();
if(!empty($this->optionLanguageLabels[$language->id])) {
$labels = $this->optionLanguageLabels[$language->id];
foreach($this->options as $key => $defaultLabel) {
if(empty($labels[$key])) continue;
$this->options[$key] = $labels[$key];
if($language->id != $defaultLanguage->id) {
$this->optionLanguageLabel($defaultLanguage, $key, $defaultLabel);
}
}
}
}
@@ -705,12 +710,10 @@ class InputfieldSelect extends Inputfield implements InputfieldHasSelectableOpti
$attrs = $this->getAttributes();
unset($attrs['value']);
$out =
return
"<select " . $this->getAttributesString($attrs) . ">" .
$this->renderOptions($this->options) .
$this->renderOptions($this->options) .
"</select>";
return $out;
}
/**
@@ -722,6 +725,7 @@ class InputfieldSelect extends Inputfield implements InputfieldHasSelectableOpti
public function ___renderValue() {
$out = '';
$sanitizer = $this->wire()->sanitizer;
foreach($this->options as $value => $label) {
@@ -738,11 +742,13 @@ class InputfieldSelect extends Inputfield implements InputfieldHasSelectableOpti
}
if(strlen($o)) {
$out .= "<li>" . $this->wire('sanitizer')->entities($o) . "</li>";
$out .= "<li>" . $sanitizer->entities($o) . "</li>";
}
}
if(strlen($out)) $out = "<ul class='pw-bullets'>$out</ul>";
if(strlen($out)) {
$out = "<ul class='pw-bullets'>$out</ul>";
}
return $out;
}
@@ -779,10 +785,10 @@ class InputfieldSelect extends Inputfield implements InputfieldHasSelectableOpti
if($this instanceof InputfieldHasArrayValue) {
/** @var InputfieldSelect $this */
if(!is_array($value)) $value = array();
foreach($value as $k => $v) {
if(!$this->isOption($v)) {
// $this->message("Removing invalid option: " . wire('sanitizer')->entities($value[$k]), Notice::debug);
unset($value[$k]);
unset($value[$k]); // remove invalid option
}
}
@@ -805,8 +811,8 @@ class InputfieldSelect extends Inputfield implements InputfieldHasSelectableOpti
*
*/
public function get($key) {
if($key == 'options') return $this->options;
if($key == 'optionAttributes') return $this->optionAttributes;
if($key === 'options') return $this->options;
if($key === 'optionAttributes') return $this->optionAttributes;
return parent::get($key);
}
@@ -874,7 +880,7 @@ class InputfieldSelect extends Inputfield implements InputfieldHasSelectableOpti
}
}
} else {
if(strlen($value) && !$this->isOption($value)) {
if(strlen("$value") && !$this->isOption($value)) {
$this->addOption($value);
}
}
@@ -901,7 +907,7 @@ class InputfieldSelect extends Inputfield implements InputfieldHasSelectableOpti
} else if($value === null || $value === false) {
return true;
} else if($value == "0") {
} else if("$value" === "0") {
if(!array_key_exists("$value", $this->options)) return true;
} else {
@@ -920,12 +926,15 @@ class InputfieldSelect extends Inputfield implements InputfieldHasSelectableOpti
public function ___getConfigInputfields() {
$inputfields = parent::___getConfigInputfields();
$modules = $this->wire()->modules;
if($this instanceof InputfieldHasArrayValue) {
$f = $this->wire('modules')->get('InputfieldTextarea');
/** @var InputfieldTextarea $f */
$f = $modules->get('InputfieldTextarea');
$f->description = $this->_('To have pre-selected default value(s), enter the option values (one per line) below.');
} else {
$f = $this->wire('modules')->get('InputfieldText');
/** @var InputfieldText $f */
$f = $modules->get('InputfieldText');
$f->description = $this->_('To have a pre-selected default value, enter the option value below.');
}
$f->attr('name', 'defaultValue');
@@ -943,10 +952,10 @@ class InputfieldSelect extends Inputfield implements InputfieldHasSelectableOpti
// the following configuration specific to non-Fieldtype use of single/multi-selects
$isInputfieldSelect = $this->className() == 'InputfieldSelect';
/** @var Languages|null $languages */
$languages = $this->wire('languages');
$languages = $this->wire()->languages;
$f = $this->wire('modules')->get('InputfieldTextarea');
/** @var InputfieldTextarea $f */
$f = $modules->get('InputfieldTextarea');
$f->attr('name', 'options');
$f->label = $this->_('Options');
$value = '';

View File

@@ -1,18 +1,45 @@
<?php namespace ProcessWire;
/**
* Select Multiple Inputfield
*
* An Inputfield for handling multiple selection using HTML `<select multiple>`.
* Also a base type for other multiple selection types (checkboxes, asmSelect, etc.)
*
* ProcessWire 3.x, Copyright 2022 by Ryan Cramer
* https://processwire.com
*
* @property int $size
*
*/
class InputfieldSelectMultiple extends InputfieldSelect implements InputfieldHasArrayValue {
const defaultSize = 10;
/**
* Default 'size' attribute value
*
*/
const defaultSize = 10;
/**
* Get module info
*
* @return array
*
*/
public static function getModuleInfo() {
return array(
'title' => __('Select Multiple', __FILE__), // Module Title
'summary' => __('Select multiple items from a list', __FILE__), // Module Summary
'version' => 101,
'permanent' => true,
);
);
}
/**
* Construct
*
*/
public function __construct() {
parent::__construct();
$this->setAttribute('multiple', 'multiple');
@@ -23,6 +50,11 @@ class InputfieldSelectMultiple extends InputfieldSelect implements InputfieldHas
* Add options only if they are non-blank
*
* We don't need blank options in a select multiple since the unselected state involves no selected options
*
* @param string|int $value
* @param string|null $label
* @param array|null $attributes
* @return InputfieldSelect|InputfieldSelectMultiple|self
*
*/
public function addOption($value, $label = null, array $attributes = null) {
@@ -30,11 +62,18 @@ class InputfieldSelectMultiple extends InputfieldSelect implements InputfieldHas
return parent::addOption($value, $label, $attributes);
}
/**
* Configure Inputfield
*
* @return InputfieldWrapper
*
*/
public function ___getConfigInputfields() {
$inputfields = parent::___getConfigInputfields();
if($this->className() == 'InputfieldSelectMultiple') {
if($this->className() === 'InputfieldSelectMultiple') {
// descending classes may null out the 'size' attribute if they don't need it
$f = $this->wire('modules')->get('InputfieldInteger');
/** @var InputfieldInteger $f */
$f = $this->wire()->modules->get('InputfieldInteger');
$f->label = $this->_('Size: number of rows visible at once in the select multiple');
$f->attr('name', 'size');
$f->attr('value', (int) $this->attr('size'));
@@ -42,6 +81,4 @@ class InputfieldSelectMultiple extends InputfieldSelect implements InputfieldHas
}
return $inputfields;
}
}

View File

@@ -3,14 +3,27 @@
/**
* An Inputfield for handling "textarea" form inputs
*
* ProcessWire 3.x, Copyright 2022 by Ryan Cramer
* https://processwire.com
*
* @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;
/**
* Default value for rows attribute
*
*/
const defaultRows = 5;
/**
* Get module info
*
* @return array
*
*/
public static function getModuleInfo() {
return array(
'title' => __('Textarea', __FILE__), // Module Title
@@ -20,7 +33,10 @@ class InputfieldTextarea extends InputfieldText {
);
}
/**
* Init Inputfield
*
*/
public function init() {
parent::init();
$this->setAttribute('rows', self::defaultRows);
@@ -70,10 +86,8 @@ class InputfieldTextarea extends InputfieldText {
*
*/
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));
if($this->isContentTypeHTML()) $value = strip_tags($value);
$value = $this->wire()->sanitizer->textarea($value, array('stripTags' => false));
return parent::getValueLength($value, $countWords);
}
@@ -89,11 +103,10 @@ class InputfieldTextarea extends InputfieldText {
$value = $attrs['value'];
unset($attrs['value'], $attrs['size'], $attrs['type']);
$out =
return
"<textarea " . $this->getAttributesString($attrs) . ">" .
htmlspecialchars($value, ENT_QUOTES, "UTF-8") .
"</textarea>";
return $out;
}
/**
@@ -105,8 +118,10 @@ class InputfieldTextarea extends InputfieldText {
*
*/
protected function setAttributeValue($value) {
$maxlength = $this->attr('maxlength');
$value = (string) $value;
if($maxlength > 0 && $this->hasFieldtype === false) {
$value = $this->wire()->sanitizer->textarea($value, array(
'maxLength' => $maxlength,
@@ -119,7 +134,9 @@ class InputfieldTextarea extends InputfieldText {
$value = str_replace("\r\n", "\n", $value);
}
}
if($this->stripTags) $value = strip_tags($value);
return $this->noTrim ? $value : trim($value);
}
@@ -133,6 +150,7 @@ class InputfieldTextarea extends InputfieldText {
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);
@@ -161,26 +179,49 @@ class InputfieldTextarea extends InputfieldText {
*
*/
public function ___renderValue() {
if($this->contentType == FieldtypeTextarea::contentTypeHTML) {
$out = "<div class='InputfieldTextareaContentTypeHTML'>" .
$this->wire('sanitizer')->purify($this->attr('value')) . "</div>";
if($this->isContentTypeHTML()) {
$out =
"<div class='InputfieldTextareaContentTypeHTML'>" .
$this->wire()->sanitizer->purify($this->val()) .
"</div>";
} else {
$out = nl2br(htmlentities($this->attr('value'), ENT_QUOTES, "UTF-8"));
$out = nl2br(htmlentities($this->val(), ENT_QUOTES, "UTF-8"));
}
return $out;
}
/**
* Is current content-type an HTML content-type?
*
* @return bool
*
*/
public function isContentTypeHTML() {
$contentTypes = array(
FieldtypeTextarea::contentTypeHTML,
FieldtypeTextarea::contentTypeImageHTML
);
return in_array($this->contentType, $contentTypes);
}
/**
* Configure Inputfield
*
* @return InputfieldWrapper
*
*/
public function ___getConfigInputfields() {
$inputfields = parent::___getConfigInputfields();
$removes = array('size', 'pattern');
foreach($removes as $name) {
$f = $inputfields->getChildByName($name);
if($f) $inputfields->remove($f);
}
/** @var InputfieldInteger $field */
$field = $this->modules->get('InputfieldInteger');
$field = $this->wire()->modules->get('InputfieldInteger');
$field->setAttribute('name', 'rows');
$field->label = $this->_('Rows');
$field->setAttribute('value', $this->attr('rows') > 0 ? $this->attr('rows') : self::defaultRows);
@@ -191,7 +232,14 @@ class InputfieldTextarea extends InputfieldText {
return $inputfields;
}
/**
* Get config fields allowed for context
*
* @param Field $field
* @return array
*
*/
public function ___getConfigAllowContext($field) {
return array_merge(parent::___getConfigAllowContext($field), array('rows'));
}

View File

@@ -1,9 +1,12 @@
<?php namespace ProcessWire;
/**
* Class InputfieldURL
* URL Inputfield Module
*
* An Inputfield for handling input of URLs
* An Inputfield for handling input of URLs in ProcessWire forms.
*
* ProcessWire 3.x, Copyright 2022 by Ryan Cramer
* https://processwire.com
*
* @property int|bool $noRelative Whether relative URLs are disabled
* @property int|bool $addRoot Whether to prepend root path
@@ -17,10 +20,14 @@ class InputfieldURL extends InputfieldText {
return array(
'title' => __('URL', __FILE__), // Module Title
'summary' => __('URL in valid format', __FILE__), // Module Summary
'version' => 102,
);
'version' => 103,
);
}
/**
* Construct
*
*/
public function __construct() {
parent::__construct();
$this->setAttribute('type', 'text');
@@ -34,44 +41,75 @@ class InputfieldURL extends InputfieldText {
$this->set('allowQuotes', 0); // whether to allow quote characters in URLs
}
/**
* Render Inputfield
*
* @return string
*
*/
public function ___render() {
$rootUrl = $this->config->urls->root;
$rootUrl = $this->wire()->config->urls->root;
if($this->addRoot && !$this->noRelative && !$this->notes && strlen($rootUrl) > 1) {
$this->notes = sprintf($this->_("Start local URLs with \"/\" and leave off the \"%s\" part."), $rootUrl); // Instruction for local URLs displayed when site is running from a subdirectory
$this->notes = sprintf(
$this->_("Start local URLs with “/” and leave off the “%s” part."), // Instruction for local URLs displayed when site is running from a subdirectory
$rootUrl
);
}
return parent::___render();
}
/**
* Set value attribute
*
* @param string $value
* @return string
*
*/
protected function setAttributeValue($value) {
if(strlen($value)) {
$value = trim($value);
$unsanitized = $value;
$value = $this->wire('sanitizer')->url($value, array(
'allowRelative' => $this->noRelative ? false : true,
'allowIDN' => $this->allowIDN ? true : false,
'stripQuotes' => $this->allowQuotes ? false : true,
));
if(!$value || $unsanitized != $value && "http://$unsanitized" != $value) {
$error = true;
if($value && strpos($unsanitized, '%') !== false) {
$test = rawurldecode($unsanitized);
if($value == $test || $value == "http://$test") $error = false;
}
if($error) {
$this->error($this->name . ': ' . $this->_("Error found - please check that it is a valid URL")); // Error message when invalid URL found
}
} else if($value != $unsanitized && $value == "http://$unsanitized") {
$this->message($this->name . ': ' . $this->_("Note that \"http://\" was added")); // Message displayed when http scheme was automatically added to the URL
$value = trim((string) $value);
$dirty = $value;
$label = $this->label ? $this->label : $this->name;
if(!strlen($dirty)) return '';
$value = $this->wire()->sanitizer->url($dirty, array(
'allowRelative' => $this->noRelative ? false : true,
'allowIDN' => $this->allowIDN ? true : false,
'stripQuotes' => $this->allowQuotes ? false : true,
));
if(empty($value) || ($dirty !== $value && "http://$dirty" !== $value && "https://$dirty" !== $value)) {
$error = true;
if(strpos($dirty, '%') !== false) {
$test = rawurldecode($dirty);
if($value === $test || $value === "http://$test" || $value === "https://$test") $error = false;
}
if($error) {
$this->error("$label - " . $this->_("Error found - please check that it is a valid URL")); // Error message when invalid URL found
}
} else $value = '';
} else if($value !== $dirty) {
$scheme = '';
foreach(array('http', 'https') as $s) {
if($value !== "$s://$dirty") continue;
$scheme = "$s://";
break;
}
if($scheme) {
$this->message("$label - " . sprintf($this->_("Note that %s was added"), $scheme)); // Message displayed when scheme was automatically added to the URL
}
}
return $value;
}
/**
* Configure Inputfield
*
* @return InputfieldWrapper
*
*/
public function ___getConfigInputfields() {
$inputfields = parent::___getConfigInputfields();
$f = $inputfields->get('stripTags');