Module.php #1

  • //
  • guest/
  • perforce_software/
  • chronicle/
  • main/
  • application/
  • site/
  • Module.php
  • View
  • Commits
  • Open Download .zip Download (28 KB)
<?php
/**
 * Integrate the site module with the rest of the application.
 *
 * @copyright   2011 Perforce Software. All rights reserved.
 * @license     Please see LICENSE.txt in top-level folder of this distribution.
 * @version     <release>/<patch>
 */
class Site_Module extends P4Cms_Module_Integration
{
    /**
     * Perform early integration work (before load).
     */
    public static function init()
    {
        // register a controller plugin to handle access/branch acl check
        $front = Zend_Controller_Front::getInstance();
        $front->registerPlugin(new Site_AccessBranchCheck);

        // provide form to filter modules by keyword search.
        P4Cms_PubSub::subscribe('p4cms.site.module.grid.form.subForms',
            function(Zend_Form $form)
            {
                return new Ui_Form_GridSearch;
            }
        );

        // provide form to filter modules by type
        P4Cms_PubSub::subscribe('p4cms.site.module.grid.form.subForms',
            function(Zend_Form $form)
            {
                $options = array(
                    ''          => 'Any Type',
                    'core'      => 'Only Core',
                    'external'  => 'Only Optional'
                );

                $form = new P4Cms_Form_SubForm;
                $form->setName('typeFilter')
                     ->setAttrib('class', 'type-filter-form')
                     ->setOrder(10)
                     ->addElement(
                        'Radio', 'display',
                        array(
                            'label'         => 'Type',
                            'multiOptions'  => $options,
                            'autoApply'     => true,
                            'order'         => 20,
                            'value'         => ''
                        )
                     );

                return $form;
            }
        );

        // provide form to filter modules by status
        P4Cms_PubSub::subscribe('p4cms.site.module.grid.form.subForms',
            function(Zend_Form $form)
            {
                $options = array(
                    ''          => 'Any Status',
                    'enabled'   => 'Only Enabled',
                    'disabled'  => 'Only Disabled'
                );

                $form = new P4Cms_Form_SubForm;
                $form->setName('statusFilter')
                     ->setAttrib('class', 'status-filter-form')
                     ->setOrder(20)
                     ->addElement(
                        'Radio', 'display',
                        array(
                            'label'         => 'Status',
                            'multiOptions'  => $options,
                            'autoApply'     => true,
                            'order'         => 20,
                            'value'         => ''
                        )
                     );

                return $form;
            }
        );

        // provide form to filter modules by tag
        P4Cms_PubSub::subscribe('p4cms.site.module.grid.form.subForms',
            function(Zend_Form $form)
            {
                $tags = array();
                foreach (P4Cms_Module::fetchAll() as $module) {
                    $moduleTags = $module->getTags();
                    if (count($moduleTags)) {
                        $tags += array_combine($moduleTags, $moduleTags);
                    }
                }
                if (!count($tags)) {
                    return null;
                }

                natcasesort($tags);
                $form = new P4Cms_Form_SubForm;
                $form->setName('tagFilter')
                     ->setAttrib('class', 'tag-filter-form')
                     ->setOrder(30)
                     ->addElement(
                        'MultiCheckbox', 'display',
                        array(
                            'label'         => 'Tags',
                            'multiOptions'  => $tags,
                            'autoApply'     => true,
                            'order'         => 20,
                        )
                     );

                return $form;
            }
        );

        // filter modules by status
        P4Cms_PubSub::subscribe('p4cms.site.module.grid.populate',
            function(P4Cms_Model_Iterator $modules, Zend_Form $form)
            {
                // extract selected status.
                $values = $form->getValues();
                $status = $values['statusFilter']['display'];
                $status = isset($status) ? $status : '';

                switch ($status) {
                    case 'enabled':  return $modules->filter('enabled', array(true));
                    case 'disabled': return $modules->filter('enabled', array(false));
                    default:         return $modules;
                }
            }
        );

        // filter modules by type
        P4Cms_PubSub::subscribe('p4cms.site.module.grid.populate',
            function(P4Cms_Model_Iterator $modules, Zend_Form $form)
            {
                // extract selected status.
                $values = $form->getValues();
                $type = $values['typeFilter']['display'];
                $type = isset($type) ? $type : '';

                switch ($type) {
                    case 'core':     return $modules->filter('core', array(true));
                    case 'external': return $modules->filter('core', array(false));
                    default:         return $modules;
                }
            }
        );

        // filter modules by tag
        P4Cms_PubSub::subscribe('p4cms.site.module.grid.populate',
            function(P4Cms_Model_Iterator $modules, Zend_Form $form)
            {
                // extract selected status.
                $values = $form->getValues();
                if (!array_key_exists('tagFilter', $values)) {
                    return $modules;
                }
                $tags = $values['tagFilter']['display'];
                if (!isset($tags)) {
                    return $modules;
                }

                return $modules->filter(
                    'tags',
                    $tags,
                    array(
                        P4_Model_Iterator::FILTER_CONTAINS,
                        P4_Model_Iterator::FILTER_IMPLODE,
                    )
                );
            }
        );

        // filter module list by keyword search.
        P4Cms_PubSub::subscribe('p4cms.site.module.grid.populate',
            function(P4Cms_Model_Iterator $modules, Zend_Form $form)
            {
                $values = $form->getValues();

                // skip searching if there is no query
                $query = $values['search']['query'];
                if (!isset($query) || !strlen($query)) {
                    return;
                }

                // remove users that don't match search query.
                return $modules->search(
                    array('name', 'description', 'version', 'maintainerInfo'),
                    $values['search']['query']
                );
            }
        );

        // provide form to filter theme by keyword search.
        P4Cms_PubSub::subscribe('p4cms.site.theme.grid.form.subForms',
            function(Zend_Form $form)
            {
                return new Ui_Form_GridSearch;
            }
        );

        // filter theme list by keyword search.
        P4Cms_PubSub::subscribe('p4cms.site.theme.grid.populate',
            function(P4Cms_Model_Iterator $themes, Zend_Form $form)
            {
                $values = $form->getValues();

                // skip searching if there is no query
                $query = $values['search']['query'];
                if (!isset($query) || !strlen($query)) {
                    return;
                }

                // return themes that match search query.
                return $themes->search(
                    array('name', 'label', 'description', 'version', 'maintainerInfo'),
                    $query
                );
            }
        );

        // provide form to filter themes by tag
        P4Cms_PubSub::subscribe('p4cms.site.theme.grid.form.subForms',
            function(Zend_Form $form)
            {
                $tags = array();
                foreach (P4Cms_Theme::fetchAll() as $theme) {
                    $themeTags = $theme->getTags();
                    if (count($themeTags)) {
                        $tags += array_combine($themeTags, $themeTags);
                    }
                }
                if (!count($tags)) {
                    return null;
                }

                natcasesort($tags);
                $form = new P4Cms_Form_SubForm;
                $form->setName('tagFilter')
                     ->setAttrib('class', 'tag-filter-form')
                     ->setOrder(30)
                     ->addElement(
                        'MultiCheckbox', 'display',
                        array(
                            'label'         => 'Tags',
                            'multiOptions'  => $tags,
                            'autoApply'     => true,
                            'order'         => 20,
                        )
                     );

                return $form;
            }
        );

        // filter themes by tag
        P4Cms_PubSub::subscribe('p4cms.site.theme.grid.populate',
            function(P4Cms_Model_Iterator $themes, Zend_Form $form)
            {
                // extract selected status.
                $values = $form->getValues();
                if (!array_key_exists('tagFilter', $values)) {
                    return $themes;
                }
                $tags = $values['tagFilter']['display'];
                if (!isset($tags)) {
                    return $themes;
                }

                return $themes->filter(
                    'tags',
                    $tags,
                    array(
                        P4_Model_Iterator::FILTER_CONTAINS,
                        P4_Model_Iterator::FILTER_IMPLODE,
                    )
                );
            }
        );

        // provide form to filter sites/branches by keyword search.
        P4Cms_PubSub::subscribe('p4cms.site.branch.grid.form.subForms',
            function(Zend_Form $form)
            {
                return new Ui_Form_GridSearch;
            }
        );

        // filter site/branch list by keyword search.
        P4Cms_PubSub::subscribe('p4cms.site.branch.grid.populate',
            function(P4Cms_Model_Iterator $items, Zend_Form $form)
            {
                $values = $form->getValues();

                // skip searching if there is no query
                $query = $values['search']['query'];
                if (!isset($query) || !strlen($query)) {
                    return;
                }

                // return items that match search query.
                return $items->search(
                    array('name', 'owner'),
                    $query
                );
            }
        );

        // provide form to filter site/branch list by site.
        P4Cms_PubSub::subscribe('p4cms.site.branch.grid.form.subForms',
            function(Site_Form_BranchGridOptions $form)
            {
                $items   = $form->getItems()
                                ->filter('type', 'site', P4Cms_Model_Iterator::FILTER_COPY);
                $options = array_combine(
                    $items->invoke('getId'), $items->invoke('getValue', array('name'))
                );

                // exit early if we have no options
                if (empty($options)) {
                    return null;
                }

                $subform = new P4Cms_Form_SubForm;
                $subform->setName('site')
                        ->setAttrib('class', 'site-branch-form')
                        ->setOrder(20)
                        ->addElement(
                            'MultiCheckbox', 'sites',
                            array(
                                'label'         => 'Site',
                                'multiOptions'  => $options,
                                'autoApply'     => true
                            )
                        );

                return $subform;
            }
        );

        // filter site/branch list by site
        P4Cms_PubSub::subscribe('p4cms.site.branch.grid.populate',
            function(P4Cms_Model_Iterator $items, Zend_Form $form)
            {
                $values = $form->getValues();

                // extract selected sites.
                $sites = isset($values['site']['sites'])
                    ? $values['site']['sites']
                    : array();

                if (!empty($sites)) {
                    $items->filter('siteId', $sites);
                }
            }
        );

        // provide form to filter site/branch list by owner.
        P4Cms_PubSub::subscribe('p4cms.site.branch.grid.form.subForms',
            function(Site_Form_BranchGridOptions $form)
            {
                $users   = $form->getItems()->invoke('getValue', array('owner'));
                $options = array_combine($users, $users);

                // exit early if we have no users
                if (empty($users)) {
                    return null;
                }

                $subform = new P4Cms_Form_SubForm;
                $subform->setName('user')
                        ->setAttrib('class', 'site-branch-form')
                        ->setOrder(30)
                        ->addElement(
                            'MultiCheckbox', 'users',
                            array(
                                'label'         => 'Owner',
                                'filters'       => array('StringTrim'),
                                'multiOptions'  => $options,
                                'autoApply'     => true
                            )
                        );

                return $subform;
            }
        );

        // filter site/branch list by owner
        P4Cms_PubSub::subscribe('p4cms.site.branch.grid.populate',
            function(P4_Model_Iterator $items, Zend_Form $form)
            {
                $values = $form->getValues();

                // extract selected users.
                $users = isset($values['user']['users'])
                    ? $values['user']['users']
                    : array();

                if (!empty($users)) {
                    $items->filter('owner', $users);
                }
            }
        );

        // provide site/branch management actions
        P4Cms_PubSub::subscribe('p4cms.site.branch.grid.actions',
            function($actions)
            {
                $actions->addPages(
                    array(
                        array(
                            'label'     => 'View',
                            'onClick'   => 'p4cms.site.branch.grid.Actions.onClickView();',
                            'onShow'    => 'p4cms.site.branch.grid.Actions.onShowView(this);',
                            'order'     => '10'
                        ),
                        array(
                            'label'     => 'Edit',
                            'onClick'   => 'p4cms.site.branch.grid.Actions.onClickEdit();',
                            'onShow'    => 'p4cms.site.branch.grid.Actions.onShowEdit(this);',
                            'order'     => '20'
                        ),
                        array(
                            'label'     => 'Delete',
                            'onClick'   => 'p4cms.site.branch.grid.Actions.onClickDelete();',
                            'onShow'    => 'p4cms.site.branch.grid.Actions.onShowDelete(this);',
                            'order'     => '30'
                        ),
                        array(
                            'type'      => 'P4Cms_Navigation_Page_Separator',
                            'order'     => '40'
                        ),
                        array(
                            'label'     => 'Add Branch',
                            'onClick'   => 'p4cms.site.branch.grid.Actions.onClickAddBranch();',
                            'onShow'    => 'p4cms.site.branch.grid.Actions.onShowAddBranch(this);',
                            'order'     => '50'
                        )
                    )
                );
            }
        );

        // provide 'site' macro.
        P4Cms_PubSub::subscribe('p4cms.macro.site',
            function($params, $body, $context)
            {
                $field  = isset($params[0]) ? $params[0] : 'title';
                $site   = P4Cms_Site::fetchActive();
                $config = $site->getConfig();

                switch ($field) {
                    case 'title':
                        return $config->getTitle();
                        break;
                    case 'description':
                        return $config->getDescription();
                        break;
                    case 'theme':
                        return $config->getTheme();
                        break;
                    case 'branch':
                        return $site->getStream()->getName();
                        break;
                    default:
                        return null;
                }
            }
        );

        // provide 'theme' macro.
        P4Cms_PubSub::subscribe('p4cms.macro.theme',
            function($params, $body, $context)
            {
                $field = isset($params[0]) ? $params[0] : 'baseUrl';
                $theme = P4Cms_Theme::fetchActive();

                switch ($field) {
                    case 'baseUrl':
                        return $theme->getBaseUrl();
                        break;
                    default:
                        return null;
                }
            }
        );

        // organize config-related records when pulling changes.
        P4Cms_PubSub::subscribe(
            'p4cms.site.branch.pull.groupPaths',
            function($paths, $source, $target, $result)
            {
                // make a umbrella group for all config related entries.
                $config = new Site_Model_PullPathGroup;
                $config->setLabel('Configuration');
                $paths->addSubGroup($config);

                // make sub-groups to hold general config, theme selection and module config.
                $config->addSubGroup(
                    array(
                        'label'         => 'General Settings',
                        'hideCount'     => true,
                        'inheritPaths'  => $target->getId() . '/' . P4Cms_Site_Config::ID_GENERAL,
                        'details'       =>
                            function($paths) use ($source)
                            {
                                $path    = $paths->first();
                                $details = new P4Cms_Model_Iterator;

                                if ($path) {
                                    $details[] = new P4Cms_Model(
                                        array(
                                            'conflict' => $path->conflict,
                                            'action'   => $path->action,
                                            'type'     => 'Configuration',
                                            'label'    => 'General Settings'
                                        )
                                    );
                                }

                                return $details;
                            }
                    )
                );
                $config->addSubGroup(
                    array(
                        'label'         => 'Theme Setting',
                        'hideCount'     => true,
                        'inheritPaths'  => $target->getId() . '/' . P4Cms_Site_Config::ID_THEME,
                        'details'       =>
                            function($paths) use ($source)
                            {
                                $path    = $paths->first();
                                $details = new P4Cms_Model_Iterator;

                                if ($path) {
                                    $details[] = new P4Cms_Model(
                                        array(
                                            'conflict' => $path->conflict,
                                            'action'   => $path->action,
                                            'type'     => 'Configuration',
                                            'label'    => 'Theme Setting'
                                        )
                                    );
                                }

                                return $details;
                            }
                    )
                );
                // @todo if modules become branch specific we will have to be careful
                //       which branch we query here. We need to read from source.
                $config->addSubGroup(
                    array(
                        'label'         => 'Module Settings',
                        'basePaths'     => $target->getId() . '/config/module/...',
                        'inheritPaths'  => $target->getId() . '/config/module/...',
                        'details'       =>
                            function($paths) use ($source)
                            {
                                $details = new P4Cms_Model_Iterator;
                                foreach ($paths as $path) {
                                    $id        = basename($path->depotFile);
                                    $entry     = P4Cms_Module::fetch($id);

                                    // customize action to reflect module operations
                                    $action    = $path->action;
                                    $action    = $action == 'branch'    ? 'enable'    : $action;
                                    $action    = $action == 'delete'    ? 'disable'   : $action;
                                    $action    = $action == 'integrate' ? 'configure' : $action;

                                    $details[] = new P4Cms_Model(
                                        array(
                                            'conflict' => $path->conflict,
                                            'action'   => $action,
                                            'label'    => $entry->getName()
                                        )
                                    );
                                }

                                $details->setProperty(
                                    'columns',
                                    array('label' => 'Module', 'action' => 'Action')
                                );

                                return $details;
                            }
                    )
                );

                // exclude the url configuration from being pulled
                $paths->getPaths()->filter(
                    'depotFile',
                    $target->getId() . '/' . P4Cms_Site_Config::ID_URLS,
                    P4Cms_Model_Iterator::FILTER_INVERSE
                );
            }
        );

        // provide dynamic branches menu
        P4Cms_PubSub::subscribe('p4cms.navigation.dynamicHandlers',
            function()
            {
                $handler = new P4Cms_Navigation_DynamicHandler;
                $handler->setId('site.branches')
                        ->setLabel('Branch Listing')
                        ->setExpansionCallback(
                            function($item, $options)
                            {
                                // fetch branches for the active site.
                                $active   = P4Cms_Site::fetchActive();
                                $branches = P4Cms_Site::fetchAll(
                                    array(
                                        P4Cms_Site::FETCH_BY_SITE   => $active->getSiteId(),
                                        P4Cms_Site::FETCH_SORT_FLAT => true
                                    )
                                );

                                // add each branch as a menu item.
                                $items = array();
                                $user  = P4Cms_User::fetchActive();
                                foreach ($branches as $branch) {
                                    // doesn't make sense to include the active branch
                                    // as these items can only switch-to or pull-from
                                    if ($branch->getId() == $active->getId()) {
                                        continue;
                                    }

                                    // by default skip branches the user doesn't have
                                    // access to, if doPull is set, only skip branches
                                    // the user doesn't have permission to pull from.
                                    $privilege = $item->doPull ? 'pull-from' : 'access';
                                    if (!$user->isAllowed('branch', $privilege, $branch->getAcl())) {
                                        continue;
                                    }

                                    // we need json-encoded branch data for switch-to
                                    // and pull-from javascript functions.
                                    $data = Zend_Json::encode(
                                        array(
                                            'id'        => $branch->getId(),
                                            'name'      => $branch->getStream()->getName(),
                                            'basename'  => $branch->getBranchBasename(),
                                            'url'       => $branch->getConfig()->getUrl()
                                        )
                                    );

                                    // default behavior of item is to switch
                                    // to the branch, if doPull is set, prompt
                                    // to pull from the branch.
                                    $items[] = array(
                                        'label'   => $branch->getStream()->getName(),
                                        'onClick' => $item->doPull
                                            ? "p4cms.site.branch.pullFrom($data);"
                                            : "p4cms.site.branch.switchTo($data);"
                                    );
                                }

                                // if we don't have any items, add empty text if specified
                                if (!$items && $item->emptyText) {
                                    $items[] = array(
                                        'label'    => $item->emptyText,
                                        'disabled' => true
                                    );
                                }

                                // if there are items, add the separator if one was requested
                                if ($items && $item->separator == 'after') {
                                    $items[] = array('label' => '-');
                                }
                                if ($items && $item->separator == 'before') {
                                    array_unshift($items, array('label' => '-'));
                                }

                                return $items;
                            }
                        );

                return array($handler);
            }
        );
    }

    /**
     * Perform integration operations when the site is loaded.
     */
    public static function load()
    {
        // include the site description, if there is one, in the meta tags
        if (P4Cms_Site::hasActive()) {
            $site        = P4Cms_Site::fetchActive();
            $description = $site->getConfig()->getDescription();
            if (strlen($description)) {
                Zend_Layout::getMvcInstance()
                    ->getView()
                    ->headMeta()
                    ->appendName('description', $description);
            }

            // make 'id' and 'siteId' of the active site visible to javascript
            $view = Zend_Layout::getMvcInstance()->getView();
            $data = array(
                'id'     => $site->getId(),
                'siteId' => $site->getSiteId()
            );
            $script = "dojo.setObject('p4cms.site.active', " . Zend_Json::encode($data) . ");";
            $view->headScript()->appendScript($script);
        }
    }
}
# Change User Description Committed
#1 16170 perforce_software Move Chronicle files to follow new path scheme for branching.
//guest/perforce_software/chronicle/application/site/Module.php
#1 8972 Matt Attaway Initial add of the Chronicle source code