Ejemplo n.º 1
0
 public function getPresenterClass(&$name)
 {
     if (isset($this->cache[$name])) {
         list($className, $name) = $this->cache[$name];
         return $className;
     }
     if (!is_string($name) || !String::match($name, "#^[a-zA-Z-ÿ][a-zA-Z0-9-ÿ:]*\$#")) {
         throw new InvalidPresenterException("Presenter name must be alphanumeric string, '{$name}' is invalid.");
     }
     $classNameBase = str_replace(':', 'Module\\', $name) . 'Presenter';
     $classNames = array_map(function ($namespace) use($classNameBase) {
         return ($namespace ? $namespace . "\\" : "") . $classNameBase;
     }, $this->namespaces);
     foreach ($classNames as $className) {
         if (!class_exists($className)) {
             continue;
         }
         $reflection = new ClassReflection($className);
         if (!$reflection->implementsInterface('Nette\\Application\\IPresenter')) {
             throw new InvalidPresenterException("Cannot load presenter '{$name}', class '{$className}' is not Nette\\Application\\IPresenter implementor.");
         }
         if ($reflection->isAbstract()) {
             throw new InvalidPresenterException("Cannot load presenter '{$name}', class '{$className}' is abstract.");
         }
         return $className;
     }
     throw new InvalidPresenterException("Cannot load presenter {$name}, class " . implode(" nor ", $classNames) . " does not exist");
 }
	/**
	 * Processes given request.
	 *
	 * @author   Jan Tvrdík
	 * @param    PresenterRequest
	 * @return   void
	 * @throws   Nette\Applicationy\AbortException|BadRequestException
	 */
	public function processRequest(PresenterRequest $request)
	{
		$params = $request->getParams();
		if (!isset($params['page'])) {
			throw new BadRequestException('Invalid request. Parameter \'page\' is required.');
		}
		$this->page = $params['page'];
		if (!Nette\String::match($this->page, self::PAGE_REGEXP)) {
			throw new BadRequestException('Parameter \'page\' contains illegal characters.');
		}
		$this->sendTemplate();
	}
Ejemplo n.º 3
0
	/**
	 * @param  string  presenter name
	 * @return string  class name
	 * @throws InvalidPresenterException
	 */
	public function getPresenterClass(& $name)
	{
		if (isset($this->cache[$name])) {
			list($class, $name) = $this->cache[$name];
			return $class;
		}

		if (!is_string($name) || !Nette\String::match($name, "#^[a-zA-Z\x7f-\xff][a-zA-Z0-9\x7f-\xff:]*$#")) {
			throw new InvalidPresenterException("Presenter name must be alphanumeric string, '$name' is invalid.");
		}

		$class = $this->formatPresenterClass($name);

		if (!class_exists($class)) {
			// internal autoloading
			$file = $this->formatPresenterFile($name);
			if (is_file($file) && is_readable($file)) {
				Nette\Loaders\LimitedScope::load($file);
			}

			if (!class_exists($class)) {
				throw new InvalidPresenterException("Cannot load presenter '$name', class '$class' was not found in '$file'.");
			}
		}

		$reflection = new Nette\Reflection\ClassReflection($class);
		$class = $reflection->getName();

		if (!$reflection->implementsInterface('Nette\Application\IPresenter')) {
			throw new InvalidPresenterException("Cannot load presenter '$name', class '$class' is not Nette\\Application\\IPresenter implementor.");
		}

		if ($reflection->isAbstract()) {
			throw new InvalidPresenterException("Cannot load presenter '$name', class '$class' is abstract.");
		}

		// canonicalize presenter name
		$realName = $this->unformatPresenterClass($class);
		if ($name !== $realName) {
			if ($this->caseSensitive) {
				throw new InvalidPresenterException("Cannot load presenter '$name', case mismatch. Real name is '$realName'.");
			} else {
				$this->cache[$name] = array($class, $realName);
				$name = $realName;
			}
		} else {
			$this->cache[$name] = array($class, $realName);
		}

		return $class;
	}
Ejemplo n.º 4
0
	function tokenize($input)
	{
		$this->input = $input;
		if ($this->names) {
			$this->tokens = String::matchAll($input, $this->re);
			$len = 0;
			foreach ($this->tokens as & $match) {
				$name = NULL;
				for ($i = 1; $i < count($this->names); $i++) {
					if (!isset($match[$i])) {
						break;
					} elseif ($match[$i] != NULL) {
						$name = $this->names[$i - 1]; break;
					}
				}
				$match = array($match[0], $name);
				$len += strlen($match[0]);
			}
			if ($len !== strlen($input)) {
				$errorOffset = $len;
			}

		} else {
			$this->tokens = String::split($input, $this->re, PREG_SPLIT_NO_EMPTY);
			if ($this->tokens && !String::match(end($this->tokens), $this->re)) {
				$tmp = String::split($this->input, $this->re, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_OFFSET_CAPTURE);
				list(, $errorOffset) = end($tmp);
			}
		}

		if (isset($errorOffset)) {
			$line = $errorOffset ? substr_count($this->input, "\n", 0, $errorOffset) + 1 : 1;
			$col = $errorOffset - strrpos(substr($this->input, 0, $errorOffset), "\n") + 1;
			$token = str_replace("\n", '\n', substr($input, $errorOffset, 10));
			throw new TokenizerException("Unexpected '$token' on line $line, column $col.");
		}
		return $this;
	}
Ejemplo n.º 5
0
	/**
	 * Matches next token.
	 * @param  string
	 * @return array
	 */
	private function match($re)
	{
		if ($matches = String::match($this->input, $re, PREG_OFFSET_CAPTURE, $this->offset)) {
			$this->output .= substr($this->input, $this->offset, $matches[0][1] - $this->offset);
			$this->offset = $matches[0][1] + strlen($matches[0][0]);
			foreach ($matches as $k => $v) $matches[$k] = $v[0];
		}
		return $matches;
	}
Ejemplo n.º 6
0
 /**
  * Parses PHP file.
  * @param  string
  * @return void
  */
 private static function parseScript($file)
 {
     $T_NAMESPACE = PHP_VERSION_ID < 50300 ? -1 : T_NAMESPACE;
     $T_NS_SEPARATOR = PHP_VERSION_ID < 50300 ? -1 : T_NS_SEPARATOR;
     $s = file_get_contents($file);
     if (String::match($s, '#//nette' . 'loader=(\\S*)#')) {
         return;
         // TODO: allways ignore?
     }
     $expected = $namespace = $class = $docComment = NULL;
     $level = $classLevel = 0;
     foreach (token_get_all($s) as $token) {
         if (is_array($token)) {
             switch ($token[0]) {
                 case T_DOC_COMMENT:
                     $docComment = $token[1];
                 case T_WHITESPACE:
                 case T_COMMENT:
                     continue 2;
                 case T_STRING:
                 case $T_NS_SEPARATOR:
                 case T_VARIABLE:
                     if ($expected) {
                         $name .= $token[1];
                     }
                     continue 2;
                 case T_FUNCTION:
                 case T_VAR:
                 case T_PUBLIC:
                 case T_PROTECTED:
                 case $T_NAMESPACE:
                 case T_CLASS:
                 case T_INTERFACE:
                     $expected = $token[0];
                     $name = NULL;
                     continue 2;
                 case T_STATIC:
                 case T_ABSTRACT:
                 case T_FINAL:
                     continue 2;
                     // ignore in expectation
                 // ignore in expectation
                 case T_CURLY_OPEN:
                 case T_DOLLAR_OPEN_CURLY_BRACES:
                     $level++;
             }
         }
         if ($expected) {
             switch ($expected) {
                 case T_CLASS:
                 case T_INTERFACE:
                     $class = $namespace . $name;
                     $classLevel = $level;
                     $name = '';
                     // break intentionally omitted
                 // break intentionally omitted
                 case T_FUNCTION:
                     if ($token === '&') {
                         continue 2;
                     }
                     // ignore
                 // ignore
                 case T_VAR:
                 case T_PUBLIC:
                 case T_PROTECTED:
                     if ($class && $name !== NULL && $docComment) {
                         self::$cache[$class][$name] = self::parseComment($docComment);
                     }
                     break;
                 case $T_NAMESPACE:
                     $namespace = $name . '\\';
             }
             $expected = $docComment = NULL;
         }
         if ($token === ';') {
             $docComment = NULL;
         } elseif ($token === '{') {
             $docComment = NULL;
             $level++;
         } elseif ($token === '}') {
             $level--;
             if ($level === $classLevel) {
                 $class = NULL;
             }
         }
     }
 }
Ejemplo n.º 7
0
 /**
  * @param string $header
  * @return string
  */
 public static function getContentType($header, $default = NULL)
 {
     $match = String::match($header, self::CONTENT_TYPE);
     return isset($match['type']) ? $match['type'] : $default;
 }
Ejemplo n.º 8
0
 /**
  * Float validator: is a control's value float number?
  * @param  TextBase
  * @return bool
  */
 public static function validateFloat(TextBase $control)
 {
     return (bool) String::match($control->getValue(), '/^-?[0-9]*[.,]?[0-9]+$/');
 }
Ejemplo n.º 9
0
 /**
  * Maps HTTP request to a PresenterRequest object.
  * @param  Nette\Web\IHttpRequest
  * @return PresenterRequest|NULL
  */
 public function match(Nette\Web\IHttpRequest $httpRequest)
 {
     // combine with precedence: mask (params in URL-path), fixity, query, (post,) defaults
     // 1) URL MASK
     $uri = $httpRequest->getUri();
     if ($this->type === self::HOST) {
         $path = '//' . $uri->getHost() . $uri->getPath();
     } elseif ($this->type === self::RELATIVE) {
         $basePath = $uri->getBasePath();
         if (strncmp($uri->getPath(), $basePath, strlen($basePath)) !== 0) {
             return NULL;
         }
         $path = (string) substr($uri->getPath(), strlen($basePath));
     } else {
         $path = $uri->getPath();
     }
     if ($path !== '') {
         $path = rtrim($path, '/') . '/';
     }
     if (!($matches = String::match($path, $this->re))) {
         // stop, not matched
         return NULL;
     }
     // deletes numeric keys, restore '-' chars
     $params = array();
     foreach ($matches as $k => $v) {
         if (is_string($k) && $v !== '') {
             $params[str_replace('___', '-', $k)] = $v;
             // trick
         }
     }
     // 2) CONSTANT FIXITY
     foreach ($this->metadata as $name => $meta) {
         if (isset($params[$name])) {
             //$params[$name] = $this->flags & self::CASE_SENSITIVE === 0 ? strtolower($params[$name]) : */$params[$name]; // strtolower damages UTF-8
         } elseif (isset($meta['fixity']) && $meta['fixity'] !== self::OPTIONAL) {
             $params[$name] = NULL;
             // cannot be overwriten in 3) and detected by isset() in 4)
         }
     }
     // 3) QUERY
     if ($this->xlat) {
         $params += self::renameKeys($httpRequest->getQuery(), array_flip($this->xlat));
     } else {
         $params += $httpRequest->getQuery();
     }
     // 4) APPLY FILTERS & FIXITY
     foreach ($this->metadata as $name => $meta) {
         if (isset($params[$name])) {
             if (!is_scalar($params[$name])) {
             } elseif (isset($meta[self::FILTER_TABLE][$params[$name]])) {
                 // applyies filterTable only to scalar parameters
                 $params[$name] = $meta[self::FILTER_TABLE][$params[$name]];
             } elseif (isset($meta[self::FILTER_IN])) {
                 // applyies filterIn only to scalar parameters
                 $params[$name] = call_user_func($meta[self::FILTER_IN], (string) $params[$name]);
                 if ($params[$name] === NULL && !isset($meta['fixity'])) {
                     return NULL;
                     // rejected by filter
                 }
             }
         } elseif (isset($meta['fixity'])) {
             $params[$name] = $meta[self::VALUE];
         }
     }
     // 5) BUILD PresenterRequest
     if (!isset($params[self::PRESENTER_KEY])) {
         throw new \InvalidStateException('Missing presenter in route definition.');
     }
     if (isset($this->metadata[self::MODULE_KEY])) {
         if (!isset($params[self::MODULE_KEY])) {
             throw new \InvalidStateException('Missing module in route definition.');
         }
         $presenter = $params[self::MODULE_KEY] . ':' . $params[self::PRESENTER_KEY];
         unset($params[self::MODULE_KEY], $params[self::PRESENTER_KEY]);
     } else {
         $presenter = $params[self::PRESENTER_KEY];
         unset($params[self::PRESENTER_KEY]);
     }
     return new PresenterRequest($presenter, $httpRequest->getMethod(), $params, $httpRequest->getPost(), $httpRequest->getFiles(), array(PresenterRequest::SECURED => $httpRequest->isSecured()));
 }
Ejemplo n.º 10
0
	/**
	 * Builds HTML content.
	 * @return void
	 */
	protected function buildHtml()
	{
		if ($this->html instanceof Nette\Templates\ITemplate) {
			$this->html->mail = $this;
			if ($this->basePath === NULL && $this->html instanceof Nette\Templates\IFileTemplate) {
				$this->basePath = dirname($this->html->getFile());
			}
			$this->html = $this->html->__toString(TRUE);
		}

		if ($this->basePath !== FALSE) {
			$cids = array();
			$matches = String::matchAll($this->html, '#(src\s*=\s*|background\s*=\s*|url\()(["\'])(?![a-z]+:|[/\\#])(.+?)\\2#i', PREG_OFFSET_CAPTURE);
			foreach (array_reverse($matches) as $m)	{
				$file = rtrim($this->basePath, '/\\') . '/' . $m[3][0];
				$cid = isset($cids[$file]) ? $cids[$file] : $cids[$file] = substr($this->addEmbeddedFile($file)->getHeader("Content-ID"), 1, -1);
				$this->html = substr_replace($this->html, "{$m[1][0]}{$m[2][0]}cid:$cid{$m[2][0]}", $m[0][1], strlen($m[0][0]));
			}
		}

		if (!$this->getSubject() && $matches = String::match($this->html, '#<title>(.+?)</title>#is')) {
			$this->setSubject(html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8'));
		}
	}
Ejemplo n.º 11
0
 /**
  * {widget ...}
  */
 public function macroWidget($content)
 {
     $pair = LatteFilter::fetchToken($content);
     // widget[:method]
     if ($pair === NULL) {
         throw new \InvalidStateException("Missing widget name in {widget} on line {$this->filter->line}.");
     }
     $pair = explode(':', $pair, 2);
     $widget = LatteFilter::formatString($pair[0]);
     $method = isset($pair[1]) ? ucfirst($pair[1]) : '';
     $method = String::match($method, '#^(' . LatteFilter::RE_IDENTIFIER . '|)$#') ? "render{$method}" : "{\"render{$method}\"}";
     $param = LatteFilter::formatArray($content);
     if (strpos($content, '=>') === FALSE) {
         $param = substr($param, 6, -1);
     }
     // removes array()
     return ($widget[0] === '$' ? "if (is_object({$widget})) {$widget}->{$method}({$param}); else " : '') . "\$control->getWidget({$widget})->{$method}({$param})";
 }
Ejemplo n.º 12
0
 /**
  * @return string
  */
 public function getClassName()
 {
     return ($tmp = Nette\String::match($this, '#>\\s+([a-z0-9_\\\\]+)#i')) ? $tmp[1] : NULL;
 }
Ejemplo n.º 13
0
 /**
  * Reads single token (optionally delimited by comma) from string.
  * @param  string
  * @return string
  */
 public static function fetchToken(&$s)
 {
     if ($matches = String::match($s, '#^((?>' . self::RE_STRING . '|[^\'"\\s,]+)+)\\s*,?\\s*(.*)$#')) {
         // token [,] tail
         $s = $matches[2];
         return $matches[1];
     }
     return NULL;
 }
Ejemplo n.º 14
0
	/**
	 * Reads single token (optionally delimited by comma) from string.
	 * @param  string
	 * @return string
	 */
	public function fetchToken(& $s)
	{
		if ($matches = String::match($s, '#^((?>'.LatteFilter::RE_STRING.'|[^\'"\s,]+)+)\s*,?\s*(.*)$#s')) { // token [,] tail
			$s = $matches[2];
			return $matches[1];
		}
		return NULL;
	}
Ejemplo n.º 15
0
 /**
  * Changes current action. Only alphanumeric characters are allowed.
  * @param  string
  * @return void
  */
 public function changeAction($action)
 {
     if (Nette\String::match($action, "#^[a-zA-Z0-9][a-zA-Z0-9_-ÿ]*\$#")) {
         $this->action = $action;
         $this->view = $action;
     } else {
         throw new BadRequestException("Action name '{$action}' is not alphanumeric string.");
     }
 }
Ejemplo n.º 16
0
 /**
  * Analyse PHP file.
  * @param  string
  * @return void
  */
 private function scanScript($file)
 {
     $T_NAMESPACE = PHP_VERSION_ID < 50300 ? -1 : T_NAMESPACE;
     $T_NS_SEPARATOR = PHP_VERSION_ID < 50300 ? -1 : T_NS_SEPARATOR;
     $expected = FALSE;
     $namespace = '';
     $level = 0;
     $time = filemtime($file);
     $s = file_get_contents($file);
     if ($matches = String::match($s, '#//nette' . 'loader=(\\S*)#')) {
         foreach (explode(',', $matches[1]) as $name) {
             $this->addClass($name, $file, $time);
         }
         return;
     }
     foreach (token_get_all($s) as $token) {
         if (is_array($token)) {
             switch ($token[0]) {
                 case T_COMMENT:
                 case T_DOC_COMMENT:
                 case T_WHITESPACE:
                     continue 2;
                 case $T_NS_SEPARATOR:
                 case T_STRING:
                     if ($expected) {
                         $name .= $token[1];
                     }
                     continue 2;
                 case $T_NAMESPACE:
                 case T_CLASS:
                 case T_INTERFACE:
                     $expected = $token[0];
                     $name = '';
                     continue 2;
                 case T_CURLY_OPEN:
                 case T_DOLLAR_OPEN_CURLY_BRACES:
                     $level++;
             }
         }
         if ($expected) {
             switch ($expected) {
                 case T_CLASS:
                 case T_INTERFACE:
                     if ($level === 0) {
                         $this->addClass($namespace . $name, $file, $time);
                     }
                     break;
                 case $T_NAMESPACE:
                     $namespace = $name . '\\';
             }
             $expected = NULL;
         }
         if ($token === '{') {
             $level++;
         } elseif ($token === '}') {
             $level--;
         }
     }
 }
Ejemplo n.º 17
0
	private function parseCallback() {
		$line = $this->currentToken[2];
		if(String::match($this->currentToken[1], "/::/")) {
			$this->onOutput(self::OI_POSSIBLE_CALLBACK, array(
				self::FILE => $this->currentFile,
				self::LINE => $line,
				self::NAMESPACE_NAME => $this->namespace,
				self::VALUE => $this->currentToken[1],
			));
		}
	}