示例#1
0
 /**
  * Loads configuration from file and process it.
  * @return DI\Container
  */
 public function loadConfig($file, $section = NULL)
 {
     if ($file === NULL) {
         $file = $this->defaultConfigFile;
     }
     $container = $this->container;
     $file = $container->expand($file);
     if (!is_file($file)) {
         $file = preg_replace('#\\.neon$#', '.ini', $file);
         // back compatibility
     }
     if ($section === NULL) {
         if (PHP_SAPI === 'cli') {
             $section = Environment::CONSOLE;
         } else {
             $section = $container->params['productionMode'] ? Environment::PRODUCTION : Environment::DEVELOPMENT;
         }
     }
     $cache = new Cache($container->templateCacheStorage, 'Nette.Configurator');
     $cacheKey = array((array) $container->params, $file, $section);
     $cached = $cache->load($cacheKey);
     if ($cached) {
         require $cached['file'];
         fclose($cached['handle']);
         return $this->container;
     }
     $config = Nette\Config\Config::fromFile($file, $section);
     $code = "<?php\n// source file {$file}\n\n";
     // back compatibility with singular names
     foreach (array('service', 'variable') as $item) {
         if (isset($config[$item])) {
             trigger_error(basename($file) . ": Section '{$item}' is deprecated; use plural form '{$item}s' instead.", E_USER_WARNING);
             $config[$item . 's'] = $config[$item];
             unset($config[$item]);
         }
     }
     // process services
     if (isset($config['services'])) {
         foreach ($config['services'] as $key => &$def) {
             if (preg_match('#^Nette\\\\.*\\\\I?([a-zA-Z]+)$#', strtr($key, '-', '\\'), $m)) {
                 // back compatibility
                 $m[1][0] = strtolower($m[1][0]);
                 trigger_error(basename($file) . ": service name '{$key}' has been renamed to '{$m['1']}'", E_USER_WARNING);
                 $key = $m[1];
             }
             if (is_array($def)) {
                 if (method_exists(get_called_class(), "createService{$key}") && !isset($def['factory']) && !isset($def['class'])) {
                     $def['factory'] = array(get_called_class(), "createService{$key}");
                 }
                 if (isset($def['option'])) {
                     $def['arguments'][] = $def['option'];
                 }
                 if (!empty($def['run'])) {
                     $def['tags'] = array('run');
                 }
             }
         }
         $builder = new DI\ContainerBuilder();
         $code .= $builder->generateCode($config['services']);
         unset($config['services']);
     }
     // consolidate variables
     if (!isset($config['variables'])) {
         $config['variables'] = array();
     }
     foreach ($config as $key => $value) {
         if (!in_array($key, array('variables', 'services', 'php', 'const', 'mode'))) {
             $config['variables'][$key] = $value;
         }
     }
     // pre-expand variables at compile-time
     $variables = $config['variables'];
     array_walk_recursive($config, function (&$val) use($variables) {
         $val = Configurator::preExpand($val, $variables);
     });
     // add variables
     foreach ($config['variables'] as $key => $value) {
         $code .= $this->generateCode('$container->params[?] = ?', $key, $value);
     }
     // PHP settings
     if (isset($config['php'])) {
         foreach ($config['php'] as $key => $value) {
             if (is_array($value)) {
                 // back compatibility - flatten INI dots
                 foreach ($value as $k => $v) {
                     $code .= $this->configurePhp("{$key}.{$k}", $v);
                 }
             } else {
                 $code .= $this->configurePhp($key, $value);
             }
         }
     }
     // define constants
     if (isset($config['const'])) {
         foreach ($config['const'] as $key => $value) {
             $code .= $this->generateCode('define', $key, $value);
         }
     }
     // set modes - back compatibility
     if (isset($config['mode'])) {
         foreach ($config['mode'] as $mode => $state) {
             trigger_error(basename($file) . ": Section 'mode' is deprecated; use '{$mode}Mode' in section 'variables' instead.", E_USER_WARNING);
             $code .= $this->generateCode('$container->params[?] = ?', $mode . 'Mode', (bool) $state);
         }
     }
     // pre-loading
     $code .= self::preloadEnvironment($container);
     // auto-start services
     $code .= 'foreach ($container->getServiceNamesByTag("run") as $name => $foo) { $container->getService($name); }' . "\n";
     $cache->save($cacheKey, $code, array(Cache::FILES => $file));
     Nette\Utils\LimitedScope::evaluate($code, array('container' => $container));
     return $this->container;
 }
示例#2
0
	/**
	 * Loads configuration from file and process it.
	 * @return DI\Container
	 */
	public function loadConfig($file, $section = NULL)
	{
		if ($file === NULL) {
			$file = $this->defaultConfigFile;
		}
		$container = $this->container;
		$file = $container->expand($file);
		if (!is_file($file)) {
			$file = preg_replace('#\.neon$#', '.ini', $file); // back compatibility
		}
		if ($section === NULL) {
			if (PHP_SAPI === 'cli') {
				$section = Environment::CONSOLE;
			} else {
				$section = $container->params['productionMode'] ? Environment::PRODUCTION : Environment::DEVELOPMENT;
			}
		}

		$cache = new Cache($container->templateCacheStorage, 'Nette.Configurator');
		$cacheKey = array((array) $container->params, $file, $section);
		$cached = $cache->load($cacheKey);
		if ($cached) {
			require $cached['file'];
			fclose($cached['handle']);
			return $this->container;
		}

		$config = Nette\Config\Config::fromFile($file, $section);
		$code = "<?php\n// source file $file\n\n";

		// back compatibility with singular names
		foreach (array('service', 'variable') as $item) {
			if (isset($config[$item])) {
				trigger_error(basename($file) . ": Section '$item' is deprecated; use plural form '{$item}s' instead.", E_USER_WARNING);
				$config[$item . 's'] = $config[$item];
				unset($config[$item]);
			}
		}

		// add expanded variables
		while (!empty($config['variables'])) {
			$old = $config['variables'];
			foreach ($config['variables'] as $key => $value) {
				try {
					$code .= $this->generateCode('$container->params[?] = ?', $key, $container->params[$key] = $container->expand($value));
					unset($config['variables'][$key]);
				} catch (Nette\InvalidArgumentException $e) {}
			}
			if ($old === $config['variables']) {
				throw new InvalidStateException("Unable to expand variables: " . implode(', ', array_keys($old)) . ".");
			}
		}
		unset($config['variables']);

		// process services
		if (isset($config['services'])) {
			foreach ($config['services'] as $key => & $def) {
				if (preg_match('#^Nette\\\\.*\\\\I?([a-zA-Z]+)$#', strtr($key, '-', '\\'), $m)) { // back compatibility
					$m[1][0] = strtolower($m[1][0]);
					trigger_error(basename($file) . ": service name '$key' has been renamed to '$m[1]'", E_USER_WARNING);
					$key = $m[1];
				}

				if (is_array($def)) {
					if (method_exists(get_called_class(), "createService$key") && !isset($def['factory']) && !isset($def['class'])) {
						$def['factory'] = array(get_called_class(), "createService$key");
					}

					if (isset($def['option'])) {
						$def['arguments'][] = $def['option'];
					}

					if (!empty($def['run'])) {
						$def['tags'] = array('run');
					}
				}
			}
			$builder = new DI\ContainerBuilder;
			/**/$code .= $builder->generateCode($config['services']);/**/
			/*5.2* $code .= $this->generateCode('$builder = new '.get_class($builder).'; $builder->addDefinitions($container, ?)', $config['services']);*/
			unset($config['services']);
		}

		// expand variables
		array_walk_recursive($config, function(&$val) use ($container) {
			$val = $container->expand($val);
		});

		// PHP settings
		if (isset($config['php'])) {
			foreach ($config['php'] as $key => $value) {
				if (is_array($value)) { // back compatibility - flatten INI dots
					foreach ($value as $k => $v) {
						$code .= $this->configurePhp("$key.$k", $v);
					}
				} else {
					$code .= $this->configurePhp($key, $value);
				}
			}
			unset($config['php']);
		}

		// define constants
		if (isset($config['const'])) {
			foreach ($config['const'] as $key => $value) {
				$code .= $this->generateCode('define', $key, $value);
			}
			unset($config['const']);
		}

		// set modes - back compatibility
		if (isset($config['mode'])) {
			trigger_error(basename($file) . ": Section 'mode' is deprecated; use 'params' instead.", E_USER_WARNING);
			foreach ($config['mode'] as $mode => $state) {
				$code .= $this->generateCode('$container->params[?] = ?', $mode . 'Mode', (bool) $state);
			}
			unset($config['mode']);
		}

		// other
		foreach ($config as $key => $value) {
			$code .= $this->generateCode('$container->params[?] = ' . (is_array($value) ? 'Nette\ArrayHash::from(?)' : '?'), $key, $value);
		}

		// pre-loading
		$code .= self::preloadEnvironment($container);

		// auto-start services
		$code .= 'foreach ($container->getServiceNamesByTag("run") as $name => $foo) { $container->getService($name); }' . "\n";

		$cache->save($cacheKey, $code, array(
			Cache::FILES => $file,
		));

		Nette\Utils\LimitedScope::evaluate($code, array('container' => $container));
		return $this->container;
	}
示例#3
0
 static function parseService(Nette\DI\ServiceDefinition $definition, $config, $shared = TRUE)
 {
     if (!is_array($config)) {
         $config = array('class' => $config);
     }
     $known = $shared ? array('class', 'factory', 'arguments', 'setup', 'autowired', 'run', 'tags') : array('class', 'factory', 'arguments', 'setup', 'autowired', 'internal', 'parameters');
     if ($error = array_diff(array_keys($config), $known)) {
         throw new Nette\InvalidStateException("Unknown key '" . implode("', '", $error) . "' in definition of service.");
     }
     $arguments = array();
     if (isset($config['arguments'])) {
         Validators::assertField($config, 'arguments', 'array');
         $arguments = self::filterArguments($config['arguments']);
     }
     if (isset($config['class'])) {
         Validators::assertField($config, 'class', 'string|stdClass');
         if ($config['class'] instanceof \stdClass) {
             $definition->setClass($config['class']->value, self::filterArguments($config['class']->attributes));
         } else {
             $definition->setClass($config['class'], $arguments);
         }
     }
     if (isset($config['factory'])) {
         Validators::assertField($config, 'factory', 'callable|stdClass');
         if ($config['factory'] instanceof \stdClass) {
             $definition->setFactory($config['factory']->value, self::filterArguments($config['factory']->attributes));
         } else {
             $definition->setFactory($config['factory'], $arguments);
         }
     }
     if (isset($config['setup'])) {
         if (Config::takeParent($config['setup'])) {
             $definition->setup = array();
         }
         Validators::assertField($config, 'setup', 'list');
         foreach ($config['setup'] as $id => $setup) {
             Validators::assert($setup, 'callable|stdClass', "setup item #{$id}");
             if ($setup instanceof \stdClass) {
                 Validators::assert($setup->value, 'callable', "setup item #{$id}");
                 if (strpos(is_array($setup->value) ? implode('', $setup->value) : $setup->value, '$') === FALSE) {
                     $definition->addSetup($setup->value, self::filterArguments($setup->attributes));
                 } else {
                     Validators::assert($setup->attributes, 'list:1', "setup arguments for '{$setup->value}'");
                     $definition->addSetup($setup->value, $setup->attributes[0]);
                 }
             } else {
                 $definition->addSetup($setup);
             }
         }
     }
     $definition->setShared($shared);
     if (isset($config['parameters'])) {
         Validators::assertField($config, 'parameters', 'array');
         $definition->setParameters($config['parameters']);
     }
     if (isset($config['autowired'])) {
         Validators::assertField($config, 'autowired', 'bool|string');
         $definition->setAutowired($config['autowired']);
     }
     if (isset($config['internal'])) {
         Validators::assertField($config, 'internal', 'bool');
         $definition->setInternal($config['internal']);
     }
     if (isset($config['run'])) {
         $config['tags']['run'] = (bool) $config['run'];
     }
     if (isset($config['tags'])) {
         Validators::assertField($config, 'tags', 'array');
         if (Config::takeParent($config['tags'])) {
             $definition->tags = array();
         }
         foreach ($config['tags'] as $tag => $attrs) {
             if (is_int($tag) && is_string($attrs)) {
                 $definition->addTag($attrs);
             } else {
                 $definition->addTag($tag, $attrs);
             }
         }
     }
 }
示例#4
0
 /**
  * Loads global configuration from file and process it.
  * @param  string|Nette\Config\Config  file name or Config object
  * @return Nette\Config\Config
  */
 public function loadConfig($file)
 {
     $name = Environment::getName();
     if ($file instanceof Config) {
         $config = $file;
         $file = NULL;
     } else {
         if ($file === NULL) {
             $file = $this->defaultConfigFile;
         }
         $file = Environment::expand($file);
         $config = Config::fromFile($file, $name);
     }
     // process environment variables
     if ($config->variable instanceof Config) {
         foreach ($config->variable as $key => $value) {
             Environment::setVariable($key, $value);
         }
     }
     // expand variables
     $iterator = new \RecursiveIteratorIterator($config);
     foreach ($iterator as $key => $value) {
         $tmp = $iterator->getDepth() ? $iterator->getSubIterator($iterator->getDepth() - 1)->current() : $config;
         $tmp[$key] = Environment::expand($value);
     }
     // process services
     $runServices = array();
     $context = Environment::getContext();
     if ($config->service instanceof Config) {
         foreach ($config->service as $key => $value) {
             $key = strtr($key, '-', '\\');
             // limited INI chars
             if (is_string($value)) {
                 $context->removeService($key);
                 $context->addService($key, $value);
             } else {
                 if ($value->factory) {
                     $context->removeService($key);
                     $context->addService($key, $value->factory, isset($value->singleton) ? $value->singleton : TRUE, (array) $value->option);
                 } elseif (isset($this->defaultServices[$key])) {
                     $context->removeService($key);
                     $context->addService($key, $this->defaultServices[$key], isset($value->singleton) ? $value->singleton : TRUE, (array) $value->option);
                 }
                 if ($value->run) {
                     $runServices[] = $key;
                 }
             }
         }
     }
     // process ini settings
     if (!$config->php) {
         // backcompatibility
         $config->php = $config->set;
         unset($config->set);
     }
     if ($config->php instanceof Config) {
         if (PATH_SEPARATOR !== ';' && isset($config->php->include_path)) {
             $config->php->include_path = str_replace(';', PATH_SEPARATOR, $config->php->include_path);
         }
         foreach (clone $config->php as $key => $value) {
             // flatten INI dots
             if ($value instanceof Config) {
                 unset($config->php->{$key});
                 foreach ($value as $k => $v) {
                     $config->php->{"{$key}.{$k}"} = $v;
                 }
             }
         }
         foreach ($config->php as $key => $value) {
             $key = strtr($key, '-', '.');
             // backcompatibility
             if (!is_scalar($value)) {
                 throw new \InvalidStateException("Configuration value for directive '{$key}' is not scalar.");
             }
             if ($key === 'date.timezone') {
                 // PHP bug #47466
                 date_default_timezone_set($value);
             }
             if (function_exists('ini_set')) {
                 ini_set($key, $value);
             } else {
                 switch ($key) {
                     case 'include_path':
                         set_include_path($value);
                         break;
                     case 'iconv.internal_encoding':
                         iconv_set_encoding('internal_encoding', $value);
                         break;
                     case 'mbstring.internal_encoding':
                         mb_internal_encoding($value);
                         break;
                     case 'date.timezone':
                         date_default_timezone_set($value);
                         break;
                     case 'error_reporting':
                         error_reporting($value);
                         break;
                     case 'ignore_user_abort':
                         ignore_user_abort($value);
                         break;
                     case 'max_execution_time':
                         set_time_limit($value);
                         break;
                     default:
                         if (ini_get($key) != $value) {
                             // intentionally ==
                             throw new \NotSupportedException('Required function ini_set() is disabled.');
                         }
                 }
             }
         }
     }
     // define constants
     if ($config->const instanceof Config) {
         foreach ($config->const as $key => $value) {
             define($key, $value);
         }
     }
     // set modes
     if (isset($config->mode)) {
         foreach ($config->mode as $mode => $state) {
             Environment::setMode($mode, $state);
         }
     }
     // auto-start services
     foreach ($runServices as $name) {
         $context->getService($name);
     }
     return $config;
 }
示例#5
0
 function dump(array $data)
 {
     $tmp = array();
     foreach ($data as $name => $secData) {
         if ($parent = Config::takeParent($secData)) {
             $name .= ' ' . self::INHERITING_SEPARATOR . ' ' . $parent;
         }
         $tmp[$name] = $secData;
     }
     return "# generated by Nette\n\n" . Neon::encode($tmp, Neon::BLOCK);
 }