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