[ Mini Kiebo ]
Server: Windows NT DESKTOP-5B8S0D4 6.2 build 9200 (Windows 8 Professional Edition) i586
Path:
D:
/
Backup
/
05122024
/
htdocs
/
jurnal-kesmas
/
v1
/
lib
/
pkp
/
classes
/
core
/
[
Home
]
File: EntityDAO.php
<?php /** * @file classes/core/EntityDAO.php * * Copyright (c) 2014-2021 Simon Fraser University * Copyright (c) 2000-2021 John Willinsky * Distributed under the GNU GPL v3. For full terms see the file docs/COPYING. * * @class EntityDAO * * @brief A base class for DAOs that read and write an entity to the database */ namespace PKP\core; use Exception; use Illuminate\Support\Facades\DB; use PKP\db\DAO; use PKP\services\PKPSchemaService; /** * @template T of DataObject */ abstract class EntityDAO { /** @var string One of the \PKP\services\PKPSchemaService::SCHEMA_... constants */ public $schema; /** @var string The name of the primary table for this entity */ public $table; /** @var string The name of the settings table for this entity */ public $settingsTable; /** @var string The column name for the object id in primary and settings tables */ public $primaryKeyColumn; /** @var array Maps schema properties for the primary table to their column names */ public $primaryTableColumns = []; /** * @var array Map schema properties to the primary table * * An array mapping the property names of an entity to the * correct column in the database table. * * Example: * * ``` * [ * 'id' => 'announcement_id', * 'datePosted' => 'date_posted', * } * ``` * * Only include properties stored in self::$table. Properties * stored in self::$settingsTable do not need to be mapped. */ public $primaryKeyColumns; /** * @var DAO An instance of PKP\db\DAO * * This provides access to a few methods that are * still shared with the deprecated DAOs. * * @deprecated 3.4 */ public $deprecatedDao; /** @var PKPSchemaService<T> $schemaService */ protected $schemaService; /** * Constructor */ public function __construct(PKPSchemaService $schemaService) { $this->deprecatedDao = new DAO(); $this->schemaService = $schemaService; } /** * Creates a new DataObject * * @return T */ public function newDataObject() { throw new Exception('Not implemented'); } /** * Convert a row from the database query into a DataObject * * @return T */ public function fromRow(object $row): DataObject { $schema = $this->schemaService->get($this->schema); $object = $this->newDataObject(); foreach ($this->primaryTableColumns as $propName => $column) { if (property_exists($row, $column)) { $object->setData( $propName, $this->convertFromDB($row->{$column}, $schema->properties->{$propName}->type, true) ); } } if ($this->settingsTable) { $rows = DB::table($this->settingsTable) ->where($this->primaryKeyColumn, '=', $row->{$this->primaryKeyColumn}) ->get(); $rows->each(function ($row) use ($object, $schema) { if (!empty($schema->properties->{$row->setting_name})) { $object->setData( $row->setting_name, $this->convertFromDB( $row->setting_value, $schema->properties->{$row->setting_name}->type ), empty($row->locale) ? null : $row->locale ); } }); } return $object; } /** * Insert an object into the database * @param T $object */ protected function _insert(DataObject $object): int { $schemaService = $this->schemaService; $schema = $schemaService->get($this->schema); $sanitizedProps = $schemaService->sanitize($this->schema, $object->_data); $primaryDbProps = $this->getPrimaryDbProps($object); if (empty($primaryDbProps)) { throw new Exception('Tried to insert ' . get_class($object) . ' without any properties for the ' . $this->table . ' table.'); } DB::table($this->table)->insert($primaryDbProps); $object->setId((int) DB::getPdo()->lastInsertId()); // Add additional properties to settings table if they exist if ($this->settingsTable && count($sanitizedProps) !== count($primaryDbProps)) { foreach ($schema->properties as $propName => $propSchema) { if (!isset($sanitizedProps[$propName]) || array_key_exists($propName, $this->primaryTableColumns)) { continue; } if (!empty($propSchema->multilingual)) { foreach ($sanitizedProps[$propName] as $localeKey => $localeValue) { DB::table($this->settingsTable)->insert([ $this->primaryKeyColumn => $object->getId(), 'locale' => $localeKey, 'setting_name' => $propName, 'setting_value' => $this->convertToDB($localeValue, $schema->properties->{$propName}->type), ]); } } else { DB::table($this->settingsTable)->insert([ $this->primaryKeyColumn => $object->getId(), 'setting_name' => $propName, 'setting_value' => $this->convertToDB($sanitizedProps[$propName], $schema->properties->{$propName}->type), ]); } } } return $object->getId(); } /** * Update an object in the database * @param T $object */ protected function _update(DataObject $object) { $schemaService = $this->schemaService; $schema = $schemaService->get($this->schema); $sanitizedProps = $schemaService->sanitize($this->schema, $object->_data); $primaryDbProps = $this->getPrimaryDbProps($object); DB::table($this->table) ->where($this->primaryKeyColumn, '=', $object->getId()) ->update($primaryDbProps); if ($this->settingsTable) { $deleteSettings = []; foreach ($schema->properties as $propName => $propSchema) { if (array_key_exists($propName, $this->primaryTableColumns)) { continue; } elseif (!isset($sanitizedProps[$propName])) { $deleteSettings[] = $propName; continue; } if (!empty($propSchema->multilingual)) { foreach ($sanitizedProps[$propName] as $localeKey => $localeValue) { // Delete rows with a null value if (is_null($localeValue)) { DB::table($this->settingsTable) ->where($this->primaryKeyColumn, '=', $object->getId()) ->where('setting_name', '=', $propName) ->where('locale', '=', $localeKey) ->delete(); } else { DB::table($this->settingsTable) ->updateOrInsert( [ $this->primaryKeyColumn => $object->getId(), 'locale' => $localeKey, 'setting_name' => $propName, ], [ 'setting_value' => $this->convertToDB($localeValue, $schema->properties->{$propName}->type), ] ); } } } else { DB::table($this->settingsTable) ->updateOrInsert( [ $this->primaryKeyColumn => $object->getId(), 'locale' => '', 'setting_name' => $propName, ], [ 'setting_value' => $this->convertToDB($sanitizedProps[$propName], $schema->properties->{$propName}->type), ] ); } } if (count($deleteSettings)) { DB::table($this->settingsTable) ->where($this->primaryKeyColumn, '=', $object->getId()) ->whereIn('setting_name', $deleteSettings) ->delete(); } } } /** * Delete an object from the database * @param T $object */ protected function _delete(DataObject $object) { $this->deleteById($object->getId()); } /** * Delete an object from the database by its id */ public function deleteById(int $id) { DB::table($this->table) ->where($this->primaryKeyColumn, '=', $id) ->delete(); } /** * Prepare data to be inserted into the primary table * * Compiles the properties of a DataObject into a key/value * array that maps them to the primary table columns. * * @see $this->primaryTableColumns * @param T $object */ protected function getPrimaryDbProps(DataObject $object): array { $schema = $this->schemaService->get($this->schema); $sanitizedProps = $this->schemaService->sanitize($this->schema, $object->_data); $primaryDbProps = []; foreach ($this->primaryTableColumns as $propName => $columnName) { if ($propName !== 'id' && array_key_exists($propName, $sanitizedProps)) { $primaryDbProps[$columnName] = $this->convertToDB($sanitizedProps[$propName] ?? null, $schema->properties->{$propName}->type, true); // Convert empty string values for DATETIME columns into null values // because an empty string can not be saved to a DATETIME column if ($primaryDbProps[$columnName] === '' && isset($schema->properties->{$propName}->validation) && ( in_array('date_format:Y-m-d H:i:s', $schema->properties->{$propName}->validation) || in_array('date_format:Y-m-d', $schema->properties->{$propName}->validation) ) ) { $primaryDbProps[$columnName] = null; } } } return $primaryDbProps; } /** * @copydoc DAO::convertFromDB() */ protected function convertFromDB($value, string $type, bool $nullable = false) { return $this->deprecatedDao->convertFromDB($value, $type, $nullable); } /** * @copydoc DAO::convertToDB() */ protected function convertToDB($value, string $type, bool $nullable = false) { return $this->deprecatedDao->convertToDB($value, $type, $nullable); } }