diff --git a/wire/core/PageFinder.php b/wire/core/PageFinder.php index f9a00ce6..7084215d 100644 --- a/wire/core/PageFinder.php +++ b/wire/core/PageFinder.php @@ -106,6 +106,7 @@ class PageFinder extends Wire { 'returnAllColsOptions' => array( 'joinFields' => array(), // names of additional fields to join 'joinSortfield' => false, // include 'sortfield' in returned columns? (joined from pages_sortfields table) + 'joinPath' => false, // include the 'path' in returned columns (joined from pages_paths table, requires PagePaths module) 'getNumChildren' => false, // include 'numChildren' in returned columns? (sub-select from pages table) 'unixTimestamps' => false, // return dates as unix timestamps? ), @@ -1506,6 +1507,13 @@ class PageFinder extends Wire { if($opts['getNumChildren']) { $query->select('(SELECT COUNT(*) FROM pages AS children WHERE children.parent_id=pages.id) AS numChildren'); } + if($opts['joinPath']) { + if(!$this->wire()->modules->isInstalled('PagePaths')) { + throw new PageFinderException('Requested option for URL or path (joinPath) requires the PagePaths module be installed'); + } + $columns[] = 'pages_paths.path AS path'; + $query->leftjoin('pages_paths ON pages_paths.pages_id=pages.id'); + } if(!empty($opts['joinFields'])) { foreach($opts['joinFields'] as $joinField) { $joinField = $this->wire()->fields->get($joinField); diff --git a/wire/core/PagesRaw.php b/wire/core/PagesRaw.php index 22e653f1..2d40b20e 100644 --- a/wire/core/PagesRaw.php +++ b/wire/core/PagesRaw.php @@ -128,6 +128,12 @@ class PagesRawFinder extends Wire { */ protected $customFields = array(); + /** + * @var array + * + */ + protected $runtimeFields = array(); + /** * @var array * @@ -168,6 +174,14 @@ class PagesRawFinder extends Wire { */ protected $getAll = false; + /** + * Get/join the pages_paths table? + * + * @var bool + * + */ + protected $getPaths = false; + /** * IDs of pages to find, becomes array once known * @@ -250,7 +264,13 @@ class PagesRawFinder extends Wire { $this->getMultiple = false; } - if(!$this->getAll) { + if($this->getAll) { + if($this->wire()->modules->isInstalled('PagePaths')) { + $this->getPaths = true; + $this->runtimeFields['url'] = 'url'; + $this->runtimeFields['path'] = 'path'; + } + } else { // split request fields into nativeFields and customFields $this->splitFields(); } @@ -284,7 +304,7 @@ class PagesRawFinder extends Wire { $this->init($selector, $field, $options); // requested native pages table fields/properties - if(count($this->nativeFields) || $this->getAll) { + if(count($this->nativeFields) || $this->getAll || $this->getPaths) { // one or more native pages table column(s) requested $this->findNativeFields(); } @@ -383,6 +403,14 @@ class PagesRawFinder extends Wire { // @todo not yet supported $this->childrenFields[$fullName] = array($fieldName, $colName); + } else if($fullName === 'url' || $fullName === 'path') { + if($this->wire()->modules->isInstalled('PagePaths')) { + $this->runtimeFields[$fullName] = $fullName; + $this->getPaths = true; + } else { + $fails[] = "Property '$fullName' requires the PagePaths module be installed"; + } + } else if($fieldObject instanceof Field) { $this->customFields[$fieldName] = $fieldObject; if(!empty($colName)) { @@ -413,6 +441,10 @@ class PagesRawFinder extends Wire { $this->ids = array(); $allNatives = array(); $fails = array(); + $rootUrl = $this->wire()->config->urls->root; + $templates = $this->wire()->templates; + $templatesById = array(); + $getPaths = $this->getPaths; foreach($this->findIDs($this->selector, '*') as $row) { $id = (int) $row['id']; @@ -456,17 +488,33 @@ class PagesRawFinder extends Wire { } if(count($fails)) $this->unknownFieldsException($fails, 'column/field'); - - if(count($getNatives)) { - // remove any native data that is present but was not requested - foreach($this->values as $id => $row) { - foreach($row as $colName => $value) { - if(!isset($getNatives[$colName])) { - unset($this->values[$id][$colName]); + + if(!count($getNatives) && !$getPaths) return; + + // remove any native data that is present but was not requested and populate any runtime fields + foreach($this->values as $id => $row) { + $templateId = (int) $row['templates_id']; + foreach($row as $colName => $value) { + if($getPaths && $colName === 'path') { + // populate path and/or url runtime properties + if(!isset($templatesById[$templateId])) $templatesById[$templateId] = $templates->get($templateId); + $template = $templatesById[$templateId]; /** @var Template $template */ + $slash = $template->slashUrls ? '/' : ''; + $path = strlen($value) && $value !== '/' ? "$value$slash" : ''; + if(isset($this->runtimeFields['url'])) { + $this->values[$id]['url'] = $rootUrl . $path; } + if(isset($this->runtimeFields['path'])) { + $this->values[$id]['path'] = "/$path"; + } else { + unset($this->values[$id]['path']); + } + } else if(!isset($getNatives[$colName])) { + unset($this->values[$id][$colName]); } } } + } /** @@ -730,6 +778,7 @@ class PagesRawFinder extends Wire { $options = array_merge($this->options, $options); $options['verbose'] = $verbose; $options['indexed'] = true; + $options['joinPath'] = $this->getPaths; // if selector was just a page ID, return it in an id indexed array if(is_int($selector) || (is_string($selector) && ctype_digit($selector))) { @@ -754,15 +803,30 @@ class PagesRawFinder extends Wire { // convert selector to CSV string of page IDs $selector = implode(',', array_map('intval', $selector)); - + + $selects = array(); + $joins = array(); + $wheres = array("id IN($selector)"); + if($verbose === '*') { // get all columns - $sql = "SELECT * FROM pages WHERE id IN($selector)"; + $selects[] = 'pages.*'; } else { // get just base columns - $sql = "SELECT id, templates_id, parent_id FROM pages WHERE id IN($selector)"; + $selects = array('pages.id', 'pages.templates_id', 'pages.parent_id'); } + if($this->getPaths) { + $selects[] = 'pages_paths.path AS path'; + $joins[] = 'LEFT JOIN pages_paths ON pages_paths.pages_id=pages.id'; + } + + $sql = + "SELECT " . implode(', ', $selects) . " " . + "FROM pages " . + (count($joins) ? implode(' ', $joins) . " " : '') . + "WHERE " . implode(' ', $wheres); + $query = $this->wire()->database->prepare($sql); $query->execute(); $rows = array();