<?php /* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* # ***** BEGIN LICENSE BLOCK ***** # This file is part of Plume Framework, a simple PHP Application Framework. # Copyright (C) 2001-2006 Loic d'Anterroches and contributors. # # Plume Framework is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; either version 2.1 of the License, or # (at your option) any later version. # # Plume Framework is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # ***** END LICENSE BLOCK ***** */ // We directly load the functions we are often going to use in the // views. This makes the code cleaner. Pluf::loadFunction('Pluf_HTTP_URL_urlForView'); Pluf::loadFunction('Pluf_Shortcuts_RenderToResponse'); Pluf::loadFunction('Pluf_Shortcuts_GetObjectOr404'); Pluf::loadFunction('Pluf_Shortcuts_GetFormForModel'); /** * The views of the Todo application. * * As the application is rather simple, all the views are within one class * but for a complex application views will be spread over several classes. * In that case the recommended structure is to have your views in: * - YourApp/Views/ViewOne.php * - YourApp/Views/ViewTwo.php * * For example, we could have broken the current views of the Todo app in: * - Todo/Views.php : The install/uninstall/main views * - Todo/Views/Item.php : Views related to the items * - Todo/Views/Cat.php : Views related to the categories * * Of course you are flexible to use the structure you want, but a little * ordering eases the maintenance on the long run. * * Each method is answering a request. The method is called by the * dispatcher if a dispatcher is used. The content of each method can * also be directly put into a .php file if no dispatcher is used. */ class Todo_Views { /** * Display the main page of the application. * * The main page is only displaying data. So we load the categories * and for each category we display the corresponding items. * * @param Pluf_HTTP_Request Request object * @param array Matches against the regex of the dispatcher * @return Pluf_HTTP_Response or can throw Exception */ public function main($request, $match) { // In the main page we want a list of all the Todo lists with // a link to edit each of them, a link to see the content and // a link to create a new list. // Get the complete list of Todo_List object $lists = Pluf::factory('Todo_List')->getList(); // Create a context for the template $context = new Pluf_Template_Context(array('page_title' => 'Home', 'lists' => $lists) ); // Load a template $tmpl = new Pluf_Template('todo/index.html'); // Render the template and send the response to the user return new Pluf_HTTP_Response($tmpl->render($context)); } /** * Display the viewItem page of the application. * * @param Pluf_HTTP_Request Request object * @param array Matches against the regex of the dispatcher * @return Pluf_HTTP_Response or can throw Exception */ public function viewItem($request, $match) { // Basically the same as the viewList view but with a Todo_Item $item_id = $match[1]; // We now are loading the corresponding item $item = new Todo_Item($item_id); // And check that the item has been found if ($item->id != $item_id) { return new Pluf_HTTP_Response_NotFound('The item has not been found.'); } // Now we get the list in wich the item is $list = $item->get_list(); // We have the item and the list, just display them. Instead of // creating a context, then a template and then rendering it // within a response object, we are going to use a shortcut // function. Using shortcuts is better as you end up having a // cleaner code. return Pluf_Shortcuts_RenderToResponse('todo/item/view.html', array('page_title' => 'View Item', 'list' => $list, 'item' => $item)); } /** * Display the addItem page of the application. * * @param Pluf_HTTP_Request Request object * @param array Matches against the regex of the dispatcher * @return Pluf_HTTP_Response or can throw Exception */ public function addItem($request, $match) { // The workflow of the addition of an item is simple // If the request of GET method a form is displayed // If it is a POST method, the form is submitted and the // content is proceeded to create the new item. // We create a Todo_Item item as we are creating one here $item = new Todo_Item(); $list = Pluf_Shortcuts_GetObjectOr404('Todo_List', $match[1]); if ($request->method == 'POST') { // We get the data submitted by the user and initialize // the form with. $form = Pluf_Shortcuts_GetFormForModel($item, $request->POST); if ($form->isValid()) { // If no errors, we can save the Todo_Item from the data $item = $form->save(); // We redirect the user to the page of the Todo_List in which // we have created the item. // We redirect the user to the page of the Todo_List // in which we have updated the item. We are using a // shortcut to get the URL directly from the view name // of interest. This allows us to not hard code the // path to the view in the view itself. $url = Pluf_HTTP_URL_urlForView('Todo_Views::viewList', array($item->list)); return new Pluf_HTTP_Response_Redirect($url); } } else { // As we already now the list in which we are going to add // the item, we pass it as initial value. The user can // change it in the select box. $initial = array('list'=>$list->id); $form = Pluf_Shortcuts_GetFormForModel($item, $initial); } // Here we are with a GET request or a POST request with errors // So we create the rendering view of the form // We create a new rendering view return Pluf_Shortcuts_RenderToResponse('todo/item/add.html', array('page_title' => 'Create a Todo Item', 'list' => $list, 'form' => $form)); } /** * Display the updateItem page of the application. * * @param Pluf_HTTP_Request Request object * @param array Matches against the regex of the dispatcher * @return Pluf_HTTP_Response or can throw Exception */ public function updateItem($request, $match) { // Updating an item is somehow like creating an object but you // need first to load it to populate the form The workflow of // the update of an item is simple If the request of GET // method a form is displayed If it is a POST method, the form // is submitted and the content is proceeded to update item. // We create a Todo_Item item as we are updating one here // Here we are going to use another shortcut to get the item // or return a 404 error page if failing. $item = Pluf_Shortcuts_GetObjectOr404('Todo_Item', $match[1]); $new_data = $item->getData(); if ($request->method == 'POST') { // We get the data submitted by the user $form = Pluf_Shortcuts_GetFormForModel($item, $request->POST); if ($form->isValid()) { // The form is valid, we save it. $item = $form->save(); // We redirect the user to the page of the Todo_List // in which we have updated the item. We are using a // shortcut to get the URL directly from the view name // of interest. This allows us to not hard code the // path to the view in the view itself. $url = Pluf_HTTP_URL_urlForView('Todo_Views::viewList', array($item->list)); return new Pluf_HTTP_Response_Redirect($url); } } else { $form = Pluf_Shortcuts_GetFormForModel($item, $item->getData()); } // We proceed the same way by creating a context for a template // and providing the results to the user. return Pluf_Shortcuts_RenderToResponse('todo/item/update.html', array('page_title' => 'Update a Todo Item', 'item' => $item, 'form' => $form)); } /** * Display the deleteItem page of the application. * * @param Pluf_HTTP_Request Request object * @param array Matches against the regex of the dispatcher * @return Pluf_HTTP_Response or can throw Exception */ public function deleteItem($request, $match) { // A delete of an item is like an update. First you check that // the item is available, then you delete it if the request is // a POST request, else you provide a form to ask confirmation // before deletion. $item = Pluf_Shortcuts_GetObjectOr404('Todo_Item', $match[1]); if ($request->method == 'POST') { // Store the list id. $list_id = $item->list; // We can here directly delete the Todo_Item. Note that if // your object is linking to other objects you need to be // sure that you are taking into consideration the // foreignkey and manytomany relationships. $item->delete(); $url = Pluf_HTTP_URL_urlForView('Todo_Views::viewList', array($list_id)); return new Pluf_HTTP_Response_Redirect($url); } // Here we are with a GET request we show a form with a // confirmation button to delete the item. return Pluf_Shortcuts_RenderToResponse('todo/item/delete.html', array('page_title' => 'Delete a Todo Item', 'item' => $item)); } /** * Display the listLists page of the application. * * @param Pluf_HTTP_Request Request object * @param array Matches against the regex of the dispatcher * @return Pluf_HTTP_Response or can throw Exception */ public function listLists($request, $match) { // The list of lists is like the home, so we just return // the same content. return $this->main($request, $match); } /** * Display the viewList page of the application. * * @param Pluf_HTTP_Request Request object * @param array Matches against the regex of the dispatcher * @return Pluf_HTTP_Response or can throw Exception */ public function viewList($request, $match) { // We are showing the content of the list. // That is, all the items in the list. $list = Pluf_Shortcuts_GetObjectOr404('Todo_List', $match[1]); // Now we get the items in the list $items = $list->get_todo_item_list(); // We have the items and the list, just display them // Create a context for the template return Pluf_Shortcuts_RenderToResponse('todo/list/view.html', array('page_title' => 'View List', 'list' => $list, 'items' => $items)); } /** * Display the updateList page of the application. * * @param Pluf_HTTP_Request Request object * @param array Matches against the regex of the dispatcher * @return Pluf_HTTP_Response or can throw Exception */ public function updateList($request, $match) { // Take a look at updateItem() to have explanations. Here you // can see that the code is quite compact without comments. $list = Pluf_Shortcuts_GetObjectOr404('Todo_List', $match[1]); if ($request->method == 'POST') { $form = new Todo_Form_List($request->POST); if ($form->isValid()) { $list->setFromFormData($form->cleaned_data); $list->update(); $url = Pluf_HTTP_URL_urlForView('Todo_Views::viewList', array($list->id)); return new Pluf_HTTP_Response_Redirect($url); } } else { $form = new Todo_Form_List($list->getData()); } return Pluf_Shortcuts_RenderToResponse('todo/list/update.html', array('page_title' => 'Edit a Todo List', 'list' => $list, 'form' => $form)); } /** * Display the deleteList page of the application. * * @param Pluf_HTTP_Request Request object * @param array Matches against the regex of the dispatcher * @return Pluf_HTTP_Response or can throw Exception */ public function deleteList($request, $match) { // Here we show how a list can be delete with the associated // Todo_Item. $list = Pluf_Shortcuts_GetObjectOr404('Todo_List', $match[1]); if ($request->method == 'POST') { // We need first to delete all the Todo_Item in the list. $items = $list->get_todo_item_list(); foreach ($items as $item) { $item->delete(); } // Then we can delete the list $list->delete(); // You can also drop directly the list and the todo items // will be automatically dropped at the same time. $url = Pluf_HTTP_URL_urlForView('Todo_Views::main', array()); return new Pluf_HTTP_Response_Redirect($url); } // Here we are with a GET request we show a form with a // confirmation button to delete the list. // To show the items to be deleted, we get them $items = $list->get_todo_item_list(); return Pluf_Shortcuts_RenderToResponse('todo/list/delete.html', array('page_title' => 'Delete a Todo List', 'list' => $list, 'items' => $items)); } /** * Display the addList page of the application. * * @param Pluf_HTTP_Request Request object * @param array Matches against the regex of the dispatcher * @return Pluf_HTTP_Response or can throw Exception */ public function addList($request, $match) { // The workflow of the addition of an item is simple // If the request of GET method a form is displayed // If it is a POST method, the form is submitted and the // content is proceeded to create the new list. // We create a Todo_List item as we are creating one here $list = new Todo_List(); if ($request->method == 'POST') { // We create the form bounded to the data submitted. $form = new Todo_Form_List($request->POST); if ($form->isValid()) { // If no errors, we can save the Todo_List from the data $list->setFromFormData($form->cleaned_data); $list->create(); // We redirect the user to the page of the Todo_List $url = Pluf_HTTP_URL_urlForView('Todo_Views::viewList', array($list->id)); return new Pluf_HTTP_Response_Redirect($url); } } else { $form = new Todo_Form_List(); } return Pluf_Shortcuts_RenderToResponse('todo/list/add.html', array('page_title' => 'Add a Todo List', 'form' => $form)); } }