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