1: <?php
2:
3: /**
4: * This file is part of the Nette Framework (http://nette.org)
5: * Copyright (c) 2004 David Grudl (http://davidgrudl.com)
6: */
7:
8: namespace Nette\Application\UI;
9:
10: use Nette;
11:
12:
13: /**
14: * Control is renderable Presenter component.
15: *
16: * @property-read ITemplate $template
17: * @property-read string $snippetId
18: */
19: abstract class Control extends PresenterComponent implements IRenderable
20: {
21: /** @var ITemplateFactory */
22: private $templateFactory;
23:
24: /** @var ITemplate */
25: private $template;
26:
27: /** @var array */
28: private $invalidSnippets = array();
29:
30: /** @var bool */
31: public $snippetMode;
32:
33:
34: /********************* template factory ****************d*g**/
35:
36:
37: public function setTemplateFactory(ITemplateFactory $templateFactory)
38: {
39: $this->templateFactory = $templateFactory;
40: }
41:
42:
43: /**
44: * @return ITemplate
45: */
46: public function getTemplate()
47: {
48: if ($this->template === NULL) {
49: $value = $this->createTemplate();
50: if (!$value instanceof ITemplate && $value !== NULL) {
51: $class2 = get_class($value); $class = get_class($this);
52: throw new Nette\UnexpectedValueException("Object returned by $class::createTemplate() must be instance of Nette\\Application\\UI\\ITemplate, '$class2' given.");
53: }
54: $this->template = $value;
55: }
56: return $this->template;
57: }
58:
59:
60: /**
61: * @return ITemplate
62: */
63: protected function createTemplate()
64: {
65: $templateFactory = $this->templateFactory ?: $this->getPresenter()->getTemplateFactory();
66: return $templateFactory->createTemplate($this);
67: }
68:
69:
70: /**
71: * Descendant can override this method to customize template compile-time filters.
72: * @param ITemplate
73: * @return void
74: */
75: public function templatePrepareFilters($template)
76: {
77: }
78:
79:
80: /**
81: * Saves the message to template, that can be displayed after redirect.
82: * @param string
83: * @param string
84: * @return \stdClass
85: */
86: public function flashMessage($message, $type = 'info')
87: {
88: $id = $this->getParameterId('flash');
89: $messages = $this->getPresenter()->getFlashSession()->$id;
90: $messages[] = $flash = (object) array(
91: 'message' => $message,
92: 'type' => $type,
93: );
94: $this->getTemplate()->flashes = $messages;
95: $this->getPresenter()->getFlashSession()->$id = $messages;
96: return $flash;
97: }
98:
99:
100: /********************* rendering ****************d*g**/
101:
102:
103: /**
104: * Forces control or its snippet to repaint.
105: * @return void
106: */
107: public function redrawControl($snippet = NULL, $redraw = TRUE)
108: {
109: if ($redraw) {
110: $this->invalidSnippets[$snippet === NULL ? "\0" : $snippet] = TRUE;
111:
112: } elseif ($snippet === NULL) {
113: $this->invalidSnippets = array();
114:
115: } else {
116: unset($this->invalidSnippets[$snippet]);
117: }
118: }
119:
120:
121: /** @deprecated */
122: function invalidateControl($snippet = NULL)
123: {
124: $this->redrawControl($snippet);
125: }
126:
127: /** @deprecated */
128: function validateControl($snippet = NULL)
129: {
130: $this->redrawControl($snippet, FALSE);
131: }
132:
133:
134: /**
135: * Is required to repaint the control or its snippet?
136: * @param string snippet name
137: * @return bool
138: */
139: public function isControlInvalid($snippet = NULL)
140: {
141: if ($snippet === NULL) {
142: if (count($this->invalidSnippets) > 0) {
143: return TRUE;
144:
145: } else {
146: $queue = array($this);
147: do {
148: foreach (array_shift($queue)->getComponents() as $component) {
149: if ($component instanceof IRenderable) {
150: if ($component->isControlInvalid()) {
151: // $this->invalidSnippets['__child'] = TRUE; // as cache
152: return TRUE;
153: }
154:
155: } elseif ($component instanceof Nette\ComponentModel\IContainer) {
156: $queue[] = $component;
157: }
158: }
159: } while ($queue);
160:
161: return FALSE;
162: }
163:
164: } else {
165: return isset($this->invalidSnippets["\0"]) || isset($this->invalidSnippets[$snippet]);
166: }
167: }
168:
169:
170: /**
171: * Returns snippet HTML ID.
172: * @param string snippet name
173: * @return string
174: */
175: public function getSnippetId($name = NULL)
176: {
177: // HTML 4 ID & NAME: [A-Za-z][A-Za-z0-9:_.-]*
178: return 'snippet-' . $this->getUniqueId() . '-' . $name;
179: }
180:
181: }
182: