Aug
18
Библиотеката за календари е едно от хубавите неща в CodeIgniter. Има още работа по нея, а и има алтернативи - като AJAX-базирани такива. И все пак вграденият календар е доста разчупен и става за качествена работа.
Не знам как са нещата в Kohana, може би Веско ще сподели за Kohana и своя опит календарите.
Та, как да създадем пълнофункционален календар? В сегашното демо имаме база от данни с няколкостотин записа на именици. Искаме да получим информация за имениците през всеки един ден от годината. Затова отваряме един календар, избираме ден от него и - воала - виждаме кой ще празнува тогава.
N.B. демото е относително просто - изпуснати са различни типове проверки, като съм наблегнал главно на възможностите на календара.
Предварителна подготовка
На първо време, трябва ни конфигуриран и готов за начална работа CodeIgniter. Няма да се спирам на конфигурацията на нов проект, но добре е да имаме работещ .htaccess файл, да премахнем index.php от URL адреса и да конфигурираме правилно конфигурационните файлове в system/application/config директорията.
Трябва ни и MySQL с една таблица с 4 полета: id (int, primary key), day (int), month (int) и name (varchar). В нея са попълнени необходимите данни. Могат да бъдат всякакви неща, които се повтарят ежемесечно или ежегодишно и програмата да борави като органайзер - примерно на всяко 18-то число излиза фактурата за телефона, на 2-ро - сметката за тока и т.н. Всеки 5-ти август имаме годишнина, etc.
Имаме 4 основни файла в проекта: welcome.php и schedule.php - 2 контролера и придружаващите ги 2 изгледа: welcome_view.php и schedule_view.php. Първият контролер манипулира календарите, а втория - линковете от тях и връзките с базата от данни.
welcome.php
Welcome е стандартният контролер в CodeIgniter. Ето как изглежда един стандартен адрес на проект на локалния сървър:
http://localhost/project
това е еквивалентно на
http://localhost/project/welcome/index
Първият адрес извиква контролера по подразбиране и входната точка за контролера. В стандартна инсталация това са 'welcome' и 'index'.
При кое да е от двете извиквания календарът ни ще бъде зареден с текущите месец и година. Подавайки параметри на функцията index() обаче можем да изграждаме и календари на базата на други година и месец. Т.е. извикването на
http://localhost/project/welcome/index/2007/11
ще създаде календар за ноември 2007г.
Посредством конфигурацията на календара (част от възможностите на библиотеката) задаваме бутони за предишен и следващ месец. Това ни позволява лесна навигация през месеците за календарната година, както и преминаване в съседните години.
Последната манипулация за входния контролер е задаването на препратки за всеки един ден от месеца. По този начин лесно ще преглеждаме всички празнуващи в конкретния ден
Използваме функцията cal_days_in_month(), за да пресметнем дните в дадения месец и да създадем динамично линковете.
Ето как изглежда контролерът:
<?php class Welcome extends Controller { private $_year = NULL; private $_month = NULL; private $_days_in_month = NULL; function Welcome() { parent::Controller(); // url is required for site_url() and redirect() $this->load->helper('url'); } // inits the object variables private function _initialize($year, $month) { // initialize year - set current one if none selected if($year == NULL) { $this->_year = date('Y'); } else { $this->_year = $year; } // initialize month - set current one if none selected if($month == NULL) { $this->_month = date('n'); } else { $this->_month = $month; } // count days in month $this->_days_in_month = cal_days_in_month(CAL_GREGORIAN, $this->_month, $this->_year); } // loads calendar specific preferences function _getPreferences() { $preferences = array(); $preferences['start_day'] = 'monday'; $preferences['show_next_prev'] = TRUE; $preferences['next_prev_url'] = site_url('welcome/index'); return $preferences; } function index($year = NULL, $month = NULL) { $this->_initialize($year, $month); $preferences = $this->_getPreferences(); $this->load->library('calendar', $preferences); $links = array(); // set active link for each day in month for($day = 1; $day <= $this->_days_in_month; $day++) { $links[$day] = site_url('schedule/index/'. $this->_month. '/'. $day); } // creates the data array that is accessible in the view $data['year'] = $this->_year; $data['month'] = $this->_month; $data['links'] = $links; $data['prefs'] = $preferences; $this->load->view('welcome_view', $data); } } /* End of file welcome.php */ /* Location: ./system/application/controllers/welcome.php */
Изгледът е далеч по-прост: единствената му задача е да създаде календар с линковете и зададени година и месец:
<?= $this->calendar->generate($year, $month, $links) ?>
По подобен начин изглежда календарът за настоящия месец:

schedule.php
Очевидно препратките от календара насочват към нов контролер, а именно schedule.php. Така изглежда един примерен линк:
http://localhost/project/schedule/index/месец/ден
Функцията ни поема месец и ден. За да направим демото по-динамично, месецът и денят ще бъдат използвани при търсенето в базата от данни. За всеки 2 параметъра ще извличаме всички имена, които празнуват на тази дата.
Казахме, че ще пропуснем изграждането на модели. Затова тук използваме една ключова функция:
$this->db->get_where('namedays', array('month' => $month, 'day' => $day));
От таблицата ни извличаме всички записи, които отговарят на параметрите ни ден и месец.
Ето пълното демо:
<?php class Schedule extends Controller { function Schedule() { parent::Controller(); $this->load->helper('url'); } function index($month = NULL, $day = NULL) { if($month == NULL || $day == NULL) { redirect('welcome/index'); } $query = $this->db->get_where('namedays', array('month' => $month, 'day' => $day)); $data['events'] = $query->result(); $this->load->view('schedule_view', $data); } } /* End of file schedule.php */ /* Location: ./system/application/controllers/schedule.php */
View-то ни извежда списък с всички именици:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title>Именици: </title> </head> <body> <ul> <? foreach($events as $event): ?> <li><?= $event->name; ?></li> <? endforeach; ?> </ul> </body> </html>
Скрийншот на 15-ти август, който премина (списъкът ми е беден и ме няма в него :) ):

Скоро ще прикача и активно демо на използваем календар.
Безподобния пост.
Related posts brought to you by Yet Another Related Posts Plugin.


















Доста добре изглежда
Малко писане, а върши доста полезна работа. AJAX-базираният календар също е добър и се интегрира лесно, но в случая гледах да работя с библиотеката.
Смятам още да разпиша за страницирането (pagination) и евентуално за многоезиковата поддръжка.
За многоезиковата поддръжка и аз бих писал, но сърцето ми се къса да я ползвам след като видях в Kohana как е реализирана
И аз правя съпоставка с по-културни реализации, но все пак е добре да се изгради един рутин за лесното й подкарване. Замислям се дали да добавя бързо втори език в един от сайтовете, или да прибегна към могъщата copy-paste технология