Overview

Namespaces

  • Charcoal
    • Config

Classes

  • Charcoal\Config\AbstractConfig
  • Charcoal\Config\AbstractEntity
  • Charcoal\Config\GenericConfig

Interfaces

  • Charcoal\Config\ConfigInterface
  • Charcoal\Config\ConfigurableInterface
  • Charcoal\Config\DelegatesAwareInterface
  • Charcoal\Config\EntityInterface
  • Charcoal\Config\FileAwareInterface
  • Charcoal\Config\SeparatorAwareInterface

Traits

  • Charcoal\Config\ConfigurableTrait
  • Charcoal\Config\DelegatesAwareTrait
  • Charcoal\Config\FileAwareTrait
  • Charcoal\Config\SeparatorAwareTrait
  • Overview
  • Namespace
  • Class
  1: <?php
  2: 
  3: namespace Charcoal\Config;
  4: 
  5: use Traversable;
  6: use Throwable;
  7: use Exception;
  8: use LogicException;
  9: use InvalidArgumentException;
 10: use UnexpectedValueException;
 11: 
 12: // From 'symfony/yaml'
 13: use Symfony\Component\Yaml\Parser as YamlParser;
 14: 
 15: /**
 16:  * Provides an object with the ability to read file contents.
 17:  *
 18:  * Supported file formats: INI, JSON, PHP, YAML*.
 19:  *
 20:  * Note: YAML requires the {@link https://packagist.org/packages/symfony/yaml Symfony YAML component}.
 21:  *
 22:  * This is a full implementation of {@see FileAwareInterface}.
 23:  */
 24: trait FileAwareTrait
 25: {
 26:     /**
 27:      * Loads a configuration file.
 28:      *
 29:      * @param  string $path A path to a supported file.
 30:      * @throws InvalidArgumentException If the path is invalid.
 31:      * @return array An array on success.
 32:      */
 33:     public function loadFile($path)
 34:     {
 35:         if (!is_string($path)) {
 36:             throw new InvalidArgumentException(
 37:                 'File must be a string'
 38:             );
 39:         }
 40: 
 41:         if (!file_exists($path)) {
 42:             throw new InvalidArgumentException(
 43:                 sprintf('File "%s" does not exist', $path)
 44:             );
 45:         }
 46: 
 47:         $ext = pathinfo($path, PATHINFO_EXTENSION);
 48:         switch ($ext) {
 49:             case 'php':
 50:                 return $this->loadPhpFile($path);
 51: 
 52:             case 'json':
 53:                 return $this->loadJsonFile($path);
 54: 
 55:             case 'ini':
 56:                 return $this->loadIniFile($path);
 57: 
 58:             case 'yml':
 59:             case 'yaml':
 60:                 return $this->loadYamlFile($path);
 61:         }
 62: 
 63:         $validConfigExts = [ 'ini', 'json', 'php', 'yml' ];
 64:         throw new InvalidArgumentException(sprintf(
 65:             'Unsupported file format for "%s"; must be one of "%s"',
 66:             $path,
 67:             implode('", "', $validConfigExts)
 68:         ));
 69:     }
 70: 
 71:     /**
 72:      * Load an INI file as an array.
 73:      *
 74:      * @param  string $path A path to an INI file.
 75:      * @throws UnexpectedValueException If the file can not correctly be parsed into an array.
 76:      * @return array An array on success.
 77:      */
 78:     private function loadIniFile($path)
 79:     {
 80:         $data = parse_ini_file($path, true);
 81:         if ($data === false) {
 82:             throw new UnexpectedValueException(
 83:                 sprintf('INI file "%s" is empty or invalid', $path)
 84:             );
 85:         }
 86: 
 87:         return $data;
 88:     }
 89: 
 90:     /**
 91:      * Load a JSON file as an array.
 92:      *
 93:      * @param  string $path A path to a JSON file.
 94:      * @throws UnexpectedValueException If the file can not correctly be parsed into an array.
 95:      * @return array An array on success.
 96:      *     If the file is parsed as any other type, an empty array is returned.
 97:      */
 98:     private function loadJsonFile($path)
 99:     {
100:         $data = null;
101:         $json = file_get_contents($path);
102:         if ($json) {
103:             $data = json_decode($json, true);
104:             if (json_last_error() !== JSON_ERROR_NONE) {
105:                 $error = json_last_error_msg() ?: 'Unknown error';
106:                 throw new UnexpectedValueException(
107:                     sprintf('JSON file "%s" could not be parsed: %s', $path, $error)
108:                 );
109:             }
110:         }
111: 
112:         if (!is_array($data)) {
113:             return [];
114:         }
115: 
116:         return $data;
117:     }
118: 
119:     /**
120:      * Load a PHP file, maybe as an array.
121:      *
122:      * Note:
123:      * - The context of $this is bound to the current object.
124:      * - Data may be any value; the {@see self::addFile()} method will ignore
125:      *   anything that isn't an (associative) array.
126:      *
127:      * @param  string $path A path to a PHP file.
128:      * @throws UnexpectedValueException If the file can not correctly be parsed.
129:      * @return array|Traversable An array or iterable object on success.
130:      *     If the file is parsed as any other type, an empty array is returned.
131:      */
132:     private function loadPhpFile($path)
133:     {
134:         try {
135:             $data = include $path;
136:         } catch (Exception $e) {
137:             $message = sprintf('PHP file "%s" could not be parsed: %s', $path, $e->getMessage());
138:             throw new UnexpectedValueException($message, 0, $e);
139:         } catch (Throwable $e) {
140:             $message = sprintf('PHP file "%s" could not be parsed: %s', $path, $e->getMessage());
141:             throw new UnexpectedValueException($message, 0, $e);
142:         }
143: 
144:         if (is_array($data) || ($data instanceof Traversable)) {
145:             return $data;
146:         }
147: 
148:         return [];
149:     }
150: 
151:     /**
152:      * Load a YAML file as an array.
153:      *
154:      * @param  string $path A path to a YAML/YML file.
155:      * @throws LogicException If a YAML parser is unavailable.
156:      * @throws UnexpectedValueException If the file can not correctly be parsed into an array.
157:      * @return array An array on success.
158:      *     If the file is parsed as any other type, an empty array is returned.
159:      */
160:     private function loadYamlFile($path)
161:     {
162:         if (!class_exists('Symfony\Component\Yaml\Parser')) {
163:             throw new LogicException('YAML format requires the Symfony YAML component');
164:         }
165: 
166:         try {
167:             $yaml = new YamlParser();
168:             $data = $yaml->parseFile($path);
169:         } catch (Exception $e) {
170:             $message = sprintf('YAML file "%s" could not be parsed: %s', $path, $e->getMessage());
171:             throw new UnexpectedValueException($message, 0, $e);
172:         }
173: 
174:         if (!is_array($data)) {
175:             return [];
176:         }
177: 
178:         return $data;
179:     }
180: }
181: 
API documentation generated by ApiGen