Ampache PHP Cross Reference Groupware Applications

Source: /modules/Guzzle/Service/AbstractConfigLoader.php - 177 lines - 6001 bytes - Summary - Text - Print

Description: Abstract config loader

   1  <?php
   2  
   3  namespace Guzzle\Service;
   4  
   5  use Guzzle\Common\Exception\InvalidArgumentException;
   6  use Guzzle\Common\Exception\RuntimeException;
   7  
   8  /**
   9   * Abstract config loader
  10   */
  11  abstract class AbstractConfigLoader implements ConfigLoaderInterface
  12  {
  13      /** @var array Array of aliases for actual filenames */
  14      protected $aliases = array();
  15  
  16      /** @var array Hash of previously loaded filenames */
  17      protected $loadedFiles = array();
  18  
  19      /** @var array JSON error code mappings */
  20      protected static $jsonErrors = array(
  21          JSON_ERROR_NONE => 'JSON_ERROR_NONE - No errors',
  22          JSON_ERROR_DEPTH => 'JSON_ERROR_DEPTH - Maximum stack depth exceeded',
  23          JSON_ERROR_STATE_MISMATCH => 'JSON_ERROR_STATE_MISMATCH - Underflow or the modes mismatch',
  24          JSON_ERROR_CTRL_CHAR => 'JSON_ERROR_CTRL_CHAR - Unexpected control character found',
  25          JSON_ERROR_SYNTAX => 'JSON_ERROR_SYNTAX - Syntax error, malformed JSON',
  26          JSON_ERROR_UTF8 => 'JSON_ERROR_UTF8 - Malformed UTF-8 characters, possibly incorrectly encoded'
  27      );
  28  
  29      public function load($config, array $options = array())
  30      {
  31          // Reset the array of loaded files because this is a new config
  32          $this->loadedFiles = array();
  33  
  34          if (is_string($config)) {
  35              $config = $this->loadFile($config);
  36          } elseif (!is_array($config)) {
  37              throw new InvalidArgumentException('Unknown type passed to configuration loader: ' . gettype($config));
  38          } else {
  39              $this->mergeIncludes($config);
  40          }
  41  
  42          return $this->build($config, $options);
  43      }
  44  
  45      /**
  46       * Add an include alias to the loader
  47       *
  48       * @param string $filename Filename to alias (e.g. _foo)
  49       * @param string $alias    Actual file to use (e.g. /path/to/foo.json)
  50       *
  51       * @return self
  52       */
  53      public function addAlias($filename, $alias)
  54      {
  55          $this->aliases[$filename] = $alias;
  56  
  57          return $this;
  58      }
  59  
  60      /**
  61       * Remove an alias from the loader
  62       *
  63       * @param string $alias Alias to remove
  64       *
  65       * @return self
  66       */
  67      public function removeAlias($alias)
  68      {
  69          unset($this->aliases[$alias]);
  70  
  71          return $this;
  72      }
  73  
  74      /**
  75       * Perform the parsing of a config file and create the end result
  76       *
  77       * @param array $config  Configuration data
  78       * @param array $options Options to use when building
  79       *
  80       * @return mixed
  81       */
  82      protected abstract function build($config, array $options);
  83  
  84      /**
  85       * Load a configuration file (can load JSON or PHP files that return an array when included)
  86       *
  87       * @param string $filename File to load
  88       *
  89       * @return array
  90       * @throws InvalidArgumentException
  91       * @throws RuntimeException when the JSON cannot be parsed
  92       */
  93      protected function loadFile($filename)
  94      {
  95          if (isset($this->aliases[$filename])) {
  96              $filename = $this->aliases[$filename];
  97          }
  98  
  99          switch (pathinfo($filename, PATHINFO_EXTENSION)) {
 100              case 'js':
 101              case 'json':
 102                  $level = error_reporting(0);
 103                  $json = file_get_contents($filename);
 104                  error_reporting($level);
 105  
 106                  if ($json === false) {
 107                      $err = error_get_last();
 108                      throw new InvalidArgumentException("Unable to open {$filename}: " . $err['message']);
 109                  }
 110  
 111                  $config = json_decode($json, true);
 112                  // Throw an exception if there was an error loading the file
 113                  if ($error = json_last_error()) {
 114                      $message = isset(self::$jsonErrors[$error]) ? self::$jsonErrors[$error] : 'Unknown error';
 115                      throw new RuntimeException("Error loading JSON data from {$filename}: ({$error}) - {$message}");
 116                  }
 117                  break;
 118              case 'php':
 119                  if (!is_readable($filename)) {
 120                      throw new InvalidArgumentException("Unable to open {$filename} for reading");
 121                  }
 122                  $config = require $filename;
 123                  if (!is_array($config)) {
 124                      throw new InvalidArgumentException('PHP files must return an array of configuration data');
 125                  }
 126                  break;
 127              default:
 128                  throw new InvalidArgumentException('Unknown file extension: ' . $filename);
 129          }
 130  
 131          // Keep track of this file being loaded to prevent infinite recursion
 132          $this->loadedFiles[$filename] = true;
 133  
 134          // Merge include files into the configuration array
 135          $this->mergeIncludes($config, dirname($filename));
 136  
 137          return $config;
 138      }
 139  
 140      /**
 141       * Merges in all include files
 142       *
 143       * @param array  $config   Config data that contains includes
 144       * @param string $basePath Base path to use when a relative path is encountered
 145       *
 146       * @return array Returns the merged and included data
 147       */
 148      protected function mergeIncludes(&$config, $basePath = null)
 149      {
 150          if (!empty($config['includes'])) {
 151              foreach ($config['includes'] as &$path) {
 152                  // Account for relative paths
 153                  if ($path[0] != DIRECTORY_SEPARATOR && !isset($this->aliases[$path]) && $basePath) {
 154                      $path = "{$basePath}/{$path}";
 155                  }
 156                  // Don't load the same files more than once
 157                  if (!isset($this->loadedFiles[$path])) {
 158                      $this->loadedFiles[$path] = true;
 159                      $config = $this->mergeData($this->loadFile($path), $config);
 160                  }
 161              }
 162          }
 163      }
 164  
 165      /**
 166       * Default implementation for merging two arrays of data (uses array_merge_recursive)
 167       *
 168       * @param array $a Original data
 169       * @param array $b Data to merge into the original and overwrite existing values
 170       *
 171       * @return array
 172       */
 173      protected function mergeData(array $a, array $b)
 174      {
 175          return array_merge_recursive($a, $b);
 176      }
 177  }

title

Description

title

Description

title

Description

title

title

Body