Tell me more ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

Consider the following bootstrapper:

<?php

/**
 * Zend_Application Bootstrapper
 *
 * @copyright 2011 Case Western Reserve University, College of Arts and Sciences
 * @author Billy O'Neal III (bro4@case.edu)
 */

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
    public function __construct($application)
    {
        parent::__construct($application);
        Cas_Ldap::SetGlobalOptions($this->getOption('ldapserver'), $this->getOption('ldapsearchbase'));
    }

    protected function _initLayout()
    {
        $layout = Zend_Layout::startMvc();
        $layout->setLayoutPath(APPLICATION_PATH . '/layouts/scripts');
        $layout->setLayout('layout');
        return $layout;
    }

    protected function _initView()
    {
        $this->bootstrap('db');
        $view = new Zend_View();

        //Set the version string with subversion revision if found.
        $version = '0.1';
        $svnPath = APPLICATION_PATH . '/../.svnrev';
        if (file_exists($svnPath))
        {
            $hFile = fopen($svnPath, 'r');
            $version .= '.' . fgets($hFile);
            fclose($hFile);
            $lastModTime = filemtime($svnPath);
            $dateTime = new DateTime('@' . $lastModTime, new DateTimeZone('America/New_York'));
            $version .= ' ' . $dateTime->format('o-n-j G:i') . 'Z';
        }
        $view->version = $version;

        // Setup Navigation

        $nav = array();
        $nav[] = array(
            'label' => 'Welcome',
            'controller' => 'index',
            'action' => 'index',
            'order' => -1
        );

        $loggedIn = Cas_Users_User::LoggedIn();

        $logxLink = array('controller' => 'User', 'order' => 1000);
        $logxLink['label'] = $loggedIn ? 'Logout' : 'Login';
        $logxLink['action'] = strtolower($logxLink['label']);
        $logxLink['pages'] = array(array(
            'controller' => 'User',
            'action' => 'AccessDenied',
            'visible' => false,
            'label' => 'Access Denied'
        ));
        $nav[] = $logxLink;

        $adminPermission = Cas_Acl_Privilege::CreateExisting('refreshAdmin');
        unset($hasAdmin);
        $hasAdmin = (bool)Cas_Users_User::CurrentPrivilegeCheck($adminPermission);
        $nav[] = array(
            'controller' => 'admin',
            'action' => 'index',
            'order' => 2,
            'label' => 'Administration',
            'visible' => $hasAdmin,
            'pages' => array(array(
                'controller' => 'admin',
                'action' => 'useradmin',
                'label' => 'User Administration',
                'order' => 1
            ),array(
                'controller' => 'admin',
                'action' => 'globalpermissions',
                'label' => 'System Permissions',
                'order' => 2
            ),array(
                'controller' => 'admin',
                'action' => 'editevents',
                'label' => 'Edit Events List',
                'order' => 3
            ),array(
                'controller' => 'template',
                'action' => 'index',
                'label' => 'Edit Templates',
                'order' => 4
            ), array(
                'controller' => 'admin',
                'action' => 'notauthorized',
                'label' => 'Access Denied',
                'visible' => false
            ), array(
                'controller' => 'admin',
                'action' => 'usermembership',
                'label' => 'User Membership Edit',
                'visible' => false
            ))
        );

        $nav[] = array(
            'controller' => 'faq',
            'action' => 'index',
            'order' => 3,
            'label' => 'Frequently Asked Questions'
        );

        if ($loggedIn)
        {
            $nav[] = array(
                'order' => 4,
                'label' => 'My Refresh',
                'uri' => '#',
                'pages' => array(
                    array(
                        'label' => 'Accelerate My Refresh',
                        'order' => 1,
                        'controller' => 'accelerate',
                        'action' => 'index'
                    )
                )
            );

            $standardSystems = array();
            $standardSystems[] = array(
                'label' => 'About Standard Computers'
            );
            $standardSystems[] = array(
                'label' => 'Dell Optiplex 980 MT',
                'make' => 'Dell',
                'model' => 'Optiplex980MT'
            );
            $standardSystems[] = array(
                'label' => 'Dell Latitude E4310',
                'make' => 'Dell',
                'model' => 'LatitudeE4310'
            );
            $standardSystems[] = array(
                'label' => 'Dell Latitude E6410',
                'make' => 'Dell',
                'model' => 'LatitudeE6410'
            );
            $standardSystems[] = array(
                'label' => 'Dell Latitude E6510',
                'make' => 'Dell',
                'model' => 'LatitudeE6510'
            );
            $standardSystems[] = array(
                'label' => 'Apple iMac 21.5&quot;',
                'make' => 'Apple',
                'model' => 'iMac'
            );
            $standardSystems[] = array(
                'label' => 'Apple MacBook Pro 13&quot;',
                'make' => 'Apple',
                'model' => 'MacBookPro'
            );
            $standardSystems[] = array(
                'label' => 'Apple MacBook Air 11&quot;',
                'make' => 'Apple',
                'model' => 'MacBookAir'
            );

            foreach ($standardSystems as $key => &$value)
            {
                $value['controller'] = 'StandardSystem';
                $value['action'] = 'index';
                $value['order'] = $key;
                if (!isset($value['make']))
                    continue;
                $value['params'] = array('make' => $value['make'], 'model' => $value['model']);
                unset($value['make']);
                unset($value['model']);
            }

            $nav[] = array(
                'controller' => 'StandardSystem',
                'action' => 'index',
                'label' => 'Standard Computers',
                'order' => 5,
                'pages' => $standardSystems
            );

            $nav[] = array(
                'uri' => 'mailto:casrefresh@case.edu',
                'label' => 'Send Feedback',
                'order' => 6
            );
        }

        $nav = new Zend_Navigation(new Zend_Config($nav));
        $view->navigation($nav);
        //Done setting up navigation.

        //Register the view, and return it.
        $viewRenderer =
            Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer');
        $viewRenderer->setView($view);

        $view->setHelperPath(APPLICATION_PATH . '/views/helpers', 'Cas_View_Helper');
        return $view;
       }

    protected function _initFrontController()
    {
        $fc = Zend_Controller_Front::getInstance();
        $fc->setControllerDirectory(APPLICATION_PATH . '/controllers');
        $fc->registerPlugin(new Cas_Controller_DefaultViews());
        Zend_Controller_Action_HelperBroker::addPrefix('Cas_Controller_Helper');
        return $fc;
    }
}

this seems a bit ... wrong, because there's a lot of business logic going on inside the bootstrapper. Is there a better way to accomplish what's going on here?

share|improve this question

2 Answers

up vote 1 down vote accepted

You're right, there's a lot of work going on here.

You probably need to be a bit more granular in your use of _init methods. You have navigation, ACL, view configuration and plugin registration all wrapped up in the _initView method. Try breaking these up into their own _init methods. Try to limit each _init method to a single purpose.

Personally, I prefer to limit the Bootstrap to a "spark plug" rolle , and move this kind of logic into Resource Plugins:

http://framework.zend.com/manual/en/zend.application.theory-of-operation.html#zend.application.theory-of-operation.resources

I divide those plugins into components that I'm likely to reuse on other projects, and components that are specific to the project under development. I store these in separate "namespaced" folders in the application library.

Externalise parameters (like $standardSystems ) into ini|php|xml files where possible - this will help you swap parameters based on application environment where required (i.e. database connectors).

If I have a lot of sequential logic in a class, I tend to use one function for traffic control duties - but keep the details in separate methods. Currently, I feel that there are too many points of potential failure in the _initView method which will make debugging tricky.

share|improve this answer

Resource plugins allow one to encapsulate a plugin class to perform one purpose & can be unit tested. Otherwise the bootstrap becomes a GOD class. Plugins have hooks too.

Worst case at least split up your '_initView' method as it is massive.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.