|
<?php |
|
class Category { |
|
// (A) CONSTRUCTOR - CONNECT TO DATABASE |
|
protected $pdo = null; |
|
protected $stmt = null; |
|
public $error = ""; |
|
function __construct() { |
|
$this->pdo = new PDO( |
|
"mysql:host=".DB_HOST.";dbname=".DB_NAME.";charset=".DB_CHARSET, |
|
DB_USER, DB_PASSWORD, [ |
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, |
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC |
|
]); |
|
} |
|
|
|
// (B) DESTRUCTOR - CLOSE CONNECTION |
|
function __destruct() { |
|
if ($this->stmt !== null) { $this->stmt = null; } |
|
if ($this->pdo !== null) { $this->pdo = null; } |
|
} |
|
|
|
// (C) HELPER - RUN SQL QUERY |
|
function query ($sql, $data=null) : void { |
|
$this->stmt = $this->pdo->prepare($sql); |
|
$this->stmt->execute($data); |
|
} |
|
|
|
// (D) GET ALL CATEGORIES RECURSIVELY |
|
function getAll ($id=0) { |
|
// (D1) GET CATEGORIES WITH GIVEN PARENT ID |
|
$this->query("SELECT * FROM `category` WHERE `parent_id`=?", [$id]); |
|
$cat = []; |
|
while ($r = $this->stmt->fetch()) { |
|
$cat[$r["category_id"]] = [ |
|
"n" => $r["category_name"], |
|
"c" => null |
|
]; |
|
} |
|
|
|
// (D2) GET CHILDREN |
|
if (count($cat)>0) { |
|
foreach ($cat as $id => $c) { $cat[$id]["c"] = $this->getAll($id); } |
|
return $cat; |
|
} else { return null; } |
|
} |
|
|
|
// (E) GET ALL CHILDREN CATEGORY ID |
|
function getChildren ($id) { |
|
$this->query("SELECT `category_id` FROM `category` WHERE `parent_id`=?", [$id]); |
|
$cat = $this->stmt->fetchAll(PDO::FETCH_COLUMN); |
|
foreach ($cat as $cid) { |
|
$cat = array_merge($cat, $this->getChildren($cid)); |
|
} |
|
return $cat; |
|
} |
|
|
|
// (F) ADD NEW CATEGORY |
|
function add ($name, $parent=0) { |
|
$this->query( |
|
"INSERT INTO `category` (`category_name`, `parent_id`) VALUES (?, ?)", |
|
[$name, $parent] |
|
); |
|
return true; |
|
} |
|
|
|
// (G) UPDATE CATEGORY |
|
function update ($name, $id, $parent) { |
|
// (G1) CHECK PARENT ID |
|
// PARENT ID CANNOT BE SET TO SELF + CANNOT MOVE UNDER CHILDREN |
|
$cannot = $this->getChildren($id); |
|
$cannot[] = $id; |
|
if (in_array($parent, $cannot)) { |
|
$this->error = "Invalid parent ID"; |
|
return false; |
|
} |
|
|
|
// (G2) UPDATE ENTRY |
|
$this->query( |
|
"UPDATE `category` SET `category_name`=?, `parent_id`=? WHERE `category_id`=?", |
|
[$name, $parent, $id] |
|
); |
|
return true; |
|
} |
|
|
|
// (H) "SAFE DELETE" - CHILDREN WILL REVERT TO PARENT ID 0 |
|
function safeDel ($id) { |
|
// (H1) GET ALL CHILDREN |
|
$children = $this->getChildren($id); |
|
|
|
// (H2) AUTO-COMMIT OFF |
|
$this->pdo->beginTransaction(); |
|
|
|
// (H3) REVERT CHILDREN TO PARENT ID 0 |
|
if (count($children) > 0) { |
|
$in = implode(",", $children); |
|
$this->query("UPDATE `category` SET `parent_id`=0 WHERE `category_id` IN ($in)"); |
|
} |
|
|
|
// (H4) DELETE CATEGORY |
|
$this->query("DELETE FROM `category` WHERE `category_id`=?", [$id]); |
|
|
|
// (H5) COMMIT; |
|
$this->pdo->commit(); |
|
return true; |
|
} |
|
|
|
// (I) "CASCADE DELETE" - ALL CHILDREN WILL ALSO BE DELETED |
|
function casDel ($id) { |
|
// (H1) GET ALL CHILDREN + SET CURRENT ID |
|
$in = $this->getChildren($id); |
|
$in[] = $id; |
|
$in = implode(",", $in); |
|
|
|
// (H2) DELETE |
|
$this->query("DELETE FROM `category` WHERE `category_id` IN ($in)"); |
|
return true; |
|
} |
|
} |
|
|
|
// (J) DATABASE SETTINGS - CHANGE TO YOUR OWN! |
|
define("DB_HOST", "localhost"); |
|
define("DB_NAME", "test"); |
|
define("DB_CHARSET", "utf8mb4"); |
|
define("DB_USER", "root"); |
|
define("DB_PASSWORD", ""); |
|
|
|
// (K) NEW CATEGORY OBJECT |
|
$_CAT = new Category(); |