diff --git a/api/js/etemplate/et2_widget_url.js b/api/js/etemplate/et2_widget_url.js index 56b41d1f41..f001f96db2 100644 --- a/api/js/etemplate/et2_widget_url.js +++ b/api/js/etemplate/et2_widget_url.js @@ -26,6 +26,18 @@ var et2_url = (function(){ "use strict"; return et2_textbox.extend( attributes: { "multiline": { "ignore": true + }, + "allow_path": { + type: "boolean", + name: "Allow path", + description: "Allow a path instead of a URL, path must start with /", + default: false + }, + "trailing_slash": { + type: "boolean", + name: "Trailing slash", + description: "Require (or forbid) that the path ends with a /", + default: et2_no_init } }, @@ -212,10 +224,24 @@ var et2_url = (function(){ "use strict"; return et2_textbox.extend( if(value == "") return; switch(e.data._type) { case "url": - if(value.indexOf("://") == -1) { + if(value.indexOf("://") == -1 && !e.data.options.allow_path) { e.data.set_value("http://"+value); e.data.showMessage(e.data.egw().lang("Protocol is required"), "hint", true); } + else if (e.data.options.allow_path && value[0] !== '/') + { + e.data.showMessage(e.data.egw().lang("Path must start with '/'"), "hint", true); + } + + // Adjust trailing slash - required or forbidden + if(e.data.options.trailing_slash === true && value[value.length-1] !== '/' ) + { + e.data.set_value(value+'/'); + } + else if (e.data.options.trailing_slash === false && value[value.length-1] === '/' ) + { + e.data.set_value(value.substr(0,value.length-1)); + } break; case "url-email": if(!e.data.EMAIL_PREG.test(value) || diff --git a/api/src/Etemplate/Widget/Url.php b/api/src/Etemplate/Widget/Url.php index 39306aec86..5dc3dbfc68 100644 --- a/api/src/Etemplate/Widget/Url.php +++ b/api/src/Etemplate/Widget/Url.php @@ -78,17 +78,34 @@ class Url extends Etemplate\Widget } elseif ((string)$value != '' && !isset($this->attrs['preg'])) { + $url_valid = true; switch($this->type) { case 'url': + $this->attrs['preg'] = self::URL_PREG; + if($this->attrs['allow_path']) + { + $url_valid = $value[0] === '/'; + + // Just need to override the regex + $this->attrs['preg'] = '_\/.*_'; + } // if no protocol given eg. "www.egroupware.org" prepend "http://" for validation - if (($missing_protocol = strpos($value, '://') === false)) + else if (($missing_protocol = strpos($value, '://') === false)) { $value = 'http://'.$value; } - $url_valid = filter_var($value, FILTER_VALIDATE_URL) || - // Remove intl chars & check again, but if it passes we'll keep the original - filter_var(preg_replace('/[^[:print:]]/','',$value), FILTER_VALIDATE_URL); + if($url_valid && !$this->attrs['allow_path']) + { + $url_valid = filter_var($value, FILTER_VALIDATE_URL) || + // Remove intl chars & check again, but if it passes we'll keep the original + filter_var(preg_replace('/[^[:print:]]/','',$value), FILTER_VALIDATE_URL); + } + if(array_key_exists('trailing_slash', $this->attrs)) + { + $trailing_slash = substr($value, -1) === '/'; + $url_valid = (($this->attrs['trailing_slash'] == 'true') == $trailing_slash); + } //error_log(__METHOD__."() filter_var(value=".array2string($value).", FILTER_VALIDATE_URL)=".array2string(filter_var($value, FILTER_VALIDATE_URL))." --> url_valid=".array2string($url_valid)); // remove http:// validation prefix again if ($missing_protocol) @@ -100,7 +117,6 @@ class Url extends Etemplate\Widget self::set_validation_error($form_name,lang("'%1' has an invalid format !!!",$value),''); return; } - $this->attrs['preg'] = self::URL_PREG; break; case 'url-email': $this->attrs['preg'] = self::EMAIL_PREG;