public static function traverseConfig($original_file_path, $data, $values, $imported_config, &$shared_config = array(), $basePath = '') { $imported_config = array($original_file_path); try { $data = Utils::traverseArray($data, function ($key, $value, $level = 0, $base_path = '') use($values, $original_file_path, $data, $imported_config, &$shared_config) { $value = is_string($value) ? trim($value) : $value; $key = is_string($key) ? trim($key) : $key; if ($key === '@extend') { if ($level !== 0) { throw new SubLevelExtendConfigException(sprintf('You can only use @extend once in the first level of your config: %s', $original_file_path)); } // construct path and resolve properly if relative if (substr($value, 0, 1) !== '/') { $file_path = dirname($original_file_path) . '/' . $value; } else { $file_path = $value; } // load referenced config $extend_data = Config::realLoad($file_path, $values, $imported_config); // merge current data $extended_data = Utils::arrayExtend($extend_data, $data); // remove @extend ... we don't want an infinite loop if (isset($extended_data['@extend'])) { unset($extended_data['@extend']); } // traverse new extended array $extended_data = Config::traverseConfig($original_file_path, $extended_data, $values, $imported_config, $shared_config, $base_path); // throw exception throw new ExtendedConfigException('Config has been extended and traversed', $extended_data); } if (preg_match('/^@import\\s+(.+)$/', $value, $matches)) { if (substr($matches[1], 0, 1) !== '/') { $file_path = dirname($original_file_path) . '/' . $matches[1]; } else { $file_path = $matches[1]; } $newBasePath = ($base_path ? $base_path . '.' : '') . $key; return Config::realLoad($file_path, $values, $imported_config, $shared_config, array(), $newBasePath); } if (preg_match('/^@clone\\s+(.+)$/', $value, $matches)) { //@TODO: figure out why a sinlge clone value is called mutiple times //var_dump($matches[0]); $shared_config[($base_path ? "{$base_path}." : '') . $key] = $matches[1]; } return $value; }, 0, $basePath); } catch (ExtendedConfigException $e) { return $e->getConfig(); } return $data; }