From 35e1f9217f8cfcc70cc006e27530b2d78b5ab899 Mon Sep 17 00:00:00 2001 From: Georgi Hristov Date: Wed, 5 Aug 2020 16:02:22 +0200 Subject: [PATCH] [update] accept Closure for Model:getFields filter and provide 'persisting' filter preset --- src/Model.php | 93 +++++++++++++++++------------------ src/Persistence/Sql/Query.php | 40 ++------------- 2 files changed, 50 insertions(+), 83 deletions(-) diff --git a/src/Model.php b/src/Model.php index 340acf4b24..2aa8108e2b 100644 --- a/src/Model.php +++ b/src/Model.php @@ -613,26 +613,49 @@ public function getFields($filter = null): array { if ($filter === null) { return $this->fields; - } elseif (is_string($filter)) { + } elseif (!is_array($filter)) { $filter = [$filter]; } - return array_filter($this->fields, function (Field $field, $name) use ($filter) { - // do not return fields outside of "only_fields" scope - if ($this->only_fields && !in_array($name, $this->only_fields, true)) { - return false; - } - foreach ($filter as $f) { - if ( - ($f === 'system' && $field->system) - || ($f === 'not system' && !$field->system) - || ($f === 'editable' && $field->isEditable()) - || ($f === 'visible' && $field->isVisible()) - ) { + $filterPresets = [ + 'system' => function (Field $field) { + return $this->isOnlyField($field->short_name) && $field->system; + }, + 'not system' => function (Field $field) { + return $this->isOnlyField($field->short_name) && !$field->system; + }, + 'editable' => function (Field $field) { + return $this->isOnlyField($field->short_name) && $field->isEditable(); + }, + 'visible' => function (Field $field) { + return $this->isOnlyField($field->short_name) && $field->isVisible(); + }, + 'persisting' => function (Field $field) { + if ($field->never_persist) { + return false; + } + + if (!$field->system) { + return $this->isOnlyField($field->short_name); + } + + return true; + }, + ]; + + return array_filter($this->fields, function (Field $field, $name) use ($filter, $filterPresets) { + foreach ($filter as $fx) { + if (!$fx instanceof \Closure) { + if (!isset($filterPresets[$fx])) { + throw (new Exception('Filter is not supported')) + ->addMoreInfo('filter', $fx); + } + + $fx = $filterPresets[$fx]; + } + + if ($fx($field, $name)) { return true; - } elseif (!in_array($f, ['system', 'not system', 'editable', 'visible'], true)) { - throw (new Exception('Filter is not supported')) - ->addMoreInfo('filter', $f); } } @@ -640,6 +663,11 @@ public function getFields($filter = null): array }, ARRAY_FILTER_USE_BOTH); } + public function isOnlyField($fieldName) + { + return !$this->only_fields || in_array($fieldName, $this->only_fields, true); + } + /** * Set field value. * @@ -1675,38 +1703,7 @@ public function export(array $fields = null, $key_field = null, $typecast_data = // prepare array with field names if ($fields === null) { - $fields = []; - - if ($this->only_fields) { - // Add requested fields first - foreach ($this->only_fields as $field) { - $f_object = $this->getField($field); - if ($f_object->never_persist) { - continue; - } - $fields[$field] = true; - } - - // now add system fields, if they were not added - foreach ($this->getFields() as $field => $f_object) { - if ($f_object->never_persist) { - continue; - } - if ($f_object->system && !isset($fields[$field])) { - $fields[$field] = true; - } - } - - $fields = array_keys($fields); - } else { - // Add all model fields - foreach ($this->getFields() as $field => $f_object) { - if ($f_object->never_persist) { - continue; - } - $fields[] = $field; - } - } + $fields = array_keys($this->getFields('persisting')); } // add key_field to array if it's not there diff --git a/src/Persistence/Sql/Query.php b/src/Persistence/Sql/Query.php index 90105cb31a..25590e7992 100644 --- a/src/Persistence/Sql/Query.php +++ b/src/Persistence/Sql/Query.php @@ -75,42 +75,12 @@ protected function initSelect($fields = null): void return; } - // add fields - if (is_array($fields)) { - // Set of fields is strictly defined for purposes of export, - // so we will ignore even system fields. - foreach ($fields as $fieldName) { - $this->addField($this->model->getField($fieldName)); - } - } elseif ($this->model->only_fields) { - $addedFields = []; - - // Add requested fields first - foreach ($this->model->only_fields as $fieldName) { - $field = $this->model->getField($fieldName); - if ($field->never_persist) { - continue; - } - $this->addField($field); - $addedFields[$fieldName] = true; - } + if (!is_array($fields)) { + $fields = array_keys($this->model->getFields('persisting')); + } - // now add system fields, if they were not added - foreach ($this->model->getFields() as $fieldName => $field) { - if ($field->never_persist) { - continue; - } - if ($field->system && !isset($addedFields[$fieldName])) { - $this->addField($field); - } - } - } else { - foreach ($this->model->getFields() as $fieldName => $field) { - if ($field->never_persist) { - continue; - } - $this->addField($field); - } + foreach ($fields as $fieldName) { + $this->addField($this->model->getField($fieldName)); } }