mirror of
https://github.com/processwire/processwire.git
synced 2025-08-24 15:23:11 +02:00
Add new $page->if(condition, yes, no) convenience method
This commit is contained in:
@@ -77,9 +77,12 @@
|
||||
* @property string $editURL Alias of $editUrl. #pw-internal
|
||||
* @property PageRender $render May be used for field markup rendering like $page->render->title. #pw-advanced
|
||||
* @property bool $loaderCache Whether or not pages loaded as a result of this one may be cached by PagesLoaderCache. #pw-internal
|
||||
* @property PageArray $references Return pages that are referencing the given one by way of Page references. #pw-group-traversal
|
||||
* @property int $numReferences Total number of pages referencing this page with Page reference fields. #pw-group-traversal
|
||||
* @property int $hasReferences Number of visible pages (to current user) referencing this page with page reference fields. #pw-group-traversal
|
||||
* @property PageArray $referencing Return pages that this page is referencing by way of Page reference fields. #pw-group-traversal
|
||||
* @property int $numReferencing Total number of other pages this page is pointing to (referencing) with Page fields. #pw-group-traversal
|
||||
* @property PageArray $links Return pages that link to this one contextually in Textarea/HTML fields. #pw-group-traversal
|
||||
* @property int $numLinks Total number of pages manually linking to this page in Textarea/HTML fields. #pw-group-traversal
|
||||
* @property int $hasLinks Number of visible pages (to current user) linking to this page in Textarea/HTML fields. #pw-group-traversal
|
||||
*
|
||||
@@ -149,6 +152,7 @@
|
||||
* @method string|mixed renderValue($value, $file) Returns rendered markup for $value using $file relative to templates/fields/. #pw-internal
|
||||
* @method PageArray references($selector = '', $field = '') Return pages that are pointing to this one by way of Page reference fields. #pw-group-traversal
|
||||
* @method PageArray links($selector = '', $field = '') Return pages that link to this one contextually in Textarea/HTML fields. #pw-group-traversal
|
||||
* @method string|mixed if($key, $yes, $no = '') If value is available for $key return or call $yes condition (with optional $no condition)
|
||||
*
|
||||
* Alias/alternate methods
|
||||
* -----------------------
|
||||
@@ -1220,18 +1224,34 @@ class Page extends WireData implements \Countable, WireMatchable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not $field is valid for this Page
|
||||
* Returns whether or not given $field name, ID or object is valid for this Page
|
||||
*
|
||||
* Note that this only indicates validity, not whether the field is populated.
|
||||
*
|
||||
* #pw-advanced
|
||||
*
|
||||
* @param int|string|Field $field Field name, object or ID to chck
|
||||
* @return bool True if valid, false if not.
|
||||
* @param int|string|Field|array $field Field name, object or ID to check.
|
||||
* - In 3.0.126+ this may also be an array or pipe "|" separated string of field names to check.
|
||||
* @return bool|string True if valid, false if not.
|
||||
* - In 3.0.126+ returns first matching field name if given an array of field names or pipe separated string of field names.
|
||||
*
|
||||
*/
|
||||
public function hasField($field) {
|
||||
return $this->template ? $this->template->fieldgroup->hasField($field) : false;
|
||||
if(!$this->template) return false;
|
||||
if(is_string($field) && strpos($field, '|') !== false) {
|
||||
$field = explode('|', $field);
|
||||
}
|
||||
if(is_array($field)) {
|
||||
$result = false;
|
||||
foreach($field as $f) {
|
||||
$f = trim($f);
|
||||
if(!empty($f) && $this->hasField($f)) $result = $f;
|
||||
if($result) break;
|
||||
}
|
||||
} else {
|
||||
$result = $this->template->fieldgroup->hasField($field);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1479,6 +1499,94 @@ class Page extends WireData implements \Countable, WireMatchable {
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* If value is available for $key return or call $yes condition (with optional $no condition)
|
||||
*
|
||||
* This merges the capabilities of an if() statement, get() and getMarkup() methods in one,
|
||||
* plus some useful PW type-specific logic, providing a useful output shortcut. It many situations
|
||||
* it enables you to accomplish on one-line of code what might have otherwise taken multiple lines
|
||||
* of code. Use this when looking for a useful shortcut and this one fits your need, otherwise
|
||||
* use a regular PHP if() statement.
|
||||
*
|
||||
* This function is primarily intended for conditionally outputting some formatted string value or
|
||||
* markup, however its use is not limited to that, as you can specify whatever you’d like for the
|
||||
* $yes and $no conditions. The examples section best describes potential usages of this method,
|
||||
* so I recommend looking at those before reading all the details of this method.
|
||||
*
|
||||
* Note that the logic is a little bit smarter for PW than a regular PHP if() statement in these ways:
|
||||
*
|
||||
* - If value resolves to any kind of *empty* `WireArray` (like a `PageArray`) the NO condition is used.
|
||||
* If the WireArray is populated with at least one item then the YES condition is used. So this if()
|
||||
* method (unlike PHP if) requires that not only is the value present, but it is also populated.
|
||||
*
|
||||
* - If value resolves to a `NullPage` the NO condition is used.
|
||||
*
|
||||
* The `$key` argument may be any of the following:
|
||||
*
|
||||
* - A field name, in which case we will use the value of that field on this page. If the value is
|
||||
* empty the NO condition will be used, otherwise the YES condition will be used. You can use any
|
||||
* format for the field name that the `Page::get()` method accepts, so subfields and OR field
|
||||
* statements are also okay, i.e. `categories.count`, `field1|field2|field3', etc.
|
||||
*
|
||||
* - A selector string that must match this page in order to return the YES condition. If it does not
|
||||
* match then the NO condition will be used.
|
||||
*
|
||||
* - A boolean, integer, digit string or PHP array. If considered empty by PHP it will return the NO
|
||||
* condition, otherwise it will return the YES condition.
|
||||
*
|
||||
* The `$yes` and `$no` arguments (the conditional actions) may be any of the following:
|
||||
*
|
||||
* - Any string value that you’d like (HTML markup is fine too).
|
||||
*
|
||||
* - A field name that is present on this page, or optionally the word “value” to refer to the field
|
||||
* specified in the `$key` argument. Either way, makes this method return the actual field value as it
|
||||
* exists on the page, rather than a string/markup version of it. Note that if this word (“value”) is
|
||||
* used for the argument then of course the `$key` argument must be a field name (not a selector string).
|
||||
*
|
||||
* - Any callable inline function that returns the value you want this function to return.
|
||||
*
|
||||
* - A string containing one or more `{field}` placeholders, where you replace “field” with a field name.
|
||||
* These are in turn populated by the `Page::getMarkup()` method. You can also use `{field.subfield}`
|
||||
* and `{field1|field2|field3}` type placeholder strings.
|
||||
*
|
||||
* - A string containing `{val}` or `{value}` where they will be replaced with the markup value of the
|
||||
* field name given in the $key argument.
|
||||
*
|
||||
* - If you omit the `$no` argument an empty string is assumed.
|
||||
*
|
||||
* - If you omit both the `$yes` and `$no` arguments, then boolean is assumed (true for yes, false for no),
|
||||
* which makes this method likewise return a boolean. The only real reason to do this would be to take
|
||||
* advantage of the method’s slightly different behavior than regular PHP if() statements (i.e. treating
|
||||
* empty WireArray or NullPage objects as false conditions).
|
||||
*
|
||||
* ~~~~~
|
||||
* // if summary is populated, output it in an paragraph
|
||||
* echo $page->if("summary", "<p class='summary'>{summary}</p>");
|
||||
*
|
||||
* // same as above, but shows you can specify {value} to assume field in $key arg
|
||||
* echo $page->if("summary", "<p class='summary'>{value}</p>");
|
||||
*
|
||||
* // if price is populated, format for output, otherwise ask them to call for price
|
||||
* echo $page->if("price", function($val) { return '$' . number_format($val); }, "Please call");
|
||||
*
|
||||
* // you can also use selector strings
|
||||
* echo $page->if("inventory>10", "In stock", "Limited availability");
|
||||
*
|
||||
* // output an <img> tag for the first image on the page, or blank if none
|
||||
* echo $page->if("images", function($val) { return "<img src='{$val->first->url}'>"; });
|
||||
* ~~~~~
|
||||
*
|
||||
* @param string|bool|int $key Name of field to check, selector string to evaluate, or boolean/int to evalute
|
||||
* @param string|callable|mixed $yes If value for $key is present, return or call this
|
||||
* @param string|callable|mixed $no If value for $key is empty, return or call this
|
||||
* @return mixed|string|bool
|
||||
* @since 3.0.126
|
||||
*
|
||||
*/
|
||||
public function ___if($key, $yes = '', $no = '') {
|
||||
return $this->comparison()->_if($this, $key, $yes, $no);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the markup value for a given field name or {tag} string
|
||||
@@ -1555,7 +1663,7 @@ class Page extends WireData implements \Countable, WireMatchable {
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Same as getMarkup() except returned value is plain text
|
||||
*
|
||||
|
@@ -39,6 +39,96 @@ class PageComparison {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* If value is available for $key return or call $yes condition (with optional $no condition)
|
||||
*
|
||||
* This merges the capabilities of an if() statement, get() and getMarkup() methods in one,
|
||||
* plus some useful PW type-specific logic, providing a useful output shortcut.
|
||||
*
|
||||
* See phpdoc in `Page::if()` for full details.
|
||||
*
|
||||
* @param Page $page
|
||||
* @param string|bool|int $key Name of field to check, selector string to evaluate, or boolean/int to evalute
|
||||
* @param string|callable|mixed $yes If value for $key is present, return or call this
|
||||
* @param string|callable|mixed $no If value for $key is empty, return or call this
|
||||
* @return mixed|string|bool
|
||||
* @since 3.0.126
|
||||
*
|
||||
*/
|
||||
public function _if(Page $page, $key, $yes = '', $no = '') {
|
||||
|
||||
/** @var Sanitizer $sanitizer */
|
||||
$sanitizer = $page->wire('sanitizer');
|
||||
|
||||
// if only given a key argument, we will be returning a boolean
|
||||
if($yes === '' && $no === '') list($yes, $no) = array(true, false);
|
||||
|
||||
if(is_bool($key) || is_int($key)) {
|
||||
// boolean or int
|
||||
$val = $key;
|
||||
$action = empty($val) ? $no : $yes;
|
||||
} else if(ctype_digit("$key")) {
|
||||
// integer or string value of Wire object
|
||||
$val = (int) $key;
|
||||
$action = empty($val) ? $no : $yes;
|
||||
} else if(!ctype_alnum("$key") && Selectors::stringHasOperator($key)) {
|
||||
// selector string
|
||||
$val = $page->matches($key) ? 1 : 0;
|
||||
$action = $val ? $yes : $no;
|
||||
} else {
|
||||
// field name or other format string accepted by $page->get()
|
||||
$val = $page->get($key);
|
||||
$action = empty($val) || ($val instanceof WireArray && !$val->count()) || $val instanceof NullPage ? $no : $yes;
|
||||
}
|
||||
|
||||
if(is_string($action)) {
|
||||
// action is a string
|
||||
$getValue = false;
|
||||
$tools = $sanitizer->getTextTools();
|
||||
if(($action === 'value' || $action === 'val') && !$page->template->fieldgroup->hasField($action)) {
|
||||
// implicit 'value' or 'val' maps back to name specified in $key argument
|
||||
$getValue = $key;
|
||||
}
|
||||
if(empty($action)) {
|
||||
$result = $action;
|
||||
|
||||
} else if($getValue) {
|
||||
$result = $page->get($getValue);
|
||||
|
||||
} else if($tools->hasPlaceholders($action)) {
|
||||
// action is a getMarkup() string
|
||||
$keyIsFieldName = $sanitizer->fieldName($key) === $key;
|
||||
$act = $action;
|
||||
// if value placeholders present, replace them with field name placeholders
|
||||
foreach(array('{value}', '{val}') as $tag) {
|
||||
// string with {val} or {value} has that tag replaced with the {field_name}
|
||||
if(strpos($action, $tag) === false) continue;
|
||||
// if val or value is actually the name of a field in the system, then do not override it
|
||||
if($page->hasField(trim($tag, '{}'))) continue;
|
||||
$action = str_replace($tag, ($keyIsFieldName ? '{' . $key . '}' : $val), $action);
|
||||
}
|
||||
$result = $act === $action || $tools->hasPlaceholders($action) ? $page->getMarkup($action) : $action;
|
||||
|
||||
} else if($sanitizer->fieldSubfield($action, -1) === $action && $page->hasField($sanitizer->fieldSubfield($action, 0))) {
|
||||
// action is another field name that we want to get the value for
|
||||
$result = $page->get($action);
|
||||
} else {
|
||||
// action is just a string to return
|
||||
$result = $action;
|
||||
}
|
||||
|
||||
} else if(is_callable($action)) {
|
||||
// action is callable
|
||||
$result = call_user_func_array($action, array($val, $key, $page));
|
||||
|
||||
} else {
|
||||
// action is a number, array or object
|
||||
$result = $action;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a Selectors object or a selector string, return whether this Page matches it
|
||||
*
|
||||
|
Reference in New Issue
Block a user