Namespaces

  • Nette
    • Application
    • Caching
    • Collections
    • Config
    • Forms
    • IO
    • Loaders
    • Mail
    • Reflection
    • Security
    • Templates
    • Web
  • None
  • PHP

Classes

  • AppForm
  • Application
  • CliRouter
  • Control
  • DownloadResponse
  • ForwardingResponse
  • JsonResponse
  • Link
  • MultiRouter
  • Presenter
  • PresenterComponent
  • PresenterLoader
  • PresenterRequest
  • RedirectingResponse
  • RenderResponse
  • Route
  • SimpleRouter

Interfaces

  • IPartiallyRenderable
  • IPresenter
  • IPresenterLoader
  • IPresenterResponse
  • IRenderable
  • IRouter
  • ISignalReceiver
  • IStatePersistent

Exceptions

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