From c01c44186ed7deaa5db065da95afc67f472bf8bf Mon Sep 17 00:00:00 2001 From: Ryan Cramer Date: Fri, 25 Feb 2022 11:26:31 -0500 Subject: [PATCH] Update Field getFieldgroups() and getTemplates() methods to pull from DB rather than API (to avoid loading all templates/fieldgroups) and move the code from Field class into Fields class. --- wire/core/Field.php | 46 +----------------- wire/core/Fields.php | 111 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+), 44 deletions(-) diff --git a/wire/core/Field.php b/wire/core/Field.php index 5df22252..2ef62901 100644 --- a/wire/core/Field.php +++ b/wire/core/Field.php @@ -914,29 +914,7 @@ class Field extends WireData implements Saveable, Exportable { * */ public function getFieldgroups($getCount = false) { - - $fieldgroups = $this->wire()->fieldgroups; - $items = $getCount ? null : $this->wire(new FieldgroupsArray()); /** @var FieldgroupsArray $items */ - $count = 0; - - /* - * note: all fieldgroups load on the foreach($fieldgroups) so this code doesn't seem necessary? - if($fieldgroups->useLazy()) { - $fieldgroups->loadLazyItemsByValue('fields_id', $this->settings['id']); - } - */ - - foreach($fieldgroups as $fieldgroup) { - foreach($fieldgroup as $field) { - if($field->id == $this->id) { - if($items) $items->add($fieldgroup); - $count++; - break; - } - } - } - - return $getCount ? $count : $items; + return $this->wire()->fields->getFieldgroups($this, $getCount); } /** @@ -949,29 +927,9 @@ class Field extends WireData implements Saveable, Exportable { * */ public function getTemplates($getCount = false) { - $templates = $this->wire()->templates; - if($getCount) { - $count = 0; - foreach($templates as $template) { - if($template->hasField($this)) $count++; - } - return $count; - } - /** @var TemplatesArray $items */ - $items = $this->wire(new TemplatesArray()); - $fieldgroups = $this->getFieldgroups(); - foreach($templates as $template) { - foreach($fieldgroups as $fieldgroup) { - if($template->fieldgroups_id == $fieldgroup->id) { - $items->add($template); - break; - } - } - } - return $items; + return $this->wire()->fields->getTemplates($this, $getCount); } - /** * Return the default value for this field (if set), or null otherwise. * diff --git a/wire/core/Fields.php b/wire/core/Fields.php index 091594a2..cf0a64c2 100644 --- a/wire/core/Fields.php +++ b/wire/core/Fields.php @@ -260,6 +260,7 @@ class Fields extends WireSaveableItems { * */ public function getAll() { + if($this->useLazy()) $this->loadAllLazyItems(); return $this->getWireArray(); } @@ -1310,6 +1311,116 @@ class Fields extends WireSaveableItems { if($this->tableTools === null) $this->tableTools = $this->wire(new FieldsTableTools()); return $this->tableTools; } + + /** + * Return the list of Fieldgroups using given field. + * + * #pw-internal + * + * @param Field|int|string Field to get fieldgroups for + * @param bool $getCount Get count rather than FieldgroupsArray? (default=false) 3.0.182+ + * @return FieldgroupsArray|int WireArray of Fieldgroup objects or count if requested + * + */ + public function getFieldgroups($field, $getCount = false) { + + $fieldId = $this->_fieldId($field); + $fieldgroups = $this->wire()->fieldgroups; + $items = $getCount ? null : $this->wire(new FieldgroupsArray()); /** @var FieldgroupsArray $items */ + $ids = array(); + $count = 0; + + $sql = "SELECT fieldgroups_id FROM fieldgroups_fields WHERE fields_id=:fields_id"; + $query = $this->wire()->database->prepare($sql); + $query->bindValue(':fields_id', $fieldId, \PDO::PARAM_INT); + $query->execute(); + + while($row = $query->fetch(\PDO::FETCH_NUM)) { + $id = (int) $row[0]; + $ids[$id] = $id; + } + + $query->closeCursor(); + + foreach($ids as $id) { + $fieldgroup = $fieldgroups->get($id); + if(!$fieldgroup) continue; + if($items) $items->add($fieldgroup); + $count++; + } + + return $getCount ? $count : $items; + } + + /** + * Return the list of of Templates using given field. + * + * #pw-internal + * + * @param Field|int|string Field to get templates for + * @param bool $getCount Get count rather than FieldgroupsArray? (default=false) + * @return TemplatesArray|int WireArray of Template objects or count when requested. + * @since 3.0.195 + * + */ + public function getTemplates($field, $getCount = false) { + + $fieldId = $this->_fieldId($field); + $templates = $this->wire()->templates; + $items = $getCount ? null : $this->wire(new TemplatesArray()); /** @var TemplatesArray $items */ + $count = 0; + $ids = array(); + + if(!$fieldId) return $items; + + $sql = + "SELECT fieldgroups_fields.fieldgroups_id, templates.id AS templates_id " . + "FROM fieldgroups_fields " . + "JOIN templates ON templates.fieldgroups_id=fieldgroups_fields.fieldgroups_id " . + "WHERE fieldgroups_fields.fields_id=:fields_id"; + + $query = $this->wire()->database->prepare($sql); + $query->bindValue(':fields_id', $fieldId, \PDO::PARAM_INT); + $query->execute(); + + while($row = $query->fetch(\PDO::FETCH_ASSOC)) { + $id = (int) $row['templates_id']; + $ids[$id] = $id; + } + + $query->closeCursor(); + + foreach($ids as $id) { + $template = $templates->get($id); + if(!$template) continue; + if($items) $items->add($template); + $count++; + } + + return $getCount ? $count : $items; + } + + /** + * Return field ID for given value (Field, field name, field ID) or 0 if none + * + * #pw-internal + * + * @param Field|string|int $field + * @return int + * @since 3.0.195 + * + */ + public function _fieldId($field) { + if($field instanceof Field) { + $fieldId = $field->id; + } else if(ctype_digit("$field")) { + $fieldId = (int) $field; + } else { + $field = $this->get($field); + $fieldId = $field ? $field->id : 0; + } + return $fieldId; + } }