mirror of
https://github.com/processwire/processwire.git
synced 2025-08-11 17:24:46 +02:00
Documentation updates to several core classes
This commit is contained in:
@@ -3,6 +3,10 @@
|
||||
/**
|
||||
* ProcessWire Notices
|
||||
*
|
||||
* #pw-summary Manages notifications in the ProcessWire admin, primarily for internal use.
|
||||
* #pw-use-constants
|
||||
* #pw-use-constructor
|
||||
*
|
||||
* Base class that holds a message, source class, and timestamp.
|
||||
* Contains notices/messages used by the application to the user.
|
||||
*
|
||||
@@ -28,6 +32,8 @@ abstract class Notice extends WireData {
|
||||
/**
|
||||
* Flag indicates the notice is a warning
|
||||
*
|
||||
* #pw-internal
|
||||
*
|
||||
* @deprecated use NoticeWarning instead.
|
||||
*
|
||||
*/
|
||||
@@ -46,7 +52,7 @@ abstract class Notice extends WireData {
|
||||
const logOnly = 16;
|
||||
|
||||
/**
|
||||
* Flag indicates the notice is allowed to contain markup and won't be automatically entity encoded
|
||||
* Flag indicates the notice is allowed to contain markup and won’t be automatically entity encoded
|
||||
*
|
||||
* Note: entity encoding is done by the admin theme at output time, which should detect this flag.
|
||||
*
|
||||
@@ -56,8 +62,8 @@ abstract class Notice extends WireData {
|
||||
/**
|
||||
* Create the Notice
|
||||
*
|
||||
* @param string $text
|
||||
* @param int $flags
|
||||
* @param string $text Notification text
|
||||
* @param int $flags Flags
|
||||
*
|
||||
*/
|
||||
public function __construct($text, $flags = 0) {
|
||||
@@ -69,6 +75,8 @@ abstract class Notice extends WireData {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the notice log
|
||||
*
|
||||
* @return string Name of log (basename)
|
||||
*
|
||||
*/
|
||||
@@ -111,21 +119,88 @@ class NoticeWarning extends Notice {
|
||||
|
||||
|
||||
/**
|
||||
* A class to contain multiple Notice instances, whether messages or errors
|
||||
* ProcessWire Notices
|
||||
*
|
||||
* #pw-summary A class to contain multiple Notice instances, whether messages, warnings or errors
|
||||
* #pw-body =
|
||||
* This class manages notices that have been sent by `Wire::message()`, `Wire::warning()` and `Wire::error()` calls.
|
||||
* The message(), warning() and error() methods are available on every `Wire` derived object. This class is primarily
|
||||
* for internal use in the admin. However, it may also be useful in some front-end contexts.
|
||||
* ~~~~~
|
||||
* // Adding a NoticeMessage using object syntax
|
||||
* $notices->add(new NoticeMessage("Hello World"));
|
||||
*
|
||||
* // Adding a NoticeMessage using regular syntax
|
||||
* $notices->message("Hello World");
|
||||
*
|
||||
* // Adding a NoticeWarning, and allow markup in it
|
||||
* $notices->message("Hello <strong>World</strong>", Notice::allowMarkup);
|
||||
*
|
||||
* // Adding a NoticeError that only appears if debug mode is on
|
||||
* $notices->error("Hello World", Notice::debug);
|
||||
* ~~~~~
|
||||
* Iterating and outputting Notices:
|
||||
* ~~~~~
|
||||
* foreach($notices as $notice) {
|
||||
* // skip over debug notices, if debug mode isn't active
|
||||
* if($notice->flags & Notice::debug && !$config->debug) continue;
|
||||
* // entity encode notices unless the allowMarkup flag is set
|
||||
* if($notice->flags & Notice::allowMarkup) {
|
||||
* $text = $notice->text;
|
||||
* } else {
|
||||
* $text = $sanitizer->entities($notice->text);
|
||||
* }
|
||||
* // output either an error, warning or message notice
|
||||
* if($notice instanceof NoticeError) {
|
||||
* echo "<p class='error'>$text</p>";
|
||||
* } else if($notice instanceof NoticeWarning) {
|
||||
* echo "<p class='warning'>$text</p>";
|
||||
* } else {
|
||||
* echo "<p class='message'>$text</p>";
|
||||
* }
|
||||
* }
|
||||
* ~~~~~
|
||||
*
|
||||
* #pw-body
|
||||
*
|
||||
*
|
||||
*/
|
||||
class Notices extends WireArray {
|
||||
|
||||
const logAllNotices = false; // for debugging/dev purposes
|
||||
|
||||
/**
|
||||
* #pw-internal
|
||||
*
|
||||
* @param mixed $item
|
||||
* @return bool
|
||||
*
|
||||
*/
|
||||
public function isValidItem($item) {
|
||||
return $item instanceof Notice;
|
||||
}
|
||||
|
||||
/**
|
||||
* #pw-internal
|
||||
*
|
||||
* @return Notice
|
||||
*
|
||||
*/
|
||||
public function makeBlankItem() {
|
||||
return $this->wire(new NoticeMessage(''));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a Notice object
|
||||
*
|
||||
* ~~~~
|
||||
* $notices->add(new NoticeError("An error occurred!"));
|
||||
* ~~~~
|
||||
*
|
||||
* @param Notice $item
|
||||
* @return $this
|
||||
*
|
||||
*/
|
||||
public function add($item) {
|
||||
|
||||
if($item->flags & Notice::debug) {
|
||||
@@ -178,6 +253,12 @@ class Notices extends WireArray {
|
||||
$this->wire('log')->save($item->getName(), $text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Are there NoticeError items present?
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
*/
|
||||
public function hasErrors() {
|
||||
$numErrors = 0;
|
||||
foreach($this as $notice) {
|
||||
@@ -186,6 +267,12 @@ class Notices extends WireArray {
|
||||
return $numErrors > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Are there NoticeWarning items present?
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
*/
|
||||
public function hasWarnings() {
|
||||
$numWarnings = 0;
|
||||
foreach($this as $notice) {
|
||||
@@ -199,6 +286,8 @@ class Notices extends WireArray {
|
||||
*
|
||||
* This enables us to safely print_r the string for debugging purposes
|
||||
*
|
||||
* #pw-internal
|
||||
*
|
||||
* @param array $a
|
||||
* @return array
|
||||
*
|
||||
|
@@ -14,6 +14,11 @@
|
||||
*
|
||||
* PageArray is returned by all API methods in ProcessWire that can return more than one page at once.
|
||||
* `$pages->find()` and `$page->children()` are common examples.
|
||||
*
|
||||
* The recommended way to create a new PageArray is to use the `$pages->newPageArray()` method:
|
||||
* ~~~~~
|
||||
* $pageArray = $pages->newPageArray();
|
||||
* ~~~~~
|
||||
* #pw-body
|
||||
*
|
||||
* ProcessWire 3.x, Copyright 2016 by Ryan Cramer
|
||||
|
@@ -7,6 +7,7 @@
|
||||
* #pw-summary-traversal For the most part you’ll want to traverse from the parent `Pagefiles` object than these methods.
|
||||
* #pw-summary-manipulation Remember to follow up any manipulations with a `$pages->save()` call.
|
||||
* #pw-summary-tags Be sure to see the `Pagefiles::getTag()` and `Pagesfiles::findTag()` methods, which enable you retrieve files by tag.
|
||||
* #pw-use-constructor
|
||||
* #pw-body =
|
||||
* Pagefile objects are contained by a `Pagefiles` object.
|
||||
* #pw-body
|
||||
@@ -50,6 +51,8 @@ class Pagefile extends WireData {
|
||||
/**
|
||||
* Reference to the owning collection of Pagefiles
|
||||
*
|
||||
* @var Pagefiles
|
||||
*
|
||||
*/
|
||||
protected $pagefiles;
|
||||
|
||||
|
@@ -6,6 +6,7 @@
|
||||
* #pw-summary Represents an image item attached to a page, typically via an Image Fieldtype.
|
||||
* #pw-summary-variations A variation refers to an image that is based upon another (like a resized or cropped version for example).
|
||||
* #pw-order-groups common,resize-and-crop,variations,other
|
||||
* #pw-use-constructor
|
||||
* #pw-body =
|
||||
* Pageimage objects are usually contained by a `Pageimages` object, which is a type of `Pagefiles` and `WireArray`.
|
||||
* In addition to the methods and properties below, you'll also want to look at `Pagefile` which this class inherits
|
||||
@@ -93,9 +94,14 @@ class Pageimage extends Pagefile {
|
||||
protected $error = '';
|
||||
|
||||
/**
|
||||
* Construct a new Pagefile
|
||||
* Construct a new Pageimage
|
||||
*
|
||||
* @param Pagefiles $pagefiles
|
||||
* ~~~~~
|
||||
* // Construct a new Pageimage, assumes that $page->images is a FieldtypeImage Field
|
||||
* $pageimage = new Pageimage($page->images, '/path/to/file.png');
|
||||
* ~~~~~
|
||||
*
|
||||
* @param Pageimages|Pagefiles $pagefiles
|
||||
* @param string $filename Full path and filename to this pagefile
|
||||
* @throws WireException
|
||||
*
|
||||
|
@@ -3,8 +3,15 @@
|
||||
/**
|
||||
* ProcessWire PagesType
|
||||
*
|
||||
* Provides an interface to the Pages class but specific to
|
||||
* a given page class/type, with predefined parent and template.
|
||||
* #pw-summary Provides an interface to the Pages class but specific to a given page class/type, with predefined parent and template.
|
||||
* #pw-body =
|
||||
* This class is primarily used by the core as an alternative to `$pages`, providing an API for other Page types like
|
||||
* `User`, `Role`, `Permission`, and `Language`. The `$users`, `$roles`, `$permissions` and `$languages` API variables
|
||||
* are all instances of `PagesType`. This class is typically not instantiated on its own and instead acts as a base class
|
||||
* which is extended.
|
||||
*
|
||||
* #pw-body
|
||||
* #pw-use-constructor
|
||||
*
|
||||
* ProcessWire 3.x, Copyright 2016 by Ryan Cramer
|
||||
* https://processwire.com
|
||||
@@ -83,6 +90,8 @@ class PagesType extends Wire implements \IteratorAggregate, \Countable {
|
||||
/**
|
||||
* Add one or more templates that this PagesType represents
|
||||
*
|
||||
* #pw-group-family
|
||||
*
|
||||
* @param array|int|string $templates Single or array of Template objects, IDs, or names
|
||||
*
|
||||
*/
|
||||
@@ -110,6 +119,8 @@ class PagesType extends Wire implements \IteratorAggregate, \Countable {
|
||||
/**
|
||||
* Add one or more of parents that this PagesType represents
|
||||
*
|
||||
* #pw-group-family
|
||||
*
|
||||
* @param array|int|string|Page $parents Single or array of Page objects, IDs, or paths
|
||||
*
|
||||
*/
|
||||
@@ -171,6 +182,8 @@ class PagesType extends Wire implements \IteratorAggregate, \Countable {
|
||||
/**
|
||||
* Is the given page a valid type for this class?
|
||||
*
|
||||
* #pw-internal
|
||||
*
|
||||
* @param Page $page
|
||||
* @return bool
|
||||
*
|
||||
@@ -233,9 +246,10 @@ class PagesType extends Wire implements \IteratorAggregate, \Countable {
|
||||
* Given a Selector string, return the Page objects that match in a PageArray.
|
||||
*
|
||||
* @param string $selectorString
|
||||
* @param array $options
|
||||
- findOne: apply optimizations for finding a single page and include pages with 'hidden' status
|
||||
* @param array $options Options to modify default behavior:
|
||||
* - `findOne` (bool): apply optimizations for finding a single page and include pages with 'hidden' status
|
||||
* @return PageArray
|
||||
* @see Pages::find()
|
||||
*
|
||||
*/
|
||||
public function find($selectorString, $options = array()) {
|
||||
@@ -301,13 +315,11 @@ class PagesType extends Wire implements \IteratorAggregate, \Countable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a page object and it's fields to database.
|
||||
* Save a page object and its fields to database.
|
||||
*
|
||||
* If the page is new, it will be inserted. If existing, it will be updated.
|
||||
*
|
||||
* This is the same as calling $page->save()
|
||||
*
|
||||
* If you want to just save a particular field in a Page, use $page->save($fieldName) instead.
|
||||
* - This is the same as calling $page->save()
|
||||
* - If the page is new, it will be inserted. If existing, it will be updated.
|
||||
* - If you want to just save a particular field in a Page, use `$page->save($fieldName)` instead.
|
||||
*
|
||||
* @param Page $page
|
||||
* @return bool True on success
|
||||
@@ -320,11 +332,11 @@ class PagesType extends Wire implements \IteratorAggregate, \Countable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Permanently delete a page and it's fields.
|
||||
* Permanently delete a page and its fields.
|
||||
*
|
||||
* Unlike trash(), pages deleted here are not restorable.
|
||||
* Unlike `$pages->trash()`, pages deleted here are not restorable.
|
||||
*
|
||||
* If you attempt to delete a page with children, and don't specifically set the $recursive param to True, then
|
||||
* If you attempt to delete a page with children, and don’t specifically set the `$recursive` argument to `true`, then
|
||||
* this method will throw an exception. If a recursive delete fails for any reason, an exception will be thrown.
|
||||
*
|
||||
* @param Page $page
|
||||
@@ -339,12 +351,12 @@ class PagesType extends Wire implements \IteratorAggregate, \Countable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new page with the given $name and returns the Page
|
||||
* Adds a new page with the given $name and returns it
|
||||
*
|
||||
* If they page has any other fields, they will not be populated, only the name will.
|
||||
* Returns a NullPage if error, such as a page of this type already existing with the same name.
|
||||
* - If the page has any other fields, they will not be populated, only the name will.
|
||||
* - Returns a `NullPage` on error, such as when a page of this type already exists with the same name/parent.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $name Name to use for the new page
|
||||
* @return Page|NullPage
|
||||
*
|
||||
*/
|
||||
@@ -376,31 +388,81 @@ class PagesType extends Wire implements \IteratorAggregate, \Countable {
|
||||
*
|
||||
* Only recommended for page types that don't contain a lot of pages.
|
||||
*
|
||||
* #pw-internal
|
||||
*
|
||||
*/
|
||||
public function getIterator() {
|
||||
return $this->find("id>0, sort=name");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the template used by this type (or first template if there are multiple)
|
||||
*
|
||||
* #pw-group-family
|
||||
*
|
||||
* @return Template
|
||||
*
|
||||
*/
|
||||
public function getTemplate() {
|
||||
return $this->template;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the templates (plural) used by this type
|
||||
*
|
||||
* #pw-group-family
|
||||
*
|
||||
* @return array|Template[] Array of Template objects indexed by template ID.
|
||||
*
|
||||
*/
|
||||
public function getTemplates() {
|
||||
return count($this->templates) ? $this->templates : array($this->template);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parent page ID used by this type (or first parent ID if there are multiple)
|
||||
*
|
||||
* #pw-group-family
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
*/
|
||||
public function getParentID() {
|
||||
return $this->parent_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parent page IDs used by this type
|
||||
*
|
||||
* #pw-group-family
|
||||
*
|
||||
* @return array Array of parent page IDs (integers)
|
||||
*
|
||||
*/
|
||||
public function getParentIDs() {
|
||||
return count($this->parents) ? $this->parents : array($this->parent_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parent Page object (or first parent Page object if there are multiple)
|
||||
*
|
||||
* #pw-group-family
|
||||
*
|
||||
* @return Page|NullPage
|
||||
*
|
||||
*/
|
||||
public function getParent() {
|
||||
return $this->wire('pages')->get($this->parent_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parent Page objects in a PageArray
|
||||
*
|
||||
* #pw-group-family
|
||||
*
|
||||
* @return PageArray
|
||||
*
|
||||
*/
|
||||
public function getParents() {
|
||||
if(count($this->parents)) {
|
||||
return $this->wire('pages')->getById($this->parents);
|
||||
@@ -412,16 +474,41 @@ class PagesType extends Wire implements \IteratorAggregate, \Countable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the PHP class name to use for Page objects of this type
|
||||
*
|
||||
* #pw-group-family
|
||||
*
|
||||
* @param string $class
|
||||
*
|
||||
*/
|
||||
public function setPageClass($class) {
|
||||
$this->pageClass = $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the PHP class name used by Page objects of this type
|
||||
*
|
||||
* #pw-group-family
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
public function getPageClass() {
|
||||
if($this->pageClass) return $this->pageClass;
|
||||
if($this->template && $this->template->pageClass) return $this->template->pageClass;
|
||||
return 'Page';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of pages in this type matching the given selector string
|
||||
*
|
||||
* @param string $selectorString Optional, if omitted then returns count of all pages of this type
|
||||
* @param array $options Options to modify default behavior (see $pages->count method for details)
|
||||
* @return int
|
||||
* @see Pages::count()
|
||||
*
|
||||
*/
|
||||
public function count($selectorString = '', array $options = array()) {
|
||||
if(empty($selectorString) && empty($options) && count($this->parents) == 1) {
|
||||
return $this->getParent()->numChildren();
|
||||
@@ -450,6 +537,8 @@ class PagesType extends Wire implements \IteratorAggregate, \Countable {
|
||||
/**
|
||||
* Hook called just before a page is saved
|
||||
*
|
||||
* #pw-hooker
|
||||
*
|
||||
* @param Page $page The page about to be saved
|
||||
* @return array Optional extra data to add to pages save query.
|
||||
*
|
||||
@@ -465,6 +554,8 @@ class PagesType extends Wire implements \IteratorAggregate, \Countable {
|
||||
* This is the same as Pages::save, except that it occurs before other save-related hooks (below),
|
||||
* Whereas Pages::save occurs after. In most cases, the distinction does not matter.
|
||||
*
|
||||
* #pw-hooker
|
||||
*
|
||||
* @param Page $page The page that was saved
|
||||
* @param array $changes Array of field names that changed
|
||||
* @param array $values Array of values that changed, if values were being recorded, see Wire::getChanges(true) for details.
|
||||
@@ -475,6 +566,8 @@ class PagesType extends Wire implements \IteratorAggregate, \Countable {
|
||||
/**
|
||||
* Hook called when a new page has been added
|
||||
*
|
||||
* #pw-hooker
|
||||
*
|
||||
* @param Page $page
|
||||
*
|
||||
*/
|
||||
@@ -483,6 +576,8 @@ class PagesType extends Wire implements \IteratorAggregate, \Countable {
|
||||
/**
|
||||
* Hook called when a page is about to be deleted, but before data has been touched
|
||||
*
|
||||
* #pw-hooker
|
||||
*
|
||||
* @param Page $page
|
||||
*
|
||||
*/
|
||||
@@ -491,6 +586,8 @@ class PagesType extends Wire implements \IteratorAggregate, \Countable {
|
||||
/**
|
||||
* Hook called when a page and it's data have been deleted
|
||||
*
|
||||
* #pw-hooker
|
||||
*
|
||||
* @param Page $page
|
||||
*
|
||||
*/
|
||||
|
@@ -1,45 +1,105 @@
|
||||
<?php namespace ProcessWire;
|
||||
|
||||
/**
|
||||
* ProcessWire API Bootstrap
|
||||
*
|
||||
* Initializes all the ProcessWire classes and prepares them for API use
|
||||
*
|
||||
* ProcessWire 3.x, Copyright 2016 by Ryan Cramer
|
||||
* https://processwire.com
|
||||
*
|
||||
* @todo: get language permissions to work with extra actions
|
||||
*
|
||||
*/
|
||||
|
||||
require_once(__DIR__ . '/boot.php');
|
||||
|
||||
/**
|
||||
* ProcessWire API bootstrap class
|
||||
* ProcessWire API Bootstrap
|
||||
*
|
||||
* Gets ProcessWire's API ready for use
|
||||
* #pw-summary Represents an instance of ProcessWire connected with a set of API variables.
|
||||
* #pw-summary-instances Methods for managing ProcessWire instances. Note that most of these methods are static.
|
||||
* #pw-use-constants
|
||||
* #pw-use-constructor
|
||||
* #pw-body =
|
||||
* This class boots a ProcessWire instance. The current ProcessWire instance is represented by the `$wire` API variable.
|
||||
* ~~~~~
|
||||
* // To create a new ProcessWire instance
|
||||
* $wire = new ProcessWire('/server/path/', 'https://hostname/url/');
|
||||
* ~~~~~
|
||||
* #pw-body
|
||||
*
|
||||
* ProcessWire 3.x, Copyright 2016 by Ryan Cramer
|
||||
* https://processwire.com
|
||||
*
|
||||
* @method init()
|
||||
* @method ready()
|
||||
* @method finished()
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
class ProcessWire extends Wire {
|
||||
|
||||
/**
|
||||
* Major version number
|
||||
*
|
||||
*/
|
||||
const versionMajor = 3;
|
||||
|
||||
/**
|
||||
* Minor version number
|
||||
*
|
||||
*/
|
||||
const versionMinor = 0;
|
||||
|
||||
/**
|
||||
* Reversion revision number
|
||||
*
|
||||
*/
|
||||
const versionRevision = 41;
|
||||
|
||||
/**
|
||||
* Version suffix string (when applicable)
|
||||
*
|
||||
*/
|
||||
const versionSuffix = '';
|
||||
|
||||
const indexVersion = 300; // required version for index.php file (represented by PROCESSWIRE define)
|
||||
/**
|
||||
* Minimum required index.php version, represented by the PROCESSWIRE define
|
||||
*
|
||||
*/
|
||||
const indexVersion = 300;
|
||||
|
||||
/**
|
||||
* Minimum required .htaccess file version
|
||||
*
|
||||
*/
|
||||
const htaccessVersion = 300;
|
||||
|
||||
const statusBoot = 0; // system is booting
|
||||
const statusInit = 2; // system and modules are initializing
|
||||
const statusReady = 4; // system and $page are ready
|
||||
const statusRender = 8; // $page's template is being rendered
|
||||
const statusFinished = 16; // request has been delivered
|
||||
const statusFailed = 1024; // request failed due to exception or 404
|
||||
/**
|
||||
* Status when system is booting
|
||||
*
|
||||
*/
|
||||
const statusBoot = 0;
|
||||
|
||||
/**
|
||||
* Status when system and modules are initializing
|
||||
*
|
||||
*/
|
||||
const statusInit = 2;
|
||||
|
||||
/**
|
||||
* Systus when system, $page and API variables are ready
|
||||
*
|
||||
*/
|
||||
const statusReady = 4;
|
||||
|
||||
/**
|
||||
* Status when the current $page’s template file is being rendered
|
||||
*
|
||||
*/
|
||||
const statusRender = 8;
|
||||
|
||||
/**
|
||||
* Status when the request has been fully delivered
|
||||
*
|
||||
*/
|
||||
const statusFinished = 16;
|
||||
|
||||
/**
|
||||
* Status when the request failed due to an Exception or 404
|
||||
*
|
||||
*/
|
||||
const statusFailed = 1024;
|
||||
|
||||
/**
|
||||
* Whether debug mode is on or off
|
||||
@@ -126,7 +186,7 @@ class ProcessWire extends Wire {
|
||||
if(is_string($config)) $config = self::buildConfig($config, $rootURL);
|
||||
if(!$config instanceof Config) throw new WireException("No configuration information available");
|
||||
|
||||
// this is reset in the $this->config() method based on current debug mode
|
||||
// this is reset in the $this->setConfig() method based on current debug mode
|
||||
ini_set('display_errors', true);
|
||||
error_reporting(E_ALL | E_STRICT);
|
||||
|
||||
@@ -145,7 +205,7 @@ class ProcessWire extends Wire {
|
||||
$this->wire('hooks', new WireHooks($this, $config), true);
|
||||
|
||||
$this->shutdown = $this->wire(new WireShutdown());
|
||||
$this->config($config);
|
||||
$this->setConfig($config);
|
||||
$this->load($config);
|
||||
|
||||
if($this->getNumInstances() > 1) {
|
||||
@@ -170,7 +230,7 @@ class ProcessWire extends Wire {
|
||||
* @param Config $config
|
||||
*
|
||||
*/
|
||||
protected function config(Config $config) {
|
||||
protected function setConfig(Config $config) {
|
||||
|
||||
$this->wire('config', $config, true);
|
||||
$this->wire($config->paths);
|
||||
@@ -277,7 +337,9 @@ class ProcessWire extends Wire {
|
||||
}
|
||||
|
||||
/**
|
||||
* Load's ProcessWire using the supplied Config and populates all API fuel
|
||||
* Load’s ProcessWire using the supplied Config and populates all API fuel
|
||||
*
|
||||
* #pw-internal
|
||||
*
|
||||
* @param Config $config
|
||||
* @throws WireDatabaseException|WireException on fatal error
|
||||
@@ -417,6 +479,8 @@ class ProcessWire extends Wire {
|
||||
/**
|
||||
* Hookable init for anyone that wants to hook immediately before any autoload modules initialized or after all modules initialized
|
||||
*
|
||||
* #pw-hooker
|
||||
*
|
||||
*/
|
||||
protected function ___init() {
|
||||
if($this->debug) Debug::timer('boot.modules.autoload.init');
|
||||
@@ -427,6 +491,8 @@ class ProcessWire extends Wire {
|
||||
/**
|
||||
* Hookable ready for anyone that wants to hook immediately before any autoload modules ready or after all modules ready
|
||||
*
|
||||
* #pw-hooker
|
||||
*
|
||||
*/
|
||||
protected function ___ready() {
|
||||
if($this->debug) Debug::timer('boot.modules.autoload.ready');
|
||||
@@ -439,6 +505,8 @@ class ProcessWire extends Wire {
|
||||
/**
|
||||
* Hookable ready for anyone that wants to hook when the request is finished
|
||||
*
|
||||
* #pw-hooker
|
||||
*
|
||||
*/
|
||||
protected function ___finished() {
|
||||
|
||||
@@ -514,6 +582,15 @@ class ProcessWire extends Wire {
|
||||
return parent::__call($method, $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an API variable
|
||||
*
|
||||
* #pw-internal
|
||||
*
|
||||
* @param string $name Optional API variable name
|
||||
* @return mixed|null|Fuel
|
||||
*
|
||||
*/
|
||||
public function fuel($name = '') {
|
||||
if(empty($name)) return $this->fuel;
|
||||
return $this->fuel->$name;
|
||||
@@ -540,6 +617,8 @@ class ProcessWire extends Wire {
|
||||
/**
|
||||
* Instance ID of this ProcessWire instance
|
||||
*
|
||||
* #pw-group-instances
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
*/
|
||||
@@ -550,6 +629,8 @@ class ProcessWire extends Wire {
|
||||
/**
|
||||
* Add a ProcessWire instance and return the instance ID
|
||||
*
|
||||
* #pw-group-instances
|
||||
*
|
||||
* @param ProcessWire $wire
|
||||
* @return int
|
||||
*
|
||||
@@ -564,6 +645,8 @@ class ProcessWire extends Wire {
|
||||
/**
|
||||
* Get all ProcessWire instances
|
||||
*
|
||||
* #pw-group-instances
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
*/
|
||||
@@ -574,6 +657,8 @@ class ProcessWire extends Wire {
|
||||
/**
|
||||
* Return number of instances
|
||||
*
|
||||
* #pw-group-instances
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
*/
|
||||
@@ -584,6 +669,8 @@ class ProcessWire extends Wire {
|
||||
/**
|
||||
* Get a ProcessWire instance by ID
|
||||
*
|
||||
* #pw-group-instances
|
||||
*
|
||||
* @param int|null $instanceID Omit this argument to return the current instance
|
||||
* @return null|ProcessWire
|
||||
*
|
||||
@@ -596,6 +683,8 @@ class ProcessWire extends Wire {
|
||||
/**
|
||||
* Get the current ProcessWire instance
|
||||
*
|
||||
* #pw-group-instances
|
||||
*
|
||||
* @return ProcessWire|null
|
||||
*
|
||||
*/
|
||||
@@ -610,6 +699,8 @@ class ProcessWire extends Wire {
|
||||
/**
|
||||
* Set the current ProcessWire instance
|
||||
*
|
||||
* #pw-group-instances
|
||||
*
|
||||
* @param ProcessWire $wire
|
||||
*
|
||||
*/
|
||||
@@ -620,6 +711,8 @@ class ProcessWire extends Wire {
|
||||
/**
|
||||
* Remove a ProcessWire instance
|
||||
*
|
||||
* #pw-group-instances
|
||||
*
|
||||
* @param ProcessWire $wire
|
||||
*
|
||||
*/
|
||||
@@ -634,7 +727,7 @@ class ProcessWire extends Wire {
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a Config object for booting ProcessWire
|
||||
* Static method to build a Config object for booting ProcessWire
|
||||
*
|
||||
* @param string $rootPath Path to root of installation where ProcessWire's index.php file is located.
|
||||
* @param string $rootURL Should be specified only for secondary ProcessWire instances.
|
||||
|
@@ -11,33 +11,62 @@
|
||||
* ProcessWire 3.x, Copyright 2016 by Ryan Cramer
|
||||
* https://processwire.com
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Selector maintains a single selector consisting of field name, operator, and value.
|
||||
* #pw-summary Selector maintains a single selector consisting of field name, operator, and value.
|
||||
*
|
||||
* Field and value may optionally be arrays, where are assumed to be OR values.
|
||||
* #pw-body =
|
||||
* - Serves as the base class for the different Selector types (`SelectorEqual`, `SelectorNotEqual`, `SelectorLessThan`, etc.)
|
||||
* - The constructor requires `$field` and `$value` properties which may either be an array or string.
|
||||
* An array indicates multiple items in an OR condition. Multiple items may also be specified by
|
||||
* pipe “|” separated strings.
|
||||
* - Operator is determined by the Selector class name, and thus may not be changed without replacing
|
||||
* the entire Selector.
|
||||
*
|
||||
* Serves as the base class for the different Selector types (seen below this class).
|
||||
* ~~~~~
|
||||
* // very basic usage example
|
||||
* // constructor takes ($field, $value) which can be strings or arrays
|
||||
* $s = new SelectorEqual('title', 'About Us');
|
||||
* // $page can be any kind of Wire-derived object
|
||||
* if($s->matches($page)) {
|
||||
* // $page has title "About Us"
|
||||
* }
|
||||
* ~~~~~
|
||||
* ~~~~~
|
||||
* // another usage example
|
||||
* $s = new SelectorContains('title|body|summary', 'foo|bar');
|
||||
* if($s->matches($page)) {
|
||||
* // the title, body or summary properties of $page contain either the text "foo" or "bar"
|
||||
* }
|
||||
* ~~~~~
|
||||
*
|
||||
* @property string|array $field Field or fields present in the selector (can be string or array) [1]
|
||||
* @property array $fields Fields that were present in selector (same as $field, but always array)
|
||||
* @property string $operator Operator used by the selector [2]
|
||||
* @property string|array $value Value or values present in the selector (can be string or array) [1]
|
||||
* @property array $values Values that were present in selector (same as $value, but always array)
|
||||
* @property bool $not Is this a NOT selector? (i.e. returns the opposite if what it would otherwise)
|
||||
* @property string|null $group Group name for this selector (if field was prepended with a "group_name@")
|
||||
* @property string $quote Type of quotes value was in, or blank if it was not quoted. One of: '"[{(
|
||||
* @property string $str String value of selector
|
||||
* @property null|bool $forceMatch When boolean, it forces match (true) or non-match (false).
|
||||
* ### List of core selector-derived classes
|
||||
*
|
||||
* [1] The $field and $value properties may either be an array or string. As a result, we recommend
|
||||
* accessing the $fields or $values properties (instead of $field or $value), because they are always
|
||||
* return an array.
|
||||
* - `SelectorEqual`
|
||||
* - `SelectorNotEqual`
|
||||
* - `SelectorGreaterThan`
|
||||
* - `SelectorLessThan`
|
||||
* - `SelectorGreaterThanEqual`
|
||||
* - `SelectorLessThanEqual`
|
||||
* - `SelectorContains`
|
||||
* - `SelectorContainsLike`
|
||||
* - `SelectorContainsWords`
|
||||
* - `SelectorStarts`
|
||||
* - `SelectorStartsLike`
|
||||
* - `SelectorEnds`
|
||||
* - `SelectorEndsLike`
|
||||
* - `SelectorBitwiseAnd`
|
||||
*
|
||||
* [2] Operator is determined by the Selector class name, and thus may not be changed without replacing
|
||||
* the entire Selector.
|
||||
* #pw-body
|
||||
*
|
||||
* @property array $fields Fields that were present in selector (same as $field, but always an array).
|
||||
* @property string|array $field Field or fields present in the selector (string if single, or array of strings if multiple). Preferable to use $fields property instead.
|
||||
* @property-read string $operator Operator used by the selector.
|
||||
* @property array $values Values that were present in selector (same as $value, but always array).
|
||||
* @property string|array $value Value or values present in the selector (string if single, or array of strings if multiple). Preferable to use $values property instead.
|
||||
* @property bool $not Is this a NOT selector? Indicates the selector returns the opposite if what it would otherwise. #pw-group-properties
|
||||
* @property string|null $group Group name for this selector (if field was prepended with a "group_name@"). #pw-group-properties
|
||||
* @property string $quote Type of quotes value was in, or blank if it was not quoted. One of: '"[{( #pw-group-properties
|
||||
* @property-read string $str String value of selector, i.e. “a=b”. #pw-group-properties
|
||||
* @property null|bool $forceMatch When boolean, it forces match (true) or non-match (false). (default=null) #pw-group-properties
|
||||
*
|
||||
*/
|
||||
abstract class Selector extends WireData {
|
||||
@@ -71,27 +100,112 @@ abstract class Selector extends WireData {
|
||||
$this->set('forceMatch', null); // boolean true to force match, false to force non-match
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the operator used by this Selector
|
||||
*
|
||||
* @return string
|
||||
* @since 3.0.42 Prior versions just supported the 'operator' property.
|
||||
*
|
||||
*/
|
||||
public function operator() {
|
||||
return self::getOperator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the field(s) of this Selector
|
||||
*
|
||||
* Note that if calling this as a property (rather than a method) it can return either a string or an array.
|
||||
*
|
||||
* @param bool|int $forceString Specify one of the following:
|
||||
* - `true` (bool): to only return a string, where multiple-fields will be split by pipe "|". (default)
|
||||
* - `false` (bool): to return string if 1 field, or array of multiple fields (same behavior as field property).
|
||||
* - `1` (int): to return only the first value (string).
|
||||
* @return string|array|null
|
||||
* @since 3.0.42 Prior versions only supported the 'field' property.
|
||||
* @see Selector::fields()
|
||||
*
|
||||
*/
|
||||
public function field($forceString = true) {
|
||||
$field = parent::get('field');
|
||||
if($forceString && is_array($field)) {
|
||||
if($forceString === 1) {
|
||||
$field = reset($field);
|
||||
} else {
|
||||
$field = implode('|', $field);
|
||||
}
|
||||
}
|
||||
return $field;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return array of field(s) for this Selector
|
||||
*
|
||||
* @return array
|
||||
* @see Selector::field()
|
||||
* @since 3.0.42 Prior versions just supported the 'fields' property.
|
||||
*
|
||||
*/
|
||||
public function fields() {
|
||||
$field = parent::get('field');
|
||||
if(is_array($field)) return $field;
|
||||
if(!strlen($field)) return array();
|
||||
return array($field);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value(s) of this Selector
|
||||
*
|
||||
* Note that if calling this as a property (rather than a method) it can return either a string or an array.
|
||||
*
|
||||
* @param bool|int $forceString Specify one of the following:
|
||||
* - `true` (bool): to only return a string, where multiple-values will be split by pipe "|". (default)
|
||||
* - `false` (bool): to return string if 1 value, or array of multiple values (same behavior as value property).
|
||||
* - `1` (int): to return only the first value (string).
|
||||
* @return string|array|null
|
||||
* @since 3.0.42 Prior versions only supported the 'value' property.
|
||||
* @see Selector::values()
|
||||
*
|
||||
*/
|
||||
public function value($forceString = true) {
|
||||
$value = parent::get('value');
|
||||
if($forceString && is_array($value)) {
|
||||
if($forceString === 1) {
|
||||
$value = reset($value);
|
||||
} else {
|
||||
$value = implode('|', $value);
|
||||
}
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return array of value(s) for this Selector
|
||||
*
|
||||
* @return array
|
||||
* @see Selector::value()
|
||||
* @since 3.0.42 Prior versions just supported the 'values' property.
|
||||
*
|
||||
*/
|
||||
public function values() {
|
||||
$values = parent::get('value');
|
||||
if(is_array($values)) return $values;
|
||||
if(!is_object($values) && !strlen($values)) return array();
|
||||
return array($values);
|
||||
}
|
||||
|
||||
public function get($key) {
|
||||
if($key == 'operator') return $this->getOperator();
|
||||
if($key == 'str') return $this->__toString();
|
||||
if($key == 'values') {
|
||||
$value = $this->value;
|
||||
if(is_array($value)) return $value;
|
||||
if(!is_object($value) && !strlen($value)) return array();
|
||||
return array($value);
|
||||
}
|
||||
if($key == 'fields') {
|
||||
$field = $this->field;
|
||||
if(is_array($field)) return $field;
|
||||
if(!strlen($field)) return array();
|
||||
return array($field);
|
||||
}
|
||||
if($key == 'values') return $this->values();
|
||||
if($key == 'fields') return $this->fields();
|
||||
return parent::get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the selector field(s), optionally forcing as string or array
|
||||
*
|
||||
* #pw-internal
|
||||
*
|
||||
* @param string $type Omit for automatic, or specify 'string' or 'array' to force return in that type
|
||||
* @return string|array
|
||||
* @throws WireException if given invalid type
|
||||
@@ -115,6 +229,8 @@ abstract class Selector extends WireData {
|
||||
* When the $type argument is not specified, this method may return a string, array or Selectors object.
|
||||
* A Selectors object is only returned if the value happens to contain an embedded selector.
|
||||
*
|
||||
* #pw-internal
|
||||
*
|
||||
* @param string $type Omit for automatic, or specify 'string' or 'array' to force return in that type
|
||||
* @return string|array|Selectors
|
||||
* @throws WireException if given invalid type
|
||||
@@ -161,6 +277,8 @@ abstract class Selector extends WireData {
|
||||
*
|
||||
* Strict standards don't let us make static abstract methods, so this one throws an exception if it's not reimplemented.
|
||||
*
|
||||
* #pw-internal
|
||||
*
|
||||
* @return string
|
||||
* @throws WireException
|
||||
*
|
||||
@@ -292,6 +410,8 @@ abstract class Selector extends WireData {
|
||||
/**
|
||||
* Add all individual selector types to the runtime Selectors
|
||||
*
|
||||
* #pw-internal
|
||||
*
|
||||
*/
|
||||
static public function loadSelectorTypes() {
|
||||
Selectors::addType(SelectorEqual::getOperator(), 'SelectorEqual');
|
||||
|
@@ -1,17 +1,40 @@
|
||||
<?php namespace ProcessWire;
|
||||
|
||||
require_once(PROCESSWIRE_CORE_PATH . "Selector.php");
|
||||
|
||||
/**
|
||||
* ProcessWire Selectors
|
||||
*
|
||||
* Processes a Selector string and can then be iterated to retrieve each resulting Selector object.
|
||||
* #pw-summary Processes a selector string into a WireArray of Selector objects.
|
||||
* #pw-summary-static-helpers Static helper methods useful in analyzing selector strings outside of this class.
|
||||
* #pw-body =
|
||||
* This Selectors class is used internally by ProcessWire to provide selector string (and array) matching throughout the core.
|
||||
*
|
||||
* ~~~~~
|
||||
* $selectors = new Selectors("sale_price|retail_price>100, currency=USD|EUR");
|
||||
* if($selectors->matches($page)) {
|
||||
* // selector string matches the given $page (which can be any Wire-derived item)
|
||||
* }
|
||||
* ~~~~~
|
||||
* ~~~~~
|
||||
* // iterate and display what's in this Selectors object
|
||||
* foreach($selectors as $selector) {
|
||||
* echo "<p>";
|
||||
* echo "Field(s): " . implode('|', $selector->fields) . "<br>";
|
||||
* echo "Operator: " . $selector->operator . "<br>";
|
||||
* echo "Value(s): " . implode('|', $selector->values) . "<br>";
|
||||
* echo "</p>";
|
||||
* }
|
||||
* ~~~~~
|
||||
* #pw-body
|
||||
*
|
||||
* @link https://processwire.com/api/selectors/ Official Selectors Documentation
|
||||
*
|
||||
* ProcessWire 3.x, Copyright 2016 by Ryan Cramer
|
||||
* https://processwire.com
|
||||
*
|
||||
*/
|
||||
|
||||
require_once(PROCESSWIRE_CORE_PATH . "Selector.php");
|
||||
|
||||
class Selectors extends WireArray {
|
||||
|
||||
/**
|
||||
@@ -104,6 +127,11 @@ class Selectors extends WireArray {
|
||||
/**
|
||||
* Set the selector string or array (if not set already from the constructor)
|
||||
*
|
||||
* ~~~~~
|
||||
* $selectors = new Selectors();
|
||||
* $selectors->init("sale_price|retail_price>100, currency=USD|EUR");
|
||||
* ~~~~~
|
||||
*
|
||||
* @param string|array $selector
|
||||
*
|
||||
*/
|
||||
@@ -120,6 +148,8 @@ class Selectors extends WireArray {
|
||||
/**
|
||||
* Set the selector string
|
||||
*
|
||||
* #pw-internal
|
||||
*
|
||||
* @param string $selectorStr
|
||||
*
|
||||
*/
|
||||
@@ -131,6 +161,8 @@ class Selectors extends WireArray {
|
||||
/**
|
||||
* Import items into this WireArray.
|
||||
*
|
||||
* #pw-internal
|
||||
*
|
||||
* @throws WireException
|
||||
* @param string|WireArray $items Items to import.
|
||||
* @return WireArray This instance.
|
||||
@@ -148,6 +180,8 @@ class Selectors extends WireArray {
|
||||
/**
|
||||
* Per WireArray interface, return true if the item is a Selector instance
|
||||
*
|
||||
* #pw-internal
|
||||
*
|
||||
* @param Selector $item
|
||||
* @return bool
|
||||
*
|
||||
@@ -159,6 +193,8 @@ class Selectors extends WireArray {
|
||||
/**
|
||||
* Per WireArray interface, return a blank Selector
|
||||
*
|
||||
* #pw-internal
|
||||
*
|
||||
*/
|
||||
public function makeBlankItem() {
|
||||
return $this->wire(new SelectorEqual('',''));
|
||||
@@ -170,6 +206,8 @@ class Selectors extends WireArray {
|
||||
* Static since there may be multiple instances of this Selectors class at runtime.
|
||||
* See Selector.php
|
||||
*
|
||||
* #pw-internal
|
||||
*
|
||||
* @param string $operator
|
||||
* @param string $class
|
||||
*
|
||||
@@ -185,6 +223,10 @@ class Selectors extends WireArray {
|
||||
/**
|
||||
* Return array of all valid operator characters
|
||||
*
|
||||
* #pw-group-static-helpers
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
*/
|
||||
static public function getOperatorChars() {
|
||||
return self::$operatorChars;
|
||||
@@ -193,6 +235,8 @@ class Selectors extends WireArray {
|
||||
/**
|
||||
* Does the given string have an operator in it?
|
||||
*
|
||||
* #pw-group-static-helpers
|
||||
*
|
||||
* @param string $str
|
||||
* @return bool
|
||||
*
|
||||
@@ -251,6 +295,8 @@ class Selectors extends WireArray {
|
||||
*
|
||||
* Meaning string starts with [field][operator] like "field="
|
||||
*
|
||||
* #pw-group-static-helpers
|
||||
*
|
||||
* @param string $str
|
||||
* @return bool
|
||||
*
|
||||
@@ -283,14 +329,18 @@ class Selectors extends WireArray {
|
||||
return $has;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new Selector object from a field name, operator, and value
|
||||
*
|
||||
* @param string $field
|
||||
* @param string $operator
|
||||
* @param string $value
|
||||
* @return Selector
|
||||
* This is mostly for internal use, as the Selectors object already does this when you pass it
|
||||
* a selector string in the constructor or init() method.
|
||||
*
|
||||
* #pw-group-advanced
|
||||
*
|
||||
* @param string $field Field name or names (separated by a pipe)
|
||||
* @param string $operator Operator, i.e. "="
|
||||
* @param string $value Value or values (separated by a pipe)
|
||||
* @return Selector Returns the correct type of `Selector` object that corresponds to the given `$operator`.
|
||||
* @throws WireException
|
||||
*
|
||||
*/
|
||||
@@ -614,6 +664,8 @@ class Selectors extends WireArray {
|
||||
/**
|
||||
* Given a value string with an "api_var" or "api_var.property" return the string value of the property
|
||||
*
|
||||
* #pw-internal
|
||||
*
|
||||
* @param string $value var or var.property
|
||||
* @return null|string Returns null if it doesn't resolve to anything or a string of the value it resolves to
|
||||
*
|
||||
@@ -635,6 +687,8 @@ class Selectors extends WireArray {
|
||||
*
|
||||
* By default this is true, so only need to call this method to disable variable parsing.
|
||||
*
|
||||
* #pw-internal
|
||||
*
|
||||
* @param bool $parseVars
|
||||
*
|
||||
*/
|
||||
@@ -645,6 +699,8 @@ class Selectors extends WireArray {
|
||||
/**
|
||||
* Does the given Selector value contain a parseable value?
|
||||
*
|
||||
* #pw-internal
|
||||
*
|
||||
* @param Selector $selector
|
||||
* @return bool
|
||||
*
|
||||
@@ -666,6 +722,8 @@ class Selectors extends WireArray {
|
||||
*
|
||||
* It is assumed the value was quoted in "[value]", and the quotes are not there now.
|
||||
*
|
||||
* #pw-internal
|
||||
*
|
||||
* @param string $value The value to evaluate
|
||||
* @return bool
|
||||
*
|
||||
@@ -758,6 +816,8 @@ class Selectors extends WireArray {
|
||||
/**
|
||||
* Create this Selectors object from an array
|
||||
*
|
||||
* #pw-internal
|
||||
*
|
||||
* @param array $a
|
||||
* @throws WireException
|
||||
*
|
||||
@@ -883,6 +943,7 @@ class Selectors extends WireArray {
|
||||
if(isset($data['value'])) throw new WireException("You may not specify both 'value' and 'find' at the same time");
|
||||
// if(!is_array($data['find'])) throw new WireException("Selector 'find' property must be specified as array");
|
||||
$find = $data['find'];
|
||||
$data['value'] = array();
|
||||
}
|
||||
|
||||
if(isset($data['whitelist']) && $data['whitelist'] !== null) {
|
||||
@@ -967,6 +1028,14 @@ class Selectors extends WireArray {
|
||||
$fields[] = $_name;
|
||||
}
|
||||
|
||||
// convert WireArray types to an array of $_values
|
||||
if(count($_values) === 1) {
|
||||
$value = reset($_values);
|
||||
if(is_object($value) && $value instanceof WireArray) {
|
||||
$_values = explode('|', (string) $value);
|
||||
}
|
||||
}
|
||||
|
||||
// determine value(s)
|
||||
foreach($_values as $value) {
|
||||
$_sanitize = $sanitize;
|
||||
@@ -1017,6 +1086,8 @@ class Selectors extends WireArray {
|
||||
* - If you need a literal comma, use a double comma ",,".
|
||||
* - If you need a literal equals, use a double equals "==".
|
||||
*
|
||||
* #pw-group-static-helpers
|
||||
*
|
||||
* @param string $s
|
||||
* @return array
|
||||
*
|
||||
@@ -1052,6 +1123,8 @@ class Selectors extends WireArray {
|
||||
/**
|
||||
* Given an assoc array, convert to a key=value selector-style string
|
||||
*
|
||||
* #pw-group-static-helpers
|
||||
*
|
||||
* @param $a
|
||||
* @return string
|
||||
*
|
||||
|
@@ -395,9 +395,7 @@ class Session extends Wire implements \IteratorAggregate {
|
||||
*/
|
||||
public function get($key, $_key = null) {
|
||||
if($key == 'CSRF') {
|
||||
if(!$this->sessionInit) $this->init(); // init required for CSRF
|
||||
if(is_null($this->CSRF)) $this->CSRF = $this->wire(new SessionCSRF());
|
||||
return $this->CSRF;
|
||||
return $this->CSRF();
|
||||
} else if(!is_null($_key)) {
|
||||
// namespace
|
||||
return $this->getFor($key, $_key);
|
||||
@@ -1133,4 +1131,32 @@ class Session extends Wire implements \IteratorAggregate {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance of ProcessWire’s CSRF object, which provides an API for cross site request forgery protection.
|
||||
*
|
||||
* ~~~~
|
||||
* // output somewhere in <form> markup when rendering a form
|
||||
* echo $session->CSRF->renderInput();
|
||||
* ~~~~
|
||||
* ~~~~
|
||||
* // when processing form (POST request), check to see if token is present
|
||||
* if($session->CSRF->hasValidToken()) {
|
||||
* // form submission is valid
|
||||
* // okay to process
|
||||
* } else {
|
||||
* // form submission is NOT valid
|
||||
* throw new WireException('CSRF check failed!');
|
||||
* }
|
||||
* ~~~~
|
||||
*
|
||||
* @return SessionCSRF
|
||||
* @see SessionCSRF::renderInput(), SessionCSRF::validate(), SessionCSRF::hasValidToken()
|
||||
*
|
||||
*/
|
||||
public function CSRF() {
|
||||
if(!$this->sessionInit) $this->init(); // init required for CSRF
|
||||
if(is_null($this->CSRF)) $this->CSRF = $this->wire(new SessionCSRF());
|
||||
return $this->CSRF;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -9,13 +9,37 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Triggered when CSRF detected
|
||||
* Exception triggered by SessionCSRF::validate() when CSRF detected
|
||||
*
|
||||
*/
|
||||
class WireCSRFException extends WireException {}
|
||||
|
||||
/**
|
||||
* ProcessWire CSRF Protection class
|
||||
* ProcessWire CSRF Protection
|
||||
*
|
||||
* #pw-summary Provides an API for cross site request forgery protection.
|
||||
* #pw-body =
|
||||
* ~~~~
|
||||
* // output somewhere in form markup when rendering a form
|
||||
* echo $session->CSRF->renderInput();
|
||||
* ~~~~
|
||||
* ~~~~
|
||||
* // when processing form (POST request), check to see if token is present
|
||||
* if($session->CSRF->hasValidToken()) {
|
||||
* // form submission is valid
|
||||
* // okay to process
|
||||
* } else {
|
||||
* // form submission is NOT valid
|
||||
* throw new WireException('CSRF check failed!');
|
||||
* }
|
||||
* ~~~~
|
||||
* ~~~~
|
||||
* // this alternative to hasValidToken() throws WireCSRFException when invalid
|
||||
* $session->CSRF->validate();
|
||||
* ~~~~
|
||||
*
|
||||
* #pw-body
|
||||
*
|
||||
*
|
||||
*/
|
||||
class SessionCSRF extends Wire {
|
||||
@@ -23,6 +47,8 @@ class SessionCSRF extends Wire {
|
||||
/**
|
||||
* Get a CSRF Token name, or create one if it doesn't yet exist
|
||||
*
|
||||
* #pw-group-initiating
|
||||
*
|
||||
* @param int|string|null $id Optional unique ID for this token
|
||||
* @return string
|
||||
*
|
||||
@@ -39,6 +65,8 @@ class SessionCSRF extends Wire {
|
||||
/**
|
||||
* Get a CSRF Token value as stored in the session, or create one if it doesn't yet exist
|
||||
*
|
||||
* #pw-group-initiating
|
||||
*
|
||||
* @param int|string|null $id Optional unique ID for this token
|
||||
* @return string
|
||||
*
|
||||
@@ -58,6 +86,8 @@ class SessionCSRF extends Wire {
|
||||
/**
|
||||
* Get a CSRF Token timestamp
|
||||
*
|
||||
* #pw-group-initiating
|
||||
*
|
||||
* @param int|string|null $id Optional unique ID for this token
|
||||
* @return string
|
||||
*
|
||||
@@ -71,6 +101,8 @@ class SessionCSRF extends Wire {
|
||||
/**
|
||||
* Get a CSRF Token name and value
|
||||
*
|
||||
* #pw-group-initiating
|
||||
*
|
||||
* @param int|string|null $id Optional unique ID for this token
|
||||
* @return array ("name" => "token name", "value" => "token value", "time" => created timestamp)
|
||||
*
|
||||
@@ -89,6 +121,8 @@ class SessionCSRF extends Wire {
|
||||
* Note that a single call to hasValidToken($id) or validate($id) will invalidate the single use token.
|
||||
* So call them once and store your result if you need the result multiple times.
|
||||
*
|
||||
* #pw-group-initiating
|
||||
*
|
||||
* @param int|string $id Optional unique ID/name for this token (of omitted one is generated automatically)
|
||||
* @return array ("id' => "token ID", "name" => "token name", "value" => "token value", "time" => created timestamp)
|
||||
*
|
||||
@@ -112,6 +146,8 @@ class SessionCSRF extends Wire {
|
||||
/**
|
||||
* Returns true if the current POST request contains a valid CSRF token, false if not
|
||||
*
|
||||
* #pw-group-validating
|
||||
*
|
||||
* @param int|string|null $id Optional unique ID for this token, but required if checking a single use token.
|
||||
* @return bool
|
||||
*
|
||||
@@ -140,6 +176,8 @@ class SessionCSRF extends Wire {
|
||||
/**
|
||||
* Throws an exception if the token is invalid
|
||||
*
|
||||
* #pw-group-validating
|
||||
*
|
||||
* @param int|string|null $id Optional unique ID for this token
|
||||
* @throws WireCSRFException if token not valid
|
||||
* @return bool Always returns true or throws exception
|
||||
@@ -155,6 +193,8 @@ class SessionCSRF extends Wire {
|
||||
/**
|
||||
* Clear out token value
|
||||
*
|
||||
* #pw-group-resetting
|
||||
*
|
||||
* @param int|string|null $id Optional unique ID for this token
|
||||
*
|
||||
*/
|
||||
@@ -167,6 +207,8 @@ class SessionCSRF extends Wire {
|
||||
/**
|
||||
* Clear out all saved token values
|
||||
*
|
||||
* #pw-group-resetting
|
||||
*
|
||||
*/
|
||||
public function resetAll() {
|
||||
$this->session->remove($this, true);
|
||||
@@ -175,6 +217,15 @@ class SessionCSRF extends Wire {
|
||||
/**
|
||||
* Render a form input[hidden] containing the token name and value, as looked for by hasValidToken()
|
||||
*
|
||||
* ~~~~~
|
||||
* <form method='post'>
|
||||
* <input type='submit'>
|
||||
* <?php echo $session->CSRF->renderInput(); ?>
|
||||
* </form>
|
||||
* ~~~~~
|
||||
*
|
||||
* #pw-group-initiating
|
||||
*
|
||||
* @param int|string|null $id Optional unique ID for this token
|
||||
* @return string
|
||||
*
|
||||
|
@@ -1,35 +1,63 @@
|
||||
<?php namespace ProcessWire;
|
||||
|
||||
/**
|
||||
* ProcessWire Database Backup and Restore
|
||||
*
|
||||
* #pw-summary ProcessWire Database Backup and Restore
|
||||
* #pw-body =
|
||||
* This class intentionally does not have any external dependencies (other than PDO)
|
||||
* so that it can be included by outside tools for restoring/exporting, with the main
|
||||
* example of that being the ProcessWire installer.
|
||||
*
|
||||
* The recommended way to access these backup methods is via the `$database` API variable
|
||||
* method `$database->backups()`, which returns a `WireDatabaseBackup` instance.
|
||||
*
|
||||
* ### Easy Initialization (recommended)
|
||||
* ~~~~~
|
||||
* $backup = $database->backups();
|
||||
* ~~~~~
|
||||
*
|
||||
* ### Manual Initialization (if you need it)
|
||||
* ~~~~~
|
||||
* // determine where backups will go (should NOT be web accessible)
|
||||
* $backupPath = $config->paths->assets . 'backups/';
|
||||
*
|
||||
* // create a new WireDatabaseBackup instance
|
||||
* $backup = new WireDatabaseBackup($backupPath);
|
||||
*
|
||||
* // Option 1: set the already-connected DB connection
|
||||
* $backup->setDatabase($this->database);
|
||||
*
|
||||
* // Option 2: OR provide a Config object that contains the DB connection info
|
||||
* $backup->setDatabaseConfig($this->config);
|
||||
*
|
||||
* ~~~~~
|
||||
* ### Backup the database
|
||||
* ~~~~~
|
||||
* $options = array(); // optional
|
||||
* $file = $backup->backup($options);
|
||||
* if($file) {
|
||||
* print_r($backup->notes());
|
||||
* } else {
|
||||
* print_r($backup->errors());
|
||||
* }
|
||||
* ~~~~~
|
||||
* Note: the `print_r()` function calls are just for demonstration and testing purposes. We are not suggesting
|
||||
* you actually do that except when testing.
|
||||
*
|
||||
* ### Restore a database
|
||||
* ~~~~~
|
||||
* $options = array(); // optional
|
||||
* $success = $backup->restore($file, $options);
|
||||
* if($success) {
|
||||
* print_r($backup->notes());
|
||||
* } else {
|
||||
* print_r($backup->errors());
|
||||
* }
|
||||
* ~~~~~
|
||||
* #pw-body
|
||||
*
|
||||
* ProcessWire 3.x, Copyright 2016 by Ryan Cramer
|
||||
* https://processwire.com
|
||||
*
|
||||
* USAGE
|
||||
*
|
||||
* Initialization
|
||||
* ==============
|
||||
* $backup = new WireDatabaseBackup('/path/to/backups/');
|
||||
* $backup->setDatabase($this->database); // optional, if omitted it will attempt it's own connection
|
||||
* $backup->setDatabaseConfig($this->config); // optional, only if setDatabase() was called
|
||||
*
|
||||
* Backup
|
||||
* ======
|
||||
* $file = $backup->backup([$options]);
|
||||
* if($file) print_r($backup->notes());
|
||||
* else print_r($backup->errors());
|
||||
*
|
||||
*
|
||||
* Restore
|
||||
* =======
|
||||
* $success = $backup->restore($file, [$options]);
|
||||
* if($success) print_r($backup->notes());
|
||||
* else print_r($backup->errors());
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -548,9 +576,26 @@ class WireDatabaseBackup {
|
||||
/**
|
||||
* Perform a database export/dump
|
||||
*
|
||||
* @param array $options See $backupOptions
|
||||
* @param array $options Options to modify default behavior:
|
||||
* - `filename` (string): filename for backup: default is to make a dated filename, but this can also be used (basename only, no path)
|
||||
* - `description` (string): optional description of this backup
|
||||
* - `tables` (array): if specified, export will only include these tables
|
||||
* - `user` (string): username to associate with the backup file (string), optional
|
||||
* - `excludeTables` (array): exclude creating or inserting into these tables
|
||||
* - `excludeCreateTables` (array): exclude creating these tables, but still export data
|
||||
* - `excludeExportTables` (array): exclude exporting data, but still create tables
|
||||
* - `whereSQL` (array): SQL conditions for export of individual tables [table => [SQL conditions]]. The `table` portion (index) may also be a full PCRE regexp, must start with `/` to be recognized as regex.
|
||||
* - `maxSeconds` (int): max number of seconds allowed for execution (default=1200)
|
||||
* - `allowDrop` (bool): use DROP TABLES statements before CREATE TABLE statements? (default=true)
|
||||
* - `allowUpdate` (bool): use UPDATE ON DUPLICATE KEY so that INSERT statements can UPDATE when rows already present (all tables). (default=false)
|
||||
* - `allowUpdateTables` (array): table names that will use UPDATE ON DUPLICATE KEY (does NOT require allowUpdate=true)
|
||||
* - `findReplace` (array): find and replace in row data during backup. Example: ['databass' => 'database']
|
||||
* - `findReplaceCreateTable` (array): find and replace in create table statements
|
||||
* Example: ['DEFAULT CHARSET=latin1;' => 'DEFAULT CHARSET=utf8;']
|
||||
* - `extraSQL` (array): additional SQL queries to append at the bottom. Example: ['UPDATE pages SET created=NOW()']
|
||||
* @return string Full path and filename of database export file, or false on failure.
|
||||
* @throws \Exception on fatal error
|
||||
* @see WireDatabaseBackup::restore()
|
||||
*
|
||||
*/
|
||||
public function backup(array $options = array()) {
|
||||
@@ -827,9 +872,17 @@ class WireDatabaseBackup {
|
||||
* Import a database SQL file that was created by this class
|
||||
*
|
||||
* @param string $filename Filename to restore, optionally including path (if no path, then path set to construct is assumed)
|
||||
* @param array $options See WireDatabaseBackup::$restoreOptions
|
||||
* @param array $options Options to modify default behavior:
|
||||
* - `tables` (array): table names to restore (empty=all)
|
||||
* - `allowDrop` (bool): allow DROP TABLE statements (default=true)
|
||||
* - `haltOnError` (bool): halt execution when an error occurs? (default=false)
|
||||
* - `maxSeconds` (int): max number of seconds allowed for execution (default=1200)
|
||||
* - `findReplace` (array): find and replace in row data. Example: ['databass' => 'database']
|
||||
* - `findReplaceCreateTable` (array): find and replace in create table statements.
|
||||
* Example: ['DEFAULT CHARSET=utf8;' => 'DEFAULT CHARSET=utf8mb4;']
|
||||
* @return true on success, false on failure. Call the errors() method to retrieve errors.
|
||||
* @throws \Exception on fatal error
|
||||
* @see WireDatabaseBackup::backup()
|
||||
*
|
||||
*/
|
||||
public function restore($filename, array $options = array()) {
|
||||
|
@@ -733,13 +733,13 @@ class WireDatabasePDO extends Wire implements WireDatabase {
|
||||
/**
|
||||
* Retrieve new instance of WireDatabaseBackups ready to use with this connection
|
||||
*
|
||||
* See WireDatabaseBackup class for usage.
|
||||
* See `WireDatabaseBackup` class for usage.
|
||||
*
|
||||
* #pw-group-custom
|
||||
*
|
||||
* @return WireDatabaseBackup
|
||||
* @throws WireException|\Exception on fatal error
|
||||
* @see WireDatabaseBackup
|
||||
* @see WireDatabaseBackup::backup(), WireDatabaseBackup::restore()
|
||||
*
|
||||
*/
|
||||
public function backups() {
|
||||
|
@@ -6,6 +6,17 @@
|
||||
* Provides capability for sending POST/GET requests to URLs
|
||||
*
|
||||
* #pw-summary WireHttp enables you to send HTTP requests to URLs, download files, and more.
|
||||
* #pw-body =
|
||||
* ~~~~~
|
||||
* $http = new WireHttp();
|
||||
* $response = $http->get("http://domain.com/path/");
|
||||
* if($response !== false) {
|
||||
* echo "Successful response: " . $sanitizer->entities($response);
|
||||
* } else {
|
||||
* echo "HTTP request failed: " . $http->getError();
|
||||
* }
|
||||
* ~~~~~
|
||||
* #pw-body
|
||||
*
|
||||
* Thanks to @horst for his assistance with several methods in this class.
|
||||
*
|
||||
@@ -219,7 +230,7 @@ class WireHttp extends Wire {
|
||||
* $response = $http->post("http://domain.com/path/", [
|
||||
* 'foo' => bar',
|
||||
* ]);
|
||||
* if($response) {
|
||||
* if($response !== false) {
|
||||
* echo "Successful response: " . $sanitizer->entities($response);
|
||||
* } else {
|
||||
* echo "HTTP request failed: " . $http->getError();
|
||||
@@ -244,7 +255,7 @@ class WireHttp extends Wire {
|
||||
* $response = $http->get("http://domain.com/path/", [
|
||||
* 'foo' => 'bar',
|
||||
* ]);
|
||||
* if($response) {
|
||||
* if($response !== false) {
|
||||
* echo "Successful response: " . $sanitizer->entities($response);
|
||||
* } else {
|
||||
* echo "HTTP request failed: " . $http->getError();
|
||||
|
Reference in New Issue
Block a user