eesyphp/example/src/Db/Item.php
2024-02-18 18:27:59 +01:00

173 lines
4.5 KiB
PHP

<?php
namespace EesyPHPExample\Db;
use EesyPHP\Hook;
use EesyPHP\Log;
use EesyPHP\Db\AttrBool;
use EesyPHP\Db\AttrInt;
use EesyPHP\Db\AttrStr;
use EesyPHP\Db\AttrTimestamp;
use EesyPHP\Db\DbObject;
use EesyPHP\Export\CSV;
use Unidecode\Unidecode;
/**
* Item database object
* @property int|null $id
* @property string $name
* @property \DateTime|null $date
* @property string $status
* @property string|null $description
*/
class Item extends DbObject {
protected const TABLE = 'item';
protected const PRIMARY_KEYS = ['id'];
protected const DEFAULT_ORDER = 'id';
protected const DEFAULT_ORDER_DIRECTION = 'DESC';
protected const POSSIBLE_ORDERS = ['id', 'name', 'date', 'status'];
protected static function get_schema() {
return [
'id' => new AttrInt(['autoincrement' => true]),
'name' => new AttrStr(['required' => true]),
'date' => new AttrTimestamp(['default' => 'time']),
'status' => new AttrStr(['required' => true, 'default' => 'pending']),
'description' => new AttrStr(),
];
}
/**
* Change item status in DB
* @param string $status New item status
* @return bool
*/
public function change_status($status) {
$this->status = $status;
if ($this -> save()) {
Log :: info("Status of item #$this->id changed to $status.");
return true;
}
return false;
}
/**
* Set item as archived in DB
* @return bool
*/
public function archive() {
return $this -> change_status('archived');
}
/**
* Compute WHERE clauses from word pattern
* @throws \EesyPHP\Db\DbException
* @return array
*/
public static function word_to_filters($word) {
$patterns_word = [];
// If numeric pattern ?
if (preg_match('/^[0-9]+$/', $word)) {
// Numeric pattern
$word = intval($word);
$patterns_word['id = ?'] = $word;
}
else {
// Text pattern
foreach (array('name', 'description') as $field) {
if (self :: DB_CLASS :: is_pgsql()) {
$word = Unidecode::unidecode($word);
$patterns_word["unaccent($field) ILIKE ?"] = "%$word%";
}
else
$patterns_word["$field LIKE ?"] = "%$word%";
}
}
return $patterns_word;
}
/**
* Search objects
* @throws \EesyPHP\Db\DbException
* @see \EesyPHP\Db\DbObject::search()
* @return array|false The search result as an array, or False in case of error.
*/
public static function search($params) {
if (
$params &&
isset($params['filters']) &&
isset($params['filters']['status']) &&
$params['filters']['status'] == 'all'
)
unset($params['filters']['status']);
return parent :: search($params);
}
/**
* Export items
* @param resource|null $fd The file pointer where to export (optional, default: php://output)
* @param array<int,array<string,mixed>>|null $items Items to export
* @param array<string,\EesyPHP\Db\Attr> $schema The object schema (optional)
* @return boolean
*/
static function export($fd=null, $items=null, $schema=null) {
$schema = $schema ? $schema : static :: get_schema();
$export = new CSV(static :: csv_export_fields($schema));
$items = $items?$items:static :: list();
if ($items === false)
return false;
$rows = [];
foreach ($items as $item) {
$row = [];
foreach($schema as $attr => $attr_type)
$row[$attr] = $item->$attr;
$rows[] = $row;
}
return $export->export($rows, $fd);
}
static function restore($fd=null, $schema=null) {
$schema = $schema ? $schema : static :: get_schema();
$import = new CSV(static :: csv_export_fields($schema));
$items = $import->load($fd);
if ($items === false) {
Log :: error("Error loading items.");
return false;
}
if (!$items) {
Log :: error("No item loaded.");
return false;
}
try {
if (self :: DB_CLASS :: truncate(self :: TABLE)) {
Log :: debug("Table %s truncated", self :: TABLE);
}
else {
Log :: error("An unknown error occurred truncating table %s in database.", self :: TABLE);
return false;
}
}
catch (\Exception $e) {
Log :: error("Error truncating item table in database : ".$e->getMessage());
return false;
}
$success = true;
foreach($items as $item) {
$obj = new Item();
$obj->apply($item);
$success = $success && $obj->save();
}
// Trigger hooks
Hook :: trigger('items_restored');
return $success;
}
}