Codeigniter. Модель для рейтинга, часть 2
И так в прошлой статье мы создали модель для нашего рейтинга, но стандартный способ вызова модели в codeigniter не очень нам подходит, так как не позволяет работать с моделью, как с объектом создавая множество объектов данного типа. Что бы было понятней, в дальнейшем понадобится возвращать внутри объекта каталог, объект оценку и вот тут стандартный способ работы с моделью станет не возможен. При стандартной работе с моделью
$this->load->model(‘rating’);
Создается один объект и последующие вызовы возвращают указатель на этот объект.
В новой версии можно делать так:
$rating = new Rating();
$rating2 = new Rating();
И так изменённая модель Rating
Class Rating {
/**
* Ид оценки
* @var int
*/
public $rating_id = <span style="caps">NULL</span>;
/**
* Общая оценка
* @var float
*/
public $rate = <span style="caps">NULL</span>;
/**
* Кол-во проголосовавших
* @var int
*/
public $voted = <span style="caps">NULL</span>;
/**
* Активна оценка или нет
* @var bool
*/
public $active = <span style="caps">NULL</span>;
/**
* Имя нашей таблицы в бд
* @var string
*/
private $_table_name;
/**
* Максимально возможная оценка
* @var int
*/
private $_max_rate = 5;
private $_CI;
public function __construct() {
$this->_CI = & get_instance();
$this->_CI->config->load(‘rating’);
if (($this->_table_name = $this->_CI->config->item(‘table_name’, ‘rating_config’)) === <span style="caps">FALSE</span>) {
//Если не получил имя таблицы, то выводим окно ошибки
show_error(‘Не удалось получить имя таблицы в базе данных для системы оценок’);
}
$this->_max_rate = $this->_CI->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 = “<span style="caps">INSERT</span> <span style="caps">INTO</span> “ . $this->_table_name . “ (rate,voted,active) <span style="caps">VALUES</span>;”;
$this->_CI->db->query($sql, array($rate, $voted, $active));
if ($this->_CI->db->affected_rows() > 0) {
$this->rating_id = $this->_CI->db->insert_id();
$this->rate = $rate;
$this->voted = $voted;
$this->active = $active;
return <span style="caps">TRUE</span>;
} else {
$this->_clear_rate();
return <span style="caps">FALSE</span>;
}
}
/**
* Удаляем оценку
* param type $id - ид оценки, если не указан ид, то пытается удалить текущий объект
* return boolean – результат удаления
*/
public function delete($id = false) {
if ($id !== false) {
$this->_CI->db->delete($this->_table_name, array(‘rating_id’ => $id));
} else {
if (is_numeric($this->rating_id)) {
$this->_CI->db->delete($this->_table_name, array(‘rating_id’ => $this->rating_id));
} else {
return <span style="caps">FALSE</span>;
}
}
if ($this->_CI->db->affected_rows() > 0) {
if (($id = false) || ($id $this->rating_id)) {
$this->_clear_rate();
}
return <span style="caps">TRUE</span>;
} else {
return <span style="caps">FALSE</span>;
}
}
/**
* Клас ищет оценку по ид
* param type $id - ид оценки
* param type $active – искать только активные
* @return boolean – true если нашел, ну или false
*/
public function find_by_id($id, $active = true) {
$sql = “<span style="caps">SELECT</span> rating_id,rate,voted,active <span style="caps">FROM</span> “ . $this->_table_name . “ <span style="caps">WHERE</span> rating_id=?”;
$result = null;
if ($active) {
$sql .= “ <span style="caps">AND</span> active=?”;
$result = $this->_CI->db->query($sql, array($id, $active));
} else {
$result = $this->_CI->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 <span style="caps">TRUE</span>;
} else {
$this->_clear_rate();
return <span style="caps">FALSE</span>;
}
}
/**
* Редактируем данные
* @return boolean результат обновления
*/
public function edit() {
if (is_numeric($this->rating_id)) {
$sql = “<span style="caps">UPDATE</span> “ . $this->_table_name . “ <span style="caps">SET</span> rate=?,voted=?,active=? <span style="caps">WHERE</span> rating_id=?”;
$this->_CI->db->query($sql, array($this->rate, $this->voted, $this->active, $this->rating_id));
if ($this->_CI->db->affected_rows() > 0) {
return <span style="caps">TRUE</span>;
} else {
return <span style="caps">FALSE</span>;
}
} else {
return <span style="caps">FALSE</span>;
}
}
/**
* Добаляем оценку
* param type $rate - оценка проголосовавшего
* param type $id – ид оценки, если не указывать, то попытается использховать текущий объект
* param type $ret - возращать обновленный объект или нет
* return boolean если $ret=true, то вернет объект с новыми данными, если $ret=false, то просто вернет true
*/
public function add_rate($rate, $id = <span style="caps">FALSE</span>, $ret = <span style="caps">TRUE</span>) {
$sql = “<span style="caps">UPDATE</span> “ . $this->_table_name . “ <span style="caps">SET</span> voted = voted+1, rate = <span style="caps">ROUND</span>)+?)/voted,1) <span style="caps">WHERE</span> rating_id=?”;
if ($rate > $this->_max_rate)
$rate = $this->_max_rate;
if ($id !== <span style="caps">FALSE</span>) {
$this->_CI->db->query($sql, array($rate, $id));
} else {
if (is_numeric($this->rating_id)) {
$this->_CI->db->query($sql, array($rate, $this->rating_id));
$id = $this->rating_id;
} else {
return <span style="caps">FALSE</span>;
}
}
if ($this->_CI->db->affected_rows() > 0) {
if ($ret) {
return $this->find_by_id($id);
}
return <span style="caps">TRUE</span>;
} else {
return <span style="caps">FALSE</span>;
}
}
/**
* Возвращает максимальную оценку
* @return int
*/
public function get_max_rate() {
return $this->_max_rate;
}
/**
* Удаляем значения
*/
private function _clear_rate() {
$this->rating_id = <span style="caps">NULL</span>;
$this->rate = <span style="caps">NULL</span>;
$this->voted = <span style="caps">NULL</span>;
$this->active = <span style="caps">NULL</span>;
}
}
?>
Теперь в папке application/controllers создадим два контроллера
ajax.php – для обработка ajax запросов
rate.php – для тестирования работы код ajax.php
BASEPATH’))
exit(‘No direct script access allowed’);
class Ajax extends CI_Controller {
public function __construct() {
parent::__construct();
}
/**
* Возращает результат добаления оценки
* param type $id - id оценки
* param type $rate – rate оценка
*/
public function rate($id = false, $rate = false) {
if ($id !== false) {
require_once <span style="caps">APPPATH</span> . ‘models/Rating.php’;
$this->load->helper(‘rating’);
$rating = new Rating();
$id = preg_replace(’/[^0-9]/’, ‘’, $id);
if ($rate !== false) {
$rate = preg_replace(’/[^0-9]/’, ‘’, $rate);
$rating->add_rate($rate, $id);
set_rating_cookie(1);
$data[‘rating’] = $rating;
$this->load->view(‘rate/result’, $data);
}
}
}
}
?>
код rate.php
BASEPATH’))
exit(‘No direct script access allowed’);
class Rate extends CI_Controller {
private $rating;
public function __construct() {
parent::__construct();
require_once <span style="caps">APPPATH</span> . ‘models/Rating.php’;
}
/**
*
* @param type $id – ид оценки
*/
public function view($id = false) {
if($id!== false) {
$id = preg_replace(’/[^0-9]/’, ‘’, $id);//оставляем только цифры
$this->rating = new Rating();
if ($this->rating->find_by_id($id)) {
$this->load->view(‘head’);
$data[‘rating’] = $this->rating;
$this->load->helper(‘rating’);
$this->load->view(‘rate/result’, $data);
if(!exist_rating_cookie($this->rating->rating_id)) {
$this->load->view(‘rate/voted’, $data);
}
$this->load->view(‘foot’);
}
} else {
$this->load->view(‘head’);
echo '
# No id rate
';
$this->load->view(‘foot’);
}
}
}
?>
Теперь создадим хелпер для работы с куками в папке application/helpers создаем rating_helper.php
BASEPATH’))
exit(‘No direct script access allowed’);
/**
* Проверяет и устанавливает куки
* param type $rating_id - ид оценки
* return boolean – результат добавления
*/
function set_rating_cookie($rating_id) {
$CI = & get_instance();
$rating = $CI->input->cookie(‘rating’, <span style="caps">TRUE</span>);
if ($rating !== false) {
$rating = unserialize($rating);
if (is_array($rating)) {
if (array_search($rating_id, $rating) === false) {
$rating[] = $rating_id;
} else {
return <span style="caps">FALSE</span>;
}
} else {
$rating = array($rating_id);
}
} else {
$rating = array($rating_id);
}
$cookie = array(
‘name’ => ‘rating’,
‘value’ => serialize($rating),
‘expire’ => ‘86500’, //24 часа
‘secure’ => false
);
$CI->input->set_cookie($cookie);
return <span style="caps">TRUE</span>;
}
/**
* Функция проверяет существует ли заданая кука для оценки
* param type $rating_id - ид оценки
* return boolean – результат существования
*/
function exist_rating_cookie($rating_id) {
$CI = & get_instance();
$rating = $CI->input->cookie(‘rating’, <span style="caps">TRUE</span>);
if ($rating !== false) {
$rating = unserialize($rating);
if (is_array($rating)) {
if (array_search($rating_id, $rating) !== false) {
return <span style="caps">TRUE</span>;
} else {
return <span style="caps">FALSE</span>;
}
} else {
return <span style="caps">FALSE</span>;
}
} else {
return <span style="caps">FALSE</span>;
}
}
?>
В контроллере rate у нас идет вызов 4 представлений
1. head – шапка сайта
2. rate/result – форма вывода результатов голосования
3. rate/voted – форма для голосования
4. foot – подвал сайт Теперь создадим их в папке application/view создаем файл head.php
<br>
function add_rate(id,rate) {<br>
$.ajax({<br>
url: ‘/turcat/ajax/rate/’<ins>id</ins>‘/’+rate, <br>
success: function (data) { <br>
$(#rate).html(data);<br>
$(#action_rate).html(’<p>Ваш голос принят</p>’);<br>
} , <br>
error: function () { <br>
$(#action_rate).html(’<p>Произошла ошибка.</p>’);<br>
} <br>
}); <br>
} <br>
Там же foot.php
Теперь создадим папку rate и в ней 2 файла result.php и voted.php result.php
**Оценка: ** rate; ?>
**Всего проголосовало: ** voted; ?>
voted.php
**Оцените:**
$max = $rating->get_max_rate();
for ($i = 1; $i <= $max; $i++) {
echo ‘[rating_id . ‘,’ . $i . ‘);>’ . $i . ‘](#) ‘;
}
?>
Теперь если мы создадим тестовый рейтинг выполнив запрос к базе:
INSERT INTO rating (rate,voted,active) VALUES(0,0,TRUE); И обратимся к нашему сайту http://ip-addres/путь-к-codeigniter/rate/view/1 Увидим следующую страницу, теперь проголосовав, нажав на одну из оценок, наша система обновит страницу по средствам ajax запроса После чего в куках появится id оценки и на 24 часа вы не сможете больше голосовать.