1
0
mirror of https://github.com/processwire/processwire.git synced 2025-08-27 08:35:15 +02:00

Add new $pages->findJoin() method and $pages->find("selector, field=title|summary"); option that lets you specify which fields to autojoin in a page finding operation. Also added is an experimental PagesLoader::findMin() method that finds and loads pages in one query rather than splitting them out into separate find() and getById() calls. For now, we just use this method to handle the findJoin() and joinFields options, but may expand its use later. This commit also contains numerous performance optimizations to the Page class, and several updates to the PageFinder class to support the new autojoin options.

This commit is contained in:
Ryan Cramer
2021-02-05 11:28:48 -05:00
parent a697795c08
commit 7fe8e5f1fb
7 changed files with 757 additions and 328 deletions

View File

@@ -0,0 +1,230 @@
<?php namespace ProcessWire;
/**
* ProcessWire Page properties helper
*
* For static runtime property detection by the base Page class.
* The properties/methods in this class were originally in the base Page class
* but have been moved here for Page class load time optimization purposes.
* Except where indicated, please treat these properties as private to the
* Page class.
*
* ProcessWire 3.x, Copyright 2021 by Ryan Cramer
* https://processwire.com
*
*/
abstract class PageProperties {
/**
* Page class helper object instances (one of each helper per ProcessWire instance, lazy loaded)
*
* @var array
*
*/
public static $helpers = array();
/**
* Status string shortcuts, so that status can be specified as a word
*
* See also: Page::getStatuses() method.
*
* @var array
*
*/
public static $statuses = array(
'reserved' => Page::statusReserved,
'locked' => Page::statusLocked,
'systemID' => Page::statusSystemID,
'system' => Page::statusSystem,
'unique' => Page::statusUnique,
'draft' => Page::statusDraft,
'flagged' => Page::statusFlagged,
'internal' => Page::statusInternal,
'temp' => Page::statusTemp,
'hidden' => Page::statusHidden,
'unpublished' => Page::statusUnpublished,
'trash' => Page::statusTrash,
'deleted' => Page::statusDeleted,
'systemOverride' => Page::statusSystemOverride,
'corrupted' => Page::statusCorrupted,
'max' => Page::statusMax,
'on' => Page::statusOn,
);
/**
* Properties that can be accessed, mapped to method of access (excluding custom fields of course)
*
* Keys are base property name, values are one of:
* - [methodName]: method name that it maps to ([methodName]=actual method name)
* - "s": property name is accessible in $this->settings using same key
* - "p": Property name maps to same property name in $this
* - "m": Property name maps to same method name in $this
* - "n": Property name maps to same method name in $this, but may be overridden by custom field
* - "t": Property name maps to PageTraversal method with same name, if not overridden by custom field
* - [blank]: needs additional logic to be handled ([blank]='')
*
* @var array
*
*/
public static $baseProperties = array(
'accessTemplate' => 'getAccessTemplate',
'addable' => 'm',
'child' => 'm',
'children' => 'm',
'created' => 's',
'createdStr' => '',
'createdUser' => '',
'created_users_id' => 's',
'deletable' => 'm',
'deleteable' => 'm',
'editable' => 'm',
'editUrl' => 'm',
'fieldgroup' => '',
'filesManager' => 'm',
'filesPath' => 'm',
'filesUrl' => 'm',
'hasChildren' => 'm',
'hasFiles' => 'm',
'hasFilesPath' => 'm',
'hasLinks' => 't',
'hasParent' => 'parents',
'hasReferences' => 't',
'httpUrl' => 'm',
'id' => 's',
'index' => 'n',
'instanceID' => 'p',
'isHidden' => 'm',
'isLoaded' => 'm',
'isLocked' => 'm',
'isNew' => 'm',
'isPublic' => 'm',
'isTrash' => 'm',
'isUnpublished' => 'm',
'links' => 'n',
'listable' => 'm',
'modified' => 's',
'modifiedStr' => '',
'modifiedUser' => '',
'modified_users_id' => 's',
'moveable' => 'm',
'name' => 's',
'namePrevious' => 'p',
'next' => 'm',
'numChildren' => 's',
'numParents' => 'm',
'numDescendants' => 'm',
'numLinks' => 't',
'numReferences' => 't',
'output' => 'm',
'outputFormatting' => 'p',
'parent' => 'm',
'parent_id' => '',
'parentPrevious' => 'p',
'parents' => 'm',
'path' => 'm',
'prev' => 'm',
'publishable' => 'm',
'published' => 's',
'publishedStr' => '',
'quietMode' => 'p',
'references' => 'n',
'referencing' => 't',
'render' => '',
'rootParent' => 'm',
'siblings' => 'm',
'sort' => 's',
'sortable' => 'm',
'sortfield' => 's',
'status' => 's',
'statusPrevious' => 'p',
'statusStr' => '',
'template' => 'p',
'templates_id' => '',
'templatePrevious' => 'p',
'trashable' => 'm',
'url' => 'm',
'urls' => 'm',
'viewable' => 'm'
);
/**
* Alternate names accepted for base properties
*
* Keys are alternate property name and values are base property name
*
* @var array
*
*/
public static $basePropertiesAlternates = array(
'createdUserID' => 'created_users_id',
'createdUsersID' => 'created_users_id',
'created_user_id' => 'created_users_id',
'editURL' => 'editUrl',
'fields' => 'fieldgroup',
'has_parent' => 'hasParent',
'httpURL' => 'httpUrl',
'modifiedUserID' => 'modified_users_id',
'modifiedUsersID' => 'modified_users_id',
'modified_user_id' => 'modified_users_id',
'num_children' => 'numChildren',
'numChildrenVisible' => 'hasChildren',
'numVisibleChildren' => 'hasChildren',
'of' => 'outputFormatting',
'out' => 'output',
'parentID' => 'parent_id',
'subpages' => 'children',
'template_id' => 'templates_id',
'templateID' => 'templates_id',
'templatesID' => 'templates_id',
);
/**
* Method alternates/aliases (alias => actual)
*
* @var array
*
*/
public static $baseMethodAlternates = array(
'descendants' => 'find',
'descendant' => 'findOne',
);
/**
* Name and status language properties (populated by LanguagesSupport module when applicable)
*
* Keys are language property, values array where index 0 is property name and index 1 is language ID.
* ~~~~~
* [
* 'name1234' => [ 'name', 1234 ],
* 'status1234' => [ 'status', 1234 ],
* ...
* ]
* ~~~~~
*
* @var array|null
*
*/
public static $languageProperties = array();
/**
* Given a status (flags int) return array of status names
*
* @param int $status
* @return array
*
*/
public static function statusToNames($status) {
$names = array();
$remainder = $status;
foreach(self::$statuses as $name => $value) {
if($value <= Page::statusOn || $value >= Page::statusMax) continue;
if($status & $value) {
$names[$value] = $name;
$remainder = $remainder & ~$value;
}
}
if($remainder > 1) $names[$remainder] = "unknown-$remainder";
return $names;
}
}