Namespaces

  • Latte
    • Loaders
    • Macros
    • Runtime
  • Nette
    • Application
      • Responses
      • Routers
      • UI
    • Bridges
      • ApplicationDI
      • ApplicationLatte
      • ApplicationTracy
      • CacheDI
      • CacheLatte
      • DatabaseDI
      • DatabaseTracy
      • DITracy
      • FormsDI
      • FormsLatte
      • Framework
      • HttpDI
      • HttpTracy
      • MailDI
      • ReflectionDI
      • SecurityDI
      • SecurityTracy
    • Caching
      • Storages
    • ComponentModel
    • Database
      • Conventions
      • Drivers
      • Reflection
      • Table
    • DI
      • Config
        • Adapters
      • Extensions
    • Diagnostics
    • Forms
      • Controls
      • Rendering
    • Http
    • Iterators
    • Latte
    • Loaders
    • Localization
    • Mail
    • Neon
    • PhpGenerator
    • Reflection
    • Security
    • Templating
    • Utils
  • NetteModule
  • none
  • Tracy
    • Bridges
      • Nette

Classes

  • Control
  • Form
  • Multiplier
  • Presenter
  • PresenterComponent

Interfaces

  • IRenderable
  • ISignalReceiver
  • IStatePersistent
  • ITemplate
  • ITemplateFactory

Exceptions

  • BadSignalException
  • InvalidLinkException
  • Overview
  • Namespace
  • Class
  • Tree
  • Deprecated
  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:  * PresenterComponent is the base class for all Presenter components.
 15:  *
 16:  * Components are persistent objects located on a presenter. They have ability to own
 17:  * other child components, and interact with user. Components have properties
 18:  * for storing their status, and responds to user command.
 19:  *
 20:  * @property-read Presenter $presenter
 21:  * @property-read string $uniqueId
 22:  */
 23: abstract class PresenterComponent extends Nette\ComponentModel\Container implements ISignalReceiver, IStatePersistent, \ArrayAccess
 24: {
 25:     /** @var array */
 26:     protected $params = array();
 27: 
 28: 
 29:     /**
 30:      * Returns the presenter where this component belongs to.
 31:      * @param  bool   throw exception if presenter doesn't exist?
 32:      * @return Presenter|NULL
 33:      */
 34:     public function getPresenter($need = TRUE)
 35:     {
 36:         return $this->lookup('Nette\Application\UI\Presenter', $need);
 37:     }
 38: 
 39: 
 40:     /**
 41:      * Returns a fully-qualified name that uniquely identifies the component
 42:      * within the presenter hierarchy.
 43:      * @return string
 44:      */
 45:     public function getUniqueId()
 46:     {
 47:         return $this->lookupPath('Nette\Application\UI\Presenter', TRUE);
 48:     }
 49: 
 50: 
 51:     /**
 52:      * This method will be called when the component (or component's parent)
 53:      * becomes attached to a monitored object. Do not call this method yourself.
 54:      * @param  Nette\ComponentModel\IComponent
 55:      * @return void
 56:      */
 57:     protected function attached($presenter)
 58:     {
 59:         if ($presenter instanceof Presenter) {
 60:             $this->loadState($presenter->popGlobalParameters($this->getUniqueId()));
 61:         }
 62:     }
 63: 
 64: 
 65:     /**
 66:      * @return void
 67:      */
 68:     protected function validateParent(Nette\ComponentModel\IContainer $parent)
 69:     {
 70:         parent::validateParent($parent);
 71:         $this->monitor('Nette\Application\UI\Presenter');
 72:     }
 73: 
 74: 
 75:     /**
 76:      * Calls public method if exists.
 77:      * @param  string
 78:      * @param  array
 79:      * @return bool  does method exist?
 80:      */
 81:     protected function tryCall($method, array $params)
 82:     {
 83:         $rc = $this->getReflection();
 84:         if ($rc->hasMethod($method)) {
 85:             $rm = $rc->getMethod($method);
 86:             if ($rm->isPublic() && !$rm->isAbstract() && !$rm->isStatic()) {
 87:                 $this->checkRequirements($rm);
 88:                 $rm->invokeArgs($this, $rc->combineArgs($rm, $params));
 89:                 return TRUE;
 90:             }
 91:         }
 92:         return FALSE;
 93:     }
 94: 
 95: 
 96:     /**
 97:      * Checks for requirements such as authorization.
 98:      * @return void
 99:      */
100:     public function checkRequirements($element)
101:     {
102:     }
103: 
104: 
105:     /**
106:      * Access to reflection.
107:      * @return PresenterComponentReflection
108:      */
109:     public static function getReflection()
110:     {
111:         return new PresenterComponentReflection(get_called_class());
112:     }
113: 
114: 
115:     /********************* interface IStatePersistent ****************d*g**/
116: 
117: 
118:     /**
119:      * Loads state informations.
120:      * @param  array
121:      * @return void
122:      */
123:     public function loadState(array $params)
124:     {
125:         $reflection = $this->getReflection();
126:         foreach ($reflection->getPersistentParams() as $name => $meta) {
127:             if (isset($params[$name])) { // NULLs are ignored
128:                 $type = gettype($meta['def']);
129:                 if (!$reflection->convertType($params[$name], $type)) {
130:                     throw new Nette\Application\BadRequestException("Invalid value for persistent parameter '$name' in '{$this->getName()}', expected " . ($type === 'NULL' ? 'scalar' : $type) . ".");
131:                 }
132:                 $this->$name = $params[$name];
133:             } else {
134:                 $params[$name] = $this->$name;
135:             }
136:         }
137:         $this->params = $params;
138:     }
139: 
140: 
141:     /**
142:      * Saves state informations for next request.
143:      * @param  array
144:      * @param  PresenterComponentReflection (internal, used by Presenter)
145:      * @return void
146:      */
147:     public function saveState(array & $params, $reflection = NULL)
148:     {
149:         $reflection = $reflection === NULL ? $this->getReflection() : $reflection;
150:         foreach ($reflection->getPersistentParams() as $name => $meta) {
151: 
152:             if (isset($params[$name])) {
153:                 // injected value
154: 
155:             } elseif (array_key_exists($name, $params)) { // NULLs are skipped
156:                 continue;
157: 
158:             } elseif (!isset($meta['since']) || $this instanceof $meta['since']) {
159:                 $params[$name] = $this->$name; // object property value
160: 
161:             } else {
162:                 continue; // ignored parameter
163:             }
164: 
165:             $type = gettype($meta['def']);
166:             if (!PresenterComponentReflection::convertType($params[$name], $type)) {
167:                 throw new InvalidLinkException(sprintf("Invalid value for persistent parameter '%s' in '%s', expected %s.", $name, $this->getName(), $type === 'NULL' ? 'scalar' : $type));
168:             }
169: 
170:             if ($params[$name] === $meta['def'] || ($meta['def'] === NULL && is_scalar($params[$name]) && (string) $params[$name] === '')) {
171:                 $params[$name] = NULL; // value transmit is unnecessary
172:             }
173:         }
174:     }
175: 
176: 
177:     /**
178:      * Returns component param.
179:      * @param  string key
180:      * @param  mixed  default value
181:      * @return mixed
182:      */
183:     public function getParameter($name, $default = NULL)
184:     {
185:         if (isset($this->params[$name])) {
186:             return $this->params[$name];
187: 
188:         } else {
189:             return $default;
190:         }
191:     }
192: 
193: 
194:     /**
195:      * Returns component parameters.
196:      * @return array
197:      */
198:     public function getParameters()
199:     {
200:         return $this->params;
201:     }
202: 
203: 
204:     /**
205:      * Returns a fully-qualified name that uniquely identifies the parameter.
206:      * @param  string
207:      * @return string
208:      */
209:     public function getParameterId($name)
210:     {
211:         $uid = $this->getUniqueId();
212:         return $uid === '' ? $name : $uid . self::NAME_SEPARATOR . $name;
213:     }
214: 
215: 
216:     /** @deprecated */
217:     function getParam($name = NULL, $default = NULL)
218:     {
219:         //trigger_error(__METHOD__ . '() is deprecated; use getParameter() instead.', E_USER_DEPRECATED);
220:         return func_num_args() ? $this->getParameter($name, $default) : $this->getParameters();
221:     }
222: 
223: 
224:     /**
225:      * Returns array of classes persistent parameters. They have public visibility and are non-static.
226:      * This default implementation detects persistent parameters by annotation @persistent.
227:      * @return array
228:      */
229:     public static function getPersistentParams()
230:     {
231:         $rc = new \ReflectionClass(get_called_class());
232:         $params = array();
233:         foreach ($rc->getProperties(\ReflectionProperty::IS_PUBLIC) as $rp) {
234:             if (!$rp->isStatic() && PresenterComponentReflection::parseAnnotation($rp, 'persistent')) {
235:                 $params[] = $rp->getName();
236:             }
237:         }
238:         return $params;
239:     }
240: 
241: 
242:     /********************* interface ISignalReceiver ****************d*g**/
243: 
244: 
245:     /**
246:      * Calls signal handler method.
247:      * @param  string
248:      * @return void
249:      * @throws BadSignalException if there is not handler method
250:      */
251:     public function signalReceived($signal)
252:     {
253:         if (!$this->tryCall($this->formatSignalMethod($signal), $this->params)) {
254:             $class = get_class($this);
255:             throw new BadSignalException("There is no handler for signal '$signal' in class $class.");
256:         }
257:     }
258: 
259: 
260:     /**
261:      * Formats signal handler method name -> case sensitivity doesn't matter.
262:      * @param  string
263:      * @return string
264:      */
265:     public static function formatSignalMethod($signal)
266:     {
267:         return $signal == NULL ? NULL : 'handle' . $signal; // intentionally ==
268:     }
269: 
270: 
271:     /********************* navigation ****************d*g**/
272: 
273: 
274:     /**
275:      * Generates URL to presenter, action or signal.
276:      * @param  string   destination in format "[//] [[[module:]presenter:]action | signal! | this] [#fragment]"
277:      * @param  array|mixed
278:      * @return string
279:      * @throws InvalidLinkException
280:      */
281:     public function link($destination, $args = array())
282:     {
283:         try {
284:             return $this->getPresenter()->createRequest($this, $destination, is_array($args) ? $args : array_slice(func_get_args(), 1), 'link');
285: 
286:         } catch (InvalidLinkException $e) {
287:             return $this->getPresenter()->handleInvalidLink($e);
288:         }
289:     }
290: 
291: 
292:     /**
293:      * Returns destination as Link object.
294:      * @param  string   destination in format "[//] [[[module:]presenter:]action | signal! | this] [#fragment]"
295:      * @param  array|mixed
296:      * @return Link
297:      */
298:     public function lazyLink($destination, $args = array())
299:     {
300:         return new Link($this, $destination, is_array($args) ? $args : array_slice(func_get_args(), 1));
301:     }
302: 
303: 
304:     /**
305:      * Determines whether it links to the current page.
306:      * @param  string   destination in format "[//] [[[module:]presenter:]action | signal! | this] [#fragment]"
307:      * @param  array|mixed
308:      * @return bool
309:      * @throws InvalidLinkException
310:      */
311:     public function isLinkCurrent($destination = NULL, $args = array())
312:     {
313:         if ($destination !== NULL) {
314:             $this->getPresenter()->createRequest($this, $destination, is_array($args) ? $args : array_slice(func_get_args(), 1), 'test');
315:         }
316:         return $this->getPresenter()->getLastCreatedRequestFlag('current');
317:     }
318: 
319: 
320:     /**
321:      * Redirect to another presenter, action or signal.
322:      * @param  int      [optional] HTTP error code
323:      * @param  string   destination in format "[//] [[[module:]presenter:]action | signal! | this] [#fragment]"
324:      * @param  array|mixed
325:      * @return void
326:      * @throws Nette\Application\AbortException
327:      */
328:     public function redirect($code, $destination = NULL, $args = array())
329:     {
330:         if (!is_numeric($code)) { // first parameter is optional
331:             $args = is_array($destination) ? $destination : array_slice(func_get_args(), 1);
332:             $destination = $code;
333:             $code = NULL;
334: 
335:         } elseif (!is_array($args)) {
336:             $args = array_slice(func_get_args(), 2);
337:         }
338: 
339:         $presenter = $this->getPresenter();
340:         $presenter->redirectUrl($presenter->createRequest($this, $destination, $args, 'redirect'), $code);
341:     }
342: 
343: 
344:     /********************* interface \ArrayAccess ****************d*g**/
345: 
346: 
347:     /**
348:      * Adds the component to the container.
349:      * @param  string  component name
350:      * @param  Nette\ComponentModel\IComponent
351:      * @return void
352:      */
353:     public function offsetSet($name, $component)
354:     {
355:         $this->addComponent($component, $name);
356:     }
357: 
358: 
359:     /**
360:      * Returns component specified by name. Throws exception if component doesn't exist.
361:      * @param  string  component name
362:      * @return Nette\ComponentModel\IComponent
363:      * @throws Nette\InvalidArgumentException
364:      */
365:     public function offsetGet($name)
366:     {
367:         return $this->getComponent($name, TRUE);
368:     }
369: 
370: 
371:     /**
372:      * Does component specified by name exists?
373:      * @param  string  component name
374:      * @return bool
375:      */
376:     public function offsetExists($name)
377:     {
378:         return $this->getComponent($name, FALSE) !== NULL;
379:     }
380: 
381: 
382:     /**
383:      * Removes component from the container.
384:      * @param  string  component name
385:      * @return void
386:      */
387:     public function offsetUnset($name)
388:     {
389:         $component = $this->getComponent($name, FALSE);
390:         if ($component !== NULL) {
391:             $this->removeComponent($component);
392:         }
393:     }
394: 
395: }
396: 
Nette 2.3.4 API API documentation generated by ApiGen 2.8.0