Download plugins/CoreAdminHome/Commands/ConfigGet.php from Leon4gr45/matomo: direct link, hf CLI and curl.
- Browser
- Download file 12.2 kB
-
https://huggingface.co/spaces/Leon4gr45/matomo/resolve/main/plugins/CoreAdminHome/Commands/ConfigGet.php
- Command line
-
hf download hf://spaces/Leon4gr45/matomo/plugins/CoreAdminHome/Commands/ConfigGet.php
-
curl -L -o ConfigGet.php https://huggingface.co/spaces/Leon4gr45/matomo/resolve/main/plugins/CoreAdminHome/Commands/ConfigGet.php
12.2 kB
| /** | |
| * Matomo - free/libre analytics platform | |
| * | |
| * @link https://matomo.org | |
| * @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later | |
| */ | |
| namespace Piwik\Plugins\CoreAdminHome\Commands; | |
| use Piwik\Config; | |
| use Piwik\Plugin\ConsoleCommand; | |
| use Piwik\Settings\FieldConfig; | |
| use Piwik\Settings\Plugin\SystemConfigSetting; | |
| use Spyc; | |
| class ConfigGet extends ConsoleCommand | |
| { | |
| //SystemConfigSetting throws an error if the setting name is empty, so use a fake one that is unlikely to actually exist, which we will check for later. | |
| private const NO_SETTING_NAME_FOUND_PLACEHOLDER = 'ConfigGet_FAKE_SETTING_NAME'; | |
| // Valid output formats. | |
| public const OUTPUT_FORMATS = ['json', 'yaml', 'text']; | |
| // Default output format. | |
| public const OUTPUT_FORMAT_DEFAULT = 'json'; | |
| // Message output if no matching setting is found. | |
| private const MSG_NOTHING_FOUND = 'Nothing found'; | |
| protected function configure() | |
| { | |
| $this->setName('config:get'); | |
| $this->setDescription('Get a config value or section'); | |
| $this->addOptionalArgument( | |
| 'argument', | |
| "A config setting in the format Section.key or Section.array_key[], e.g. 'Database.username' or 'PluginsInstalled'" | |
| ); | |
| $this->addRequiredValueOption('section', 's', 'The section the INI config setting belongs to.'); | |
| $this->addRequiredValueOption('key', 'k', 'The name of the INI config setting.'); | |
| $this->addOptionalValueOption('format', 'f', 'Format the output as ' . json_encode(self::OUTPUT_FORMATS) . '; Default is ' . self::OUTPUT_FORMAT_DEFAULT, self::OUTPUT_FORMAT_DEFAULT); | |
| $this->setHelp("This command can be used to get a INI config setting or a whole section of settings on a Piwik instance. | |
| You can get config values per the two sections below, where: | |
| - [Section] is the name of the section, e.g. database or General. | |
| - [config_setting_name] the name of the setting, e.g. username. | |
| (1) By settings options --section=[Section] and --key=[config_setting_name]. The option --section is required. Examples: | |
| #Return all settings in this section. | |
| $ ./console %command.name% --section=database | |
| #Return only this setting. | |
| $ ./console %command.name% --section=database --key=username | |
| OR | |
| (2) By using a command argument in the format [Section].[config_setting_name]. Examples: | |
| #Return all settings in this section. | |
| $ ./console %command.name% 'database' | |
| #Return all settings in this array; square brackets are optional. | |
| $ ./console %command.name% 'PluginsInstalled.PluginsInstalled' | |
| $ ./console %command.name% 'PluginsInstalled.PluginsInstalled[]' | |
| #Return only this setting. | |
| $ ./console %command.name% 'database.username' | |
| NOTES: | |
| - Section and key names are case-sensitive; so e.g. --section=Database fails but --section=database works. Look in global.ini.php for the proper case. | |
| - If no matching section/setting is found, the string \"" . self::MSG_NOTHING_FOUND . "\" shows. | |
| - Else the output will be shown JSON-encoded. You can use something like https://stedolan.github.io/jq to parse it. | |
| - If you ask for 'PluginsInstalled.PluginsInstalled[\"some_array_item\"]', it will ignore the array key (\"some_array_item\") and you will get back the whole array of values (e.g. all PluginsInstalled[] values). | |
| "); | |
| } | |
| protected function doExecute(): int | |
| { | |
| $input = $this->getInput(); | |
| $output = $this->getOutput(); | |
| // Gather options, then discard ones with an empty value so we do not need to check for empty later. | |
| $options = array_filter([ | |
| 'section' => $input->getOption('section'), | |
| 'key' => $input->getOption('key'), | |
| ]); | |
| // If none specified, set default format. | |
| $format = $input->getOption('format'); | |
| if (empty($format) || !in_array($format, self::OUTPUT_FORMATS, true)) { | |
| $format = self::OUTPUT_FORMAT_DEFAULT; | |
| } | |
| $argument = trim($input->getArgument('argument') ?? ''); | |
| // If there are multiple arguments, just use the last one. | |
| $argument = array_slice(explode(' ', $argument), -1)[0]; | |
| // Sanity check inputs. | |
| switch (true) { | |
| case empty($argument) && empty($options): | |
| throw new \InvalidArgumentException('You must set either an argument or set options --section and optional --key'); | |
| case (!empty($argument) && !empty($options)): | |
| throw new \InvalidArgumentException('You cannot set both an argument (' . serialize($argument) . ') and options (' . serialize($argument) . ')'); | |
| case empty($argument) && (!isset($options['section']) || empty($options['section'])): | |
| throw new \InvalidArgumentException('When using options, the --section value must be set'); | |
| case (!empty($argument)): | |
| $settingStr = $argument; | |
| break; | |
| case (!empty($options)): | |
| $settingStr = implode('.', $options); | |
| break; | |
| default: | |
| // We should not get here, but just in case. | |
| throw new \Exception('Some unexpected error occurred in ' . __FUNCTION__ . ' at line ' . __LINE__); | |
| } | |
| // Parse the $settingStr into a SystemConfigSetting object. | |
| $setting = self::parseSettingStr($settingStr); | |
| $result = $this->getConfigValue(Config::getInstance(), $setting); | |
| if (empty($result)) { | |
| $output->writeln(self::wrapInTag('comment', self::MSG_NOTHING_FOUND)); | |
| } else { | |
| $output->writeln($this->formatVariableForOutput($setting, $result, $format)); | |
| } | |
| return self::SUCCESS; | |
| } | |
| /** | |
| * Get a config section or section.value. | |
| * | |
| * @param Config $config A Matomo Config instance. | |
| * @param SystemConfigSetting $setting A setting object describing what to get e.g. from self::make(). | |
| * @return Mixed The config section or value. | |
| */ | |
| private function getConfigValue(Config $config, SystemConfigSetting $setting) | |
| { | |
| // This should have been caught in the calling function, so assume a bad implementation and throw an error. | |
| if (empty($sectionName = $setting->getConfigSectionName())) { | |
| throw new \InvalidArgumentException('A section name must be specified'); | |
| } | |
| if (empty($section = $config->__get($sectionName))) { | |
| return null; | |
| } | |
| // Convert array to object since it is slightly cleaner/easier to work with. | |
| $section = (object) $section; | |
| // Look for the specific setting. | |
| $settingName = $setting->getName(); | |
| // Return the whole setting section if requested. | |
| // The name=FAKE_SETTING_NAME is a placeholder for when no setting is specified. | |
| if (empty($settingName) || $settingName === self::NO_SETTING_NAME_FOUND_PLACEHOLDER) { | |
| $sectionContents = $section; | |
| return (array) $sectionContents; | |
| } | |
| switch (true) { | |
| case (!isset($section->$settingName)): | |
| $settingValue = null; | |
| break; | |
| case is_array($settingValue = $section->$settingName): | |
| break; | |
| default: | |
| $settingValue = $setting->getValue(); | |
| } | |
| return $settingValue; | |
| } | |
| /** | |
| * Build a SystemConfigSetting object from a string. | |
| * | |
| * @param string $settingStr Config setting string to parse. | |
| * @return SystemConfigSetting A SystemConfigSetting object. | |
| */ | |
| public static function parseSettingStr(string $settingStr): SystemConfigSetting | |
| { | |
| $matches = []; | |
| if (!preg_match('/^([a-zA-Z0-9_]+)(?:\.([a-zA-Z0-9_]+))?(\[\])?/', $settingStr, $matches) || empty($matches[1])) { | |
| throw new \InvalidArgumentException("Invalid input string='{$settingStr}' =expected section.name or section.name[]"); | |
| } | |
| return new SystemConfigSetting( | |
| // Setting name. SystemConfigSetting throws an error if the setting name is empty, so use placeholder that flags that no setting was specified. | |
| $matches[2] ?? self::NO_SETTING_NAME_FOUND_PLACEHOLDER, | |
| // Default value. | |
| '', | |
| // Type. | |
| FieldConfig::TYPE_STRING, | |
| // Plugin name. | |
| 'core', | |
| // Section name. | |
| $matches[1] | |
| ); | |
| } | |
| /** | |
| * Format the config setting to the specified output format. | |
| * | |
| * @param SystemConfigSetting $setting The found SystemConfigSetting. | |
| * @param mixed $var The config setting -- either scalar or an array of settings. | |
| * @param string $format The output format: One of self::OUTPUT_FORMAT_DEFAULT. | |
| * @return string The formatted output. | |
| */ | |
| private function formatVariableForOutput(SystemConfigSetting $setting, $var, string $format = self::OUTPUT_FORMAT_DEFAULT): string | |
| { | |
| switch ($format) { | |
| case 'json': | |
| return $this->toJson($var); | |
| case 'yaml': | |
| return $this->toYaml($var); | |
| case 'text': | |
| return $this->toText($setting, $var); | |
| default: | |
| throw new \InvalidArgumentException('Unsupported output format'); | |
| } | |
| } | |
| /** | |
| * Convert $var to a YAML string. | |
| * Throws an error on invalid types (a PHP resource or object). | |
| * | |
| * @param mixed $var The variable to convert. | |
| * @return string The Yaml-formatted string. | |
| */ | |
| private function toYaml($var): string | |
| { | |
| // Remove leading dash and spaces Spyc adds so we just output the bare value. | |
| return trim(ltrim(Spyc::YAMLDump($var, 2, 0, true), '-')); | |
| } | |
| /** | |
| * Convert $var to a JSON string. | |
| * Throws an error on json_encode failure. | |
| * | |
| * @param mixed $var The variable to convert. | |
| * @return string The JSON-formatted string. | |
| */ | |
| private function toJson($var): string | |
| { | |
| $result = json_encode($var, JSON_UNESCAPED_SLASHES); | |
| if ($result === false) { | |
| throw new \Exception('Failed to json_encode'); | |
| } | |
| return $result; | |
| } | |
| /** | |
| * Convert $var to Symfony-colorized CLI output text. | |
| * | |
| * @param SystemConfigSetting $setting The found SystemConfigSetting. | |
| * @param mixed $var The thing to format: Config scalar values lead to $var being scalar; Config array values lead to $var being an array of scalars; Config sections lead to $var being a mixed array of both scalar and array values. | |
| * @return string The formatted result. | |
| */ | |
| private function toText(SystemConfigSetting $setting, $var): string | |
| { | |
| // Strip off the NO_SETTING_NAME_FOUND_PLACEHOLDER. | |
| $settingName = $setting->getName() === self::NO_SETTING_NAME_FOUND_PLACEHOLDER ? '' : $setting->getName(); | |
| $sectionAndSettingName = implode('.', array_filter([$setting->getConfigSectionName(), $settingName])); | |
| $output = ''; | |
| switch (true) { | |
| case is_array($var): | |
| $output .= $this->wrapInTag('info', ($settingName ? $sectionAndSettingName : "[{$sectionAndSettingName}]") . PHP_EOL); | |
| $output .= $this->wrapInTag('info', '--' . PHP_EOL); | |
| foreach ($var as $thisSettingName => &$val) { | |
| if (is_array($val)) { | |
| foreach ($val as &$arrayVal) { | |
| $output .= $this->wrapInTag('info', "{$thisSettingName}[] = " . $this->wrapInTag('comment', $arrayVal)) . PHP_EOL; | |
| } | |
| } else { | |
| $output .= $this->wrapInTag('info', $thisSettingName . ' = ' . $this->wrapInTag('comment', $val)) . PHP_EOL; | |
| } | |
| } | |
| $output .= $this->wrapInTag('info', '--' . PHP_EOL); | |
| break; | |
| case is_scalar($var): | |
| $output .= $this->wrapInTag('info', $sectionAndSettingName . ' = ' . $this->wrapInTag('comment', $var)); | |
| break; | |
| default: | |
| throw new \InvalidArgumentException('Cannot output unknown type'); | |
| } | |
| return $output; | |
| } | |
| } | |