Пример #1
0
 private function replace_www($template, $document, $args = array())
 {
     foreach ($document->query('//www:*') as $node) {
         $nested = null;
         switch ($node->name()) {
             case 'www:template':
                 $nested = $this->render_template($template->get($node['@name']));
                 break;
             case 'www:xslt':
                 $args = $node->attribute('args');
                 if ($node->attribute('cache') !== 'true') {
                     $nested = $this->render_xslt($template, $node['@xsl'], $node['@xml'], $args ? args::decode($args) : array());
                 } else {
                     $cache_args = $node->attribute('cache-args') ? $node->attribute('cache-args') : array();
                     $cache_lifetime = $node->attribute('cache-lifetime');
                     is_null($cache_lifetime) or is_numeric($cache_lifetime) or runtime_error('Cache lifetime should be numeric: ' . $cache_lifetime);
                     $cache_args = args::decode($cache_args);
                     $filename = cache_location . md5($node['@xsl'] . $node['@xml'] . ($args ? $args : '')) . '.xml';
                     if (!fs::exists($filename) || $cache_lifetime && $cache_lifetime > time() - fs::modification($filename)) {
                         fs::write($filename, $this->render_xslt($template, $node['@xsl'], $node['@xml'], $args ? args::decode($args) : array())->render(false));
                     }
                     $fragment = fs::checked_read($filename);
                     if (!empty($cache_args)) {
                         $fragment = vars::apply_assoc($fragment, $cache_args);
                     }
                     $nested = $document->fragment($fragment);
                 }
                 break;
             case 'www:xquery':
                 require_once www_root . 'thirdparty/xquerylite/class_xquery_lite.php';
                 $xq = new XqueryLite();
                 $fragment = $xq->evaluate_xqueryl(fs::checked_read($node['@src']));
                 $nested = $document->fragment($fragment);
                 break;
             case 'www:style':
                 $src = $node['@src'];
                 $nested = $document->element('link');
                 $nested['@rel'] = 'stylesheet';
                 $nested['@href'] = $src . '?' . fs::crc32($src);
                 break;
             case 'www:script':
                 $src = $node['@src'];
                 $nested = $document->element('script', '');
                 $nested['@type'] = 'text/javascript';
                 $nested['@src'] = $src . '?' . fs::crc32($src);
                 break;
             case 'www:img':
                 $src = $node['@src'];
                 $nested = $document->element('img');
                 $nested['@src'] = $src . '?' . crc32(fs::modification($src));
                 foreach ($node->attributes() as $name => $value) {
                     if ($name != 'src') {
                         $nested['@' . $name] = $value;
                     }
                 }
                 break;
             case 'www:bbcode':
                 $allow = $node->attribute('allow');
                 $deny = $node->attribute('deny');
                 $nested = bbcode::parse($node, $allow ? preg_split('/, */', $allow) : null, $deny ? preg_split('/, */', $deny) : null);
                 break;
             default:
                 runtime_error('Unknown extension element: ' . $node->name());
         }
         self::replace_node($document, $node, $nested);
     }
 }
Пример #2
0
 function request($params, $global, $get, $post, $cookies, $files, $extensions)
 {
     $values = [];
     $batch = [];
     foreach (array_merge($global, $this->params) as $name => $param) {
         $value = self::substitute($param->value, $params);
         switch ($param->type) {
             case 'value':
                 $values[$name] = $value;
                 break;
             case 'json':
                 $values[$name] = json::decode(fs::checked_read($value));
                 break;
             case 'xml':
                 $values[$name] = 'TODO: Add XML support here';
                 break;
             case 'query':
                 $batch[$name] = $value;
                 break;
             case 'get':
                 isset($get[$value]) or isset($param->default) or runtime_error('GET parameter not found: ' . $name);
                 $values[$name] = isset($get[$value]) ? $get[$value] : $param->default;
                 break;
             case 'post':
                 isset($post[$value]) or isset($param->default) or runtime_error('POST parameter not found: ' . $name);
                 $values[$name] = isset($post[$value]) ? $post[$value] : $param->default;
                 break;
             case 'cookie':
                 isset($cookies[$value]) or isset($param->default) or runtime_error('Cookie parameter not found: ' . $name);
                 $values[$name] = isset($cookies[$value]) ? $cookies[$value] : $param->default;
                 break;
         }
     }
     foreach ($batch as $name => &$value) {
         $value = preg_replace_callback('/\\{@(\\w+)\\}/', function ($matches) use($values) {
             return isset($values[$matches[1]]) ? $values[$matches[1]] : $matches[0];
         }, $value);
     }
     $response = [];
     $params = array_merge($values, empty($batch) ? [] : $this->api->batch($batch));
     if ($this->script) {
         $script_args = $params;
         if ($this->files) {
             $script_args = array_merge($script_args, [$this->files => $files]);
         }
         $prototype = '$' . implode(',$', array_keys($script_args));
         $script = '';
         foreach ($this->require as $require) {
             $script .= 'require_once(\'' . $this->scripts . $require . '\');';
         }
         $script .= 'return function(' . (empty($script_args) ? '' : $prototype) . ") { {$this->script} };";
         $closure = eval($script);
         if ($result = call_user_func_array($closure->bindTo($this->api), array_values($script_args))) {
             $params = array_replace($params, $result);
         }
         foreach (['cookies', 'redirect', 'headers'] as $builtin) {
             $mangled = '_' . $builtin;
             if (isset($params[$mangled])) {
                 $response[$builtin] = $params[$mangled];
                 unset($params[$mangled]);
             }
         }
     }
     if ($this->template) {
         switch ($this->engine) {
             case 'twig':
                 $loader = new Twig_Loader_Filesystem($this->templates);
                 $options = [];
                 if ($this->cache) {
                     $options['cache'] = $this->cache;
                 }
                 $twig = new Twig_Environment($loader, $options);
                 //$twig->addExtension(new Twig_Extension_Debug());
                 $twig->getExtension('core')->setNumberFormat(0, '.', ' ');
                 $closure = function ($haystack, $needle) {
                     return $needle === "" or strpos($haystack, $needle) === 0;
                 };
                 $function = new Twig_SimpleFunction('starts_with', $closure);
                 $twig->addFunction($function);
                 $closure = function ($filename) {
                     return json_decode(file_get_contents($this->data . $filename));
                 };
                 $function = new Twig_SimpleFunction('json', $closure->bindTo($this, $this));
                 $twig->addFunction($function);
                 $closure = function ($object) {
                     $array = [];
                     foreach ($object as $key => $value) {
                         $array[$key] = $value;
                     }
                     return $array;
                 };
                 $filter = new Twig_SimpleFilter('array', $closure);
                 $twig->addFilter($filter);
                 $closure = function ($number) {
                     return ceil($number);
                 };
                 $filter = new Twig_SimpleFilter('ceil', $closure);
                 $twig->addFilter($filter);
                 $closure = function ($string) {
                     return md5($string);
                 };
                 $filter = new Twig_SimpleFilter('md5', $closure);
                 $twig->addFilter($filter);
                 $closure = function ($alias) {
                     return $this->locale->get($alias);
                 };
                 $function = new Twig_SimpleFilter('local', $closure->bindTo($this, $this));
                 $twig->addFilter($function);
                 if (!is_null($extensions) and isset($extensions['twig'])) {
                     if (isset($extensions['twig']['filters'])) {
                         foreach ($extensions['twig']['filters'] as $name => $closure) {
                             $twig->addFilter(new Twig_SimpleFilter($name, $closure->bindTo($this, $this)));
                         }
                     }
                     if (isset($extensions['twig']['functions'])) {
                         foreach ($extensions['twig']['functions'] as $name => $closure) {
                             $twig->addFunction(new Twig_SimpleFunction($name, $closure->bindTo($this, $this)));
                         }
                     }
                 }
                 $template = $twig->loadTemplate($this->template);
                 $response['content'] = $template->render($params);
                 break;
             case 'smarty':
                 $smarty = new Smarty();
                 $smarty->setTemplateDir($this->templates);
                 if ($this->cache) {
                     $smarty->setCompileDir($this->cache)->setCacheDir($this->cache);
                 }
                 $smarty->assign($params);
                 $response['content'] = @$smarty->fetch($this->template);
                 break;
         }
     }
     return (object) $response;
 }