/** * Updates an entity with the posted data. * * @param $categoryName * @param $entityName * @param $instance * @param array $data * @return mixed */ function updateEntity($categoryName, $entityName, $instance, array $data) { // Start a transaction DB::connection()->getPdo()->beginTransaction(); $autoUpdaterService = new SharpEloquentAutoUpdaterService(); $instance = $autoUpdaterService->updateEntity($this, $categoryName, $entityName, $instance, $data); DB::connection()->getPdo()->commit(); return $instance; }
/** * Valuate the field */ public function valuate() { // First save the entity if new and transient (pivot creation would be impossible if entity has no ID) if (!$this->instance->getKey()) { $this->instance->save(); } $order = 0; $saved = []; if (is_array($this->itemsForm)) { $itemIdAttribute = $this->listFieldConfig->item_id_attribute ?: "id"; // Iterate items posted foreach ($this->itemsForm as $itemForm) { $item = null; $itemId = $itemForm[$itemIdAttribute]; if (Str::startsWith($itemId, "N_")) { // First test if there is a special hook method on the controller // that takes the precedence. Method name should be "create[$listKey]ListItem" $methodName = "create" . ucFirst(Str::camel($this->listKey)) . "ListItem"; if (method_exists($this->sharpRepository, $methodName)) { $item = $this->sharpRepository->{$methodName}($this->instance); } else { // Have to create this item : we can't use $entity->$listKey()->create([]), because // we don't want a ->save() call on the item (which could fail because of mandatory DB attribute) $item = $this->instance->{$this->listKey}()->getRelated()->newInstance([]); $item->setAttribute($this->instance->{$this->listKey}()->getPlainForeignKey(), $this->instance->{$this->listKey}()->getParentKey()); } } else { foreach ($this->instance->{$this->listKey} as $itemDb) { if ($itemDb->{$itemIdAttribute} == $itemId) { // DB item found $item = $itemDb; break; } } } if (!$item) { // Item can't be found and isn't new. It's an error. throw new InvalidArgumentException("Item [{$itemId}] can't be found."); } // Update item $methodName = "update" . ucFirst(Str::camel($this->listKey)) . "ListItem"; if (method_exists($this->sharpRepository, $methodName)) { $item = $this->sharpRepository->{$methodName}($this->instance, $item, $itemForm); } else { foreach ($itemForm as $attr => $value) { if ($attr == $itemIdAttribute) { // Id is not updatable continue; } // For other attributes: foreach ($this->listFieldConfig->item as $configListItemKey) { if ($configListItemKey == $attr) { $configListItemConfigAttr = $this->listFieldConfig->item->{$configListItemKey}; // Call the auto-updater updateField method $this->autoUpdater->updateField($item, $itemForm, $configListItemConfigAttr, $configListItemKey, $this->listKey); } } } } // Manage order if ($this->listFieldConfig->order_attribute) { if (Str::contains($this->listFieldConfig->order_attribute, "~")) { list($relation, $orderAttr) = explode('~', $this->listFieldConfig->order_attribute); $itemRelation = $item->{$relation}; $itemRelation->{$orderAttr} = $order; $itemRelation->save(); } else { $item->{$this->listFieldConfig->order_attribute} = $order; } $order++; } // Eloquent save $item->save(); // Keep reference of the item for deletions $saved[] = $item->{$itemIdAttribute}; } // Manage deletions of the non-present items foreach ($this->instance->{$this->listKey} as $itemDb) { if (!in_array($itemDb->{$itemIdAttribute}, $saved)) { $itemDb->delete(); } } } else { // No item sent. foreach ($this->instance->{$this->listKey} as $itemDb) { $itemDb->delete(); } } }
/** * Valuate the field */ public function valuate() { // First catch the DB instance $embeddedInstance = $this->instance->{$this->attr}; if ($embeddedInstance instanceof Collection) { // Embed-list case: we have to find the correct item $embeddedInstance = $this->findItem($embeddedInstance); } // Special cases: deletion, empty value if ($this->data == "__DELETE__" || $this->data == "") { // Deleted instance if ($embeddedInstance) { // We have to delete the embedded instance $embeddedInstance->delete(); } return null; } // Embed data is compressed: we have to decode it. $embeddedData = sharp_decode_embedded_entity_data($this->data); // First save the entity if new and transient (embed creation would be impossible if entity has no ID) if (!$this->instance->getKey()) { $this->instance->save(); } if (!$embeddedInstance) { // Embedded instance needs to be created. We test if there is a special hook method on the controller // that takes the precedence. Method name should be "create[key]Embed" $methodName = "create" . ucFirst(Str::camel($this->attr)) . "Embed"; if (method_exists($this->sharpRepository, $methodName)) { $embeddedInstance = $this->sharpRepository->{$methodName}($this->instance); } else { // Have to create this embedded instance: we can't use $entity->$attr()->create([]), because // we don't want a ->save() call on the object (which could fail because of mandatory DB attribute) $embeddedInstance = $this->instance->{$this->attr}()->getRelated()->newInstance([]); $embeddedInstance->setAttribute($this->instance->{$this->attr}()->getPlainForeignKey(), $this->instance->{$this->attr}()->getParentKey()); } } // Update embedded instance $autoUpdaterService = new SharpEloquentAutoUpdaterService(); return $autoUpdaterService->updateEntityWithConfig($this->sharpRepository, $this->embedFieldConfig, $embeddedInstance, $embeddedData, $this->callbackBeforeSave); }