4 * Load custom field data from storage.
6 * This query loads the data directly into the field objects and does not
7 * return it to the caller. It can bulk load data for any list of fields,
8 * even if they have different objects or object types.
10 final class PhabricatorCustomFieldStorageQuery
extends Phobject
{
12 private $fieldMap = array();
13 private $storageSources = array();
15 public function addFields(array $fields) {
16 assert_instances_of($fields, 'PhabricatorCustomField');
18 foreach ($fields as $field) {
19 $this->addField($field);
25 public function addField(PhabricatorCustomField
$field) {
26 $role_storage = PhabricatorCustomField
::ROLE_STORAGE
;
28 if (!$field->shouldEnableForRole($role_storage)) {
32 $storage = $field->newStorageObject();
33 $source_key = $storage->getStorageSourceKey();
35 $this->fieldMap
[$source_key][] = $field;
37 if (empty($this->storageSources
[$source_key])) {
38 $this->storageSources
[$source_key] = $storage;
44 public function execute() {
45 foreach ($this->storageSources
as $source_key => $storage) {
46 $fields = idx($this->fieldMap
, $source_key, array());
47 $this->loadFieldsFromStorage($storage, $fields);
51 private function loadFieldsFromStorage($storage, array $fields) {
52 // Only try to load fields which have a persisted object.
54 foreach ($fields as $key => $field) {
55 $object = $field->getObject();
56 $phid = $object->getPHID();
61 $loadable[$key] = $field;
65 $data = $storage->loadStorageSourceData($loadable);
70 foreach ($fields as $key => $field) {
71 if (array_key_exists($key, $data)) {
73 $field->setValueFromStorage($value);
74 $field->didSetValueFromStorage();
75 } else if (isset($loadable[$key])) {
76 // NOTE: We set this only if the object exists. Otherwise, we allow
77 // the field to retain any default value it may have.
78 $field->setValueFromStorage(null);
79 $field->didSetValueFromStorage();