From 024c69870d7ca64b346dce6cdc65163e93c811b7 Mon Sep 17 00:00:00 2001 From: Oreolek Date: Sat, 18 Jan 2014 15:02:16 +0700 Subject: [PATCH] Working CRUD for subscriptions --- application/classes/Controller/Layout.php | 9 ++ .../classes/Controller/Subscription.php | 106 ++++++++++++++++++ application/classes/Model/Subscription.php | 10 +- application/classes/ORM.php | 21 ++++ application/classes/View/Index.php | 45 +------- application/classes/View/Layout.php | 3 +- .../classes/View/Subscription/Index.php | 29 +++++ application/i18n/ru.php | 14 ++- application/templates/index.mustache | 6 +- .../templates/subscription/index.mustache | 18 +++ 10 files changed, 214 insertions(+), 47 deletions(-) create mode 100644 application/classes/Controller/Subscription.php create mode 100644 application/classes/View/Subscription/Index.php create mode 100644 application/templates/subscription/index.mustache diff --git a/application/classes/Controller/Layout.php b/application/classes/Controller/Layout.php index 9c47617..66ba21c 100644 --- a/application/classes/Controller/Layout.php +++ b/application/classes/Controller/Layout.php @@ -5,6 +5,11 @@ class Controller_Layout extends Controller { protected $is_private = FALSE; public $auto_render = TRUE; public $template = ''; + /** + * Array of CRUD controls (create & edit). + * @see View_Edit + **/ + protected $controls = array(); public function before() { @@ -31,6 +36,10 @@ class Controller_Layout extends Controller { { if ($this->auto_render) { + if (!empty($this->controls)) + { + $this->template->controls = $this->controls; + } $renderer = Kostache_Layout::factory('layout'); $this->response->body($renderer->render($this->template, $this->template->_view)); } diff --git a/application/classes/Controller/Subscription.php b/application/classes/Controller/Subscription.php new file mode 100644 index 0000000..26d5f1b --- /dev/null +++ b/application/classes/Controller/Subscription.php @@ -0,0 +1,106 @@ + 'input', + 'description' => 'textarea', + 'period' => 'input', +// 'price' => 'input' + ); + + public function action_index() + { + $this->template = new View_Subscription_Index; + $this->template->title = __('Subscription index'); + $this->template->items = ORM::factory('Subscription') + ->filter_by_page($this->request->param('page')) + ->find_all(); + } + + public function action_create() + { + $this->template = new View_Edit; + $this->template->model = ORM::factory('Subscription'); + $this->template->title = __('New subscription'); + $this->_edit($this->template->model); + } + + public function action_edit() + { + $this->template = new View_Edit; + $this->template->title = __('Edit subscription'); + $id = $this->request->param('id'); + $model = ORM::factory('Subscription', $id); + if (!$model->loaded()) + { + $this->redirect('error/404'); + } + $this->_edit($model); + } + + public function action_delete() + { + $this->template = new View_Delete; + $id = $this->request->param('id'); + $model = ORM::factory('Subscription', $id); + if (!$model->loaded()) + { + $this->redirect('error/404'); + } + $this->template->title = __('Delete subscription'); + $this->template->content_title = $model->title; + $this->template->content = $model->description; + + $confirmation = $this->request->post('confirmation'); + if ($confirmation === 'yes') { + $post->delete(); + $this->redirect('/'); + } + } + + /** + * Edit or create model. + **/ + protected function _edit($model) + { + if (!($model instanceof ORM)) + { + Log::instance()->add(Log::ERROR, __('Attempt to call _edit() on non-ORM model. Parameter class should be ORM, not ').get_class($model).'.'); + $this->redirect('error/500'); + } + $this->template->errors = array(); + + if ($this->request->method() === HTTP_Request::POST) { + $model->values($this->request->post(), array_keys($this->controls)); + $validation = $model->validate_create($this->request->post()); + $model->customize(); + try + { + if ($validation->check()) + { + $model->save(); + } + else + { + $this->template->errors = $validation->errors('default'); + } + } + catch (ORM_Validation_Exception $e) + { + $this->template->errors = $e->errors('default'); + } + if (empty($this->template->errors)) + { + $this->redirect(Route::url('default', array('controller' => Request::current()->controller(), 'action' => 'view','id' => $model->id))); + } + } + $this->template->model = $model; + } + +} diff --git a/application/classes/Model/Subscription.php b/application/classes/Model/Subscription.php index 169749e..cfcee95 100644 --- a/application/classes/Model/Subscription.php +++ b/application/classes/Model/Subscription.php @@ -18,7 +18,7 @@ class Model_Subscription extends ORM { array('not_empty'), array('min_length', array(':value', 4)), array('max_length', array(':value', 100)), - ) + ), 'description' => array( array('not_empty'), array('min_length', array(':value', 20)), @@ -42,4 +42,12 @@ class Model_Subscription extends ORM { 'period' => 'Mailing period (in days)', 'description' => 'Description (for the clients)' ); + + public function customize() + { + if ($this->period < 1) + { + $this->period = 1; + } + } } diff --git a/application/classes/ORM.php b/application/classes/ORM.php index 4bc796c..3825d25 100644 --- a/application/classes/ORM.php +++ b/application/classes/ORM.php @@ -126,4 +126,25 @@ class ORM extends Kohana_ORM { return $this->where($this->_object_name .'.'. $this->_primary_key, 'IN', $id)->find_all(); return $this->where('id', '=', $id)->find(); } + + /** + * Pagination filter: get only current page + * @param int $num page number (i.e. 1 for first page, 2 - second page and so on). + **/ + public function filter_by_page($num = 0) + { + $num = (int) $num - 1; + if ($num < 0) + { + $num = 0; + } + $page_size = Kohana::$config->load('common.page_size'); + $first_item = $page_size * $num; + return $this->offset($first_item)->limit($page_size); + } + + /** + * A utility function to customize model before saving it + **/ + public function customize() {} } diff --git a/application/classes/View/Index.php b/application/classes/View/Index.php index 391825c..a1b1e08 100644 --- a/application/classes/View/Index.php +++ b/application/classes/View/Index.php @@ -1,4 +1,4 @@ -items) OR $this->items === FALSE OR count($this->items) === 0) { - return 'Не найдено объектов для отображения.'; + return __('No objects found to show'); }; if ($this->item_count === count($this->items)) { @@ -85,53 +85,20 @@ class View_Index extends View_Layout { $this->is_admin = Auth::instance()->logged_in('admin'); } $output = array( - 'date' => '', - 'name' => '', - 'edit_link' => '', - 'view_link' => '', - 'delete_link' => '', + 'view_link' => HTML::anchor(Route::url('default', array('controller' => Request::current()->controller(), 'action' => 'view','id' => $item->id)), $item->name, array('class' => 'link_view')), ); if ($this->show_date) { $output['date'] = $item->posted_at; } - $output['name'] = $item->name; - $output['view_link'] = $this->link_view($item->id); if ($this->is_admin and $this->show_edit) { - $output['edit_link'] = $this->link_edit($item->id); - $output['delete_link'] = $this->link_delete($item->id); + $output['edit_link'] = HTML::anchor(Route::url('default', array('controller' => Request::current()->controller(), 'action' => 'edit','id' => $item->id)), __('Edit'), array('class' => 'link_edit')); + $output['delete_link'] = HTML::anchor(Route::url('default', array('controller' => Request::current()->controller(), 'action' => 'delete','id' => $item->id)), __('Delete'), array('class' => 'link_delete')); } return $output; } - /** - * Generate a link to view item by its ID - * @param integer ID - **/ - protected function link_view($id) - { - return Route::url('default', array('controller' => Request::current()->controller(), 'action' => 'view','id' => $id)); - } - - /** - * Generate a link to edit item by its ID - * @param integer ID - **/ - protected function link_edit($id) - { - return Route::url('default', array('controller' => Request::current()->controller(), 'action' => 'edit','id' => $id)); - } - - /** - * Generate a link to delete item by its ID - * @param integer ID - **/ - protected function link_delete($id) - { - return Route::url('default', array('controller' => Request::current()->controller(), 'action' => 'delete','id' => $id)); - } - /** * Filters $this->items to only current page. **/ @@ -180,7 +147,7 @@ class View_Index extends View_Layout { { if (Auth::instance()->logged_in('admin')) { - return 'Добавить'; + return ''.__('Add').''; } return ''; } diff --git a/application/classes/View/Layout.php b/application/classes/View/Layout.php index a141311..af78189 100644 --- a/application/classes/View/Layout.php +++ b/application/classes/View/Layout.php @@ -68,8 +68,7 @@ class View_Layout { { $result = array(); $navigation = array( -// 'Список страниц' => 'page/index', -// 'О сайте' => 'page/view/1', + __('Subscriptions') => 'subscription/index', ); if (!Auth::instance()->logged_in()) { diff --git a/application/classes/View/Subscription/Index.php b/application/classes/View/Subscription/Index.php new file mode 100644 index 0000000..d9d9963 --- /dev/null +++ b/application/classes/View/Subscription/Index.php @@ -0,0 +1,29 @@ + $item->description, + 'view_link' => HTML::anchor(Route::url('default', array('controller' => Request::current()->controller(), 'action' => 'view','id' => $item->id)),$item->title, array('class' => 'link_view')), + 'edit_link' => HTML::anchor(Route::url('default', array('controller' => Request::current()->controller(), 'action' => 'edit','id' => $item->id)), __('Edit'), array('class' => 'link_edit')), + 'delete_link' => HTML::anchor(Route::url('default', array('controller' => Request::current()->controller(), 'action' => 'delete','id' => $item->id)), __('Delete'), array('class' => 'link_delete')), + ); + return $output; + } +} diff --git a/application/i18n/ru.php b/application/i18n/ru.php index d2cccee..0b3682e 100644 --- a/application/i18n/ru.php +++ b/application/i18n/ru.php @@ -12,7 +12,17 @@ return array( 'Mailing period (in days)' => 'Период рассылки (в днях)', 'Description (for the clients)' => 'Описание (для клиентов)', 'Email' => 'Email', - 'Subscription token' => 'Токен подписки', + 'Subscription token' => 'Токен рассылки', 'Mailing date' => 'Дата отправки', - 'Status' => 'Статус' + 'Status' => 'Статус', + 'Subscriptions' => 'Рассылки', + 'No objects found to show' => 'Не найдено объектов для отображения.', + 'Add' => 'Добавить', + 'Edit' => 'Редактировать', + 'Delete' => 'Удалить', + 'Attempt to call _edit() on non-ORM model. Parameter class should be ORM, not ' => 'Попытка вызвать __edit() на не-ORM модели. Класс параметра должен быть ORM, а не ', + 'New subscription' => 'Новая рассылка', + 'Subscription index' => 'Все рассылки', + 'Delete subscription' => 'Удалить рассылку', + 'Edit subscription' => 'Редактировать рассылку' ); diff --git a/application/templates/index.mustache b/application/templates/index.mustache index 553fb97..c36d142 100644 --- a/application/templates/index.mustache +++ b/application/templates/index.mustache @@ -10,10 +10,10 @@ {{#date}}
{{date}}
{{/date}} -
{{{name}}}
+
{{{view_link}}}
{{#edit_link}} -
Редактировать
-
Удалить
+
{{{edit_link}}}
+
{{{delete_link}}}
{{/edit_link}} {{/get_items}} diff --git a/application/templates/subscription/index.mustache b/application/templates/subscription/index.mustache new file mode 100644 index 0000000..c0e63f9 --- /dev/null +++ b/application/templates/subscription/index.mustache @@ -0,0 +1,18 @@ +{{#show_create}} + {{{link_new}}} +{{/show_create}} +
+ {{{content}}} +
+ +{{#get_items}} + + + + {{#edit_link}} + + + {{/edit_link}} + +{{/get_items}} +
{{{view_link}}}{{{description}}}{{{edit_link}}}{{{delete_link}}}