Previo a incluir los nuevos métodos en nuestro controlador, no podemos olvidar que hemos de espeficar a las rutas de acceso de nuestro módulo esperará un parámetro ID. Para ello modificaremos el fichero module.config.php del módulo Menus:
Contenido del fichero /module/Menus/config/module.config.php:
<?php return array( 'controllers' => array( 'invokables' => array( 'Menus\Controller\Index' => 'Menus\Controller\Index', 'Menus\Controller\Menus' => 'Menus\Controller\MenusController', ), ), 'router' => array( 'routes' => array( 'menus' => array( 'type' => 'Literal', 'options' => array( // Change this to something specific to your module 'route' => '/menus', 'defaults' => array( // Change this value to reflect the namespace in which // the controllers for your module are found '__NAMESPACE__' => 'Menus\Controller', 'controller' => 'Index', 'action' => 'index', ), ), 'may_terminate' => true, 'child_routes' => array( // This route is a sane default when developing a module; // as you solidify the routes for your module, however, // you may want to remove it and replace it with more // specific routes. 'default' => array( 'type' => 'Segment', 'options' => array( 'route' => '/[:controller[/:action[/:id]]]', 'constraints' => array( 'controller' => '[a-zA-Z][a-zA-Z0-9_-]*', 'action' => '[a-zA-Z][a-zA-Z0-9_-]*', 'id' => '[0-9]*', ), 'defaults' => array( ), ), ), ), ), ), ), 'view_manager' => array( 'template_path_stack' => array( 'Menus' => __DIR__ . '/../view', ), ), );
Vamos ahora sí a por faena y vamos a incluir en el controlador ambas acciones:
Añadir los siguientes métodos en el fichero /module/Menus/src/Menus/Controller/MenusController.php:
public function editAction() { $form = new MenuForm(); $form->setInputFilter(new MenuFilter()); $viewVars = array ( 'title' => 'Edit Menu', 'form' => $form ); if (! $this->request->isPost ()) { $id = ( int ) $this->params ()->fromRoute ( 'id' ); $adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'); $menusTable = new MenusTable($adapter); $menuDb = $menusTable->getMenuById ( $id ); $form->setData ( $menuDb ); return new ViewModel ( $viewVars ); } else { $post = $this->request->getPost (); $id = ( int ) $post->id_menu; $form->setData ( $post ); if (! $form->isValid ()) { $viewVars ['error'] = true; return new ViewModel ( $viewVars ); } } // Edit menu try { $formData = $form->getData (); $menu = (isset ( $formData ['menu'] )) ? $formData ['menu'] : null; $name = (isset ( $formData ['name'] )) ? $formData ['name'] : null; $label = (isset ( $formData ['label'] )) ? $formData ['label'] : null; $module = (isset ( $formData ['module'] )) ? $formData ['module'] : null; $controller = (isset ( $formData ['controller'] )) ? $formData ['controller'] : null; $action = (isset ( $formData ['action'] )) ? $formData ['action'] : null; $order = (isset ( $formData ['order'] )) ? $formData ['order'] : null; $adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'); $menusTable = new MenusTable($adapter); $menusTable->updateMenu ( $id, $menu, $name, $label, $module, $controller, $action, $order ); return $this->redirect ()->toRoute ( NULL, array ( 'controller' => 'menus', 'action' => 'index' ) ); } catch ( \Exception $e ) { $viewVars ['error'] = true; $viewVars ['message'] = $e->getMessage (); return new ViewModel ( $viewVars ); } } public function deleteAction() { try { $id = ( int ) $this->params ()->fromRoute ( 'id' ); $adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'); $menusTable = new MenusTable($adapter); $menusTable->deleteMenu( $id ); return $this->redirect ()->toRoute ( NULL, array ( 'controller' => 'Menus', 'action' => 'index' ) ); } catch ( \Exception $e ) { $viewVars ['title'] = 'Delete Menu'; $viewVars ['message'] = $e->getMessage (); return new ViewModel ( $viewVars ); } }
Por cada acción necesitaremos una vista asociada, así pues hemos de crear ambas, edit.phtml y delete.phtml.
Contenido del archivo /module/Menus/view/menus/menus/edit.phtml :
<section class="edit"> <h2><?php echo $this->translate($this->title); ?></h2> <?php if ($this->error){ ?> <p class="error"> <?php echo $this->translate('There were one or more isues with your submission. Please correct them as indicated below.'); ?> <?php if(isset($this->message) && $this->message != '') { ?> <br> <?php echo $this->message; ?> <?php } ?> </p> <?php } ?> <?php $form = $this->form; $form->prepare(); $form->setAttribute('action', $this->url(NULL, array('controller'=>'menus', 'action' => 'edit'))); $form->setAttribute('method', 'post'); echo $this->form()->openTag($form); ?> <div class="form-group"> <?php echo $this->formLabel($form->get('menu')); ?> <?php echo $this->formElement($form->get('menu')); echo $this->formElementErrors($form->get('menu')); ?> </div> <div class="form-group"> <?php echo $this->formLabel($form->get('name')); ?> <?php echo $this->formElement($form->get('name')); echo $this->formElementErrors($form->get('name')); ?> </div> <div class="form-group"> <?php echo $this->formLabel($form->get('label')); ?> <?php echo $this->formElement($form->get('label')); echo $this->formElementErrors($form->get('label')); ?> </div> <div class="form-group"> <?php echo $this->formLabel($form->get('module')); ?> <?php echo $this->formElement($form->get('module')); echo $this->formElementErrors($form->get('module')); ?> </div> <div class="form-group"> <?php echo $this->formLabel($form->get('controller')); ?> <?php echo $this->formElement($form->get('controller')); echo $this->formElementErrors($form->get('controller')); ?> </div> <div class="form-group"> <?php echo $this->formLabel($form->get('action')); ?> <?php echo $this->formElement($form->get('action')); echo $this->formElementErrors($form->get('action')); ?> </div> <div class="form-group"> <?php echo $this->formLabel($form->get('order')); ?> <?php echo $this->formElement($form->get('order')); echo $this->formElementErrors($form->get('order')); ?> </div> <div class="form-group"> <?php echo $this->formElement($form->get('submit')); echo $this->formElementErrors($form->get('submit')); ?> <a class="btn btn-default" href="<?php echo $this->url('menus/default', array('controller' => 'menus', 'action' => 'index'), null); ?>"><?php echo $this->translate('Return back');?></a> </div> <?php echo $this->formElement($form->get('id_menu')); ?> <?php echo $this->form()->closeTag() ?> </section>
Contenido del archivo /module/Menus/view/menus/menus/delete.phtml :
<section class="delete-confirm"> <h3><?php echo $this->translate($this->title); ?></h3> <p class="error"> <?php echo $this->translate('There were one or more isues with your submission. Please correct them as indicated below.'); ?> <?php if(isset($this->message) && $this->message != '') { ?> <br> <?php echo $this->message; ?> <?php } ?> </p> <p><a href="<?php echo $this->url('menus/default', array('controller' => 'groups'), null); ?>"><?php echo $this->translate('Return back');?></a></p> </section>Para finalizar debemos actualizar el modelo de la tabla Menus para incluir la actualización y borrado de registros, así como la búsqueda de un registro por identificador.
Añadir los siguientes métodos en el fichero /module/Menus/src/Menus/Model/MenusTable.php:
public function getMenuById($id) { $id = (int) $id; $rowset = $this->select(array('id_menu' => $id)); $row = $rowset->current(); if (!$row) { throw new \Exception("Could not find row $id"); } return $row; } public function updateMenu($id, $menu, $name, $label, $module, $controller, $action, $order){ $row = $this->getMenuById($id); $data['menu'] = $menu; $data['name'] = $name; $data['label'] = $label; $data['module'] = $module; $data['controller'] = $controller; $data['action'] = $action; $data['order'] = $order; if ($row) { $this->update($data, array('id_menu' => $id)); } else { throw new \Exception('Menu ID does not exist'); } } public function deleteMenu($id){ $id = (int) $id; $rowset = $this->select(array('id_menu' => $id)); $row = $rowset->current(); if (!$row) { throw new \Exception("Could not find row $id"); } $this->delete(array('id_menu' => $id)); }
Podemos probar los scripts y validar tanto la edición como el borrado de entradas.
El uso de getServiceLocator
Puede ser interesante encapsular las llamadas tanto al modelo como al formulario mediante el uso de getServiceLocator.Si editamos el fichero /module/Module.php y incluimos el siguiente método a la clase Module:
public function getServiceConfig(){ return array( 'abstract_factories' => array(), 'aliases' => array(), 'factories' => array( 'MenusTable' => function ($sm) { return new MenusTable( $sm->get('\Zend\Db\Adapter\Adapter') ); }, // Forms 'MenuForm' => function ($sm) { $form = new \Menus\Form\MenuForm(); $form->SetInputFilter($sm->get('MenuFilter')); return $form; }, //Filters 'MenuFilter' => function ($sm) { return new \Menus\Form\MenuFilter(); }, ), 'invokables' => array(), 'services' => array(), 'shared' => array(), ); }
En nuestro código podremos sustituir todas las llamadas a MenusTables y MenuForm usando getServiceLocator.
En el caso de MenusTable el código:
$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'); $menusTable = new MenusTable($adapter);
Podremos sustituirlo por:
$menusTable = $this->getServiceLocator ()->get ( 'MenusTable' );
En el caso de la llamada al formulario:
$form = new MenuForm(); $form->setInputFilter(new MenuFilter());
Podremos sustituirlo por:
$form = $this->getServiceLocator ()->get ( 'MenuForm' );
El código queda más limpio.