Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/gallery.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/config
diff options
context:
space:
mode:
authorOlivier Paroz <github@oparoz.com>2015-09-07 23:06:17 +0300
committerOlivier Paroz <github@oparoz.com>2015-09-07 23:06:17 +0300
commitbbdc4d6a5b728bdcff680b7de66b336dc476828f (patch)
treea9ebbd2c06f2e3a96b77321281978b94ebb05cd1 /config
parent812c24e735ede2be70af5d618f5626504e872db7 (diff)
Unit tests for ConfigParser
Diffstat (limited to 'config')
-rw-r--r--config/configexception.php28
-rw-r--r--config/configparser.php215
2 files changed, 243 insertions, 0 deletions
diff --git a/config/configexception.php b/config/configexception.php
new file mode 100644
index 00000000..d421f70f
--- /dev/null
+++ b/config/configexception.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * ownCloud - gallery
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Olivier Paroz <owncloud@interfasys.ch>
+ *
+ * @copyright Olivier Paroz 2015
+ */
+
+namespace OCA\Gallery\Config;
+
+/**
+ * Thrown when the configuration parser cannot parse a file
+ */
+class ConfigException extends \Exception {
+
+ /**
+ * Constructor
+ *
+ * @param string $msg the message contained in the exception
+ */
+ public function __construct($msg) {
+ parent::__construct($msg);
+ }
+}
diff --git a/config/configparser.php b/config/configparser.php
new file mode 100644
index 00000000..2d81210e
--- /dev/null
+++ b/config/configparser.php
@@ -0,0 +1,215 @@
+<?php
+/**
+ * ownCloud - gallery
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Olivier Paroz <owncloud@interfasys.ch>
+ *
+ * @copyright Olivier Paroz 2015
+ */
+
+namespace OCA\Gallery\Config;
+
+use Symfony\Component\Yaml\Parser;
+use Symfony\Component\Yaml\Exception\ParseException;
+
+use OCP\Files\Folder;
+use OCP\Files\File;
+
+/**
+ * Parses configuration files
+ *
+ * @package OCA\Gallery\Config
+ */
+class ConfigParser {
+
+ /**
+ * Returns a parsed global configuration if one was found in the root folder
+ *
+ * @param Folder $folder the current folder
+ * @param string $configName name of the configuration file
+ *
+ * @return null|array
+ */
+ public function getFeaturesList($folder, $configName) {
+ $featuresList = [];
+ $parsedConfig = $this->parseConfig($folder, $configName);
+ $key = 'features';
+ if (array_key_exists($key, $parsedConfig)) {
+ $featuresList = $parsedConfig[$key];
+ }
+
+ return $featuresList;
+ }
+
+ /**
+ * Returns a parsed configuration if one was found in the current folder
+ *
+ * @param Folder $folder the current folder
+ * @param string $configName name of the configuration file
+ * @param array $currentConfig the configuration collected so far
+ * @param array <string,bool> $completionStatus determines if we already have all we need for a
+ * config sub-section
+ * @param int $level the starting level is 0 and we add 1 each time we visit a parent folder
+ *
+ * @return array <null|array,array<string,bool>>
+ * @throws ConfigException
+ */
+ public function getFolderConfig($folder, $configName, $currentConfig, $completionStatus, $level
+ ) {
+ $parsedConfig = $this->parseConfig($folder, $configName);
+ list($config, $completionStatus) =
+ $this->buildAlbumConfig($currentConfig, $parsedConfig, $completionStatus, $level);
+
+ return [$config, $completionStatus];
+ }
+
+ /**
+ * Returns a parsed configuration
+ *
+ * @param Folder $folder the current folder
+ * @param string $configName
+ *
+ * @return array|string[]
+ *
+ * @throws ConfigException
+ */
+ private function parseConfig($folder, $configName) {
+ try {
+ /** @var File $configFile */
+ $configFile = $folder->get($configName);
+ $rawConfig = $configFile->getContent();
+ $saneConfig = $this->bomFixer($rawConfig);
+ $yaml = new Parser();
+ $parsedConfig = $yaml->parse($saneConfig);
+
+ //\OC::$server->getLogger()->debug("rawConfig : {path}", ['path' => $rawConfig]);
+
+ return $parsedConfig;
+ } catch (\Exception $exception) {
+ $errorMessage = "Problem while reading or parsing the configuration file";
+ throw new ConfigException($errorMessage);
+ }
+ }
+
+ /**
+ * Removes the BOM from a file
+ *
+ * http://us.php.net/manual/en/function.pack.php#104151
+ *
+ * @param string $file
+ *
+ * @return string
+ */
+ private function bomFixer($file) {
+ $bom = pack("CCC", 0xef, 0xbb, 0xbf);
+ if (strncmp($file, $bom, 3) === 0) {
+ $file = substr($file, 3);
+ }
+
+ return $file;
+ }
+
+ /**
+ * Returns either the local config or one merged with a config containing sorting information
+ *
+ * @param array $currentConfig the configuration collected so far
+ * @param array $parsedConfig the configuration collected in the current folder
+ * @param array <string,bool> $completionStatus determines if we already have all we need for a
+ * config sub-section
+ * @param int $level the starting level is 0 and we add 1 each time we visit a parent folder
+ *
+ * @return array <null|array,array<string,bool>>
+ */
+ private function buildAlbumConfig($currentConfig, $parsedConfig, $completionStatus, $level) {
+ foreach ($completionStatus as $key => $complete) {
+ if (!$this->isConfigItemComplete($key, $parsedConfig, $complete)) {
+ $parsedConfigItem = $parsedConfig[$key];
+ if ($this->isConfigUsable($parsedConfigItem, $level)) {
+ list($configItem, $itemComplete) =
+ $this->addConfigItem($key, $parsedConfigItem, $level);
+ $currentConfig = array_merge($currentConfig, $configItem);
+ $completionStatus[$key] = $itemComplete;
+ }
+ }
+ }
+
+ return [$currentConfig, $completionStatus];
+ }
+
+ /**
+ * Determines if we already have everything we need for this configuration sub-section
+ *
+ * @param string $key the configuration sub-section identifier
+ * @param array $parsedConfig the configuration for that sub-section
+ * @param bool $complete
+ *
+ * @return bool
+ */
+ private function isConfigItemComplete($key, $parsedConfig, $complete) {
+ return !(!$complete && array_key_exists($key, $parsedConfig));
+ }
+
+ /**
+ * Determines if we can use this configuration sub-section
+ *
+ * It's possible in two cases:
+ * * the configuration was collected from the currently opened folder
+ * * the configuration was collected in a parent folder and is inheritable
+ *
+ * @param array $parsedConfigItem the configuration for a sub-section
+ * @param int $level the starting level is 0 and we add 1 each time we visit a parent folder
+ *
+ * @return bool
+ */
+ private function isConfigUsable($parsedConfigItem, $level) {
+ $inherit = $this->isConfigInheritable($parsedConfigItem);
+
+ return $level === 0 || $inherit;
+ }
+
+ /**
+ * Adds a config sub-section to the global config
+ *
+ * @param string $key the configuration sub-section identifier
+ * @param array $parsedConfigItem the configuration for a sub-section
+ * @param int $level the starting level is 0 and we add 1 each time we visit a parent folder
+ *
+ * @return array<null|array<string,string>,bool>
+ */
+ private function addConfigItem($key, $parsedConfigItem, $level) {
+ if ($key === 'sorting' && !array_key_exists('type', $parsedConfigItem)) {
+
+ return [[], false];
+ } else {
+ $parsedConfigItem['level'] = $level;
+ $configItem = [$key => $parsedConfigItem];
+ $itemComplete = true;
+
+ return [$configItem, $itemComplete];
+ }
+ }
+
+ /**
+ * Determines if we can use a configuration sub-section found in parent folders
+ *
+ * @param array $parsedConfigItem the configuration for a sub-section
+ *
+ * @return bool
+ */
+ private function isConfigInheritable($parsedConfigItem) {
+ $inherit = false;
+ if (array_key_exists('inherit', $parsedConfigItem)) {
+ $inherit = $parsedConfigItem['inherit'];
+ }
+
+ if ($inherit === 'yes') {
+ $inherit = true;
+ }
+
+ return $inherit;
+ }
+
+}