mirror of
https://github.com/processwire/processwire.git
synced 2025-08-07 07:16:51 +02:00
Add PageFieldValueInterface as an implementation option for objects supporting page field values. Basically a helper for certain object-based values like Pagefiles/Pageimages, and likely others.
This commit is contained in:
@@ -15,6 +15,7 @@ namespace PHPSTORM_META {
|
||||
\wire('') => [
|
||||
'' == '@',
|
||||
'config' instanceof \ProcessWire\Config,
|
||||
'cache' instanceof \ProcessWire\WireCache,
|
||||
'wire' instanceof \ProcessWire\ProcessWire,
|
||||
'log' instanceof \ProcessWire\WireLog,
|
||||
'notices' instanceof \ProcessWire\Notices,
|
||||
@@ -46,6 +47,7 @@ namespace PHPSTORM_META {
|
||||
// this one does not appear to work, leaving in case someone knows how to make it work
|
||||
'' == '@',
|
||||
'config' instanceof \ProcessWire\Config,
|
||||
'cache' instanceof \ProcessWire\WireCache,
|
||||
'wire' instanceof \ProcessWire\ProcessWire,
|
||||
'log' instanceof \ProcessWire\WireLog,
|
||||
'notices' instanceof \ProcessWire\Notices,
|
||||
|
@@ -455,6 +455,56 @@ interface FieldtypeLanguageInterface {
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for objects that carry a Field value for a Page
|
||||
*
|
||||
* Optional, but enables Page to do some of the work rather than the Fieldtype
|
||||
*
|
||||
*/
|
||||
interface PageFieldValueInterface {
|
||||
|
||||
/**
|
||||
* Get or set formatted state
|
||||
*
|
||||
* @param bool|null $set Specify bool to set formatted state or omit to retrieve formatted state
|
||||
* @return bool
|
||||
*
|
||||
*/
|
||||
public function formatted($set = null);
|
||||
|
||||
/**
|
||||
* Set the Page
|
||||
*
|
||||
* @param Page $page
|
||||
*
|
||||
*/
|
||||
public function setPage(Page $page);
|
||||
|
||||
/**
|
||||
* Set the Field
|
||||
*
|
||||
* @param Field $field
|
||||
*
|
||||
*/
|
||||
public function setField(Field $field);
|
||||
|
||||
/**
|
||||
* Get the page or null if not set
|
||||
*
|
||||
* @return Page|null
|
||||
*
|
||||
*/
|
||||
public function getPage();
|
||||
|
||||
/**
|
||||
* Get the field or null if not set
|
||||
*
|
||||
* @return Field|null
|
||||
*
|
||||
*/
|
||||
public function getField();
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for tracking runtime events
|
||||
*
|
||||
|
@@ -630,8 +630,7 @@ class Page extends WireData implements \Countable, WireMatchable {
|
||||
$value2 = clone $value;
|
||||
$this->set($name, $value2); // commit cloned value
|
||||
// if value is Pagefiles, then tell it the new page
|
||||
if($value2 instanceof Pagefiles) $value2->setPage($this);
|
||||
|
||||
if($value2 instanceof PageFieldValueInterface) $value2->setPage($this);
|
||||
}
|
||||
$this->instanceID .= ".clone";
|
||||
if($track) $this->setTrackChanges(true);
|
||||
@@ -656,7 +655,7 @@ class Page extends WireData implements \Countable, WireMatchable {
|
||||
*
|
||||
* @param string $key Name of property to set
|
||||
* @param mixed $value Value to set
|
||||
* @return Page Reference to this Page
|
||||
* @return Page|WireData Reference to this Page
|
||||
* @see __set
|
||||
* @throws WireException
|
||||
*
|
||||
@@ -783,9 +782,9 @@ class Page extends WireData implements \Countable, WireMatchable {
|
||||
*
|
||||
* #pw-internal
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return $this
|
||||
* @param string $key Name of field/property to set
|
||||
* @param mixed $value Value to set
|
||||
* @return Page|WireData Returns reference to this page
|
||||
*
|
||||
*/
|
||||
public function setForced($key, $value) {
|
||||
@@ -804,7 +803,7 @@ class Page extends WireData implements \Countable, WireMatchable {
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param bool $load Should the existing value be loaded for change comparisons? (applicable only to non-autoload fields)
|
||||
* @return $this
|
||||
* @return Page|WireData Returns reference to this Page
|
||||
* @throws WireException
|
||||
*
|
||||
*/
|
||||
@@ -855,15 +854,24 @@ class Page extends WireData implements \Countable, WireMatchable {
|
||||
// retrieve old value first in case it's not autojoined so that change comparisons and save's work
|
||||
if($load && $this->isLoaded) $this->get($key);
|
||||
|
||||
} else if($this->outputFormatting && $field->type->formatValue($this, $field, $value) != $value) {
|
||||
// The field has been loaded or dereferenced from the API, and this field changes when formatters are applied to it.
|
||||
// There is a good chance they are trying to set a formatted value, and we don't allow this situation because the
|
||||
// possibility of data corruption is high. We set the Page::statusCorrupted status so that Pages::save() can abort.
|
||||
$this->set('status', $this->status | self::statusCorrupted);
|
||||
$corruptedFields = $this->get('_statusCorruptedFields');
|
||||
if(!is_array($corruptedFields)) $corruptedFields = array();
|
||||
$corruptedFields[$field->name] = $field->name;
|
||||
$this->set('_statusCorruptedFields', $corruptedFields);
|
||||
} else {
|
||||
// check if the field is corrupted
|
||||
$isCorrupted = false;
|
||||
if(is_object($value) && $value instanceof PageFieldValueInterface) {
|
||||
if($value->formatted()) $isCorrupted = true;
|
||||
} else if($this->outputFormatting && $field->type->formatValue($this, $field, $value) != $value) {
|
||||
$isCorrupted = true;
|
||||
}
|
||||
if($isCorrupted) {
|
||||
// The field has been loaded or dereferenced from the API, and this field changes when formatters are applied to it.
|
||||
// There is a good chance they are trying to set a formatted value, and we don't allow this situation because the
|
||||
// possibility of data corruption is high. We set the Page::statusCorrupted status so that Pages::save() can abort.
|
||||
$this->set('status', $this->status | self::statusCorrupted);
|
||||
$corruptedFields = $this->get('_statusCorruptedFields');
|
||||
if(!is_array($corruptedFields)) $corruptedFields = array();
|
||||
$corruptedFields[$field->name] = $field->name;
|
||||
$this->set('_statusCorruptedFields', $corruptedFields);
|
||||
}
|
||||
}
|
||||
|
||||
// isLoaded so sanitizeValue can determine if it can perform a typecast rather than a full sanitization (when helpful)
|
||||
@@ -1223,13 +1231,13 @@ class Page extends WireData implements \Countable, WireMatchable {
|
||||
// note: we do not store this blank value in the Page, so that
|
||||
// the real value can potentially be loaded later without output formatting
|
||||
$value = $field->type->getBlankValue($this, $field);
|
||||
return $field->type->formatValue($this, $field, $value);
|
||||
return $this->formatFieldValue($field, $value);
|
||||
}
|
||||
}
|
||||
|
||||
if(!is_null($value) && empty($selector)) {
|
||||
// if the non-filtered value is already loaded, return it
|
||||
return $this->outputFormatting ? $field->type->formatValue($this, $field, $value) : $value;
|
||||
return $this->formatFieldValue($field, $value);
|
||||
}
|
||||
|
||||
$track = $this->trackChanges();
|
||||
@@ -1261,8 +1269,40 @@ class Page extends WireData implements \Countable, WireMatchable {
|
||||
if(is_object($value) && $value instanceof Wire) $value->resetTrackChanges(true);
|
||||
if($track) $this->setTrackChanges(true);
|
||||
|
||||
return $this->formatFieldValue($field, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a value consistent with the page’s output formatting state
|
||||
*
|
||||
* This is primarily for use as a helper to the getFieldValue() method.
|
||||
*
|
||||
* @param Field $field
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*
|
||||
*/
|
||||
protected function formatFieldValue(Field $field, $value) {
|
||||
|
||||
$hasInterface = is_object($value) && $value instanceof PageFieldValueInterface;
|
||||
|
||||
return $this->outputFormatting ? $field->type->formatValue($this, $field, $value) : $value;
|
||||
if($hasInterface) {
|
||||
$value->setPage($this);
|
||||
$value->setField($field);
|
||||
}
|
||||
|
||||
if($this->outputFormatting) {
|
||||
// output formatting is enabled so return a formatted value
|
||||
$value = $field->type->formatValue($this, $field, $value);
|
||||
if($hasInterface) $value->formatted(true);
|
||||
|
||||
} else if($hasInterface && $value->formatted()) {
|
||||
// unformatted requested, and value is already formatted so load a fresh copy
|
||||
$this->__unset($field->name);
|
||||
$value = $this->getFieldValue($field->name);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2570,6 +2610,7 @@ class Page extends WireData implements \Countable, WireMatchable {
|
||||
*
|
||||
* @return string Returns page URL, for example: `/my-site/about/contact/`
|
||||
* @see Page::path(), Page::httpUrl(), Page::editUrl(), Page::localUrl()
|
||||
* @todo add $options support
|
||||
*
|
||||
*/
|
||||
public function url() {
|
||||
@@ -3099,7 +3140,7 @@ class Page extends WireData implements \Countable, WireMatchable {
|
||||
* - `true` (boolean): To return an array of status names (indexed by status number).
|
||||
* - `integer|string|array`: Status number(s) or status name(s) to set the current page status (same as $page->status = $value)
|
||||
* @param int|null $status If you specified `true` for first argument, optionally specify status value you want to use (if not the current).
|
||||
* @return int|array|$this If setting status, `$this` is returned. If getting status: current status or array of status names is returned.
|
||||
* @return int|array|Page If setting status, `$this` is returned. If getting status: current status or array of status names is returned.
|
||||
* @see Page::addStauts(), Page::removeStatus(), Page::hasStatus()
|
||||
*
|
||||
*/
|
||||
|
@@ -21,7 +21,7 @@
|
||||
* @property-read string $name Returns the filename without the path, same as the "basename" property.
|
||||
* @property-read string $hash Get a unique hash (for the page) representing this Pagefile.
|
||||
* @property-read string $tagsArray Get file tags as an array. #pw-group-tags @since 3.0.17
|
||||
* @property-read int $sort Sort order in database. #pw-group-other
|
||||
* @property int $sort Sort order in database. #pw-group-other
|
||||
* @property string $basename Returns the filename without the path.
|
||||
* @property string $description Value of the file’s description field (string), if enabled. Note you can also set this property directly.
|
||||
* @property string $tags Value of the file’s tags field (string), if enabled. #pw-group-tags
|
||||
@@ -159,7 +159,7 @@ class Pagefile extends WireData {
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return $this
|
||||
* @return Pagefile|WireData
|
||||
*
|
||||
*/
|
||||
public function set($key, $value) {
|
||||
|
@@ -50,7 +50,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
class Pagefiles extends WireArray {
|
||||
class Pagefiles extends WireArray implements PageFieldValueInterface {
|
||||
|
||||
/**
|
||||
* The Page object associated with these Pagefiles
|
||||
@@ -83,6 +83,14 @@ class Pagefiles extends WireArray {
|
||||
*
|
||||
*/
|
||||
protected $hookIDs = array();
|
||||
|
||||
/**
|
||||
* Whether or not this is a formatted value
|
||||
*
|
||||
* @var bool
|
||||
*
|
||||
*/
|
||||
protected $formatted = false;
|
||||
|
||||
/**
|
||||
* Construct a Pagefiles object
|
||||
@@ -161,7 +169,7 @@ class Pagefiles extends WireArray {
|
||||
*
|
||||
* #pw-internal
|
||||
*
|
||||
* @return WireArray
|
||||
* @return Pagefiles|WireArray
|
||||
*
|
||||
*/
|
||||
public function makeNew() {
|
||||
@@ -310,10 +318,13 @@ class Pagefiles extends WireArray {
|
||||
public function add($item) {
|
||||
|
||||
if(is_string($item)) {
|
||||
/** @var Pagefile $item */
|
||||
$item = $this->wire(new Pagefile($this, $item));
|
||||
}
|
||||
|
||||
return parent::add($item);
|
||||
/** @var Pagefiles $result */
|
||||
$result = parent::add($item);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -522,10 +533,11 @@ class Pagefiles extends WireArray {
|
||||
* @return $this
|
||||
*
|
||||
*/
|
||||
|
||||
public function trackChange($what, $old = null, $new = null) {
|
||||
if($this->field && $this->page) $this->page->trackChange($this->field->name);
|
||||
return parent::trackChange($what, $old, $new);
|
||||
/** @var Pagefiles $result */
|
||||
$result = parent::trackChange($what, $old, $new);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -677,13 +689,14 @@ class Pagefiles extends WireArray {
|
||||
* @return $this
|
||||
*
|
||||
*/
|
||||
|
||||
public function resetTrackChanges($trackChanges = true) {
|
||||
$this->unlinkQueue = array();
|
||||
if($this->page && $this->page->id && $this->field) {
|
||||
$this->page->untrackChange($this->field->name);
|
||||
}
|
||||
return parent::resetTrackChanges($trackChanges);
|
||||
/** @var Pagefiles $result */
|
||||
$result = parent::resetTrackChanges($trackChanges);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -696,6 +709,17 @@ class Pagefiles extends WireArray {
|
||||
//$this->page = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or set formatted state
|
||||
*
|
||||
* @param bool|null $set
|
||||
* @return bool
|
||||
*
|
||||
*/
|
||||
public function formatted($set = null) {
|
||||
if(is_bool($set)) $this->formatted = $set;
|
||||
return $this->formatted;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -26,7 +26,7 @@
|
||||
* ================
|
||||
* @method PageArray find() find($selectorString, array $options = array()) Find and return all pages matching the given selector string. Returns a PageArray. #pw-group-retrieval
|
||||
* @method bool save() save(Page $page) Save any changes made to the given $page. Same as : $page->save() Returns true on success. #pw-group-manipulation
|
||||
* @method bool saveField() saveField(Page $page, $field) Save just the named field from $page. Same as: $page->save('field') #pw-group-manipulation
|
||||
* @method bool saveField() saveField(Page $page, $field, array $options = array()) Save just the named field from $page. Same as: $page->save('field') #pw-group-manipulation
|
||||
* @method bool trash() trash(Page $page, $save = true) Move a page to the trash. If you have already set the parent to somewhere in the trash, then this method won't attempt to set it again. #pw-group-manipulation
|
||||
* @method bool restore(Page $page, $save = true) Restore a trashed page to its original location. #pw-group-manipulation
|
||||
* @method int emptyTrash() Empty the trash and return number of pages deleted. #pw-group-manipulation
|
||||
@@ -843,10 +843,11 @@ class Pages extends Wire {
|
||||
* #pw-internal
|
||||
*
|
||||
* @param Page $page
|
||||
* @return void
|
||||
*
|
||||
*/
|
||||
public function cache(Page $page) {
|
||||
return $this->cacher->cache($page);
|
||||
$this->cacher->cache($page);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1141,7 +1142,7 @@ class Pages extends Wire {
|
||||
*
|
||||
*/
|
||||
public function executeQuery(\PDOStatement $query, $throw = true, $maxTries = 3) {
|
||||
$this->wire('database')->execute($query, $throw, $maxTries);
|
||||
return $this->wire('database')->execute($query, $throw, $maxTries);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1152,7 +1153,7 @@ class Pages extends Wire {
|
||||
* When given an array, it calls $pages->getById($key);
|
||||
*
|
||||
* @param string|int|array $key
|
||||
* @return Page|PageArray
|
||||
* @return Page|Pages|PageArray
|
||||
*
|
||||
*/
|
||||
public function __invoke($key) {
|
||||
@@ -1262,7 +1263,9 @@ class Pages extends Wire {
|
||||
$str = "Saved page";
|
||||
if(count($changes)) $str .= " (Changes: " . implode(', ', $changes) . ")";
|
||||
$this->log($str, $page);
|
||||
$this->wire('cache')->maintenance($page);
|
||||
/** @var WireCache $cache */
|
||||
$cache = $this->wire('cache');
|
||||
$cache->maintenance($page);
|
||||
if($page->className() != 'Page') {
|
||||
$manager = $page->getPagesManager();
|
||||
if($manager instanceof PagesType) $manager->saved($page, $changes, $values);
|
||||
@@ -1395,7 +1398,9 @@ class Pages extends Wire {
|
||||
*/
|
||||
public function ___deleted(Page $page) {
|
||||
$this->log("Deleted page", $page);
|
||||
$this->wire('cache')->maintenance($page);
|
||||
/** @var WireCache $cache */
|
||||
$cache = $this->wire('cache');
|
||||
$cache->maintenance($page);
|
||||
if($page->className() != 'Page') {
|
||||
$manager = $page->getPagesManager();
|
||||
if($manager instanceof PagesType) $manager->deleted($page);
|
||||
|
@@ -66,6 +66,7 @@ class PagesLoaderCache extends Wire {
|
||||
* Cache the given page.
|
||||
*
|
||||
* @param Page $page
|
||||
* @return void
|
||||
*
|
||||
*/
|
||||
public function cache(Page $page) {
|
||||
|
Reference in New Issue
Block a user