Powered by CodeIgniter

Уроки

(28)
14
16 голосов
Учиться, учиться и еще раз учиться — развитие личности идет таким путем.
screenshot-2009-10-20-v-15.07.34.png Друзья, продолжаем реализацию намеченных планов. Сегодня речь пойдет о создании шестеренки инвайтов, которая позволит ограничить регистрацию на сайте или же вовсе закрыть доступ для нежелательных гостей.
Реализация, предложенная мною, обеспечивает только базовый функционал шестеренки. При наличии желания вы можете добавить собственный функционал.

Файловая структура

Как обычно, создадим каркас шестеренки.

screenshot-2009-10-20-v-15.28.22.png

Файл конфигурации

Все стандартно, без особых новшеств. Добавим только лишь параметр, позволяющий закрыть доступ для неавторизированных пользователей.
;================================================== ; Invites config ;================================================== title = Invites description = Access to site or register via invite only core = 1.0 group = modules position = 1 enabled = FALSE access_mode = FALSE

База данных

Создадим дамп таблицы, который будет исполнен при установке шестеренки.
/gears/invites/install.sql:
CREATE TABLE IF NOT EXISTS `invites` ( `id` int(10) unsigned NOT NULL auto_increment, `from` int(10) unsigned NOT NULL default '1', `to` int(10) unsigned default NULL, `invite` varchar(255) NOT NULL, PRIMARY KEY (`id`), KEY `from` (`from`), KEY `to` (`to`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;

Интернационализация

Создадим файл с языковыми переменными.
/gears/invites/lang/ru.lng:
[gears] invites = "Инвайты" invites_description = "Регистрация только по приглашениям." [invites] gift = "Раздача приглашений" title = "Доступ только для участников сообщества" invite = "Приглашение" invites = "Приглашения" invite_description = "Регистрация только по приглашениям."; invited = "Приглашенные" no_such_invite = "Такого приглашения не существует или оно уже было использовано!" ;-------------------------------------------------- ; Control Panel ;-------------------------------------------------- total_invited = "Зарегистрировавшихся по приглашению" total_invites = "Общее количество свободных приглашений" users = "Кто получит приглашения?" users_description = "Вы можете ввести имена пользователей через запятую или же поставить знак <strong>*</strong>, чтобы приглашения получили все пользователи."; count = "Количество приглашений"; added = "Приглашения отправлены"; grab = "Отобрать приглашения?"; grab_description = "Все с точностью да наоборот."; grabbed = "Приглашения отобраны"; access_mode = "Ограничение доступа к сайту" access_mode_description = "Пользователь без авторизации не сможет увидеть содержимое сайта."

Хуки

Итак, нам потребуются хуки для следующих действий:
  • Переадресация на страницу авторизации для незарегистрированных пользователей, в случае, если в настройках включен соответствующий параметр.
  • Добавление поля ввода для инвайта в форму регистрации.
  • Сохранение id пользователя в таблице инвайтов после регистрации (для завершения цепочки «пригласивший — приглашенный»).
  • Проверка правильности инвайта в форме регистрации.
  • Добавление списка кодов инвайтов в профиль пользователя.
/gears/invites/_hooks.php:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); /** * CoGear * * Content management system based on CodeIgniter * * @package CoGear * @author CodeMotion, Dmitriy Belyaev * @copyright Copyright © 2009, CodeMotion * @license http://cogear.ru/license.html * @link http://cogear.ru * @since Version 1.0 * @filesource */ // ------------------------------------------------------------------------ /** * Invites hooks * * @package CoGear * @subpackage Invites * @category Gears hooks * @author CodeMotion, Dmitriy Belyaev * @link http://cogear.ru/user_guide/ */ /** * Redirect to login form if 'access_mode' param is enabled and user is not registered * * @param object * @return void */ function invites_header($CI){ if($CI->gears->invites->access_mode && !$CI->user->get('id')){ if($CI->name != 'user' && !in_array('ajax',$CI->uri->segments)){ redirect('/user/login'); } else { title(t('invites title'),TRUE,TRUE); } } } // ------------------------------------------------------------------------ /** * Add invite field into register form * * @param object * @return void */ function invites_form_result_($Form){ $CI =& get_instance(); if($Form->name == 'register' && !$CI->user->get('id')){ d('invites'); $Form->input('invite',array('validation'=>'required|check_invite','js_validation'=>'required|length[5,-1]'),6); d(); } } // ------------------------------------------------------------------------ /** * Add user id to invites table after registration is complete * * @param object * @param array * @return void */ function invites_form_save_after_($Form,$result){ if($Form->name == 'register'){ $CI->db->update('invites',array('to'=>$Form->insert_id),array('invite'=>$result['invite'],'to'=>NULL)); } } /** * Check for invite * * @param string * @return boolean */ function check_invite($invite){ $CI =& get_instance(); $CI->form_validation->set_message('check_invite', t('!invites no_such_invite')); return $CI->db->get_where('invites',array('invite'=>$invite,'to'=>NULL))->row() ? TRUE : FALSE; } // ------------------------------------------------------------------------ /** * Show user invites in profile * * @param object * @return void */ function invites_panel_compile_($Panel){ if($Panel->name == 'userinfo_profile'){ $CI =& get_instance(); $item['type'] = 'line'; if($CI->user->get('id') == $Panel->data->id){ $item['left'] = fc_t('!invites invites'); $query = $CI->db->select('invite')->get_where('invites',array('from'=>$CI->user->get('id'),'to'=>NULL))->result_array(); if($query){ foreach($query as $invite){ $invites[] = $invite['invite']; } $item['right'] = isset($invites) ? $CI->builder->div(implode(' ',$invites),'hide-show') : t('!invites no_invites'); $Panel->add($item,6); $item['left'] = fc_t('!invites invited'); $query = $CI->db->select('users.name,users.url_name')->join('users','users.id = invites.to','inner')->get_where('invites',array('from'=>$CI->user->get('id'),'to'=>'IS NOT NULL'))->result_array(); } if($query){ foreach($query as $invite){ $invited[] = $CI->builder->a($user['name'],l('/user/'.$user['url_name']),'user '.($CI->buddy->check($user['name']) !== FALSE ? 'buddy' : FALSE)); } $item['right'] = isset($invited) ? implode(', ',$invited) : t('!invites no_invited'); $Panel->add($item,7); } } } } // ------------------------------------------------------------------------ // ------------------------------------------------------------------------

Панель управления

Дает возможность раздавать инвайты пользователям, а также редактировать настройки шестеренки.
/gears/invites/_admin.php:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); /** * CoGear * * Content management system based on CodeIgniter * * @package CoGear * @author CodeMotion, Dmitriy Belyaev * @copyright Copyright © 2009, CodeMotion * @license http://cogear.ru/license.html * @link http://cogear.ru * @since Version 1.0 * @filesource */ // ------------------------------------------------------------------------ /** * Invites CP controller * * @package CoGear * @subpackage Invites * @category Gears controllers * @author CodeMotion, Dmitriy Belyaev * @link http://cogear.ru/user_guide/ */ class _Admin extends Controller{ /** * Constructor * * @return void */ function _Admin(){ parent::Controller(); d('invites'); $this->invites_tabs = new Panel('invites_tabs',FALSE,FALSE,'tabs'); $this->invites_tabs->set_title = TRUE; $this->invites_tabs->links_base = '/admin/invites/'; $this->invites_tabs->add(array('name'=>'index','text'=>fc_t('%settings'),'index'=>TRUE)); $this->invites_tabs->add(array('name'=>'gift','text'=>fc_t('gift'))); $this->invites_tabs->set_active(empty($this->uri->segments['3']) ? 'index' : $this->uri->segments['3']); $this->invites_tabs->compile(12); } // ------------------------------------------------------------------------ /** * Index method * * @return */ function index(){ $this->form->set('admin/invites') ->checkbox('access_mode') ->buttons('save') ->set_values($this->gears->invites); if($result = $this->form->result(TRUE)){ $this->info->set(GEARS.'invites/invites')->change('access_mode',$result['access_mode'])->compile(); msg(t('form saved')); $this->form->set_values($result); } $this->form->compile(); } /** * Show invites statistics, create invites * * @return void */ function gift(){ $this->form->set('invites') ->input('users',array('validation'=>'required')) ->input('count',array('validation'=>'required|is_natural_no_zero','js_validation'=>'required|digit')) ->checkbox('grab') ->buttons('create'); if($result = $this->form->result(TRUE)){ if(trim($result['users']) == '*'){ $users = array4key($this->db->select('url_name')->order_by('id','asc')->get('users')->result_array(),FALSE,'url_name'); } else $users = explode(',',$result['users']); $this->load->library('encrypt'); foreach($users as $user){ if($user = $this->user->info(url_name($user))){ if($result['grab']){ $this->db->limit($result['count'])->delete('invites',array('invites.from'=>$user->id,'invites.to'=>NULL)); } else { for($i = 0; $i < $result['count']; $i++){ $data = array( 'datetime'=>date('H:i:s d.m.Y'), 'username'=>$user->name, 'count'=>$i ); $invite = $this->encrypt->sha1(serialize($data)); $this->db->insert('invites',array('invites.from'=>$user->id,'invite'=>$invite)); } } } } msg(t('!invites '.(isset($result['grab']) ? 'grabbed' : 'added')),TRUE); } $this->form->compile(); $total_invited = $this->db->where('invites.to IS NOT NULL')->count_all_results('invites'); $this->builder->div(TRUE,'line',TRUE); $this->builder->div(t('total_invited'),'left',TRUE); $this->builder->div($total_invited,'right',TRUE); $this->builder->div(FALSE,'line',TRUE); $total_invites = $this->db->where('invites.to IS NULL')->count_all_results('invites'); $this->builder->div(TRUE,'line',TRUE); $this->builder->div(t('total_invites'),'left',TRUE); $this->builder->div($total_invites,'right',TRUE); $this->builder->div(FALSE,'line',TRUE); $this->builder->div('','clear',TRUE); d(); } // ------------------------------------------------------------------------ } // ------------------------------------------------------------------------

Заключение

Не забудьте активировать шестеренку в панели управления.

firefox-2.png

Дистрибутив обновлен.
15:52 ← 20 октября 2009 Отправить в Твиттер adminadmin  RSS comments 14

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

inetlover inetlover time 18:00 ← 20 октября 2009 #
Движок становится, все серьезнее и серьезнее, спасибо автору за полезную шестеренку!
Автор
admin admin time 18:00 ← 20 октября 2009 #
Пожалуйста.
JiLiZART JiLiZART time 19:47 ← 20 октября 2009 #
Всё больше убеждаю себя в гениальности данного движка =) не встречал из русских открытых движков более крутого чем этот =) браво, как всегда браво.
Ildar Ildar time 19:49 ← 20 октября 2009 #
Супер движок! Как будет время начну делать сайт на данном движке.
Автор
admin admin time 19:51 ← 20 октября 2009 #
Захвалили. Не хватает мнения матерого программиста, который выскажет негатив по поводу кода и производительности.
Minister Minister time 21:11 ← 20 октября 2009 #
Нада бы глянуть твой код и поматерить тебя как следует, если оно того стоит :))
Только бы вот времени где достать свободного. Впрочем чего жаловаться. Я слежу за развитием этого движка и честно рад за то, что Дима его продолжается развивать в лучшую сторону. А так я конечно бы и сам написал сайт на этом движке, как только доберусь до плотного изучения движка.
Fr3nzy Fr3nzy time 20:42 ← 21 октября 2009 #
Горизонт завален ;)
Автор
admin admin time 20:43 ← 21 октября 2009 #
Хоть что-то :-)
imdogma imdogma time 21:40 ← 20 октября 2009 #
Здорово! Осталось только урока по темизации дождаться!
mobman mobman time 20:35 ← 21 октября 2009 #
Отличный урок! Нужная вещь!
Ildar Ildar time 15:51 ← 19 ноября 2009 #
А когда будет урок, по созданию тем? а в то в папке дефлаут только 2 файла, и непонятно что да как.
Автор
admin admin time 15:57 ← 19 ноября 2009 #
По мере возможности. Кроме движка в жизни есть еще много чего интересного.
P.S. Я не робот :-)
Ildar Ildar time 16:03 ← 19 ноября 2009 #
Да я понимаю, но скажите в каких файлах еще копать дизайн?
Автор
admin admin time 16:06 ← 19 ноября 2009 #
Смотрите по маске — /gears/*/templates/*.