Codeigniter. Создаем модель для рейтинга.
И так поехали объяснять как поставить codeigniter,apache и прочее я не буду и изначально расчитываю на набор необходимых знаний , создадим таблицу под нашу будущею систему оценок.
Создаем таблицу, я пишу под mysql, но если у вас есть понимание можно и под psql все сделать и так создаем:
CREATE TABLE `rating`( `rating_id` INT(5) NOT NULL AUTO_INCREMENT, `rate` FLOAT(1), `voted` INT(7), `active` BOOL, PRIMARY KEY (`rating_id`) );
rating_id – наш ключ, по которому мы будем находить оценку и работать с ней
rate – сама оценка
voted – кол-во проголосовавших
active – возможность отключить голосовалку без удаления и вернуть обратно Как же эта система будет взаитмодействовать с другими элементами сайта, да легко. Мы просто
сможем добавить в любую таблицу например article поле rating_id, или в таблицу images то же поле
и привязать к объекту нашу оценку. Для начало создадим конфигурационный файл в папке applicationconfig создаем rating.php
И добавляем в него наши настройки
<?php
$rating_config[‘table_name’] = ‘rating’;
// Максимально допустимая оценка
$rating_config[‘max_rate’] = 10;
//Добавляем к основному конфигу
$config[‘rating_config’] = $rating_config;
?>
Приступим к реализации, создадим в папке applicationmodels файл Rating.php
со следующим значением:
<?
config->load('rating');
if (($this->_table_name = $this->config->item('table_name', 'rating_config')) === FALSE) {
//Если не получил имя таблицы, то выводим окно ошибки
show_error('Не удалось получить имя таблицы в базе данных для системы оценок');
}
$this->_max_rate = $this->config->item('max_rate', 'rating_config');
}
/**
* Создаем оценку
* @param float $rate - Оценка, по умолчанию 0
* @param int $voted - Кол-во проголосовавших
* @param bool $active - Активировать оценку
* @return bool - результат создания объекта
*/
public function create($rate = 0, $voted = 0, $active = true) {
$sql = INSERT INTO . $this->_table_name . (rate,voted,active) VALUES(?,?,?);;
$this->db->query($sql, array($rate, $voted, $active));
if ($this->db->affected_rows() > 0) {
$this->rating_id = $this->db->insert_id();
$this->rate = $rate;
$this->voted = $voted;
$this->active = $active;
return TRUE;
} else {
$this->_clear_rate();
return FALSE;
}
}
/**
* Удаляем оценку
* @param type $id - ид оценки, если не указан ид, то пытается удалить текущий объект
* @return boolean - результат удаления
*/
public function delete($id = false) {
if ($id !== false) {
$this->db->delete($this->_table_name, array('rating_id' => $id));
} else {
if (is_numeric($this->rating_id)) {
$this->db->delete($this->_table_name, array('rating_id' => $this->rating_id));
} else {
return FALSE;
}
}
if ($this->db->affected_rows() > 0) {
if (($id === false) || ($id == $this->rating_id)) {
$this->_clear_rate();
}
return TRUE;
} else {
return FALSE;
}
}
/**
* Клас ищет оценку по ид
* @param type $id - ид оценки
* @param type $active - искать только активные
* @return boolean - true если нашел, ну или false
*/
public function find_by_id($id, $active = true) {
$sql = SELECT rating_id,rate,voted,active FROM . $this->_table_name . WHERE rating_id=?;
$result = null;
if ($active) {
$sql .= AND active=?;
$result = $this->db->query($sql, array($id, $active));
} else {
$result = $this->db->query($sql, array($id));
}
if ($result->num_rows() > 0) {
$tmp = $result->row();
$this->rating_id = $tmp->rating_id;
$this->rate = $tmp->rate;
$this->voted = $tmp->voted;
$this->active = $tmp->active;
return TRUE;
} else {
$this->_clear_rate();
return FALSE;
}
}
/**
* Редактируем данные
* @return boolean результат обновления
*/
public function edit() {
if (is_numeric($this->rating_id)) {
$sql = UPDATE . $this->_table_name . SET rate=?,voted=?,active=? WHERE rating_id=?;
$this->db->query($sql, array($this->rate, $this->voted, $this->active, $this->rating_id));
if ($this->db->affected_rows() > 0) {
return TRUE;
} else {
return FALSE;
}
} else {
return FALSE;
}
}
/**
* Добаляем оценку
* @param type $rate - оценка проголосовавшего
* @param type $id - ид оценки, если не указывать, то попытается использховать текущий объект
* @param type $ret - возращать обновленный объект или нет
* @return boolean если $ret=true, то вернет объект с новыми данными, если $ret=false, то просто вернет true
*/
public function add_rate($rate, $id = FALSE, $ret = TRUE) {
$sql = UPDATE . $this->_table_name . SET voted = voted+1, rate = ROUND(((rate*(voted-1))+?)/voted,1) WHERE rating_id=?;
if ($rate > $this->_max_rate)
$rate = $this->_max_rate;
if ($id !== FALSE) {
$this->db->query($sql, array($rate, $id));
} else {
if (is_numeric($this->rating_id)) {
$this->db->query($sql, array($rate, $this->rating_id));
$id = $this->rating_id;
} else {
return FALSE;
}
}
if ($this->db->affected_rows() > 0) {
if($ret) {
return $this->find_by_id($id);
}
return TRUE;
} else {
return FALSE;
}
}
/**
* Удаляем значения
*/
private function _clear_rate() {
$this->rating_id = NULL;
$this->rate = NULL;
$this->voted = NULL;
$this->active = NULL;
}
}
?>
Как теперь с эти работать.
В контроллере загрузим нашу модель
$this->load->model(‘rating’);
При загрузке выполнится конструктор и проверит указан ли таблица. Далее мы можем создать оценку или найти ее.
Если мы используем данный объект в админке и хотим например для вновь созданой статьи добавить оценку, мы просто инициализируем нашу модель
и создаем оценку:
$this->load->model('rating');
$this->rating->create();
В случае успеха $this->rating->create() вернет true и обновит данные внутри объекта, если же создать не удалось, то вернет false
как пример использования:
$this->load->model(‘rating’);
if($this->rating->create()) {
echo ‘Оценка создана’;
} else {
echo ‘Не получилось создать оценку’;
}
После того, как мы создали объект мы можем получить данные о нем обратившись:
$this->rating->rating_id – получим ид созданой оценки
$this->rating->rate – Текущая общая оценка
$this->rating->voted – Кол-во проголосовавших
$this->rating->active – активна или нет Так же мы можем создавать оценку с уже готовыми параметрами
$this->rating->create(оценку, кол-во проголосовавших, активна или нет) После того как создали объект мы можем передать $this->rating->rating_id в нужную нам модель.
Например у нас есть модель article и в ней есть возможность к статье прикрепить оценку вызвав (article->add_rating($id_raing))
как пример:
$this->load->model(‘rating’);
$this->load->model(‘article’);
if($this->rating->create()) {
$this->article->add_rating($this->rating->rating_id);
}
Как получить нам нашу оценку, наша модель article вернула нам id оценки теперь мы с помощью find_by_id можем получить объект оценку.
Пример:
$this->load->model('rating');
$this->load->model('article');
$rating_id = $this->article->get_rating_id();
if($this->rating->find_by_id($rating_id)) {
echo 'Средняя оценка: '.$this->rating->rate;
echo 'Проголосовало: '.$this->rating->voted;
}
Учтите, что find_by_id ищет оценку только ту у которой параметр active = TRUE, если вы хотите искать по всем оценками, то добавьте второй парамметр
rating_id,false); Редактирование оценки, допустим мы получили оценку и хотим ее сделать не активной, обнулив полностью, тогда код будет такой:
$this->load->model('rating');
$this->load->model('article');
$rating_id = $this->article->get_rating_id();
if($this->rating->find_by_id($rating_id)) {
$this->rating->rate = 0;
$this->rating->voted = 0;
$this->rating->active = false;
if($this->rating->edit()) {
echo 'Данные обновлены';
}
}
Добавление оценки, тут наверно оптимальней использовать ajax и контроллер, который это буедт обрабатовать:
public function add_rating($id, $paramm ) {
//тут всякие проверки и пр
$this->load->model(‘rating’);
if($this->rating->add_rate($paramm,$id)) {
echo ‘Обновленная оценка’;
echo ‘Средняя оценка: ‘.$this->rating->rate;
echo ‘Проголосовало: ‘.$this->rating->voted;
}
}
если мы просто хотим обновить оценку без обновления данных в объекте, то нужно указать 3 параметр в false
paramm,$id,false) просто запишет обновленные данные в базу, сам объект обновлятся не будет.
Так же можно получить объект и добавить оценку:
$this->load->model('rating');
$this->load->model('article');
$rating_id = $this->article->get_rating_id();
if($this->rating->find_by_id($rating_id)) {
$this->rating->add_rate($paramm);
}
Ну практически и все, так же нашу оценку можно удалить вызвав перед этим find_by_id или указав id оценки
пример с id:
$this->load->model('rating');
$this->load->model('article');
$rating_id = $this->article->get_rating_id();
if($this->rating->find_by_id($rating_id)) {
if($this->rating->delete()) echo 'Удален..';
}
Или же:
$this->load->model('rating');
$this->load->model('article');
$rating_id = $this->article->get_rating_id();
if($this->rating->delete($rating_id)) echo 'Удален..';