mirror of
https://github.com/processwire/processwire.git
synced 2025-08-10 08:44:46 +02:00
Various minor updates and optimizations to several core classes
This commit is contained in:
@@ -20,7 +20,7 @@
|
||||
* This file is licensed under the MIT license
|
||||
* https://processwire.com/about/license/mit/
|
||||
*
|
||||
* ProcessWire 3.x, Copyright 2016 by Ryan Cramer
|
||||
* ProcessWire 3.x, Copyright 2019 by Ryan Cramer
|
||||
* https://processwire.com
|
||||
*
|
||||
*
|
||||
@@ -109,11 +109,12 @@ class DatabaseQuerySelectFulltext extends Wire {
|
||||
break;
|
||||
|
||||
case '~=':
|
||||
case '!~=':
|
||||
$words = preg_split('/[-\s,]/', $value, -1, PREG_SPLIT_NO_EMPTY);
|
||||
foreach($words as $word) {
|
||||
$len = function_exists('mb_strlen') ? mb_strlen($word) : strlen($word);
|
||||
if(DatabaseStopwords::has($word) || $len < $database->getVariable('ft_min_word_len')) {
|
||||
$this->matchWordLIKE($tableName, $fieldName, $word);
|
||||
$this->matchWordLIKE($tableName, $fieldName, $operator, $word);
|
||||
} else {
|
||||
$this->matchContains($tableName, $fieldName, $operator, $word);
|
||||
}
|
||||
@@ -192,26 +193,32 @@ class DatabaseQuerySelectFulltext extends Wire {
|
||||
$tableField = "$tableName.$fieldName";
|
||||
$database = $this->wire('database');
|
||||
$v = $database->escapeStr($value);
|
||||
$not = strpos($operator, '!') === 0;
|
||||
if($not) $operator = ltrim($operator, '!');
|
||||
|
||||
$n = 0;
|
||||
do {
|
||||
$scoreField = "_score_{$tableName}_{$fieldName}" . (++$n);
|
||||
} while(in_array($scoreField, self::$scoreFields));
|
||||
self::$scoreFields[] = $scoreField;
|
||||
|
||||
$query->select("MATCH($tableField) AGAINST('$v') AS $scoreField");
|
||||
|
||||
$match = $not ? 'NOT MATCH' : 'MATCH';
|
||||
$query->select("$match($tableField) AGAINST('$v') AS $scoreField");
|
||||
$query->orderby($scoreField . " DESC");
|
||||
|
||||
$partial = $operator != '~=';
|
||||
$partial = $operator != '~=' && $operator != '!~=';
|
||||
$booleanValue = $database->escapeStr($this->getBooleanQueryValue($value, true, $partial));
|
||||
if($booleanValue) $j = "MATCH($tableField) AGAINST('$booleanValue' IN BOOLEAN MODE) ";
|
||||
else $j = '';
|
||||
if($booleanValue) {
|
||||
$j = "$match($tableField) AGAINST('$booleanValue' IN BOOLEAN MODE) ";
|
||||
} else {
|
||||
$j = '';
|
||||
}
|
||||
|
||||
if($operator == '^=' || $operator == '$=' || ($operator == '*=' && (!$j || preg_match('/[-\s]/', $v)))) {
|
||||
// if $operator is a ^begin/$end, or if there are any word separators in a *= operator value
|
||||
|
||||
if($operator == '^=' || $operator == '$=') {
|
||||
$type = 'RLIKE';
|
||||
$type = $not ? 'NOT RLIKE' : 'RLIKE';
|
||||
$v = $database->escapeStr(preg_quote($value)); // note $value not $v
|
||||
$like = "[[:space:]]*(<[^>]+>)*[[:space:]]*";
|
||||
if($operator == '^=') {
|
||||
@@ -221,7 +228,7 @@ class DatabaseQuerySelectFulltext extends Wire {
|
||||
}
|
||||
|
||||
} else {
|
||||
$type = 'LIKE';
|
||||
$type = $not ? 'NOT LIKE' : 'LIKE';
|
||||
$v = $this->escapeLIKE($v);
|
||||
$like = "%$v%";
|
||||
}
|
||||
@@ -241,15 +248,17 @@ class DatabaseQuerySelectFulltext extends Wire {
|
||||
*
|
||||
* @param string $tableName
|
||||
* @param string $fieldName
|
||||
* @param string $operator
|
||||
* @param $word
|
||||
*
|
||||
*/
|
||||
protected function matchWordLIKE($tableName, $fieldName, $word) {
|
||||
protected function matchWordLIKE($tableName, $fieldName, $operator, $word) {
|
||||
$tableField = "$tableName.$fieldName";
|
||||
$database = $this->wire('database');
|
||||
$v = $database->escapeStr(preg_quote($word));
|
||||
$regex = "([[[:blank:][:punct:]]|^)$v([[:blank:][:punct:]]|$)";
|
||||
$where = "($tableField REGEXP '$regex')";
|
||||
$type = strpos($operator, '!') === 0 ? 'NOT REGEXP' : 'REGEXP';
|
||||
$where = "($tableField $type '$regex')";
|
||||
$this->query->where($where);
|
||||
}
|
||||
|
||||
|
@@ -20,7 +20,7 @@
|
||||
* @property string $table Database table used by the field #pw-group-properties
|
||||
* @property string $prevTable Previously database table (if field was renamed) #pw-group-properties
|
||||
* @property Fieldtype|null $type Fieldtype module that represents the type of this field #pw-group-properties
|
||||
* @property Fieldtype $prevFieldtype Previous Fieldtype, of type was changed #pw-group-properties
|
||||
* @property Fieldtype|null $prevFieldtype Previous Fieldtype, if type was changed #pw-group-properties
|
||||
* @property int $flags Bitmask of flags used by this field #pw-group-properties
|
||||
* @property-read string $flagsStr Names of flags used by this field (readonly) #pw-group-properties
|
||||
* @property string $label Text string representing the label of the field #pw-group-properties
|
||||
|
@@ -631,7 +631,7 @@ class Fieldgroup extends WireArray implements Saveable, Exportable, HasLookupIte
|
||||
if(!$inputfield) continue;
|
||||
if($inputfield->collapsed == Inputfield::collapsedHidden) continue;
|
||||
|
||||
$inputfield->setAttribute('value', $page->get($field->name));
|
||||
if(!$page instanceof NullPage) $inputfield->setAttribute('value', $page->get($field->name));
|
||||
|
||||
if($multiMode) {
|
||||
$fieldInputfields[$field->id] = $inputfield;
|
||||
|
@@ -467,9 +467,14 @@ class Fieldgroups extends WireSaveableItemsLookup {
|
||||
if(is_null($template)) $template = $this->wire('templates')->get($fieldgroup->name);
|
||||
|
||||
if(($field->flags & Field::flagGlobal) && (!$template || !$template->noGlobal)) {
|
||||
return
|
||||
"Field '$field' may not be removed from fieldgroup '$fieldgroup->name' " .
|
||||
"because it is globally required (Field::flagGlobal).";
|
||||
if($template && $template->getConnectedField()) {
|
||||
// if template has a 1-1 relationship with a field, noGlobal is not enforced
|
||||
return false;
|
||||
} else {
|
||||
return
|
||||
"Field '$field' may not be removed from fieldgroup '$fieldgroup->name' " .
|
||||
"because it is globally required (Field::flagGlobal).";
|
||||
}
|
||||
}
|
||||
|
||||
if($field->flags & Field::flagPermanent) {
|
||||
|
@@ -7,7 +7,7 @@
|
||||
* #pw-body Template objects also maintain several properties which can affect the render behavior of pages using it.
|
||||
* #pw-order-groups identification,manipulation,family,URLs,access,files,cache,page-editor,behaviors,other
|
||||
*
|
||||
* ProcessWire 3.x, Copyright 2016 by Ryan Cramer
|
||||
* ProcessWire 3.x, Copyright 2019 by Ryan Cramer
|
||||
* https://processwire.com
|
||||
*
|
||||
* @todo add multi-language option for redirectLogin setting
|
||||
@@ -108,6 +108,11 @@
|
||||
* @property string $tags Optional tags that can group this template with others in the admin templates list. #pw-group-other
|
||||
* @property string $pageLabelField CSV or space separated string of field names to be displayed by ProcessPageList (overrides those set with ProcessPageList config). #pw-group-other
|
||||
* @property int|bool $_importMode Internal use property set by template importer when importing #pw-internal
|
||||
* @property int|null $connectedFieldID ID of connected field or null or 0 if not applicable. #pw-internal
|
||||
*
|
||||
* Hookable methods
|
||||
*
|
||||
* @method Field|null getConnectedField() Get Field object connected to this field, or null if not applicable. #pw-internal
|
||||
*
|
||||
*
|
||||
*/
|
||||
@@ -263,6 +268,7 @@ class Template extends WireData implements Saveable, Exportable {
|
||||
'nameLabel' => '', // label for the "name" property of the page (if something other than "Name")
|
||||
'contentType' => '', // Content-type header or index of header from $config->contentTypes
|
||||
'errorAction' => 0, // action to take on save when required field on published page is empty (0=notify,1=restore,2=unpublish)
|
||||
'connectedFieldID' => null, // ID of connected field or null if not applicable
|
||||
'ns' => '', // namespace found in the template file, or blank if not determined
|
||||
);
|
||||
|
||||
@@ -700,7 +706,10 @@ class Template extends WireData implements Saveable, Exportable {
|
||||
$this->setIcon($value);
|
||||
|
||||
} else if($key == 'urlSegments') {
|
||||
$this->urlSegments($value);
|
||||
$this->urlSegments($value);
|
||||
|
||||
} else if($key == 'connectedFieldID') {
|
||||
parent::set($key, (int) $value);
|
||||
|
||||
} else {
|
||||
parent::set($key, $value);
|
||||
@@ -1192,6 +1201,37 @@ class Template extends WireData implements Saveable, Exportable {
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Field object connected with this template
|
||||
*
|
||||
* #pw-internal
|
||||
*
|
||||
* @return Field|null Returns Field object or null if not applicable
|
||||
* @since 3.0.142
|
||||
*
|
||||
*/
|
||||
public function ___getConnectedField() {
|
||||
if($this->connectedFieldID) {
|
||||
$field = $this->wire('fields')->get((int) $this->connectedFieldID);
|
||||
} else {
|
||||
$field = null;
|
||||
}
|
||||
if(!$field) {
|
||||
$fieldName = '';
|
||||
$templateName = $this->name;
|
||||
$prefixes = array('field-', 'field_', 'repeater_');
|
||||
foreach($prefixes as $prefix) {
|
||||
if(strpos($templateName, $prefix) !== 0) continue;
|
||||
list(,$fieldName) = explode($prefix, $templateName, 2);
|
||||
break;
|
||||
}
|
||||
if($fieldName) {
|
||||
$field = $this->wire('fields')->get($fieldName);
|
||||
}
|
||||
}
|
||||
return $field;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that isset() and empty() work for this classes properties.
|
||||
*
|
||||
|
@@ -2724,7 +2724,7 @@ class ProcessTemplate extends Process {
|
||||
}
|
||||
|
||||
if($isDeleted) {
|
||||
if(($field->flags & Field::flagGlobal) && !$this->template->noGlobal) {
|
||||
if(!$this->template->getConnectedField() && (($field->flags & Field::flagGlobal) && !$this->template->noGlobal)) {
|
||||
$this->error(sprintf($this->_('Field "%s" may not be removed because it is globally required by all fieldgroups'), $field));
|
||||
} else {
|
||||
$removedFields->add($field);
|
||||
|
@@ -848,7 +848,11 @@ function InputfieldColumnWidths($target) {
|
||||
}
|
||||
|
||||
colspacing = $form.attr('data-colspacing');
|
||||
if(typeof colspacing == 'undefined') colspacing = 1;
|
||||
if(typeof colspacing == 'undefined') {
|
||||
colspacing = 1;
|
||||
} else {
|
||||
colspacing = parseInt(colspacing);
|
||||
}
|
||||
|
||||
// if no borders, we don't worry about keeping heights aligned since they won't be seen
|
||||
useHeights = $form.hasClass('InputfieldFormNoHeights') ? false : true;
|
||||
|
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user