1: <?php
2:
3: 4: 5: 6:
7:
8: namespace Nette\Application;
9:
10: use Nette;
11:
12:
13: 14: 15:
16: class LinkGenerator extends Nette\Object
17: {
18:
19: private $router;
20:
21:
22: private $refUrl;
23:
24:
25: private $presenterFactory;
26:
27:
28: public function __construct(IRouter $router, Nette\Http\Url $refUrl, IPresenterFactory $presenterFactory = NULL)
29: {
30: $this->router = $router;
31: $this->refUrl = $refUrl;
32: $this->presenterFactory = $presenterFactory;
33: }
34:
35:
36: 37: 38: 39: 40: 41:
42: public function link($dest, array $params = array())
43: {
44: if (!preg_match('~^([\w:]+):(\w*+)(#.*)?()\z~', $dest, $m)) {
45: throw new UI\InvalidLinkException("Invalid link destination '$dest'.");
46: }
47: list(, $presenter, $action, $frag) = $m;
48:
49: try {
50: $class = $this->presenterFactory ? $this->presenterFactory->getPresenterClass($presenter) : NULL;
51: } catch (InvalidPresenterException $e) {
52: throw new UI\InvalidLinkException($e->getMessage(), NULL, $e);
53: }
54:
55: if (is_subclass_of($class, 'Nette\Application\UI\Presenter')) {
56: if ($action === '') {
57: $action = UI\Presenter::DEFAULT_ACTION;
58: }
59: if (method_exists($class, $method = $class::formatActionMethod($action))
60: || method_exists($class, $method = $class::formatRenderMethod($action))
61: ) {
62: UI\Presenter::argsToParams($class, $method, $params);
63: }
64: }
65:
66: if ($action !== '') {
67: $params[UI\Presenter::ACTION_KEY] = $action;
68: }
69:
70: $url = $this->router->constructUrl(new Request($presenter, NULL, $params), $this->refUrl);
71: if ($url === NULL) {
72: unset($params[UI\Presenter::ACTION_KEY]);
73: $params = urldecode(http_build_query($params, NULL, ', '));
74: throw new UI\InvalidLinkException("No route for $dest($params)");
75: }
76: return $url . $frag;
77: }
78:
79: }
80: