db = $database; $this->validator = $validator; $this->configure(); // Komplexe Suche immer aktivieren $this->registerSelectFilter(new ComplexSearchFilter()); } /** * @param array $filter * @param array $sorting * @param array $columns * @param array $includes * @param int $page * @param int $paging * * @return CollectionResult */ public function getList( array $filter = [], array $sorting = [], array $columns = [], array $includes = [], $page = 1, $paging = 20 ) { /** @var SelectQuery $selectAll */ $selectAll = $this->selectAllQuery(); if (!$selectAll) { throw new EndpointNotAvailableException(); } if (!$selectAll instanceof SelectQuery) { throw new InvalidArgumentException(sprintf( 'selectAllQuery() must return an instance of %s', SelectQuery::class )); } // Suchfilter und Sortierung hinzufügen $selectAll = $this->applySelectFilter($selectAll, [ SelectFilterInterface::TYPE_SEARCHING => $filter, SelectFilterInterface::TYPE_SORTING => $sorting, ]); // Filter hinzufügen //$selectAll = $this->appendFilterQuery($filter, $selectAll); //$bindValues = $this->appendFilterBindings($filter, $bindValues); // Sortierung hinzufügen //$selectAll = $this->appendSorting($sorting, $selectAll); /*echo "
"; echo $selectAll->getStatement(); var_dump($selectAll->getBindValues()); echo ""; exit;*/ // Ergebnisse ermitteln $selectList = clone $selectAll; if (!empty($columns)) { $selectList->resetCols()->cols($columns); } $selectList->page($page)->setPaging($paging); $items = $this->db->fetchAll( $selectList->getStatement(), $selectList->getBindValues() ); if (count($items) === 0) { throw new ResourceNotFoundException(); } // Gesamtanzahl der Ergebnisse ermitteln $selectCount = clone $selectAll; $selectCount->resetOrderBy()->resetCols()->cols(['COUNT(*)']); $total = (int)$this->db->fetchValue( $selectCount->getStatement(), $selectCount->getBindValues() ); $pagination = $this->getPagination($total, count($items), $paging, $page); // Includes in Ergebnis integrieren $items = $this->integrateIncludes($includes, $items); return new CollectionResult($items, $pagination); } /** * @param array $ids * @param array $columns Spalten überschreiben * * @return CollectionResult */ public function getIds(array $ids, array $columns = []) { /** @var SelectQuery $selectIds */ $selectIds = $this->selectIdsQuery(); if (!$selectIds) { throw new EndpointNotAvailableException(); } if (!$selectIds instanceof SelectQuery) { throw new InvalidArgumentException(sprintf( 'selectIdsQuery() must return an instance of %s', SelectQuery::class )); } if (!empty($columns)) { $selectIds->resetCols()->cols($columns); } $data = $this->db->fetchAssoc( $selectIds->getStatement(), ['ids' => $ids] ); if (!$data) { throw new ResourceNotFoundException(); } return new CollectionResult($data); } /** * @param int $id * @param array $includes * * @return ItemResult */ public function getOne($id, array $includes = []) { /** @var SelectQuery $selectOne */ $selectOne = $this->selectOneQuery(); if (!$selectOne) { throw new EndpointNotAvailableException(); } if (!$selectOne instanceof SelectQuery) { throw new InvalidArgumentException(sprintf( 'selectOneQuery() must return an instance of %s', SelectQuery::class )); } $data = $this->db->fetchRow($selectOne->getStatement(), ['id' => $id]); if (!$data) { throw new ResourceNotFoundException(); } // Includes in Ergebnis integrieren $data = $this->integrateIncludes($includes, $data, false); return new ItemResult($data); } /** * Prüfen ob übergebene ID in Datenbank vorhanden ist * * @param int $id * @param string|null $message Fehlermeldung wenn ID nicht vorhanden ist */ public function checkOrFail($id, $message = null) { /** @var SelectQuery $selectOne */ $select = $this->selectOneQuery(); if (!$select) { throw new EndpointNotAvailableException(); } if (!$select instanceof SelectQuery) { throw new InvalidArgumentException(sprintf( 'selectOneQuery() must return an instance of %s', SelectQuery::class )); } $value = $this->db->fetchValue($select->getStatement(), ['id' => $id]); if ((int)$value !== (int)$id) { throw new ResourceNotFoundException($message === null ? 'Resource not found' : $message); } } /** * @param int $id * @param array $inputVars * @param array|null $inputMapping Assoc-Array ['Eingabefeld' => 'Datenbankfeld'] * * @return ItemResult */ public function edit($id, $inputVars, $inputMapping = null) { $updateQuery = $this->updateQuery(); if (!$updateQuery) { throw new EndpointNotAvailableException(); } if (!$updateQuery instanceof UpdateQuery) { throw new InvalidArgumentException(sprintf( 'updateQuery() must return an instance of %s', UpdateQuery::class )); } // Eingabe validieren $this->validateData($inputVars, $id); $inputVars['id'] = $id; // Eingabe- zu Datenbankfeld mappen $inputVars = $this->mapInputData($inputVars, $inputMapping); $bindValues = []; foreach ($inputVars as $inputKey => $inputVal) { $updateQuery->col($inputKey); $bindValues[$inputKey] = $inputVal; } $this->db->perform($updateQuery->getStatement(), $bindValues); // Bei Erfolg die geänderte Resource zurückliefern; mit Success-Flag $result = $this->getOne($id); $result->setSuccess(true); return $result; } /** * @param array $inputVars * @param array|null $inputMapping Assoc-Array ['Eingabefeld' => 'Datenbankfeld'] * * @return ItemResult */ public function insert($inputVars, $inputMapping = null) { $insertQuery = $this->insertQuery(); if (!$insertQuery) { throw new EndpointNotAvailableException(); } if (!$insertQuery instanceof InsertQuery) { throw new InvalidArgumentException(sprintf( 'insertQuery() must return an instance of %s', InsertQuery::class )); } // Eingabe validieren $this->validateData($inputVars); // Eingabe- zu Datenbankfeld mappen $inputVars = $this->mapInputData($inputVars, $inputMapping); $bindValues = []; foreach ($inputVars as $inputKey => $inputVal) { $insertQuery->col($inputKey); $bindValues[$inputKey] = $inputVal; } $this->db->perform($insertQuery->getStatement(), $bindValues); $id = $this->db->lastInsertId(); // Bei Erfolg die angelegte Resource zurückliefern; mit Success-Flag $result = $this->getOne($id); $result->setSuccess(true); return $result; } /** * @param int $id * * @return ItemResult */ public function delete($id) { $deleteQuery = $this->deleteQuery(); if (!$deleteQuery) { throw new EndpointNotAvailableException(); } if (!$deleteQuery instanceof DeleteQuery && !$deleteQuery instanceof UpdateQuery) { throw new InvalidArgumentException(sprintf( 'deleteQuery() must return an instance of %s or %s', DeleteQuery::class, UpdateQuery::class )); } try { $this->db->perform($deleteQuery->getStatement(), ['id' => $id]); $success = true; } catch (Exception $e) { $success = false; } $result = new ItemResult(['id' => $id]); $result->setSuccess($success); return $result; } /** * Eingabe- zu Datenbankfeld mappen * * @param array $inputVars * @param array|null $inputMapping Assoc-Array ['Eingabefeld' => 'Datenbankfeld'] * * @return array */ protected function mapInputData($inputVars, $inputMapping = null) { if (empty($inputMapping)) { return $inputVars; } foreach ($inputMapping as $inputKey => $dbKey) { if (empty($inputKey) || empty($dbKey)) { continue; } if ($inputKey === $dbKey) { continue; } if (array_key_exists($inputKey, $inputVars)) { $inputVars[$dbKey] = $inputVars[$inputKey]; unset($inputVars[$inputKey]); } } return $inputVars; } /** * @param int $itemsTotal * @param int $itemsCurrent * @param int $itemsPerPage * @param int $pageCurrent * * @return array */ protected function getPagination($itemsTotal, $itemsCurrent, $itemsPerPage, $pageCurrent) { return [ 'items_per_page' => (int)$itemsPerPage, 'items_current' => (int)$itemsCurrent, 'items_total' => (int)$itemsTotal, 'page_current' => (int)$pageCurrent, 'page_last' => (int)ceil($itemsTotal / $itemsPerPage), ]; } /** * @param string $resourceClass * * @return AbstractResource */ protected function getResource($resourceClass) { return new $resourceClass( $this->db, $this->validator ); } }