repository = $repository; return $this; } /** * Return the target being worked with * * @return mixed */ protected function getBaseTable() { if ($this->baseTable === null) { return $this->repository->getBaseTable(); } return $this->baseTable; } /** * Return the name of the entry to handle * * @return string */ protected function getIdentifier() { return $this->identifier; } /** * Return the current data of the entry being handled * * @return array */ protected function getData() { return $this->data; } /** * Return whether an entry should be inserted * * @return bool */ public function shouldInsert() { return $this->mode === self::MODE_INSERT; } /** * Return whether an entry should be udpated * * @return bool */ public function shouldUpdate() { return $this->mode === self::MODE_UPDATE; } /** * Return whether an entry should be deleted * * @return bool */ public function shouldDelete() { return $this->mode === self::MODE_DELETE; } /** * Add a new entry * * @param array $data The defaults to use, if any * * @return $this */ public function add(array $data = null) { $this->mode = static::MODE_INSERT; $this->data = $data; return $this; } /** * Edit an entry * * @param string $name The entry's name * @param array $data The entry's current data * * @return $this */ public function edit($name, array $data = null) { $this->mode = static::MODE_UPDATE; $this->identifier = $name; $this->data = $data; return $this; } /** * Remove an entry * * @param string $name The entry's name * * @return $this */ public function remove($name) { $this->mode = static::MODE_DELETE; $this->identifier = $name; return $this; } /** * Fetch and return the entry to pre-populate the form with when in mode update * * @return false|object */ protected function fetchEntry() { return $this->repository ->select() ->from($this->getBaseTable()) ->applyFilter($this->createFilter()) ->fetchRow(); } /** * Return whether the entry supposed to be removed exists * * @return bool */ protected function entryExists() { $count = $this->repository ->select() ->from($this->getBaseTable()) ->addFilter($this->createFilter()) ->count(); return $count > 0; } /** * Insert the new entry */ protected function insertEntry() { $this->repository->insert($this->getBaseTable(), $this->getValues()); } /** * Update the entry */ protected function updateEntry() { $this->repository->update($this->getBaseTable(), $this->getValues(), $this->createFilter()); } /** * Delete the entry */ protected function deleteEntry() { $this->repository->delete($this->getBaseTable(), $this->createFilter()); } /** * Create and add elements to this form * * @param array $formData The data sent by the user */ public function createElements(array $formData) { if ($this->shouldInsert()) { $this->createInsertElements($formData); } elseif ($this->shouldUpdate()) { $this->createUpdateElements($formData); } elseif ($this->shouldDelete()) { $this->createDeleteElements($formData); } } /** * Prepare the form for the requested mode */ public function onRequest() { if ($this->shouldInsert()) { $this->onInsertRequest(); } elseif ($this->shouldUpdate()) { $this->onUpdateRequest(); } elseif ($this->shouldDelete()) { $this->onDeleteRequest(); } } /** * Prepare the form for mode insert * * Populates the form with the data passed to add(). */ protected function onInsertRequest() { $data = $this->getData(); if (! empty($data)) { $this->setDefaults($data); } } /** * Prepare the form for mode update * * Populates the form with either the data passed to edit() or tries to fetch it from the repository. * * @throws NotFoundError In case the entry to update cannot be found */ protected function onUpdateRequest() { $data = $this->getData(); if ($data === null) { $row = $this->fetchEntry(); if ($row === false) { throw new NotFoundError('Entry "%s" not found', $this->getIdentifier()); } $data = get_object_vars($row); } $this->setDefaults($data); } /** * Prepare the form for mode delete * * Verifies that the repository contains the entry to delete. * * @throws NotFoundError In case the entry to delete cannot be found */ protected function onDeleteRequest() { if (! $this->entryExists()) { throw new NotFoundError('Entry "%s" not found', $this->getIdentifier()); } } /** * Apply the requested mode on the repository * * @return ?bool */ public function onSuccess() { if ($this->shouldInsert()) { return $this->onInsertSuccess(); } elseif ($this->shouldUpdate()) { return $this->onUpdateSuccess(); } elseif ($this->shouldDelete()) { return $this->onDeleteSuccess(); } } /** * Apply mode insert on the repository * * @return bool */ protected function onInsertSuccess() { try { $this->insertEntry(); } catch (Exception $e) { Notification::error($this->getInsertMessage(false)); $this->error($e->getMessage()); return false; } Notification::success($this->getInsertMessage(true)); return true; } /** * Apply mode update on the repository * * @return bool */ protected function onUpdateSuccess() { try { $this->updateEntry(); } catch (Exception $e) { Notification::error($this->getUpdateMessage(false)); $this->error($e->getMessage()); return false; } Notification::success($this->getUpdateMessage(true)); return true; } /** * Apply mode delete on the repository * * @return bool */ protected function onDeleteSuccess() { try { $this->deleteEntry(); } catch (Exception $e) { Notification::error($this->getDeleteMessage(false)); $this->error($e->getMessage()); return false; } Notification::success($this->getDeleteMessage(true)); return true; } /** * Create and add elements to this form to insert an entry * * @param array $formData The data sent by the user */ abstract protected function createInsertElements(array $formData); /** * Create and add elements to this form to update an entry * * Calls createInsertElements() by default. Overwrite this to add different elements when in mode update. * * @param array $formData The data sent by the user */ protected function createUpdateElements(array $formData) { $this->createInsertElements($formData); } /** * Create and add elements to this form to delete an entry * * @param array $formData The data sent by the user */ abstract protected function createDeleteElements(array $formData); /** * Create and return a filter to use when selecting, updating or deleting an entry * * @return Filter */ abstract protected function createFilter(); /** * Return a notification message to use when inserting an entry * * @param bool $success true or false, whether the operation was successful * * @return string */ abstract protected function getInsertMessage($success); /** * Return a notification message to use when updating an entry * * @param bool $success true or false, whether the operation was successful * * @return string */ abstract protected function getUpdateMessage($success); /** * Return a notification message to use when deleting an entry * * @param bool $success true or false, whether the operation was successful * * @return string */ abstract protected function getDeleteMessage($success); }