Строим свою CMS на PHP и MySQL. Часть 7
В предыдущем уроке серии мы начали процесс добавления функционала категорий в нашу простую CMS. Рассмотрим, что нужно поменять в коде классов для реализации задуманных изменений.
Создание класса Category
Также как ранее мы создавали класс Article для управления хранением и выводом статей, нам нужно построить класс Category для решения таких же задач с категориями.
В папке cms имеется каталог classes. В каталоге classes создаем новый файл Category.php и копируем в него следующий код:
/**
* Класс для обработки категорий статей
*/
class Category
{
// Свойства
/**
* @var int ID категории из базы данных
*/
public $id = null;
/**
* @var string Название категории
*/
public $name = null;
/**
* @var string Короткое описание категории
*/
public $description = null;
/**
* Устанавливаем свойства объекта с использованием значений в передаваемом массиве
*
* @param assoc Значения свойств
*/
public function __construct( $data=array() ) {
if ( isset( $data['id'] ) ) $this->id = (int) $data['id'];
if ( isset( $data['name'] ) ) $this->name = preg_replace ( "/[^\.\,\-\_\'\"\@\?\!\:\$ a-zA-Z0-9()]/", "", $data['name'] );
if ( isset( $data['description'] ) ) $this->description = preg_replace ( "/[^\.\,\-\_\'\"\@\?\!\:\$ a-zA-Z0-9()]/", "", $data['description'] );
}
/**
* Устанавливаем свойства объекта с использованием значений из формы редактирования
*
* @param assoc Значения из формы редактирования
*/
public function storeFormValues ( $params ) {
// Store all the parameters
$this->__construct( $params );
}
/**
* Возвращаем объект Category, соответствующий заданному ID
*
* @param int ID категории
* @return Category|false Объект Category object или false, если запись не была найдена или в случае другой ошибки
*/
public static function getById( $id ) {
$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$sql = "SELECT * FROM categories WHERE id = :id";
$st = $conn->prepare( $sql );
$st->bindValue( ":id", $id, PDO::PARAM_INT );
$st->execute();
$row = $st->fetch();
$conn = null;
if ( $row ) return new Category( $row );
}
/**
* Возвращаем все (или диапазон) объектов Category из базы данных
*
* @param int Optional Количество возвращаемых строк (по умолчаниюt = all)
* @param string Optional Столбец, по которому сортируются категории(по умолчанию = "name ASC")
* @return Array|false Двух элементный массив: results => массив с объектами Category; totalRows => общее количество категорий
*/
public static function getList( $numRows=1000000, $order="name ASC" ) {
$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$sql = "SELECT SQL_CALC_FOUND_ROWS * FROM categories
ORDER BY " . mysql_escape_string($order) . " LIMIT :numRows";
$st = $conn->prepare( $sql );
$st->bindValue( ":numRows", $numRows, PDO::PARAM_INT );
$st->execute();
$list = array();
while ( $row = $st->fetch() ) {
$category = new Category( $row );
$list[] = $category;
}
// Получаем общее количество категорий, которые соответствуют критериям
$sql = "SELECT FOUND_ROWS() AS totalRows";
$totalRows = $conn->query( $sql )->fetch();
$conn = null;
return ( array ( "results" => $list, "totalRows" => $totalRows[0] ) );
}
/**
* Вставляем текущий объект Category в базу данных и устанавливаем его свойство ID.
*/
public function insert() {
// У объекта Category уже есть ID?
if ( !is_null( $this->id ) ) trigger_error ( "Category::insert(): Attempt to insert a Category object that already has its ID property set (to $this->id).", E_USER_ERROR );
// Вставляем категорию
$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$sql = "INSERT INTO categories ( name, description ) VALUES ( :name, :description )";
$st = $conn->prepare ( $sql );
$st->bindValue( ":name", $this->name, PDO::PARAM_STR );
$st->bindValue( ":description", $this->description, PDO::PARAM_STR );
$st->execute();
$this->id = $conn->lastInsertId();
$conn = null;
}
/**
* Обновляем текущий объект Category в базе данных.
*/
public function update() {
// У объекта Category есть ID?
if ( is_null( $this->id ) ) trigger_error ( "Category::update(): Attempt to update a Category object that does not have its ID property set.", E_USER_ERROR );
// Обновляем категорию
$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$sql = "UPDATE categories SET name=:name, description=:description WHERE id = :id";
$st = $conn->prepare ( $sql );
$st->bindValue( ":name", $this->name, PDO::PARAM_STR );
$st->bindValue( ":description", $this->description, PDO::PARAM_STR );
$st->bindValue( ":id", $this->id, PDO::PARAM_INT );
$st->execute();
$conn = null;
}
/**
* Удаляем текущий объект Category из базы данных.
*/
public function delete() {
// У объекта Category есть ID?
if ( is_null( $this->id ) ) trigger_error ( "Category::delete(): Attempt to delete a Category object that does not have its ID property set.", E_USER_ERROR );
// Удаляем категорию
$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$st = $conn->prepare ( "DELETE FROM categories WHERE id = :id LIMIT 1" );
$st->bindValue( ":id", $this->id, PDO::PARAM_INT );
$st->execute();
$conn = null;
}
}
?>
Данный класс очень похож на класс Article и немного проще. Он содержит три свойства, которые соответствуют полям в таблице categories — id, name и description, конструктор __construct(), который создает новый объект Category. Также класс имеет метод storeFormValues() для сохранения данных из формы редактирования, методы для получения одной категории по ID и списка категорий, а также методов для вставки, обновления и удаления категории в базе данных.
Нам нужно включить новый класс Category в наши файлы кода, чтобы CMS могла получить доступ к нему. Поэтому включаем файл с классом в файл config.phpв папке cms, также как мы включали Article.php:
ini_set( "display_errors", true );
date_default_timezone_set( "Australia/Sydney" ); // http://www.php.net/manual/en/timezones.php
define( "DB_DSN", "mysql:host=localhost;dbname=cms" );
define( "DB_USERNAME", "username" );
define( "DB_PASSWORD", "password" );
define( "CLASS_PATH", "classes" );
define( "TEMPLATE_PATH", "templates" );
define( "HOMEPAGE_NUM_ARTICLES", 5 );
define( "ADMIN_USERNAME", "admin" );
define( "ADMIN_PASSWORD", "mypass" );
require( CLASS_PATH . "/Article.php" );
require( CLASS_PATH . "/Category.php" );
function handleException( $exception ) {
echo "Sorry, a problem occurred. Please try later.";
error_log( $exception->getMessage() );
}
set_exception_handler( 'handleException' );
?>
Модифицируем Article
Кроме создания нового класса Category нужно также модифицировать класс Article для работы с категориями. Ниже приводится код файла Article.php:
/**
* Класс для управления статьями
*/
class Article
{
// Свойства
/**
* @var int ID статьи из базы данных
*/
public $id = null;
/**
* @var int Дата публикации статьи
*/
public $publicationDate = null;
/**
* @var int ID категории статьи
*/
public $categoryId = null;
/**
* @var string Полное название статьи
*/
public $title = null;
/**
* @var string Резюме статьи
*/
public $summary = null;
/**
* @var string Содержание HTML статьи
*/
public $content = null;
/**
* Устанавливаем свойства объекта с использованием значений из массива
*
* @param assoc Значения свойств
*/
public function __construct( $data=array() ) {
if ( isset( $data['id'] ) ) $this->id = (int) $data['id'];
if ( isset( $data['publicationDate'] ) ) $this->publicationDate = (int) $data['publicationDate'];
if ( isset( $data['categoryId'] ) ) $this->categoryId = (int) $data['categoryId'];
if ( isset( $data['title'] ) ) $this->title = preg_replace ( "/[^\.\,\-\_\'\"\@\?\!\:\$ a-zA-Z0-9()]/", "", $data['title'] );
if ( isset( $data['summary'] ) ) $this->summary = preg_replace ( "/[^\.\,\-\_\'\"\@\?\!\:\$ a-zA-Z0-9()]/", "", $data['summary'] );
if ( isset( $data['content'] ) ) $this->content = $data['content'];
}
/**
* Устанавливаем свойства объекта с использованием значений из формы
*
* @param assoc Значения из формы
*/
public function storeFormValues ( $params ) {
// Сохраняем все параметры
$this->__construct( $params );
// Разбираем и сохраняем дату публикации
if ( isset($params['publicationDate']) ) {
$publicationDate = explode ( '-', $params['publicationDate'] );
if ( count($publicationDate) == 3 ) {
list ( $y, $m, $d ) = $publicationDate;
$this->publicationDate = mktime ( 0, 0, 0, $m, $d, $y );
}
}
}
/**
* Возвращаем объект Article соответствующий заданному ID
*
* @param int ID статьи
* @return Article|false Объект Article или false, если запись не найдена или в случае другой ошибки
*/
public static function getById( $id ) {
$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$sql = "SELECT *, UNIX_TIMESTAMP(publicationDate) AS publicationDate FROM articles WHERE id = :id";
$st = $conn->prepare( $sql );
$st->bindValue( ":id", $id, PDO::PARAM_INT );
$st->execute();
$row = $st->fetch();
$conn = null;
if ( $row ) return new Article( $row );
}
/**
* Возвращает все (или диапазон) объекты Article из базы данных
*
* @param int Optional Количество возвращаемых строк (по умолчанию = all)
* @param int Optional Вернуть статьи только из категории с указанным ID
* @param string Optional Столбц, по которому выполняется сортировка статей (по умолчанию = "publicationDate DESC")
* @return Array|false Двух элементный массив: results => массив объектов Article; totalRows => общее количество строк
*/
public static function getList( $numRows=1000000, $categoryId=null, $order="publicationDate DESC" ) {
$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$categoryClause = $categoryId ? "WHERE categoryId = :categoryId" : "";
$sql = "SELECT SQL_CALC_FOUND_ROWS *, UNIX_TIMESTAMP(publicationDate) AS publicationDate
FROM articles $categoryClause
ORDER BY " . mysql_escape_string($order) . " LIMIT :numRows";
$st = $conn->prepare( $sql );
$st->bindValue( ":numRows", $numRows, PDO::PARAM_INT );
if ( $categoryId ) $st->bindValue( ":categoryId", $categoryId, PDO::PARAM_INT );
$st->execute();
$list = array();
while ( $row = $st->fetch() ) {
$article = new Article( $row );
$list[] = $article;
}
// Получаем общее количество статей, которые соответствуют критерию
$sql = "SELECT FOUND_ROWS() AS totalRows";
$totalRows = $conn->query( $sql )->fetch();
$conn = null;
return ( array ( "results" => $list, "totalRows" => $totalRows[0] ) );
}
/**
* Вставляем текущий объек Article в базу данных, устанавливаем его ID.
*/
public function insert() {
// Есть уже у объекта Article ID?
if ( !is_null( $this->id ) ) trigger_error ( "Article::insert(): Attempt to insert an Article object that already has its ID property set (to $this->id).", E_USER_ERROR );
// Вставляем статью
$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$sql = "INSERT INTO articles ( publicationDate, categoryId, title, summary, content ) VALUES ( FROM_UNIXTIME(:publicationDate), :categoryId, :title, :summary, :content )";
$st = $conn->prepare ( $sql );
$st->bindValue( ":publicationDate", $this->publicationDate, PDO::PARAM_INT );
$st->bindValue( ":categoryId", $this->categoryId, PDO::PARAM_INT );
$st->bindValue( ":title", $this->title, PDO::PARAM_STR );
$st->bindValue( ":summary", $this->summary, PDO::PARAM_STR );
$st->bindValue( ":content", $this->content, PDO::PARAM_STR );
$st->execute();
$this->id = $conn->lastInsertId();
$conn = null;
}
/**
* Обновляем текущий объект Article в базе данных.
*/
public function update() {
// У объекта Article есть ID?
if ( is_null( $this->id ) ) trigger_error ( "Article::update(): Attempt to update an Article object that does not have its ID property set.", E_USER_ERROR );
// Обновляем статью
$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$sql = "UPDATE articles SET publicationDate=FROM_UNIXTIME(:publicationDate), categoryId=:categoryId, title=:title, summary=:summary, content=:content WHERE id = :id";
$st = $conn->prepare ( $sql );
$st->bindValue( ":publicationDate", $this->publicationDate, PDO::PARAM_INT );
$st->bindValue( ":categoryId", $this->categoryId, PDO::PARAM_INT );
$st->bindValue( ":title", $this->title, PDO::PARAM_STR );
$st->bindValue( ":summary", $this->summary, PDO::PARAM_STR );
$st->bindValue( ":content", $this->content, PDO::PARAM_STR );
$st->bindValue( ":id", $this->id, PDO::PARAM_INT );
$st->execute();
$conn = null;
}
/**
* Удаляем текущий объект Article из базы данных
*/
public function delete() {
// У объекта Article есть ID?
if ( is_null( $this->id ) ) trigger_error ( "Article::delete(): Attempt to delete an Article object that does not have its ID property set.", E_USER_ERROR );
// Удаляем объект Article
$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$st = $conn->prepare ( "DELETE FROM articles WHERE id = :id LIMIT 1" );
$st->bindValue( ":id", $this->id, PDO::PARAM_INT );
$st->execute();
$conn = null;
}
}
?>
Рассмотрим изменения в классе Article подробно:
- Новое свойство categoryId
Чтобы установить соответствие статьи и категории мы добавили свойство categoryId для хранения ID категории, которой принадлежит статья. Также мы модифицировали конструктор __construct() для сохранения нового свойства categoryId в только что созданных объектах Article.
- Изменение метода getList()
Первоначальный вариант метода getList() возвращал все статьи в базе данных (или заданное количество записей). Так как нам нужно, чтобы CMS выводила список статей в определенной категории, модифицируем метод getList() для принятия опционального аргумента $categoryId. Если он задан, то возвращаются статьи только из указанной категории.
Если задан $categoryId, создаем строку $categoryClause для выражения WHERE, чтобы вернуть только те статьи, в которых значение поля categoryId соответствует значению categoryId. Затем модифицируем выражения SQL SELECT для включения переменной $categoryClause. Также добавляем новый вызов к $st->bindValue() для привязки заданного $categoryId.
- Изменяем методы insert() и update()
Также мы модифицировали методы класса Article insert() и update() для работы с новым полем categoryId. Изменили запросы SQL INSERT и UPDATE в каждом методе, и добавили новые вызовы к bindValue() для передачи свойства $categoryId в выражения SQL.
В следующем уроке серии мы изменим шаблоны клиентской и серверной частей для работы с категориями.
Создание класса Category
Также как ранее мы создавали класс Article для управления хранением и выводом статей, нам нужно построить класс Category для решения таких же задач с категориями.
В папке cms имеется каталог classes. В каталоге classes создаем новый файл Category.php и копируем в него следующий код:
Код
/**
* Класс для обработки категорий статей
*/
class Category
{
// Свойства
/**
* @var int ID категории из базы данных
*/
public $id = null;
/**
* @var string Название категории
*/
public $name = null;
/**
* @var string Короткое описание категории
*/
public $description = null;
/**
* Устанавливаем свойства объекта с использованием значений в передаваемом массиве
*
* @param assoc Значения свойств
*/
public function __construct( $data=array() ) {
if ( isset( $data['id'] ) ) $this->id = (int) $data['id'];
if ( isset( $data['name'] ) ) $this->name = preg_replace ( "/[^\.\,\-\_\'\"\@\?\!\:\$ a-zA-Z0-9()]/", "", $data['name'] );
if ( isset( $data['description'] ) ) $this->description = preg_replace ( "/[^\.\,\-\_\'\"\@\?\!\:\$ a-zA-Z0-9()]/", "", $data['description'] );
}
/**
* Устанавливаем свойства объекта с использованием значений из формы редактирования
*
* @param assoc Значения из формы редактирования
*/
public function storeFormValues ( $params ) {
// Store all the parameters
$this->__construct( $params );
}
/**
* Возвращаем объект Category, соответствующий заданному ID
*
* @param int ID категории
* @return Category|false Объект Category object или false, если запись не была найдена или в случае другой ошибки
*/
public static function getById( $id ) {
$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$sql = "SELECT * FROM categories WHERE id = :id";
$st = $conn->prepare( $sql );
$st->bindValue( ":id", $id, PDO::PARAM_INT );
$st->execute();
$row = $st->fetch();
$conn = null;
if ( $row ) return new Category( $row );
}
/**
* Возвращаем все (или диапазон) объектов Category из базы данных
*
* @param int Optional Количество возвращаемых строк (по умолчаниюt = all)
* @param string Optional Столбец, по которому сортируются категории(по умолчанию = "name ASC")
* @return Array|false Двух элементный массив: results => массив с объектами Category; totalRows => общее количество категорий
*/
public static function getList( $numRows=1000000, $order="name ASC" ) {
$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$sql = "SELECT SQL_CALC_FOUND_ROWS * FROM categories
ORDER BY " . mysql_escape_string($order) . " LIMIT :numRows";
$st = $conn->prepare( $sql );
$st->bindValue( ":numRows", $numRows, PDO::PARAM_INT );
$st->execute();
$list = array();
while ( $row = $st->fetch() ) {
$category = new Category( $row );
$list[] = $category;
}
// Получаем общее количество категорий, которые соответствуют критериям
$sql = "SELECT FOUND_ROWS() AS totalRows";
$totalRows = $conn->query( $sql )->fetch();
$conn = null;
return ( array ( "results" => $list, "totalRows" => $totalRows[0] ) );
}
/**
* Вставляем текущий объект Category в базу данных и устанавливаем его свойство ID.
*/
public function insert() {
// У объекта Category уже есть ID?
if ( !is_null( $this->id ) ) trigger_error ( "Category::insert(): Attempt to insert a Category object that already has its ID property set (to $this->id).", E_USER_ERROR );
// Вставляем категорию
$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$sql = "INSERT INTO categories ( name, description ) VALUES ( :name, :description )";
$st = $conn->prepare ( $sql );
$st->bindValue( ":name", $this->name, PDO::PARAM_STR );
$st->bindValue( ":description", $this->description, PDO::PARAM_STR );
$st->execute();
$this->id = $conn->lastInsertId();
$conn = null;
}
/**
* Обновляем текущий объект Category в базе данных.
*/
public function update() {
// У объекта Category есть ID?
if ( is_null( $this->id ) ) trigger_error ( "Category::update(): Attempt to update a Category object that does not have its ID property set.", E_USER_ERROR );
// Обновляем категорию
$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$sql = "UPDATE categories SET name=:name, description=:description WHERE id = :id";
$st = $conn->prepare ( $sql );
$st->bindValue( ":name", $this->name, PDO::PARAM_STR );
$st->bindValue( ":description", $this->description, PDO::PARAM_STR );
$st->bindValue( ":id", $this->id, PDO::PARAM_INT );
$st->execute();
$conn = null;
}
/**
* Удаляем текущий объект Category из базы данных.
*/
public function delete() {
// У объекта Category есть ID?
if ( is_null( $this->id ) ) trigger_error ( "Category::delete(): Attempt to delete a Category object that does not have its ID property set.", E_USER_ERROR );
// Удаляем категорию
$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$st = $conn->prepare ( "DELETE FROM categories WHERE id = :id LIMIT 1" );
$st->bindValue( ":id", $this->id, PDO::PARAM_INT );
$st->execute();
$conn = null;
}
}
?>
Данный класс очень похож на класс Article и немного проще. Он содержит три свойства, которые соответствуют полям в таблице categories — id, name и description, конструктор __construct(), который создает новый объект Category. Также класс имеет метод storeFormValues() для сохранения данных из формы редактирования, методы для получения одной категории по ID и списка категорий, а также методов для вставки, обновления и удаления категории в базе данных.
Нам нужно включить новый класс Category в наши файлы кода, чтобы CMS могла получить доступ к нему. Поэтому включаем файл с классом в файл config.phpв папке cms, также как мы включали Article.php:
Код
ini_set( "display_errors", true );
date_default_timezone_set( "Australia/Sydney" ); // http://www.php.net/manual/en/timezones.php
define( "DB_DSN", "mysql:host=localhost;dbname=cms" );
define( "DB_USERNAME", "username" );
define( "DB_PASSWORD", "password" );
define( "CLASS_PATH", "classes" );
define( "TEMPLATE_PATH", "templates" );
define( "HOMEPAGE_NUM_ARTICLES", 5 );
define( "ADMIN_USERNAME", "admin" );
define( "ADMIN_PASSWORD", "mypass" );
require( CLASS_PATH . "/Article.php" );
require( CLASS_PATH . "/Category.php" );
function handleException( $exception ) {
echo "Sorry, a problem occurred. Please try later.";
error_log( $exception->getMessage() );
}
set_exception_handler( 'handleException' );
?>
Модифицируем Article
Кроме создания нового класса Category нужно также модифицировать класс Article для работы с категориями. Ниже приводится код файла Article.php:
Код
/**
* Класс для управления статьями
*/
class Article
{
// Свойства
/**
* @var int ID статьи из базы данных
*/
public $id = null;
/**
* @var int Дата публикации статьи
*/
public $publicationDate = null;
/**
* @var int ID категории статьи
*/
public $categoryId = null;
/**
* @var string Полное название статьи
*/
public $title = null;
/**
* @var string Резюме статьи
*/
public $summary = null;
/**
* @var string Содержание HTML статьи
*/
public $content = null;
/**
* Устанавливаем свойства объекта с использованием значений из массива
*
* @param assoc Значения свойств
*/
public function __construct( $data=array() ) {
if ( isset( $data['id'] ) ) $this->id = (int) $data['id'];
if ( isset( $data['publicationDate'] ) ) $this->publicationDate = (int) $data['publicationDate'];
if ( isset( $data['categoryId'] ) ) $this->categoryId = (int) $data['categoryId'];
if ( isset( $data['title'] ) ) $this->title = preg_replace ( "/[^\.\,\-\_\'\"\@\?\!\:\$ a-zA-Z0-9()]/", "", $data['title'] );
if ( isset( $data['summary'] ) ) $this->summary = preg_replace ( "/[^\.\,\-\_\'\"\@\?\!\:\$ a-zA-Z0-9()]/", "", $data['summary'] );
if ( isset( $data['content'] ) ) $this->content = $data['content'];
}
/**
* Устанавливаем свойства объекта с использованием значений из формы
*
* @param assoc Значения из формы
*/
public function storeFormValues ( $params ) {
// Сохраняем все параметры
$this->__construct( $params );
// Разбираем и сохраняем дату публикации
if ( isset($params['publicationDate']) ) {
$publicationDate = explode ( '-', $params['publicationDate'] );
if ( count($publicationDate) == 3 ) {
list ( $y, $m, $d ) = $publicationDate;
$this->publicationDate = mktime ( 0, 0, 0, $m, $d, $y );
}
}
}
/**
* Возвращаем объект Article соответствующий заданному ID
*
* @param int ID статьи
* @return Article|false Объект Article или false, если запись не найдена или в случае другой ошибки
*/
public static function getById( $id ) {
$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$sql = "SELECT *, UNIX_TIMESTAMP(publicationDate) AS publicationDate FROM articles WHERE id = :id";
$st = $conn->prepare( $sql );
$st->bindValue( ":id", $id, PDO::PARAM_INT );
$st->execute();
$row = $st->fetch();
$conn = null;
if ( $row ) return new Article( $row );
}
/**
* Возвращает все (или диапазон) объекты Article из базы данных
*
* @param int Optional Количество возвращаемых строк (по умолчанию = all)
* @param int Optional Вернуть статьи только из категории с указанным ID
* @param string Optional Столбц, по которому выполняется сортировка статей (по умолчанию = "publicationDate DESC")
* @return Array|false Двух элементный массив: results => массив объектов Article; totalRows => общее количество строк
*/
public static function getList( $numRows=1000000, $categoryId=null, $order="publicationDate DESC" ) {
$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$categoryClause = $categoryId ? "WHERE categoryId = :categoryId" : "";
$sql = "SELECT SQL_CALC_FOUND_ROWS *, UNIX_TIMESTAMP(publicationDate) AS publicationDate
FROM articles $categoryClause
ORDER BY " . mysql_escape_string($order) . " LIMIT :numRows";
$st = $conn->prepare( $sql );
$st->bindValue( ":numRows", $numRows, PDO::PARAM_INT );
if ( $categoryId ) $st->bindValue( ":categoryId", $categoryId, PDO::PARAM_INT );
$st->execute();
$list = array();
while ( $row = $st->fetch() ) {
$article = new Article( $row );
$list[] = $article;
}
// Получаем общее количество статей, которые соответствуют критерию
$sql = "SELECT FOUND_ROWS() AS totalRows";
$totalRows = $conn->query( $sql )->fetch();
$conn = null;
return ( array ( "results" => $list, "totalRows" => $totalRows[0] ) );
}
/**
* Вставляем текущий объек Article в базу данных, устанавливаем его ID.
*/
public function insert() {
// Есть уже у объекта Article ID?
if ( !is_null( $this->id ) ) trigger_error ( "Article::insert(): Attempt to insert an Article object that already has its ID property set (to $this->id).", E_USER_ERROR );
// Вставляем статью
$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$sql = "INSERT INTO articles ( publicationDate, categoryId, title, summary, content ) VALUES ( FROM_UNIXTIME(:publicationDate), :categoryId, :title, :summary, :content )";
$st = $conn->prepare ( $sql );
$st->bindValue( ":publicationDate", $this->publicationDate, PDO::PARAM_INT );
$st->bindValue( ":categoryId", $this->categoryId, PDO::PARAM_INT );
$st->bindValue( ":title", $this->title, PDO::PARAM_STR );
$st->bindValue( ":summary", $this->summary, PDO::PARAM_STR );
$st->bindValue( ":content", $this->content, PDO::PARAM_STR );
$st->execute();
$this->id = $conn->lastInsertId();
$conn = null;
}
/**
* Обновляем текущий объект Article в базе данных.
*/
public function update() {
// У объекта Article есть ID?
if ( is_null( $this->id ) ) trigger_error ( "Article::update(): Attempt to update an Article object that does not have its ID property set.", E_USER_ERROR );
// Обновляем статью
$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$sql = "UPDATE articles SET publicationDate=FROM_UNIXTIME(:publicationDate), categoryId=:categoryId, title=:title, summary=:summary, content=:content WHERE id = :id";
$st = $conn->prepare ( $sql );
$st->bindValue( ":publicationDate", $this->publicationDate, PDO::PARAM_INT );
$st->bindValue( ":categoryId", $this->categoryId, PDO::PARAM_INT );
$st->bindValue( ":title", $this->title, PDO::PARAM_STR );
$st->bindValue( ":summary", $this->summary, PDO::PARAM_STR );
$st->bindValue( ":content", $this->content, PDO::PARAM_STR );
$st->bindValue( ":id", $this->id, PDO::PARAM_INT );
$st->execute();
$conn = null;
}
/**
* Удаляем текущий объект Article из базы данных
*/
public function delete() {
// У объекта Article есть ID?
if ( is_null( $this->id ) ) trigger_error ( "Article::delete(): Attempt to delete an Article object that does not have its ID property set.", E_USER_ERROR );
// Удаляем объект Article
$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
$st = $conn->prepare ( "DELETE FROM articles WHERE id = :id LIMIT 1" );
$st->bindValue( ":id", $this->id, PDO::PARAM_INT );
$st->execute();
$conn = null;
}
}
?>
Рассмотрим изменения в классе Article подробно:
- Новое свойство categoryId
Чтобы установить соответствие статьи и категории мы добавили свойство categoryId для хранения ID категории, которой принадлежит статья. Также мы модифицировали конструктор __construct() для сохранения нового свойства categoryId в только что созданных объектах Article.
- Изменение метода getList()
Первоначальный вариант метода getList() возвращал все статьи в базе данных (или заданное количество записей). Так как нам нужно, чтобы CMS выводила список статей в определенной категории, модифицируем метод getList() для принятия опционального аргумента $categoryId. Если он задан, то возвращаются статьи только из указанной категории.
Если задан $categoryId, создаем строку $categoryClause для выражения WHERE, чтобы вернуть только те статьи, в которых значение поля categoryId соответствует значению categoryId. Затем модифицируем выражения SQL SELECT для включения переменной $categoryClause. Также добавляем новый вызов к $st->bindValue() для привязки заданного $categoryId.
- Изменяем методы insert() и update()
Также мы модифицировали методы класса Article insert() и update() для работы с новым полем categoryId. Изменили запросы SQL INSERT и UPDATE в каждом методе, и добавили новые вызовы к bindValue() для передачи свойства $categoryId в выражения SQL.
В следующем уроке серии мы изменим шаблоны клиентской и серверной частей для работы с категориями.
-
FalleN -
2337 -
1 -
220
Но только нужно ставить наверное на те модули которые обновляться должны не раньше через пару тройку минут
С Уважением, Андрей...