CRUD opérations et backoffice - Zend Framework 1.12 partie 6

Tutorial Application Facebook PHP/JS : CRUD opérations et backoffice

Publié le 02/10/2013

Liste des tâches :

  • - Route et Url dans la vue
  • - Création de routes pour les actions CRUD sur un model Doctrine
  • - Création du formulaire de saisie
  • - Création du formulaire d'update
  • - Création d’un modèle de controller admin
  • - Création d’un controller admin

L’exemple se base sur l’entité sectors de la bdd.

1 - Route et Url dans la vue

Nous allons pouvoir déclencher un action d’un controller via action fourni par une balise en injectant un echo dans l’attribut href qui contiendra l’objet agissant sur les paramètres en GET

Pour exécuter cette action, l'aide de vue url va nous permettre de récupérer un route "standart" et de construire son url afin de la rendre disponible à la vue :

<?php echo $this->url(array('controller' => 'sector', 'action' => 'create', 'module' => 'admin'),'default'); ?>

L'url va donc prendre en paramètre :

- un tableau de paramètres :

  • - 'controller' => 'namecontroller'
  • - 'action' => 'nameaction'
  • - 'module' => 'namemodule'

Et 'default' en dernier argument

2 - Création de routes pour les actions CRUD sur un model Doctrine

Voici les routes correspondant au modèle Sectors.php dans le module admin :

resources.router.routes.sector.route = /admin/sector resources.router.routes.sector.defaults.module = admin resources.router.routes.sector.defaults.controller = sector resources.router.routes.sector.defaults.action = index resources.router.routes.sector-delete.route = /admin/sector/delete/:id resources.router.routes.sector-delete.defaults.module = admin resources.router.routes.sector-delete.defaults.controller = sector resources.router.routes.sector-delete.defaults.action = delete resources.router.routes.sector-display.route = /admin/sector/view/:id resources.router.routes.sector-display.defaults.module = admin resources.router.routes.sector-display.defaults.controller = sector resources.router.routes.sector-display.defaults.action = display resources.router.routes.sector-update.route = /admin/sector/edit/:id resources.router.routes.sector-update.defaults.module = admin resources.router.routes.sector-update.defaults.controller = sector resources.router.routes.sector-update.defaults.action = update

3 - Création du formulaire de saisie

Remarque : Le nom des champs du formulaire devra être en correspondance directe avec le nom des champs des tables de la base.

Dans le dossier "APPLICATION_PATH"/library/Next/Form/, nous allons créer le fichier SectorCreate.php :


<?php
class Next_Form_SectorCreate extends Zend_Form
{
    public function init()
    {
         // initialize form
        $this->setAction('/admin/sector/create')
             ->setMethod('post');

        // create text input for sector
        $sector = new Zend_Form_Element_Text('name');
        $sector->setLabel('Secteur : ')
               ->setOptions(array('size' => '50'))
               ->setRequired(true)
               ->addValidator('NotEmpty', true, array(
                       'messages' => array(
                           Zend_Validate_NotEmpty::IS_EMPTY => "Erreur : le champ secteur ne peut être vide."
                       )
                ))
               ->addFilter('HTMLEntities')
               ->addFilter('StringTrim');

        // create submit button
        $submit= new Zend_Form_Element_Submit('submit');
        $submit->setLabel('Submit Entry')
               ->setOrder(100)
               ->setOptions(array('class' => 'submit'));

        // attach elements to form
        $this->addElement($sector)
             ->addElement($submit);
    }
}

4 - Création du formulaire d'update

Dans le dossier "APPLICATION_PATH"/library/Next/Form/ nous allons créer le fichier SectorUpdate.php :


<?php
class Next_Form_SectorUpdate extends Next_Form_SectorCreate
{
    public function init()
    {
        // get parent form
        parent::init();

        // create hidden input for sector ID
        $id = new Zend_Form_Element_Hidden('id');
        $id->addValidator('Int')
            ->addFilter('HtmlEntities')
            ->addFilter('StringTrim');

        // set form action
        $this->addElement($id);

        $this->setAction('/admin/sector/update');
    }
}

5 - Création d’un modèle de controller admin

Nous allons créer un modèle de controller admin dans la librairie Next qui va servir de base pour les controllers du module admin que nous allons créer par la suite. Ces derniers vont hériter de la class abstraite.

Ce modèle de controller va fournir un test d’authentification utilisateur, le set-up du layout et celui les flash messages.

Dans le dossier "APPLICATION_PATH"/library/Next/ nous allons créer un dossier Controller dans lequel nous allons créer le fichier AdminController.php :


<?php
abstract class Next_Controller_AdminController extends Zend_Controller_Action
{
    public function init()
    {
        // set layout
        $this->_helper->layout->setLayout('admin');

        // set messages in view
        $this->view->messages = $this->_helper->getHelper('FlashMessenger')->getMessages();
    }
    // action to handle admin URLs
    public function preDispatch()
    {
        // set admin layout
        // check if user is authenticated
        // if not, redirect to login page
        $url = $this->getRequest()->getRequestURI();

        if (!Zend_Auth::getInstance()->hasIdentity())
        {
            $session = new Zend_Session_Namespace('next.auth');
            $session->requestURL = $url;
            $this->_redirect('/admin/login');
        }
    }
}

6 - Création d’un controller admin

Nous allons créer dans le dossier "APPLICATION_PATH"/application/modules/admin/ un dossier controllers dans lequel nous allons créer le fichier SectorController.php. Ce dernier contiendra les methodes CRUD :


<?php
class Admin_SectorController extends Next_Controller_AdminController
{
    public function init()
    {
        // get parent init()
        parent::init();
        // define place holder navigation
        $this->view->placeholder('rubrique')->set('sector');
    }

    // action to display list of sectors items
    public function indexAction()
    {
        // action to display list of sectors items
        $result = Next_Model_Sectors::getSectors();
        $this->view->records = $result;
    }

    // action to create sector item
    public function createAction()
    {
        // generate input form
        $form = new Next_Form_SectorCreate();
        $this->view->form = $form;

        // test for valid input
        // if valid, populate model
        // save to database
        if($this->getRequest()->isPost())
        {
            if($form->isValid($this->getRequest()->getPost()))
            {
                $sector = new Next_Model_Sectors;
                $sector->fromArray($form->getValues());
                $sector->save();
                $this->_helper->getHelper('FlashMessenger')->addMessage('Entrée ajoutée à la base.');
                $this->_redirect('/admin/sector/');
            }
        }
    }

    // action to delete sector item
    public function deleteAction()
    {
        // set filters and validators for POST input
        $filters = array(
            'id' => array('HtmlEntities', 'StripTags', 'StringTrim')
        );
        $validators = array(
            'id' => array('NotEmpty', 'Int')
        );
        $input = new Zend_Filter_Input($filters, $validators);
        $input->setData($this->getRequest()->getParams());

        // retrieve record from children sector records
        $sectorResult = Next_Model_Sectors::getSectorChildren($input->id);

        // test if input have children
        if(!$sectorResult)
        {
            // test if input is valid
            // read array of record identifiers
            // delete records from database
            if ($input->isValid())
            {
                //delete sector
                Next_Model_Sectors::deleteSector($input->id);
                $this->_helper->getHelper('FlashMessenger')->addMessage('L\'enregistrement a été effacé avec succès');
                $this->_redirect('/admin/sector/');
            }
            else
            {
                throw new Zend_Controller_Action_Exception('Invalid input');
            }
        }
        else
        {
            $this->_helper->getHelper('FlashMessenger')->addMessage('L\'enregistrement ne peut être effacé : il contient les clients');
            $this->_redirect('/admin/sector/');
        }
    }

    // action to modify an individual sector item
    public function updateAction()
    {
        // generate input form
        $form = new Next_Form_SectorUpdate;
        $this->view->form = $form;
        if ($this->getRequest()->isPost())
        {
            // if POST request
            // test if input is valid
            // retrieve current record
            // update values and replace in database
            $postData = $this->getRequest()->getPost();
            if ($form->isValid($postData))
            {
                $input = $form->getValues();
                $sector = Doctrine::getTable('Next_Model_Sectors')->find($input['id']);
                $sector->fromArray($input);
                $sector->save();
                $this->_helper->getHelper('FlashMessenger')->addMessage('L\'enregistrement a été mis à jour correctement.');
                $this->_redirect('/admin/sector/');
            }
        }
        else
        {
            // if GET request
            // set filters and validators for GET input
            // test if input is valid
            // retrieve requested record
            // pre-populate form
            $filters = array(
                'id' => array('HtmlEntities', 'StripTags', 'StringTrim')
            );
            $validators = array(
                'id' => array('NotEmpty', 'Int')
            );
            $input = new Zend_Filter_Input($filters, $validators);
            $input->setData($this->getRequest()->getParams());
            if ($input->isValid())
            {
                // get selected sector item
                $result = Next_Model_Sectors::getSector($input->id);
                if (count($result) == 1)
                {
                   $this->view->form->populate($result[0]);
                }
               else
               {
                   throw new Zend_Controller_Action_Exception('Page not found', 404);
               }
            }
            else
            {
                throw new Zend_Controller_Action_Exception('Invalid input');
            }
        }
    }
}