/** * Executes this task. */ public function main() { if ($this->path === null) { throw new BuildException('The path attribute must be specified'); } $check = new AgaviModuleFilesystemCheck(); $check->setConfigDirectory($this->project->getProperty('module.config.directory')); $check->setPath($this->path->getAbsolutePath()); if (!$check->check()) { throw new BuildException('The path attribute must be a valid module base directory'); } /* We don't know whether the module is configured or not here, so load the * values we want properly. */ $this->tryLoadAgavi(); $this->tryBootstrapAgavi(); require_once AgaviConfigCache::checkConfig(sprintf('%s/%s/module.xml', $this->path->getAbsolutePath(), (string) $this->project->getProperty('module.config.directory'))); $actionPath = AgaviToolkit::expandVariables(AgaviToolkit::expandDirectives(AgaviConfig::get(sprintf('modules.%s.agavi.action.path', strtolower($this->path->getName())), '%core.module_dir%/${moduleName}/actions/${actionName}Action.class.php')), array('moduleName' => $this->path->getName())); $pattern = '#^' . AgaviToolkit::expandVariables(str_replace('\\$\\{actionName\\}', '${actionName}', preg_quote($actionPath, '#')), array('actionName' => '(?P<action_name>.*?)')) . '$#'; $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->path->getAbsolutePath())); for (; $iterator->valid(); $iterator->next()) { $rdi = $iterator->getInnerIterator(); if ($rdi->isDot() || !$rdi->isFile()) { continue; } $file = $rdi->getPathname(); if (preg_match($pattern, $file, $matches)) { $this->log(str_replace(DIRECTORY_SEPARATOR, '.', $matches['action_name'])); } } }
public function initialize(AgaviContext $ctx, array $parameters = array()) { parent::initialize($ctx, $parameters); $this->dqlViews = (include AgaviConfigCache::checkConfig(AgaviToolkit::expandDirectives('%core.module_dir%/Api/config/views.xml'))); $this->view = $parameters["view"]; $this->viewParameters = isset($parameters["parameters"]) ? $parameters["parameters"] : array(); $this->validateTarget(); $connection = $this->defaultConnection; if (isset($parameters["connection"])) { $connection = $parameters["connection"]; } if ($this->view["connection"]) { $connection = $this->view["connection"]; } AppKitLogger::verbose("Switching to connection %s", $connection); $db = $this->getContext()->getDatabaseManager()->getDatabase($connection); $this->useRetained = $db->useRetained(); $this->connection = $ctx->getDatabaseConnection($connection); if ($this->connection != "icinga") { $ctx->getModel("DBALMetaManager", "Api")->switchIcingaDatabase($connection); } $this->user = $this->getContext()->getUser()->getNsmUser(); $this->parseBaseDQL(); $this->parseCustomVariables(); $this->parseDQLExtensions(); $this->parseDependencies(); }
public function execute(AgaviXmlConfigDomDocument $document) { $data = array(); $prefix = "org.icinga."; $document->setDefaultNamespace(self::XML_NAMESPACE, 'settings'); foreach ($document->getConfigurationElements() as $cfg) { foreach ($cfg->get('settings') as $setting) { $localPrefix = $prefix; // let's see if this buddy has a <settings> parent with valuable information if ($setting->parentNode->localName == 'settings') { if ($setting->parentNode->hasAttribute('prefix')) { $localPrefix = $setting->parentNode->getAttribute('prefix'); } } $settingName = $localPrefix . $setting->getAttribute('name'); if ($setting->hasAgaviParameters()) { $data[$settingName] = $setting->getAgaviParameters(); } else { $data[$settingName] = AgaviToolkit::literalize($setting->getValue()); } } } $code = 'AgaviConfig::fromArray(' . var_export($data, true) . ');'; return $this->generate($code, $document->documentURI); }
private function importModuleXML($accessLocation) { $config = (include AgaviConfigCache::checkConfig(AgaviToolkit::expandDirectives($accessLocation))); $this->instances = array_merge_recursive($this->instances, $config["instances"]); $this->defaults = array_merge_recursive($this->defaults, $config["defaults"]); $this->hosts = array_merge_recursive($this->hosts, $config["hosts"]); }
protected function parseRoutesAndFiles(AgaviRouting $routing, $routes, &$data) { $controller = $this->context->getController(); $request = $this->context->getRequest(); foreach ($routes as $route) { $outputTypes = array(); $routeName = $route->getAttribute('name'); if ($routeName !== '*' && is_null($routing->getRoute($routeName))) { throw new AgaviConfigurationException('Route name "' . $routeName . '" does not exist or is not correct.'); } if ($route->hasAttribute('output_type')) { foreach (explode(' ', $route->getAttribute('output_type')) as $ot) { if ($controller->getOutputType($ot)) { $outputTypes[] = $ot; } } } else { $outputTypes[] = $controller->getOutputType()->getName(); // Defaults to HTML } foreach ($route->get('filelist') as $filelist) { $metatype = $filelist->getAttribute('metatype'); foreach ($filelist->getElementsByTagName('file') as $file) { foreach ($outputTypes as $ot) { if ($file->hasAttribute('name')) { $data[$routeName][$ot][$metatype][$file->getAttribute('name')] = AgaviToolkit::expandDirectives($file->getValue()); } else { $data[$routeName][$ot][$metatype][] = AgaviToolkit::expandDirectives($file->getValue()); } } } } } }
/** * Execute this configuration handler. * * @param AgaviXmlConfigDomDocument The document to parse. * * @return string Data to be written to a cache file. * * @throws <b>AgaviParseException</b> If a requested configuration file is * improperly formatted. * * @author Sean Kerr <*****@*****.**> * @author Dominik del Bondio <*****@*****.**> * @author David Zülke <*****@*****.**> * @since 0.9.0 */ public function execute(AgaviXmlConfigDomDocument $document) { // set up our default namespace $document->setDefaultNamespace(self::XML_NAMESPACE, 'compile'); $config = $document->documentURI; $data = array(); // let's do our fancy work foreach ($document->getConfigurationElements() as $configuration) { if (!$configuration->has('compiles')) { continue; } foreach ($configuration->get('compiles') as $compileFile) { $file = trim($compileFile->getValue()); $file = AgaviToolkit::expandDirectives($file); $file = self::replacePath($file); $file = realpath($file); if (!is_readable($file)) { // file doesn't exist $error = 'Configuration file "%s" specifies nonexistent ' . 'or unreadable file "%s"'; $error = sprintf($error, $config, $compileFile->getValue()); throw new AgaviParseException($error); } if (AgaviConfig::get('core.debug', false)) { // debug mode, just require() the files, makes for nicer stack traces $contents = 'require(' . var_export($file, true) . ');'; } else { // no debug mode, so make things fast $contents = $this->formatFile(file_get_contents($file)); } // append file data $data[$file] = $contents; } } return $this->generate($data, $config); }
private function loadModuleFiles($tm, &$files) { $default = $tm->getDefaultDomain(); $translator = $tm->getDomainTranslator($default, AgaviTranslationManager::MESSAGE); $locale = $tm->getCurrentLocale(); $domains = array(); if ($translator instanceof AppKitGettextTranslator) { $basePath = $translator->getDomainPathPattern(); $modules = scandir(AgaviToolkit::literalize("%core.module_dir%")); foreach ($modules as $m) { if ($m != '.' && $m != '..') { $domains[] = $m; } } foreach ($domains as $domain) { $path = AgaviToolkit::expandVariables($basePath, array('domain' => $domain)); foreach (AgaviLocale::getLookupPath($tm->getCurrentLocale()->getIdentifier()) as $prefix) { $result = $this->loadFile($path, $prefix, $files); if ($result) { $files[$domain] = $result; } } } } }
/** * Validates the input. * * @return bool The value is a valid boolean * * @author Felix Gilcher <*****@*****.**> * @since 1.0.4 */ protected function validate() { $value =& $this->getData($this->getArgument()); $origValue = $value; if (is_bool($value)) { // noop } elseif (1 === $value || '1' === $value) { $value = true; } elseif (0 === $value || '0' === $value) { $value = false; } elseif (is_string($value)) { $value = AgaviToolkit::literalize($value); } if (is_bool($value)) { // we don't cast if the value is exported. // caution, AgaviValidator::export does the test for empty // strings, null and false values, so we can't use // hasParameter here if ($this->getParameter('export')) { $value = $origValue; } else { $this->export($value); } return true; } $value = $origValue; $this->throwError('type'); return false; }
public static function loadConfig() { if (self::$configLoaded) { return; } self::$config = (include AgaviConfigCache::checkConfig(AgaviToolkit::expandDirectives('%core.module_dir%/Api/config/access.xml'))); self::$configLoaded = true; }
/** * Load Propel config * * @param AgaviDatabaseManager The database manager of this instance. * @param array An assoc array of initialization params. * * @author David Zülke <*****@*****.**> * @since 0.10.0 */ public function initialize(AgaviDatabaseManager $databaseManager, array $parameters = array()) { parent::initialize($databaseManager, $parameters); $configPath = AgaviToolkit::expandDirectives($this->getParameter('config')); $datasource = $this->getParameter('datasource', null); $use_as_default = $this->getParameter('use_as_default', false); $config = (require $configPath); if ($datasource === null || $datasource == 'default') { if (isset($config['propel']['datasources']['default'])) { $datasource = $config['propel']['datasources']['default']; } elseif (isset($config['datasources']['default'])) { $datasource = $config['datasources']['default']; } else { throw new AgaviDatabaseException('No datasource given for Propel connection, and no default datasource specified in runtime configuration file.'); } } if (!class_exists('Propel')) { include 'propel/Propel.php'; } if (!Propel::isInit()) { Propel::init($configPath); } $is13 = version_compare(Propel::VERSION, '1.4', '<'); // grab the configuration values and inject possibly defined overrides for this data source if ($is13) { // old-style config array; PropelConfiguration was added after 1.3.0, http://trac.agavi.org/ticket/1195 $config = Propel::getConfiguration(); $config['datasources'][$datasource]['adapter'] = $this->getParameter('overrides[adapter]', $config['datasources'][$datasource]['adapter']); $config['datasources'][$datasource]['connection'] = array_merge($config['datasources'][$datasource]['connection'], $this->getParameter('overrides[connection]', array())); // also the autoload classes $config['datasources'][$datasource]['classes'] = array_merge($config['datasources'][$datasource]['classes'], $this->getParameter('overrides[classes]', array())); // and init queries if (!isset($config['datasources'][$datasource]['connection']['settings']['queries']['query'])) { $config['datasources'][$datasource]['connection']['settings']['queries']['query'] = array(); } // array cast because "query" might be a string if just one init query was given, http://trac.agavi.org/ticket/1194 $config['datasources'][$datasource]['connection']['settings']['queries']['query'] = array_merge((array) $config['datasources'][$datasource]['connection']['settings']['queries']['query'], (array) $this->getParameter('init_queries')); // set the new config Propel::setConfiguration($config); } else { $config = Propel::getConfiguration(PropelConfiguration::TYPE_OBJECT); $overrides = (array) $this->getParameter('overrides'); // set override values foreach ($overrides as $key => $value) { $config->setParameter($key, $value); } // handle init queries in a cross-adapter fashion (they all support the "init_queries" param) $queries = (array) $config->getParameter('datasources.' . $datasource . '.connection.settings.queries.query', array()); // yes... it's one array, [connection][settings][queries][query], with all the init queries from the config, so we append to that $queries = array_merge($queries, (array) $this->getParameter('init_queries')); $config->setParameter('datasources.' . $datasource . '.connection.settings.queries.query', $queries); } if (true === $this->getParameter('enable_instance_pooling')) { Propel::enableInstancePooling(); } elseif (false === $this->getParameter('enable_instance_pooling')) { Propel::disableInstancePooling(); } }
public function initialize(AgaviContext $context, array $parameters = array()) { parent::initialize($context, $parameters); $this->config = (include AgaviConfigCache::checkConfig(AgaviToolkit::expandDirectives('%core.module_dir%/Api/config/icingaCommands.xml'))); $this->user = $context->getUser(); if ($this->user->getNsmUser()->hasTarget('IcingaCommandRestrictions')) { $this->filterCommandsByUser($this->config); } }
/** * Startup the Agavi core * * @param string environment the environment to use for this session. * * @author David Zülke <*****@*****.**> * @since 0.11.0 */ public static function bootstrap($environment = null) { // set up our __autoload spl_autoload_register(array('AgaviAutoloader', 'loadClass')); try { if ($environment === null) { // no env given? let's read one from core.environment $environment = AgaviConfig::get('core.environment'); } elseif (AgaviConfig::has('core.environment') && AgaviConfig::isReadonly('core.environment')) { // env given, but core.environment is read-only? then we must use that instead and ignore the given setting $environment = AgaviConfig::get('core.environment'); } if ($environment === null) { // still no env? oh man... throw new AgaviException('You must supply an environment name to Agavi::bootstrap() or set the name of the default environment to be used in the configuration directive "core.environment".'); } // finally set the env to what we're really using now. AgaviConfig::set('core.environment', $environment, true, true); AgaviConfig::set('core.debug', false, false); if (!AgaviConfig::has('core.app_dir')) { throw new AgaviException('Configuration directive "core.app_dir" not defined, terminating...'); } // define a few filesystem paths AgaviConfig::set('core.cache_dir', AgaviConfig::get('core.app_dir') . '/cache', false, true); AgaviConfig::set('core.config_dir', AgaviConfig::get('core.app_dir') . '/config', false, true); AgaviConfig::set('core.system_config_dir', AgaviConfig::get('core.agavi_dir') . '/config/defaults', false, true); AgaviConfig::set('core.lib_dir', AgaviConfig::get('core.app_dir') . '/lib', false, true); AgaviConfig::set('core.model_dir', AgaviConfig::get('core.app_dir') . '/models', false, true); AgaviConfig::set('core.module_dir', AgaviConfig::get('core.app_dir') . '/modules', false, true); AgaviConfig::set('core.template_dir', AgaviConfig::get('core.app_dir') . '/templates', false, true); AgaviConfig::set('core.cldr_dir', AgaviConfig::get('core.agavi_dir') . '/translation/data', false, true); // autoloads first (will trigger the compilation of config_handlers.xml) $autoload = AgaviConfig::get('core.config_dir') . '/autoload.xml'; if (!is_readable($autoload)) { $autoload = AgaviConfig::get('core.system_config_dir') . '/autoload.xml'; } AgaviConfigCache::load($autoload); // load base settings AgaviConfigCache::load(AgaviConfig::get('core.config_dir') . '/settings.xml'); // clear our cache if the conditions are right if (AgaviConfig::get('core.debug')) { AgaviToolkit::clearCache(); // load base settings AgaviConfigCache::load(AgaviConfig::get('core.config_dir') . '/settings.xml'); } $compile = AgaviConfig::get('core.config_dir') . '/compile.xml'; if (!is_readable($compile)) { $compile = AgaviConfig::get('core.system_config_dir') . '/compile.xml'; } // required classes for the framework AgaviConfigCache::load($compile); } catch (Exception $e) { AgaviException::render($e); } }
/** * Executes the task. */ public function main() { if ($this->property === null) { throw new BuildException('The property attribute must be specified'); } if ($this->string === null) { throw new BuildException('The string attribute must be specified'); } $result = str_replace('/', '_', AgaviToolkit::canonicalName($this->string)); $this->project->setUserProperty($this->property, $result); }
public function testCheckConfig() { $config = AgaviConfig::get('core.config_dir') . DIRECTORY_SEPARATOR . 'autoload.xml'; $config = AgaviToolkit::normalizePath($config); $expected = AgaviConfigCache::getCacheName($config); if (file_exists($expected)) { unlink($expected); } $cacheName = AgaviConfigCache::checkConfig($config); $this->assertEquals($expected, $cacheName); $this->assertFileExists($cacheName); }
public function testConfigHandlersConfigHandler() { $hf = AgaviToolkit::normalizePath(AgaviConfig::get('core.config_dir') . '/routing.xml'); $CHCH = new AgaviConfigHandlersConfigHandler(); $document = $this->parseConfiguration(AgaviConfig::get('core.config_dir') . '/tests/config_handlers.xml', AgaviConfig::get('core.agavi_dir') . '/config/xsl/config_handlers.xsl'); $file = $this->getIncludeFile($CHCH->execute($document)); $handlers = (include $file); unlink($file); $this->assertCount(1, $handlers); $this->assertTrue(isset($handlers[$hf])); $this->assertSame('CHCHTestHandler', $handlers[$hf]['class']); $this->assertSame(AgaviConfig::get('core.agavi_dir') . '/config/xsd/routing.xsd', $handlers[$hf]['validations']['single']['transformations_after']['xml_schema'][0]); $this->assertSame(array('foo' => 'bar', 'dir' => AgaviConfig::get('core.agavi_dir')), $handlers[$hf]['parameters']); }
/** * Create an instance of PHPTAL and initialize it correctly. * * @return PHPTAL The PHPTAL instance. * * @author David Zülke <*****@*****.**> * @since 1.0.2 */ protected function createEngineInstance() { $phptalPhpCodeDestination = AgaviConfig::get('core.cache_dir') . DIRECTORY_SEPARATOR . AgaviPhptalRenderer::COMPILE_DIR . DIRECTORY_SEPARATOR . AgaviPhptalRenderer::COMPILE_SUBDIR . DIRECTORY_SEPARATOR; // we keep this for < 1.2 if (!defined('PHPTAL_PHP_CODE_DESTINATION')) { define('PHPTAL_PHP_CODE_DESTINATION', $phptalPhpCodeDestination); } AgaviToolkit::mkdir($phptalPhpCodeDestination, fileperms(AgaviConfig::get('core.cache_dir')), true); if (!class_exists('PHPTAL')) { require 'PHPTAL.php'; } $phptal = new PHPTAL(); if (version_compare(PHPTAL_VERSION, '1.2', 'ge')) { $phptal->setPhpCodeDestination($phptalPhpCodeDestination); } return $phptal; }
/** * Execute this configuration handler. * * @param AgaviXmlConfigDomDocument The document to parse. * * @return string Data to be written to a cache file. * * @throws <b>AgaviParseException</b> If a requested configuration file is * improperly formatted. * * @author David Zülke <*****@*****.**> * @since 0.9.0 */ public function execute(AgaviXmlConfigDomDocument $document) { // set up our default namespace $document->setDefaultNamespace(self::XML_NAMESPACE, 'module'); // remember the config file path $config = $document->documentURI; $enabled = false; $prefix = 'modules.${moduleName}.'; $data = array(); // loop over <configuration> elements foreach ($document->getConfigurationElements() as $configuration) { $module = $configuration->getChild('module'); if (!$module) { continue; } // enabled flag is treated separately $enabled = (bool) AgaviToolkit::literalize($module->getAttribute('enabled')); // loop over <setting> elements; there can be many of them foreach ($module->get('settings') as $setting) { $localPrefix = $prefix; // let's see if this buddy has a <settings> parent with valuable information if ($setting->parentNode->localName == 'settings') { if ($setting->parentNode->hasAttribute('prefix')) { $localPrefix = $setting->parentNode->getAttribute('prefix'); } } $settingName = $localPrefix . $setting->getAttribute('name'); if ($setting->hasAgaviParameters()) { $data[$settingName] = $setting->getAgaviParameters(); } else { $data[$settingName] = AgaviToolkit::literalize($setting->getValue()); } } } $code = array(); $code[] = '$lcModuleName = strtolower($moduleName);'; $code[] = 'AgaviConfig::set(AgaviToolkit::expandVariables(' . var_export($prefix . 'enabled', true) . ', array(\'moduleName\' => $lcModuleName)), ' . var_export($enabled, true) . ', true, true);'; if (count($data)) { $code[] = '$moduleConfig = ' . var_export($data, true) . ';'; $code[] = '$moduleConfigKeys = array_keys($moduleConfig);'; $code[] = 'foreach($moduleConfigKeys as &$value) $value = AgaviToolkit::expandVariables($value, array(\'moduleName\' => $lcModuleName));'; $code[] = '$moduleConfig = array_combine($moduleConfigKeys, $moduleConfig);'; $code[] = 'AgaviConfig::fromArray($moduleConfig);'; } return $this->generate($code, $config); }
/** * Execute this configuration handler. * * @param AgaviXmlConfigDomDocument The document to handle. * * @return string Data to be written to a cache file. * * @throws <b>AgaviUnreadableException</b> If a requested configuration * file does not exist or is not * readable. * @throws <b>AgaviParseException</b> If a requested configuration file is * improperly formatted. * * @author Dominik del Bondio <*****@*****.**> * @author Noah Fontes <*****@*****.**> * @author David Zülke <*****@*****.**> * @since 0.11.0 */ public function execute(AgaviXmlConfigDomDocument $document) { // set up our default namespace $document->setDefaultNamespace(self::XML_NAMESPACE, 'config_handlers'); // init our data arrays $handlers = array(); foreach ($document->getConfigurationElements() as $configuration) { if (!$configuration->has('handlers')) { continue; } // let's do our fancy work foreach ($configuration->get('handlers') as $handler) { $pattern = $handler->getAttribute('pattern'); $category = AgaviToolkit::normalizePath(AgaviToolkit::expandDirectives($pattern)); $class = $handler->getAttribute('class'); $transformations = array(AgaviXmlConfigParser::STAGE_SINGLE => array(), AgaviXmlConfigParser::STAGE_COMPILATION => array()); if ($handler->has('transformations')) { foreach ($handler->get('transformations') as $transformation) { $path = AgaviToolkit::literalize($transformation->getValue()); $for = $transformation->getAttribute('for', AgaviXmlConfigParser::STAGE_SINGLE); $transformations[$for][] = $path; } } $validations = array(AgaviXmlConfigParser::STAGE_SINGLE => array(AgaviXmlConfigParser::STEP_TRANSFORMATIONS_BEFORE => array(AgaviXmlConfigParser::VALIDATION_TYPE_RELAXNG => array(), AgaviXmlConfigParser::VALIDATION_TYPE_SCHEMATRON => array(), AgaviXmlConfigParser::VALIDATION_TYPE_XMLSCHEMA => array()), AgaviXmlConfigParser::STEP_TRANSFORMATIONS_AFTER => array(AgaviXmlConfigParser::VALIDATION_TYPE_RELAXNG => array(), AgaviXmlConfigParser::VALIDATION_TYPE_SCHEMATRON => array(), AgaviXmlConfigParser::VALIDATION_TYPE_XMLSCHEMA => array())), AgaviXmlConfigParser::STAGE_COMPILATION => array(AgaviXmlConfigParser::STEP_TRANSFORMATIONS_BEFORE => array(AgaviXmlConfigParser::VALIDATION_TYPE_RELAXNG => array(), AgaviXmlConfigParser::VALIDATION_TYPE_SCHEMATRON => array(), AgaviXmlConfigParser::VALIDATION_TYPE_XMLSCHEMA => array()), AgaviXmlConfigParser::STEP_TRANSFORMATIONS_AFTER => array(AgaviXmlConfigParser::VALIDATION_TYPE_RELAXNG => array(), AgaviXmlConfigParser::VALIDATION_TYPE_SCHEMATRON => array(), AgaviXmlConfigParser::VALIDATION_TYPE_XMLSCHEMA => array()))); if ($handler->has('validations')) { foreach ($handler->get('validations') as $validation) { $path = AgaviToolkit::literalize($validation->getValue()); $type = null; if (!$validation->hasAttribute('type')) { $type = $this->guessValidationType($path); } else { $type = $validation->getAttribute('type'); } $for = $validation->getAttribute('for', AgaviXmlConfigParser::STAGE_SINGLE); $step = $validation->getAttribute('step', AgaviXmlConfigParser::STEP_TRANSFORMATIONS_AFTER); $validations[$for][$step][$type][] = $path; } } $handlers[$category] = isset($handlers[$category]) ? $handlers[$category] : array('parameters' => array()); $handlers[$category] = array('class' => $class, 'parameters' => $handler->getAgaviParameters($handlers[$category]['parameters']), 'transformations' => $transformations, 'validations' => $validations); } } $data = array('return ' . var_export($handlers, true)); return $this->generate($data, $document->documentURI); }
/** * Fetches the Validation xml for the action/module combination and returns it as * an DOMDocument * * @param string The module name * @param string The action to get the validation xml for * @return AgaviXmlConfigDomDocument * * @author Jannis Moßhammer<*****@*****.**> * @throws AgaviConfigurationException when module or action does not exist */ protected function getValidatorXMLForAction($module, $action) { // get Module path $path = AgaviToolkit::literalize('%core.module_dir%') . "/" . $module; if (!file_exists(AgaviToolkit::normalizePath($path))) { throw new AgaviConfigurationException("Couldn't find module " . $module); } // get Validation file $actionPath = str_replace(".", "/", $action); $xml = $path . "/validate/" . $actionPath . ".xml"; if (!file_exists(AgaviToolkit::normalizePath($path))) { throw new AgaviConfigurationException("Couldn't find validation file for " . $action); } $dom = new AgaviXmlConfigDomDocument(); $dom->load(AgaviToolKit::normalizePath($xml)); //TODO: Validate xml return $dom; }
/** * Get the full, resolved stream location name to the template resource. * * @return string A PHP stream resource identifier. * * @throws AgaviException If the template could not be found. * * @author David Zülke <*****@*****.**> * @since 0.11.0 */ public function getResourceStreamIdentifier() { $template = $this->getParameter('template'); if ($template === null) { // no template set, we return null so nothing gets rendered return null; } $args = array(); if (AgaviConfig::get('core.use_translation')) { // i18n is enabled, build a list of sprintf args with the locale identifier foreach (AgaviLocale::getLookupPath($this->context->getTranslationManager()->getCurrentLocaleIdentifier()) as $identifier) { $args[] = array('locale' => $identifier); } } if (empty($args)) { $args[] = array(); // add one empty arg to always trigger target lookups (even if i18n is disabled etc.) } $scheme = $this->getParameter('scheme'); // FIXME: a simple workaround for broken ubuntu and debian packages (fixed already), we can remove that for final 0.11 if ($scheme != 'file' && !in_array($scheme, stream_get_wrappers())) { throw new AgaviException('Unknown stream wrapper "' . $scheme . '", must be one of "' . implode('", "', stream_get_wrappers()) . '".'); } $check = $this->getParameter('check'); $attempts = array(); // try each of the patterns foreach ((array) $this->getParameter('targets', array()) as $pattern) { // try pattern with each argument list foreach ($args as $arg) { $target = AgaviToolkit::expandVariables($pattern, array_merge(array_filter($this->getParameters(), 'is_scalar'), array_filter($this->getParameters(), 'is_null'), $arg)); // FIXME (should they fix it): don't add file:// because suhosin's include whitelist is empty by default, does not contain 'file' as allowed uri scheme if ($scheme != 'file') { $target = $scheme . '://' . $target; } if (!$check || is_readable($target)) { return $target; } $attempts[] = $target; } } // no template found, time to throw an exception throw new AgaviException('Template "' . $template . '" could not be found. Paths tried:' . "\n" . implode("\n", $attempts)); }
private function importModuleConfigurations() { $moduleDir = AgaviToolkit::literalize("%core.module_dir%"); $modules = scandir($moduleDir); foreach ($modules as $folder) { $dir = $moduleDir; if ($folder == ".." || $folder == "." || $folder == "Api") { continue; } $dir = $dir . "/" . $folder . "/"; if (!is_dir($dir) || !is_readable($dir)) { continue; } $accessLocation = $dir . "config/views.xml"; if (file_exists($accessLocation) && is_readable($accessLocation)) { $this->importModuleXML($accessLocation); } } }
/** * Execute this configuration handler. * * @param AgaviXmlConfigDomDocument The document to parse. * * @return string Data to be written to a cache file. * * @throws <b>AgaviParseException</b> If a requested configuration file is * improperly formatted. * * @author David Zülke <*****@*****.**> * @author Sean Kerr <*****@*****.**> * @since 0.9.0 */ public function execute(AgaviXmlConfigDomDocument $document) { // set up our default namespace $document->setDefaultNamespace(self::XML_NAMESPACE, 'filters'); $config = $document->documentURI; $filters = array(); foreach ($document->getConfigurationElements() as $cfg) { if ($cfg->has('filters')) { foreach ($cfg->get('filters') as $filter) { $name = $filter->getAttribute('name', AgaviToolkit::uniqid()); if (!isset($filters[$name])) { $filters[$name] = array('params' => array(), 'enabled' => AgaviToolkit::literalize($filter->getAttribute('enabled', true))); } else { $filters[$name]['enabled'] = AgaviToolkit::literalize($filter->getAttribute('enabled', $filters[$name]['enabled'])); } if ($filter->hasAttribute('class')) { $filters[$name]['class'] = $filter->getAttribute('class'); } $filters[$name]['params'] = $filter->getAgaviParameters($filters[$name]['params']); } } } $data = array(); foreach ($filters as $name => $filter) { if (stripos($name, 'agavi') === 0) { throw new AgaviConfigurationException('Filter names must not start with "agavi".'); } if (!isset($filter['class'])) { throw new AgaviConfigurationException('No class name specified for filter "' . $name . '" in ' . $config); } if ($filter['enabled']) { $rc = new ReflectionClass($filter['class']); $if = 'AgaviI' . ucfirst(strtolower(substr(basename($config), 0, strpos(basename($config), '_filters')))) . 'Filter'; if (!$rc->implementsInterface($if)) { throw new AgaviFactoryException('Filter "' . $name . '" does not implement interface "' . $if . '"'); } $data[] = '$filter = new ' . $filter['class'] . '();'; $data[] = '$filter->initialize($this->context, ' . var_export($filter['params'], true) . ');'; $data[] = '$filters[' . var_export($name, true) . '] = $filter;'; } } return $this->generate($data, $config); }
/** * Create an instance of PHPTAL and initialize it correctly. * * @return PHPTAL The PHPTAL instance. * * @author David Zülke <*****@*****.**> * @since 1.0.2 */ protected function createEngineInstance() { $phptalPhpCodeDestination = AgaviConfig::get('core.cache_dir') . DIRECTORY_SEPARATOR . AgaviPhptalRenderer::COMPILE_DIR . DIRECTORY_SEPARATOR . AgaviPhptalRenderer::COMPILE_SUBDIR . DIRECTORY_SEPARATOR; // we keep this for < 1.2 if (!defined('PHPTAL_PHP_CODE_DESTINATION')) { define('PHPTAL_PHP_CODE_DESTINATION', $phptalPhpCodeDestination); } AgaviToolkit::mkdir($phptalPhpCodeDestination, fileperms(AgaviConfig::get('core.cache_dir')), true); if (!class_exists('PHPTAL')) { require 'PHPTAL.php'; } $phptal = new PHPTAL(); if (version_compare(PHPTAL_VERSION, '1.2', 'ge')) { $phptal->setPhpCodeDestination($phptalPhpCodeDestination); } else { trigger_error('Support for PHPTAL versions older than 1.2 is deprecated and will be removed in Agavi 1.2.', E_USER_DEPRECATED); } if ($this->hasParameter('encoding')) { $phptal->setEncoding($this->getParameter('encoding')); } return $phptal; }
/** * Execute this configuration handler. * * @param AgaviXmlConfigDomDocument The document to parse. * * @return string Data to be written to a cache file. * * @throws <b>AgaviParseException</b> If a requested configuration file is * improperly formatted. * * @author Sean Kerr <*****@*****.**> * @author Dominik del Bondio <*****@*****.**> * @author Noah Fontes <*****@*****.**> * @author David Zülke <*****@*****.**> * @since 0.9.0 */ public function execute(AgaviXmlConfigDomDocument $document) { // set up our default namespace $document->setDefaultNamespace(self::XML_NAMESPACE, 'autoload'); $classes = $namespaces = array(); foreach ($document->getConfigurationElements() as $configuration) { if (!$configuration->has('autoloads')) { continue; } // let's do our fancy work foreach ($configuration->get('autoloads') as $autoload) { // we can have variables in the filename $path = AgaviToolkit::expandDirectives($autoload->getValue()); // sanity check; XML Schema can't do <xs:choice> on attributes... if (($isClass = $autoload->hasAttribute('class')) && $autoload->hasAttribute('namespace')) { $error = sprintf('Configuration file "%s" specifies both "class" and "namespace" attribute for path "%s"', $document->documentURI, $path); throw new AgaviParseException($error); } // prepend the app dir if the path is not absolute $file = self::replacePath($path); // check if absolute path is readable or try to resolve it against the include path if (!file_exists($file) && ($path == $file || !($file = stream_resolve_include_path($path)))) { // the class path doesn't exist and couldn't be resolved against the include path either $error = sprintf('Configuration file "%s" specifies %s "%s" with non-existent path "%s"', $document->documentURI, $isClass ? 'file' : 'namespace', $isClass ? $autoload->getAttribute('class') : $autoload->getAttribute('namespace'), $path); throw new AgaviParseException($error); } if ($isClass) { // it's a class $classes[$autoload->getAttribute('class')] = $file; } else { // it's a whole namespace // trim backslashes from the namespace and trailing slashes or backslashes from the path $namespaces[trim($autoload->getAttribute('namespace'), '\\')] = rtrim($file, '/\\'); } } } $code = array('AgaviAutoloader::addClasses(' . var_export($classes, true) . ');', 'AgaviAutoloader::addNamespaces(' . var_export($namespaces, true) . ');'); return $this->generate($code, $document->documentURI); }
/** * Execute this configuration handler. * * @param AgaviXmlConfigDomDocument The document to parse. * * @return string Data to be written to a cache file. * * @throws <b>AgaviParseException</b> If a requested configuration file is * improperly formatted. * * @author Sean Kerr <*****@*****.**> * @author Dominik del Bondio <*****@*****.**> * @author Noah Fontes <*****@*****.**> * @since 0.9.0 */ public function execute(AgaviXmlConfigDomDocument $document) { // set up our default namespace $document->setDefaultNamespace(self::XML_NAMESPACE, 'autoload'); $data = array(); foreach ($document->getConfigurationElements() as $configuration) { if (!$configuration->has('autoloads')) { continue; } // let's do our fancy work foreach ($configuration->get('autoloads') as $autoload) { // we can have variables in the filename $file = AgaviToolkit::expandDirectives($autoload->getValue()); // we need the filename w/o app dir prepended since the file could // be placed in the include path $originalFile = $file; // if the filename is not absolute we assume its relative to the app dir $file = self::replacePath($file); $class = $autoload->getAttribute('name'); if (!($fp = @fopen($file, 'r', true))) { if ($originalFile != $file && ($fpOriginal = @fopen($originalFile, 'r', true))) { $file = $originalFile; $fp = $fpOriginal; } else { // the class path doesn't exist $error = 'Configuration file "%s" specifies class "%s" with ' . 'nonexistent or unreadable file "%s"'; $error = sprintf($error, $document->documentURI, $class, $file); throw new AgaviParseException($error); } } fclose($fp); $data[$class] = $file; } } $code = array('return ' . var_export($data, true) . ';'); return $this->generate($code, $document->documentURI); }
/** * Validates the input. * * @return bool The value is a valid boolean * * @author Felix Gilcher <*****@*****.**> * @since 1.0.4 */ protected function validate() { $value =& $this->getData($this->getArgument()); $castValue = $value; if (is_bool($castValue)) { // noop } elseif (1 === $castValue || '1' === $castValue) { $castValue = true; } elseif (0 === $castValue || '0' === $castValue) { $castValue = false; } elseif (is_string($castValue)) { $castValue = AgaviToolkit::literalize($castValue); } if (is_bool($castValue)) { if ($this->hasParameter('export')) { $this->export($castValue); } else { $value = $castValue; } return true; } $this->throwError('type'); return false; }
/** * AgaviTimeZone API. * * @see AgaviTimeZone::getOffsetRef() * * @author Dominik del Bondio <*****@*****.**> * @author The ICU Project * @since 0.11.0 */ public function getOffsetRef($date, $local, &$rawoff, &$dstoff) { // The check against finalMillis will suffice most of the time, except // for the case in which finalMillis == DBL_MAX, date == DBL_MAX, // and finalZone == 0. For this case we add "&& finalZone != 0". if ($date >= $this->finalMillis && $this->finalZone !== null) { $millis = 0; $days = AgaviToolkit::floorDivide($date, AgaviDateDefinitions::MILLIS_PER_DAY, $millis); $year = 0; $month = 0; $dom = 0; $dow = 0; AgaviCalendarGrego::dayToFields($days, $year, $month, $dom, $dow); $rawoff = $this->finalZone->getRawOffset(); if (!$local) { // Adjust from GMT to local $date += $rawoff; $days2 = AgaviToolkit::floorDivide($date, AgaviDateDefinitions::MILLIS_PER_DAY, $millis); if ($days2 != $days) { AgaviCalendarGrego::dayToFields($days2, $year, $month, $dom, $dow); } } $dstoff = $this->finalZone->getOffset(AgaviGregorianCalendar::AD, $year, $month, $dom, $dow, $millis) - $rawoff; return; } $secs = floor($date / AgaviDateDefinitions::MILLIS_PER_SECOND); $transition = $this->findTransition($secs, $local); $rawoff = $this->types[$transition['type']]['rawOffset'] * AgaviDateDefinitions::MILLIS_PER_SECOND; $dstoff = $this->types[$transition['type']]['dstOffset'] * AgaviDateDefinitions::MILLIS_PER_SECOND; }
/** * Loads the data from the data file for the given domain with the current * locale. * * @param string The domain to load the data for. * * @author Dominik del Bondio <*****@*****.**> * @since 0.11.0 */ public function loadDomainData($domain) { $localeName = $this->locale->getIdentifier(); $localeNameBases = AgaviLocale::getLookupPath($localeName); if (!isset($this->domainPaths[$domain])) { if (!$this->domainPathPattern) { throw new AgaviException('Using domain "' . $domain . '" which has no path specified'); } else { $basePath = $this->domainPathPattern; } } else { $basePath = $this->domainPaths[$domain]; } $basePath = AgaviToolkit::expandVariables($basePath, array('domain' => $domain)); $data = array(); foreach ($localeNameBases as $localeNameBase) { $fileName = AgaviToolkit::expandVariables($basePath, array('locale' => $localeNameBase)); if ($fileName === $basePath) { // no replacing of $locale happened $fileName = $basePath . '/' . $localeNameBase . '.mo'; } if (is_readable($fileName)) { $fileData = AgaviGettextMoReader::readFile($fileName); // instead of array_merge, which doesn't handle null bytes in keys properly. careful, the order matters here. $data = $fileData + $data; } } $headers = array(); if (count($data)) { $headerData = str_replace("\r", '', $data['']); $headerLines = explode("\n", $headerData); foreach ($headerLines as $line) { $values = explode(':', $line, 2); // skip empty / invalid lines if (count($values) == 2) { $headers[$values[0]] = $values[1]; } } } $this->pluralFormFunc = null; if (isset($headers['Plural-Forms'])) { $pf = $headers['Plural-Forms']; if (preg_match('#nplurals=\\d+;\\s+plural=(.*)$#D', $pf, $match)) { $funcCode = $match[1]; $validOpChars = array(' ', 'n', '!', '&', '|', '<', '>', '(', ')', '?', ':', ';', '=', '+', '*', '/', '%', '-'); if (preg_match('#[^\\d' . preg_quote(implode('', $validOpChars), '#') . ']#', $funcCode, $errorMatch)) { throw new AgaviException('Illegal character ' . $errorMatch[0] . ' in plural form ' . $funcCode); } // add parenthesis around all ternary expressions. This is done // to make the ternary operator (?) have precedence over the delimiter (:) // This will transform // "a ? 1 : b ? c ? 3 : 4 : 2" to "(a ? 1 : (b ? (c ? 3 : 4) : 2))" and // "a ? b ? c ? d ? 5 : 4 : 3 : 2 : 1" to "(a ? (b ? (c ? (d ? 5 : 4) : 3) : 2) : 1)" // "a ? b ? c ? 4 : 3 : d ? 5 : 2 : 1" to "(a ? (b ? (c ? 4 : 3) : (d ? 5 : 2)) : 1)" // "a ? b ? c ? 4 : 3 : d ? 5 : e ? 6 : 2 : 1" to "(a ? (b ? (c ? 4 : 3) : (d ? 5 : (e ? 6 : 2))) : 1)" $funcCode = rtrim($funcCode, ';'); $parts = preg_split('#(\\?|\\:)#', $funcCode, -1, PREG_SPLIT_DELIM_CAPTURE); $parenthesisCount = 0; $unclosedParenthesisCount = 0; $firstParenthesis = true; $funcCode = ''; for ($i = 0, $c = count($parts); $i < $c; ++$i) { $lastPart = $i > 0 ? $parts[$i - 1] : null; $part = $parts[$i]; $nextPart = $i + 1 < $c ? $parts[$i + 1] : null; if ($nextPart == '?') { if ($lastPart == ':') { // keep track of parenthesis which need to be closed // directly after this ternary expression ++$unclosedParenthesisCount; --$parenthesisCount; } $funcCode .= ' (' . $part; ++$parenthesisCount; } elseif ($lastPart == ':') { $funcCode .= $part . ') '; if ($unclosedParenthesisCount > 0) { $funcCode .= str_repeat(')', $unclosedParenthesisCount); $unclosedParenthesisCount = 0; } --$parenthesisCount; } else { $funcCode .= $part; } } if ($parenthesisCount > 0) { // add the missing top level parenthesis $funcCode .= str_repeat(')', $parenthesisCount); } $funcCode .= ';'; $funcCode = 'return ' . str_replace('n', '$n', $funcCode); $this->pluralFormFunc = create_function('$n', $funcCode); } } $this->domainData[$domain] = array('headers' => $headers, 'msgs' => $data); }
/** * Initialize this validator. * * @param AgaviContext The Context. * @param array An array of validator parameters. * @param array An array of argument names which should be validated. * @param array An array of error messages. * * @author Dominik del Bondio <*****@*****.**> * @since 0.11.0 */ public function initialize(AgaviContext $context, array $parameters = array(), array $arguments = array(), array $errors = array()) { $this->context = $context; $this->arguments = $arguments; $this->errorMessages = $errors; if (!isset($parameters['depends']) || !is_array($parameters['depends'])) { $parameters['depends'] = !empty($parameters['depends']) ? explode(' ', $parameters['depends']) : array(); } if (!isset($parameters['provides']) || !is_array($parameters['provides'])) { $parameters['provides'] = !empty($parameters['provides']) ? explode(' ', $parameters['provides']) : array(); } if (!isset($parameters['source'])) { $parameters['source'] = AgaviRequestDataHolder::SOURCE_PARAMETERS; } $this->setParameters($parameters); $this->name = $this->getParameter('name', AgaviToolkit::uniqid()); }
/** * Converts an AgaviXmlConfigDomElement into an array. * * @param AgaviXmlConfigDomElement The configuration element to convert. * @param bool Whether this is a top level element. * * @return array The configuration values as an array. * * @author Dominik del Bondio <*****@*****.**> * @author David Zülke <*****@*****.**> * @since 0.11.0 */ protected function convertToArray(AgaviXmlConfigDomElement $item, $topLevel = false) { $idAttribute = $this->getParameter('id_attribute', 'name'); $valueKey = $this->getParameter('value_key', 'value'); $forceArrayValues = $this->getParameter('force_array_values', false); $attributePrefix = $this->getParameter('attribute_prefix', ''); $literalize = $this->getParameter('literalize', true); $singularParentName = AgaviInflector::singularize($item->getName()); $data = array(); $attribs = $item->getAttributes(); $numAttribs = count($attribs); if ($idAttribute && $item->hasAttribute($idAttribute)) { $numAttribs--; } foreach ($item->getAttributes() as $name => $value) { if ($topLevel && in_array($name, array('context', 'environment')) || $name == $idAttribute) { continue; } if ($literalize) { $value = AgaviToolkit::literalize($value); } if (!isset($data[$name])) { $data[$attributePrefix . $name] = $value; } } if (!(int) $item->ownerDocument->getXpath()->evaluate(sprintf('count(*[namespace-uri() = "%s"])', $item->ownerDocument->getDefaultNamespaceUri()), $item)) { if ($literalize) { $val = $item->getLiteralValue(); } else { $val = $item->getValue(); } if ($val === null) { $val = ''; } if (!$topLevel && ($numAttribs || $forceArrayValues)) { $data[$valueKey] = $val; } elseif (!$topLevel) { $data = $val; } } else { $names = array(); $children = $item->ownerDocument->getXpath()->query(sprintf('*[namespace-uri() = "%s"]', $item->ownerDocument->getDefaultNamespaceUri()), $item); foreach ($children as $child) { $names[] = $child->getName(); } $dupes = array(); foreach (array_unique(array_diff_assoc($names, array_unique($names))) as $name) { $dupes[] = $name; } foreach ($children as $key => $child) { $hasId = $idAttribute && $child->hasAttribute($idAttribute); $isDupe = in_array($child->getName(), $dupes); $hasParent = $child->getName() == $singularParentName && $item->getName() != $singularParentName; if (($hasId || $isDupe) && !$hasParent) { // it's one of multiple tags in this level without the respective plural form as the parent node if (!isset($data[$idx = AgaviInflector::pluralize($child->getName())])) { $data[$idx] = array(); } $hasParent = true; $to =& $data[$idx]; } else { $to =& $data; } if ($hasId) { $key = $child->getAttribute($idAttribute); if ($literalize) { // no literalize, just constants! $key = AgaviToolkit::expandDirectives($key); } $to[$key] = $this->convertToArray($child); } elseif ($hasParent) { $to[] = $this->convertToArray($child); } else { $to[$child->getName()] = $this->convertToArray($child); } } } return $data; }