Powered by CodeIgniter

Уроки

(28)
14
16 голосов
Учиться, учиться и еще раз учиться — развитие личности идет таким путем.
Урок создания компонента рейтинга Друзья, данной статьей открываю новое сообщество. Как вы уже догадались, в нем будут публиковаться «туториалы» (от англ. «tutorials»), т.е. уроки.
Как и обещал, но несколько ранее, мы с вами вместе создадим систему рейтингов и фильтрации контента, чему будет посвящен цикл статей.
Первым делом внесем изменения в уже существующую шестеренку «index».
Начнем мы с того, что создадим представление о топике на главной странице. Чем он будет отличаться от других? Быть может создать отдельную, связующую таблицу топиков «вообще» и «на главной»? А вот и нет. Самое правильное действие — всегда самое простое. Поэтому мы просто добавим поле в таблице «nodes», которое будет отвечать за то, попадает топик на главную или нет.
Создадим поле «promoted» типа «enum» (два возможных значения — true и NULL). Можно, конечно, было использовать тип «tinyint», но нам лишние значения не нужны — только все самое необходимое. Также создадим индекс на данном поле для того, чтобы база данных отдавала предпочтение хранению информацию в оперативной памяти более, чем на диске.
ALTER TABLE `nodes` ADD `promoted` ENUM( 'true' ) NULL AFTER `published` , ADD INDEX ( `promoted` ) Обратимся к контроллеру "/gears/index/index.php" и добавим новое условие выборки на 68 (для счетчиков) и 77 (для запроса) строки.
$this->db->where('promoted','true'); Теперь было бы здорово дать администратору возможность снимать и назначать топики на главную страницу вручную.
Для этого добавим после заголовка «галочку», видимую лишь тем пользователям, которым это будет разрешено через шестеренку «Права доступа» (админу можно все).
Откроем файл хуков "/gears/index/_hooks.php". Создадим новый хук в виде функции «index_breadcrumb_compile_». Заголовок топика представлен моделью «хлебных крошек» для того, чтобы обеспечить расширяемость, и мы этим воспользуемся.
Название хука состоит из трех частей:
  • index — хуком заведует шестеренка «index».
  • breadcrumb — хук адресован модели (суффикс "_" в конце названия функции указывает на то, что хук действует на модель) «хлебных крошек».
  • compile — хук действует на метод compile (в классе он назван _compile для обеспечения возможности работы с хуками).
Для того чтобы узнать количество аргументов, посмотрим в код адресованного метода файла "/gears/global/models/breadcrumb.php". Существующие параметры для нас не важны, поэтому хук принимает только лишь один параметр — саму модель «хлебных крошек» (хук контроллера принимал бы сущности движка — $CI).
Также обратимся к модели ноды "/gears/nodes/models/node.php" с целью выяснить, какое имя носит объект «breadcrumb», участвующий в создании заголовка топика.
/** * Add checkbox to node title breadcrumb * * @param object Breadcrumb * @return void */ function index_breadcrumb_compile_($Breadcrumb){ if($Breadcrumb->name == 'node_title' && acl('index promote')){ $node =& $Breadcrumb->data; // If node is already on index page — checbox will be checked $value = empty($node->promoted) ? '' : 'value="checked"'; $Breadcrumb->add('<input type="checkbox" class="index-promote" id="index-promote-'.$node->id.'"'.$value.'>'); } } Отлично, около названия топика появился checkbox, причем с главной все топики исчезли.

checkbox у заголовка топика


Теперь следует прицепить на клик по чекбоксу скрипт и добавить языковую переменную.
Откроем файл "/gears/index/lang/ru.lng" и добавим строчки:
[acl] promote = "Выводить топики на главную" Помните, что все изменения в языковых файлах фиксируются автоматически при отключенном кеше.
Создадим файл "/gears/index/js/promote.js", который будет ответственным по данному вопросу.
window.addEvent('domready',function(){ $$('input.index-promote').each(function(checkbox){ checkbox.addEvent('click',function(){ var nid = this.get('id').split('-').getLast(); new Request.JSON({ url: "/ajax/index/promote/", data: 'nid='+nid, method: 'post', onComplete: function(re){ msg(re.msg); } }).post(); }); }); }); Помните, что js-файлы также подключаются автоматически.
Конечно, данный запрос кто-то должен обрабатывать, поэтому добавим метод «promote» в контроллер "/gears/index/index.php".
/** * Promote node to index * * @return json */ public function promote(){ // Check access level if(!acl('index promote')) return _403(); // Catch node id and some kind of filter it $nid = (int)$this->input->post('nid'); // Predefine results in case of errors $success = FALSE; $msg = t('promote_error'); // Get node if($node = $this->db->get_where('nodes',array('id'=>$nid))->row()){ // Set i18n section/department d('index'); $promote = empty($node->promoted) ? 'true' : NULL; if($this->db->update('nodes',array('promoted'=> $promote),array('id'=>$node->id))){ $this->cache->tags('nodes/'.$node->id)->clear(); $success = TRUE; $msg = empty($promote) ? t('depromoted') : t('promoted'); } } ajax($success,$msg); } Обновим языковой файл.
[acl] promote = "Выводить топики на главную" always_on_index = "Топики пользователя всегда выводятся на главную" [index] promoted = "Топик отправлен на главную страницу." depromoted = "Топик снят с главной страницы." promote_error = "Не удалось изменить статус топика." Последний штрих — сделаем так, чтобы топики админа и других пользователей, обладающих соответствующими правами, всегда выводились на главную. Для этого создадим хук, который будет срабатывать при сохранении данных формой создания топика.
/** * Add node to index after topic is created * * @param object Form * @param boolean result * @return void */ function index_form_save_after_($Form,$result){ if($Form->name == 'node_createdit' && acl('index always_on_index') && !empty($result)){ $Form->db->update('nodes',array('promoted'=>'true'),array('id'=>$Form->insert_id)); } } Обратите внимание, поскольку мы хотим, чтобы хук сработал после метода «save», то задаем суффикс «after» в названии хука. В этом случае вторым аргументом принимается результат, а после него — параметры адресуемого метода (в данном случае они опущены в силу ненадобности).
Дистрибутив обновлен.
18:51 ← 11 сентября 2009 Отправить в Твиттер adminadmin  RSS comments 25

Комментарии (25) ↓

Автор
admin admin time 23:59 ← 11 сентября 2009 #
Кто понял суть урока — поднимите руку! :-)
Boga Boga time 00:02 ← 12 сентября 2009 #
Дим, извини что не по теме, но ты не перестаешь меня удивлять своими идеями!
Спасибо большое за «how to» сообщество, это очередная гениальная и очень нужная идея. Спасибо!
Автор
admin admin time 00:08 ← 12 сентября 2009 #
Пожалуйста! Стремлюсь хотя бы как-то приблизиться к реализации большей части идей :-)
Понял важную вещь — если ты что-то придумал интересное, то нельзя и желать, что бы другие люди сразу же осознали твои идеи. Следует донести до них путеводную нить — информацию, которая поможет им встать на путь осмысления твоих идей.
Надеюсь, что из данного топика понятно, насколько у движка гибкая архитектура.
JiLiZART JiLiZART time 06:36 ← 12 сентября 2009 #
Я это понял как только перечитал весь код. Понял что на нём можно сделать всё :-D
Приятный урок =)
combat combat time 18:53 ← 12 сентября 2009 #
объясните пожалуйста, я сделал sql запрос:
ALTER TABLE `nodes` ADD `promoted` ENUM( 'true' ) NULL AFTER `published`,
ADD INDEX ( `index` )
и выдало ошибку:
#1072 — Key column 'index' doesn't exist in table
что это значит? И на главной выскакивает сообщение:
A Database Error Occurred
Error Number: 1054
Unknown column 'promoted' in 'where clause'
SELECT COUNT(nodes.id) AS numrows FROM (nodes) LEFT JOIN `community` ON `community`.`id` = `nodes`.`cid` INNER JOIN users ON users.id = nodes.aid WHERE `promoted` = 'true' AND `community`.`private` IS NULL AND `nodes`.`published` IS NOT NULL AND `nodes`.`created_date` < '2009-09-12 19'
Автор
admin admin time 20:44 ← 12 сентября 2009 #
Моя вина — когда писал статью, поле назвал «index». Когда написал, понял, что называть колонку «index» не хорошо в плане синтаксиса MySQL, переименовав ее в «promoted». После уже правил статью, проглядел строчку.
combat combat time 19:23 ← 12 сентября 2009 #
Все разобрался, при отправки запроса, ADD INDEX ( `index` ) не прописалась в бд, пришлось вручную. Объясните пожалуйста, вот после обновления пришлось все уже написанные новости по новой выводить на главную, причем, заходя в блоги написавших, но нигде не обозначилось например «новая записи», щелкнув по этому сообщению можно было бы попасть в не опубликованные на главной посты и выбрать что отправлять, а что нет на главную.
Автор
admin admin time 20:47 ← 12 сентября 2009 #
ADD INDEX ('promoted'). Да, действительно, давайте сделаем такую ссылку. Где ее лучше разместить?
combat combat time 21:40 ← 12 сентября 2009 #
в верхнем меню, оптимальный вариант
BerikIushi BerikIushi time 11:45 ← 13 сентября 2009 #
Создадим поле «index» типа «enum» (два возможных значения — true и NULL).
Здесь наверное тоже не «index» а «promoted»
Автор
admin admin time 15:54 ← 13 сентября 2009 #
Верно, исправил.
combat combat time 21:44 ← 13 сентября 2009 #
только сегодня заметил — влез в бд, а там аж почти 800 юзеров зарегистрировано — не плохо спамеры постарались, я так понимаю движок не очень защищен от этой болезни, можно что нибудь изменить?
Автор
admin admin time 23:50 ← 13 сентября 2009 #
Какой сайт? Может юзеры настоящие? :-D
Можно капчу CodeIgniter заменить на reCaptcha.
combat combat time 08:37 ← 14 сентября 2009 #
может как дополненительную защиту добавить контрольный вопрос? типа сколько будет 2+2 или столица России…
Автор
admin admin time 09:27 ← 14 сентября 2009 #
Посмотрел рекапчу и решил не связываться с ней. Она требует регистрации и получения ключа доступа к API. Не хочу, чтобы знакомство с cogear начиналось с этого.
Переработал обычную капчу, убрав из нее контрольные слова по-умолчанию. Теперь капча генерируется произвольным образом.
combat combat time 08:10 ← 14 сентября 2009 #
да нет, юзеры не настоящие, там только 3 настоящих это я точно знаю, сайт www.galstudio.org/. У многих лжеюзеров нету емайла в бд, логины типа sasestdtrfti ну и т.д. и это всего за неделю-другую, а что будет за месяц иди год. нет нужно что-то делать, а то и посты в скором времени левые будут появлятся, если хотите дамп бд users скину, посмотрите
Автор
admin admin time 08:22 ← 14 сентября 2009 #
В принципе, капча CodeIgniter — и не капча вовсе. Ее очень легко подобрать.
Хорошо, тогда следующим уроком будет переход на reCaptcha, а после уже — рейтинги.
dqpb dqpb time 15:07 ← 14 сентября 2009 #
Инвайты, как альтернатива.
Автор
admin admin time 15:11 ← 14 сентября 2009 #
Хорошо, будет урок, как сделать инвайты.
Daron Daron time 09:50 ← 15 сентября 2009 #
Да да да
Инвайты по любому :)
fjey fjey time 23:09 ← 14 сентября 2009 #
upd: извиняюсь, не туда написал.
inetlover inetlover time 11:27 ← 21 сентября 2009 #
Все описанное в посте, просто гениально!
inetlover inetlover time 10:42 ← 24 сентября 2009 #
Не нашел куда написать, напишу сюда в Уроки.

Решил для начала разобраться с виджетами, как они устроены (внешний вид, заголовки), попробовал повторить виджет Stats и вот возник вопрос. А именно, хочу уточнить количество созданных файлов в этом примере. Я насчитал 3:
  • stats/widgets/stats.php
  • stats/widgets/stats.info
  • stats/lang/ru.lng
Но как минимум, в папке stats должен быть еще один файл stats.info, что бы в админке в боковой панели мы увидели созданный виджет stats /*Скриншот*/

Вот хотелось попросить, а нельзя ли сделать простенький урок по виджетам?

Содержание урока:

  1. На примере виджета Stats показать, как можно визуально сделать его похожим на виджет На сайте или Сообщества в рамочке и как сделать без нее как у виджетов Поиск или Теги
  2. Как можно расположить виджеты с правой стороны, а не с левой как сейчас
  3. Как в низ виджета добавить ссылку, например: все сообщества или все комментарии.
P.S. Если это все просто и не заслуживает урока, то можно тогда выложить архив с самым простым виджетом, хотя бы тот же Stats
С уважением.
Автор
admin admin time 23:13 ← 25 сентября 2009 #
Хорошо, сделаю урок по виджетам в порядке очереди.
inetlover inetlover time 12:06 ← 26 сентября 2009 #
Спасибо!