/** * Prepares ApiGen configuration. * * @return array * @throws \ApiGen\Config\Exception If there is an error in the configuration */ private function prepareConfiguration() { // Short command line options $cliArguments = $this->arguments; foreach (array('config', 'source', 'destination', 'help') as $option) { if (isset($cliArguments[$option[0]]) && !isset($cliArguments[$option])) { $cliArguments[$option] = $cliArguments[$option[0]]; } unset($cliArguments[$option[0]]); } // Command line options $cliOptions = array(); $originalNames = array(); foreach ($cliArguments as $name => $value) { $newName = preg_replace_callback('~-([a-z])~', function ($matches) { return ucfirst($matches[1]); }, $name); $originalNames[$newName] = $name; $cliOptions[$newName] = $value; } // Check for unknown options $unknownOptions = array_keys(array_diff_key($cliOptions, $this->defaultConfig)); if (!empty($unknownOptions)) { $originalOptions = array_map(function ($option) { return (1 === strlen($option) ? '-' : '--') . $option; }, array_values(array_diff_key($originalNames, $this->defaultConfig))); $message = count($unknownOptions) > 1 ? sprintf('Unknown command line options "%s"', implode('", "', $originalOptions)) : sprintf('Unknown command line option "%s"', $originalOptions[0]); throw new ConfigException($message); } // It is not possible to define plugins via command line if (isset($cliOptions['plugins'])) { throw new ConfigException('Plugins cannot be defined via command line options'); } // Load config file if (empty($cliOptions) && Helper::defaultConfigExists()) { // Default config file present $cliOptions['config'] = Helper::getDefaultConfigPath(); } elseif (!empty($cliOptions['config'])) { // Make the config file name absolute $cliOptions['config'] = Helper::getAbsoluteFilePath($cliOptions['config'], array(getcwd())); if (null === $cliOptions['config']) { // @todo } } if (!empty($cliOptions['config'])) { $fileOptions = $this->loadFromFile($cliOptions['config']); $unknownOptions = array_keys(array_diff_key($fileOptions, $this->defaultConfig)); if (!empty($unknownOptions)) { $message = count($unknownOptions) > 1 ? sprintf('Unknown config file options "%s"', implode('", "', $unknownOptions)) : sprintf('Unknown config file option "%s"', $unknownOptions[0]); throw new ConfigException($message); } } else { $fileOptions = array(); } // Merge configurations $config = array_merge($this->defaultConfig, $fileOptions, $cliOptions); // Compatibility with the old option name "undocumented" if (!isset($config['report']) && isset($config['undocumented'])) { $config['report'] = $config['undocumented']; unset($config['undocumented']); } // Convert option data types foreach ($this->defaultConfig as $option => $valueDefinition) { if (is_array($config[$option]) && !is_array($valueDefinition)) { throw new ConfigException(sprintf('Option "%s" must be set only once', $option)); } if (is_bool($config[$option]) && !is_bool($valueDefinition)) { throw new ConfigException(sprintf('Option "%s" expects value', $option)); } if (!is_bool($config[$option]) && is_bool($valueDefinition)) { // Boolean option $value = strtolower($config[$option]); if ('on' === $value || 'yes' === $value || 'true' === $value || '' === $value) { $value = true; } elseif ('off' === $value || 'no' === $value || 'false' === $value) { $value = false; } $config[$option] = (bool) $value; } elseif (is_array($valueDefinition) && 'plugins' !== $option) { // Array option $config[$option] = array_unique((array) $config[$option]); foreach ($config[$option] as $key => $value) { $value = explode(',', $value); while (!empty($value)) { array_push($config[$option], array_shift($value)); } $config[$option][$key] = array_shift($value); } $config[$option] = array_values(array_filter($config[$option])); } // Check possible values if (!empty($this->possibleOptionsValues[$option])) { $values = $this->possibleOptionsValues[$option]; if (is_array($valueDefinition)) { $config[$option] = array_filter($config[$option], function ($value) use($values) { return in_array($value, $values); }); } elseif (!in_array($config[$option], $values)) { $config[$option] = ''; } } } // Unify character sets $config['charset'] = array_map('strtoupper', $config['charset']); // Process options that specify a filesystem path foreach ($this->pathOptions as $option) { if (is_array($config[$option])) { array_walk($config[$option], function (&$value) { if (file_exists($value)) { $value = realpath($value); } else { $value = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $value); } }); usort($config[$option], 'strcasecmp'); } else { if (file_exists($config[$option])) { $config[$option] = realpath($config[$option]); } else { $config[$option] = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $config[$option]); } } } // Unify prefixes $config['skipDocPrefix'] = array_map(function ($prefix) { return ltrim($prefix, '\\'); }, $config['skipDocPrefix']); usort($config['skipDocPrefix'], 'strcasecmp'); // Base url without slash at the end $config['baseUrl'] = rtrim($config['baseUrl'], '/'); // No progressbar in quiet mode if ($config['quiet']) { $config['progressbar'] = false; } // No update check in debug mode if ($config['debug']) { $config['updateCheck'] = false; } // Help if (empty($cliOptions) && !Helper::defaultConfigExists()) { $config['help'] = true; } // Default template config $config['template'] = array('require' => array(), 'resources' => array(), 'templates' => array('common' => array(), 'optional' => array())); // Merge template configuration $templateConfigAbsolutePath = Helper::getAbsoluteFilePath($config['templateConfig'], array(getcwd(), !empty($cliArguments['config']) ? dirname($cliArguments['config']) : '', Helper::getTemplatesDir())); if (null !== $templateConfigAbsolutePath) { // @todo } $config = array_merge_recursive($config, array('template' => $this->loadFromFile($templateConfigAbsolutePath))); // Plugins foreach ($config['pluginConfig'] as $fileName) { $fileName = Helper::getAbsoluteFilePath($fileName, array(getcwd(), !empty($cliArguments['config']) ? dirname($cliArguments['config']) : '')); // @todo Check if file name is not null foreach ($this->loadFromFile($fileName) as $name => $definition) { if (isset($definition['location'])) { $definition['location'] = Helper::getAbsoluteDirectoryPath($definition['location'], array(dirname($fileName))); } $config['plugins'][$name] = $definition; } } // Set overall DIC parameters $config['application'] = array('application' => array('name' => Environment::getApplicationName(), 'version' => Environment::getApplicationVersion())); return $config; }