Perforce Chronicle 2012.2/486814
API Documentation

P4Cms_Site Class Reference

Sites are used to group website configurations and contents. More...

Inheritance diagram for P4Cms_Site:
P4Cms_Model P4Cms_ModelInterface

List of all members.

Public Member Functions

 __sleep ()
 We need a custom sleep to exclude the adapter and connections.
 __wakeup ()
 We need a custom wakeup to provide any unserialized connected objects with valid connections.
 getAcl ()
 Get the ACL for this site.
 getBranchBasename ()
 Get the sub-folder of this site branch in the site depot.
 getConfig ()
 Get the configuration object for this site branch.
 getConnection ()
 Get the perforce connection for this site.
 getDataPath ()
 Get the path to this site branch's data folder.
 getDeferredAdapter ()
 Get a 'deferred' storage adapter.
 getDeferredConnection ()
 Get a 'deferred' connection.
 getModulesPath ()
 Get the path to this site's modules.
 getPackagesPath ()
 Get the path to this site's packages folder (not branch specific)
 getParent ()
 Get a reference to this site/branch's parent branch (if it has one).
 getResourcesPath ()
 Get the path to this site's (writable) public resources.
 getSiteId ()
 Get the id of the site that this branch belongs to.
 getStorageAdapter ()
 Get the storage adapter to use when reading records from and writing records to this site.
 getStream ()
 Get the stream object for this site branch.
 getThemesPath ()
 Get the path to this site's themes.
 getWorkspacesPath ()
 Get the path to this site's p4 workspaces.
 hasConnection ()
 Check if this site/branch already has a perforce connection.
 load ()
 Load this site into the environment and set it as the active site.
 setConnection (P4_Connection_Interface $connection=null)
 Warning: this method changes the client of the given connection.
 setParent (P4Cms_Site $parent=null)
 Set a reference to this site/branch's parent branch.
 setTemplateConnection (P4_Connection_Interface $connection=null)
 The connection to use as a template when generating a new connection.

Static Public Member Functions

static clearActive ()
 Clear the active site.
static exists ($id, P4_Connection_Interface $connection=null)
 Check if a site exists with the given id.
static fetch ($id, P4_Connection_Interface $connection=null)
 Fetch a single site by id from the local sites list.
static fetchActive ()
 Fetch the active (currently loaded) site.
static fetchAll (array $options=null, P4_Connection_Interface $connection=null)
 Get all sites/branches from Perforce as site models.
static fetchByRequest (Zend_Controller_Request_Http $request, array $limit=null, P4_Connection_Interface $connection=null)
 Get the first site/branch that matches the request.
static getSitesDataPath ($siteId=null)
 Get the path to the sites data folder.
static getSitesPackagesPath ($siteId=null)
 Get the path to the sites packages folder.
static hasActive ()
 Determine if there is an active (currently loaded) site.
static setSitesDataPath ($path)
 Set the path to the sites data folder (where sites data is stored).
static setSitesPackagesPath ($path)
 Set the path to the sites packages folder.

Public Attributes

const ACL_RECORD_ID = 'config/acl'
const CACHE_KEY = 'sites'
const DEFAULT_BRANCH = 'live'
const FETCH_BY_ACL = 'acl'
const FETCH_BY_SITE = 'site'
const FETCH_SORT_FLAT = 'flat'
const SITE_PREFIX = 'chronicle-'

Protected Member Functions

 _customizeConnection (P4_Connection_Interface $connection)
 Customize the given connection for this site.
 _setStream (P4_Stream $stream=null)
 Used by fetchAll to set the stream on a new instance.

Static Protected Member Functions

static _sortBySiteTitle (P4Cms_Model_Iterator $sites)
 Sort sites by the title of the first mainline within each site.

Protected Attributes

 $_acl = null
 $_adapter = null
 $_config = null
 $_connection = null
 $_parent = null
 $_stream = null
 $_templateConnection = null

Static Protected Attributes

static $_activeSite = null
static $_idField = 'id'
static $_sitesDataPath = null
static $_sitesPackagesPath = null

Detailed Description

Sites are used to group website configurations and contents.

Site configuration and content are stored in Perforce.

This class models a particular branch (a stream) of a site. The identifier for a site branch corresponds directly with the id of a stream in Perforce.

Arguably this class should not be called 'P4Cms_Site' as it does not actually model a site, but rather a specific branch of a site (a site contains many branches). We chose to treat this as a implementation detail because in most cases the calling code that interfaces with the site object does not care that it is actually a branch. It is simpler to think of it as a site.

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

P4Cms_Site::__sleep ( )

We need a custom sleep to exclude the adapter and connections.

Connection objects cannot be serialized.

Returns:
array list of properties to serialize
    {
        return array_diff(
            array_keys(get_object_vars($this)),
            array('_connection', '_templateConnection', '_adapter')
        );
    }
P4Cms_Site::__wakeup ( )

We need a custom wakeup to provide any unserialized connected objects with valid connections.

We use deferred connections to avoid actually creating the connections until they are needed and to ensure that the connected objects always use the same connection as the site.

Note: the site config object takes care of itself. It always defers to its associated site's adapter (e.g. in save()).

    {
        if ($this->_stream) {
            $this->_stream->setConnection($this->getDeferredConnection());
        }
        if ($this->_acl) {
            $this->_acl->getRecord()->setAdapter($this->getDeferredAdapter());
        }
    }
P4Cms_Site::_customizeConnection ( P4_Connection_Interface connection) [protected]

Customize the given connection for this site.

Creates a new client configured to use this site's stream and configures the given connection to use the new client.

Parameters:
P4_Connection_Interface$connectionthe connection to customize
Returns:
P4_Connection_Interface the customized connection.
    {
        // we cannot customize the connection if we don't have an id (aka a stream id)
        if (!$this->getId()) {
            throw new P4Cms_Site_Exception(
                "Cannot customize connection. No stream id has been set."
            );
        }

        // to avoid problems that result from multiple processes
        // sharing one client (namely race conditions), we generate
        // a temporary client for each request.
        $tempClientId = P4_Client::makeTempId();

        // setup our temp client to use the site's stream.
        $root   = $this->getWorkspacesPath() . "/" . $tempClientId;
        $client = new P4_Client($connection);
        $client->setId($tempClientId)
               ->setStream($this->getId())
               ->setRoot($root);

        // create the client with the values we've setup above, using
        // makeTemp() so that it will be destroyed automatically.
        // provide a custom clean-up callback to delete the workspace folder.
        $cleanup = function($entry, $defaultCallback) use ($root)
        {
            $defaultCallback($entry);
            P4Cms_FileUtility::deleteRecursive($root);
        };
        P4_Client::makeTemp($client->getValues(), $cleanup, $connection);

        // use our newly created client.
        $connection->setClient($tempClientId);

        return $connection;
    }
P4Cms_Site::_setStream ( P4_Stream stream = null) [protected]

Used by fetchAll to set the stream on a new instance.

Parameters:
P4_Stream | null$streamstream to use for this site
Returns:
P4Cms_Site provides fluent interface.
    {
        $this->_stream = $stream;

        return $this;
    }
static P4Cms_Site::_sortBySiteTitle ( P4Cms_Model_Iterator sites) [static, protected]

Sort sites by the title of the first mainline within each site.

Maintains the existing order for the branches within each site.

Parameters:
P4Cms_Model_Iterator$sitessites already sorted by stream name/depth
Returns:
P4Cms_Model_Iterator sorted result
    {
        // create a model for each site which has the mainline's title and
        // holds an iterator of all the site's branches in the correct order
        $bySite = new P4Cms_Model_Iterator;
        foreach ($sites as $site) {
            $siteId = $site->getSiteId();
            if (!isset($bySite[$siteId])) {
                $bySite[$siteId] = new P4Cms_Model;
                $bySite[$siteId]->setValue('Title', $site->getConfig()->getTitle());
                $bySite[$siteId]->branches = new P4Cms_Model_Iterator;
            }
            $bySite[$siteId]->branches[$site->getId()] = $site;
        }

        // sort the sites by the title of the mainline
        $bySite->sortBy('Title', array(P4Cms_Model_Iterator::SORT_NATURAL));

        // glue all of the branches back into a single result now
        // that they are sorted by their associated site's title
        $result = new P4Cms_Model_Iterator;
        foreach ($bySite as $site) {
            $result->merge($site->branches);
        }

        return $result;
    }
static P4Cms_Site::clearActive ( ) [static]

Clear the active site.

    {
        static::$_activeSite = null;
    }
static P4Cms_Site::exists ( id,
P4_Connection_Interface connection = null 
) [static]

Check if a site exists with the given id.

Parameters:
mixed$idthe id to check for.
P4_Connection_Interface$connectionoptional - a specific connection to use.
Returns:
bool true if the given id matches an existing site.
    {
        try {
            static::fetch($id, $connection);
            return true;
        } catch (P4Cms_Model_NotFoundException $e) {
            return false;
        }
    }
static P4Cms_Site::fetch ( id,
P4_Connection_Interface connection = null 
) [static]

Fetch a single site by id from the local sites list.

Parameters:
string$idthe id of the site to fetch.
P4_Connection_Interface$connectionoptional - a specific connection to use.
Returns:
P4Cms_Site the matching site if one exists.
Exceptions:
P4Cms_Model_NotFoundExceptionif the requested site can't be found.
    {
        // throw exception if no id given.
        if (!is_string($id) || !$id) {
            throw new InvalidArgumentException("No site id given.");
        }

        // find the identified site.
        $sites = static::fetchAll(null, $connection);
        if (!isset($sites[$id])) {
            throw new P4Cms_Model_NotFoundException("Cannot find the specified site.");
        }

        return $sites[$id];
    }
static P4Cms_Site::fetchActive ( ) [static]

Fetch the active (currently loaded) site.

Guaranteed to return the active site model or throw an exception.

Returns:
P4Cms_Site the currently active site.
Exceptions:
P4Cms_Site_Exceptionif there is no currently active site.
    {
        if (!static::$_activeSite || !static::$_activeSite instanceof P4Cms_Site) {
            throw new P4Cms_Site_Exception("There is no active (currently loaded) site.");
        }
        return static::$_activeSite;
    }
static P4Cms_Site::fetchAll ( array $  options = null,
P4_Connection_Interface connection = null 
) [static]

Get all sites/branches from Perforce as site models.

Makes heavy use of caching as this gets called numerous times per-request.

Parameters:
array | null$optionsoptional - options to limit results FETCH_BY_ACL - set to an array containing resource and/or privilige FETCH_BY_SITE - set to site id to limit to branches of that site FETCH_SORT_FLAT - set to sort by stream name ignoring hierachy
P4_Connection_Interface$connectionoptional - a specific connection to use.
Returns:
P4Cms_Model_Iterator all sites/branches.
    {
        // read sites from the global cache if possible.
        $sites = P4Cms_Cache::load(static::CACHE_KEY, 'global');
        if (!$sites instanceof P4Cms_Model_Iterator) {

            // failed to read sites out of cache, we need to read sites
            // out of perforce which means we need a connection.
            $connection = $connection ?: P4_Connection::getDefaultConnection();

            // fetch sites by querying streams in Perforce
            // chronicle sites are prefixed with 'chronicle-'
            // to distinguish them from other streams
            $streams = P4_Stream::fetchAll(
                array(
                    P4_Stream::FETCH_BY_PATH  => '//' . static::SITE_PREFIX . '*/*',
                    P4_Stream::SORT_RECURSIVE => true
                ),
                $connection
            );

            // each site will make use of this one connection
            // and in so doing change its client, we remember
            // the client here so we can restore it afterwards.
            $client = $connection->getClient();

            // generate site objects for each stream
            // we preload the site object with the stream, config and acl
            // so that next time the site object is read from cache it will
            // already have these objects set on it.
            $sites = new P4Cms_Model_Iterator;
            foreach ($streams as $stream) {
                $site = new static;
                $site->setId($stream->getId());

                // tell the site to use/customize the given connection
                // this will change the connection's client, but we will
                // set it back to the original value below.
                $site->setConnection($connection);

                // read in the stream by getting values and set it on the site.
                $stream->getValues();
                $site->_setStream($stream);

                // read in all of this site's config information.
                $site->getConfig()->getValues();

                // read in the acl (also primes acl roles).
                $site->getAcl();

                // the connection will be useless after this point as the
                // client will be changed; clear site's reference to it
                $site->setConnection(null);

                // give each site/branch a reference to its parent (if it has one)
                $parent = $site->getStream()->getParent();
                if ($parent && isset($sites[$parent])) {
                    $site->setParent($sites[$parent]);
                }

                // add this site to our list.
                $sites[$site->getId()] = $site;
            }

            // restore connection's original client.
            $connection->setClient($client);

            // sort by title of first mainline for each site
            $sites = static::_sortBySiteTitle($sites);

            // save sites to global cache.
            P4Cms_Cache::save($sites, static::CACHE_KEY, array(), null, null, 'global');
        }

        // normalize our options
        $options = (array) $options + array(
            static::FETCH_BY_SITE   => null,
            static::FETCH_BY_ACL    => null,
            static::FETCH_SORT_FLAT => null
        );

        // filter our result by site if requested
        if ($options[static::FETCH_BY_SITE]) {
            $sites->filterByCallback(
                function($site) use ($options)
                {
                    return $site->getSiteId() == $options[$site::FETCH_BY_SITE];
                }
            );
        }

        // filter by ACL if requested
        $user      = P4Cms_User::hasActive() ? P4Cms_User::fetchActive() : null;
        $acl       = (array) $options[static::FETCH_BY_ACL];
        $resource  = array_shift($acl);
        $privilege = array_shift($acl);
        if ($user && ($resource || $privilege)) {
            $sites->filterByCallback(
                function($site) use ($user, $resource, $privilege)
                {
                    return $user->isAllowed($resource, $privilege, $site->getAcl());
                }
            );
        }

        // re-sort by stream name (ignoring depth) if requested
        if ($options[static::FETCH_SORT_FLAT]) {
            $sites->sortByCallback(
                function($a, $b)
                {
                    return strnatcasecmp($a->getStream()->getName(), $b->getStream()->getName());
                }
            );
        }

        // in order for site getConnection() to work we want to give
        // each site a usable template connection if we can.
        if (!$connection && P4_Connection::hasDefaultConnection()) {
            $connection = P4_Connection::getDefaultConnection();
        }
        $sites->invoke('setTemplateConnection', array($connection));

        return $sites;
    }
static P4Cms_Site::fetchByRequest ( Zend_Controller_Request_Http $  request,
array $  limit = null,
P4_Connection_Interface connection = null 
) [static]

Get the first site/branch that matches the request.

Each site has a list of urls that it will respond to. We begin by finding the first site/branch that matches the request url. If no site matches, we return the first site/branch. If there are no sites, returns false.

Additionally, we support a convention of embedding the name of a specific branch in the request url as the first path component (after the base url). Such as: http://example.com/-dev- This permits multiple site branches without configuring DNS and/or the web server with different URLs for each branch.

If the request url specifies a particular branch, we fetch and return that site branch. If no such branch exists, an exception is thrown.

Parameters:
Zend_Controller_Request_Http$requesta request to examine to determine which site/branch to load.
array | null$limitoptional - a whitelist of site/branch ids that can be safely exposed, all other sites will be ignored - null to allow all.
P4_Connection_Interface$connectionoptional - a specific connection to use.
Returns:
P4Cms_Site|false the first matching site/branch
    {
        // compose url from http host and request uri to find site.
        $requestUrl = Zend_Uri_Http::fromString(
            $request->getScheme()
            . '://'
            . $request->getHttpHost()
            . $request->getRequestUri()
        );

        // loop over urls in site/branches to find a matching prefix.
        $found = false;
        $sites = static::fetchAll(null, $connection);
        foreach ($sites as $site) {

            // skip sites that aren't in the limit whitelist.
            if ($limit && !in_array($site->getId(), $limit)) {
                continue;
            }

            // loop over urls served by this site.
            foreach ($site->getConfig()->getUrls() as $url) {
                // trim whitespace to improve our chances of a match
                $url = trim($url);

                // if url has no scheme - assume scheme of request
                if (!preg_match('#[a-z]+://#i', $url)) {
                    $url = $request->getScheme() . '://' . $url;
                }

                // convert url to Zend_Uri_Http object and skip invalid urls
                try {
                    $url = Zend_Uri_Http::fromString($url);
                } catch (Exception $e) {
                    continue;
                }

                // request scheme (protocol) must match.
                if ($url->getScheme() != $requestUrl->getScheme()) {
                    continue;
                }

                // http host must match.
                if ($url->getHost() != $requestUrl->getHost()) {
                    continue;
                }

                // if path specified - request url must start with path.
                if ($url->getPath() && strpos($requestUrl->getPath(), $url->getPath()) !== 0) {
                    continue;
                }

                // still here? site matches!
                $found = $site;
                break 2;
            }
        }

        // if we failed to find a precise match, assume the first site.
        $found = $found ?: $sites->first();

        // if still no site, or no specific branch requested, all done.
        if (!$found
            || !$request instanceof P4Cms_Controller_Request_Http
            || !$request->getBranchName()
        ) {
            return $found;
        }

        // url specifies a particular branch -- if it's not allowed by
        // the whitelist, simply return what we have found so far.
        $branch = '//' . $found->getSiteId() . '/' . $request->getBranchName();
        if ($limit && !in_array($branch, $limit)) {
            return $found;
        }

        // attempt to fetch the specified branch, if that branch cannot
        // be found, fallback to whatever branch we found previously.
        try {
            return static::fetch($branch, $connection);
        } catch (P4Cms_Model_NotFoundException $e) {
            return $found;
        }
    }
P4Cms_Site::getAcl ( )

Get the ACL for this site.

Returns:
P4Cms_Acl the acl defined for this site.
    {
        // load acl from storage if we haven't already done so.
        if (!$this->_acl instanceof P4Cms_Acl) {
            $adapter = $this->getStorageAdapter();
            try {
                $acl = P4Cms_Acl::fetch(static::ACL_RECORD_ID, $adapter);
            } catch (P4Cms_Model_NotFoundException $e) {

                // setup record storage for acl.
                $record = new P4Cms_Record;
                $record->setId(static::ACL_RECORD_ID)
                       ->setAdapter($adapter);

                // create new, empty, acl.
                $acl = new P4Cms_Acl;
                $acl->setRecord($record);

            }

            // load roles into acl.
            $acl->setRoles(P4Cms_Acl_Role::fetchAll(null, $adapter));

            $this->_acl = $acl;
        }

        return $this->_acl;
    }
P4Cms_Site::getBranchBasename ( )

Get the sub-folder of this site branch in the site depot.

Returns:
string|null the site branch sub-folder.
    {
        return basename($this->getId()) ?: null;
    }
P4Cms_Site::getConfig ( )

Get the configuration object for this site branch.

Returns:
P4Cms_Site_Config the configuration record for this site branch.
Exceptions:
P4Cms_Model_NotFoundExceptionif an invalid revision is given.
    {
        if (!$this->_config) {
            $this->_config = new P4Cms_Site_Config($this);
        }

        return $this->_config;
    }
P4Cms_Site::getConnection ( )

Get the perforce connection for this site.

If no connection has been explicitly set, a new connection will be made using the current template (or the default connection as a template) customized for the site.

Returns:
P4_Connection_Interface a connection to this site's perforce server.
Exceptions:
P4Cms_Site_Exceptionif no explicit, template or default connection is set.
    {
        // check for existing connection.
        if ($this->_connection instanceof P4_Connection_Interface) {
            return $this->_connection;
        }

        if (!$this->_templateConnection && !P4_Connection::hasDefaultConnection()) {
            throw new P4Cms_Site_Exception(
                "Cannot get connection. No explicit or default connection set."
            );
        }

        // if we don't have an existing connection create a
        // custom version of the template or default connection
        $template   = $this->_templateConnection ?: P4_Connection::getDefaultConnection();
        $connection = P4_Connection::factory(
            $template->getPort(),
            $template->getUser(),
            $template->getClient(),
            $template->getPassword(),
            $template->getTicket(),
            get_class($template)
        );

        // attempt to login if we don't already have a ticket.
        if (!$connection->getTicket()) {
            $connection->login();
        }

        // set connection will record this connection for future
        // calls and customize it to use the site client
        $this->setConnection($connection);

        return $connection;
    }
P4Cms_Site::getDataPath ( )

Get the path to this site branch's data folder.

Returns:
string the path to this site branch's data folder.
    {
        return static::getSitesDataPath($this->getSiteId())
            . '/' . $this->getBranchBasename();
    }
P4Cms_Site::getDeferredAdapter ( )

Get a 'deferred' storage adapter.

This can be used anywhere a regular record adapter can be used.

Getting a deferred adapter will not cause the site to create a storage adapter until it is actually used. It will always link to the site's current storage adapter even if it is changed.

Returns:
P4Cms_Record_DeferredAdapter an adapter linked to this site's adapter.
    {
        $site = $this;
        return new P4Cms_Record_DeferredAdapter(
            function() use ($site)
            {
                return $site->getStorageAdapter();
            }
        );
    }
P4Cms_Site::getDeferredConnection ( )

Get a 'deferred' connection.

This can be used anywhere a regular connection can be used.

Getting a deferred connection will not cause the site to create a connection until it is actually used. It will always link to the site's current connection even if it is changed.

Returns:
P4_Connection_Deferred a connection linked to this site's connection.
    {
        $site = $this;
        return new P4_Connection_Deferred(
            function() use ($site)
            {
                return $site->getConnection();
            }
        );
    }
P4Cms_Site::getModulesPath ( )

Get the path to this site's modules.

Returns:
string the path to this site's modules folder.
    {
        return $this->getPackagesPath() . '/modules';
    }
P4Cms_Site::getPackagesPath ( )

Get the path to this site's packages folder (not branch specific)

Returns:
string the path to this site's packages folder.
    {
        return static::getSitesPackagesPath($this->getSiteId());
    }
P4Cms_Site::getParent ( )

Get a reference to this site/branch's parent branch (if it has one).

Returns:
P4Cms_Site|null this branch's parent branch or null if no parent.
    {
        return $this->_parent;
    }
P4Cms_Site::getResourcesPath ( )

Get the path to this site's (writable) public resources.

Returns:
string the path to the site's (writable) public resources.
    {
        return $this->getDataPath() . '/resources';
    }
P4Cms_Site::getSiteId ( )

Get the id of the site that this branch belongs to.

Returns:
string|null the site id for this branch.
    {
        $id = $this->getId();

        if (!$id) {
            return null;
        }

        // try to extract the site id from the branch id.
        if (preg_match("#^//([^/]+)#", $id, $matches)) {
            return $matches[1];
        }

        throw new P4Cms_Site_Exception("Failed to get site id from site branch id.");
    }
static P4Cms_Site::getSitesDataPath ( siteId = null) [static]

Get the path to the sites data folder.

This writable folder contains a sub-folder for each site under which site data is stored.

If a site id is given this method will return the path to that specific site's data folder.

Parameters:
string | null$siteIdoptional - the id of a site to get its specific package path
Returns:
string the path to the sites data folder.
Exceptions:
P4Cms_Site_Exceptionif the sites data path has not been set.
InvalidArgumentExceptionif an malformed site id is given.
    {
        if (!strlen(static::$_sitesDataPath)) {
            throw new P4Cms_Site_Exception("The sites data path has not been set.");
        }

        // if no site id given, simply return top-level sites data path.
        if (!$siteId) {
            return static::$_sitesDataPath;
        }

        $validator = new P4Cms_Validate_SiteId;
        if (!$validator->isValid($siteId)) {
            throw new InvalidArgumentException(
                "Cannot get sites data path. Given site id is malformed."
            );
        }

        // we strip the site id prefix to shorten the path.
        return static::$_sitesDataPath . '/' . substr($siteId, strlen(static::SITE_PREFIX));
    }
static P4Cms_Site::getSitesPackagesPath ( siteId = null) [static]

Get the path to the sites packages folder.

This folder contains a sub-folder for each site (plus an all folder) under which theme and module packages reside for each specific site. The 'all' folder contains themes and modules available to all sites.

If a site id is given this method will return the path to that specific site's packages folder.

Parameters:
string | null$siteIdoptional - the id of a site to get its specific package path
Returns:
string the path to the sites folder.
Exceptions:
P4Cms_Site_Exceptionif the sites path has not been set.
    {
        if (!strlen(static::$_sitesPackagesPath)) {
            throw new P4Cms_Site_Exception("The sites packages path has not been set.");
        }

        // if no site id given, simply return top-level sites packages path.
        if (!$siteId) {
            return static::$_sitesPackagesPath;
        }

        $validator = new P4Cms_Validate_SiteId;
        if (!$validator->isValid($siteId)) {
            throw new InvalidArgumentException(
                "Cannot get sites packages path. Given site id is malformed."
            );
        }

        // we strip the site id prefix to shorten the path.
        return static::$_sitesPackagesPath . '/' . substr($siteId, strlen(static::SITE_PREFIX));
    }
P4Cms_Site::getStorageAdapter ( )

Get the storage adapter to use when reading records from and writing records to this site.

Returns:
P4Cms_Record_Adapter the storage adapter to use for this site branch.
    {
        if ($this->_adapter) {
            return $this->_adapter;
        }

        // no site adapter prepared, make a new one.
        $adapter = new P4Cms_Record_Adapter;

        // the adapter should use this site branch's connection
        // this will ensure it uses the appropriate stream client
        $adapter->setConnection($this->getConnection());

        // when composing record paths, use client-syntax as the base
        // this will ensure that paths resolve through the view.
        $adapter->setBasePath("//" . $this->getConnection()->getClient());

        // set the name of this site's 'umbrella' group in Perforce.
        // this is the parent group for all site roles and gives its
        // members read/write permission to this site's depot files
        // (it is site global, not branch specific).
        $adapter->setProperty(P4Cms_Acl_Role::PARENT_GROUP,  $this->getSiteId());

        // volatile records need to share a non-temp client to see
        // records because they store them as pending files - pick
        // a client name based on the site-branch id.
        $adapter->setProperty(
            P4Cms_Record_Volatile::CLIENT,
            str_replace('/', '-', trim($this->getId(), '/'))
        );

        // only make the adapter once.
        $this->_adapter = $adapter;

        return $adapter;
    }
P4Cms_Site::getStream ( )

Get the stream object for this site branch.

Returns:
P4_Stream|null the stream for this site branch or null if we don't have an id.
    {
        if ($this->_stream || !$this->getId()) {
            return $this->_stream;
        }

        $this->_stream = P4_Stream::fetch($this->getId(), $this->getConnection());

        return $this->_stream;
    }
P4Cms_Site::getThemesPath ( )

Get the path to this site's themes.

Returns:
string the path to this site's themes folder.
    {
        return $this->getPackagesPath() . '/themes';
    }
P4Cms_Site::getWorkspacesPath ( )

Get the path to this site's p4 workspaces.

Returns:
string the path to the site workspaces.
    {
        return $this->getDataPath() . '/workspaces';
    }
static P4Cms_Site::hasActive ( ) [static]

Determine if there is an active (currently loaded) site.

Returns:
boolean true if there is an active site.
    {
        try {
            static::fetchActive();
            return true;
        } catch (P4Cms_Site_Exception $e) {
            return false;
        }
    }
P4Cms_Site::hasConnection ( )

Check if this site/branch already has a perforce connection.

You cannot use getConnection() for this because it will always try to return a connection.

Returns:
bool true if this site/branch already has a connection.
    {
        return (bool) $this->_connection;
    }
P4Cms_Site::load ( )

Load this site into the environment and set it as the active site.

Establish a connection and record adapter for this site and set them as the default. Also, updates package paths to point at site resources.

Returns:
P4Cms_Site provides fluent interface.
    {
        // ensure paths we need to write to exist and are writable.
        P4Cms_FileUtility::createWritablePath($this->getDataPath());
        P4Cms_FileUtility::createWritablePath($this->getWorkspacesPath());

        // set this site's connection as the default connection for the environment.
        P4_Connection::setDefaultConnection($this->getConnection());

        // set this site's storage adapter as the default.
        P4Cms_Record::setDefaultAdapter($this->getStorageAdapter());

        // add the appropriate themes paths for this site.
        P4Cms_Theme::clearPackagesPaths();
        P4Cms_Theme::addPackagesPath(static::getSitesPackagesPath() . '/all/themes');
        P4Cms_Theme::addPackagesPath($this->getThemesPath());

        // add the appropriate modules paths for this site.
        P4Cms_Module::clearPackagesPaths();
        P4Cms_Module::addPackagesPath(static::getSitesPackagesPath() . '/all/modules');
        P4Cms_Module::addPackagesPath($this->getModulesPath());

        // set this instance as the active site.
        static::$_activeSite = $this;

        return $this;
    }
P4Cms_Site::setConnection ( P4_Connection_Interface connection = null)

Warning: this method changes the client of the given connection.

Sets the perforce connection to use for this site and configures it with a new client configured to use this site's stream.

Parameters:
P4_Connection_Interface | null$connectionthe connection to use or null.
Returns:
P4Cms_Site provides fluent interface.
    {
        $this->_connection = $connection
            ? $this->_customizeConnection($connection)
            : null;

        // wipe out the storage adapter anytime the connection changes.
        // this ensures that subsequent calls to getStorageAdapter()
        // will get the same connection that we have been handed here.
        $this->_adapter = null;

        // ensure that the stream always uses the same connection as the site.
        // if null was given a connection might be dynamically generated later.
        // we use a deferred connection to ensure the connection stays in sync.
        if ($this->_stream) {
            $this->_stream->setConnection($this->getDeferredConnection());
        }

        // the acl record also needs to be updated. it has an associated
        // p4 file object that needs to be cleared if the connection changes
        // (otherwise, it will have the old connection and related properties).
        // we use a 'deferred' adapter to delay creating a connection (in case
        // null was given) and to ensure the adapter stays in sync with the site.
        if ($this->_acl) {
            $this->_acl->getRecord()->setAdapter($this->getDeferredAdapter());
        }

        return $this;
    }
P4Cms_Site::setParent ( P4Cms_Site parent = null)

Set a reference to this site/branch's parent branch.

Parameters:
P4Cms_Site | null$parenta reference to this branch's parent branch
Returns:
P4Cms_Site provides fluent interface.
    {
        $this->_parent = $parent;
        return $this;
    }
static P4Cms_Site::setSitesDataPath ( path) [static]

Set the path to the sites data folder (where sites data is stored).

Parameters:
string$paththe path to the sites data folder.
    {
        static::$_sitesDataPath = rtrim($path, '/');
    }
static P4Cms_Site::setSitesPackagesPath ( path) [static]

Set the path to the sites packages folder.

See getSitesPackagesPath for details.

Parameters:
string$paththe path to the sites folder.
    {
        static::$_sitesPackagesPath = rtrim($path, '/');
    }
P4Cms_Site::setTemplateConnection ( P4_Connection_Interface connection = null)

The connection to use as a template when generating a new connection.

If no template is set, the default connection is used.

Parameters:
P4_Connection_Interface | null$connectionthe template connection or null.
Returns:
P4Cms_Site provides fluent interface.
    {
        $this->_templateConnection = $connection;

        return $this;
    }

Member Data Documentation

P4Cms_Site::$_acl = null [protected]
P4Cms_Site::$_activeSite = null [static, protected]
P4Cms_Site::$_adapter = null [protected]
P4Cms_Site::$_config = null [protected]
P4Cms_Site::$_connection = null [protected]
P4Cms_Site::$_idField = 'id' [static, protected]

Reimplemented from P4Cms_Model.

P4Cms_Site::$_parent = null [protected]
P4Cms_Site::$_sitesDataPath = null [static, protected]
P4Cms_Site::$_sitesPackagesPath = null [static, protected]
P4Cms_Site::$_stream = null [protected]
P4Cms_Site::$_templateConnection = null [protected]
const P4Cms_Site::ACL_RECORD_ID = 'config/acl'
const P4Cms_Site::CACHE_KEY = 'sites'
const P4Cms_Site::FETCH_BY_ACL = 'acl'
const P4Cms_Site::FETCH_BY_SITE = 'site'
const P4Cms_Site::SITE_PREFIX = 'chronicle-'

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