blob: 66dab9e94868dc0708a25d5f93511604d0cab088 [file]
<?php
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
class ContainerConfig {
public $default_container = 'default';
public $container_key = 'gadgets.container';
private $config = array();
public function __construct($defaultContainer) {
if (! empty($defaultContainer)) {
$this->loadContainers($defaultContainer);
}
}
private function loadContainers($containers) {
if (! File::exists($containers)) {
throw new Exception("Invalid container path");
}
foreach (glob("$containers/*.js") as $file) {
if (! File::readable($file)) {
throw new Exception("Could not read container config: $file");
}
if (is_dir($file)) {
// support recursive loading of sub directories
$this->loadContainers($file);
} else {
$this->loadFromFile($file);
}
}
}
private function loadFromFile($file) {
$contents = file_get_contents($file);
$contents = self::removeComments($contents);
$config = json_decode($contents, true);
if ($config == $contents) {
throw new Exception("Failed to json_decode the container configuration");
}
if (! isset($config[$this->container_key][0])) {
throw new Exception("No gadgets.container value set for current container");
}
$container = $config[$this->container_key][0];
$this->config[$container] = array();
foreach ($config as $key => $val) {
$this->config[$container][$key] = $val;
}
}
public static function removeComments($str) {
// remove /* */ style comments
$str = preg_replace('@/\\*.*?\\*/@s', '', $str);
// remove // style comments, but keep 'http://' 'https://' and '"//'
// for example: "gadgets.oauthGadgetCallbackTemplate" : "//%host%/gadgets/oauthcallback"
$str = preg_replace('/(?<!http:|https:|")\/\/.*$/m', '', $str);
return $str;
}
public function getConfig($container, $name) {
$config = array();
if (isset($this->config[$container]) && isset($this->config[$container][$name])) {
$config = $this->config[$container][$name];
}
if ($container != $this->default_container && isset($this->config[$this->default_container]) && isset($this->config[$this->default_container][$name])) {
$config = $this->mergeConfig($this->config[$this->default_container][$name], $config);
}
return $config;
}
// Code sniplet borrowed from: http://nl.php.net/manual/en/function.array-merge-recursive.php#81409
// default array merge recursive doesn't overwrite values, but creates multiple elementents for that key,
// which is not what we want here, we want array_merge like behavior
private function mergeConfig() // $array1, $array2, etc
{
$arrays = func_get_args();
$narrays = count($arrays);
for ($i = 0; $i < $narrays; $i ++) {
if (! is_array($arrays[$i])) {
trigger_error('Argument #' . ($i + 1) . ' is not an array - trying to merge array with scalar! Returning null!', E_USER_WARNING);
return null;
}
}
$ret = $arrays[0];
for ($i = 1; $i < $narrays; $i ++) {
foreach ($arrays[$i] as $key => $value) {
if (((string)$key) === ((string)intval($key))) { // integer or string as integer key - append
$ret[] = $value;
} else {
if (is_array($value) && isset($ret[$key])) {
$ret[$key] = $this->mergeConfig($ret[$key], $value);
} else {
$ret[$key] = $value;
}
}
}
}
return $ret;
}
}