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
      • Table
    • DI
      • Config
        • Adapters
      • Extensions
    • Forms
      • Controls
      • Rendering
    • Http
    • Iterators
    • Loaders
    • Localization
    • Mail
    • Neon
    • PhpGenerator
      • Traits
    • Reflection
    • Security
    • Tokenizer
    • Utils
  • Tracy
    • Bridges
      • Nette
  • none

Classes

  • Component
  • ComponentReflection
  • Control
  • Form
  • Link
  • MethodReflection
  • Multiplier
  • Presenter

Interfaces

  • IRenderable
  • ISignalReceiver
  • IStatePersistent
  • ITemplate
  • ITemplateFactory

Exceptions

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