Perforce Chronicle 2012.2/486814
API Documentation

Setup_IndexController Class Reference

Setup/configure the application. More...

List of all members.

Public Member Functions

 _p4ClientType ()
 Determine what Perforce client type is in use.
 administratorAction ()
 Obtain server administrator information.
 createAction ()
 This action allows api's to make a single post to create a new site.
 indexAction ()
 Show setup splash page.
 init ()
 Use the setup layout and disable toolbar for all setup actions.
 requirementsAction ()
 Start setup process by checking requirements.
 rewriteAction ()
 Simple action exists only to be requested to test if rewrite is working.
 siteAction ($skipRedirect=false, $optionalUrls=false)
 Setup a site definition.
 storageAction ()
 Obtain Perforce server information.
 summaryAction ()
 Summarize site setup - clear site from session.

Public Attributes

 $contexts
const MIN_P4_VERSION = '2012.1'
const MIN_PHP_VERSION = '5.3'
const P4D_BINARY = 'p4d'
const P4D_FLAGS = '-ir'
const P4D_FOLDER = 'perforce'
const P4D_PORT = 'rsh:'
const P4D_USER = 'chronicle'

Protected Member Functions

 _cleanupSession ()
 Clear out completed setup data from session.
 _getAdminConnection ($storageForm, $adminForm)
 Get a connection to the target Perforce Server as an administrator.
 _getFriendlyPort (P4_Connection_Interface $connection)
 Present rsh ports as 'Local Server: /path/to/server/root'.
 _isInitalSetup ()
 Check if setup is running for the first time.
 _isRshServer (P4_Connection_Interface $connection)
 Determines if given connection is to a local 'rsh' server.

Protected Attributes

 $_adminP4 = null
 $_session = null

Detailed Description

Setup/configure the application.

Copyright:
2011-2012 Perforce Software. All rights reserved
License:
Please see LICENSE.txt in top-level folder of this distribution.
Version:
2012.2/486814

Member Function Documentation

Setup_IndexController::_cleanupSession ( ) [protected]

Clear out completed setup data from session.

    {
        $session = $this->_getSession();
        if ($session->setupComplete) {
            $session->site          = null;
            $session->storage       = null;
            $session->administrator = null;
            $session->setupComplete = false;
        }
    }
Setup_IndexController::_getAdminConnection ( storageForm,
adminForm 
) [protected]

Get a connection to the target Perforce Server as an administrator.

This method will not return a connection to a new local server; that is the responsibility of _createLocalServer().

Parameters:
Zend_Form$storageFormthe form with the target server port.
Zend_Form$adminFormthe form containing admin credentials.
Returns:
P4_Connection_Interface an admin connection to the target server
    {
        // if we already have prepared an admin connection, re-use it.
        if ($this->_adminP4) {
            return $this->_adminP4;
        }

        // if we have a known perforce server use it,
        // otherwise use the port passed in via storageForm
        $bootstrap = $this->getInvokeArg('bootstrap');
        $port      = $bootstrap->hasResource('perforce')
            ? $bootstrap->getResource('perforce')->getPort()
            : $storageForm->getValue('port');

        $adminP4 = P4_Connection::factory(
            $port,
            $adminForm->getValue('user'),
            null,
            $adminForm->getValue('password')
        );
        $adminP4->login();

        return $adminP4;
    }
Setup_IndexController::_getFriendlyPort ( P4_Connection_Interface connection) [protected]

Present rsh ports as 'Local Server: /path/to/server/root'.

Remote server ports are returned as-is.

Parameters:
P4_Connection_Interface$connectionconnection to pretty-up port of.
Returns:
string the friendly port
    {
        if ($this->_isRshServer($connection)) {
            $info = $connection->getInfo();
            return $info['serverRoot'];
        }

        return $connection->getPort();
    }
Setup_IndexController::_isInitalSetup ( ) [protected]

Check if setup is running for the first time.

We consider it the 'maiden voyage' if perforce is not yet configured.

Returns:
bool true if it is the first setup
    {
        return !$this->getInvokeArg('bootstrap')->hasResource('perforce');
    }
Setup_IndexController::_isRshServer ( P4_Connection_Interface connection) [protected]

Determines if given connection is to a local 'rsh' server.

Parameters:
P4_Connection_Interface$connectionconnection to examine.
Returns:
bool true if connection uses rsh; false otherwise.
    {
        return strpos($connection->getPort(), 'rsh:') === 0;
    }
Setup_IndexController::_p4ClientType ( )

Determine what Perforce client type is in use.

Returns:
string description of the client type
    {
        switch (get_class(P4_Connection::getDefaultConnection())) {
            case "P4_Connection_CommandLine":
                $type = 'Perforce command-line client, P4';
                break;
            case "P4_Connection_Extension":
                $type = 'Perforce PHP extension, P4PHP';
                break;
            default:
                $type = '(unknown client)';
                break;
        }

        return $type;
    }
Setup_IndexController::administratorAction ( )

Obtain server administrator information.

    {
        // if requirements not met, return to requirements step.
        if (!$this->_isValidEnvironment()) {
            $this->redirector->gotoSimple('requirements');
            return;
        }

        // If perforce server is invalid - return to storage action.
        $storageForm = new Setup_Form_Storage;
        $storageForm->setCsrfProtection(false);         // trusted source, disable CRSF so isValid works
        $session = $this->_getSession();
        if (!is_array($session->storage) ||
            !$storageForm->isValid($session->storage)) {
            $this->redirector->gotoSimple('storage');
            return;
        }

        $this->_cleanupSession();

        // setup form.
        $form = new Setup_Form_Administrator(
            array(
                'serverType' => $storageForm->getValue('serverType'),
                'p4Port'     => $session->storage['port']
            )
        );

        // setup view.
        $view        = $this->view;
        $perforce    = $this->getInvokeArg('bootstrap')->getResource('perforce');
        $view->port  = $perforce ? $this->_getFriendlyPort($perforce) : $session->storage['port'];
        $view->isRsh = $perforce ? $this->_isRshServer($perforce) : false;
        $view->form  = $form;
        $view->headTitle()->set('Setup Administrator');

        // if form has been posted and is valid, save values
        // to session and proceed to site form.
        $request = $this->getRequest();
        if ($request->isPost() && $form->isValid($request->getPost())) {
            $session                = $this->_getSession();
            $session->administrator = $form->getValues();
            if ($request->getParam('goback')) {
                $this->redirector->gotoSimple('storage');
                return;
            }
            $this->redirector->gotoSimple('site');
            return;
        } elseif ($request->isPost()) {
            if ($request->getParam('goback')) {
                $this->redirector->gotoSimple('storage');
                return;
            }
            $count = count($form->getMessages());
            $s = ($count == 1) ? '' : 's';
            P4Cms_Notifications::add("$count field$s failed validation.", P4Cms_Notifications::SEVERITY_ERROR);
        }

    }
Setup_IndexController::createAction ( )

This action allows api's to make a single post to create a new site.

You should be able to succesfully add a site with the following post: storage[serverType]=new administrator[user]=<valid-user> administrator[email]=<valid-email> administrator[password]=<valid-password> administrator[passwordConfirm]=<valid-password> site[title]=<valid-title>

To use an existing perforce server replace the storage line with: storage[serverType]=existing storage[port]=perforce:1666

A json response will be returned with the following data: step = environment, storage, administrator, site or completed isValid = true or false errors = may contain a form key with an array of strings and/or an elements key which contains error arrays indexed by element id. value(s) can be ignored if isValid is true.

Note: the site[urls] field is only optional for the first site if any subsequent sites are added this field must be included.

    {
        // force a json context
        $this->contextSwitch->initContext('json');

        // administrator (username, email, password, confirm)
        // site-storage  (new or old radio and address)
        // site          (title/address/description)

        $request = $this->getRequest();
        $session = $this->_getSession();

        $session->administrator = $request->getPost('administrator');
        $session->storage       = $request->getPost('storage');

        // ensure the request only contains the values of site
        $site = (array) $request->getPost('site');
        $request->setPost($site + array('administrator' => '', 'storage' => '', 'site' => ''));

        // call through to the site action passing true to
        // ensure it won't redirect and our initial setup
        // status to determine if urls are optional or not.
        $this->siteAction(true, $this->_isInitalSetup());
    }
Setup_IndexController::indexAction ( )

Show setup splash page.

    {
        $this->_cleanupSession();

        // display splash page unless start is set.
        $request = $this->getRequest();
        if ($request->getParam('start')) {
            $this->_forward('requirements');
        } else {
            // build start url.
            $startUrl = $request->getBaseUrl();
            if ($this->_isRewriteWorking()) {
                $startUrl .= '/setup/start/yes';
            } else {
                $startUrl .= '?start=yes';
            }
            $this->view->startUrl = $startUrl;
        }
        $this->view->headTitle()->set('Setup');
    }
Setup_IndexController::init ( )

Use the setup layout and disable toolbar for all setup actions.

    {
        $this->_helper->layout->setLayout('setup-layout');

        // never cache setup requests; they can be particularly problematic
        // on the first run of setup caching the root page.
        if (P4Cms_Cache::canCache('page')) {
            P4Cms_Cache::getCache('page')->cancel();
        }

        // list of actions that will be skipped from the permissions check
        $skipActions = array('rewrite', 'summary');

        // don't enforce permissions if setup is needed.
        // as there is only one privilege, we can do the permissions check for all
        // actions here - with the exception of actions listed in skipActions.
        if (in_array($this->getRequest()->getActionName(), $skipActions)
            || $this->getInvokeArg('bootstrap')->isSetupNeeded()
        ) {
            return;
        }

        // enforce permissions.
        $this->_helper->acl->check('site', 'add');
    }
Setup_IndexController::requirementsAction ( )

Start setup process by checking requirements.

    {
        $this->_cleanupSession();

        $this->view->headTitle()->set('Setup Requirements');

        // check overall sanity.
        $this->view->isValidEnvironment     = $this->_isValidEnvironment();

        // check php requirement.
        $this->view->isPhpValid             = $this->_isPhpValid();
        $this->view->isPhpVersionValid      = $this->_isPhpVersionValid();
        $this->view->phpVersion             = PHP_VERSION;
        $this->view->minPhpVersion          = self::MIN_PHP_VERSION;
        $this->view->isMagicQuotesOn        = $this->_isMagicQuotesOn();

        // check mod-rewrite requirement.
        $this->view->isRewriteWorking       = $this->_isRewriteWorking();

        // check p4 requirement.
        $this->view->isP4Valid              = $this->_isP4Valid();
        $this->view->p4Version              = $this->_getP4Version();
        $this->view->minP4Version           = self::MIN_P4_VERSION;
        $this->view->isP4Installed          = $this->_isP4Installed();
        $this->view->p4ClientType           = $this->_p4ClientType();

        // check data directory.
        $this->view->isDataPathValid        = $this->_isDataPathValid();
        $this->view->isDataPathPresent      = $this->_isDataPathPresent();
        $this->view->isDataPathWritable     = $this->_isDataPathWritable();
        $this->view->dataPath               = DATA_PATH;

        // check the Perforce extension
        $this->view->isP4PHPInstalled       = extension_loaded('perforce');

        // check the Opcode Cache.
        $this->view->isWinCacheInstalled    = extension_loaded('wincache');
        $this->view->isApcInstalled         = extension_loaded('apc');
        if (P4_Environment::isWindows() && isset($_SERVER['SERVER_SOFTWARE'])) {
            $this->view->isWebServerIis     = stripos($_SERVER['SERVER_SOFTWARE'], "Microsoft-IIS") !== false;
        }

        // check for image manipulation availability
        $this->view->imageExtensions        = array();
        $this->view->imageExtensionsEnabled = array();
        foreach (P4Cms_Image_Driver_Factory::getDriverClasses() as $driverClass) {
            $extension = $driverClass::getRequiredExtension();
            if (!$extension) {
                continue;
            }
            $this->view->imageExtensions[] = $extension;
            if (extension_loaded($extension)) {
                $this->view->imageExtensionsEnabled[] = $extension;
            }
        }

        // check for common image types support for the default driver
        try {
            $defaultDriver = P4Cms_Image_Driver_Factory::create();
        } catch (P4Cms_Image_Exception $e) {
            // no driver available
            $defaultDriver = null;
        }
        $commonTypes                         = array('jpeg', 'png', 'gif');
        $this->view->defaultImageDriver      = $defaultDriver;
        $this->view->missingCommonImageTypes = $defaultDriver
            ? array_diff($commonTypes, array_filter($commonTypes, array($defaultDriver, 'isSupportedType')))
            : array();

        // save the username/group for the web server if available
        $webServerDetails = '';
        if (function_exists("posix_geteuid")
            && function_exists("posix_getpwuid")
            && function_exists("posix_getgrgid")
        ) {
            $userInfo  = posix_getpwuid(posix_geteuid());
            $userName  = $userInfo['name'];
            $groupInfo = posix_getgrgid($userInfo['gid']);
            $groupName = $groupInfo['name'];
            $webServerDetails = " (username \"$userName\", group \"$groupName\")";
        }
        $this->view->webServerDetails = $webServerDetails;
    }
Setup_IndexController::rewriteAction ( )

Simple action exists only to be requested to test if rewrite is working.

Responds with a checksum of this file.

    {
        print(md5_file(__FILE__));
        $this->_helper->layout()->disableLayout();
        $this->_helper->viewRenderer->setNoRender();
    }
Setup_IndexController::siteAction ( skipRedirect = false,
optionalUrls = false 
)

Setup a site definition.

Both of the optional paramaters are intended for use by the 'create' action.

Parameters:
bool$skipRedirectoptional - if true skips trying to redirect backward for failed requirements and simply returns.
bool$optionalUrlsoptional - if true the 'urls' field of the site form isn't required.
    {
        // if requirements not met, return to requirements step.
        if (!$this->_isValidEnvironment()) {
            $this->view->step    = 'environment';
            $this->view->isValid = false;
            $this->view->errors  = array('form' => array('One or more requirements are not met.'));

            $skipRedirect ?: $this->redirector->gotoSimple('requirements');
            return;
        }

        // if perforce server is invalid - return to storage action.
        $storageForm  = new Setup_Form_Storage;
        $storageForm->setCsrfProtection(false);         // trusted source, disable CRSF so isValid works
        $session = $this->_getSession();
        if (!$storageForm->isValid((array) $session->storage)) {
            $this->view->step    = 'storage';
            $this->view->isValid = false;
            $this->view->form    = $storageForm;

            $skipRedirect ?: $this->redirector->gotoSimple('storage');
            return;
        }

        // if administrator credentials are invalid, return to administrator action
        $options   = array('serverType' => $session->storage['serverType']);
        $adminForm = new Setup_Form_Administrator($options);
        $adminForm->setCsrfProtection(false);   // trusted source, disable CRSF so isValid works
        $adminForm->setP4Port($session->storage['port']);
        $adminForm->setServerType($session->storage['serverType']);
        if (!$adminForm->isValid((array) $session->administrator)) {
            $this->view->step    = 'administrator';
            $this->view->isValid = false;
            $this->view->form    = $adminForm;

            $skipRedirect ?: $this->redirector->gotoSimple('administrator');
            return;
        }

        // set the page title
        $view = $this->view;
        $view->headTitle()->set('Setup Site');

        // prepare the site form - if we are adding a site to an existing
        // perforce server, we need a connection to the server so that the
        // form can check if the site title is taken.
        $form       = new Setup_Form_Site;
        $view->form = $form;
        $bootstrap  = $this->getInvokeArg('bootstrap');
        if ($bootstrap->hasResource('perforce')
            || $storageForm->getValue('serverType') !== $storageForm::SERVER_TYPE_NEW
        ) {
            $form->setConnection(
                $this->_getAdminConnection($storageForm, $adminForm)
            );
        }

        // make urls optional if requested by caller
        // this is intended for API driven create
        if ($optionalUrls) {
            $form->getElement('urls')->setRequired(false);
        }

        // if form has been posted and is valid, create site.
        $request = $this->getRequest();
        if ($request->isPost() && $form->isValid($request->getPost())) {
            if ($request->getParam('goback')) {
                $this->redirector->gotoSimple('administrator');
                return;
            }

            $site = $this->_createSite($form, $storageForm, $adminForm);

            // as we have created a new site, we need to clear the site cache.
            P4Cms_Cache::remove(P4Cms_Site::CACHE_KEY, 'global');

            $session->site          = $site;
            $session->setupComplete = true;

            $this->view->step       = 'completed';
            $this->view->isValid    = true;

            $skipRedirect ?: $this->redirector->gotoSimple('summary');
        } elseif ($request->isPost()) {
            if ($request->getParam('goback')) {
                $this->redirector->gotoSimple('administrator');
                return;
            }

            $this->view->step    = 'site';
            $this->view->isValid = false;
            $this->view->form    = $form;

            $count = count($form->getMessages());
            $s = ($count == 1) ? '' : 's';
            P4Cms_Notifications::add("$count field$s failed validation.", P4Cms_Notifications::SEVERITY_ERROR);
        }
    }
Setup_IndexController::storageAction ( )

Obtain Perforce server information.

    {
        // if requirements not met, return to requirements step.
        if (!$this->_isValidEnvironment()) {
            $this->redirector->gotoSimple('requirements');
            return;
        }

        // setup view.
        $form                       = new Setup_Form_Storage;
        $this->view->form           = $form;
        $this->view->isP4dInstalled = $form->isP4dInstalled();
        $this->view->isP4dValid     = $form->isP4dValid();
        $this->view->minP4Version   = self::MIN_P4_VERSION;
        $this->view->headTitle()->set('Setup Site Storage');

        // if we have a previously configured perforce connection, setup
        // the form to always use it (regardless of request paramaters)
        $request  = $this->getRequest();
        $perforce = $this->getInvokeArg('bootstrap')->getResource('perforce');
        if ($perforce) {
            $form->getElement('serverType')
                 ->setAttrib('disabled', true)
                 ->setValue($form::SERVER_TYPE_EXISTING);

            $form->getElement('port')
                 ->setAttrib('disabled', true)
                 ->setValue($perforce->getPort())
                 ->setDescription('You have already configured a Perforce Server.');

            $request->setPost('serverType', $form::SERVER_TYPE_EXISTING)
                    ->setPost('port',       $perforce->getPort());
        }

        // if form has been posted and is valid, save values
        // to session and proceed to administrator form.
        if ($request->isPost() && $form->isValid($request->getPost())) {
            $session          = $this->_getSession();
            $session->storage = $form->getValues();
            if ($request->getParam('goback')) {
                $this->redirector->gotoSimple('requirements');
                return;
            }
            $this->redirector->gotoSimple('administrator');
            return;
        } elseif ($request->isPost()) {
            if ($request->getParam('goback')) {
                $this->redirector->gotoSimple('requirements');
                return;
            }
            $count = count($form->getMessages());
            $s = ($count == 1) ? '' : 's';
            P4Cms_Notifications::add("$count field$s failed validation.", P4Cms_Notifications::SEVERITY_ERROR);
        }

        // if serverType=new, disable port/address field
        if ($form->getValue('serverType') == $form::SERVER_TYPE_NEW) {
            $group = $form->getDisplayGroup('existingServer');
            $group->setAttrib('class', $group->getAttrib('class') . ' disabled');
        }

        // if we have a previously configured 'rsh' perforce server,
        // pretty-up the port value to hide 'rsh' details.
        if ($perforce && $this->_isRshServer($perforce)) {
            $form->getElement('port')
                 ->setValue($this->_getFriendlyPort($perforce))
                 ->setLabel('Local Server');
        }
    }
Setup_IndexController::summaryAction ( )

Summarize site setup - clear site from session.

    {
        // if requirements not met, return to requirements step.
        if (!$this->_isValidEnvironment()) {
            $this->redirector->gotoSimple('requirements');
            return;
        }

        // if no site data in session, redirect to site creation.
        $session = $this->_getSession();
        if (!isset($session->site)) {
            $this->redirector->gotoSimple('site');
            return;
        }

        // setup view data.
        $view           = $this->view;
        $perforce       = $this->getInvokeArg('bootstrap')->getResource('perforce');
        $view->port     = $perforce ? $this->_getFriendlyPort($perforce) : $session->storage['port'];
        $view->isRsh    = $perforce ? $this->_isRshServer($perforce) : false;
        $view->site     = $session->site;
        $view->storage  = $session->storage;
        $view->admin    = $session->administrator;
        $view->headTitle()->set('Setup Summary');
    }

Member Data Documentation

Setup_IndexController::$_adminP4 = null [protected]
Setup_IndexController::$_session = null [protected]
Setup_IndexController::$contexts
Initial value:
 array(
        'requirements'  => array('partial'),
        'create'        => array('json')
    )
const Setup_IndexController::P4D_USER = 'chronicle'

The documentation for this class was generated from the following file: