Files
xstore/inc/Hura8/System/Model/aCategoryBaseModel.php

293 lines
8.7 KiB
PHP
Raw Permalink Normal View History

2025-10-04 11:46:59 +07:00
<?php
namespace Hura8\System\Model;
use Hura8\Interfaces\AppResponse;
use Hura8\System\Security;
use Hura8\System\Security\DataType;
abstract class aCategoryBaseModel extends aEntityBaseModel
{
public function __construct($entity_type, $tb_name = "") {
parent::__construct($entity_type, $tb_name);
}
protected function extendedFilterOptions() : array
{
return [
// empty for now
];
}
// get all categories and group by parents
public function getAllByParent(array $condition = array()) : array
{
$item_list = array(); // parentId=>array(childId)
foreach ( $this->getAll($condition) as $item ) {
$item_list[$item['parent_id']][$item['id']] = $item;
}
return $item_list;
}
// get all categories
public function getAll(array $condition = array()){
/*$condition = [
"parent_id" => 1,
"status" => 1,
];*/
$bind_types = [];
$bind_values = [];
$where_clause = '';
if(isset($condition['status'])) {
$where_clause .= " AND `status` = ? ";
$bind_types[] = 'd';
$bind_values[] = intval($condition['status']);
}
$query = $this->db->runQuery(
" SELECT * FROM `". $this->tb_entity ."` WHERE 1 ".$where_clause." ORDER BY `ordering` DESC LIMIT 5000 ",
$bind_types, $bind_values
);
return $this->db->fetchAll($query);
}
protected function beforeCreateItem(array $input_info) : AppResponse
{
$parent_id = isset($input_info['parent_id']) ? $input_info['parent_id'] : 0;
$api_key = (isset($input_info['api_key']) && $input_info['api_key']) ? $input_info['api_key'] : $input_info['title'];
$api_key = Security\DataClean::makeInputSafe($api_key, DataType::ID);
$api_key = $this->createUniqueAPIKey(0, $api_key);
if(!isset($input_info['url_index']) || !$input_info['url_index']) {
$input_info['url_index'] = $this->createUniqueUrlIndex(0, $input_info['title']);
}else{
$input_info['url_index'] = $this->createUniqueUrlIndex(0, $input_info['url_index']);
}
$info = array_merge($input_info, array(
"parent_id" => $parent_id,
"api_key" => $api_key,
"create_by" => ADMIN_NAME,
"create_time" => CURRENT_TIME,
"last_update_by" => ADMIN_NAME,
"last_update" => CURRENT_TIME,
) );
return new AppResponse('ok', null, $info);
}
protected function afterCreateItem($new_item_id, $new_item_info) {
//update path&child
$this->updatePath($new_item_id);
$this->updateChild($new_item_id);
$this->updateChild($new_item_info['parent_id']);
}
protected function beforeUpdateItem($item_id, $current_item_info, $new_input_info) : AppResponse
{
$info = $new_input_info;
if(isset($info['url_index'])) {
if(!$info['url_index']) {
$info['url_index'] = $this->createUniqueUrlIndex($item_id, $info['title']);
}else{
$info['url_index'] = $this->createUniqueUrlIndex($item_id, $info['url_index']);
}
}
$info['last_update'] = CURRENT_TIME;
$info['last_update_by'] = ADMIN_NAME;
return new AppResponse('ok', null, $info);
}
protected function afterUpdateItem($item_id, $old_item_info, $new_item_info) {
//update cat-path for category
$this->updatePath($item_id);
$this->updateChild($item_id);
//update child_ids for new/old parents and parents of parent
if($new_item_info['parent_id'] != $old_item_info['parent_id']) {
$this->updateChild($new_item_info['parent_id']);
$this->updateChild($old_item_info['parent_id']);
}
}
protected function afterDeleteItem($item_id, $item_info){
$this->updateChild($item_info["parent_id"]);
}
//create an unique request-path
protected function createUniqueAPIKey($id, $api_key){
//if exist and belong other id, create a new one
$query = $this->db->runQuery("SELECT `id` FROM `".$this->tb_entity."` WHERE `api_key` = ? LIMIT 1 ", ['s'], [$api_key]) ;
if($info = $this->db->fetchAssoc($query)){
if($info['id'] != $id) {
$new_api_key = $api_key."-1";
return $this->createUniqueAPIKey($id, $new_api_key);
}
}
return $api_key;
}
protected function updatePathAndChildAll($id, $child_ids, $parent_id, $old_parent_id) {
$this->updatePathAndChild($id);
//update for childs
$list_child_to_update = array_filter(explode(",", $child_ids));
foreach($list_child_to_update as $_id) {
if($_id != $id) $this->updatePathAndChild($_id);
}
//cap nhat lai child list cua danh muc old_parent and new parent id, and parent of these parents
$query = $this->db->runQuery(
"SELECT cat_path FROM `". $this->tb_entity ."` WHERE `id`= ? OR `id`= ? ",
['d', 'd'], [$parent_id, $old_parent_id]
);
$cat_path_all = join(":", array_map(function ($item){
return $item['cat_path'];
} , $this->db->fetchAll($query)));
$list_parent_to_update = array_unique(array_filter(explode(":", $cat_path_all)));
foreach($list_parent_to_update as $_id) {
if($_id > 0) $this->updatePathAndChild($_id);
}
}
public function updatePathAndChild($id) {
if(!$id) return false;
$new_cat_path = $this->findCatPath($id);
$new_child_list = $this->findChildList($id);
$is_parent = ( $new_child_list === $id) ? 0 : 1;
return $this->db->update(
$this->tb_entity ,
[
'cat_path' => $new_cat_path,
'child_ids' => $new_child_list,
'is_parent' => $is_parent,
],
[
'id' => $id,
]
);
}
protected function updatePath($id) {
if(!$id) return false;
$new_cat_path = $this->findCatPath($id);
return $this->db->update(
$this->tb_entity ,
[
'cat_path' => $new_cat_path,
],
[
'id' => $id,
]
);
}
//update childs for current id and its parents and its parents' parents....
protected function updateChild($id) {
if(!$id) return false;
$query = $this->db->runQuery("SELECT `cat_path` FROM `".$this->tb_entity."` WHERE `id` = ? LIMIT 1 ", ['d'], [$id]) ;
if($item_info = $this->db->fetchAssoc($query)){
$cat_id_list = array_filter(explode(":", $item_info['cat_path']));
foreach ($cat_id_list as $_id) {
$new_child_list = $this->findChildList($_id);
$is_parent = ( $new_child_list === $_id) ? 0 : 1;
$this->db->update(
$this->tb_entity ,
[
'child_ids' => $new_child_list,
'is_parent' => $is_parent,
],
[
'id' => $_id,
]
);
}
}
return true;
}
protected function _buildQueryConditionExtend(array $condition) : ?array
{
$catCondition = [];
$bind_types = [];
$bind_values = [];
return array(join(" ", $catCondition), $bind_types, $bind_values);
}
//build category path 0:parent:categoryId
protected function findCatPath($categoryId){
$path = ":".$categoryId;
$query = $this->db->runQuery("SELECT `parent_id` FROM `".$this->tb_entity."` WHERE `id` = ? LIMIT 1", ['d'], [$categoryId]);
if($rs = $this->db->fetchAssoc($query)){
if($rs['parent_id']) $path .= $this->findCatPath($rs['parent_id']);
}
return $path;
}
//lay toan bo cac muc la con
protected function findChildList($p_category_id){
$all_categories = $this->getAllByParent();
$list = $p_category_id;
if(isset($all_categories[$p_category_id])) {
foreach ( $all_categories[$p_category_id] as $rs ) {
$list .= ",". $this->findChildList($rs['id']);
}
}
return $list;
}
protected function getAllParent(array $condition = []) {
$cache_key = 'all-category-by-parent-'.$this->getEntityType();
return self::getCache($cache_key, function () use ($condition){
return $this->getAllByParent($condition);
});
}
}