Location: PHPKode > scripts > SourceScribe > rstacruz-SourceScribe/include/class.scconfig.php
<?php

class ScConfig
{
    /* Class: ScConfig
     * Wee
     * 
     * [Filed under "API Reference"]
     */
    
    function ScConfig(&$Sc, $variant = NULL)
    {
        /* Function: ScConfig()
         * Constructor.
         */

        $this->Sc = $Sc;
        
        // Find config file
        $config_file = $Sc->findConfigFile();
        if ($config_file === FALSE)
            { ScStatus::error('No config file found. You may generate one using `ss makeconfig`.'); return; }
        
        // Load config file and validate
        $this->cwd = dirname($config_file);
        $this->_config = yaml($config_file);
        if (!is_array($this->_config))
            { ScStatus::error('Configuration file is invalid.'); return; }
            
        if (!is_null($variant))
        {
            $vfile = str_replace('.conf', ".$variant.conf", $config_file);
            if (!is_file($vfile))
                { ScStatus::error("Configuration for variant '$variant' not found."); return; }
            $arr = yaml($vfile);
            if (!is_array($arr))
                { ScStatus::error("Configuration for variant '$variant' is invalid."); return; }
            $this->_config = array_merge($this->_config, $arr);
        }
    }
    
    
    function load()
    {
        /* Function: load()
         * Loads the configuration; called by the constructor.
         * [Private, grouped under "Private functions"]
         */
        
        $Sc =& $this->Sc;
     
        // Verify each required field.
        // It is loaded from $this->_config, which is the YAML file.
        foreach (array('name', 'output') as $required_field) {
            if (!isset($this->_config[$required_field]))
            {
                ScStatus::error(
                    'Configuration is missing the ' .
                    'required field "' . $required_field . '".');
                return;
            }
        }
        
        // Initialize options with defaults
        foreach ($this->defaults as $k => $v)
            { $this->options[$k] = $v; }
        
        // Load configuration variables
        foreach (array('name', 'output', 'src_path', 'exclude', 'tags') as $k)
        {
            if (!isset($this->_config[$k])) { continue; }
            $this->options[$k] = $this->_config[$k];
        }
            
        if (isset($this->_config['tags']))
        {
            if (isset($this->_config['reset_tags']))
                { $this->options['tags'] = array(); }
                
            $this->options['tags'] = array_merge(
                $this->options['tags'],
                (array) $this->_config['tags']);
        }
        
        if (isset($this->_config['exclude_tags']))
        {
            // Add to `tags` the tags that aren't there yet
            // (but are in 'exclude_tags')
            foreach ($this->_config['exclude_tags'] as $tag)
                if (!in_array($tag, $this->options['tags']))
                    $this->options['tags'][] = $tag;
                
            $this->options['exclude_tags'] = (array) $this->_config['exclude_tags'];
        }
        
        if (isset($this->_config['tag_synonyms']))
        {
            $this->options['tag_synonyms'] = array_merge_recursive(
                $this->options['tag_synonyms'],
                (array) $this->_config['tag_synonyms']);
        }
        
        
        if (isset($this->_config['include']))
        {
                
            if (!is_array($this->_config['include']))
                { return ScStatus::error('"include" defined is not an array'); }
            
            $this->options['include'] = array();
            foreach ($this->_config['include'] as $k => $v)
            {
                if (is_numeric($k))
                    { $this->options['include'][$v] = 'default'; }
                else
                    { $this->options['include'][$k] = $v; }
            }
        }    
            
        if (isset($this->_config['block_types']))
        {
            if (isset($this->_config['reset_block_types']))
                { $this->options['block_types'] = array(); }
                
            if (!is_array($this->_config['block_types']))
                { return ScStatus::error('block_types defined is not an array'); }
                
            foreach ($this->_config['block_types'] as $id => $data)
            {
                if (!isset($this->options['block_types'][$id]))
                    { $this->options['block_types'][$id] = $data; continue; }
                
                if (!is_array($data))
                    { return ScStatus::error('block_types has an invalid definition for "' . $id . '"'); }
                    
                foreach ($data as $k => $v)
                {
                    if (in_array($k, array('synonyms','parent_in_id','starts_group_for')))
                    {
                        $this->options['block_types'][$id][$k] =
                            array_merge((array) $this->options['block_types'][$id][$k], (array) $v);
                    }
                    else
                        { $this->options['block_types'][$id][$k] = $v; }
                }
            }
        }
        
        $this->_verify();
        $this->_postVerify();
        $this->_verifyBlockTypes();
        return $this->options;
    }
    
    function _verify()
    {
        /* Function: _verify()
         * Verifies the configuration; called by [[load()]].
         * 
         * Returns:
         *   Returns TRUE on pass, exits otherwise.
         * 
         * [Private, grouped under "Private functions"]
         */
     
        $Sc =& $this->Sc;
        
        // Check output
        if ((!is_array($this->options['output'])) ||
            (count($this->options['output']) == 0))
        {
            return ScStatus::error("You must define at least one output.");
        }
        
        // Check output
        foreach ($this->options['output'] as $id => $output)
        {
            if (!is_array($output))
                { return ScStatus::error("Output #$id is invalid."); }
            if (!isset($output['driver'])) { return ScStatus::error("Output #$id is missing a driver."); }
            if (!isset($output['path']))   { return ScStatus::error("Output #$id ({$output['driver']}) is missing it's output path."); }
        }
        
        // Check if all paths are valid
        $this->options['src_path'] = (array) $this->options['src_path'];
        foreach ($this->options['src_path'] as $k => $path)
        {
            // Try as a relative path
            if (!is_dir($this->options['src_path'][$k]))
                { $this->options['src_path'][$k] = ($this->cwd . DS . $path); } 
            
            // If invalid, die
            if (!is_dir($this->options['src_path'][$k]))
                { return ScStatus::error('Source path is invalid: "' . $path . '"'); }
        }
        
        return TRUE;
    }

    function _postVerify()
    {
        // Add Default output to spit out the .sourcescribe_index file
        $this->options['output']['serial'] = array('driver' => 'serial'); 
    }
    
    function _verifyBlockTypes()
    {
        /* Function: _verifyBlockTypes()
         * Verifies the block types; called by [[load()]].
         * 
         * Returns:
         *   TRUE on success; dies if something is wrong.
         * 
         * [Private, grouped under "Private functions"]
         */
         
        if (!isset($this->options['block_types']))
            { return ScStatus::error("Block types is not valid!"); }
            
        if (!is_array($this->options['block_types']))
            { return ScStatus::error("Block types is not valid!"); }

        $this->options['type_keywords'] = array();

        foreach ($this->options['block_types'] as $id => &$block_type)
        {
            if (!isset($block_type['title_plural']))
                { $block_type['title_plural'] = strtoupper(substr($id,0,1)) . substr($id,1,999)."s"; }
                
            if (!isset($block_type['has_brief']))
                { $block_type['has_brief'] = FALSE; }
                
            if (!isset($block_type['parent_in_id']))
                { $block_type['parent_in_id'] = array(); }
                
            if (!isset($block_type['tags']))
                { $block_type['tags'] = array(); }
                
            if (!isset($block_type['priority']))
                { $block_type['priority'] = NULL; }
                
            if (!isset($block_type['default_order']))
                { $block_type['default_order'] = 0; }
                
            if (!is_array($block_type['tags']))
                { $block_type['tags'] = (array) $block_type['tags']; }
                
            if (!is_array($block_type['parent_in_id']))
                { $block_type['parent_in_id'] = (array) $block_type['parent_in_id']; }
                
            if (!isset($block_type['short']))
                { $block_type['short'] = $id; }
                
            if (!isset($block_type['starts_group_for']))
                { $block_type['starts_group_for'] = array(); }
                
            if (!is_array($block_type['starts_group_for']))
                { $block_type['starts_group_for'] = (array) $block_type['starts_group_for']; }
                
            if (!isset($block_type['synonyms']))
                { $block_type['synonyms'] = array(); }
                
            if (!is_array($block_type['synonyms']))
                { $block_type['synonyms'] = (array) $block_type['synonyms']; }

            $this->options['type_keywords'][$id] = $id;
            foreach ($block_type['synonyms'] as $alias)
                { $this->options['type_keywords'][$alias] = $id; }
        }
        
        return TRUE;
    }
    
    /*
     * Property: $Sc
     * Reference to the [[Sc]] instance.
     */
     
    var $Sc;
    
    /*
     * Property: $_config
     * Raw config as loaded from the YAML file. 
     */
    
    var $_config;
    
    /*
     * Property: $options
     * The actual options.
     */
     
    var $options;
    
    /*
     * Property: $defaults
     * An array containing default options.
     */
     
    var $defaults = array
    (   
        'block_types' => array
        (
            'page' => array(
                'title_plural' => 'Pages',
                'short' => '',
                'has_brief' => FALSE,
                'synonyms' => array('page', 'section'),
                'default_order' => 10,
            ),
            'function' => array(
                'title_plural' => 'Functions',
                'has_brief' => TRUE,
                'parent_in_id' => array('class'),
                'short' => 'fn',
                'title_suffix' => '()',
                'synonyms' => array('constructor', 'ctor', 'destructor', 'dtor', 'method'),
                'tags' => array('static', 'private', 'public', 'protected', 'virtual'),
                'default_order' => 0,
            ),
            'constant' => array(
                'title_plural' => 'Constants',
                'has_brief' => TRUE,
                'short' => 'def',
                'synonyms' => array('define'),
                'default_order' => -5,
            ),
            'var' => array(
                'title_plural' => 'Properties',
                'has_brief' => TRUE,
                'parent_in_id' => array('class'),
                'short' => 'var',
                'synonyms' => array('property'),
                'title_prefix' => '$',
                'tags' => array('read-only', 'private', 'public', 'protected', 'constant'),
                'default_order' => -5,
            ),
            'class' => array(
                'title_plural' => 'Classes',
                'has_brief' => TRUE,
                'starts_group_for' => array('var', 'function'),
                'priority' => 8,
                'title_prefix' => 'Class ',
                // 'block_class' => 'ScClassBlock',
                'tags' => array('interface', 'abstract'),
                'short' => 'class',
                'default_order' => 0,
            ),
            'module' => array(
                'title_plural' => 'Sections',
                'has_brief' => TRUE,
                'priority' => 4,
                'starts_group_for' => array('page', 'class', 'function', 'var'),
                'short' => 'mod',
                'synonyms' => array('file'),
                'default_order' => 20,
            ),
        ),
        
        'include' => array
        (
            '\.inc$'  => 'default',
            '\.rb$'   => 'default',
            '\.py$'   => 'default',
            '\.js$'   => 'default',
            '\.as$'   => 'default',
            '\.c$'    => 'default',
            '\.d$'    => 'default',
            '\.sql$'  => 'default',
            '\.nse$'  => 'default',
            '\.cpp$'  => 'default',
            '\.java$' => 'default',
            '\.m$'    => 'default',
            '\.sh$'   => 'default',
            '\.cs$'   => 'default',
            '\.h$'    => 'default',
            '\.pl$'   => 'default',
            '\.perl$' => 'default',
            '\.php[3-5]?$' => 'default',
            '\.doc.txt$' => 'default'
        ),
        
        'tags' => array('deprecated', 'unimplemented'),
        
        'exclude_tags' => array(),
        
        'tag_synonyms' => array(
            'read-only'  => array('readonly'),
            'deprecated' => array('deprec'),
            'constant'   => array('const'),
        ),
    );
}
Return current item: SourceScribe