Module.php #1

  • //
  • guest/
  • perforce_software/
  • chronicle/
  • main/
  • application/
  • system/
  • Module.php
  • View
  • Commits
  • Open Download .zip Download (13 KB)
<?php
/**
 * Contribute information to the system module and integrate it 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 System_Module extends P4Cms_Module_Integration
{
    /**
     * Perform early integration work (before load).
     */
    public static function init()
    {
        P4Cms_PubSub::subscribe('p4cms.system.info', 'System_Module', 'getGeneralInformation');
        P4Cms_PubSub::subscribe('p4cms.system.info', 'System_Module', 'getPerforceInformation');
        P4Cms_PubSub::subscribe('p4cms.system.info', 'System_Module', 'getWebserverInformation');
        P4Cms_PubSub::subscribe('p4cms.system.info', 'System_Module', 'getPhpInformation');
        P4Cms_PubSub::subscribe('p4cms.system.info', 'System_Module', 'getModuleInformation');
        P4Cms_PubSub::subscribe('p4cms.system.info', 'System_Module', 'getThemeInformation');
    }

    /**
     * Perforce Client Application
     *   p4 or p4php version
     *   p4port
     * Perforce Server (p4 info)
     *   (some client* entries removed)
     * License info
     *   number of licenses & expiration date
     *   number of users
     *
     * @param P4Cms_Model_Iterator $systemInformation The model list to add to.
     */
    public static function getPerforceInformation($systemInformation)
    {
        $sysinfo = new System_Model_Info();
        $sysinfo->setId('support');
        $sysinfo->title = 'Perforce';
        $sysinfo->order = 0;

        // use the default connection.
        $p4 = P4_Connection::getDefaultConnection();

        // client version
        $identity   = $p4->getConnectionIdentity();
        $minVersion = strtolower(Setup_IndexController::MIN_P4_VERSION);
        $ourVersion = strtolower($identity['version']);
        $p4Valid    = version_compare($ourVersion, $minVersion) >= 0;
        $p4Version  = $identity['original'];

        $content['Client Version'] = array(
            'displayClass'  => $p4Valid ? 'good' : 'bad',
            'details'       => $p4Version
        );

        // p4port that client uses
        $p4Port = $p4->getPort();
        $isPortRsh = false;
        if (preg_match('/^rsh:/', $p4Port)) {
            $isPortRsh = true;
            $content['P4PORT'] = $p4Port . ' (local)';
        } else {
            $content['P4PORT'] = $p4Port;
        }

        // capture p4 info output into content
        foreach ($p4->getInfo() as $key => $value) {
            // exclude these entries always
            if (preg_match('/^client(Cwd|Name|Root)/', $key)) {
                continue;
            }
            // exclude these entries if connection is rsh
            if ($isPortRsh && $key === 'serverUptime') {
                continue;
            }

            // "keyName" -> "key Name"
            $newKey = preg_replace('/([a-z])([A-Z])/', '$1 $2', $key);
            $newKey = ucfirst($newKey);

            // tweak serverAddress if rsh
            if ($isPortRsh && $key === 'serverAddress') {
                $content[$newKey] = $value . ' (local)';
            } else {
                // default case
                $content[$newKey] = $value;
            }
        }

        // license info
        $license = $p4->run('license', array('-u'))->getData(0);
        $content['Is Licensed'] = $license['isLicensed'];

        // if a particular count is numeric, display "Used X out of " portion
        // if a soft limit is in play, use that, with explanation

        $formatLimit = function($limit, $softMessage) use ($license)
        {
            $message  = '';
            $license += array($limit . "SoftLimit" => null);
            if (is_numeric($license[$limit . 'Count'])) {
                $message .= 'Used '. $license[$limit . 'Count'] .' out of ';
            }

            $message .= $license[$limit . 'SoftLimit'] ?: $license[$limit . 'Limit'];
            if ($license[$limit . 'SoftLimit']) {
                $message .= ' (' . $license[$limit . 'Limit'] . ' if '
                         .  $softMessage . ' not exceeded)';
            }

            return $message;
        };

        // display user limit
        $content['User Limit']   = $formatLimit('user',   'File Limit is');
        $content['Client Limit'] = $formatLimit('client', 'File Limit is');
        $content['File Limit']   = $formatLimit('file',   'User and Client Limits are');

        $sysinfo->content = $content;

        $systemInformation[] = $sysinfo;
    }

    /**
     * General P4CMS info (version, active site, sites available, etc.)
     *
     * @param P4Cms_Model_Iterator $systemInformation The model list to add to.
     */
    public static function getGeneralInformation($systemInformation)
    {
        $sysinfo = new System_Model_Info();
        $sysinfo->setId('p4cms');
        $sysinfo->title             = 'General';
        $sysinfo->order             = -10;
        $sysinfo->view              = APPLICATION_PATH . '/system/views/scripts/general-info.phtml';
        $supportData                = array();
        $supportData['version']     = P4CMS_VERSION;

        // get active site data usage info
        $report        = '';

        $userCount     = P4Cms_User::count();
        $plural        = $userCount != 1 ? 's' : '';
        $report       .= "$userCount user$plural";

        $roleCount     = P4Cms_Acl_Role::count();
        $plural        = $roleCount != 1 ? 's' : '';
        $report       .= ", $roleCount role$plural";

        $contentCount  = P4Cms_Content::count();
        $plural        = $contentCount != 1 ? 'ies' : 'y';
        $report       .= ", $contentCount content entr$plural";

        $typeCount     = P4Cms_Content_Type::count();
        $plural        = $typeCount != 1 ? 's' : '';
        $report       .= ", $typeCount content type$plural";

        $categoryCount = count(Category_Model_Category::fetchAll());
        $plural        = $categoryCount != 1 ? 'ies' : 'y';
        $report       .= " and $categoryCount categor$plural.";

        $activeSite    = P4Cms_Site::fetchActive();
        $supportData['Active Site'] = array(
            'site'     => $activeSite,
            'details'  => $report
        );

        // produce a list of all sites and branches
        $siteList = P4Cms_Site::fetchAll();
        $siteInfo = array();
        
        foreach ($siteList as $site) {
            $title = $site->getConfig()->getTitle();
            
            if (!array_key_exists($title, $siteInfo)) {
                $siteInfo[$title] = array();
            }
            
            $stream             = $site->getStream()->getName();
            $siteInfo[$title][] = $stream;
        }

        $supportData['All Sites'] = $siteInfo;

        // case sensitive on case-sensitive OSs.
        $directoryHandle = dir(LIBRARY_PATH);
        while (false != ($entry = $directoryHandle->read())) {
            if (strpos($entry, '.') !== 0) {
                $supportData['libraries'][] = $entry;
            }
        }
        $directoryHandle->close();

        $originalMd5    = static::fetchMd5(BASE_PATH . '/index.php.md5', true);
        $currentMd5     = md5_file(BASE_PATH . '/index.php');
        $supportData['index.php'] = array(
            'displayClass'      => $originalMd5 == $currentMd5
                ? 'good'
                : 'bad',
            'status'            => $originalMd5 == $currentMd5
                ? 'Ok'
                : 'Failed',
            'details'           => $currentMd5
        );

        $originalMd5    = static::fetchMd5(APPLICATION_PATH . '/Bootstrap.php.md5', true);
        $currentMd5     = md5_file(APPLICATION_PATH . '/Bootstrap.php');
        $supportData['Bootstrap.php'] = array(
            'displayClass'      => $originalMd5 == $currentMd5
                ? 'good'
                : 'bad',
            'status'            => $originalMd5 == $currentMd5
                ? 'Ok'
                : 'Failed',
            'details'           => $currentMd5
        );

        $sysinfo->content       = $supportData;
        $systemInformation[]    = $sysinfo;
    }

    /**
     * Fetches the contents of a file containing one or more md5 calculations, and the
     * filenames for which they have been calculated.
     * Optionally, strips the filenames from the lines in the file, leaving only the md5
     * calculations.
     *
     * @param   string  $path            The full path to the file.
     * @param   bool    $stripFilenames  Whether or not to strip the filenames.
     * @return  string                   The fetched file contents, or empty string if file cannot be read.
     */
    public static function fetchMd5($path, $stripFilenames = false)
    {
        // pull in the requested file contents
        $md5 = is_readable($path) ? trim(file_get_contents($path)) : '';

        // optionally remove trailing file-names
        if ($stripFilenames) {
            $md5 = preg_replace('/^(\w*).*$/m', '\\1', $md5);
        }

        return $md5;
    }

    /**
     * Web server info
     * Which one being used (Apache, etc.)
     * Version
     * Modules in use (can we detect this?  Not right now.  @todo, add this later)
     * Other settings (perhaps a dump of what we can detect from the web server?)
     *
     * @param P4Cms_Model_Iterator $systemInformation The model list to add to.
     */
    public static function getWebserverInformation($systemInformation)
    {
        $sysinfo = new System_Model_Info();
        $sysinfo->setId('webserver');
        $sysinfo->title             = 'Webserver';
        $sysinfo->order             = 40;
        $supportData                = array();

        // When running unit tests, this key will not exist, throwing an error and failing any
        // related tests.
        $supportData['server']      = (array_key_exists('SERVER_SOFTWARE', $_SERVER))
                                    ? $_SERVER['SERVER_SOFTWARE']
                                    : 'Unavailable';

        $sysinfo->content           = $supportData;
        $systemInformation[]        = $sysinfo;
    }

    /**
     * PHP info
     * Version
     * Modules in use
     * phpinfo() ???
     *
     * @param P4Cms_Model_Iterator $systemInformation The model list to add to.
     */
    public static function getPhpInformation($systemInformation)
    {
        $sysinfo = new System_Model_Info();
        $sysinfo->setId('php');
        $sysinfo->title             = 'PHP';
        $sysinfo->order             = 30;
        $supportData                = array();
        $supportData['version']     = array(
            'displayClass'  => (version_compare(PHP_VERSION, Setup_IndexController::MIN_PHP_VERSION) >= 0)
                ? 'good'
                : 'bad',
            'status'        => PHP_VERSION
        );

        $supportData['modules']     = implode(', ', get_loaded_extensions());

        // collect phpinfo()'s HTML markup and make it available to the report.
        ob_start();
        phpinfo();
        $supportData['phpinfo']     = trim(ob_get_clean());

        $sysinfo->content           = $supportData;
        $sysinfo->view              = APPLICATION_PATH . '/system/views/scripts/php-info.phtml';

        $systemInformation[]        = $sysinfo;
    }

    /**
     * Optional/contributed Modules installed / enabled / disabled / MD5 checksums
     *
     * @param P4Cms_Model_Iterator $systemInformation The model list to add to.
     */
    public static function getModuleInformation($systemInformation)
    {
        $sysinfo = new System_Model_Info();
        $sysinfo->setId('modules');
        $sysinfo->title         = 'Modules';
        $sysinfo->order         = 130;
        $sysinfo->content       = P4Cms_Module::fetchAll()->sortBy(
            array(
                array('core', array(P4_Model_Iterator::SORT_DESCENDING)),
                array('name', array(P4_Model_Iterator::SORT_NATURAL))
            )
        );
        $sysinfo->view          = APPLICATION_PATH . '/system/views/scripts/packages-info.phtml';

        $systemInformation[]    = $sysinfo;
    }

    /**
     * Themes installed / enabled / disabled / MD5 checksums (?)
     *
     * @param P4Cms_Model_Iterator $systemInformation The model list to add to.
     */
    public static function getThemeInformation($systemInformation)
    {
        $sysinfo = new System_Model_Info();
        $sysinfo->setId('themes');
        $sysinfo->title     = 'Themes';
        $sysinfo->order     = 140;
        $sysinfo->view      = APPLICATION_PATH . '/system/views/scripts/packages-info.phtml';
        $sysinfo->content   = P4Cms_Theme::fetchAll();

        $systemInformation[] = $sysinfo;
    }
}
# Change User Description Committed
#1 16170 perforce_software Move Chronicle files to follow new path scheme for branching.
//guest/perforce_software/chronicle/application/system/Module.php
#1 8972 Matt Attaway Initial add of the Chronicle source code