File: src/Config.php

Recommend this page to a friend!
  Classes of Vitaly  >  Queasy PHP Config  >  src/Config.php  >  Download  
File: src/Config.php
Role: Class source
Content type: text/plain
Description: Class source
Class: Queasy PHP Config
Read a configuration from files in several formats
Author: By
Last change:
Date: 5 months ago
Size: 10,998 bytes
 

Contents

Class file image Download
<?php

/*
 * Queasy PHP Framework - Configuration
 *
 * (c) Vitaly Demyanenko <vitaly_demyanenko@yahoo.com>
 *
 * For the full copyright and license information, please view the LICENSE file that was distributed with this source code.
 */

namespace queasy\config;

use queasy\helper\Arrays;
use queasy\helper\Strings;

use queasy\config\loader\ConfigLoaderException;
use queasy\config\loader\LoaderFactory;

/**
 * Main configuration class
 */
class Config extends AbstractConfig
{
    const DEFAULT_PATH = 'queasy-config.php';

    const QUEASY_MARKER = '@queasy:';

    /**
     * Constructor.
     *
     * @param string|array|null $data Array with configuration data, or path to a config file, or null to load config from path
     *      specified by QUEASY_CONFIG_PATH constant if present, or from default path
     *
     * @throws InvalidPathException When configuration load attempt fails, in case of missing or corrupted (doesn't returning an array) file
     */
    public function __construct($data = null, ConfigInterface $parent = null)
    {
        if (null === $data) {
            $data = (defined('QUEASY_CONFIG_PATH'))
                ? QUEASY_CONFIG_PATH
                : static::DEFAULT_PATH;

            if (!is_file($data) && !is_link($data)) {
                $data = array();
            }
        } else if (!is_string($data)
                && !is_array($data)) {
            throw new InvalidPathException(gettype($data));
        }

        parent::__construct($data, $parent);
    }

    /**
     * Get an option value from configuration by option name provided like a object property.
     *
     * @param string $name Config option name
     *
     * @return mixed|null Option value or null if $name is missing in config
     *
     * @throws ConfigLoaderException When configuration load attempt fails, in case of missing or corrupted (doesn't returning an array) file
     */
    public function __get($name)
    {
        return $this->get($name);
    }

    /**
     * Not implemented.
     *
     * @throws ReadOnlyException
     */
    public function __set($name, $value)
    {
        throw new ReadOnlyException(__METHOD__);
    }

    /**
     * Check if $name option is present.
     *
     * @param string $name Config option name
     *
     * @return boolean True if present, false if not
     *
     * @throws ConfigLoaderException When configuration load attempt fails, in case of missing or corrupted (doesn't returning an array) file
     */
    public function __isset($name)
    {
        return $this->offsetExists($name);
    }

    /**
     * Not implemented.
     *
     * @throws ReadOnlyException
     */
    public function __unset($name)
    {
        throw new ReadOnlyException(__METHOD__);
    }

    /**
     * Get an option value from configuration by option name or return default value if provided or return null.
     *
     * @param string $name Config option name
     * @param mixed $default Value to be returned if $name option is missing
     *
     * @return mixed Option value or $default if $name option is missing in config
     *
     * @throws ConfigLoaderException When configuration load attempt fails, in case of missing or corrupted (doesn't returning an array) file
     */
    public function get($name, $default = null)
    {
        if (isset($this[$name])) {
            return $this[$name];
        } elseif (is_array($default)) {
            $className = get_class($this);

            return new $className($default, $this);
        }

        return $default;
    }

    /**
     * Get an option value from configuration by option name.
     *
     * @param string $name Config option name
     *
     * @return mixed Option value
     *
     * @throws ConfigLoaderException When configuration load attempt fails, in case of missing or corrupted (doesn't returning an array) file
     * @throws MissingOptionException When $name option is missing
     */
    public function need($name)
    {
        if (isset($this[$name])) {
            return $this[$name];
        } else {
            throw new MissingOptionException($name);
        }
    }

    /**
     * Move config array pointer to the beginning.
     *
     * @throws ConfigLoaderException When configuration load attempt fails, in case of missing or corrupted (doesn't returning an array) file
     */
    public function rewind()
    {
        $data = &$this->data();

        reset($data);
    }

    /**
     * Get current config array item.
     *
     * @throws ConfigLoaderException When configuration load attempt fails, in case of missing or corrupted (doesn't returning an array) file
     */
    public function current()
    {
        $data = &$this->data();

        return $this->item(current($data));
    }

    /**
     * Move to the next config array item and return it.
     *
     * @throws ConfigLoaderException When configuration load attempt fails, in case of missing or corrupted (doesn't returning an array) file
     */
    public function next()
    {
        $data = &$this->data();

        return $this->item(next($data));
    }

    /**
     * Return current config array key.
     *
     * @throws ConfigLoaderException When configuration load attempt fails, in case of missing or corrupted (doesn't returning an array) file
     */
    public function key()
    {
        $data = &$this->data();

        return key($data);
    }

    /**
     * Validate current config array key.
     *
     * @throws ConfigLoaderException When configuration load attempt fails, in case of missing or corrupted (doesn't returning an array) file
     */
    public function valid()
    {
        $data = &$this->data();

        $key = key($data);

        return ($key !== null)
            && ($key !== false);
    }

    /**
     * Return number of items in a current configuration level.
     *
     * @return int Number of items
     *
     * @throws ConfigLoaderException When configuration load attempt fails, in case of missing or corrupted (doesn't returning an array) file
     */
    public function count()
    {
        return count($this->data());
    }

    /**
     * Check if $name option is present.
     *
     * @param string $name Config option name
     *
     * @return boolean True if present, false if not
     *
     * @throws ConfigLoaderException When configuration load attempt fails, in case of missing or corrupted (doesn't returning an array) file
     */
    public function offsetExists($name)
    {
        $data = &$this->data();

        $parent = $this->parent();

        if (isset($data[$name]) || array_key_exists($name, $data)) {
            return true;
        } elseif (null === $parent) {
            return false;
        } else {
            return $parent->offsetExists($name);
        }
    }

    /**
     * Get an option value from config by option $name or throw ConfigException if option is missing.
     *
     * @param string $name Config option name
     *
     * @return mixed Config option value
     *
     * @throws ConfigLoaderException When configuration load attempt fails, in case of missing or corrupted (doesn't returning an array) file
     */
    public function offsetGet($name)
    {
        if ($this->offsetExists($name)) {
            $data = &$this->data();
            if (isset($data[$name]) || array_key_exists($name, $data)) {
                return $this->item($data[$name]);
            } else {
                $parent = $this->parent();

                return (null === $parent)? null: $parent[$name];
            }
        } else {
            return null;
        }
    }

    /**
     * Not implemented.
     *
     * @throws BadMethodCallException
     */
    public function offsetUnset($name)
    {
        throw new ReadOnlyException(__METHOD__);
    }

    /**
     * Not implemeted.
     *
     * @throws BadMethodCallException
     */
    public function offsetSet($name, $value)
    {
        throw new ReadOnlyException(__METHOD__);
    }

    /**
     * Search for config keys using regular expression.
     *
     * @param string $regex Regular expression
     *
     * @return ConfigInterface Config instance containing key/option pairs found.
     */
    public function regex($regex)
    {
        $data = &$this->data();

        $options = array();
        foreach ($data as $key => $value) {
            if (preg_match($regex, $key)) {
                $options[$key] = $value;
            }
        }

        $className = get_class($this);

        return new $className($options);
    }

    public function merge($array)
    {
        $data = Arrays::merge($this->data(), $array);

        $this->setData($data);
    }

    /**
     * Convert all configuration structure into a regular array.
     *
     * @return array Configuration represented as a regular array
     *
     * @throws ConfigLoaderException When any of included configuration files are missing or corrupted (doesn't return an array)
     */
    public function toArray()
    {
        $result = array();
        foreach ($this->data() as $key => $item) {
            $item = $this->item($item);

            $result[$key] = (is_object($item) && ($item instanceof ConfigInterface))
                ? $item->toArray()
                : $result[$key] = $item;
        }

        return $result;
    }

    /**
     * Check if data is loaded, and try to load it using loader if not.
     *
     * @return &array A reference to array containing config
     *
     * @throws ConfigLoaderException When configuration load attempt fails,
     *          in case of missing or corrupted (doesn't returning an array) file
     */
    protected function &data()
    {
        $data = &parent::data();
        if (is_string($data)) {
            $loader = LoaderFactory::create($data);

            $data = $loader();

            $this->setData($data);
        }

        return $data;
    }

    /**
     * Check if $item is an array and if yes return ConfigInterface instance that encapsulates this array,
     * if $item is instance of ConfigInterface, set $this as his parent, in other way return $item as is.
     * If $item starts with "@queasy:" then run eval() for the rest of the string (to support multi-file configs
     * for formats other than PHP)
     *
     * @param mixed $item An item to check
     *
     * @return ConfigInterface|mixed ConfigInterface instance if $item was an array, or $item as is
     */
    protected function item($item)
    {
        if (is_array($item)) {
            $className = get_class($this);

            $item = new $className($item, $this);
        } elseif ($item instanceof ConfigInterface) {
            $item->setParent($this);
        } elseif (is_string($item) && Strings::startsWith($tritem = trim($item), self::QUEASY_MARKER)) {
            $item = eval('return ' . substr($tritem, strlen(self::QUEASY_MARKER)) . (Strings::endsWith($tritem, ';')? '': ';'));
        }

        return $item;
    }
}

For more information send a message to info at phpclasses dot org.