mirror of
				https://github.com/Icinga/icingaweb2.git
				synced 2025-11-03 04:35:06 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			719 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			719 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */
 | 
						|
 | 
						|
namespace Icinga\Web;
 | 
						|
 | 
						|
use LogicException;
 | 
						|
use InvalidArgumentException;
 | 
						|
use Icinga\Web\Session\SessionNamespace;
 | 
						|
use Icinga\Web\Form\Decorator\ElementDoubler;
 | 
						|
 | 
						|
/**
 | 
						|
 * Container and controller for form based wizards
 | 
						|
 */
 | 
						|
class Wizard
 | 
						|
{
 | 
						|
    /**
 | 
						|
     * An integer describing the wizard's forward direction
 | 
						|
     */
 | 
						|
    const FORWARD = 0;
 | 
						|
 | 
						|
    /**
 | 
						|
     * An integer describing the wizard's backward direction
 | 
						|
     */
 | 
						|
    const BACKWARD = 1;
 | 
						|
 | 
						|
    /**
 | 
						|
     * An integer describing that the wizard does not change its position
 | 
						|
     */
 | 
						|
    const NO_CHANGE = 2;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The name of the button to advance the wizard's position
 | 
						|
     */
 | 
						|
    const BTN_NEXT = 'btn_next';
 | 
						|
 | 
						|
    /**
 | 
						|
     * The name of the button to rewind the wizard's position
 | 
						|
     */
 | 
						|
    const BTN_PREV = 'btn_prev';
 | 
						|
 | 
						|
    /**
 | 
						|
     * The name and id of the element for showing the user an activity indicator when advancing the wizard
 | 
						|
     */
 | 
						|
    const PROGRESS_ELEMENT = 'wizard_progress';
 | 
						|
 | 
						|
    /**
 | 
						|
     * This wizard's parent
 | 
						|
     *
 | 
						|
     * @var Wizard
 | 
						|
     */
 | 
						|
    protected $parent;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The name of the wizard's current page
 | 
						|
     *
 | 
						|
     * @var string
 | 
						|
     */
 | 
						|
    protected $currentPage;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The pages being part of this wizard
 | 
						|
     *
 | 
						|
     * @var array
 | 
						|
     */
 | 
						|
    protected $pages = array();
 | 
						|
 | 
						|
    /**
 | 
						|
     * Initialize a new wizard
 | 
						|
     */
 | 
						|
    public function __construct()
 | 
						|
    {
 | 
						|
        $this->init();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Run additional initialization routines
 | 
						|
     *
 | 
						|
     * Should be implemented by subclasses to add pages to the wizard.
 | 
						|
     */
 | 
						|
    protected function init()
 | 
						|
    {
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return this wizard's parent or null in case it has none
 | 
						|
     *
 | 
						|
     * @return  Wizard|null
 | 
						|
     */
 | 
						|
    public function getParent()
 | 
						|
    {
 | 
						|
        return $this->parent;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Set this wizard's parent
 | 
						|
     *
 | 
						|
     * @param   Wizard  $wizard     The parent wizard
 | 
						|
     *
 | 
						|
     * @return  $this
 | 
						|
     */
 | 
						|
    public function setParent(Wizard $wizard)
 | 
						|
    {
 | 
						|
        $this->parent = $wizard;
 | 
						|
        return $this;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the pages being part of this wizard
 | 
						|
     *
 | 
						|
     * In case this is a nested wizard a flattened array of all contained pages is returned.
 | 
						|
     *
 | 
						|
     * @return  array
 | 
						|
     */
 | 
						|
    public function getPages()
 | 
						|
    {
 | 
						|
        $pages = array();
 | 
						|
        foreach ($this->pages as $page) {
 | 
						|
            if ($page instanceof self) {
 | 
						|
                $pages = array_merge($pages, $page->getPages());
 | 
						|
            } else {
 | 
						|
                $pages[] = $page;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        return $pages;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the page with the given name
 | 
						|
     *
 | 
						|
     * Note that it's also possible to retrieve a nested wizard's page by using this method.
 | 
						|
     *
 | 
						|
     * @param   string      $name   The name of the page to return
 | 
						|
     *
 | 
						|
     * @return  null|Form           The page or null in case there is no page with the given name
 | 
						|
     */
 | 
						|
    public function getPage($name)
 | 
						|
    {
 | 
						|
        foreach ($this->getPages() as $page) {
 | 
						|
            if ($name === $page->getName()) {
 | 
						|
                return $page;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Add a new page or wizard to this wizard
 | 
						|
     *
 | 
						|
     * @param   Form|Wizard     $page   The page or wizard to add to the wizard
 | 
						|
     *
 | 
						|
     * @return  $this
 | 
						|
     */
 | 
						|
    public function addPage($page)
 | 
						|
    {
 | 
						|
        if (! $page instanceof Form && ! $page instanceof self) {
 | 
						|
            throw InvalidArgumentException(
 | 
						|
                'The $page argument must be an instance of Icinga\Web\Form '
 | 
						|
                . 'or Icinga\Web\Wizard but is of type: ' . get_class($page)
 | 
						|
            );
 | 
						|
        } elseif ($page instanceof self) {
 | 
						|
            $page->setParent($this);
 | 
						|
        }
 | 
						|
 | 
						|
        $this->pages[] = $page;
 | 
						|
        return $this;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Add multiple pages or wizards to this wizard
 | 
						|
     *
 | 
						|
     * @param   array   $pages      The pages or wizards to add to the wizard
 | 
						|
     *
 | 
						|
     * @return  $this
 | 
						|
     */
 | 
						|
    public function addPages(array $pages)
 | 
						|
    {
 | 
						|
        foreach ($pages as $page) {
 | 
						|
            $this->addPage($page);
 | 
						|
        }
 | 
						|
 | 
						|
        return $this;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Assert that this wizard has any pages
 | 
						|
     *
 | 
						|
     * @throws  LogicException      In case this wizard has no pages
 | 
						|
     */
 | 
						|
    protected function assertHasPages()
 | 
						|
    {
 | 
						|
        $pages = $this->getPages();
 | 
						|
        if (count($pages) < 2) {
 | 
						|
            throw new LogicException("Although Chuck Norris can advance a wizard with less than two pages, you can't.");
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the current page of this wizard
 | 
						|
     *
 | 
						|
     * @return  Form
 | 
						|
     *
 | 
						|
     * @throws  LogicException      In case the name of the current page currently being set is invalid
 | 
						|
     */
 | 
						|
    public function getCurrentPage()
 | 
						|
    {
 | 
						|
        if ($this->parent) {
 | 
						|
            return $this->parent->getCurrentPage();
 | 
						|
        }
 | 
						|
 | 
						|
        if ($this->currentPage === null) {
 | 
						|
            $this->assertHasPages();
 | 
						|
            $pages = $this->getPages();
 | 
						|
            $this->currentPage = $this->getSession()->get('current_page', $pages[0]->getName());
 | 
						|
        }
 | 
						|
 | 
						|
        if (($page = $this->getPage($this->currentPage)) === null) {
 | 
						|
            throw new LogicException(sprintf('No page found with name "%s"', $this->currentPage));
 | 
						|
        }
 | 
						|
 | 
						|
        return $page;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Set the current page of this wizard
 | 
						|
     *
 | 
						|
     * @param   Form    $page   The page to set as current page
 | 
						|
     *
 | 
						|
     * @return  $this
 | 
						|
     */
 | 
						|
    public function setCurrentPage(Form $page)
 | 
						|
    {
 | 
						|
        $this->currentPage = $page->getName();
 | 
						|
        $this->getSession()->set('current_page', $this->currentPage);
 | 
						|
        return $this;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Setup the given page that is either going to be displayed or validated
 | 
						|
     *
 | 
						|
     * Implement this method in a subclass to populate default values and/or other data required to process the form.
 | 
						|
     *
 | 
						|
     * @param   Form        $page       The page to setup
 | 
						|
     * @param   Request     $request    The current request
 | 
						|
     */
 | 
						|
    public function setupPage(Form $page, Request $request)
 | 
						|
    {
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Process the given request using this wizard
 | 
						|
     *
 | 
						|
     * Validate the request data using the current page, update the wizard's
 | 
						|
     * position and redirect to the page's redirect url upon success.
 | 
						|
     *
 | 
						|
     * @param   Request     $request    The request to be processed
 | 
						|
     *
 | 
						|
     * @return  Request                 The request supposed to be processed
 | 
						|
     */
 | 
						|
    public function handleRequest(Request $request = null)
 | 
						|
    {
 | 
						|
        $page = $this->getCurrentPage();
 | 
						|
 | 
						|
        if (($wizard = $this->findWizard($page)) !== null) {
 | 
						|
            return $wizard->handleRequest($request);
 | 
						|
        }
 | 
						|
 | 
						|
        if ($request === null) {
 | 
						|
            $request = $page->getRequest();
 | 
						|
        }
 | 
						|
 | 
						|
        $this->setupPage($page, $request);
 | 
						|
        $requestData = $this->getRequestData($page, $request);
 | 
						|
        if ($page->wasSent($requestData)) {
 | 
						|
            if (($requestedPage = $this->getRequestedPage($requestData)) !== null) {
 | 
						|
                $isValid = false;
 | 
						|
                $direction = $this->getDirection($request);
 | 
						|
                if ($direction === static::FORWARD && $page->isValid($requestData)) {
 | 
						|
                    $isValid = true;
 | 
						|
                    if ($this->isLastPage($page)) {
 | 
						|
                        $this->setIsFinished();
 | 
						|
                    }
 | 
						|
                } elseif ($direction === static::BACKWARD) {
 | 
						|
                    $page->populate($requestData);
 | 
						|
                    $isValid = true;
 | 
						|
                }
 | 
						|
 | 
						|
                if ($isValid) {
 | 
						|
                    $pageData = & $this->getPageData();
 | 
						|
                    $pageData[$page->getName()] = $page->getValues();
 | 
						|
                    $this->setCurrentPage($this->getNewPage($requestedPage, $page));
 | 
						|
                    $page->getResponse()->redirectAndExit($page->getRedirectUrl());
 | 
						|
                }
 | 
						|
            } elseif ($page->getValidatePartial()) {
 | 
						|
                $page->isValidPartial($requestData);
 | 
						|
            } else {
 | 
						|
                $page->populate($requestData);
 | 
						|
            }
 | 
						|
        } elseif (($pageData = $this->getPageData($page->getName())) !== null) {
 | 
						|
            $page->populate($pageData);
 | 
						|
        }
 | 
						|
 | 
						|
        return $request;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the wizard for the given page or null if its not part of a wizard
 | 
						|
     *
 | 
						|
     * @param   Form    $page   The page to return its wizard for
 | 
						|
     *
 | 
						|
     * @return  Wizard|null
 | 
						|
     */
 | 
						|
    protected function findWizard(Form $page)
 | 
						|
    {
 | 
						|
        foreach ($this->getWizards() as $wizard) {
 | 
						|
            if ($wizard->getPage($page->getName()) === $page) {
 | 
						|
                return $wizard;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return this wizard's child wizards
 | 
						|
     *
 | 
						|
     * @return  array
 | 
						|
     */
 | 
						|
    protected function getWizards()
 | 
						|
    {
 | 
						|
        $wizards = array();
 | 
						|
        foreach ($this->pages as $pageOrWizard) {
 | 
						|
            if ($pageOrWizard instanceof self) {
 | 
						|
                $wizards[] = $pageOrWizard;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        return $wizards;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the request data based on given form's request method
 | 
						|
     *
 | 
						|
     * @param   Form        $page       The page to fetch the data for
 | 
						|
     * @param   Request     $request    The request to fetch the data from
 | 
						|
     *
 | 
						|
     * @return  array
 | 
						|
     */
 | 
						|
    protected function getRequestData(Form $page, Request $request)
 | 
						|
    {
 | 
						|
        if (strtolower($request->getMethod()) === $page->getMethod()) {
 | 
						|
            return $request->{'get' . ($request->isPost() ? 'Post' : 'Query')}();
 | 
						|
        }
 | 
						|
 | 
						|
        return array();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the name of the requested page
 | 
						|
     *
 | 
						|
     * @param   array   $requestData    The request's data
 | 
						|
     *
 | 
						|
     * @return  null|string             The name of the requested page or null in case no page has been requested
 | 
						|
     */
 | 
						|
    protected function getRequestedPage(array $requestData)
 | 
						|
    {
 | 
						|
        if ($this->parent) {
 | 
						|
            return $this->parent->getRequestedPage($requestData);
 | 
						|
        }
 | 
						|
 | 
						|
        if (isset($requestData[static::BTN_NEXT])) {
 | 
						|
            return $requestData[static::BTN_NEXT];
 | 
						|
        } elseif (isset($requestData[static::BTN_PREV])) {
 | 
						|
            return $requestData[static::BTN_PREV];
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the direction of this wizard using the given request
 | 
						|
     *
 | 
						|
     * @param   Request     $request    The request to use
 | 
						|
     *
 | 
						|
     * @return  int                     The direction @see Wizard::FORWARD @see Wizard::BACKWARD @see Wizard::NO_CHANGE
 | 
						|
     */
 | 
						|
    protected function getDirection(Request $request = null)
 | 
						|
    {
 | 
						|
        if ($this->parent) {
 | 
						|
            return $this->parent->getDirection($request);
 | 
						|
        }
 | 
						|
 | 
						|
        $currentPage = $this->getCurrentPage();
 | 
						|
 | 
						|
        if ($request === null) {
 | 
						|
            $request = $currentPage->getRequest();
 | 
						|
        }
 | 
						|
 | 
						|
        $requestData = $this->getRequestData($currentPage, $request);
 | 
						|
        if (isset($requestData[static::BTN_NEXT])) {
 | 
						|
            return static::FORWARD;
 | 
						|
        } elseif (isset($requestData[static::BTN_PREV])) {
 | 
						|
            return static::BACKWARD;
 | 
						|
        }
 | 
						|
 | 
						|
        return static::NO_CHANGE;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the new page to set as current page
 | 
						|
     *
 | 
						|
     * Permission is checked by verifying that the requested page or its previous page has page data available.
 | 
						|
     * The requested page is automatically permitted without any checks if the origin page is its previous
 | 
						|
     * page or one that occurs later in order.
 | 
						|
     *
 | 
						|
     * @param   string  $requestedPage      The name of the requested page
 | 
						|
     * @param   Form    $originPage         The origin page
 | 
						|
     *
 | 
						|
     * @return  Form                        The new page
 | 
						|
     *
 | 
						|
     * @throws  InvalidArgumentException    In case the requested page does not exist or is not permitted yet
 | 
						|
     */
 | 
						|
    protected function getNewPage($requestedPage, Form $originPage)
 | 
						|
    {
 | 
						|
        if ($this->parent) {
 | 
						|
            return $this->parent->getNewPage($requestedPage, $originPage);
 | 
						|
        }
 | 
						|
 | 
						|
        if (($page = $this->getPage($requestedPage)) !== null) {
 | 
						|
            $permitted = true;
 | 
						|
 | 
						|
            $pages = $this->getPages();
 | 
						|
            if (! $this->hasPageData($requestedPage) && ($index = array_search($page, $pages, true)) > 0) {
 | 
						|
                $previousPage = $pages[$index - 1];
 | 
						|
                if ($originPage === null || ($previousPage->getName() !== $originPage->getName()
 | 
						|
                    && array_search($originPage, $pages, true) < $index)) {
 | 
						|
                    $permitted = $this->hasPageData($previousPage->getName());
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            if ($permitted) {
 | 
						|
                return $page;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        throw new InvalidArgumentException(
 | 
						|
            sprintf('"%s" is either an unknown page or one you are not permitted to view', $requestedPage)
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the next or previous page based on the given one
 | 
						|
     *
 | 
						|
     * @param   Form    $page   The page to skip
 | 
						|
     *
 | 
						|
     * @return  Form
 | 
						|
     */
 | 
						|
    protected function skipPage(Form $page)
 | 
						|
    {
 | 
						|
        if ($this->parent) {
 | 
						|
            return $this->parent->skipPage($page);
 | 
						|
        }
 | 
						|
 | 
						|
        if ($this->hasPageData($page->getName())) {
 | 
						|
            $pageData = & $this->getPageData();
 | 
						|
            unset($pageData[$page->getName()]);
 | 
						|
        }
 | 
						|
 | 
						|
        $pages = $this->getPages();
 | 
						|
        if ($this->getDirection() === static::FORWARD) {
 | 
						|
            $nextPage = $pages[array_search($page, $pages, true) + 1];
 | 
						|
            $newPage = $this->getNewPage($nextPage->getName(), $page);
 | 
						|
        } else { // $this->getDirection() === static::BACKWARD
 | 
						|
            $previousPage = $pages[array_search($page, $pages, true) - 1];
 | 
						|
            $newPage = $this->getNewPage($previousPage->getName(), $page);
 | 
						|
        }
 | 
						|
 | 
						|
        return $newPage;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return whether the given page is this wizard's last page
 | 
						|
     *
 | 
						|
     * @param   Form    $page   The page to check
 | 
						|
     *
 | 
						|
     * @return  bool
 | 
						|
     */
 | 
						|
    protected function isLastPage(Form $page)
 | 
						|
    {
 | 
						|
        if ($this->parent) {
 | 
						|
            return $this->parent->isLastPage($page);
 | 
						|
        }
 | 
						|
 | 
						|
        $pages = $this->getPages();
 | 
						|
        return $page->getName() === end($pages)->getName();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return whether all of this wizard's pages were visited by the user
 | 
						|
     *
 | 
						|
     * The base implementation just verifies that the very last page has page data available.
 | 
						|
     *
 | 
						|
     * @return  bool
 | 
						|
     */
 | 
						|
    public function isComplete()
 | 
						|
    {
 | 
						|
        $pages = $this->getPages();
 | 
						|
        return $this->hasPageData($pages[count($pages) - 1]->getName());
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Set whether this wizard has been completed
 | 
						|
     *
 | 
						|
     * @param   bool    $state      Whether this wizard has been completed
 | 
						|
     *
 | 
						|
     * @return  $this
 | 
						|
     */
 | 
						|
    public function setIsFinished($state = true)
 | 
						|
    {
 | 
						|
        $this->getSession()->set('isFinished', $state);
 | 
						|
        return $this;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return whether this wizard has been completed
 | 
						|
     *
 | 
						|
     * @return  bool
 | 
						|
     */
 | 
						|
    public function isFinished()
 | 
						|
    {
 | 
						|
        return $this->getSession()->get('isFinished', false);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the overall page data or one for a particular page
 | 
						|
     *
 | 
						|
     * Note that this method returns by reference so in order to update the
 | 
						|
     * returned array set this method's return value also by reference.
 | 
						|
     *
 | 
						|
     * @param   string  $pageName   The page for which to return the data
 | 
						|
     *
 | 
						|
     * @return  array
 | 
						|
     */
 | 
						|
    public function & getPageData($pageName = null)
 | 
						|
    {
 | 
						|
        $session = $this->getSession();
 | 
						|
 | 
						|
        if (false === isset($session->page_data)) {
 | 
						|
            $session->page_data = array();
 | 
						|
        }
 | 
						|
 | 
						|
        $pageData = & $session->getByRef('page_data');
 | 
						|
        if ($pageName !== null) {
 | 
						|
            $data = null;
 | 
						|
            if (isset($pageData[$pageName])) {
 | 
						|
                $data = & $pageData[$pageName];
 | 
						|
            }
 | 
						|
 | 
						|
            return $data;
 | 
						|
        }
 | 
						|
 | 
						|
        return $pageData;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return whether there is any data for the given page
 | 
						|
     *
 | 
						|
     * @param   string  $pageName   The name of the page to check
 | 
						|
     *
 | 
						|
     * @return  bool
 | 
						|
     */
 | 
						|
    public function hasPageData($pageName)
 | 
						|
    {
 | 
						|
        return $this->getPageData($pageName) !== null;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return a session to be used by this wizard
 | 
						|
     *
 | 
						|
     * @return  SessionNamespace
 | 
						|
     */
 | 
						|
    public function getSession()
 | 
						|
    {
 | 
						|
        if ($this->parent) {
 | 
						|
            return $this->parent->getSession();
 | 
						|
        }
 | 
						|
 | 
						|
        return Session::getSession()->getNamespace(get_class($this));
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Clear the session being used by this wizard
 | 
						|
     */
 | 
						|
    public function clearSession()
 | 
						|
    {
 | 
						|
        $this->getSession()->clear();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Add buttons to the given page based on its position in the page-chain
 | 
						|
     *
 | 
						|
     * @param   Form    $page   The page to add the buttons to
 | 
						|
     */
 | 
						|
    protected function addButtons(Form $page)
 | 
						|
    {
 | 
						|
        $pages = $this->getPages();
 | 
						|
        $index = array_search($page, $pages, true);
 | 
						|
        if ($index === 0) {
 | 
						|
            $page->addElement(
 | 
						|
                'button',
 | 
						|
                static::BTN_NEXT,
 | 
						|
                array(
 | 
						|
                    'class'         => 'control-button',
 | 
						|
                    'type'          => 'submit',
 | 
						|
                    'value'         => $pages[1]->getName(),
 | 
						|
                    'label'         => t('Next'),
 | 
						|
                    'decorators'    => array('ViewHelper', 'Spinner')
 | 
						|
                )
 | 
						|
            );
 | 
						|
        } elseif ($index < count($pages) - 1) {
 | 
						|
            $page->addElement(
 | 
						|
                'button',
 | 
						|
                static::BTN_PREV,
 | 
						|
                array(
 | 
						|
                    'class'             => 'control-button',
 | 
						|
                    'type'              => 'submit',
 | 
						|
                    'value'             => $pages[$index - 1]->getName(),
 | 
						|
                    'label'             => t('Back'),
 | 
						|
                    'decorators'        => array('ViewHelper'),
 | 
						|
                    'formnovalidate'    => 'formnovalidate'
 | 
						|
                )
 | 
						|
            );
 | 
						|
            $page->addElement(
 | 
						|
                'button',
 | 
						|
                static::BTN_NEXT,
 | 
						|
                array(
 | 
						|
                    'class'         => 'control-button',
 | 
						|
                    'type'          => 'submit',
 | 
						|
                    'value'         => $pages[$index + 1]->getName(),
 | 
						|
                    'label'         => t('Next'),
 | 
						|
                    'decorators'    => array('ViewHelper')
 | 
						|
                )
 | 
						|
            );
 | 
						|
        } else {
 | 
						|
            $page->addElement(
 | 
						|
                'button',
 | 
						|
                static::BTN_PREV,
 | 
						|
                array(
 | 
						|
                    'class'             => 'control-button',
 | 
						|
                    'type'              => 'submit',
 | 
						|
                    'value'             => $pages[$index - 1]->getName(),
 | 
						|
                    'label'             => t('Back'),
 | 
						|
                    'decorators'        => array('ViewHelper'),
 | 
						|
                    'formnovalidate'    => 'formnovalidate'
 | 
						|
                )
 | 
						|
            );
 | 
						|
            $page->addElement(
 | 
						|
                'button',
 | 
						|
                static::BTN_NEXT,
 | 
						|
                array(
 | 
						|
                    'class'         => 'control-button',
 | 
						|
                    'type'          => 'submit',
 | 
						|
                    'value'         => $page->getName(),
 | 
						|
                    'label'         => t('Finish'),
 | 
						|
                    'decorators'    => array('ViewHelper')
 | 
						|
                )
 | 
						|
            );
 | 
						|
        }
 | 
						|
 | 
						|
        $page->setAttrib('data-progress-element', static::PROGRESS_ELEMENT);
 | 
						|
        $page->addElement(
 | 
						|
            'note',
 | 
						|
            static::PROGRESS_ELEMENT,
 | 
						|
            array(
 | 
						|
                'order'         => 99, // Ensures that it's shown on the right even if a sub-class adds another button
 | 
						|
                'decorators'    => array(
 | 
						|
                    'ViewHelper',
 | 
						|
                    array('Spinner', array('id' => static::PROGRESS_ELEMENT))
 | 
						|
                )
 | 
						|
            )
 | 
						|
        );
 | 
						|
 | 
						|
        $page->addDisplayGroup(
 | 
						|
            array(static::BTN_PREV, static::BTN_NEXT, static::PROGRESS_ELEMENT),
 | 
						|
            'buttons',
 | 
						|
            array(
 | 
						|
                'decorators' => array(
 | 
						|
                    'FormElements',
 | 
						|
                    new ElementDoubler(array(
 | 
						|
                        'double'        => static::BTN_NEXT,
 | 
						|
                        'condition'     => static::BTN_PREV,
 | 
						|
                        'placement'     => ElementDoubler::PREPEND,
 | 
						|
                        'attributes'    => array('tabindex' => -1, 'class' => 'double')
 | 
						|
                    )),
 | 
						|
                    array('HtmlTag', array('tag' => 'div', 'class' => 'buttons'))
 | 
						|
                )
 | 
						|
            )
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the current page of this wizard with appropriate buttons being added
 | 
						|
     *
 | 
						|
     * @return  Form
 | 
						|
     */
 | 
						|
    public function getForm()
 | 
						|
    {
 | 
						|
        $form = $this->getCurrentPage();
 | 
						|
        $form->create(); // Make sure that buttons are displayed at the very bottom
 | 
						|
        $this->addButtons($form);
 | 
						|
        return $form;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the current page of this wizard rendered as HTML
 | 
						|
     *
 | 
						|
     * @return  string
 | 
						|
     */
 | 
						|
    public function __toString()
 | 
						|
    {
 | 
						|
        return (string) $this->getForm();
 | 
						|
    }
 | 
						|
}
 |