Namespaces

  • Nette
    • Application
      • Diagnostics
      • Responses
      • Routers
      • UI
    • Caching
      • Storages
    • ComponentModel
    • Config
      • Adapters
      • Extensions
    • Database
      • Diagnostics
      • Drivers
      • Reflection
      • Table
    • DI
      • Diagnostics
    • Diagnostics
    • Forms
      • Controls
      • Rendering
    • Http
    • Iterators
    • Latte
      • Macros
    • Loaders
    • Localization
    • Mail
    • Reflection
    • Security
      • Diagnostics
    • Templating
    • Utils
      • PhpGenerator
  • NetteModule
  • None
  • PHP

Classes

  • Control
  • Form
  • Multiplier
  • Presenter
  • PresenterComponent

Interfaces

  • IRenderable
  • ISignalReceiver
  • IStatePersistent

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