From 76a15a2539d3d7d19a6471bf5f66152adab10a2d Mon Sep 17 00:00:00 2001 From: Ryan Cramer Date: Fri, 18 May 2018 15:07:24 -0400 Subject: [PATCH] Some other tweaks to Fieldtype and FieldtypeComments and bump version to 3.0.103 --- wire/core/Field.php | 6 ++ wire/core/Fieldtype.php | 32 +++++++ wire/core/ProcessWire.php | 2 +- .../FieldtypeComments.module | 96 ++++++++++++++++--- 4 files changed, 124 insertions(+), 12 deletions(-) diff --git a/wire/core/Field.php b/wire/core/Field.php index c0875c19..5a7113e4 100644 --- a/wire/core/Field.php +++ b/wire/core/Field.php @@ -341,6 +341,11 @@ class Field extends WireData implements Saveable, Exportable { * */ public function get($key) { + if($key === 'type' && isset($this->settings['type'])) { + $value = $this->settings['type']; + if($value) $value->setLastAccessField($this); + return $value; + } if($key == 'viewRoles') return $this->viewRoles; else if($key == 'editRoles') return $this->editRoles; else if($key == 'table') return $this->getTable(); @@ -1010,6 +1015,7 @@ class Field extends WireData implements Saveable, Exportable { } $inputfields->attr('title', $this->_('Input')); $inputfields->attr('id+name', 'inputfieldConfig'); + /** @var InputfieldWrapper $inputfieldInputfields */ $inputfieldInputfields = $inputfield->getConfigInputfields(); if(!$inputfieldInputfields) $inputfieldInputfields = $this->wire(new InputfieldWrapper()); $configArray = $inputfield->getConfigArray(); diff --git a/wire/core/Fieldtype.php b/wire/core/Fieldtype.php index 93272dcb..7660792f 100644 --- a/wire/core/Fieldtype.php +++ b/wire/core/Fieldtype.php @@ -77,6 +77,14 @@ abstract class Fieldtype extends WireData implements Module { */ protected $loadPageFieldFilters = null; + /** + * Field that last referenced this Fieldtype from $field->type + * + * @var Field|null + * + */ + protected $lastAccessField = null; + /** * Construct * @@ -91,6 +99,30 @@ abstract class Fieldtype extends WireData implements Module { */ public function init() { } + /** + * Set last access field + * + * #pw-internal + * + * @param Field $field + * + */ + public function setLastAccessField(Field $field) { + $this->lastAccessField = $field; + } + + /** + * Return field that last accessed this Fieldtype via $field->type + * + * #pw-internal + * + * @return null|Field + * + */ + public function getLastAccessField() { + return $this->lastAccessField; + } + /** * Fieldtype modules are singular, in that only one instance is needed per request * diff --git a/wire/core/ProcessWire.php b/wire/core/ProcessWire.php index d82f701b..c48e2a0c 100644 --- a/wire/core/ProcessWire.php +++ b/wire/core/ProcessWire.php @@ -45,7 +45,7 @@ class ProcessWire extends Wire { * Reversion revision number * */ - const versionRevision = 102; + const versionRevision = 103; /** * Version suffix string (when applicable) diff --git a/wire/modules/Fieldtype/FieldtypeComments/FieldtypeComments.module b/wire/modules/Fieldtype/FieldtypeComments/FieldtypeComments.module index 3125b729..94be8867 100644 --- a/wire/modules/Fieldtype/FieldtypeComments/FieldtypeComments.module +++ b/wire/modules/Fieldtype/FieldtypeComments/FieldtypeComments.module @@ -980,7 +980,7 @@ class FieldtypeComments extends FieldtypeMulti { * @param string $selectorString Selector string with query * @return CommentArray * @throws WireException - * @deprecated Use $field->type->find($field, $selectorString) instead. + * @deprecated Use $field->type->find($selectorString) instead. * */ static public function findComments($field, $selectorString) { @@ -990,20 +990,59 @@ class FieldtypeComments extends FieldtypeMulti { } /** - * Given a field and a selector, find all comments matching the selector (non-static version) + * Given a field and a selector, find all comments matching the selector * - * Note that if you don't specify a limit=n, it will default to a limit of 10 - * If you don't specify a sort, it will default to sort=-created + * - If you don’t specify a “limit=n”, it will default to a limit of 10. + * - If you don’t specify a sort, it will default to “sort=-created”. + * - Arguments may be optionally reversed (for backwards compatibility). + * + * Unlike $pages->find(), pagination of comments is not automatically tied to + * $input->pageNum(). As a result, if you paginate, you should specify both + * “start=n” and “limit=n” in your selector: + * + * ~~~~~~ + * $limit = 20; + * $start = ($input->pageNum() - 1) * $limit; + * $comments = $field->type->find("text%=something, start=$start, limit=$limit"); + * ~~~~~~ + * + * Please also note that this function returns comments without taking anything + * about the page they live on into account. As a result, it can return comments + * from unpublished or non-viewable pages. If you need this, check the returned + * results: + * + * ~~~~ + * $comments = $field->type->find('text%=something'); + * foreach($comments as $comment) { + * $p = $comment->getPage(); + * if(!$p->viewable()) $comments->remove($comment); + * } + * ~~~~ * - * @param Field|string Field object or name of field - * @param string $selectorString Selector string with query + * @param string|null $selectorString Selector string with query + * @param Field|string Optional Field object. If omitted, then it will be determined automatically. * @return CommentArray * @throws WireException + * + * @todo add an 'include=' property for matching based on page status + * @todo add support for page.native properties * */ - public function find($field, $selectorString) { - if(is_string($field)) $field = $this->wire('fields')->get($field); - if(!$field instanceof Field) throw new WireException('Arg 1 to find() must be a field'); + public function find($selectorString, $field = null) { + if($field !== null) { + if($selectorString instanceof Field || Selectors::stringHasSelector($field)) { + // arguments are reversed + $s = $selectorString; + $selectorString = $field; + $field = $s; + } + if(is_string($field)) $field = $this->wire('fields')->get($field); + } + if(!$field instanceof Field) $field = $this->getLastAccessField(); + if(!$field instanceof Field) $field = $this->getCommentsFields(true); + if(!$field instanceof Field) throw new WireException("Unable to determine comments field"); + + if($selectorString === null) $selectorString = ''; $intColumns = array( 'id', @@ -1044,12 +1083,14 @@ class FieldtypeComments extends FieldtypeMulti { $selectQuery->select("$table.*")->from($table)->where('id>0'); $countQuery->select('COUNT(*)')->from($table)->where('id>0'); - - $selectors = $this->wire(new Selectors($selectorString)); + + /** @var Selectors $selectors */ + $selectors = $selectorString instanceof Selectors ? $selectorString : $this->wire(new Selectors($selectorString)); $wheres = array(); $joins = array(); $leftJoins = array(); $binds = array(); + $status = null; $cnt = 0; foreach($selectors as $selector) { @@ -1069,6 +1110,15 @@ class FieldtypeComments extends FieldtypeMulti { $values = array($value); } + if($f === 'status') { + if(!ctype_digit($value)) { + if($value === 'approved') $value = Comment::statusApproved; + else if($value === 'pending') $value = Comment::statusPending; + else if($value === 'spam') $value = Comment::statusSpam; + } + $status = (int) $value; + } + if($f == 'page') $f = 'pages_id'; if($f == 'user') $f = 'created_users_id'; if(strpos($f, 'page.') === 0) $f = 'page_' . substr($f, 6); @@ -1153,6 +1203,11 @@ class FieldtypeComments extends FieldtypeMulti { } } } + + // if no status was specified and we’re on the front-end, match only approved comments + if($status === null && $this->wire('page')->template != 'admin') { + $wheres[] = "$table.status>=" . Comment::statusApproved; + } foreach($wheres as $where) { $selectQuery->where($where); @@ -1218,6 +1273,25 @@ class FieldtypeComments extends FieldtypeMulti { return $comments; } + /** + * Return comments field(s) + * + * @param bool $one Return only the first one found? (default=false) + * @return array|Field|null + * + */ + public function getCommentsFields($one = false) { + $fields = array(); + foreach($this->wire('fields') as $field) { + if($field->type instanceof FieldtypeComments) { + $fields[] = $field; + if($one) break; + } + } + if($one) return count($fields) ? $fields[0] : null; + return $fields; + } + /** * Given a comment code or subcode, return the associated comment ID or 0 if it doesn't exist *