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