pdo = $pdo; $stmt = $this->pdo->prepare("SELECT * FROM `".self::table()."` WHERE `".static::$primary_key."`=?"); $stmt->execute([$id]); if ($stmt->rowCount() == 0) { throw new ModelNotFoundException("The ".static::$table." with id '$id' could not be found."); } $this->data = $stmt->fetch(PDO::FETCH_ASSOC); } public function __set($key, $value) { if (!in_array($key, static::$fillable_columns)) { throw new ModelIllegalAccessException("Column `".self::table()."`.`$key` cannot be edited."); } if ($this->data[$key] == $value) { return; } $stmt = $this->pdo->prepare("UPDATE `".self::table()."` SET `$key`=? WHERE `".static::$primary_key."`=?"); $stmt->execute([ $this->mutator($key, $value), $this->data[static::$primary_key] ]); if ($stmt->rowCount() != 1) { throw new ModelSetFailedException("Failed to update `".self::table()."`.`$key` to '$value'."); } $this->data[$key] = $value; } public function __get($key) { return $this->accessor($key, $this->data[$key]); } public static function create($pdo, $values) { $class = get_called_class(); $columns = array_combine(static::$fillable_columns, $values); $questions = []; foreach ($columns as $column => $value) { $columns[$column] = $class::mutator($column, $value); $questions[] = '?'; } $stmt = $pdo->prepare( "INSERT INTO `".self::table()."` " . "(`" . implode('`, `', array_keys($columns)) . "`) " . "VALUES (" . implode(',', $questions) . ")"); $stmt->execute(array_values($columns)); if ($stmt->rowCount() != 1) throw new ModelCreateFailedException(); return new $class($pdo, $pdo->lastInsertId()); } public static function searchIds($pdo, $where = [], $values = []) { $stmt = $pdo->prepare("SELECT `id` FROM `".static::table()."`" . ((count($where) > 0) ? (" WHERE (" . implode(') AND (', $where) . ")") : "")); $stmt->execute($values); $ids = []; foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) { $ids[] = $row['id']; } return $ids; } public static function search($pdo, $where = [], $values = []) { $class = get_called_class(); $items = []; foreach (self::searchIds($pdo, $where, $values) as $id) { $items[] = new $class($pdo, $id); } return $items; } public static function count($pdo, $where = [], $values = []) { $class = get_called_class(); $stmt = $pdo->prepare("SELECT COUNT(*) FROM `".static::table()."`" . ((count($where) > 0) ? (" WHERE (" . implode(') AND (', $where) . ")") : "")); $stmt->execute($values); return $stmt->fetchColumn(); } protected static function accessor($key, $value) { if (is_null($value)) { return null; } elseif (in_array($key, static::$booleans)) { return (bool) $value; } elseif (in_array($key, static::$dates) || in_array($key, static::$timestamps)) { return strtotime($value); } else { return $value; } } protected static function mutator($key, $value) { if (in_array($key, static::$dates) && is_int($value)) { return date('Y-m-d', $value); } elseif (in_array($key, static::$timestamps) && is_int($value)) { return date('Y-m-d H:i:s', $value); } else { return (string) $value; } } public function delete() { $stmt = $this->pdo->prepare("DELETE FROM `".self::table()."` WHERE `".static::$primary_key."`=?"); $stmt->execute([$this->data[static::$primary_key]]); return $stmt->rowCount() != 0; } private static function table() { return self::TABLE_PREFIX . static::$table; } }