PageRenderTime 112ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 1ms

/loader.php

https://github.com/romcok/google-translator
PHP | 5074 lines | 4868 code | 149 blank | 57 comment | 71 complexity | 19f157ee982ebd857664d4d39f093007 MD5 | raw file
  1. <?php //netteloader=IComponent
  2. /**
  3. * Nette Framework
  4. *
  5. * Copyright (c) 2004, 2010 David Grudl (http://davidgrudl.com)
  6. *
  7. * This source file is subject to the "Nette license" that is bundled
  8. * with this package in the file license.txt, and/or GPL license.
  9. *
  10. * For more information please see http://nettephp.com
  11. *
  12. * @copyright Copyright (c) 2004, 2010 David Grudl
  13. * @license http://nettephp.com/license Nette license
  14. * @link http://nettephp.com
  15. * @category Nette
  16. * @package Nette
  17. */
  18. if(version_compare(PHP_VERSION,'5.2.0','<')){throw
  19. new
  20. Exception('Nette Framework requires PHP 5.2.0 or newer.');}@set_magic_quotes_runtime(FALSE);function
  21. callback($callback,$m=NULL){return($m===NULL&&$callback
  22. instanceof
  23. Callback)?$callback:new
  24. Callback($callback,$m);}if(!function_exists('dump')){function
  25. dump($var){foreach(func_get_args()as$arg)Debug::dump($arg);return$var;}}interface
  26. IComponent{const
  27. NAME_SEPARATOR='-';function
  28. getName();function
  29. getParent();function
  30. setParent(IComponentContainer$parent=NULL,$name=NULL);}interface
  31. IComponentContainer
  32. extends
  33. IComponent{function
  34. addComponent(IComponent$component,$name);function
  35. removeComponent(IComponent$component);function
  36. getComponent($name);function
  37. getComponents($deep=FALSE,$filterType=NULL);}interface
  38. INamingContainer
  39. extends
  40. IComponentContainer{}interface
  41. ISignalReceiver{function
  42. signalReceived($signal);}interface
  43. IStatePersistent{function
  44. loadState(array$params);function
  45. saveState(array&$params);}interface
  46. IRenderable{function
  47. invalidateControl();function
  48. isControlInvalid();}interface
  49. IPartiallyRenderable
  50. extends
  51. IRenderable{}interface
  52. IPresenter{function
  53. run(PresenterRequest$request);}interface
  54. IPresenterLoader{function
  55. getPresenterClass(&$name);}interface
  56. IPresenterResponse{function
  57. send();}interface
  58. IRouter{const
  59. ONE_WAY=1;const
  60. SECURED=2;function
  61. match(IHttpRequest$httpRequest);function
  62. constructUrl(PresenterRequest$appRequest,IHttpRequest$httpRequest);}interface
  63. ICollection
  64. extends
  65. Countable,IteratorAggregate{function
  66. append($item);function
  67. remove($item);function
  68. clear();function
  69. contains($item);}interface
  70. IList
  71. extends
  72. ICollection,ArrayAccess{function
  73. indexOf($item);function
  74. insertAt($index,$item);}interface
  75. ICacheStorage{function
  76. read($key);function
  77. write($key,$data,array$dependencies);function
  78. remove($key);function
  79. clean(array$conds);}interface
  80. IMap
  81. extends
  82. ICollection,ArrayAccess{function
  83. add($key,$value);function
  84. search($item);function
  85. getKeys();}interface
  86. ISet
  87. extends
  88. ICollection{}interface
  89. IConfigAdapter{static
  90. function
  91. load($file,$section=NULL);static
  92. function
  93. save($config,$file,$section=NULL);}interface
  94. IFormControl{function
  95. loadHttpData();function
  96. setValue($value);function
  97. getValue();function
  98. getRules();function
  99. getErrors();function
  100. isDisabled();function
  101. translate($s,$count=NULL);}interface
  102. ISubmitterControl
  103. extends
  104. IFormControl{function
  105. isSubmittedBy();function
  106. getValidationScope();}interface
  107. IFormRenderer{function
  108. render(Form$form);}interface
  109. IDebuggable{function
  110. getPanels();}interface
  111. IServiceLocator{function
  112. addService($name,$service,$singleton=TRUE,array$options=NULL);function
  113. getService($name,array$options=NULL);function
  114. removeService($name);function
  115. hasService($name);}interface
  116. ITranslator{function
  117. translate($message,$count=NULL);}interface
  118. IMailer{function
  119. send(Mail$mail);}interface
  120. IAnnotation{function
  121. __construct(array$values);}interface
  122. IAuthenticator{const
  123. USERNAME='username';const
  124. PASSWORD='password';const
  125. IDENTITY_NOT_FOUND=1;const
  126. INVALID_CREDENTIAL=2;const
  127. FAILURE=3;const
  128. NOT_APPROVED=4;function
  129. authenticate(array$credentials);}interface
  130. IAuthorizator{const
  131. ALL=NULL;const
  132. ALLOW=TRUE;const
  133. DENY=FALSE;function
  134. isAllowed($role=self::ALL,$resource=self::ALL,$privilege=self::ALL);}interface
  135. IIdentity{function
  136. getName();function
  137. getRoles();}interface
  138. IPermissionAssertion{function
  139. assert(Permission$acl,$roleId,$resourceId,$privilege);}interface
  140. IResource{function
  141. getResourceId();}interface
  142. IRole{function
  143. getRoleId();}interface
  144. ITemplate{function
  145. render();}interface
  146. IFileTemplate
  147. extends
  148. ITemplate{function
  149. setFile($file);function
  150. getFile();}interface
  151. IHttpRequest{const
  152. GET='GET',POST='POST',HEAD='HEAD',PUT='PUT',DELETE='DELETE';function
  153. getUri();function
  154. getQuery($key=NULL,$default=NULL);function
  155. getPost($key=NULL,$default=NULL);function
  156. getPostRaw();function
  157. getFile($key);function
  158. getFiles();function
  159. getCookie($key,$default=NULL);function
  160. getCookies();function
  161. getMethod();function
  162. isMethod($method);function
  163. getHeader($header,$default=NULL);function
  164. getHeaders();function
  165. isSecured();function
  166. isAjax();function
  167. getRemoteAddress();function
  168. getRemoteHost();}interface
  169. IHttpResponse{const
  170. PERMANENT=2116333333;const
  171. BROWSER=0;const
  172. S200_OK=200,S204_NO_CONTENT=204,S300_MULTIPLE_CHOICES=300,S301_MOVED_PERMANENTLY=301,S302_FOUND=302,S303_SEE_OTHER=303,S303_POST_GET=303,S304_NOT_MODIFIED=304,S307_TEMPORARY_REDIRECT=307,S400_BAD_REQUEST=400,S401_UNAUTHORIZED=401,S403_FORBIDDEN=403,S404_NOT_FOUND=404,S405_METHOD_NOT_ALLOWED=405,S410_GONE=410,S500_INTERNAL_SERVER_ERROR=500,S501_NOT_IMPLEMENTED=501,S503_SERVICE_UNAVAILABLE=503;function
  173. setCode($code);function
  174. getCode();function
  175. setHeader($name,$value);function
  176. addHeader($name,$value);function
  177. setContentType($type,$charset=NULL);function
  178. redirect($url,$code=self::S302_FOUND);function
  179. setExpiration($seconds);function
  180. isSent();function
  181. getHeaders();function
  182. setCookie($name,$value,$expire,$path=NULL,$domain=NULL,$secure=NULL);function
  183. deleteCookie($name,$path=NULL,$domain=NULL,$secure=NULL);}interface
  184. IUser{function
  185. authenticate($username,$password,$extra=NULL);function
  186. signOut($clearIdentity=FALSE);function
  187. isAuthenticated();function
  188. getIdentity();function
  189. setAuthenticationHandler(IAuthenticator$handler);function
  190. getAuthenticationHandler();function
  191. setNamespace($namespace);function
  192. getNamespace();function
  193. getRoles();function
  194. isInRole($role);function
  195. isAllowed();function
  196. setAuthorizationHandler(IAuthorizator$handler);function
  197. getAuthorizationHandler();}class
  198. ArgumentOutOfRangeException
  199. extends
  200. InvalidArgumentException{}class
  201. InvalidStateException
  202. extends
  203. RuntimeException{function
  204. __construct($message='',$code=0,Exception$previous=NULL){if(version_compare(PHP_VERSION,'5.3','<')){$this->previous=$previous;parent::__construct($message,$code);}else{parent::__construct($message,$code,$previous);}}}class
  205. NotImplementedException
  206. extends
  207. LogicException{}class
  208. NotSupportedException
  209. extends
  210. LogicException{}class
  211. DeprecatedException
  212. extends
  213. NotSupportedException{}class
  214. MemberAccessException
  215. extends
  216. LogicException{}class
  217. IOException
  218. extends
  219. RuntimeException{}class
  220. FileNotFoundException
  221. extends
  222. IOException{}class
  223. DirectoryNotFoundException
  224. extends
  225. IOException{}class
  226. FatalErrorException
  227. extends
  228. Exception{private$severity;function
  229. __construct($message,$code,$severity,$file,$line,$context){parent::__construct($message,$code);$this->severity=$severity;$this->file=$file;$this->line=$line;$this->context=$context;}function
  230. getSeverity(){return$this->severity;}}final
  231. class
  232. Framework{const
  233. NAME='Nette Framework';const
  234. VERSION='0.9.3';const
  235. REVISION='cc750ea released on 2010-01-28';const
  236. PACKAGE='PHP 5.2';final
  237. function
  238. __construct(){throw
  239. new
  240. LogicException("Cannot instantiate static class ".get_class($this));}static
  241. function
  242. compareVersion($version){return
  243. version_compare($version,self::VERSION);}static
  244. function
  245. promo($xhtml=TRUE){echo'<a href="http://nettephp.com/" title="Nette Framework - The Most Innovative PHP Framework"><img ','src="http://nettephp.com/images/nette-powered.gif" alt="Powered by Nette Framework" width="80" height="15"',($xhtml?' />':'>'),'</a>';}static
  246. function
  247. fixNamespace(&$class){if($a=strrpos($class,'\\')){$class=substr($class,$a+1);}}}abstract
  248. class
  249. Object{function
  250. getClass(){trigger_error(__METHOD__.'() is deprecated; use getReflection()->getName() instead.',E_USER_WARNING);return
  251. get_class($this);}function
  252. getReflection(){return
  253. new
  254. ClassReflection($this);}function
  255. __call($name,$args){return
  256. ObjectMixin::call($this,$name,$args);}static
  257. function
  258. __callStatic($name,$args){$class=get_called_class();throw
  259. new
  260. MemberAccessException("Call to undefined static method $class::$name().");}static
  261. function
  262. extensionMethod($name,$callback=NULL){if(strpos($name,'::')===FALSE){$class=get_called_class();}else{list($class,$name)=explode('::',$name);}$class=new
  263. ClassReflection($class);if($callback===NULL){return$class->getExtensionMethod($name);}else{$class->setExtensionMethod($name,$callback);}}function&__get($name){return
  264. ObjectMixin::get($this,$name);}function
  265. __set($name,$value){return
  266. ObjectMixin::set($this,$name,$value);}function
  267. __isset($name){return
  268. ObjectMixin::has($this,$name);}function
  269. __unset($name){throw
  270. new
  271. MemberAccessException("Cannot unset the property {$this->reflection->name}::\$$name.");}}final
  272. class
  273. ObjectMixin{private
  274. static$methods;final
  275. function
  276. __construct(){throw
  277. new
  278. LogicException("Cannot instantiate static class ".get_class($this));}static
  279. function
  280. call($_this,$name,$args){$class=new
  281. ClassReflection($_this);if($name===''){throw
  282. new
  283. MemberAccessException("Call to class '$class->name' method without name.");}if($class->hasEventProperty($name)){if(is_array($list=$_this->$name)||$list
  284. instanceof
  285. Traversable){foreach($list
  286. as$handler){callback($handler)->invokeArgs($args);}}return
  287. NULL;}if($cb=$class->getExtensionMethod($name)){array_unshift($args,$_this);return$cb->invokeArgs($args);}throw
  288. new
  289. MemberAccessException("Call to undefined method $class->name::$name().");}static
  290. function&get($_this,$name){$class=get_class($_this);if($name===''){throw
  291. new
  292. MemberAccessException("Cannot read a class '$class' property without name.");}if(!isset(self::$methods[$class])){self::$methods[$class]=array_flip(get_class_methods($class));}$name[0]=$name[0]&"\xDF";$m='get'.$name;if(isset(self::$methods[$class][$m])){$val=$_this->$m();return$val;}$m='is'.$name;if(isset(self::$methods[$class][$m])){$val=$_this->$m();return$val;}$name=func_get_arg(1);throw
  293. new
  294. MemberAccessException("Cannot read an undeclared property $class::\$$name.");}static
  295. function
  296. set($_this,$name,$value){$class=get_class($_this);if($name===''){throw
  297. new
  298. MemberAccessException("Cannot assign to a class '$class' property without name.");}if(!isset(self::$methods[$class])){self::$methods[$class]=array_flip(get_class_methods($class));}$name[0]=$name[0]&"\xDF";if(isset(self::$methods[$class]['get'.$name])||isset(self::$methods[$class]['is'.$name])){$m='set'.$name;if(isset(self::$methods[$class][$m])){$_this->$m($value);return;}else{$name=func_get_arg(1);throw
  299. new
  300. MemberAccessException("Cannot assign to a read-only property $class::\$$name.");}}$name=func_get_arg(1);throw
  301. new
  302. MemberAccessException("Cannot assign to an undeclared property $class::\$$name.");}static
  303. function
  304. has($_this,$name){if($name===''){return
  305. FALSE;}$class=get_class($_this);if(!isset(self::$methods[$class])){self::$methods[$class]=array_flip(get_class_methods($class));}$name[0]=$name[0]&"\xDF";return
  306. isset(self::$methods[$class]['get'.$name])||isset(self::$methods[$class]['is'.$name]);}}final
  307. class
  308. Callback
  309. extends
  310. Object{private$cb;public
  311. static$fix520;public
  312. static$checkImmediately=FALSE;function
  313. __construct($t,$m=NULL){if($m===NULL){$this->cb=$t;}else{$this->cb=array($t,$m);}if(is_object($this->cb)){$this->cb=array($this->cb,'__invoke');}elseif(self::$fix520){if(is_string($this->cb)&&strpos($this->cb,':')){$this->cb=explode('::',$this->cb);}if(is_array($this->cb)&&is_string($this->cb[0])&&$a=strrpos($this->cb[0],'\\')){$this->cb[0]=substr($this->cb[0],$a+1);}}else{if(is_string($this->cb)&&$a=strrpos($this->cb,'\\')){$this->cb=substr($this->cb,$a+1);}elseif(is_array($this->cb)&&is_string($this->cb[0])&&$a=strrpos($this->cb[0],'\\')){$this->cb[0]=substr($this->cb[0],$a+1);}}if(!is_callable($this->cb,!self::$checkImmediately)){throw
  314. new
  315. InvalidArgumentException("Invalid callback.");}}function
  316. __invoke(){if(!is_callable($this->cb)){throw
  317. new
  318. InvalidStateException("Callback '$this' is not callable.");}$args=func_get_args();return
  319. call_user_func_array($this->cb,$args);}function
  320. invoke(){if(!is_callable($this->cb)){throw
  321. new
  322. InvalidStateException("Callback '$this' is not callable.");}$args=func_get_args();return
  323. call_user_func_array($this->cb,$args);}function
  324. invokeArgs(array$args){if(!is_callable($this->cb)){throw
  325. new
  326. InvalidStateException("Callback '$this' is not callable.");}return
  327. call_user_func_array($this->cb,$args);}function
  328. isCallable(){return
  329. is_callable($this->cb);}function
  330. getNative(){return$this->cb;}function
  331. __toString(){is_callable($this->cb,TRUE,$textual);return$textual;}}Callback::$fix520=version_compare(PHP_VERSION,'5.2.2','<');final
  332. class
  333. LimitedScope{private
  334. static$vars;final
  335. function
  336. __construct(){throw
  337. new
  338. LogicException("Cannot instantiate static class ".get_class($this));}static
  339. function
  340. evaluate(){if(func_num_args()>1){extract(func_get_arg(1));}return
  341. eval('?>'.func_get_arg(0));}static
  342. function
  343. load(){if(func_num_args()>1){extract(func_get_arg(1));}return include func_get_arg(0);}}abstract
  344. class
  345. AutoLoader
  346. extends
  347. Object{static
  348. private$loaders=array();public
  349. static$count=0;final
  350. static
  351. function
  352. load($type){foreach(func_get_args()as$type){if(!class_exists($type)){throw
  353. new
  354. InvalidStateException("Unable to load class or interface '$type'.");}}}final
  355. static
  356. function
  357. getLoaders(){return
  358. array_values(self::$loaders);}function
  359. register(){if(!function_exists('spl_autoload_register')){throw
  360. new
  361. RuntimeException('spl_autoload does not exist in this PHP installation.');}spl_autoload_register(array($this,'tryLoad'));self::$loaders[spl_object_hash($this)]=$this;}function
  362. unregister(){unset(self::$loaders[spl_object_hash($this)]);return
  363. spl_autoload_unregister(array($this,'tryLoad'));}abstract
  364. function
  365. tryLoad($type);}final
  366. class
  367. Annotations{public
  368. static$useReflection;static
  369. function
  370. has(Reflector$r,$name){trigger_error(__METHOD__.'() is deprecated; use getReflection()->hasAnnotation() instead.',E_USER_WARNING);$cache=AnnotationsParser::getAll($r);return!empty($cache[$name]);}static
  371. function
  372. get(Reflector$r,$name){trigger_error(__METHOD__.'() is deprecated; use getReflection()->getAnnotation() instead.',E_USER_WARNING);$cache=AnnotationsParser::getAll($r);return
  373. isset($cache[$name])?end($cache[$name]):NULL;}static
  374. function
  375. getAll(Reflector$r,$name=NULL){trigger_error(__METHOD__.'() is deprecated; use getReflection()->getAnnotations() instead.',E_USER_WARNING);$cache=AnnotationsParser::getAll($r);if($name===NULL){return$cache;}elseif(isset($cache[$name])){return$cache[$name];}else{return
  376. array();}}}abstract
  377. class
  378. Component
  379. extends
  380. Object
  381. implements
  382. IComponent{private$parent;private$name;private$monitors=array();function
  383. __construct(IComponentContainer$parent=NULL,$name=NULL){if($parent!==NULL){$parent->addComponent($this,$name);}elseif(is_string($name)){$this->name=$name;}}function
  384. lookup($type,$need=TRUE){Framework::fixNamespace($type);if(!isset($this->monitors[$type])){$obj=$this->parent;$path=self::NAME_SEPARATOR.$this->name;$depth=1;while($obj!==NULL){if($obj
  385. instanceof$type)break;$path=self::NAME_SEPARATOR.$obj->getName().$path;$depth++;$obj=$obj->getParent();if($obj===$this)$obj=NULL;}if($obj){$this->monitors[$type]=array($obj,$depth,substr($path,1),FALSE);}else{$this->monitors[$type]=array(NULL,NULL,NULL,FALSE);}}if($need&&$this->monitors[$type][0]===NULL){throw
  386. new
  387. InvalidStateException("Component '$this->name' is not attached to '$type'.");}return$this->monitors[$type][0];}function
  388. lookupPath($type,$need=TRUE){Framework::fixNamespace($type);$this->lookup($type,$need);return$this->monitors[$type][2];}function
  389. monitor($type){Framework::fixNamespace($type);if(empty($this->monitors[$type][3])){if($obj=$this->lookup($type,FALSE)){$this->attached($obj);}$this->monitors[$type][3]=TRUE;}}function
  390. unmonitor($type){Framework::fixNamespace($type);unset($this->monitors[$type]);}protected
  391. function
  392. attached($obj){}protected
  393. function
  394. detached($obj){}final
  395. function
  396. getName(){return$this->name;}final
  397. function
  398. getParent(){return$this->parent;}function
  399. setParent(IComponentContainer$parent=NULL,$name=NULL){if($parent===NULL&&$this->parent===NULL&&$name!==NULL){$this->name=$name;return$this;}elseif($parent===$this->parent&&$name===NULL){return$this;}if($this->parent!==NULL&&$parent!==NULL){throw
  400. new
  401. InvalidStateException("Component '$this->name' already has a parent.");}if($parent===NULL){$this->refreshMonitors(0);$this->parent=NULL;}else{$this->validateParent($parent);$this->parent=$parent;if($name!==NULL)$this->name=$name;$tmp=array();$this->refreshMonitors(0,$tmp);}return$this;}protected
  402. function
  403. validateParent(IComponentContainer$parent){}private
  404. function
  405. refreshMonitors($depth,&$missing=NULL,&$listeners=array()){if($this
  406. instanceof
  407. IComponentContainer){foreach($this->getComponents()as$component){if($component
  408. instanceof
  409. Component){$component->refreshMonitors($depth+1,$missing,$listeners);}}}if($missing===NULL){foreach($this->monitors
  410. as$type=>$rec){if(isset($rec[1])&&$rec[1]>$depth){if($rec[3]){$this->monitors[$type]=array(NULL,NULL,NULL,TRUE);$listeners[]=array($this,$rec[0]);}else{unset($this->monitors[$type]);}}}}else{foreach($this->monitors
  411. as$type=>$rec){if(isset($rec[0])){continue;}elseif(!$rec[3]){unset($this->monitors[$type]);}elseif(isset($missing[$type])){$this->monitors[$type]=array(NULL,NULL,NULL,TRUE);}else{$this->monitors[$type]=NULL;if($obj=$this->lookup($type,FALSE)){$listeners[]=array($this,$obj);}else{$missing[$type]=TRUE;}$this->monitors[$type][3]=TRUE;}}}if($depth===0){$method=$missing===NULL?'detached':'attached';foreach($listeners
  412. as$item){$item[0]->$method($item[1]);}}}function
  413. __clone(){if($this->parent===NULL){return;}elseif($this->parent
  414. instanceof
  415. ComponentContainer){$this->parent=$this->parent->_isCloning();if($this->parent===NULL){$this->refreshMonitors(0);}}else{$this->parent=NULL;$this->refreshMonitors(0);}}final
  416. function
  417. __wakeup(){throw
  418. new
  419. NotImplementedException;}}class
  420. ComponentContainer
  421. extends
  422. Component
  423. implements
  424. IComponentContainer{private$components=array();private$cloning;function
  425. addComponent(IComponent$component,$name,$insertBefore=NULL){if($name===NULL){$name=$component->getName();}if(is_int($name)){$name=(string)$name;}elseif(!is_string($name)){throw
  426. new
  427. InvalidArgumentException("Component name must be integer or string, ".gettype($name)." given.");}elseif(!preg_match('#^[a-zA-Z0-9_]+$#',$name)){throw
  428. new
  429. InvalidArgumentException("Component name must be non-empty alphanumeric string, '$name' given.");}if(isset($this->components[$name])){throw
  430. new
  431. InvalidStateException("Component with name '$name' already exists.");}$obj=$this;do{if($obj===$component){throw
  432. new
  433. InvalidStateException("Circular reference detected while adding component '$name'.");}$obj=$obj->getParent();}while($obj!==NULL);$this->validateChildComponent($component);try{if(isset($this->components[$insertBefore])){$tmp=array();foreach($this->components
  434. as$k=>$v){if($k===$insertBefore)$tmp[$name]=$component;$tmp[$k]=$v;}$this->components=$tmp;}else{$this->components[$name]=$component;}$component->setParent($this,$name);}catch(Exception$e){unset($this->components[$name]);throw$e;}}function
  435. removeComponent(IComponent$component){$name=$component->getName();if(!isset($this->components[$name])||$this->components[$name]!==$component){throw
  436. new
  437. InvalidArgumentException("Component named '$name' is not located in this container.");}unset($this->components[$name]);$component->setParent(NULL);}final
  438. function
  439. getComponent($name,$need=TRUE){if(is_int($name)){$name=(string)$name;}elseif(!is_string($name)){throw
  440. new
  441. InvalidArgumentException("Component name must be integer or string, ".gettype($name)." given.");}else{$a=strpos($name,self::NAME_SEPARATOR);if($a!==FALSE){$ext=(string)substr($name,$a+1);$name=substr($name,0,$a);}if($name===''){throw
  442. new
  443. InvalidArgumentException("Component or subcomponent name must not be empty string.");}}if(!isset($this->components[$name])){$component=$this->createComponent($name);if($component
  444. instanceof
  445. IComponent&&$component->getParent()===NULL){$this->addComponent($component,$name);}}if(isset($this->components[$name])){if(!isset($ext)){return$this->components[$name];}elseif($this->components[$name]instanceof
  446. IComponentContainer){return$this->components[$name]->getComponent($ext,$need);}elseif($need){throw
  447. new
  448. InvalidArgumentException("Component with name '$name' is not container and cannot have '$ext' component.");}}elseif($need){throw
  449. new
  450. InvalidArgumentException("Component with name '$name' does not exist.");}}protected
  451. function
  452. createComponent($name){$ucname=ucfirst($name);$method='createComponent'.$ucname;if($ucname!==$name&&method_exists($this,$method)&&$this->getReflection()->getMethod($method)->getName()===$method){return$this->$method($name);}}final
  453. function
  454. getComponents($deep=FALSE,$filterType=NULL){$iterator=new
  455. RecursiveComponentIterator($this->components);if($deep){$deep=$deep>0?RecursiveIteratorIterator::SELF_FIRST:RecursiveIteratorIterator::CHILD_FIRST;$iterator=new
  456. RecursiveIteratorIterator($iterator,$deep);}if($filterType){Framework::fixNamespace($filterType);$iterator=new
  457. InstanceFilterIterator($iterator,$filterType);}return$iterator;}protected
  458. function
  459. validateChildComponent(IComponent$child){}function
  460. __clone(){if($this->components){$oldMyself=reset($this->components)->getParent();$oldMyself->cloning=$this;foreach($this->components
  461. as$name=>$component){$this->components[$name]=clone$component;}$oldMyself->cloning=NULL;}parent::__clone();}function
  462. _isCloning(){return$this->cloning;}}class
  463. RecursiveComponentIterator
  464. extends
  465. RecursiveArrayIterator
  466. implements
  467. Countable{function
  468. hasChildren(){return$this->current()instanceof
  469. IComponentContainer;}function
  470. getChildren(){return$this->current()->getComponents();}function
  471. count(){return
  472. iterator_count($this);}}class
  473. FormContainer
  474. extends
  475. ComponentContainer
  476. implements
  477. ArrayAccess,INamingContainer{public$onValidate;protected$currentGroup;protected$valid;function
  478. setDefaults($values,$erase=FALSE){$form=$this->getForm(FALSE);if(!$form||!$form->isAnchored()||!$form->isSubmitted()){$this->setValues($values,$erase);}return$this;}function
  479. setValues($values,$erase=FALSE){if($values
  480. instanceof
  481. Traversable){$values=iterator_to_array($values);}elseif(!is_array($values)){throw
  482. new
  483. InvalidArgumentException("Values must be an array, ".gettype($values)." given.");}$cursor=&$values;$iterator=$this->getComponents(TRUE);foreach($iterator
  484. as$name=>$control){$sub=$iterator->getSubIterator();if(!isset($sub->cursor)){$sub->cursor=&$cursor;}if($control
  485. instanceof
  486. IFormControl){if((is_array($sub->cursor)||$sub->cursor
  487. instanceof
  488. ArrayAccess)&&array_key_exists($name,$sub->cursor)){$control->setValue($sub->cursor[$name]);}elseif($erase){$control->setValue(NULL);}}if($control
  489. instanceof
  490. INamingContainer){if((is_array($sub->cursor)||$sub->cursor
  491. instanceof
  492. ArrayAccess)&&isset($sub->cursor[$name])){$cursor=&$sub->cursor[$name];}else{unset($cursor);$cursor=NULL;}}}return$this;}function
  493. getValues(){$values=array();$cursor=&$values;$iterator=$this->getComponents(TRUE);foreach($iterator
  494. as$name=>$control){$sub=$iterator->getSubIterator();if(!isset($sub->cursor)){$sub->cursor=&$cursor;}if($control
  495. instanceof
  496. IFormControl&&!$control->isDisabled()&&!($control
  497. instanceof
  498. ISubmitterControl)){$sub->cursor[$name]=$control->getValue();}if($control
  499. instanceof
  500. INamingContainer){$cursor=&$sub->cursor[$name];$cursor=array();}}return$values;}function
  501. isValid(){if($this->valid===NULL){$this->validate();}return$this->valid;}function
  502. validate(){$this->valid=TRUE;$this->onValidate($this);foreach($this->getControls()as$control){if(!$control->getRules()->validate()){$this->valid=FALSE;}}}function
  503. setCurrentGroup(FormGroup$group=NULL){$this->currentGroup=$group;return$this;}function
  504. addComponent(IComponent$component,$name,$insertBefore=NULL){parent::addComponent($component,$name,$insertBefore);if($this->currentGroup!==NULL&&$component
  505. instanceof
  506. IFormControl){$this->currentGroup->add($component);}}function
  507. getControls(){return$this->getComponents(TRUE,'Nette\Forms\IFormControl');}function
  508. getForm($need=TRUE){return$this->lookup('Nette\Forms\Form',$need);}function
  509. addText($name,$label=NULL,$cols=NULL,$maxLength=NULL){return$this[$name]=new
  510. TextInput($label,$cols,$maxLength);}function
  511. addPassword($name,$label=NULL,$cols=NULL,$maxLength=NULL){$control=new
  512. TextInput($label,$cols,$maxLength);$control->setPasswordMode(TRUE);$this->addComponent($control,$name);return$control;}function
  513. addTextArea($name,$label=NULL,$cols=40,$rows=10){return$this[$name]=new
  514. TextArea($label,$cols,$rows);}function
  515. addFile($name,$label=NULL){return$this[$name]=new
  516. FileUpload($label);}function
  517. addHidden($name){return$this[$name]=new
  518. HiddenField;}function
  519. addCheckbox($name,$caption){return$this[$name]=new
  520. Checkbox($caption);}function
  521. addRadioList($name,$label=NULL,array$items=NULL){return$this[$name]=new
  522. RadioList($label,$items);}function
  523. addSelect($name,$label=NULL,array$items=NULL,$size=NULL){return$this[$name]=new
  524. SelectBox($label,$items,$size);}function
  525. addMultiSelect($name,$label=NULL,array$items=NULL,$size=NULL){return$this[$name]=new
  526. MultiSelectBox($label,$items,$size);}function
  527. addSubmit($name,$caption){return$this[$name]=new
  528. SubmitButton($caption);}function
  529. addButton($name,$caption){return$this[$name]=new
  530. Button($caption);}function
  531. addImage($name,$src=NULL,$alt=NULL){return$this[$name]=new
  532. ImageButton($src,$alt);}function
  533. addContainer($name){$control=new
  534. FormContainer;$control->currentGroup=$this->currentGroup;return$this[$name]=$control;}final
  535. function
  536. offsetSet($name,$component){$this->addComponent($component,$name);}final
  537. function
  538. offsetGet($name){return$this->getComponent($name,TRUE);}final
  539. function
  540. offsetExists($name){return$this->getComponent($name,FALSE)!==NULL;}final
  541. function
  542. offsetUnset($name){$component=$this->getComponent($name,FALSE);if($component!==NULL){$this->removeComponent($component);}}final
  543. function
  544. __clone(){throw
  545. new
  546. NotImplementedException('Form cloning is not supported yet.');}}class
  547. Form
  548. extends
  549. FormContainer{const
  550. EQUAL=':equal';const
  551. IS_IN=':equal';const
  552. FILLED=':filled';const
  553. VALID=':valid';const
  554. SUBMITTED=':submitted';const
  555. MIN_LENGTH=':minLength';const
  556. MAX_LENGTH=':maxLength';const
  557. LENGTH=':length';const
  558. EMAIL=':email';const
  559. URL=':url';const
  560. REGEXP=':regexp';const
  561. INTEGER=':integer';const
  562. NUMERIC=':integer';const
  563. FLOAT=':float';const
  564. RANGE=':range';const
  565. MAX_FILE_SIZE=':fileSize';const
  566. MIME_TYPE=':mimeType';const
  567. SCRIPT='Nette\Forms\InstantClientScript::javascript';const
  568. GET='get';const
  569. POST='post';const
  570. TRACKER_ID='_form_';const
  571. PROTECTOR_ID='_token_';public$onSubmit;public$onInvalidSubmit;private$submittedBy;private$httpData;private$element;private$renderer;private$translator;private$groups=array();private$errors=array();private$encoding='UTF-8';function
  572. __construct($name=NULL){$this->element=Html::el('form');$this->element->action='';$this->element->method=self::POST;$this->monitor(__CLASS__);if($name!==NULL){$tracker=new
  573. HiddenField($name);$tracker->unmonitor(__CLASS__);$this[self::TRACKER_ID]=$tracker;}parent::__construct(NULL,$name);}protected
  574. function
  575. attached($obj){if($obj
  576. instanceof
  577. self){throw
  578. new
  579. InvalidStateException('Nested forms are forbidden.');}}final
  580. function
  581. getForm($need=TRUE){return$this;}function
  582. setAction($url){$this->element->action=$url;return$this;}function
  583. getAction(){return$this->element->action;}function
  584. setMethod($method){if($this->httpData!==NULL){throw
  585. new
  586. InvalidStateException(__METHOD__.'() must be called until the form is empty.');}$this->element->method=strtolower($method);return$this;}function
  587. getMethod(){return$this->element->method;}function
  588. addTracker(){throw
  589. new
  590. DeprecatedException(__METHOD__.'() is deprecated; pass form name to the constructor.');}function
  591. addProtection($message=NULL,$timeout=NULL){$session=$this->getSession()->getNamespace('Nette.Forms.Form/CSRF');$key="key$timeout";if(isset($session->$key)){$token=$session->$key;}else{$session->$key=$token=md5(uniqid('',TRUE));}$session->setExpiration($timeout,$key);$this[self::PROTECTOR_ID]=new
  592. HiddenField($token);$this[self::PROTECTOR_ID]->addRule(':equal',empty($message)?'Security token did not match. Possible CSRF attack.':$message,$token);}function
  593. addGroup($caption=NULL,$setAsCurrent=TRUE){$group=new
  594. FormGroup;$group->setOption('label',$caption);$group->setOption('visual',TRUE);if($setAsCurrent){$this->setCurrentGroup($group);}if(isset($this->groups[$caption])){return$this->groups[]=$group;}else{return$this->groups[$caption]=$group;}}function
  595. removeGroup($name){if(is_string($name)&&isset($this->groups[$name])){$group=$this->groups[$name];}elseif($name
  596. instanceof
  597. FormGroup&&in_array($name,$this->groups,TRUE)){$group=$name;$name=array_search($group,$this->groups,TRUE);}else{throw
  598. new
  599. InvalidArgumentException("Group not found in form '$this->name'");}foreach($group->getControls()as$control){$this->removeComponent($control);}unset($this->groups[$name]);}function
  600. getGroups(){return$this->groups;}function
  601. getGroup($name){return
  602. isset($this->groups[$name])?$this->groups[$name]:NULL;}function
  603. setEncoding($value){$this->encoding=empty($value)?'UTF-8':strtoupper($value);if($this->encoding!=='UTF-8'&&!extension_loaded('mbstring')){throw
  604. new
  605. Exception("The PHP extension 'mbstring' is required for this encoding but is not loaded.");}return$this;}final
  606. function
  607. getEncoding(){return$this->encoding;}function
  608. setTranslator(ITranslator$translator=NULL){$this->translator=$translator;return$this;}final
  609. function
  610. getTranslator(){return$this->translator;}function
  611. isAnchored(){return
  612. TRUE;}final
  613. function
  614. isSubmitted(){if($this->submittedBy===NULL){$this->getHttpData();$this->submittedBy=!empty($this->httpData);}return$this->submittedBy;}function
  615. setSubmittedBy(ISubmitterControl$by=NULL){$this->submittedBy=$by===NULL?FALSE:$by;return$this;}final
  616. function
  617. getHttpData(){if($this->httpData===NULL){if(!$this->isAnchored()){throw
  618. new
  619. InvalidStateException('Form is not anchored and therefore can not determine whether it was submitted.');}$this->httpData=(array)$this->receiveHttpData();}return$this->httpData;}function
  620. fireEvents(){if(!$this->isSubmitted()){return;}elseif($this->submittedBy
  621. instanceof
  622. ISubmitterControl){if(!$this->submittedBy->getValidationScope()||$this->isValid()){$this->submittedBy->click();$this->onSubmit($this);}else{$this->submittedBy->onInvalidClick($this->submittedBy);$this->onInvalidSubmit($this);}}elseif($this->isValid()){$this->onSubmit($this);}else{$this->onInvalidSubmit($this);}}protected
  623. function
  624. receiveHttpData(){$httpRequest=$this->getHttpRequest();if(strcasecmp($this->getMethod(),$httpRequest->getMethod())){return;}$httpRequest->setEncoding($this->encoding);if($httpRequest->isMethod('post')){$data=ArrayTools::mergeTree($httpRequest->getPost(),$httpRequest->getFiles());}else{$data=$httpRequest->getQuery();}if($tracker=$this->getComponent(self::TRACKER_ID,FALSE)){if(!isset($data[self::TRACKER_ID])||$data[self::TRACKER_ID]!==$tracker->getValue()){return;}}return$data;}function
  625. processHttpRequest(){trigger_error(__METHOD__.'() is deprecated; use fireEvents() instead.',E_USER_WARNING);$this->fireEvents();}function
  626. getValues(){$values=parent::getValues();unset($values[self::TRACKER_ID],$values[self::PROTECTOR_ID]);return$values;}function
  627. addError($message){$this->valid=FALSE;if($message!==NULL&&!in_array($message,$this->errors,TRUE)){$this->errors[]=$message;}}function
  628. getErrors(){return$this->errors;}function
  629. hasErrors(){return(bool)$this->getErrors();}function
  630. cleanErrors(){$this->errors=array();$this->valid=NULL;}function
  631. getElementPrototype(){return$this->element;}function
  632. setRenderer(IFormRenderer$renderer){$this->renderer=$renderer;return$this;}final
  633. function
  634. getRenderer(){if($this->renderer===NULL){$this->renderer=new
  635. ConventionalRenderer;}return$this->renderer;}function
  636. render(){$args=func_get_args();array_unshift($args,$this);$s=call_user_func_array(array($this->getRenderer(),'render'),$args);if(strcmp($this->encoding,'UTF-8')){echo
  637. mb_convert_encoding($s,'HTML-ENTITIES','UTF-8');}else{echo$s;}}function
  638. __toString(){try{if(strcmp($this->encoding,'UTF-8')){return
  639. mb_convert_encoding($this->getRenderer()->render($this),'HTML-ENTITIES','UTF-8');}else{return$this->getRenderer()->render($this);}}catch(Exception$e){if(func_get_args()&&func_get_arg(0)){throw$e;}else{Debug::toStringException($e);}}}protected
  640. function
  641. getHttpRequest(){return
  642. class_exists('Environment')?Environment::getHttpRequest():new
  643. HttpRequest;}protected
  644. function
  645. getSession(){return
  646. Environment::getSession();}}class
  647. AppForm
  648. extends
  649. Form
  650. implements
  651. ISignalReceiver{function
  652. __construct(IComponentContainer$parent=NULL,$name=NULL){parent::__construct();$this->monitor('Nette\Application\Presenter');if($parent!==NULL){$parent->addComponent($this,$name);}}function
  653. getPresenter($need=TRUE){return$this->lookup('Nette\Application\Presenter',$need);}protected
  654. function
  655. attached($presenter){if($presenter
  656. instanceof
  657. Presenter){$this->setAction(new
  658. Link($presenter,$this->lookupPath('Nette\Application\Presenter').self::NAME_SEPARATOR.'submit!',array()));if($this->isSubmitted()){foreach($this->getControls()as$control){$control->loadHttpData();}}}parent::attached($presenter);}function
  659. isAnchored(){return(bool)$this->getPresenter(FALSE);}protected
  660. function
  661. receiveHttpData(){$presenter=$this->getPresenter();if(!$presenter->isSignalReceiver($this,'submit')){return;}$isPost=$this->getMethod()===self::POST;$request=$presenter->getRequest();if($request->isMethod('forward')||$request->isMethod('post')!==$isPost){return;}if($isPost){return
  662. ArrayTools::mergeTree($request->getPost(),$request->getFiles());}else{return$request->getParams();}}function
  663. signalReceived($signal){if($signal==='submit'){$this->fireEvents();}else{throw
  664. new
  665. BadSignalException("There is no handler for signal '$signal' in {$this->reflection->name}.");}}}class
  666. Application
  667. extends
  668. Object{public
  669. static$maxLoop=20;public$defaultServices=array('Nette\Application\IRouter'=>'Nette\Application\MultiRouter','Nette\Application\IPresenterLoader'=>array(__CLASS__,'createPresenterLoader'));public$catchExceptions;public$errorPresenter;public$onStartup;public$onShutdown;public$onRequest;public$onError;public$allowedMethods=array('GET','POST','HEAD','PUT','DELETE');private$requests=array();private$presenter;private$serviceLocator;function
  670. run(){$httpRequest=$this->getHttpRequest();$httpResponse=$this->getHttpResponse();$httpRequest->setEncoding('UTF-8');$httpResponse->setHeader('X-Powered-By','Nette Framework');if(Environment::getVariable('baseUri')===NULL){Environment::setVariable('baseUri',$httpRequest->getUri()->getBasePath());}if($this->allowedMethods){$method=$httpRequest->getMethod();if(!in_array($method,$this->allowedMethods,TRUE)){$httpResponse->setCode(IHttpResponse::S501_NOT_IMPLEMENTED);$httpResponse->setHeader('Allow',implode(',',$this->allowedMethods));echo'<h1>Method '.htmlSpecialChars($method).' is not implemented</h1>';return;}}$request=NULL;$repeatedError=FALSE;do{try{if(count($this->requests)>self::$maxLoop){throw
  671. new
  672. ApplicationException('Too many loops detected in application life cycle.');}if(!$request){$this->onStartup($this);$router=$this->getRouter();if($router
  673. instanceof
  674. MultiRouter&&!count($router)){$router[]=new
  675. SimpleRouter(array('presenter'=>'Default','action'=>'default'));}$request=$router->match($httpRequest);if(!($request
  676. instanceof
  677. PresenterRequest)){$request=NULL;throw
  678. new
  679. BadRequestException('No route for HTTP request.');}if(strcasecmp($request->getPresenterName(),$this->errorPresenter)===0){throw
  680. new
  681. BadRequestException('Invalid request.');}}$this->requests[]=$request;$this->onRequest($this,$request);$presenter=$request->getPresenterName();try{$class=$this->getPresenterLoader()->getPresenterClass($presenter);$request->setPresenterName($presenter);}catch(InvalidPresenterException$e){throw
  682. new
  683. BadRequestException($e->getMessage(),404,$e);}$request->freeze();$this->presenter=new$class;$response=$this->presenter->run($request);if($response
  684. instanceof
  685. ForwardingResponse){$request=$response->getRequest();continue;}elseif($response
  686. instanceof
  687. IPresenterResponse){$response->send();}break;}catch(Exception$e){if($this->catchExceptions===NULL){$this->catchExceptions=Environment::isProduction();}if(!$this->catchExceptions){throw$e;}$this->onError($this,$e);if($repeatedError){$e=new
  688. ApplicationException('An error occured while executing error-presenter',0,$e);}if(!$httpResponse->isSent()){$httpResponse->setCode($e
  689. instanceof
  690. BadRequestException?$e->getCode():500);}if(!$repeatedError&&$this->errorPresenter){$repeatedError=TRUE;$request=new
  691. PresenterRequest($this->errorPresenter,PresenterRequest::FORWARD,array('exception'=>$e));}else{echo"<meta name='robots' content='noindex'>\n\n";if($e
  692. instanceof
  693. BadRequestException){echo"<title>404 Not Found</title>\n\n<h1>Not Found</h1>\n\n<p>The requested URL was not found on this server.</p>";}else{Debug::processException($e,FALSE);echo"<title>500 Internal Server Error</title>\n\n<h1>Server Error</h1>\n\n","<p>The server encountered an internal error and was unable to complete your request. Please try again later.</p>";}echo"\n\n<hr>\n<small><i>Nette Framework</i></small>";break;}}}while(1);$this->onShutdown($this,isset($e)?$e:NULL);}final
  694. function
  695. getRequests(){return$this->requests;}final
  696. function
  697. getPresenter(){return$this->presenter;}final
  698. function
  699. getServiceLocator(){if($this->serviceLocator===NULL){$this->serviceLocator=new
  700. ServiceLocator(Environment::getServiceLocator());foreach($this->defaultServices
  701. as$name=>$service){if(!$this->serviceLocator->hasService($name)){$this->serviceLocator->addService($name,$service);}}}return$this->serviceLocator;}final
  702. function
  703. getService($name,array$options=NULL){return$this->getServiceLocator()->getService($name,$options);}function
  704. getRouter(){return$this->getServiceLocator()->getService('Nette\Application\IRouter');}function
  705. setRouter(IRouter$router){$this->getServiceLocator()->addService('Nette\Application\IRouter',$router);return$this;}function
  706. getPresenterLoader(){return$this->getServiceLocator()->getService('Nette\Application\IPresenterLoader');}static
  707. function
  708. createPresenterLoader(){return
  709. new
  710. PresenterLoader(Environment::getVariable('appDir'));}function
  711. storeRequest($expiration='+ 10 minutes'){$session=$this->getSession('Nette.Application/requests');do{$key=substr(md5(lcg_value()),0,4);}while(isset($session[$key]));$session[$key]=end($this->requests);$session->setExpiration($expiration,$key);return$key;}function
  712. restoreRequest($key){$session=$this->getSession('Nette.Application/requests');if(isset($session[$key])){$request=clone$session[$key];unset($session[$key]);$request->setFlag(PresenterRequest::RESTORED,TRUE);$this->presenter->terminate(new
  713. ForwardingResponse($request));}}protected
  714. function
  715. getHttpRequest(){return
  716. Environment::getHttpRequest();}protected
  717. function
  718. getHttpResponse(){return
  719. Environment::getHttpResponse();}protected
  720. function
  721. getSession($namespace=NULL){return
  722. Environment::getSession($namespace);}}abstract
  723. class
  724. PresenterComponent
  725. extends
  726. ComponentContainer
  727. implements
  728. ISignalReceiver,IStatePersistent,ArrayAccess{protected$params=array();function
  729. __construct(IComponentContainer$parent=NULL,$name=NULL){$this->monitor('Nette\Application\Presenter');parent::__construct($parent,$name);}function
  730. getPresenter($need=TRUE){return$this->lookup('Nette\Application\Presenter',$need);}function
  731. getUniqueId(){return$this->lookupPath('Nette\Application\Presenter',TRUE);}protected
  732. function
  733. attached($presenter){if($presenter
  734. instanceof
  735. Presenter){$this->loadState($presenter->popGlobalParams($this->getUniqueId()));}}protected
  736. function
  737. tryCall($method,array$params){$rc=$this->getReflection();if($rc->hasMethod($method)){$rm=$rc->getMethod($method);if($rm->isPublic()&&!$rm->isAbstract()&&!$rm->isStatic()){$rm->invokeNamedArgs($this,$params);return
  738. TRUE;}}return
  739. FALSE;}function
  740. getReflection(){return
  741. new
  742. PresenterComponentReflection($this);}function
  743. loadState(array$params){foreach($this->getReflection()->getPersistentParams()as$nm=>$meta){if(isset($params[$nm])){if(isset($meta['def'])){if(is_array($params[$nm])&&!is_array($meta['def'])){$params[$nm]=$meta['def'];}else{settype($params[$nm],gettype($meta['def']));}}$this->$nm=&$params[$nm];}}$this->params=$params;}function
  744. saveState(array&$params,$reflection=NULL){$reflection=$reflection===NULL?$this->getReflection():$reflection;foreach($reflection->getPersistentParams()as$nm=>$meta){if(isset($params[$nm])){$val=$params[$nm];}elseif(array_key_exists($nm,$params)){continue;}elseif(!isset($meta['since'])||$this
  745. instanceof$meta['since']){$val=$this->$nm;}else{continue;}if(is_object($val)){throw
  746. new
  747. InvalidStateException("Persistent parameter must be scalar or array, {$this->reflection->name}::\$$nm is ".gettype($val));}else{if(isset($meta['def'])){settype($val,gettype($meta['def']));if($val===$meta['def'])$val=NULL;}else{if((string)$val==='')$val=NULL;}$params[$nm]=$val;}}}final
  748. function
  749. getParam($name=NULL,$default=NULL){if(func_num_args()===0){return$this->params;}elseif(isset($this->params[$name])){return$this->params[$name];}else{return$default;}}final
  750. function
  751. getParamId($name){$uid=$this->getUniqueId();return$uid===''?$name:$uid.self::NAME_SEPARATOR.$name;}static
  752. function
  753. getPersistentParams(){$rc=new
  754. ClassReflection(func_get_arg(0));$params=array();foreach($rc->getProperties(ReflectionProperty::IS_PUBLIC)as$rp){if(!$rp->isStatic()&&$rp->hasAnnotation('persistent')){$params[]=$rp->getName();}}return$params;}function
  755. signalReceived($signal){if(!$this->tryCall($this->formatSignalMethod($signal),$this->params)){throw
  756. new
  757. BadSignalException("There is no handler for signal '$signal' in {$this->reflection->name} class.");}}function
  758. formatSignalMethod($signal){return$signal==NULL?NULL:'handle'.$signal;}function
  759. link($destination,$args=array()){if(!is_array($args)){$args=func_get_args();array_shift($args);}try{return$this->getPresenter()->createRequest($this,$destination,$args,'link');}catch(InvalidLinkException$e){return$this->getPresenter()->handleInvalidLink($e);}}function
  760. lazyLink($destination,$args=array()){if(!is_array($args)){$args=func_get_args();array_shift($args);}return
  761. new
  762. Link($this,$destination,$args);}function
  763. ajaxLink($destination,$args=array()){throw
  764. new
  765. DeprecatedException(__METHOD__.'() is deprecated.');}function
  766. redirect($code,$destination=NULL,$args=array()){if(!is_numeric($code)){$args=$destination;$destination=$code;$code=NULL;}if(!is_array($args)){$args=func_get_args();if(is_numeric(array_shift($args)))array_shift($args);}$presenter=$this->getPresenter();$presenter->redirectUri($presenter->createRequest($this,$destination,$args,'redirect'),$code);}final
  767. function
  768. offsetSet($name,$component){$this->addComponent($component,$name);}final
  769. function
  770. offsetGet($name){return$this->getComponent($name,TRUE);}final
  771. function
  772. offsetExists($name){return$this->getComponent($name,FALSE)!==NULL;}final
  773. function
  774. offsetUnset($name){$component=$this->getComponent($name,FALSE);if($component!==NULL){$this->removeComponent($component);}}}abstract
  775. class
  776. Control
  777. extends
  778. PresenterComponent
  779. implements
  780. IPartiallyRenderable{private$template;private$invalidSnippets=array();final
  781. function
  782. getTemplate(){if($this->template===NULL){$value=$this->createTemplate();if(!($value
  783. instanceof
  784. ITemplate||$value===NULL)){$class=get_class($value);throw
  785. new
  786. UnexpectedValueException("Object returned by {$this->reflection->name}::createTemplate() must be instance of Nette\\Templates\\ITemplate, '$class' given.");}$this->template=$value;}return$this->template;}protected
  787. function
  788. createTemplate(){$template=new
  789. Template;$presenter=$this->getPresenter(FALSE);$template->onPrepareFilters[]=array($this,'templatePrepareFilters');$template->component=$this;$template->control=$this;$template->presenter=$presenter;$template->baseUri=Environment::getVariable('baseUri');$template->basePath=rtrim($template->baseUri,'/');if($presenter!==NULL&&$presenter->hasFlashSession()){$id=$this->getParamId('flash');$template->flashes=$presenter->getFlashSession()->$id;}if(!isset($template->flashes)||!is_array($template->flashes)){$template->flashes=array();}$template->registerHelper('escape','Nette\Templates\TemplateHelpers::escapeHtml');$template->registerHelper('escapeUrl','rawurlencode');$template->registerHelper('stripTags','strip_tags');$template->registerHelper('nl2br','nl2br');$template->registerHelper('substr','iconv_substr');$template->registerHelper('repeat','str_repeat');$template->registerHelper('implode','implode');$template->registerHelper('number','number_format');$template->registerHelperLoader('Nette\Templates\TemplateHelpers::loader');return$template;}function
  790. templatePrepareFilters($template){$template->registerFilter(new
  791. LatteFilter);}function
  792. getWidget($name){return$this->getComponent($name);}function
  793. flashMessage($message,$type='info'){$id=$this->getParamId('flash');$messages=$this->getPresenter()->getFlashSession()->$id;$messages[]=$flash=(object)array('message'=>$message,'type'=>$type);$this->getTemplate()->flashes=$messages;$this->getPresenter()->getFlashSession()->$id=$messages;return$flash;}function
  794. invalidateControl($snippet=NULL){$this->invalidSnippets[$snippet]=TRUE;}function
  795. validateControl($snippet=NULL){if($snippet===NULL){$this->invalidSnippets=array();}else{unset($this->invalidSnippets[$snippet]);}}function
  796. isControlInvalid($snippet=NULL){if($snippet===NULL){if(count($this->invalidSnippets)>0){return
  797. TRUE;}else{foreach($this->getComponents()as$component){if($component
  798. instanceof
  799. IRenderable&&$component->isControlInvalid()){return
  800. TRUE;}}return
  801. FALSE;}}else{return
  802. isset($this->invalidSnippets[NULL])||isset($this->invalidSnippets[$snippet]);}}function
  803. getSnippetId($name=NULL){return'snippet-'.$this->getUniqueId().'-'.$name;}}class
  804. AbortException
  805. extends
  806. Exception{}class
  807. ApplicationException
  808. extends
  809. Exception{function
  810. __construct($message='',$code=0,Exception$previous=NULL){if(version_compare(PHP_VERSION,'5.3','<')){$this->previous=$previous;parent::__construct($message,$code);}else{parent::__construct($message,$code,$previous);}}}class
  811. BadRequestException
  812. extends
  813. Exception{protected$defaultCode=404;function
  814. __construct($message='',$code=0,Exception$previous=NULL){if($code<200||$code>504){$code=$this->defaultCode;}if(version_compare(PHP_VERSION,'5.3','<')){$this->previous=$previous;parent::__construct($message,$code);}else{parent::__construct($message,$code,$previous);}}}class
  815. BadSignalException
  816. extends
  817. BadRequestException{protected$defaultCode=403;}class
  818. ForbiddenRequestException
  819. extends
  820. BadRequestException{protected$defaultCode=403;}class
  821. InvalidLinkException
  822. extends
  823. Exception{}class
  824. InvalidPresenterException
  825. extends
  826. InvalidLinkException{}class
  827. Link
  828. extends
  829. Object{private$component;private$destination;private$params;function
  830. __construct(PresenterComponent$component,$destination,array$params){$this->component=$component;$this->destination=$destination;$this->params=$params;}function
  831. getDestination(){return$this->destination;}function
  832. setParam($key,$value){$this->params[$key]=$value;return$this;}function
  833. getParam($key){return
  834. isset($this->params[$key])?$this->params[$key]:NULL;}function
  835. getParams(){return$this->params;}function
  836. __toString(){try{return$this->component->link($this->destination,$this->params);}catch(Exception$e){Debug::toStringException($e);}}}abstract
  837. class
  838. Presenter
  839. extends
  840. Control
  841. implements
  842. IPresenter{const
  843. PHASE_STARTUP=1;const
  844. PHASE_SIGNAL=3;const
  845. PHASE_RENDER=4;const
  846. PHASE_SHUTDOWN=5;const
  847. INVALID_LINK_SILENT=1;const
  848. INVALID_LINK_WARNING=2;const
  849. INVALID_LINK_EXCEPTION=3;const
  850. SIGNAL_KEY='do';const
  851. ACTION_KEY='action';const
  852. FLASH_KEY='_fid';public
  853. static$defaultAction='default';public
  854. static$invalidLinkMode;public$onShutdown;public$oldLayoutMode=TRUE;public$oldModuleMode=TRUE;private$request;private$response;private$phase;public$autoCanonicalize=TRUE;public$absoluteUrls=FALSE;private$globalParams;private$globalState;private$globalStateSinces;private$action;private$view;private$layout;private$payload;private$signalReceiver;private$signal;private$ajaxMode;private$startupCheck;private$lastCreatedRequest;private$lastCreatedRequestFlag;final
  855. function
  856. getRequest(){return$this->request;}final
  857. function
  858. getPresenter($need=TRUE){return$this;}final
  859. function
  860. getUniqueId(){return'';}function
  861. run(PresenterRequest$request){try{$this->phase=self::PHASE_STARTUP;$this->request=$request;$this->payload=(object)NULL;$this->setParent($this->getParent(),$request->getPresenterName());$this->initGlobalParams();$this->startup();if(!$this->startupCheck){$class=$this->reflection->getMethod('startup')->getDeclaringClass()->getName();trigger_error("Method $class::startup() or its descendant doesn't call parent::startup().",E_USER_WARNING);}$this->tryCall($this->formatActionMethod($this->getAction()),$this->params);if($this->autoCanonicalize){$this->canonicalize();}if($this->getHttpRequest()->isMethod('head')){$this->terminate();}if(method_exists($this,'beforePrepare')){$this->beforePrepare();trigger_error('beforePrepare() is deprecated; use createComponent{Name}() instead.',E_USER_WARNING);}if($this->tryCall('prepare'.$this->getView(),$this->params)){trigger_error('prepare'.ucfirst($this->getView()).'() is deprecated; use createComponent{Name}() instead.',E_USER_WARNING);}$this->phase=self::PHASE_SIGNAL;$this->processSignal();$this->phase=self::PHASE_RENDER;$this->beforeRender();$this->tryCall($this->formatRenderMethod($this->getView()),$this->params);$this->afterRender();$this->saveGlobalState();if($this->isAjax()){$this->payload->state=$this->getGlobalState();}$this->sendTemplate();}catch(AbortException$e){}{$this->phase=self::PHASE_SHUTDOWN;if($this->isAjax())try{$hasPayload=(array)$this->payload;unset($hasPayload['state']);if($this->response
  862. instanceof
  863. RenderResponse&&($this->isControlInvalid()||$hasPayload)){SnippetHelper::$outputAllowed=FALSE;$this->response->send();$this->sendPayload();}elseif(!$this->response&&$hasPayload){$this->sendPayload();}}catch(AbortException$e){}if($this->hasFlashSession()){$this->getFlashSession()->setExpiration($this->response
  864. instanceof
  865. RedirectingResponse?'+ 30 seconds':'+ 3 seconds');}$this->onShutdown($this,$this->response);$this->shutdown($this->response);return$this->response;}}final
  866. function
  867. getPhase(){throw
  868. new
  869. DeprecatedException(__METHOD__.'() is deprecated.');return$this->phase;}protected
  870. function
  871. startup(){$this->startupCheck=TRUE;}protected
  872. function
  873. beforeRender(){}protected
  874. function
  875. afterRender(){}protected
  876. function
  877. shutdown($response){}function
  878. processSignal(){if($this->signal===NULL)return;$component=$this->signalReceiver===''?$this:$this->getComponent($this->signalReceiver,FALSE);if($component===NULL){throw
  879. new
  880. BadSignalException("The signal receiver component '$this->signalReceiver' is not found.");}elseif(!$component
  881. instanceof
  882. ISignalReceiver){throw
  883. new
  884. BadSignalException("The signal receiver component '$this->signalReceiver' is not ISignalReceiver implementor.");}if($this->oldLayoutMode&&$component
  885. instanceof
  886. IRenderable){$component->invalidateControl();}$component->signalReceived($this->signal);$this->signal=NULL;}final
  887. function
  888. getSignal(){return$this->signal===NULL?NULL:array($this->signalReceiver,$this->signal);}final
  889. function
  890. isSignalReceiver($component,$signal=NULL){if($component
  891. instanceof
  892. Component){$component=$component===$this?'':$component->lookupPath(__CLASS__,TRUE);}if($this->signal===NULL){return
  893. FALSE;}elseif($signal===TRUE){return$component===''||strncmp($this->signalReceiver.'-',$component.'-',strlen($component)+1)===0;}elseif($signal===NULL){return$this->signalReceiver===$component;}else{return$this->signalReceiver===$component&&strcasecmp($signal,$this->signal)===0;}}final
  894. function
  895. getAction($fullyQualified=FALSE){return$fullyQualified?':'.$this->getName().':'.$this->action:$this->action;}function
  896. changeAction($action){if(preg_match("#^[a-zA-Z0-9][a-zA-Z0-9_\x7f-\xff]*$#",$action)){$this->action=$action;$this->view=$action;}else{throw
  897. new
  898. BadRequestException("Action name '$action' is not alphanumeric string.");}}final
  899. function
  900. getView(){return$this->view;}function
  901. setView($view){$this->view=(string)$view;return$this;}final
  902. function
  903. getLayout(){return$this->layout;}function
  904. setLayout($layout){$this->layout=$layout===FALSE?FALSE:(string)$layout;return$this;}function
  905. sendTemplate(){$template=$this->getTemplate();if(!$template)return;if($template
  906. instanceof
  907. IFileTemplate&&!$template->getFile()){$files=$this->formatTemplateFiles($this->getName(),$this->view);foreach($files
  908. as$file){if(is_file($file)){$template->setFile($file);break;}}if(!$template->getFile()){$file=str_replace(Environment::getVariable('appDir'),"\xE2\x80\xA6",reset($files));throw
  909. new
  910. BadRequestException("Page not found. Missing template '$file'.");}if($this->layout!==FALSE){$files=$this->formatLayoutTemplateFiles($this->getName(),$this->layout?$this->layout:'layout');foreach($files
  911. as$file){if(is_file($file)){$template->layout=$file;if($this->oldLayoutMode){$template->content=clone$template;$template->setFile($file);}else{$template->_extends=$file;}break;}}if(empty($template->layout)&&$this->layout!==NULL){$file=str_replace(Environment::getVariable('appDir'),"\xE2\x80\xA6",reset($files));throw
  912. new
  913. FileNotFoundException("Layout not found. Missing template '$file'.");}}}$this->terminate(new
  914. RenderResponse($template));}function
  915. formatLayoutTemplateFiles($presenter,$layout){if($this->oldModuleMode){$root=Environment::getVariable('templatesDir',Environment::getVariable('appDir').'/templates');$presenter=str_replace(':','Module/',$presenter);$module=substr($presenter,0,(int)strrpos($presenter,'/'));$base='';if($root===Environment::getVariable('appDir').'/presenters'){$base='templates/';if($module===''){$presenter='templates/'.$presenter;}else{$presenter=substr_replace($presenter,'/templates',strrpos($presenter,'/'),0);}}return
  916. array("$root/$presenter/@$layout.phtml","$root/$presenter.@$layout.phtml","$root/$module/$base@$layout.phtml","$root/$base@$layout.phtml");}$appDir=Environment::getVariable('appDir');$path='/'.str_replace(':','Module/',$presenter);$pathP=substr_replace($path,'/templates',strrpos($path,'/'),0);$list=array("$appDir$pathP/@$layout.phtml","$appDir$pathP.@$layout.phtml");while(($path=substr($path,0,strrpos($path,'/')))!==FALSE){$list[]="$appDir$path/templates/@$layout.phtml";}return$list;}function
  917. formatTemplateFiles($presenter,$view){if($this->oldModuleMode){$root=Environment::getVariable('templatesDir',Environment::getVariable('appDir').'/templates');$presenter=str_replace(':','Module/',$presenter);$dir='';if($root===Environment::getVariable('appDir').'/presenters'){$pos=strrpos($presenter,'/');$presenter=$pos===FALSE?'templates/'.$presenter:substr_replace($presenter,'/templates',$pos,0);$dir='templates/';}return
  918. array("$root/$presenter/$view.phtml","$root/$presenter.$view.phtml","$root/$dir@global.$view.phtml");}$appDir=Environment::getVariable('appDir');$path='/'.str_replace(':','Module/',$presenter);$pathP=substr_replace($path,'/templates',strrpos($path,'/'),0);$path=substr_replace($path,'/templates',strrpos($path,'/'));return
  919. array("$appDir$pathP/$view.phtml","$appDir$pathP.$view.phtml","$appDir$path/@global.$view.phtml");}protected
  920. static
  921. function
  922. formatActionMethod($action){return'action'.$action;}protected
  923. static
  924. function
  925. formatRenderMethod($view){return'render'.$view;}protected
  926. function
  927. renderTemplate(){throw
  928. new
  929. DeprecatedException(__METHOD__.'() is deprecated; use $presenter->sendTemplate() instead.');}final
  930. function
  931. getPayload(){return$this->payload;}function
  932. isAjax(){if($this->ajaxMode===NULL){$this->ajaxMode=$this->getHttpRequest()->isAjax();}return$this->ajaxMode;}protected
  933. function
  934. sendPayload(){$this->terminate(new
  935. JsonResponse($this->payload));}function
  936. getAjaxDriver(){throw
  937. new
  938. DeprecatedException(__METHOD__.'() is deprecated; use $presenter->payload instead.');}function
  939. forward($destination,$args=array()){if($destination
  940. instanceof
  941. PresenterRequest){$this->terminate(new
  942. ForwardingResponse($destination));}elseif(!is_array($args)){$args=func_get_args();array_shift($args);}$this->createRequest($this,$destination,$args,'forward');$this->terminate(new
  943. ForwardingResponse($this->lastCreatedRequest));}function
  944. redirectUri($uri,$code=NULL){if($this->isAjax()){$this->payload->redirect=(string)$uri;$this->sendPayload();}elseif(!$code){$code=$this->getHttpRequest()->isMethod('post')?IHttpResponse::S303_POST_GET:IHttpResponse::S302_FOUND;}$this->terminate(new
  945. RedirectingResponse($uri,$code));}function
  946. backlink(){return$this->getAction(TRUE);}function
  947. getLastCreatedRequest(){return$this->lastCreatedRequest;}function
  948. getLastCreatedRequestFlag($flag){return!empty($this->lastCreatedRequestFlag[$flag]);}function
  949. terminate(IPresenterResponse$response=NULL){$this->response=$response;throw
  950. new
  951. AbortException();}function
  952. canonicalize(){if(!$this->isAjax()&&($this->request->isMethod('get')||$this->request->isMethod('head'))){$uri=$this->createRequest($this,$this->action,$this->getGlobalState()+$this->request->params,'redirectX');if($uri!==NULL&&!$this->getHttpRequest()->getUri()->isEqual($uri)){$this->terminate(new
  953. RedirectingResponse($uri,IHttpResponse::S301_MOVED_PERMANENTLY));}}}function
  954. lastModified($lastModified,$etag=NULL,$expire=NULL){if(!Environment::isProduction()){return;}if($expire!==NULL){$this->getHttpResponse()->setExpiration($expire);}if(!$this->getHttpContext()->isModified($lastModified,$etag)){$this->terminate();}}final
  955. protected
  956. function
  957. createRequest($component,$destination,array$args,$mode){static$presenterLoader,$router,$httpRequest;if($presenterLoader===NULL){$presenterLoader=$this->getApplication()->getPresenterLoader();$router=$this->getApplication()->getRouter();$httpRequest=$this->getHttpRequest();}$this->lastCreatedRequest=$this->lastCreatedRequestFlag=NULL;$a=strpos($destination,'#');if($a===FALSE){$fragment='';}else{$fragment=substr($destination,$a);$destination=substr($destination,0,$a);}$a=strpos($destination,'?');if($a!==FALSE){parse_str(substr($destination,$a+1),$args);$destination=substr($destination,0,$a);}$a=strpos($destination,'//');if($a===FALSE){$scheme=FALSE;}else{$scheme=substr($destination,0,$a);$destination=substr($destination,$a+2);}if(!($component
  958. instanceof
  959. Presenter)||substr($destination,-1)==='!'){$signal=rtrim($destination,'!');$a=strrpos($signal,':');if($a!==FALSE){$component=$component->getComponent(strtr(substr($signal,0,$a),':','-'));$signal=(string)substr($signal,$a+1);}if($signal==NULL){throw
  960. new
  961. InvalidLinkException("Signal must be non-empty string.");}$destination='this';}if($destination==NULL){throw
  962. new
  963. InvalidLinkException("Destination must be non-empty string.");}$current=FALSE;$a=strrpos($destination,':');if($a===FALSE){$action=$destination==='this'?$this->action:$destination;$presenter=$this->getName();$presenterClass=get_class($this);}else{$action=(string)substr($destination,$a+1);if($destination[0]===':'){if($a<2){throw
  964. new
  965. InvalidLinkException("Missing presenter name in '$destination'.");}$presenter=substr($destination,1,$a-1);}else{$presenter=$this->getName();$b=strrpos($presenter,':');if($b===FALSE){$presenter=substr($destination,0,$a);}else{$presenter=substr($presenter,0,$b+1).substr($destination,0,$a);}}$presenterClass=$presenterLoader->getPresenterClass($presenter);}if(isset($signal)){$reflection=new
  966. PresenterComponentReflection(get_class($component));if($signal==='this'){$signal='';if(array_key_exists(0,$args)){throw
  967. new
  968. InvalidLinkException("Extra parameter for signal '{$reflection->name}:$signal!'.");}}elseif(strpos($signal,self::NAME_SEPARATOR)===FALSE){$method=$component->formatSignalMethod($signal);if(!$reflection->hasCallableMethod($method)){throw
  969. new
  970. InvalidLinkException("Unknown signal '{$reflection->name}:$signal!'.");}if($args){self::argsToParams(get_class($component),$method,$args);}}if($args&&array_intersect_key($args,$reflection->getPersistentParams())){$component->saveState($args);}if($args&&$component!==$this){$prefix=$component->getUniqueId().self::NAME_SEPARATOR;foreach($args
  971. as$key=>$val){unset($args[$key]);$args[$prefix.$key]=$val;}}}if(is_subclass_of($presenterClass,__CLASS__)){if($action===''){$action=self::$defaultAction;}$current=($action==='*'||$action===$this->action)&&$presenterClass===get_class($this);$reflection=new
  972. PresenterComponentReflection($presenterClass);if($args||$destination==='this'){$method=call_user_func(array($presenterClass,'formatActionMethod'),$action);if(!$reflection->hasCallableMethod($method)){$method=call_user_func(array($presenterClass,'formatRenderMethod'),$action);if(!$reflection->hasCallableMethod($method)){$method=NULL;}}if($method===NULL){if(array_key_exists(0,$args)){throw
  973. new
  974. InvalidLinkException("Extra parameter for '$presenter:$action'.");}}elseif($destination==='this'){self::argsToParams($presenterClass,$method,$args,$this->params);}else{self::argsToParams($presenterClass,$method,$args);}}if($args&&array_intersect_key($args,$reflection->getPersistentParams())){$this->saveState($args,$reflection);}$globalState=$this->getGlobalState($destination==='this'?NULL:$presenterClass);if($current&&$args){$tmp=$globalState+$this->params;foreach($args
  975. as$key=>$val){if((string)$val!==(isset($tmp[$key])?(string)$tmp[$key]:'')){$current=FALSE;break;}}}$args+=$globalState;}$args[self::ACTION_KEY]=$action;if(!empty($signal)){$args[self::SIGNAL_KEY]=$component->getParamId($signal);$current=$current&&$args[self::SIGNAL_KEY]===$this->getParam(self::SIGNAL_KEY);}if(($mode==='redirect'||$mode==='forward')&&$this->hasFlashSession()){$args[self::FLASH_KEY]=$this->getParam(self::FLASH_KEY);}$this->lastCreatedRequest=new
  976. PresenterRequest($presenter,PresenterRequest::FORWARD,$args,array(),array());$this->lastCreatedRequestFlag=array('current'=>$current);if($mode==='forward')return;$uri=$router->constructUrl($this->lastCreatedRequest,$httpRequest);if($uri===NULL){unset($args[self::ACTION_KEY]);$params=urldecode(http_build_query($args,NULL,', '));throw
  977. new
  978. InvalidLinkException("No route for $presenter:$action($params)");}if($mode==='link'&&$scheme===FALSE&&!$this->absoluteUrls){$hostUri=$httpRequest->getUri()->getHostUri();if(strncmp($uri,$hostUri,strlen($hostUri))===0){$uri=substr($uri,strlen($hostUri));}}return$uri.$fragment;}private
  979. static
  980. function
  981. argsToParams($class,$method,&$args,$supplemental=array()){static$cache;$params=&$cache[strtolower($class.':'.$method)];if($params===NULL){$params=MethodReflection::from($class,$method)->getDefaultParameters();}$i=0;foreach($params
  982. as$name=>$def){if(array_key_exists($i,$args)){$args[$name]=$args[$i];unset($args[$i]);$i++;}elseif(array_key_exists($name,$args)){}elseif(array_key_exists($name,$supplemental)){$args[$name]=$supplemental[$name];}else{continue;}if($def===NULL){if((string)$args[$name]==='')$args[$name]=NULL;}else{settype($args[$name],gettype($def));if($args[$name]===$def)$args[$name]=NULL;}}if(array_key_exists($i,$args)){throw
  983. new
  984. InvalidLinkException("Extra parameter for signal '$class:$method'.");}}protected
  985. function
  986. handleInvalidLink($e){if(self::$invalidLinkMode===NULL){self::$invalidLinkMode=Environment::isProduction()?self::INVALID_LINK_SILENT:self::INVALID_LINK_WARNING;}if(self::$invalidLinkMode===self::INVALID_LINK_SILENT){return'#';}elseif(self::$invalidLinkMode===self::INVALID_LINK_WARNING){return'error: '.$e->getMessage();}else{throw$e;}}static
  987. function
  988. getPersistentComponents(){return(array)ClassReflection::from(func_get_arg(0))->getAnnotation('persistent');}private
  989. function
  990. getGlobalState($forClass=NULL){$sinces=&$this->globalStateSinces;if($this->globalState===NULL){$state=array();foreach($this->globalParams
  991. as$id=>$params){$prefix=$id.self::NAME_SEPARATOR;foreach($params
  992. as$key=>$val){$state[$prefix.$key]=$val;}}$this->saveState($state,$forClass?new
  993. PresenterComponentReflection($forClass):NULL);if($sinces===NULL){$sinces=array();foreach($this->getReflection()->getPersistentParams()as$nm=>$meta){$sinces[$nm]=$meta['since'];}}$components=$this->getReflection()->getPersistentComponents();$iterator=$this->getComponents(TRUE,'Nette\Application\IStatePersistent');foreach($iterator
  994. as$name=>$component){if($iterator->getDepth()===0){$since=isset($components[$name]['since'])?$components[$name]['since']:FALSE;}$prefix=$component->getUniqueId().self::NAME_SEPARATOR;$params=array();$component->saveState($params);foreach($params
  995. as$key=>$val){$state[$prefix.$key]=$val;$sinces[$prefix.$key]=$since;}}}else{$state=$this->globalState;}if($forClass!==NULL){$since=NULL;foreach($state
  996. as$key=>$foo){if(!isset($sinces[$key])){$x=strpos($key,self::NAME_SEPARATOR);$x=$x===FALSE?$key:substr($key,0,$x);$sinces[$key]=isset($sinces[$x])?$sinces[$x]:FALSE;}if($since!==$sinces[$key]){$since=$sinces[$key];$ok=$since&&(is_subclass_of($forClass,$since)||$forClass===$since);}if(!$ok){unset($state[$key]);}}}return$state;}protected
  997. function
  998. saveGlobalState(){foreach($this->globalParams
  999. as$id=>$foo){$this->getComponent($id,FALSE);}$this->globalParams=array();$this->globalState=$this->getGlobalState();}private
  1000. function
  1001. initGlobalParams(){$this->globalParams=array();$selfParams=array();$params=$this->request->getParams();if($this->isAjax()){$params=$this->request->getPost()+$params;}foreach($params
  1002. as$key=>$value){$a=strlen($key)>2?strrpos($key,self::NAME_SEPARATOR,-2):FALSE;if($a===FALSE){$selfParams[$key]=$value;}else{$this->globalParams[substr($key,0,$a)][substr($key,$a+1)]=$value;}}$this->changeAction(isset($selfParams[self::ACTION_KEY])?$selfParams[self::ACTION_KEY]:self::$defaultAction);$this->signalReceiver=$this->getUniqueId();if(!empty($selfParams[self::SIGNAL_KEY])){$param=$selfParams[self::SIGNAL_KEY];$pos=strrpos($param,'-');if($pos){$this->signalReceiver=substr($param,0,$pos);$this->signal=substr($param,$pos+1);}else{$this->signalReceiver=$this->getUniqueId();$this->signal=$param;}if($this->signal==NULL){$this->signal=NULL;}}$this->loadState($selfParams);}final
  1003. function
  1004. popGlobalParams($id){if(isset($this->globalParams[$id])){$res=$this->globalParams[$id];unset($this->globalParams[$id]);return$res;}else{return
  1005. array();}}function
  1006. hasFlashSession(){return!empty($this->params[self::FLASH_KEY])&&$this->getSession()->hasNamespace('Nette.Application.Flash/'.$this->params[self::FLASH_KEY]);}function
  1007. getFlashSession(){if(empty($this->params[self::FLASH_KEY])){$this->params[self::FLASH_KEY]=substr(md5(lcg_value()),0,4);}return$this->getSession('Nette.Application.Flash/'.$this->params[self::FLASH_KEY]);}protected
  1008. function
  1009. getHttpRequest(){return
  1010. Environment::getHttpRequest();}protected
  1011. function
  1012. getHttpResponse(){return
  1013. Environment::getHttpResponse();}protected
  1014. function
  1015. getHttpContext(){return
  1016. Environment::getHttpContext();}function
  1017. getApplication(){return
  1018. Environment::getApplication();}protected
  1019. function
  1020. getSession($namespace=NULL){return
  1021. Environment::getSession($namespace);}protected
  1022. function
  1023. getUser(){return
  1024. Environment::getUser();}}class
  1025. ClassReflection
  1026. extends
  1027. ReflectionClass{private
  1028. static$extMethods;static
  1029. function
  1030. from($class){return
  1031. new
  1032. self($class);}function
  1033. __toString(){return'Class '.$this->getName();}function
  1034. hasEventProperty($name){if(preg_match('#^on[A-Z]#',$name)&&$this->hasProperty($name)){$rp=$this->getProperty($name);return$rp->isPublic()&&!$rp->isStatic();}return
  1035. FALSE;}function
  1036. setExtensionMethod($name,$callback){$l=&self::$extMethods[strtolower($name)];$l[strtolower($this->getName())]=callback($callback);$l['']=NULL;return$this;}function
  1037. getExtensionMethod($name){if(self::$extMethods===NULL||$name===NULL){$list=get_defined_functions();foreach($list['user']as$fce){$pair=explode('_prototype_',$fce);if(count($pair)===2){self::$extMethods[$pair[1]][$pair[0]]=callback($fce);self::$extMethods[$pair[1]]['']=NULL;}}if($name===NULL)return
  1038. NULL;}$class=strtolower($this->getName());$l=&self::$extMethods[strtolower($name)];if(empty($l)){return
  1039. FALSE;}elseif(isset($l[''][$class])){return$l[''][$class];}$cl=$class;do{if(isset($l[$cl])){return$l[''][$class]=$l[$cl];}}while(($cl=strtolower(get_parent_class($cl)))!=='');foreach(class_implements($class)as$cl){$cl=strtolower($cl);if(isset($l[$cl])){return$l[''][$class]=$l[$cl];}}return$l[''][$class]=FALSE;}static
  1040. function
  1041. import(ReflectionClass$ref){return
  1042. new
  1043. self($ref->getName());}function
  1044. getConstructor(){return($ref=parent::getConstructor())?MethodReflection::import($ref):NULL;}function
  1045. getExtension(){return($ref=parent::getExtension())?ExtensionReflection::import($ref):NULL;}function
  1046. getInterfaces(){return
  1047. array_map(array('ClassReflection','import'),parent::getInterfaces());}function
  1048. getMethod($name){return
  1049. MethodReflection::import(parent::getMethod($name));}function
  1050. getMethods($filter=-1){return
  1051. array_map(array('MethodReflection','import'),parent::getMethods($filter));}function
  1052. getParentClass(){return($ref=parent::getParentClass())?self::import($ref):NULL;}function
  1053. getProperties($filter=-1){return
  1054. array_map(array('PropertyReflection','import'),parent::getProperties($filter));}function
  1055. getProperty($name){return
  1056. PropertyReflection::import(parent::getProperty($name));}function
  1057. hasAnnotation($name){$res=AnnotationsParser::getAll($this);return!empty($res[$name]);}function
  1058. getAnnotation($name){$res=AnnotationsParser::getAll($this);return
  1059. isset($res[$name])?end($res[$name]):NULL;}function
  1060. getAnnotations(){return
  1061. AnnotationsParser::getAll($this);}function
  1062. getReflection(){return
  1063. new
  1064. ClassReflection($this);}function
  1065. __call($name,$args){return
  1066. ObjectMixin::call($this,$name,$args);}function&__get($name){return
  1067. ObjectMixin::get($this,$name);}function
  1068. __set($name,$value){return
  1069. ObjectMixin::set($this,$name,$value);}function
  1070. __isset($name){return
  1071. ObjectMixin::has($this,$name);}function
  1072. __unset($name){throw
  1073. new
  1074. MemberAccessException("Cannot unset the property {$this->reflection->name}::\$$name.");}}class
  1075. PresenterComponentReflection
  1076. extends
  1077. ClassReflection{private
  1078. static$ppCache=array();private
  1079. static$pcCache=array();private
  1080. static$mcCache=array();function
  1081. getPersistentParams($class=NULL){$class=$class===NULL?$this->getName():$class;$params=&self::$ppCache[$class];if($params!==NULL)return$params;$params=array();if(is_subclass_of($class,'PresenterComponent')){$defaults=get_class_vars($class);foreach(call_user_func(array($class,'getPersistentParams'),$class)as$name=>$meta){if(is_string($meta))$name=$meta;$params[$name]=array('def'=>$defaults[$name],'since'=>$class);}$params=$this->getPersistentParams(get_parent_class($class))+$params;}return$params;}function
  1082. getPersistentComponents(){$class=$this->getName();$components=&self::$pcCache[$class];if($components!==NULL)return$components;$components=array();if(is_subclass_of($class,'Presenter')){foreach(call_user_func(array($class,'getPersistentComponents'),$class)as$name=>$meta){if(is_string($meta))$name=$meta;$components[$name]=array('since'=>$class);}$components=self::getPersistentComponents(get_parent_class($class))+$components;}return$components;}function
  1083. hasCallableMethod($method){$class=$this->getName();$cache=&self::$mcCache[strtolower($class.':'.$method)];if($cache===NULL)try{$cache=FALSE;$rm=MethodReflection::from($class,$method);$cache=$this->isInstantiable()&&$rm->isPublic()&&!$rm->isAbstract()&&!$rm->isStatic();}catch(ReflectionException$e){}return$cache;}}class
  1084. PresenterLoader
  1085. implements
  1086. IPresenterLoader{public$caseSensitive=FALSE;private$baseDir;private$cache=array();function
  1087. __construct($baseDir){$this->baseDir=$baseDir;}function
  1088. getPresenterClass(&$name){if(isset($this->cache[$name])){list($class,$name)=$this->cache[$name];return$class;}if(!is_string($name)||!preg_match("#^[a-zA-Z\x7f-\xff][a-zA-Z0-9\x7f-\xff:]*$#",$name)){throw
  1089. new
  1090. InvalidPresenterException("Presenter name must be alphanumeric string, '$name' is invalid.");}$class=$this->formatPresenterClass($name);if(!class_exists($class)){$file=$this->formatPresenterFile($name);if(is_file($file)&&is_readable($file)){LimitedScope::load($file);}if(!class_exists($class)){throw
  1091. new
  1092. InvalidPresenterException("Cannot load presenter '$name', class '$class' was not found in '$file'.");}}$reflection=new
  1093. ClassReflection($class);$class=$reflection->getName();if(!$reflection->implementsInterface('IPresenter')){throw
  1094. new
  1095. InvalidPresenterException("Cannot load presenter '$name', class '$class' is not Nette\\Application\\IPresenter implementor.");}if($reflection->isAbstract()){throw
  1096. new
  1097. InvalidPresenterException("Cannot load presenter '$name', class '$class' is abstract.");}$realName=$this->unformatPresenterClass($class);if($name!==$realName){if($this->caseSensitive){throw
  1098. new
  1099. InvalidPresenterException("Cannot load presenter '$name', case mismatch. Real name is '$realName'.");}else{$this->cache[$name]=array($class,$realName);$name=$realName;}}else{$this->cache[$name]=array($class,$realName);}return$class;}function
  1100. formatPresenterClass($presenter){return
  1101. strtr($presenter,':','_').'Presenter';}function
  1102. unformatPresenterClass($class){return
  1103. strtr(substr($class,0,-9),'_',':');}function
  1104. formatPresenterFile($presenter){$path='/'.str_replace(':','Module/',$presenter);return$this->baseDir.substr_replace($path,'/presenters',strrpos($path,'/'),0).'Presenter.php';}}abstract
  1105. class
  1106. FreezableObject
  1107. extends
  1108. Object{private$frozen=FALSE;function
  1109. freeze(){$this->frozen=TRUE;}final
  1110. function
  1111. isFrozen(){return$this->frozen;}function
  1112. __clone(){$this->frozen=FALSE;}protected
  1113. function
  1114. updating(){if($this->frozen){throw
  1115. new
  1116. InvalidStateException("Cannot modify a frozen object {$this->reflection->name}.");}}}final
  1117. class
  1118. PresenterRequest
  1119. extends
  1120. FreezableObject{const
  1121. FORWARD='FORWARD';const
  1122. SECURED='secured';const
  1123. RESTORED='restored';private$method;private$flags=array();private$name;private$params;private$post;private$files;function
  1124. __construct($name,$method,array$params,array$post=array(),array$files=array(),array$flags=array()){$this->name=$name;$this->method=$method;$this->params=$params;$this->post=$post;$this->files=$files;$this->flags=$flags;}function
  1125. setPresenterName($name){$this->updating();$this->name=$name;return$this;}function
  1126. getPresenterName(){return$this->name;}function
  1127. setParams(array$params){$this->updating();$this->params=$params;return$this;}function
  1128. getParams(){return$this->params;}function
  1129. setPost(array$params){$this->updating();$this->post=$params;return$this;}function
  1130. getPost(){return$this->post;}function
  1131. setFiles(array$files){$this->updating();$this->files=$files;return$this;}function
  1132. getFiles(){return$this->files;}function
  1133. setMethod($method){$this->method=$method;return$this;}function
  1134. getMethod(){return$this->method;}function
  1135. isMethod($method){return
  1136. strcasecmp($this->method,$method)===0;}function
  1137. isPost(){return
  1138. strcasecmp($this->method,'post')===0;}function
  1139. setFlag($flag,$value=TRUE){$this->updating();$this->flags[$flag]=(bool)$value;return$this;}function
  1140. hasFlag($flag){return!empty($this->flags[$flag]);}}class
  1141. DownloadResponse
  1142. extends
  1143. Object
  1144. implements
  1145. IPresenterResponse{private$file;private$contentType;private$name;function
  1146. __construct($file,$name=NULL,$contentType=NULL){if(!is_file($file)){throw
  1147. new
  1148. BadRequestException("File '$file' doesn't exist.");}$this->file=$file;$this->name=$name?$name:basename($file);$this->contentType=$contentType?$contentType:'application/octet-stream';}final
  1149. function
  1150. getFile(){return$this->file;}final
  1151. function
  1152. getName(){return$this->name;}final
  1153. function
  1154. getContentType(){return$this->contentType;}function
  1155. send(){Environment::getHttpResponse()->setContentType($this->contentType);Environment::getHttpResponse()->setHeader('Content-Disposition','attachment; filename="'.$this->name.'"');readfile($this->file);}}class
  1156. ForwardingResponse
  1157. extends
  1158. Object
  1159. implements
  1160. IPresenterResponse{private$request;function
  1161. __construct(PresenterRequest$request){$this->request=$request;}final
  1162. function
  1163. getRequest(){return$this->request;}function
  1164. send(){}}class
  1165. JsonResponse
  1166. extends
  1167. Object
  1168. implements
  1169. IPresenterResponse{private$payload;private$contentType;function
  1170. __construct($payload,$contentType=NULL){if(!is_array($payload)&&!($payload
  1171. instanceof
  1172. stdClass)){throw
  1173. new
  1174. InvalidArgumentException("Payload must be array or anonymous class, ".gettype($payload)." given.");}$this->payload=$payload;$this->contentType=$contentType?$contentType:'application/json';}final
  1175. function
  1176. getPayload(){return$this->payload;}function
  1177. send(){Environment::getHttpResponse()->setContentType($this->contentType);Environment::getHttpResponse()->setExpiration(FALSE);echo
  1178. json_encode($this->payload);}}class
  1179. RedirectingResponse
  1180. extends
  1181. Object
  1182. implements
  1183. IPresenterResponse{private$uri;private$code;function
  1184. __construct($uri,$code=IHttpResponse::S302_FOUND){$this->uri=(string)$uri;$this->code=(int)$code;}final
  1185. function
  1186. getUri(){return$this->uri;}final
  1187. function
  1188. getCode(){return$this->code;}function
  1189. send(){Environment::getHttpResponse()->redirect($this->uri,$this->code);}}class
  1190. RenderResponse
  1191. extends
  1192. Object
  1193. implements
  1194. IPresenterResponse{private$source;function
  1195. __construct($source){$this->source=$source;}final
  1196. function
  1197. getSource(){return$this->source;}function
  1198. send(){if($this->source
  1199. instanceof
  1200. ITemplate){$this->source->render();}else{echo$this->source;}}}class
  1201. CliRouter
  1202. extends
  1203. Object
  1204. implements
  1205. IRouter{const
  1206. PRESENTER_KEY='action';private$defaults;function
  1207. __construct($defaults=array()){$this->defaults=$defaults;}function
  1208. match(IHttpRequest$httpRequest){if(empty($_SERVER['argv'])||!is_array($_SERVER['argv'])){return
  1209. NULL;}$names=array(self::PRESENTER_KEY);$params=$this->defaults;$args=$_SERVER['argv'];array_shift($args);$args[]='--';foreach($args
  1210. as$arg){$opt=preg_replace('#/|-+#A','',$arg);if($opt===$arg){if(isset($flag)||$flag=array_shift($names)){$params[$flag]=$arg;}else{$params[]=$arg;}$flag=NULL;continue;}if(isset($flag)){$params[$flag]=TRUE;$flag=NULL;}if($opt!==''){$pair=explode('=',$opt,2);if(isset($pair[1])){$params[$pair[0]]=$pair[1];}else{$flag=$pair[0];}}}if(!isset($params[self::PRESENTER_KEY])){throw
  1211. new
  1212. InvalidStateException('Missing presenter & action in route definition.');}$presenter=$params[self::PRESENTER_KEY];if($a=strrpos($presenter,':')){$params[self::PRESENTER_KEY]=substr($presenter,$a+1);$presenter=substr($presenter,0,$a);}return
  1213. new
  1214. PresenterRequest($presenter,'CLI',$params);}function
  1215. constructUrl(PresenterRequest$appRequest,IHttpRequest$httpRequest){return
  1216. NULL;}function
  1217. getDefaults(){return$this->defaults;}}abstract
  1218. class
  1219. Collection
  1220. extends
  1221. ArrayObject
  1222. implements
  1223. ICollection{private$itemType;private$checkFunc;private$frozen=FALSE;function
  1224. __construct($arr=NULL,$type=NULL){if(substr($type,0,1)===':'){$this->itemType=substr($type,1);$this->checkFunc='is_'.$this->itemType;}else{$this->itemType=$type;}if($arr!==NULL){$this->import($arr);}}function
  1225. append($item){$this->beforeAdd($item);parent::append($item);}function
  1226. remove($item){$this->updating();$index=$this->search($item);if($index===FALSE){return
  1227. FALSE;}else{parent::offsetUnset($index);return
  1228. TRUE;}}protected
  1229. function
  1230. search($item){return
  1231. array_search($item,$this->getArrayCopy(),TRUE);}function
  1232. clear(){$this->updating();parent::exchangeArray(array());}function
  1233. contains($item){return$this->search($item)!==FALSE;}function
  1234. import($arr){if(!(is_array($arr)||$arr
  1235. instanceof
  1236. Traversable)){throw
  1237. new
  1238. InvalidArgumentException("Argument must be traversable.");}$this->clear();foreach($arr
  1239. as$item){$this->offsetSet(NULL,$item);}}function
  1240. getItemType(){return$this->itemType;}function
  1241. setReadOnly(){throw
  1242. new
  1243. DeprecatedException(__METHOD__.'() is deprecated; use freeze() instead.');}function
  1244. isReadOnly(){throw
  1245. new
  1246. DeprecatedException(__METHOD__.'() is deprecated; use isFrozen() instead.');}protected
  1247. function
  1248. beforeAdd($item){$this->updating();if($this->itemType!==NULL){if($this->checkFunc===NULL){if(!($item
  1249. instanceof$this->itemType)){throw
  1250. new
  1251. InvalidArgumentException("Item must be '$this->itemType' object.");}}else{$fnc=$this->checkFunc;if(!$fnc($item)){throw
  1252. new
  1253. InvalidArgumentException("Item must be $this->itemType type.");}}}}function
  1254. getIterator(){return
  1255. new
  1256. ArrayIterator($this->getArrayCopy());}function
  1257. exchangeArray($array){throw
  1258. new
  1259. NotSupportedException('Use '.__CLASS__.'::import()');}protected
  1260. function
  1261. setArray($array){parent::exchangeArray($array);return$this;}function
  1262. getReflection(){return
  1263. new
  1264. ClassReflection($this);}function
  1265. __call($name,$args){return
  1266. ObjectMixin::call($this,$name,$args);}static
  1267. function
  1268. __callStatic($name,$args){$class=get_called_class();throw
  1269. new
  1270. MemberAccessException("Call to undefined static method $class::$name().");}function&__get($name){return
  1271. ObjectMixin::get($this,$name);}function
  1272. __set($name,$value){return
  1273. ObjectMixin::set($this,$name,$value);}function
  1274. __isset($name){return
  1275. ObjectMixin::has($this,$name);}function
  1276. __unset($name){throw
  1277. new
  1278. MemberAccessException("Cannot unset the property {$this->reflection->name}::\$$name.");}function
  1279. freeze(){$this->frozen=TRUE;}final
  1280. function
  1281. isFrozen(){return$this->frozen;}function
  1282. __clone(){$this->frozen=FALSE;}protected
  1283. function
  1284. updating(){if($this->frozen){$class=get_class($this);throw
  1285. new
  1286. InvalidStateException("Cannot modify a frozen object '$class'.");}}}class
  1287. ArrayList
  1288. extends
  1289. Collection
  1290. implements
  1291. IList{protected$base=0;function
  1292. insertAt($index,$item){$index-=$this->base;if($index<0||$index>count($this)){throw
  1293. new
  1294. ArgumentOutOfRangeException;}$this->beforeAdd($item);$data=$this->getArrayCopy();array_splice($data,(int)$index,0,array($item));$this->setArray($data);return
  1295. TRUE;}function
  1296. remove($item){$this->updating();$index=$this->search($item);if($index===FALSE){return
  1297. FALSE;}else{$data=$this->getArrayCopy();array_splice($data,$index,1);$this->setArray($data);return
  1298. TRUE;}}function
  1299. indexOf($item){$index=$this->search($item);return$index===FALSE?FALSE:$this->base+$index;}function
  1300. offsetSet($index,$item){$this->beforeAdd($item);if($index===NULL){parent::offsetSet(NULL,$item);}else{$index-=$this->base;if($index<0||$index>=count($this)){throw
  1301. new
  1302. ArgumentOutOfRangeException;}parent::offsetSet($index,$item);}}function
  1303. offsetGet($index){$index-=$this->base;if($index<0||$index>=count($this)){throw
  1304. new
  1305. ArgumentOutOfRangeException;}return
  1306. parent::offsetGet($index);}function
  1307. offsetExists($index){$index-=$this->base;return$index>=0&&$index<count($this);}function
  1308. offsetUnset($index){$this->updating();$index-=$this->base;if($index<0||$index>=count($this)){throw
  1309. new
  1310. ArgumentOutOfRangeException;}$data=$this->getArrayCopy();array_splice($data,(int)$index,1);$this->setArray($data);}}class
  1311. MultiRouter
  1312. extends
  1313. ArrayList
  1314. implements
  1315. IRouter{private$cachedRoutes;function
  1316. __construct(){parent::__construct(NULL,'IRouter');}function
  1317. match(IHttpRequest$httpRequest){foreach($this
  1318. as$route){$appRequest=$route->match($httpRequest);if($appRequest!==NULL){return$appRequest;}}return
  1319. NULL;}function
  1320. constructUrl(PresenterRequest$appRequest,IHttpRequest$httpRequest){if($this->cachedRoutes===NULL){$routes=array();$routes['*']=array();foreach($this
  1321. as$route){$presenter=$route
  1322. instanceof
  1323. Route?$route->getTargetPresenter():NULL;if($presenter===FALSE)continue;if(is_string($presenter)){$presenter=strtolower($presenter);if(!isset($routes[$presenter])){$routes[$presenter]=$routes['*'];}$routes[$presenter][]=$route;}else{foreach($routes
  1324. as$id=>$foo){$routes[$id][]=$route;}}}$this->cachedRoutes=$routes;}$presenter=strtolower($appRequest->getPresenterName());if(!isset($this->cachedRoutes[$presenter]))$presenter='*';foreach($this->cachedRoutes[$presenter]as$route){$uri=$route->constructUrl($appRequest,$httpRequest);if($uri!==NULL){return$uri;}}return
  1325. NULL;}}class
  1326. Route
  1327. extends
  1328. Object
  1329. implements
  1330. IRouter{const
  1331. PRESENTER_KEY='presenter';const
  1332. MODULE_KEY='module';const
  1333. CASE_SENSITIVE=256;const
  1334. FULL_META=128;const
  1335. HOST=1;const
  1336. PATH=2;const
  1337. RELATIVE=3;const
  1338. VALUE='value';const
  1339. PATTERN='pattern';const
  1340. FILTER_IN='filterIn';const
  1341. FILTER_OUT='filterOut';const
  1342. FILTER_TABLE='filterTable';const
  1343. OPTIONAL=0;const
  1344. PATH_OPTIONAL=1;const
  1345. CONSTANT=2;public
  1346. static$defaultFlags=0;public
  1347. static$styles=array('#'=>array(self::PATTERN=>'[^/]+',self::FILTER_IN=>'rawurldecode',self::FILTER_OUT=>'rawurlencode'),'?#'=>array(),'module'=>array(self::PATTERN=>'[a-z][a-z0-9.-]*',self::FILTER_IN=>array(__CLASS__,'path2presenter'),self::FILTER_OUT=>array(__CLASS__,'presenter2path')),'presenter'=>array(self::PATTERN=>'[a-z][a-z0-9.-]*',self::FILTER_IN=>array(__CLASS__,'path2presenter'),self::FILTER_OUT=>array(__CLASS__,'presenter2path')),'action'=>array(self::PATTERN=>'[a-z][a-z0-9-]*',self::FILTER_IN=>array(__CLASS__,'path2action'),self::FILTER_OUT=>array(__CLASS__,'action2path')),'?module'=>array(),'?presenter'=>array(),'?action'=>array());private$mask;private$sequence;private$re;private$metadata=array();private$xlat;private$type;private$flags;function
  1348. __construct($mask,array$metadata=array(),$flags=0){$this->flags=$flags|self::$defaultFlags;if(!($this->flags&self::FULL_META)){foreach($metadata
  1349. as$name=>$def){$metadata[$name]=array(self::VALUE=>$def);}}$this->setMask($mask,$metadata);}function
  1350. match(IHttpRequest$httpRequest){$uri=$httpRequest->getUri();if($this->type===self::HOST){$path='//'.$uri->getHost().$uri->getPath();}elseif($this->type===self::RELATIVE){$basePath=$uri->getBasePath();if(strncmp($uri->getPath(),$basePath,strlen($basePath))!==0){return
  1351. NULL;}$path=(string)substr($uri->getPath(),strlen($basePath));}else{$path=$uri->getPath();}if($path!==''){$path=rtrim($path,'/').'/';}if(!preg_match($this->re,$path,$matches)){return
  1352. NULL;}$params=array();foreach($matches
  1353. as$k=>$v){if(is_string($k)&&$v!==''){$params[str_replace('___','-',$k)]=$v;}}foreach($this->metadata
  1354. as$name=>$meta){if(isset($params[$name])){}elseif(isset($meta['fixity'])&&$meta['fixity']!==self::OPTIONAL){$params[$name]=NULL;}}if($this->xlat){$params+=self::renameKeys($httpRequest->getQuery(),array_flip($this->xlat));}else{$params+=$httpRequest->getQuery();}foreach($this->metadata
  1355. as$name=>$meta){if(isset($params[$name])){if(!is_scalar($params[$name])){}elseif(isset($meta[self::FILTER_TABLE][$params[$name]])){$params[$name]=$meta[self::FILTER_TABLE][$params[$name]];}elseif(isset($meta[self::FILTER_IN])){$params[$name]=call_user_func($meta[self::FILTER_IN],(string)$params[$name]);if($params[$name]===NULL&&!isset($meta['fixity'])){return
  1356. NULL;}}}elseif(isset($meta['fixity'])){$params[$name]=$meta[self::VALUE];}}if(!isset($params[self::PRESENTER_KEY])){throw
  1357. new
  1358. InvalidStateException('Missing presenter in route definition.');}if(isset($this->metadata[self::MODULE_KEY])){if(!isset($params[self::MODULE_KEY])){throw
  1359. new
  1360. InvalidStateException('Missing module in route definition.');}$presenter=$params[self::MODULE_KEY].':'.$params[self::PRESENTER_KEY];unset($params[self::MODULE_KEY],$params[self::PRESENTER_KEY]);}else{$presenter=$params[self::PRESENTER_KEY];unset($params[self::PRESENTER_KEY]);}return
  1361. new
  1362. PresenterRequest($presenter,$httpRequest->getMethod(),$params,$httpRequest->getPost(),$httpRequest->getFiles(),array(PresenterRequest::SECURED=>$httpRequest->isSecured()));}function
  1363. constructUrl(PresenterRequest$appRequest,IHttpRequest$httpRequest){if($this->flags&self::ONE_WAY){return
  1364. NULL;}$params=$appRequest->getParams();$metadata=$this->metadata;$presenter=$appRequest->getPresenterName();$params[self::PRESENTER_KEY]=$presenter;if(isset($metadata[self::MODULE_KEY])){$module=$metadata[self::MODULE_KEY];if(isset($module['fixity'])&&strncasecmp($presenter,$module[self::VALUE].':',strlen($module[self::VALUE])+1)===0){$a=strlen($module[self::VALUE]);}else{$a=strrpos($presenter,':');}if($a!==FALSE){$params[self::MODULE_KEY]=substr($presenter,0,$a);$params[self::PRESENTER_KEY]=substr($presenter,$a+1);}}foreach($metadata
  1365. as$name=>$meta){if(!isset($params[$name]))continue;if(isset($meta['fixity'])){if(is_scalar($params[$name])&&strcasecmp($params[$name],$meta[self::VALUE])===0){unset($params[$name]);continue;}elseif($meta['fixity']===self::CONSTANT){return
  1366. NULL;}}if(!is_scalar($params[$name])){}elseif(isset($meta['filterTable2'][$params[$name]])){$params[$name]=$meta['filterTable2'][$params[$name]];}elseif(isset($meta[self::FILTER_OUT])){$params[$name]=call_user_func($meta[self::FILTER_OUT],$params[$name]);}if(isset($meta[self::PATTERN])&&!preg_match($meta[self::PATTERN],rawurldecode($params[$name]))){return
  1367. NULL;}}$sequence=$this->sequence;$brackets=array();$required=0;$uri='';$i=count($sequence)-1;do{$uri=$sequence[$i].$uri;if($i===0)break;$i--;$name=$sequence[$i];$i--;if($name===']'){$brackets[]=$uri;}elseif($name[0]==='['){$tmp=array_pop($brackets);if($required<count($brackets)+1){if($name!=='[!'){$uri=$tmp;}}else{$required=count($brackets);}}elseif($name[0]==='?'){continue;}elseif(isset($params[$name])&&$params[$name]!=''){$required=count($brackets);$uri=$params[$name].$uri;unset($params[$name]);}elseif(isset($metadata[$name]['fixity'])){$uri=$metadata[$name]['defOut'].$uri;}else{return
  1368. NULL;}}while(TRUE);if($this->xlat){$params=self::renameKeys($params,$this->xlat);}$sep=ini_get('arg_separator.input');$query=http_build_query($params,'',$sep?$sep[0]:'&');if($query!='')$uri.='?'.$query;if($this->type===self::RELATIVE){$uri='//'.$httpRequest->getUri()->getAuthority().$httpRequest->getUri()->getBasePath().$uri;}elseif($this->type===self::PATH){$uri='//'.$httpRequest->getUri()->getAuthority().$uri;}if(strpos($uri,'//',2)!==FALSE){return
  1369. NULL;}$uri=($this->flags&self::SECURED?'https:':'http:').$uri;return$uri;}private
  1370. function
  1371. setMask($mask,array$metadata){$this->mask=$mask;if(substr($mask,0,2)==='//'){$this->type=self::HOST;}elseif(substr($mask,0,1)==='/'){$this->type=self::PATH;}else{$this->type=self::RELATIVE;}foreach($metadata
  1372. as$name=>$meta){if(array_key_exists(self::VALUE,$meta)){$metadata[$name]['fixity']=self::CONSTANT;}}$parts=preg_split('/<([^># ]+) *([^>#]*)(#?[^>\[\]]*)>|(\[!?|\]|\s*\?.*)/',$mask,-1,PREG_SPLIT_DELIM_CAPTURE);$this->xlat=array();$i=count($parts)-1;if(isset($parts[$i-1])&&substr(ltrim($parts[$i-1]),0,1)==='?'){preg_match_all('/(?:([a-zA-Z0-9_.-]+)=)?<([^># ]+) *([^>#]*)(#?[^>]*)>/',$parts[$i-1],$matches,PREG_SET_ORDER);foreach($matches
  1373. as$match){list(,$param,$name,$pattern,$class)=$match;if($class!==''){if(!isset(self::$styles[$class])){throw
  1374. new
  1375. InvalidStateException("Parameter '$name' has '$class' flag, but Route::\$styles['$class'] is not set.");}$meta=self::$styles[$class];}elseif(isset(self::$styles['?'.$name])){$meta=self::$styles['?'.$name];}else{$meta=self::$styles['?#'];}if(isset($metadata[$name])){$meta=$metadata[$name]+$meta;}if(array_key_exists(self::VALUE,$meta)){$meta['fixity']=self::OPTIONAL;}unset($meta['pattern']);$meta['filterTable2']=empty($meta[self::FILTER_TABLE])?NULL:array_flip($meta[self::FILTER_TABLE]);$metadata[$name]=$meta;if($param!==''){$this->xlat[$name]=$param;}}$i-=5;}$brackets=0;$re='';$sequence=array();$autoOptional=array(0,0);do{array_unshift($sequence,$parts[$i]);if(strpos($parts[$i],'{')!==FALSE){throw
  1376. new
  1377. DeprecatedException('Optional parts delimited using {...} are deprecated; use [...] instead.');}$re=preg_quote($parts[$i],'#').$re;if($i===0)break;$i--;$part=$parts[$i];if($part==='['||$part===']'||$part==='[!'){$brackets+=$part[0]==='['?-1:1;if($brackets<0){throw
  1378. new
  1379. InvalidArgumentException("Unexpected '$part' in mask '$mask'.");}array_unshift($sequence,$part);$re=($part[0]==='['?'(?:':')?').$re;$i-=4;continue;}$class=$parts[$i];$i--;$pattern=trim($parts[$i]);$i--;$name=$parts[$i];$i--;array_unshift($sequence,$name);if($name[0]==='?'){$re='(?:'.preg_quote(substr($name,1),'#').'|'.$pattern.')'.$re;$sequence[1]=substr($name,1).$sequence[1];continue;}if(preg_match('#[^a-z0-9_-]#i',$name)){throw
  1380. new
  1381. InvalidArgumentException("Parameter name must be alphanumeric string due to limitations of PCRE, '$name' given.");}if($class!==''){if(!isset(self::$styles[$class])){throw
  1382. new
  1383. InvalidStateException("Parameter '$name' has '$class' flag, but Route::\$styles['$class'] is not set.");}$meta=self::$styles[$class];}elseif(isset(self::$styles[$name])){$meta=self::$styles[$name];}else{$meta=self::$styles['#'];}if(isset($metadata[$name])){$meta=$metadata[$name]+$meta;}if($pattern==''&&isset($meta[self::PATTERN])){$pattern=$meta[self::PATTERN];}$meta['filterTable2']=empty($meta[self::FILTER_TABLE])?NULL:array_flip($meta[self::FILTER_TABLE]);if(array_key_exists(self::VALUE,$meta)){if(isset($meta['filterTable2'][$meta[self::VALUE]])){$meta['defOut']=$meta['filterTable2'][$meta[self::VALUE]];}elseif(isset($meta[self::FILTER_OUT])){$meta['defOut']=call_user_func($meta[self::FILTER_OUT],$meta[self::VALUE]);}else{$meta['defOut']=$meta[self::VALUE];}}$meta[self::PATTERN]="#(?:$pattern)$#A".($this->flags&self::CASE_SENSITIVE?'':'iu');$re='(?P<'.str_replace('-','___',$name).'>'.$pattern.')'.$re;if($brackets){if(!isset($meta[self::VALUE])){$meta[self::VALUE]=$meta['defOut']=NULL;}$meta['fixity']=self::PATH_OPTIONAL;}elseif(isset($meta['fixity'])){$re='(?:'.substr_replace($re,')?',strlen($re)-$autoOptional[0],0);array_splice($sequence,count($sequence)-$autoOptional[1],0,array(']',''));array_unshift($sequence,'[','');$meta['fixity']=self::PATH_OPTIONAL;}else{$autoOptional=array(strlen($re),count($sequence));}$metadata[$name]=$meta;}while(TRUE);if($brackets){throw
  1384. new
  1385. InvalidArgumentException("Missing closing ']' in mask '$mask'.");}$this->re='#'.$re.'/?$#A'.($this->flags&self::CASE_SENSITIVE?'':'iu');$this->metadata=$metadata;$this->sequence=$sequence;}function
  1386. getMask(){return$this->mask;}function
  1387. getDefaults(){$defaults=array();foreach($this->metadata
  1388. as$name=>$meta){if(isset($meta['fixity'])){$defaults[$name]=$meta[self::VALUE];}}return$defaults;}function
  1389. getTargetPresenter(){if($this->flags&self::ONE_WAY){return
  1390. FALSE;}$m=$this->metadata;$module='';if(isset($m[self::MODULE_KEY])){if(isset($m[self::MODULE_KEY]['fixity'])&&$m[self::MODULE_KEY]['fixity']===self::CONSTANT){$module=$m[self::MODULE_KEY][self::VALUE].':';}else{return
  1391. NULL;}}if(isset($m[self::PRESENTER_KEY]['fixity'])&&$m[self::PRESENTER_KEY]['fixity']===self::CONSTANT){return$module.$m[self::PRESENTER_KEY][self::VALUE];}return
  1392. NULL;}private
  1393. static
  1394. function
  1395. renameKeys($arr,$xlat){if(empty($xlat))return$arr;$res=array();$occupied=array_flip($xlat);foreach($arr
  1396. as$k=>$v){if(isset($xlat[$k])){$res[$xlat[$k]]=$v;}elseif(!isset($occupied[$k])){$res[$k]=$v;}}return$res;}private
  1397. static
  1398. function
  1399. action2path($s){$s=preg_replace('#(.)(?=[A-Z])#','$1-',$s);$s=strtolower($s);$s=rawurlencode($s);return$s;}private
  1400. static
  1401. function
  1402. path2action($s){$s=strtolower($s);$s=preg_replace('#-(?=[a-z])#',' ',$s);$s=substr(ucwords('x'.$s),1);$s=str_replace(' ','',$s);return$s;}private
  1403. static
  1404. function
  1405. presenter2path($s){$s=strtr($s,':','.');$s=preg_replace('#([^.])(?=[A-Z])#','$1-',$s);$s=strtolower($s);$s=rawurlencode($s);return$s;}private
  1406. static
  1407. function
  1408. path2presenter($s){$s=strtolower($s);$s=preg_replace('#([.-])(?=[a-z])#','$1 ',$s);$s=ucwords($s);$s=str_replace('. ',':',$s);$s=str_replace('- ','',$s);return$s;}static
  1409. function
  1410. addStyle($style,$parent='#'){if(isset(self::$styles[$style])){throw
  1411. new
  1412. InvalidArgumentException("Style '$style' already exists.");}if($parent!==NULL){if(!isset(self::$styles[$parent])){throw
  1413. new
  1414. InvalidArgumentException("Parent style '$parent' doesn't exist.");}self::$styles[$style]=self::$styles[$parent];}else{self::$styles[$style]=array();}}static
  1415. function
  1416. setStyleProperty($style,$key,$value){if(!isset(self::$styles[$style])){throw
  1417. new
  1418. InvalidArgumentException("Style '$style' doesn't exist.");}self::$styles[$style][$key]=$value;}}class
  1419. SimpleRouter
  1420. extends
  1421. Object
  1422. implements
  1423. IRouter{const
  1424. PRESENTER_KEY='presenter';const
  1425. MODULE_KEY='module';private$module='';private$defaults;private$flags;function
  1426. __construct($defaults=array(),$flags=0){if(is_string($defaults)){$a=strrpos($defaults,':');$defaults=array(self::PRESENTER_KEY=>substr($defaults,0,$a),'action'=>substr($defaults,$a+1));}if(isset($defaults[self::MODULE_KEY])){$this->module=$defaults[self::MODULE_KEY].':';unset($defaults[self::MODULE_KEY]);}$this->defaults=$defaults;$this->flags=$flags;}function
  1427. match(IHttpRequest$httpRequest){$params=$httpRequest->getQuery();$params+=$this->defaults;if(!isset($params[self::PRESENTER_KEY])){throw
  1428. new
  1429. InvalidStateException('Missing presenter.');}$presenter=$this->module.$params[self::PRESENTER_KEY];unset($params[self::PRESENTER_KEY]);return
  1430. new
  1431. PresenterRequest($presenter,$httpRequest->getMethod(),$params,$httpRequest->getPost(),$httpRequest->getFiles(),array(PresenterRequest::SECURED=>$httpRequest->isSecured()));}function
  1432. constructUrl(PresenterRequest$appRequest,IHttpRequest$httpRequest){$params=$appRequest->getParams();$presenter=$appRequest->getPresenterName();if(strncasecmp($presenter,$this->module,strlen($this->module))===0){$params[self::PRESENTER_KEY]=substr($presenter,strlen($this->module));}else{return
  1433. NULL;}foreach($this->defaults
  1434. as$key=>$value){if(isset($params[$key])&&$params[$key]==$value){unset($params[$key]);}}$uri=$httpRequest->getUri();$uri=($this->flags&self::SECURED?'https://':'http://').$uri->getAuthority().$uri->getScriptPath();$sep=ini_get('arg_separator.input');$query=http_build_query($params,'',$sep?$sep[0]:'&');if($query!=''){$uri.='?'.$query;}return$uri;}function
  1435. getDefaults(){return$this->defaults;}}final
  1436. class
  1437. ArrayTools{final
  1438. function
  1439. __construct(){throw
  1440. new
  1441. LogicException("Cannot instantiate static class ".get_class($this));}static
  1442. function
  1443. get(array$arr,$key,$default=NULL){foreach(is_array($key)?$key:array($key)as$k){if(is_array($arr)&&array_key_exists($k,$arr)){$arr=$arr[$k];}else{return$default;}}return$arr;}static
  1444. function&getRef(&$arr,$key){foreach(is_array($key)?$key:array($key)as$k){if(is_array($arr)||$arr===NULL){$arr=&$arr[$k];}else{throw
  1445. new
  1446. InvalidArgumentException('Traversed item is not an array.');}}return$arr;}static
  1447. function
  1448. mergeTree($arr1,$arr2){$res=$arr1+$arr2;foreach(array_intersect_key($arr1,$arr2)as$k=>$v){if(is_array($v)&&is_array($arr2[$k])){$res[$k]=self::mergeTree($v,$arr2[$k]);}}return$res;}static
  1449. function
  1450. searchKey($arr,$key){$foo=array($key=>NULL);return
  1451. array_search(key($foo),array_keys($arr),TRUE);}static
  1452. function
  1453. insertBefore(array&$arr,$key,array$inserted){$offset=self::searchKey($arr,$key);$arr=array_slice($arr,0,$offset,TRUE)+$inserted+array_slice($arr,$offset,count($arr),TRUE);}static
  1454. function
  1455. insertAfter(array&$arr,$key,array$inserted){$offset=self::searchKey($arr,$key);$offset=$offset===FALSE?count($arr):$offset+1;$arr=array_slice($arr,0,$offset,TRUE)+$inserted+array_slice($arr,$offset,count($arr),TRUE);}static
  1456. function
  1457. renameKey(array&$arr,$oldKey,$newKey){$offset=self::searchKey($arr,$oldKey);if($offset!==FALSE){$keys=array_keys($arr);$keys[$offset]=$newKey;$arr=array_combine($keys,$arr);}}}class
  1458. Cache
  1459. extends
  1460. Object
  1461. implements
  1462. ArrayAccess{const
  1463. PRIORITY='priority';const
  1464. EXPIRE='expire';const
  1465. SLIDING='sliding';const
  1466. TAGS='tags';const
  1467. FILES='files';const
  1468. ITEMS='items';const
  1469. CONSTS='consts';const
  1470. CALLBACKS='callbacks';const
  1471. ALL='all';const
  1472. REFRESH='sliding';const
  1473. NAMESPACE_SEPARATOR="\x00";private$storage;private$namespace;private$key;private$data;function
  1474. __construct(ICacheStorage$storage,$namespace=NULL){$this->storage=$storage;$this->namespace=(string)$namespace;if(strpos($this->namespace,self::NAMESPACE_SEPARATOR)!==FALSE){throw
  1475. new
  1476. InvalidArgumentException("Namespace name contains forbidden character.");}}function
  1477. getStorage(){return$this->storage;}function
  1478. getNamespace(){return$this->namespace;}function
  1479. release(){$this->key=$this->data=NULL;}function
  1480. save($key,$data,array$dp=NULL){if(!is_string($key)&&!is_int($key)){throw
  1481. new
  1482. InvalidArgumentException("Cache key name must be string or integer, ".gettype($key)." given.");}if(!empty($dp[Cache::EXPIRE])){$dp[Cache::EXPIRE]=Tools::createDateTime($dp[Cache::EXPIRE])->format('U')-time();}if(isset($dp[self::FILES])){foreach((array)$dp[self::FILES]as$item){$dp[self::CALLBACKS][]=array(array(__CLASS__,'checkFile'),$item,@filemtime($item));}unset($dp[self::FILES]);}if(isset($dp[self::ITEMS])){$dp[self::ITEMS]=(array)$dp[self::ITEMS];foreach($dp[self::ITEMS]as$k=>$item){$dp[self::ITEMS][$k]=$this->namespace.self::NAMESPACE_SEPARATOR.$item;}}if(isset($dp[self::CONSTS])){foreach((array)$dp[self::CONSTS]as$item){$dp[self::CALLBACKS][]=array(array(__CLASS__,'checkConst'),$item,constant($item));}unset($dp[self::CONSTS]);}if(is_object($data)){$dp[self::CALLBACKS][]=array(array(__CLASS__,'checkSerializationVersion'),get_class($data),ClassReflection::from($data)->getAnnotation('serializationVersion'));}$this->key=NULL;$this->storage->write($this->namespace.self::NAMESPACE_SEPARATOR.$key,$data,(array)$dp);return$data;}function
  1483. clean(array$conds=NULL){$this->storage->clean((array)$conds);}function
  1484. offsetSet($key,$data){if(!is_string($key)&&!is_int($key)){throw
  1485. new
  1486. InvalidArgumentException("Cache key name must be string or integer, ".gettype($key)." given.");}$this->key=$this->data=NULL;if($data===NULL){$this->storage->remove($this->namespace.self::NAMESPACE_SEPARATOR.$key);}else{$this->storage->write($this->namespace.self::NAMESPACE_SEPARATOR.$key,$data,array());}}function
  1487. offsetGet($key){if(!is_string($key)&&!is_int($key)){throw
  1488. new
  1489. InvalidArgumentException("Cache key name must be string or integer, ".gettype($key)." given.");}$key=(string)$key;if($this->key===$key){return$this->data;}$this->key=$key;$this->data=$this->storage->read($this->namespace.self::NAMESPACE_SEPARATOR.$key);return$this->data;}function
  1490. offsetExists($key){if(!is_string($key)&&!is_int($key)){throw
  1491. new
  1492. InvalidArgumentException("Cache key name must be string or integer, ".gettype($key)." given.");}$this->key=(string)$key;$this->data=$this->storage->read($this->namespace.self::NAMESPACE_SEPARATOR.$key);return$this->data!==NULL;}function
  1493. offsetUnset($key){if(!is_string($key)&&!is_int($key)){throw
  1494. new
  1495. InvalidArgumentException("Cache key name must be string or integer, ".gettype($key)." given.");}$this->key=$this->data=NULL;$this->storage->remove($this->namespace.self::NAMESPACE_SEPARATOR.$key);}static
  1496. function
  1497. checkCallbacks($callbacks){foreach($callbacks
  1498. as$callback){$func=array_shift($callback);if(!call_user_func_array($func,$callback)){return
  1499. FALSE;}}return
  1500. TRUE;}private
  1501. static
  1502. function
  1503. checkConst($const,$value){return
  1504. defined($const)&&constant($const)===$value;}private
  1505. static
  1506. function
  1507. checkFile($file,$time){return@filemtime($file)==$time;}private
  1508. static
  1509. function
  1510. checkSerializationVersion($class,$value){return
  1511. ClassReflection::from($class)->getAnnotation('serializationVersion')===$value;}}class
  1512. DummyStorage
  1513. extends
  1514. Object
  1515. implements
  1516. ICacheStorage{function
  1517. read($key){return
  1518. NULL;}function
  1519. write($key,$data,array$dp){}function
  1520. remove($key){}function
  1521. clean(array$conds){}}class
  1522. FileStorage
  1523. extends
  1524. Object
  1525. implements
  1526. ICacheStorage{const
  1527. META_HEADER_LEN=28;const
  1528. META_TIME='time';const
  1529. META_SERIALIZED='serialized';const
  1530. META_EXPIRE='expire';const
  1531. META_DELTA='delta';const
  1532. META_ITEMS='di';const
  1533. META_CALLBACKS='callbacks';const
  1534. FILE='file';const
  1535. HANDLE='handle';public
  1536. static$gcProbability=0.001;public
  1537. static$useDirectories;private$dir;private$useDirs;private$db;function
  1538. __construct($dir){if(self::$useDirectories===NULL){self::$useDirectories=!ini_get('safe_mode');$uniq=uniqid('_',TRUE);umask(0000);if(!@mkdir("$dir/$uniq",0777)){throw
  1539. new
  1540. InvalidStateException("Unable to write to directory '$dir'. Make this directory writable.");}if(!self::$useDirectories&&@file_put_contents("$dir/$uniq/_",'')!==FALSE){self::$useDirectories=TRUE;unlink("$dir/$uniq/_");}rmdir("$dir/$uniq");}$this->dir=$dir;$this->useDirs=(bool)self::$useDirectories;if(mt_rand()/mt_getrandmax()<self::$gcProbability){$this->clean(array());}}function
  1541. read($key){$meta=$this->readMeta($this->getCacheFile($key),LOCK_SH);if($meta&&$this->verify($meta)){return$this->readData($meta);}else{return
  1542. NULL;}}private
  1543. function
  1544. verify($meta){do{if(!empty($meta[self::META_DELTA])){if(filemtime($meta[self::FILE])+$meta[self::META_DELTA]<time())break;touch($meta[self::FILE]);}elseif(!empty($meta[self::META_EXPIRE])&&$meta[self::META_EXPIRE]<time()){break;}if(!empty($meta[self::META_CALLBACKS])&&!Cache::checkCallbacks($meta[self::META_CALLBACKS])){break;}if(!empty($meta[self::META_ITEMS])){foreach($meta[self::META_ITEMS]as$depFile=>$time){$m=$this->readMeta($depFile,LOCK_SH);if($m[self::META_TIME]!==$time)break
  1545. 2;if($m&&!$this->verify($m))break
  1546. 2;}}return
  1547. TRUE;}while(FALSE);$this->delete($meta[self::FILE],$meta[self::HANDLE]);return
  1548. FALSE;}function
  1549. write($key,$data,array$dp){$meta=array(self::META_TIME=>microtime());if(!is_string($data)){$data=serialize($data);$meta[self::META_SERIALIZED]=TRUE;}if(!empty($dp[Cache::EXPIRE])){if(empty($dp[Cache::SLIDING])){$meta[self::META_EXPIRE]=$dp[Cache::EXPIRE]+time();}else{$meta[self::META_DELTA]=(int)$dp[Cache::EXPIRE];}}if(!empty($dp[Cache::ITEMS])){foreach((array)$dp[Cache::ITEMS]as$item){$depFile=$this->getCacheFile($item);$m=$this->readMeta($depFile,LOCK_SH);$meta[self::META_ITEMS][$depFile]=$m[self::META_TIME];unset($m);}}if(!empty($dp[Cache::CALLBACKS])){$meta[self::META_CALLBACKS]=$dp[Cache::CALLBACKS];}$cacheFile=$this->getCacheFile($key);if($this->useDirs&&!is_dir($dir=dirname($cacheFile))){umask(0000);if(!mkdir($dir,0777,TRUE)){return;}}$handle=@fopen($cacheFile,'r+b');if(!$handle){$handle=fopen($cacheFile,'wb');if(!$handle){return;}}if(!empty($dp[Cache::TAGS])||isset($dp[Cache::PRIORITY])){$db=$this->getDb();$dbFile=sqlite_escape_string($cacheFile);$query='';if(!empty($dp[Cache::TAGS])){foreach((array)$dp[Cache::TAGS]as$tag){$query.="INSERT INTO cache (file, tag) VALUES ('$dbFile', '".sqlite_escape_string($tag)."');";}}if(isset($dp[Cache::PRIORITY])){$query.="INSERT INTO cache (file, priority) VALUES ('$dbFile', '".(int)$dp[Cache::PRIORITY]."');";}if(!sqlite_exec($db,"BEGIN; DELETE FROM cache WHERE file = '$dbFile'; $query COMMIT;")){return;}}flock($handle,LOCK_EX);ftruncate($handle,0);$head=serialize($meta).'?>';$head='<?php //netteCache[01]'.str_pad((string)strlen($head),6,'0',STR_PAD_LEFT).$head;$headLen=strlen($head);$dataLen=strlen($data);do{if(fwrite($handle,str_repeat("\x00",$headLen),$headLen)!==$headLen){break;}if(fwrite($handle,$data,$dataLen)!==$dataLen){break;}fseek($handle,0);if(fwrite($handle,$head,$headLen)!==$headLen){break;}fclose($handle);return
  1550. TRUE;}while(FALSE);$this->delete($cacheFile,$handle);}function
  1551. remove($key){$this->delete($this->getCacheFile($key));}function
  1552. clean(array$conds){$all=!empty($conds[Cache::ALL]);$collector=empty($conds);if($all||$collector){$now=time();$base=$this->dir.DIRECTORY_SEPARATOR.'c';$iterator=new
  1553. RecursiveIteratorIterator(new
  1554. RecursiveDirectoryIterator($this->dir),RecursiveIteratorIterator::CHILD_FIRST);foreach($iterator
  1555. as$entry){$path=(string)$entry;if(strncmp($path,$base,strlen($base))){continue;}if($entry->isDir()){@rmdir($path);continue;}if($all){$this->delete($path);}else{$meta=$this->readMeta($path,LOCK_SH);if(!$meta)continue;if(!empty($meta[self::META_EXPIRE])&&$meta[self::META_EXPIRE]<$now){$this->delete($path,$meta[self::HANDLE]);continue;}fclose($meta[self::HANDLE]);}}if($all&&extension_loaded('sqlite')){sqlite_exec("DELETE FROM cache",$this->getDb());}return;}if(!empty($conds[Cache::TAGS])){$db=$this->getDb();foreach((array)$conds[Cache::TAGS]as$tag){$tmp[]="'".sqlite_escape_string($tag)."'";}$query[]="tag IN (".implode(',',$tmp).")";}if(isset($conds[Cache::PRIORITY])){$query[]="priority <= ".(int)$conds[Cache::PRIORITY];}if(isset($query)){$db=$this->getDb();$query=implode(' OR ',$query);$files=sqlite_single_query("SELECT file FROM cache WHERE $query",$db,FALSE);foreach($files
  1556. as$file){$this->delete($file);}sqlite_exec("DELETE FROM cache WHERE $query",$db);}}protected
  1557. function
  1558. readMeta($file,$lock){$handle=@fopen($file,'r+b');if(!$handle)return
  1559. NULL;flock($handle,$lock);$head=stream_get_contents($handle,self::META_HEADER_LEN);if($head&&strlen($head)===self::META_HEADER_LEN){$size=(int)substr($head,-6);$meta=stream_get_contents($handle,$size,self::META_HEADER_LEN);$meta=@unserialize($meta);if(is_array($meta)){fseek($handle,$size+self::META_HEADER_LEN);$meta[self::FILE]=$file;$meta[self::HANDLE]=$handle;return$meta;}}fclose($handle);return
  1560. NULL;}protected
  1561. function
  1562. readData($meta){$data=stream_get_contents($meta[self::HANDLE]);fclose($meta[self::HANDLE]);if(empty($meta[self::META_SERIALIZED])){return$data;}else{return@unserialize($data);}}protected
  1563. function
  1564. getCacheFile($key){if($this->useDirs){$key=explode(Cache::NAMESPACE_SEPARATOR,$key,2);return$this->dir.'/c'.(isset($key[1])?'-'.urlencode($key[0]).'/_'.urlencode($key[1]):'_'.urlencode($key[0]));}else{return$this->dir.'/c_'.urlencode($key);}}private
  1565. static
  1566. function
  1567. delete($file,$handle=NULL){if(@unlink($file)){if($handle)fclose($handle);return;}if(!$handle){$handle=@fopen($file,'r+');}if($handle){flock($handle,LOCK_EX);ftruncate($handle,0);fclose($handle);@unlink($file);}}protected
  1568. function
  1569. getDb(){if($this->db===NULL){if(!extension_loaded('sqlite')){throw
  1570. new
  1571. InvalidStateException("SQLite extension is required for storing tags and priorities.");}$this->db=sqlite_open($this->dir.'/cachejournal.sdb');@sqlite_exec($this->db,'CREATE TABLE cache (file VARCHAR NOT NULL, priority, tag VARCHAR);
  1572. CREATE INDEX IDX_FILE ON cache (file); CREATE INDEX IDX_PRI ON cache (priority); CREATE INDEX IDX_TAG ON cache (tag);');}return$this->db;}}class
  1573. MemcachedStorage
  1574. extends
  1575. Object
  1576. implements
  1577. ICacheStorage{const
  1578. META_CALLBACKS='callbacks';const
  1579. META_DATA='data';const
  1580. META_DELTA='delta';private$memcache;private$prefix;static
  1581. function
  1582. isAvailable(){return
  1583. extension_loaded('memcache');}function
  1584. __construct($host='localhost',$port=11211,$prefix=''){if(!self::isAvailable()){throw
  1585. new
  1586. Exception("PHP extension 'memcache' is not loaded.");}$this->prefix=$prefix;$this->memcache=new
  1587. Memcache;$this->memcache->connect($host,$port);}function
  1588. read($key){$key=$this->prefix.$key;$meta=$this->memcache->get($key);if(!$meta)return
  1589. NULL;if(!empty($meta[self::META_CALLBACKS])&&!Cache::checkCallbacks($meta[self::META_CALLBACKS])){$this->memcache->delete($key);return
  1590. NULL;}if(!empty($meta[self::META_DELTA])){$this->memcache->replace($key,$meta,0,$meta[self::META_DELTA]+time());}return$meta[self::META_DATA];}function
  1591. write($key,$data,array$dp){if(!empty($dp[Cache::TAGS])||isset($dp[Cache::PRIORITY])||!empty($dp[Cache::ITEMS])){throw
  1592. new
  1593. NotSupportedException('Tags, priority and dependent items are not supported by MemcachedStorage.');}$meta=array(self::META_DATA=>$data);$expire=0;if(!empty($dp[Cache::EXPIRE])){$expire=(int)$dp[Cache::EXPIRE];if(!empty($dp[Cache::SLIDING])){$meta[self::META_DELTA]=$expire;}}if(!empty($dp[Cache::CALLBACKS])){$meta[self::META_CALLBACKS]=$dp[Cache::CALLBACKS];}$this->memcache->set($this->prefix.$key,$meta,0,$expire);}function
  1594. remove($key){$this->memcache->delete($this->prefix.$key);}function
  1595. clean(array$conds){if(!empty($conds[Cache::ALL])){$this->memcache->flush();}elseif(isset($conds[Cache::TAGS])||isset($conds[Cache::PRIORITY])){throw
  1596. new
  1597. NotSupportedException('Tags and priority is not supported by MemcachedStorage.');}}}class
  1598. KeyNotFoundException
  1599. extends
  1600. RuntimeException{}class
  1601. Hashtable
  1602. extends
  1603. Collection
  1604. implements
  1605. IMap{private$throwKeyNotFound=FALSE;function
  1606. add($key,$item){if(!is_scalar($key)){throw
  1607. new
  1608. InvalidArgumentException("Key must be either a string or an integer, ".gettype($key)." given.");}if(parent::offsetExists($key)){throw
  1609. new
  1610. InvalidStateException('An element with the same key already exists.');}$this->beforeAdd($item);parent::offsetSet($key,$item);return
  1611. TRUE;}function
  1612. append($item){throw
  1613. new
  1614. NotSupportedException;}function
  1615. getKeys(){return
  1616. array_keys($this->getArrayCopy());}function
  1617. search($item){return
  1618. array_search($item,$this->getArrayCopy(),TRUE);}function
  1619. import($arr){$this->updating();if(!(is_array($arr)||$arr
  1620. instanceof
  1621. Traversable)){throw
  1622. new
  1623. InvalidArgumentException("Argument must be traversable.");}if($this->getItemType()===NULL){$this->setArray((array)$arr);}else{$this->clear();foreach($arr
  1624. as$key=>$item){$this->offsetSet($key,$item);}}}function
  1625. get($key,$default=NULL){if(!is_scalar($key)){throw
  1626. new
  1627. InvalidArgumentException("Key must be either a string or an integer, ".gettype($key)." given.");}if(parent::offsetExists($key)){return
  1628. parent::offsetGet($key);}else{return$default;}}function
  1629. throwKeyNotFound($val=TRUE){$this->throwKeyNotFound=(bool)$val;}function
  1630. offsetSet($key,$item){if(!is_scalar($key)){throw
  1631. new
  1632. InvalidArgumentException("Key must be either a string or an integer, ".gettype($key)." given.");}$this->beforeAdd($item);parent::offsetSet($key,$item);}function
  1633. offsetGet($key){if(!is_scalar($key)){throw
  1634. new
  1635. InvalidArgumentException("Key must be either a string or an integer, ".gettype($key)." given.");}if(parent::offsetExists($key)){return
  1636. parent::offsetGet($key);}elseif($this->throwKeyNotFound){throw
  1637. new
  1638. KeyNotFoundException;}else{return
  1639. NULL;}}function
  1640. offsetExists($key){if(!is_scalar($key)){throw
  1641. new
  1642. InvalidArgumentException("Key must be either a string or an integer, ".gettype($key)." given.");}return
  1643. parent::offsetExists($key);}function
  1644. offsetUnset($key){$this->updating();if(!is_scalar($key)){throw
  1645. new
  1646. InvalidArgumentException("Key must be either a string or an integer, ".gettype($key)." given.");}if(parent::offsetExists($key)){parent::offsetUnset($key);}}}class
  1647. Set
  1648. extends
  1649. Collection
  1650. implements
  1651. ISet{function
  1652. append($item){$this->beforeAdd($item);if(is_object($item)){$key=spl_object_hash($item);if(parent::offsetExists($key)){return
  1653. FALSE;}parent::offsetSet($key,$item);return
  1654. TRUE;}else{$key=$this->search($item);if($key===FALSE){parent::offsetSet(NULL,$item);return
  1655. TRUE;}return
  1656. FALSE;}}protected
  1657. function
  1658. search($item){if(is_object($item)){$key=spl_object_hash($item);return
  1659. parent::offsetExists($key)?$key:FALSE;}else{return
  1660. array_search($item,$this->getArrayCopy(),TRUE);}}function
  1661. offsetSet($key,$item){if($key===NULL){$this->append($item);}else{throw
  1662. new
  1663. NotSupportedException;}}function
  1664. offsetGet($key){throw
  1665. new
  1666. NotSupportedException;}function
  1667. offsetExists($key){throw
  1668. new
  1669. NotSupportedException;}function
  1670. offsetUnset($key){throw
  1671. new
  1672. NotSupportedException;}}class
  1673. DateTime53
  1674. extends
  1675. DateTime{function
  1676. __sleep(){$this->fix=array($this->format('Y-m-d H:i:s'),$this->getTimezone()->getName());return
  1677. array('fix');}function
  1678. __wakeup(){$this->__construct($this->fix[0],new
  1679. DateTimeZone($this->fix[1]));unset($this->fix);}function
  1680. getTimestamp(){return(int)$this->format('U');}function
  1681. setTimestamp($timestamp){return$this->__construct(date('Y-m-d H:i:s',$timestamp),new
  1682. DateTimeZone($this->getTimezone()->getName()));}}class
  1683. Config
  1684. extends
  1685. Hashtable{const
  1686. READONLY=1;const
  1687. EXPAND=2;private
  1688. static$extensions=array('ini'=>'ConfigAdapterIni');static
  1689. function
  1690. registerExtension($extension,$class){if(!class_exists($class)){throw
  1691. new
  1692. InvalidArgumentException("Class '$class' was not found.");}if(!ClassReflection::from($class)->implementsInterface('IConfigAdapter')){throw
  1693. new
  1694. InvalidArgumentException("Configuration adapter '$class' is not Nette\\Config\\IConfigAdapter implementor.");}self::$extensions[strtolower($extension)]=$class;}static
  1695. function
  1696. fromFile($file,$section=NULL,$flags=self::READONLY){$extension=strtolower(pathinfo($file,PATHINFO_EXTENSION));if(isset(self::$extensions[$extension])){$arr=call_user_func(array(self::$extensions[$extension],'load'),$file,$section);return
  1697. new
  1698. self($arr,$flags);}else{throw
  1699. new
  1700. InvalidArgumentException("Unknown file extension '$file'.");}}function
  1701. __construct($arr=NULL,$flags=self::READONLY){parent::__construct($arr);if($arr!==NULL){if($flags&self::EXPAND){$this->expand();}if($flags&self::READONLY){$this->freeze();}}}function
  1702. save($file,$section=NULL){$extension=strtolower(pathinfo($file,PATHINFO_EXTENSION));if(isset(self::$extensions[$extension])){return
  1703. call_user_func(array(self::$extensions[$extension],'save'),$this,$file,$section);}else{throw
  1704. new
  1705. InvalidArgumentException("Unknown file extension '$file'.");}}function
  1706. expand(){$this->updating();$data=$this->getArrayCopy();foreach($data
  1707. as$key=>$val){if(is_string($val)){$data[$key]=Environment::expand($val);}elseif($val
  1708. instanceof
  1709. self){$val->expand();}}$this->setArray($data);}function
  1710. import($arr){$this->updating();foreach($arr
  1711. as$key=>$val){if(is_array($val)){$arr[$key]=$obj=clone$this;$obj->import($val);}}$this->setArray($arr);}function
  1712. toArray(){$res=$this->getArrayCopy();foreach($res
  1713. as$key=>$val){if($val
  1714. instanceof
  1715. self){$res[$key]=$val->toArray();}}return$res;}function
  1716. freeze(){parent::freeze();foreach($this->getArrayCopy()as$val){if($val
  1717. instanceof
  1718. self){$val->freeze();}}}function
  1719. __clone(){parent::__clone();$data=$this->getArrayCopy();foreach($data
  1720. as$key=>$val){if($val
  1721. instanceof
  1722. self){$data[$key]=clone$val;}}$this->setArray($data);}function&__get($key){$val=$this->offsetGet($key);return$val;}function
  1723. __set($key,$item){$this->offsetSet($key,$item);}function
  1724. __isset($key){return$this->offsetExists($key);}function
  1725. __unset($key){$this->offsetUnset($key);}}final
  1726. class
  1727. ConfigAdapterIni
  1728. implements
  1729. IConfigAdapter{public
  1730. static$keySeparator='.';public
  1731. static$sectionSeparator=' < ';public
  1732. static$rawSection='!';final
  1733. function
  1734. __construct(){throw
  1735. new
  1736. LogicException("Cannot instantiate static class ".get_class($this));}static
  1737. function
  1738. load($file,$section=NULL){if(!is_file($file)||!is_readable($file)){throw
  1739. new
  1740. FileNotFoundException("File '$file' is missing or is not readable.");}Tools::tryError();$ini=parse_ini_file($file,TRUE);if(Tools::catchError($msg)){throw
  1741. new
  1742. Exception($msg);}$separator=trim(self::$sectionSeparator);$data=array();foreach($ini
  1743. as$secName=>$secData){if(is_array($secData)){if(substr($secName,-1)===self::$rawSection){$secName=substr($secName,0,-1);}elseif(self::$keySeparator){$tmp=array();foreach($secData
  1744. as$key=>$val){$cursor=&$tmp;foreach(explode(self::$keySeparator,$key)as$part){if(!isset($cursor[$part])||is_array($cursor[$part])){$cursor=&$cursor[$part];}else{throw
  1745. new
  1746. InvalidStateException("Invalid key '$key' in section [$secName] in '$file'.");}}$cursor=$val;}$secData=$tmp;}$parts=$separator?explode($separator,strtr($secName,':',$separator)):array($secName);if(count($parts)>1){$parent=trim($parts[1]);$cursor=&$data;foreach(self::$keySeparator?explode(self::$keySeparator,$parent):array($parent)as$part){if(isset($cursor[$part])&&is_array($cursor[$part])){$cursor=&$cursor[$part];}else{throw
  1747. new
  1748. InvalidStateException("Missing parent section [$parent] in '$file'.");}}$secData=ArrayTools::mergeTree($secData,$cursor);}$secName=trim($parts[0]);if($secName===''){throw
  1749. new
  1750. InvalidStateException("Invalid empty section name in '$file'.");}}if(self::$keySeparator){$cursor=&$data;foreach(explode(self::$keySeparator,$secName)as$part){if(!isset($cursor[$part])||is_array($cursor[$part])){$cursor=&$cursor[$part];}else{throw
  1751. new
  1752. InvalidStateException("Invalid section [$secName] in '$file'.");}}}else{$cursor=&$data[$secName];}if(is_array($secData)&&is_array($cursor)){$secData=ArrayTools::mergeTree($secData,$cursor);}$cursor=$secData;}if($section===NULL){return$data;}elseif(!isset($data[$section])||!is_array($data[$section])){throw
  1753. new
  1754. InvalidStateException("There is not section [$section] in '$file'.");}else{return$data[$section];}}static
  1755. function
  1756. save($config,$file,$section=NULL){$output=array();$output[]='; generated by Nette';$output[]='';if($section===NULL){foreach($config
  1757. as$secName=>$secData){if(!(is_array($secData)||$secData
  1758. instanceof
  1759. Traversable)){throw
  1760. new
  1761. InvalidStateException("Invalid section '$section'.");}$output[]="[$secName]";self::build($secData,$output,'');$output[]='';}}else{$output[]="[$section]";self::build($config,$output,'');$output[]='';}if(!file_put_contents($file,implode(PHP_EOL,$output))){throw
  1762. new
  1763. IOException("Cannot write file '$file'.");}}private
  1764. static
  1765. function
  1766. build($input,&$output,$prefix){foreach($input
  1767. as$key=>$val){if(is_array($val)||$val
  1768. instanceof
  1769. Traversable){self::build($val,$output,$prefix.$key.self::$keySeparator);}elseif(is_bool($val)){$output[]="$prefix$key = ".($val?'true':'false');}elseif(is_numeric($val)){$output[]="$prefix$key = $val";}elseif(is_string($val)){$output[]="$prefix$key = \"$val\"";}else{throw
  1770. new
  1771. InvalidArgumentException("The '$prefix$key' item must be scalar or array, ".gettype($val)." given.");}}}}class
  1772. Configurator
  1773. extends
  1774. Object{public$defaultConfigFile='%appDir%/config.ini';public$defaultServices=array('Nette\Application\Application'=>'Nette\Application\Application','Nette\Web\HttpContext'=>'Nette\Web\HttpContext','Nette\Web\IHttpRequest'=>'Nette\Web\HttpRequest','Nette\Web\IHttpResponse'=>'Nette\Web\HttpResponse','Nette\Web\IUser'=>'Nette\Web\User','Nette\Caching\ICacheStorage'=>array(__CLASS__,'createCacheStorage'),'Nette\Web\Session'=>'Nette\Web\Session','Nette\Loaders\RobotLoader'=>array(__CLASS__,'createRobotLoader'));function
  1775. detect($name){switch($name){case'environment':if($this->detect('console')){return
  1776. Environment::CONSOLE;}else{return
  1777. Environment::getMode('production')?Environment::PRODUCTION:Environment::DEVELOPMENT;}case'production':if(PHP_SAPI==='cli'){return
  1778. FALSE;}elseif(isset($_SERVER['SERVER_ADDR'])||isset($_SERVER['LOCAL_ADDR'])){$addr=isset($_SERVER['SERVER_ADDR'])?$_SERVER['SERVER_ADDR']:$_SERVER['LOCAL_ADDR'];$oct=explode('.',$addr);return$addr!=='::1'&&(count($oct)!==4||($oct[0]!=='10'&&$oct[0]!=='127'&&($oct[0]!=='172'||$oct[1]<16||$oct[1]>31)&&($oct[0]!=='169'||$oct[1]!=='254')&&($oct[0]!=='192'||$oct[1]!=='168')));}else{return
  1779. TRUE;}case'console':return
  1780. PHP_SAPI==='cli';default:return
  1781. NULL;}}function
  1782. loadConfig($file){$name=Environment::getName();if($file
  1783. instanceof
  1784. Config){$config=$file;$file=NULL;}else{if($file===NULL){$file=$this->defaultConfigFile;}$file=Environment::expand($file);$config=Config::fromFile($file,$name,0);}if($config->variable
  1785. instanceof
  1786. Config){foreach($config->variable
  1787. as$key=>$value){Environment::setVariable($key,$value);}}$config->expand();$runServices=array();$locator=Environment::getServiceLocator();if($config->service
  1788. instanceof
  1789. Config){foreach($config->service
  1790. as$key=>$value){$key=strtr($key,'-','\\');if(is_string($value)){$locator->removeService($key);$locator->addService($key,$value);}else{if($value->factory){$locator->removeService($key);$locator->addService($key,$value->factory,isset($value->singleton)?$value->singleton:TRUE,(array)$value->option);}if($value->run){$runServices[]=$key;}}}}if(!$config->php){$config->php=$config->set;unset($config->set);}if($config->php
  1791. instanceof
  1792. Config){if(PATH_SEPARATOR!==';'&&isset($config->php->include_path)){$config->php->include_path=str_replace(';',PATH_SEPARATOR,$config->php->include_path);}foreach($config->php
  1793. as$key=>$value){if($value
  1794. instanceof
  1795. Config){unset($config->php->$key);foreach($value
  1796. as$k=>$v){$config->php->{"$key.$k"}=$v;}}}foreach($config->php
  1797. as$key=>$value){$key=strtr($key,'-','.');if(!is_scalar($value)){throw
  1798. new
  1799. InvalidStateException("Configuration value for directive '$key' is not scalar.");}if(function_exists('ini_set')){ini_set($key,$value);}else{switch($key){case'include_path':set_include_path($value);break;case'iconv.internal_encoding':iconv_set_encoding('internal_encoding',$value);break;case'mbstring.internal_encoding':mb_internal_encoding($value);break;case'date.timezone':date_default_timezone_set($value);break;case'error_reporting':error_reporting($value);break;case'ignore_user_abort':ignore_user_abort($value);break;case'max_execution_time':set_time_limit($value);break;default:if(ini_get($key)!=$value){throw
  1800. new
  1801. NotSupportedException('Required function ini_set() is disabled.');}}}}}if($config->const
  1802. instanceof
  1803. Config){foreach($config->const
  1804. as$key=>$value){define($key,$value);}}if(isset($config->mode)){foreach($config->mode
  1805. as$mode=>$state){Environment::setMode($mode,$state);}}foreach($runServices
  1806. as$name){$locator->getService($name);}$config->freeze();return$config;}function
  1807. createServiceLocator(){$locator=new
  1808. ServiceLocator;foreach($this->defaultServices
  1809. as$name=>$service){$locator->addService($name,$service);}return$locator;}static
  1810. function
  1811. createCacheStorage(){return
  1812. new
  1813. FileStorage(Environment::getVariable('tempDir'));}static
  1814. function
  1815. createRobotLoader($options){$loader=new
  1816. RobotLoader;$loader->autoRebuild=!Environment::isProduction();$dirs=isset($options['directory'])?$options['directory']:array(Environment::getVariable('appDir'),Environment::getVariable('libsDir'));$loader->addDirectory($dirs);$loader->register();return$loader;}}final
  1817. class
  1818. Debug{public
  1819. static$productionMode;public
  1820. static$consoleMode;public
  1821. static$time;private
  1822. static$firebugDetected;private
  1823. static$ajaxDetected;private
  1824. static$consoleData;public
  1825. static$maxDepth=3;public
  1826. static$maxLen=150;public
  1827. static$showLocation=FALSE;const
  1828. DEVELOPMENT=FALSE;const
  1829. PRODUCTION=TRUE;const
  1830. DETECT=NULL;public
  1831. static$strictMode=FALSE;public
  1832. static$onFatalError=array();public
  1833. static$mailer=array(__CLASS__,'defaultMailer');public
  1834. static$emailSnooze=172800;private
  1835. static$enabled=FALSE;private
  1836. static$logFile;private
  1837. static$logHandle;private
  1838. static$sendEmails;private
  1839. static$emailHeaders=array('To'=>'','From'=>'noreply@%host%','X-Mailer'=>'Nette Framework','Subject'=>'PHP: An error occurred on the server %host%','Body'=>'[%date%] %message%');private
  1840. static$colophons=array(array(__CLASS__,'getDefaultColophons'));private
  1841. static$enabledProfiler=FALSE;public
  1842. static$counters=array();const
  1843. LOG='LOG';const
  1844. INFO='INFO';const
  1845. WARN='WARN';const
  1846. ERROR='ERROR';const
  1847. TRACE='TRACE';const
  1848. EXCEPTION='EXCEPTION';const
  1849. GROUP_START='GROUP_START';const
  1850. GROUP_END='GROUP_END';final
  1851. function
  1852. __construct(){throw
  1853. new
  1854. LogicException("Cannot instantiate static class ".get_class($this));}static
  1855. function
  1856. _init(){self::$time=microtime(TRUE);self::$consoleMode=PHP_SAPI==='cli';self::$productionMode=self::DETECT;self::$firebugDetected=isset($_SERVER['HTTP_USER_AGENT'])&&strpos($_SERVER['HTTP_USER_AGENT'],'FirePHP/');self::$ajaxDetected=isset($_SERVER['HTTP_X_REQUESTED_WITH'])&&$_SERVER['HTTP_X_REQUESTED_WITH']==='XMLHttpRequest';register_shutdown_function(array(__CLASS__,'_shutdownHandler'));}static
  1857. function
  1858. _shutdownHandler(){static$types=array(E_ERROR=>1,E_CORE_ERROR=>1,E_COMPILE_ERROR=>1,E_PARSE=>1);$error=error_get_last();if(self::$enabled&&isset($types[$error['type']])){if(!headers_sent()){header('HTTP/1.1 500 Internal Server Error');}if(ini_get('html_errors')){$error['message']=html_entity_decode(strip_tags($error['message']),ENT_QUOTES,'UTF-8');}self::processException(new
  1859. FatalErrorException($error['message'],0,$error['type'],$error['file'],$error['line'],NULL),TRUE);}if(self::$productionMode){return;}foreach(headers_list()as$header){if(strncasecmp($header,'Content-Type:',13)===0){if(substr($header,14,9)==='text/html'){break;}return;}}if(self::$enabledProfiler){if(self::$firebugDetected){self::fireLog('Nette profiler',self::GROUP_START);foreach(self::$colophons
  1860. as$callback){foreach((array)call_user_func($callback,'profiler')as$line)self::fireLog(strip_tags($line));}self::fireLog(NULL,self::GROUP_END);}if(!self::$ajaxDetected){$colophons=self::$colophons;?>
  1861. <style type="text/css">
  1862. /* <![CDATA[ */
  1863. #netteProfilerContainer {
  1864. position: fixed;
  1865. _position: absolute;
  1866. right: 5px;
  1867. bottom: 5px;
  1868. z-index: 23178;
  1869. }
  1870. #netteProfiler {
  1871. font: normal normal 11px/1.4 Consolas, Arial;
  1872. position: relative;
  1873. padding: 3px;
  1874. color: black;
  1875. background: #EEE;
  1876. border: 1px dotted gray;
  1877. cursor: move;
  1878. opacity: .70;
  1879. =filter: alpha(opacity=70);
  1880. }
  1881. #netteProfiler * {
  1882. color: inherit;
  1883. background: inherit;
  1884. text-align: inherit;
  1885. }
  1886. #netteProfilerIcon {
  1887. position: absolute;
  1888. right: 0;
  1889. top: 0;
  1890. line-height: 1;
  1891. padding: 2px;
  1892. color: black;
  1893. text-decoration: none;
  1894. }
  1895. #netteProfiler:hover {
  1896. opacity: 1;
  1897. =filter: none;
  1898. }
  1899. #netteProfiler ul {
  1900. margin: 0;
  1901. padding: 0;
  1902. width: 350px;
  1903. }
  1904. #netteProfiler li {
  1905. margin: 0;
  1906. padding: 1px;
  1907. text-align: left;
  1908. list-style: none;
  1909. }
  1910. #netteProfiler span[title] {
  1911. border-bottom: 1px dotted gray;
  1912. cursor: help;
  1913. }
  1914. #netteProfiler strong {
  1915. color: red;
  1916. }
  1917. /* ]]> */
  1918. </style>
  1919. <div id="netteProfilerContainer">
  1920. <div id="netteProfiler">
  1921. <a id="netteProfilerIcon" href="#"><abbr>&#x25bc;</abbr></a
  1922. ><ul>
  1923. <?php foreach($colophons
  1924. as$callback):?>
  1925. <?php foreach((array)call_user_func($callback,'profiler')as$line):?><li><?php echo$line,"\n"?></li><?php endforeach?>
  1926. <?php endforeach?>
  1927. </ul>
  1928. </div>
  1929. </div>
  1930. <script type="text/javascript">
  1931. /* <![CDATA[ */
  1932. document.getElementById('netteProfiler').onmousedown = function(e) {
  1933. e = e || event;
  1934. this.posX = parseInt(this.style.left + '0');
  1935. this.posY = parseInt(this.style.top + '0');
  1936. this.mouseX = e.clientX;
  1937. this.mouseY = e.clientY;
  1938. var thisObj = this;
  1939. document.documentElement.onmousemove = function(e) {
  1940. e = e || event;
  1941. thisObj.style.left = (e.clientX - thisObj.mouseX + thisObj.posX) + "px";
  1942. thisObj.style.top = (e.clientY - thisObj.mouseY + thisObj.posY) + "px";
  1943. return false;
  1944. };
  1945. document.documentElement.onmouseup = function(e) {
  1946. document.documentElement.onmousemove = null;
  1947. document.documentElement.onmouseup = null;
  1948. document.cookie = 'netteProfilerPosition=' + thisObj.style.left + ':' + thisObj.style.top + '; path=/';
  1949. return false;
  1950. };
  1951. };
  1952. document.getElementById('netteProfilerIcon').onclick = function(e) {
  1953. var arrow = this.getElementsByTagName('abbr')[0];
  1954. var panel = this.nextSibling;
  1955. var collapsed = panel.currentStyle ? panel.currentStyle.display == 'none' : getComputedStyle(panel, null).display == 'none';
  1956. arrow.innerHTML = collapsed ? String.fromCharCode(0x25bc) : 'Profiler ' + String.fromCharCode(0x25ba);
  1957. panel.style.display = collapsed ? 'block' : 'none';
  1958. arrow.parentNode.style.position = collapsed ? 'absolute' : 'static';
  1959. document.cookie = 'netteProfilerVisible=' + collapsed*1 + '; path=/';
  1960. return false;
  1961. }
  1962. document.body.appendChild(document.getElementById('netteProfilerContainer'));
  1963. if (document.cookie.indexOf('netteProfilerVisible=0') > -1) {
  1964. document.getElementById('netteProfilerIcon').onclick();
  1965. }
  1966. var _nettePos = document.cookie.match(/netteProfilerPosition=([0-9-]+px):([0-9-]+px)/);
  1967. if (_nettePos) {
  1968. document.getElementById('netteProfiler').style.left = _nettePos[1];
  1969. document.getElementById('netteProfiler').style.top = _nettePos[2];
  1970. }
  1971. /* ]]> */
  1972. </script>
  1973. <?php }}if(self::$consoleData){$payload=self::$consoleData;if(!function_exists('_netteDumpCb2')){function
  1974. _netteDumpCb2($m){return"$m[1]<a href='#' onclick='return !netteToggle(this)'>$m[2]($m[3]) ".($m[3]<7?'<abbr>&#x25bc;</abbr> </a><code>':'<abbr>&#x25ba;</abbr> </a><code class="collapsed">');}}ob_start();?><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  1975. <html lang="en">
  1976. <head>
  1977. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  1978. <meta name="robots" content="noindex,noarchive">
  1979. <meta name="generator" content="Nette Framework">
  1980. <title>Nette Debug Console</title>
  1981. <style type="text/css">
  1982. /* <![CDATA[ */
  1983. body {
  1984. margin: 0;
  1985. padding: 0;
  1986. font: 9pt/1.5 Verdana, sans-serif;
  1987. background: white;
  1988. color: #333;
  1989. }
  1990. h1 {
  1991. font-size: 13pt;
  1992. margin: 0;
  1993. padding: 2px 8px;
  1994. background: black;
  1995. color: white;
  1996. border-bottom: 1px solid black;
  1997. }
  1998. h2 {
  1999. font: 11pt/1.5 sans-serif;
  2000. margin: 0;
  2001. padding: 2px 8px;
  2002. background: #3484d2;
  2003. color: white;
  2004. }
  2005. a {
  2006. text-decoration: none;
  2007. color: #4197E3;
  2008. }
  2009. a abbr {
  2010. font-family: sans-serif;
  2011. color: #999;
  2012. }
  2013. p {
  2014. margin: .8em 0
  2015. }
  2016. pre, code, table {
  2017. font: 9pt/1.5 Consolas, monospace;
  2018. }
  2019. pre, table {
  2020. background: #fffbcc;
  2021. padding: .4em .7em;
  2022. border: 1px dotted silver;
  2023. }
  2024. table pre {
  2025. padding: 0;
  2026. margin: 0;
  2027. border: none;
  2028. }
  2029. pre.dump span {
  2030. color: #c16549;
  2031. }
  2032. pre.dump a {
  2033. color: #333;
  2034. }
  2035. table {
  2036. border-collapse: collapse;
  2037. width: 100%;
  2038. }
  2039. td, th {
  2040. vertical-align: top;
  2041. text-align: left;
  2042. border: 1px solid #eeeebb;
  2043. }
  2044. th {
  2045. width: 10;
  2046. padding: 2px 3px 2px 8px;
  2047. font-weight: bold;
  2048. }
  2049. td {
  2050. padding: 2px 8px 2px 3px;
  2051. }
  2052. .odd, .odd pre {
  2053. background: #faf5c3;
  2054. }
  2055. /* ]]> */
  2056. </style>
  2057. <script type="text/javascript">
  2058. /* <![CDATA[ */
  2059. document.write('<style> .collapsed { display: none; } <\/style>');
  2060. function netteToggle(link, panelId)
  2061. {
  2062. var arrow = link.getElementsByTagName('abbr')[0];
  2063. var panel = panelId ? document.getElementById(panelId) : link.nextSibling;
  2064. while (panel.nodeType !== 1) panel = panel.nextSibling;
  2065. var collapsed = panel.currentStyle ? panel.currentStyle.display == 'none' : getComputedStyle(panel, null).display == 'none';
  2066. arrow.innerHTML = String.fromCharCode(collapsed ? 0x25bc : 0x25ba);
  2067. panel.style.display = collapsed ? (panel.tagName.toLowerCase() === 'code' ? 'inline' : 'block') : 'none';
  2068. return true;
  2069. }
  2070. /* ]]> */
  2071. </script>
  2072. </head>
  2073. <body>
  2074. <h1>Nette Debug Console</h1>
  2075. </body>
  2076. </html>
  2077. <?php $document=ob_get_clean()?>
  2078. <?php ob_start()?>
  2079. <?php foreach($payload
  2080. as$item):?>
  2081. <?php if($item['title']):?>
  2082. <h2><?php echo
  2083. htmlspecialchars($item['title'])?></h2>
  2084. <?php endif?>
  2085. <table>
  2086. <?php $i=0?>
  2087. <?php foreach($item['dump']as$key=>$dump):?>
  2088. <tr class="<?php echo$i++%
  2089. 2?'odd':'even'?>">
  2090. <th><?php echo
  2091. htmlspecialchars($key)?></th>
  2092. <td><?php echo
  2093. preg_replace_callback('#(<pre class="dump">|\s+)?(.*)\((\d+)\) <code>#','_netteDumpCb2',$dump)?></td>
  2094. </tr>
  2095. <?php endforeach?>
  2096. </table>
  2097. <?php endforeach?>
  2098. <?php $body=ob_get_clean()?>
  2099. <script type="text/javascript">
  2100. /* <![CDATA[ */
  2101. if (typeof _netteConsole === 'undefined') {
  2102. _netteConsole = window.open('','_netteConsole','width=700,height=700,resizable,scrollbars=yes');
  2103. _netteConsole.document.write(<?php echo
  2104. json_encode(preg_replace('#[ \t\r\n]+#',' ',$document))?>);
  2105. _netteConsole.document.close();
  2106. _netteConsole.document.onkeyup = function(e) {
  2107. e = e || _netteConsole.event;
  2108. if (e.keyCode == 27) _netteConsole.close();
  2109. }
  2110. _netteConsole.document.body.focus();
  2111. }
  2112. _netteConsole.document.body.innerHTML = _netteConsole.document.body.innerHTML + <?php echo
  2113. json_encode($body)?>;
  2114. /* ]]> */
  2115. </script>
  2116. <?php }}static
  2117. function
  2118. dump($var,$return=FALSE){if(!$return&&self::$productionMode){return$var;}$output="<pre class=\"dump\">".self::_dump($var,0)."</pre>\n";if(self::$showLocation){$trace=debug_backtrace();$i=isset($trace[1]['class'])&&$trace[1]['class']===__CLASS__?1:0;if(isset($trace[$i]['file'],$trace[$i]['line'])){$output=substr_replace($output,' <small>'.htmlspecialchars("in file {$trace[$i]['file']} on line {$trace[$i]['line']}",ENT_NOQUOTES).'</small>',-8,0);}}if(self::$consoleMode){$output=htmlspecialchars_decode(strip_tags($output),ENT_NOQUOTES);}if($return){return$output;}else{echo$output;return$var;}}static
  2119. function
  2120. consoleDump($var,$title=NULL){if(!self::$productionMode){$dump=array();foreach((is_array($var)?$var:array(''=>$var))as$key=>$val){$dump[$key]=self::dump($val,TRUE);}self::$consoleData[]=array('title'=>$title,'dump'=>$dump);}return$var;}private
  2121. static
  2122. function
  2123. _dump(&$var,$level){static$tableUtf,$tableBin,$re='#[^\x09\x0A\x0D\x20-\x7E\xA0-\x{10FFFF}]#u';if($tableUtf===NULL){foreach(range("\x00","\xFF")as$ch){if(ord($ch)<32&&strpos("\r\n\t",$ch)===FALSE)$tableUtf[$ch]=$tableBin[$ch]='\\x'.str_pad(dechex(ord($ch)),2,'0',STR_PAD_LEFT);elseif(ord($ch)<127)$tableUtf[$ch]=$tableBin[$ch]=$ch;else{$tableUtf[$ch]=$ch;$tableBin[$ch]='\\x'.dechex(ord($ch));}}$tableUtf['\\x']=$tableBin['\\x']='\\\\x';}if(is_bool($var)){return"<span>bool</span>(".($var?'TRUE':'FALSE').")\n";}elseif($var===NULL){return"<span>NULL</span>\n";}elseif(is_int($var)){return"<span>int</span>($var)\n";}elseif(is_float($var)){return"<span>float</span>($var)\n";}elseif(is_string($var)){if(self::$maxLen&&strlen($var)>self::$maxLen){$s=htmlSpecialChars(substr($var,0,self::$maxLen),ENT_NOQUOTES).' ... ';}else{$s=htmlSpecialChars($var,ENT_NOQUOTES);}$s=strtr($s,preg_match($re,$s)||preg_last_error()?$tableBin:$tableUtf);return"<span>string</span>(".strlen($var).") \"$s\"\n";}elseif(is_array($var)){$s="<span>array</span>(".count($var).") ";$space=str_repeat($space1=' ',$level);static$marker;if($marker===NULL)$marker=uniqid("\x00",TRUE);if(empty($var)){}elseif(isset($var[$marker])){$s.="{\n$space$space1*RECURSION*\n$space}";}elseif($level<self::$maxDepth||!self::$maxDepth){$s.="<code>{\n";$var[$marker]=0;foreach($var
  2124. as$k=>&$v){if($k===$marker)continue;$k=is_int($k)?$k:'"'.strtr($k,preg_match($re,$k)||preg_last_error()?$tableBin:$tableUtf).'"';$s.="$space$space1$k => ".self::_dump($v,$level+1);}unset($var[$marker]);$s.="$space}</code>";}else{$s.="{\n$space$space1...\n$space}";}return$s."\n";}elseif(is_object($var)){$arr=(array)$var;$s="<span>object</span>(".get_class($var).") (".count($arr).") ";$space=str_repeat($space1=' ',$level);static$list=array();if(empty($arr)){$s.="{}";}elseif(in_array($var,$list,TRUE)){$s.="{\n$space$space1*RECURSION*\n$space}";}elseif($level<self::$maxDepth||!self::$maxDepth){$s.="<code>{\n";$list[]=$var;foreach($arr
  2125. as$k=>&$v){$m='';if($k[0]==="\x00"){$m=$k[1]==='*'?' <span>protected</span>':' <span>private</span>';$k=substr($k,strrpos($k,"\x00")+1);}$k=strtr($k,preg_match($re,$k)||preg_last_error()?$tableBin:$tableUtf);$s.="$space$space1\"$k\"$m => ".self::_dump($v,$level+1);}array_pop($list);$s.="$space}</code>";}else{$s.="{\n$space$space1...\n$space}";}return$s."\n";}elseif(is_resource($var)){return"<span>resource of type</span>(".get_resource_type($var).")\n";}else{return"<span>unknown type</span>\n";}}static
  2126. function
  2127. timer($name=NULL){static$time=array();$now=microtime(TRUE);$delta=isset($time[$name])?$now-$time[$name]:0;$time[$name]=$now;return$delta;}static
  2128. function
  2129. enable($mode=NULL,$logFile=NULL,$email=NULL){error_reporting(E_ALL|E_STRICT);if(is_bool($mode)){self::$productionMode=$mode;}elseif(is_string($mode)){$mode=preg_split('#[,\s]+#',$mode);}if(is_array($mode)){self::$productionMode=!isset($_SERVER['REMOTE_ADDR'])||!in_array($_SERVER['REMOTE_ADDR'],$mode,TRUE);}if(self::$productionMode===self::DETECT){if(class_exists('Environment')){self::$productionMode=Environment::isProduction();}elseif(isset($_SERVER['SERVER_ADDR'])||isset($_SERVER['LOCAL_ADDR'])){$addr=isset($_SERVER['SERVER_ADDR'])?$_SERVER['SERVER_ADDR']:$_SERVER['LOCAL_ADDR'];$oct=explode('.',$addr);self::$productionMode=$addr!=='::1'&&(count($oct)!==4||($oct[0]!=='10'&&$oct[0]!=='127'&&($oct[0]!=='172'||$oct[1]<16||$oct[1]>31)&&($oct[0]!=='169'||$oct[1]!=='254')&&($oct[0]!=='192'||$oct[1]!=='168')));}else{self::$productionMode=!self::$consoleMode;}}if(self::$productionMode&&$logFile!==FALSE){self::$logFile='log/php_error.log';if(class_exists('Environment')){if(is_string($logFile)){self::$logFile=Environment::expand($logFile);}else
  2130. try{self::$logFile=Environment::expand('%logDir%/php_error.log');}catch(InvalidStateException$e){}}elseif(is_string($logFile)){self::$logFile=$logFile;}ini_set('error_log',self::$logFile);}if(function_exists('ini_set')){ini_set('display_errors',!self::$productionMode);ini_set('html_errors',!self::$logFile&&!self::$consoleMode);ini_set('log_errors',(bool)self::$logFile);}elseif(ini_get('log_errors')!=(bool)self::$logFile||(ini_get('display_errors')!=!self::$productionMode&&ini_get('display_errors')!==(self::$productionMode?'stderr':'stdout'))){throw
  2131. new
  2132. LogicException('Function ini_set() must be enabled.');}self::$sendEmails=self::$logFile&&$email;if(self::$sendEmails){if(is_string($email)){self::$emailHeaders['To']=$email;}elseif(is_array($email)){self::$emailHeaders=$email+self::$emailHeaders;}}if(!defined('E_DEPRECATED')){define('E_DEPRECATED',8192);}if(!defined('E_USER_DEPRECATED')){define('E_USER_DEPRECATED',16384);}set_exception_handler(array(__CLASS__,'_exceptionHandler'));set_error_handler(array(__CLASS__,'_errorHandler'));self::$enabled=TRUE;}static
  2133. function
  2134. isEnabled(){return
  2135. self::$enabled;}static
  2136. function
  2137. _exceptionHandler(Exception$exception){if(!headers_sent()){header('HTTP/1.1 500 Internal Server Error');}self::processException($exception,TRUE);exit;}static
  2138. function
  2139. _errorHandler($severity,$message,$file,$line,$context){if($severity===E_RECOVERABLE_ERROR||$severity===E_USER_ERROR){throw
  2140. new
  2141. FatalErrorException($message,0,$severity,$file,$line,$context);}elseif(($severity&error_reporting())!==$severity){return
  2142. NULL;}elseif(self::$strictMode){self::_exceptionHandler(new
  2143. FatalErrorException($message,0,$severity,$file,$line,$context),TRUE);}static$types=array(E_WARNING=>'Warning',E_USER_WARNING=>'Warning',E_NOTICE=>'Notice',E_USER_NOTICE=>'Notice',E_STRICT=>'Strict standards',E_DEPRECATED=>'Deprecated',E_USER_DEPRECATED=>'Deprecated');$type=isset($types[$severity])?$types[$severity]:'Unknown error';if(self::$logFile){if(self::$sendEmails){self::sendEmail("$type: $message in $file on line $line");}return
  2144. FALSE;}elseif(!self::$productionMode&&self::$firebugDetected&&!headers_sent()){$message=strip_tags($message);self::fireLog("$type: $message in $file on line $line",self::ERROR);return
  2145. NULL;}return
  2146. FALSE;}static
  2147. function
  2148. processException(Exception$exception,$outputAllowed=FALSE){if(!self::$enabled){return;}elseif(self::$logFile){try{$hash=md5($exception.(method_exists($exception,'getPrevious')?$exception->getPrevious():(isset($exception->previous)?$exception->previous:'')));error_log("PHP Fatal error: Uncaught $exception");foreach(new
  2149. DirectoryIterator(dirname(self::$logFile))as$entry){if(strpos($entry,$hash)){$skip=TRUE;break;}}$file=dirname(self::$logFile)."/exception ".@date('Y-m-d H-i-s')." $hash.html";if(empty($skip)&&self::$logHandle=@fopen($file,'x')){ob_start();ob_start(array(__CLASS__,'_writeFile'),1);self::_paintBlueScreen($exception);ob_end_flush();ob_end_clean();fclose(self::$logHandle);}if(self::$sendEmails){self::sendEmail((string)$exception);}}catch(Exception$e){if(!headers_sent()){header('HTTP/1.1 500 Internal Server Error');}echo'Nette\Debug fatal error: ',get_class($e),': ',($e->getCode()?'#'.$e->getCode().' ':'').$e->getMessage(),"\n";exit;}}elseif(self::$productionMode){}elseif(self::$consoleMode){if($outputAllowed){echo"$exception\n";foreach(self::$colophons
  2150. as$callback){foreach((array)call_user_func($callback,'bluescreen')as$line)echo
  2151. strip_tags($line)."\n";}}}elseif(self::$firebugDetected&&self::$ajaxDetected&&!headers_sent()){self::fireLog($exception,self::EXCEPTION);}elseif($outputAllowed){if(!headers_sent()){@ob_end_clean();while(ob_get_level()&&@ob_end_clean());if(in_array('Content-Encoding: gzip',headers_list()))header('Content-Encoding: identity',TRUE);}self::_paintBlueScreen($exception);}elseif(self::$firebugDetected&&!headers_sent()){self::fireLog($exception,self::EXCEPTION);}foreach(self::$onFatalError
  2152. as$handler){call_user_func($handler,$exception);}}static
  2153. function
  2154. toStringException(Exception$exception){if(self::$enabled){self::_exceptionHandler($exception);}else{trigger_error($exception->getMessage(),E_USER_ERROR);}}static
  2155. function
  2156. _paintBlueScreen(Exception$exception){$internals=array();foreach(array('Object','ObjectMixin')as$class){if(class_exists($class,FALSE)){$rc=new
  2157. ReflectionClass($class);$internals[$rc->getFileName()]=TRUE;}}if(class_exists('Environment',FALSE)){$application=Environment::getServiceLocator()->hasService('Nette\Application\Application',TRUE)?Environment::getServiceLocator()->getService('Nette\Application\Application'):NULL;}$colophons=self::$colophons;if(!function_exists('_netteDebugPrintCode')){function
  2158. _netteDebugPrintCode($file,$line,$count=15){if(function_exists('ini_set')){ini_set('highlight.comment','#999; font-style: italic');ini_set('highlight.default','#000');ini_set('highlight.html','#06b');ini_set('highlight.keyword','#d24; font-weight: bold');ini_set('highlight.string','#080');}$start=max(1,$line-floor($count/2));$source=@file_get_contents($file);if(!$source)return;$source=explode("\n",highlight_string($source,TRUE));$spans=1;echo$source[0];$source=explode('<br />',$source[1]);array_unshift($source,NULL);$i=$start;while(--$i>=1){if(preg_match('#.*(</?span[^>]*>)#',$source[$i],$m)){if($m[1]!=='</span>'){$spans++;echo$m[1];}break;}}$source=array_slice($source,$start,$count,TRUE);end($source);$numWidth=strlen((string)key($source));foreach($source
  2159. as$n=>$s){$spans+=substr_count($s,'<span')-substr_count($s,'</span');$s=str_replace(array("\r","\n"),array('',''),$s);if($n===$line){printf("<span class='highlight'>Line %{$numWidth}s: %s\n</span>%s",$n,strip_tags($s),preg_replace('#[^>]*(<[^>]+>)[^<]*#','$1',$s));}else{printf("<span class='line'>Line %{$numWidth}s:</span> %s\n",$n,$s);}}echo
  2160. str_repeat('</span>',$spans),'</code>';}function
  2161. _netteDump($dump){return'<pre class="dump">'.preg_replace_callback('#(^|\s+)?(.*)\((\d+)\) <code>#','_netteDumpCb',$dump).'</pre>';}function
  2162. _netteDumpCb($m){return"$m[1]<a href='#' onclick='return !netteToggle(this)'>$m[2]($m[3]) ".(trim($m[1])||$m[3]<7?'<abbr>&#x25bc;</abbr> </a><code>':'<abbr>&#x25ba;</abbr> </a><code class="collapsed">');}function
  2163. _netteOpenPanel($name,$collapsed){static$id;$id++;?>
  2164. <div class="panel">
  2165. <h2><a href="#" onclick="return !netteToggle(this, 'pnl<?php echo$id?>')"><?php echo
  2166. htmlSpecialChars($name)?> <abbr><?php echo$collapsed?'&#x25ba;':'&#x25bc;'?></abbr></a></h2>
  2167. <div id="pnl<?php echo$id?>" class="<?php echo$collapsed?'collapsed ':''?>inner">
  2168. <?php
  2169. }function
  2170. _netteClosePanel(){?>
  2171. </div>
  2172. </div>
  2173. <?php
  2174. }}static$errorTypes=array(E_ERROR=>'Fatal Error',E_USER_ERROR=>'User Error',E_RECOVERABLE_ERROR=>'Recoverable Error',E_CORE_ERROR=>'Core Error',E_COMPILE_ERROR=>'Compile Error',E_PARSE=>'Parse Error',E_WARNING=>'Warning',E_CORE_WARNING=>'Core Warning',E_COMPILE_WARNING=>'Compile Warning',E_USER_WARNING=>'User Warning',E_NOTICE=>'Notice',E_USER_NOTICE=>'User Notice',E_STRICT=>'Strict',E_DEPRECATED=>'Deprecated',E_USER_DEPRECATED=>'User Deprecated');$title=($exception
  2175. instanceof
  2176. FatalErrorException&&isset($errorTypes[$exception->getSeverity()]))?$errorTypes[$exception->getSeverity()]:get_class($exception);$rn=0;if(headers_sent()){echo'</pre></xmp></table>';}?><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  2177. <html lang="en">
  2178. <head>
  2179. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  2180. <meta name="robots" content="noindex,noarchive">
  2181. <meta name="generator" content="Nette Framework">
  2182. <title><?php echo
  2183. htmlspecialchars($title)?></title><!-- <?php echo$exception->getMessage(),($exception->getCode()?' #'.$exception->getCode():'')?> -->
  2184. <style type="text/css">
  2185. /* <![CDATA[ */
  2186. body {
  2187. margin: 0 0 2em;
  2188. padding: 0;
  2189. }
  2190. #netteBluescreen {
  2191. font: 9pt/1.5 Verdana, sans-serif;
  2192. background: white;
  2193. color: #333;
  2194. position: absolute;
  2195. left: 0;
  2196. top: 0;
  2197. width: 100%;
  2198. z-index: 23178;
  2199. text-align: left;
  2200. }
  2201. #netteBluescreen * {
  2202. color: inherit;
  2203. background: inherit;
  2204. text-align: inherit;
  2205. }
  2206. #netteBluescreenIcon {
  2207. position: absolute;
  2208. right: .5em;
  2209. top: .5em;
  2210. z-index: 23179;
  2211. text-decoration: none;
  2212. background: red;
  2213. padding: 3px;
  2214. }
  2215. #netteBluescreenIcon abbr {
  2216. color: black !important;
  2217. }
  2218. #netteBluescreen h1 {
  2219. font: 18pt/1.5 Verdana, sans-serif !important;
  2220. margin: .6em 0;
  2221. }
  2222. #netteBluescreen h2 {
  2223. font: 14pt/1.5 sans-serif !important;
  2224. color: #888;
  2225. margin: .6em 0;
  2226. }
  2227. #netteBluescreen a {
  2228. text-decoration: none;
  2229. color: #4197E3;
  2230. }
  2231. #netteBluescreen a abbr {
  2232. font-family: sans-serif;
  2233. color: #999;
  2234. }
  2235. #netteBluescreen h3 {
  2236. font: bold 10pt/1.5 Verdana, sans-serif !important;
  2237. margin: 1em 0;
  2238. padding: 0;
  2239. }
  2240. #netteBluescreen p {
  2241. margin: .8em 0
  2242. }
  2243. #netteBluescreen pre, #netteBluescreen code, #netteBluescreen table {
  2244. font: 9pt/1.5 Consolas, monospace !important;
  2245. }
  2246. #netteBluescreen pre, #netteBluescreen table {
  2247. background: #fffbcc;
  2248. padding: .4em .7em;
  2249. border: 1px dotted silver;
  2250. }
  2251. #netteBluescreen table pre {
  2252. padding: 0;
  2253. margin: 0;
  2254. border: none;
  2255. }
  2256. #netteBluescreen pre.dump span {
  2257. color: #c16549;
  2258. }
  2259. #netteBluescreen pre.dump a {
  2260. color: #333;
  2261. }
  2262. #netteBluescreen div.panel {
  2263. border-bottom: 1px solid #eee;
  2264. padding: 1px 2em;
  2265. }
  2266. #netteBluescreen div.inner {
  2267. padding: 0.1em 1em 1em;
  2268. background: #f5f5f5;
  2269. }
  2270. #netteBluescreen table {
  2271. border-collapse: collapse;
  2272. width: 100%;
  2273. }
  2274. #netteBluescreen td, #netteBluescreen th {
  2275. vertical-align: top;
  2276. text-align: left;
  2277. padding: 2px 3px;
  2278. border: 1px solid #eeeebb;
  2279. }
  2280. #netteBluescreen th {
  2281. width: 10%;
  2282. font-weight: bold;
  2283. }
  2284. #netteBluescreen .odd, #netteBluescreen .odd pre {
  2285. background-color: #faf5c3;
  2286. }
  2287. #netteBluescreen ul {
  2288. font: 7pt/1.5 Verdana, sans-serif !important;
  2289. padding: 1em 2em 50px;
  2290. }
  2291. #netteBluescreen .highlight, #netteBluescreenError {
  2292. background: red;
  2293. color: white;
  2294. font-weight: bold;
  2295. font-style: normal;
  2296. display: block;
  2297. }
  2298. #netteBluescreen .line {
  2299. color: #9e9e7e;
  2300. font-weight: normal;
  2301. font-style: normal;
  2302. }
  2303. /* ]]> */
  2304. </style>
  2305. <script type="text/javascript">
  2306. /* <![CDATA[ */
  2307. document.write('<style> .collapsed { display: none; } <\/style>');
  2308. function netteToggle(link, panelId)
  2309. {
  2310. var arrow = link.getElementsByTagName('abbr')[0];
  2311. var panel = panelId ? document.getElementById(panelId) : link.nextSibling;
  2312. while (panel.nodeType !== 1) panel = panel.nextSibling;
  2313. var collapsed = panel.currentStyle ? panel.currentStyle.display == 'none' : getComputedStyle(panel, null).display == 'none';
  2314. arrow.innerHTML = String.fromCharCode(collapsed ? 0x25bc : 0x25ba);
  2315. panel.style.display = collapsed ? (panel.tagName.toLowerCase() === 'code' ? 'inline' : 'block') : 'none';
  2316. return true;
  2317. }
  2318. /* ]]> */
  2319. </script>
  2320. </head>
  2321. <body>
  2322. <div id="netteBluescreen">
  2323. <a id="netteBluescreenIcon" href="#" onclick="return !netteToggle(this)"><abbr>&#x25bc;</abbr></a
  2324. ><div>
  2325. <div id="netteBluescreenError" class="panel">
  2326. <h1><?php echo
  2327. htmlspecialchars($title),($exception->getCode()?' #'.$exception->getCode():'')?></h1>
  2328. <p><?php echo
  2329. htmlspecialchars($exception->getMessage())?></p>
  2330. </div>
  2331. <?php $ex=$exception;$level=0;?>
  2332. <?php do{?>
  2333. <?php if($level++):?>
  2334. <?php _netteOpenPanel('Caused by',$level>2)?>
  2335. <div class="panel">
  2336. <h1><?php echo
  2337. htmlspecialchars(get_class($ex)),($ex->getCode()?' #'.$ex->getCode():'')?></h1>
  2338. <p><?php echo
  2339. htmlspecialchars($ex->getMessage())?></p>
  2340. </div>
  2341. <?php endif?>
  2342. <?php $collapsed=isset($internals[$ex->getFile()]);?>
  2343. <?php if(is_file($ex->getFile())):?>
  2344. <?php _netteOpenPanel('Source file',$collapsed)?>
  2345. <p><strong>File:</strong> <?php echo
  2346. htmlspecialchars($ex->getFile())?> &nbsp; <strong>Line:</strong> <?php echo$ex->getLine()?></p>
  2347. <pre><?php _netteDebugPrintCode($ex->getFile(),$ex->getLine())?></pre>
  2348. <?php _netteClosePanel()?>
  2349. <?php endif?>
  2350. <?php _netteOpenPanel('Call stack',FALSE)?>
  2351. <ol>
  2352. <?php foreach($ex->getTrace()as$key=>$row):?>
  2353. <li><p>
  2354. <?php if(isset($row['file'])):?>
  2355. <span title="<?php echo
  2356. htmlSpecialChars($row['file'])?>"><?php echo
  2357. htmlSpecialChars(basename(dirname($row['file']))),'/<b>',htmlSpecialChars(basename($row['file'])),'</b></span> (',$row['line'],')'?>
  2358. <?php else:?>
  2359. &lt;PHP inner-code&gt;
  2360. <?php endif?>
  2361. <?php if(isset($row['file'])&&is_file($row['file'])):?><a href="#" onclick="return !netteToggle(this, 'src<?php echo"$level-$key"?>')">source <abbr>&#x25ba;</abbr></a>&nbsp; <?php endif?>
  2362. <?php if(isset($row['class']))echo$row['class'].$row['type']?>
  2363. <?php echo$row['function']?>
  2364. (<?php if(!empty($row['args'])):?><a href="#" onclick="return !netteToggle(this, 'args<?php echo"$level-$key"?>')">arguments <abbr>&#x25ba;</abbr></a><?php endif?>)
  2365. </p>
  2366. <?php if(!empty($row['args'])):?>
  2367. <div class="collapsed" id="args<?php echo"$level-$key"?>">
  2368. <table>
  2369. <?php
  2370. try{$r=isset($row['class'])?new
  2371. ReflectionMethod($row['class'],$row['function']):new
  2372. ReflectionFunction($row['function']);$params=$r->getParameters();}catch(Exception$e){$params=array();}foreach($row['args']as$k=>$v){echo'<tr><th>',(isset($params[$k])?'$'.$params[$k]->name:"#$k"),'</th><td>';echo
  2373. _netteDump(self::_dump($v,0));echo"</td></tr>\n";}?>
  2374. </table>
  2375. </div>
  2376. <?php endif?>
  2377. <?php if(isset($row['file'])&&is_file($row['file'])):?>
  2378. <pre <?php if(!$collapsed||isset($internals[$row['file']]))echo'class="collapsed"';else$collapsed=FALSE?> id="src<?php echo"$level-$key"?>"><?php _netteDebugPrintCode($row['file'],$row['line'])?></pre>
  2379. <?php endif?>
  2380. </li>
  2381. <?php endforeach?>
  2382. <?php if(!isset($row)):?>
  2383. <li><i>empty</i></li>
  2384. <?php endif?>
  2385. </ol>
  2386. <?php _netteClosePanel()?>
  2387. <?php if($ex
  2388. instanceof
  2389. IDebuggable):?>
  2390. <?php foreach($ex->getPanels()as$name=>$panel):?>
  2391. <?php _netteOpenPanel($name,empty($panel['expanded']))?>
  2392. <?php echo$panel['content']?>
  2393. <?php _netteClosePanel()?>
  2394. <?php endforeach?>
  2395. <?php endif?>
  2396. <?php if(isset($ex->context)&&is_array($ex->context)):?>
  2397. <?php _netteOpenPanel('Variables',TRUE)?>
  2398. <table>
  2399. <?php
  2400. foreach($ex->context
  2401. as$k=>$v){echo'<tr><th>$',htmlspecialchars($k),'</th><td>',_netteDump(self::_dump($v,0)),"</td></tr>\n";}?>
  2402. </table>
  2403. <?php _netteClosePanel()?>
  2404. <?php endif?>
  2405. <?php }while((method_exists($ex,'getPrevious')&&$ex=$ex->getPrevious())||(isset($ex->previous)&&$ex=$ex->previous));?>
  2406. <?php while(--$level)_netteClosePanel()?>
  2407. <?php if(!empty($application)):?>
  2408. <?php _netteOpenPanel('Nette Application',TRUE)?>
  2409. <h3>Requests</h3>
  2410. <?php $tmp=$application->getRequests();echo
  2411. _netteDump(self::_dump($tmp,0))?>
  2412. <h3>Presenter</h3>
  2413. <?php $tmp=$application->getPresenter();echo
  2414. _netteDump(self::_dump($tmp,0))?>
  2415. <?php _netteClosePanel()?>
  2416. <?php endif?>
  2417. <?php _netteOpenPanel('Environment',TRUE)?>
  2418. <?php
  2419. $list=get_defined_constants(TRUE);if(!empty($list['user'])):?>
  2420. <h3><a href="#" onclick="return !netteToggle(this, 'pnl-env-const')">Constants <abbr>&#x25bc;</abbr></a></h3>
  2421. <table id="pnl-env-const">
  2422. <?php
  2423. foreach($list['user']as$k=>$v){echo'<tr'.($rn++%2?' class="odd"':'').'><th>',htmlspecialchars($k),'</th>';echo'<td>',_netteDump(self::_dump($v,0)),"</td></tr>\n";}?>
  2424. </table>
  2425. <?php endif?>
  2426. <h3><a href="#" onclick="return !netteToggle(this, 'pnl-env-files')">Included files <abbr>&#x25ba;</abbr></a>(<?php echo
  2427. count(get_included_files())?>)</h3>
  2428. <table id="pnl-env-files" class="collapsed">
  2429. <?php
  2430. foreach(get_included_files()as$v){echo'<tr'.($rn++%2?' class="odd"':'').'><td>',htmlspecialchars($v),"</td></tr>\n";}?>
  2431. </table>
  2432. <h3>$_SERVER</h3>
  2433. <?php if(empty($_SERVER)):?>
  2434. <p><i>empty</i></p>
  2435. <?php else:?>
  2436. <table>
  2437. <?php
  2438. foreach($_SERVER
  2439. as$k=>$v)echo'<tr'.($rn++%2?' class="odd"':'').'><th>',htmlspecialchars($k),'</th><td>',_netteDump(self::_dump($v,0)),"</td></tr>\n";?>
  2440. </table>
  2441. <?php endif?>
  2442. <?php _netteClosePanel()?>
  2443. <?php _netteOpenPanel('HTTP request',TRUE)?>
  2444. <?php if(function_exists('apache_request_headers')):?>
  2445. <h3>Headers</h3>
  2446. <table>
  2447. <?php
  2448. foreach(apache_request_headers()as$k=>$v)echo'<tr'.($rn++%2?' class="odd"':'').'><th>',htmlspecialchars($k),'</th><td>',htmlspecialchars($v),"</td></tr>\n";?>
  2449. </table>
  2450. <?php endif?>
  2451. <?php foreach(array('_GET','_POST','_COOKIE')as$name):?>
  2452. <h3>$<?php echo$name?></h3>
  2453. <?php if(empty($GLOBALS[$name])):?>
  2454. <p><i>empty</i></p>
  2455. <?php else:?>
  2456. <table>
  2457. <?php
  2458. foreach($GLOBALS[$name]as$k=>$v)echo'<tr'.($rn++%2?' class="odd"':'').'><th>',htmlspecialchars($k),'</th><td>',_netteDump(self::_dump($v,0)),"</td></tr>\n";?>
  2459. </table>
  2460. <?php endif?>
  2461. <?php endforeach?>
  2462. <?php _netteClosePanel()?>
  2463. <?php _netteOpenPanel('HTTP response',TRUE)?>
  2464. <h3>Headers</h3>
  2465. <?php if(headers_list()):?>
  2466. <pre><?php
  2467. foreach(headers_list()as$s)echo
  2468. htmlspecialchars($s),'<br>';?></pre>
  2469. <?php else:?>
  2470. <p><i>no headers</i></p>
  2471. <?php endif?>
  2472. <?php _netteClosePanel()?>
  2473. <ul>
  2474. <?php foreach($colophons
  2475. as$callback):?>
  2476. <?php foreach((array)call_user_func($callback,'bluescreen')as$line):?><li><?php echo$line,"\n"?></li><?php endforeach?>
  2477. <?php endforeach?>
  2478. </ul>
  2479. </div>
  2480. </div>
  2481. <script type="text/javascript">
  2482. document.body.appendChild(document.getElementById('netteBluescreen'));
  2483. </script>
  2484. </body>
  2485. </html><?php }static
  2486. function
  2487. _writeFile($buffer){fwrite(self::$logHandle,$buffer);}private
  2488. static
  2489. function
  2490. sendEmail($message){$monitorFile=self::$logFile.'.monitor';if(@filemtime($monitorFile)+self::$emailSnooze<time()&&@file_put_contents($monitorFile,'sent')){call_user_func(self::$mailer,$message);}}private
  2491. static
  2492. function
  2493. defaultMailer($message){$host=isset($_SERVER['HTTP_HOST'])?$_SERVER['HTTP_HOST']:(isset($_SERVER['SERVER_NAME'])?$_SERVER['SERVER_NAME']:'');$headers=str_replace(array('%host%','%date%','%message%'),array($host,@date('Y-m-d H:i:s',self::$time),$message),self::$emailHeaders);$subject=$headers['Subject'];$to=$headers['To'];$body=$headers['Body'];unset($headers['Subject'],$headers['To'],$headers['Body']);$header='';foreach($headers
  2494. as$key=>$value){$header.="$key: $value\r\n";}$body=str_replace("\r\n","\n",$body);if(PHP_OS!='Linux')$body=str_replace("\n","\r\n",$body);mail($to,$subject,$body,$header);}static
  2495. function
  2496. enableProfiler(){self::$enabledProfiler=TRUE;}static
  2497. function
  2498. disableProfiler(){self::$enabledProfiler=FALSE;}static
  2499. function
  2500. addColophon($callback){if(!is_callable($callback)){$able=is_callable($callback,TRUE,$textual);throw
  2501. new
  2502. InvalidArgumentException("Colophon handler '$textual' is not ".($able?'callable.':'valid PHP callback.'));}if(!in_array($callback,self::$colophons,TRUE)){self::$colophons[]=$callback;}}private
  2503. static
  2504. function
  2505. getDefaultColophons($sender){if($sender==='profiler'){$arr[]='Elapsed time: <b>'.number_format((microtime(TRUE)-self::$time)*1000,1,'.',' ').'</b> ms | Allocated memory: <b>'.number_format(memory_get_peak_usage()/1000,1,'.',' ').'</b> kB';foreach((array)self::$counters
  2506. as$name=>$value){if(is_array($value))$value=implode(', ',$value);$arr[]=htmlSpecialChars($name).' = <strong>'.htmlSpecialChars($value).'</strong>';}$autoloaded=class_exists('AutoLoader',FALSE)?AutoLoader::$count:0;$s='<span>'.count(get_included_files()).'/'.$autoloaded.' files</span>, ';$exclude=array('stdClass','Exception','ErrorException','Traversable','IteratorAggregate','Iterator','ArrayAccess','Serializable','Closure');foreach(get_loaded_extensions()as$ext){$ref=new
  2507. ReflectionExtension($ext);$exclude=array_merge($exclude,$ref->getClassNames());}$classes=array_diff(get_declared_classes(),$exclude);$intf=array_diff(get_declared_interfaces(),$exclude);$func=get_defined_functions();$func=(array)@$func['user'];$consts=get_defined_constants(TRUE);$consts=array_keys((array)@$consts['user']);foreach(array('classes','intf','func','consts')as$item){$s.='<span '.($$item?'title="'.implode(", ",$$item).'"':'').'>'.count($$item).' '.$item.'</span>, ';}$arr[]=$s;}if($sender==='bluescreen'){$arr[]='Report generated at '.@date('Y/m/d H:i:s',self::$time);if(isset($_SERVER['HTTP_HOST'],$_SERVER['REQUEST_URI'])){$url=(isset($_SERVER['HTTPS'])&&strcasecmp($_SERVER['HTTPS'],'off')?'https://':'http://').htmlSpecialChars($_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);$arr[]='<a href="'.$url.'">'.$url.'</a>';}$arr[]='PHP '.htmlSpecialChars(PHP_VERSION);if(isset($_SERVER['SERVER_SOFTWARE']))$arr[]=htmlSpecialChars($_SERVER['SERVER_SOFTWARE']);if(class_exists('Framework'))$arr[]=htmlSpecialChars('Nette Framework '.Framework::VERSION).' <i>(revision '.htmlSpecialChars(Framework::REVISION).')</i>';}return$arr;}static
  2508. function
  2509. fireDump($var,$key){self::fireSend(2,array((string)$key=>$var));return$var;}static
  2510. function
  2511. fireLog($message,$priority=self::LOG,$label=NULL){if($message
  2512. instanceof
  2513. Exception){if($priority!==self::EXCEPTION&&$priority!==self::TRACE){$priority=self::TRACE;}$message=array('Class'=>get_class($message),'Message'=>$message->getMessage(),'File'=>$message->getFile(),'Line'=>$message->getLine(),'Trace'=>$message->getTrace(),'Type'=>'','Function'=>'');foreach($message['Trace']as&$row){if(empty($row['file']))$row['file']='?';if(empty($row['line']))$row['line']='?';}}elseif($priority===self::GROUP_START){$label=$message;$message=NULL;}return
  2514. self::fireSend(1,self::replaceObjects(array(array('Type'=>$priority,'Label'=>$label),$message)));}private
  2515. static
  2516. function
  2517. fireSend($index,$payload){if(self::$productionMode)return
  2518. NULL;if(headers_sent())return
  2519. FALSE;header('X-Wf-Protocol-nette: http://meta.wildfirehq.org/Protocol/JsonStream/0.2');header('X-Wf-nette-Plugin-1: http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.2.0');if($index===1){header('X-Wf-nette-Structure-1: http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1');}elseif($index===2){header('X-Wf-nette-Structure-2: http://meta.firephp.org/Wildfire/Structure/FirePHP/Dump/0.1');}$payload=json_encode($payload);static$counter;foreach(str_split($payload,4990)as$s){$num=++$counter;header("X-Wf-nette-$index-1-n$num: |$s|\\");}header("X-Wf-nette-$index-1-n$num: |$s|");return
  2520. TRUE;}static
  2521. private
  2522. function
  2523. replaceObjects($val){if(is_object($val)){return'object '.get_class($val).'';}elseif(is_string($val)){return@iconv('UTF-16','UTF-8//IGNORE',iconv('UTF-8','UTF-16//IGNORE',$val));}elseif(is_array($val)){foreach($val
  2524. as$k=>$v){unset($val[$k]);$k=@iconv('UTF-16','UTF-8//IGNORE',iconv('UTF-8','UTF-16//IGNORE',$k));$val[$k]=self::replaceObjects($v);}}return$val;}}Debug::_init();final
  2525. class
  2526. Environment{const
  2527. DEVELOPMENT='development';const
  2528. PRODUCTION='production';const
  2529. CONSOLE='console';const
  2530. LAB='lab';const
  2531. DEBUG='debug';const
  2532. PERFORMANCE='performance';private
  2533. static$configurator;private
  2534. static$mode=array();private
  2535. static$config;private
  2536. static$serviceLocator;private
  2537. static$vars=array('encoding'=>array('UTF-8',FALSE),'lang'=>array('en',FALSE),'cacheBase'=>array('%tempDir%',TRUE),'tempDir'=>array('%appDir%/temp',TRUE),'logDir'=>array('%appDir%/log',TRUE));private
  2538. static$aliases=array('getHttpContext'=>'Nette\Web\HttpContext','getHttpRequest'=>'Nette\Web\IHttpRequest','getHttpResponse'=>'Nette\Web\IHttpResponse','getApplication'=>'Nette\Application\Application','getUser'=>'Nette\Web\IUser');final
  2539. function
  2540. __construct(){throw
  2541. new
  2542. LogicException("Cannot instantiate static class ".get_class($this));}static
  2543. function
  2544. setConfigurator(Configurator$configurator){self::$configurator=$configurator;}static
  2545. function
  2546. getConfigurator(){if(self::$configurator===NULL){self::$configurator=new
  2547. Configurator;}return
  2548. self::$configurator;}static
  2549. function
  2550. setName($name){if(!isset(self::$vars['environment'])){self::setVariable('environment',$name,FALSE);}else{throw
  2551. new
  2552. InvalidStateException('Environment name has been already set.');}}static
  2553. function
  2554. getName(){$name=self::getVariable('environment');if($name===NULL){$name=self::getConfigurator()->detect('environment');self::setVariable('environment',$name,FALSE);}return$name;}static
  2555. function
  2556. setMode($mode,$value=TRUE){self::$mode[$mode]=(bool)$value;}static
  2557. function
  2558. getMode($mode){if(isset(self::$mode[$mode])){return
  2559. self::$mode[$mode];}else{return
  2560. self::$mode[$mode]=self::getConfigurator()->detect($mode);}}static
  2561. function
  2562. isConsole(){return
  2563. self::getMode('console');}static
  2564. function
  2565. isProduction(){return
  2566. self::getMode('production');}static
  2567. function
  2568. isDebugging(){throw
  2569. new
  2570. DeprecatedException;}static
  2571. function
  2572. setVariable($name,$value,$expand=TRUE){if(!is_string($value)){$expand=FALSE;}self::$vars[$name]=array($value,(bool)$expand);}static
  2573. function
  2574. getVariable($name,$default=NULL){if(isset(self::$vars[$name])){list($var,$exp)=self::$vars[$name];if($exp){$var=self::expand($var);self::$vars[$name]=array($var,FALSE);}return$var;}else{$const=strtoupper(preg_replace('#(.)([A-Z]+)#','$1_$2',$name));$list=get_defined_constants(TRUE);if(isset($list['user'][$const])){self::$vars[$name]=array($list['user'][$const],FALSE);return$list['user'][$const];}else{return$default;}}}static
  2575. function
  2576. getVariables(){$res=array();foreach(self::$vars
  2577. as$name=>$foo){$res[$name]=self::getVariable($name);}return$res;}static
  2578. function
  2579. expand($var){if(is_string($var)&&strpos($var,'%')!==FALSE){return@preg_replace_callback('#%([a-z0-9_-]*)%#i',array(__CLASS__,'expandCb'),$var);}return$var;}private
  2580. static
  2581. function
  2582. expandCb($m){list(,$var)=$m;if($var==='')return'%';static$livelock;if(isset($livelock[$var])){throw
  2583. new
  2584. InvalidStateException("Circular reference detected for variables: ".implode(', ',array_keys($livelock)).".");}try{$livelock[$var]=TRUE;$val=self::getVariable($var);unset($livelock[$var]);}catch(Exception$e){$livelock=array();throw$e;}if($val===NULL){throw
  2585. new
  2586. InvalidStateException("Unknown environment variable '$var'.");}elseif(!is_scalar($val)){throw
  2587. new
  2588. InvalidStateException("Environment variable '$var' is not scalar.");}return$val;}static
  2589. function
  2590. getServiceLocator(){if(self::$serviceLocator===NULL){self::$serviceLocator=self::getConfigurator()->createServiceLocator();}return
  2591. self::$serviceLocator;}static
  2592. function
  2593. getService($name,array$options=NULL){return
  2594. self::getServiceLocator()->getService($name,$options);}static
  2595. function
  2596. setServiceAlias($service,$alias){self::$aliases['get'.ucfirst($alias)]=$service;}static
  2597. function
  2598. __callStatic($name,$args){if(isset(self::$aliases[$name])){return
  2599. self::getServiceLocator()->getService(self::$aliases[$name],$args);}else{throw
  2600. new
  2601. MemberAccessException("Call to undefined static method Nette\\Environment::$name().");}}static
  2602. function
  2603. getHttpRequest(){return
  2604. self::getServiceLocator()->getService(self::$aliases[__FUNCTION__]);}static
  2605. function
  2606. getHttpContext(){return
  2607. self::getServiceLocator()->getService(self::$aliases[__FUNCTION__]);}static
  2608. function
  2609. getHttpResponse(){return
  2610. self::getServiceLocator()->getService(self::$aliases[__FUNCTION__]);}static
  2611. function
  2612. getApplication(){return
  2613. self::getServiceLocator()->getService(self::$aliases[__FUNCTION__]);}static
  2614. function
  2615. getUser(){return
  2616. self::getServiceLocator()->getService(self::$aliases[__FUNCTION__]);}static
  2617. function
  2618. getCache($namespace=''){return
  2619. new
  2620. Cache(self::getService('Nette\Caching\ICacheStorage'),$namespace);}static
  2621. function
  2622. getSession($namespace=NULL){$handler=self::getService('Nette\Web\Session');return$namespace===NULL?$handler:$handler->getNamespace($namespace);}static
  2623. function
  2624. loadConfig($file=NULL){return
  2625. self::$config=self::getConfigurator()->loadConfig($file);}static
  2626. function
  2627. getConfig($key=NULL,$default=NULL){if(func_num_args()){return
  2628. isset(self::$config[$key])?self::$config[$key]:$default;}else{return
  2629. self::$config;}}}abstract
  2630. class
  2631. FormControl
  2632. extends
  2633. Component
  2634. implements
  2635. IFormControl{public
  2636. static$idMask='frm%s-%s';public$caption;protected$value;protected$control;protected$label;private$errors=array();private$disabled=FALSE;private$htmlId;private$htmlName;private$rules;private$translator=TRUE;private$options=array();function
  2637. __construct($caption=NULL){$this->monitor('Nette\Forms\Form');parent::__construct();$this->control=Html::el('input');$this->label=Html::el('label');$this->caption=$caption;$this->rules=new
  2638. Rules($this);}protected
  2639. function
  2640. attached($form){if(!$this->disabled&&$form
  2641. instanceof
  2642. Form&&$form->isAnchored()&&$form->isSubmitted()){$this->htmlName=NULL;$this->loadHttpData();}}function
  2643. getForm($need=TRUE){return$this->lookup('Nette\Forms\Form',$need);}function
  2644. getHtmlName(){if($this->htmlName===NULL){$s='';$name=$this->getName();$obj=$this->lookup('Nette\Forms\INamingContainer',TRUE);while(!($obj
  2645. instanceof
  2646. Form)){$s="[$name]$s";$name=$obj->getName();$obj=$obj->lookup('Nette\Forms\INamingContainer',TRUE);}$name.=$s;if($name==='submit'){throw
  2647. new
  2648. InvalidArgumentException("Form control name 'submit' is not allowed due to JavaScript limitations.");}$this->htmlName=$name;}return$this->htmlName;}function
  2649. setHtmlId($id){$this->htmlId=$id;return$this;}function
  2650. getHtmlId(){if($this->htmlId===FALSE){return
  2651. NULL;}elseif($this->htmlId===NULL){$this->htmlId=sprintf(self::$idMask,$this->getForm()->getName(),$this->getHtmlName());$this->htmlId=str_replace(array('[]','[',']'),array('','-',''),$this->htmlId);}return$this->htmlId;}function
  2652. setOption($key,$value){if($value===NULL){unset($this->options[$key]);}else{$this->options[$key]=$value;}return$this;}final
  2653. function
  2654. getOption($key,$default=NULL){return
  2655. isset($this->options[$key])?$this->options[$key]:$default;}final
  2656. function
  2657. getOptions(){return$this->options;}function
  2658. setTranslator(ITranslator$translator=NULL){$this->translator=$translator;return$this;}final
  2659. function
  2660. getTranslator(){if($this->translator===TRUE){return$this->getForm(FALSE)?$this->getForm()->getTranslator():NULL;}return$this->translator;}function
  2661. translate($s,$count=NULL){$translator=$this->getTranslator();return$translator===NULL?$s:$translator->translate($s,$count);}function
  2662. setValue($value){$this->value=$value;return$this;}function
  2663. getValue(){return$this->value;}function
  2664. setDefaultValue($value){$form=$this->getForm(FALSE);if(!$form||!$form->isAnchored()||!$form->isSubmitted()){$this->setValue($value);}return$this;}function
  2665. loadHttpData(){$path=explode('[',strtr(str_replace(array('[]',']'),'',$this->getHtmlName()),'.','_'));$this->setValue(ArrayTools::get($this->getForm()->getHttpData(),$path));}function
  2666. setDisabled($value=TRUE){$this->disabled=(bool)$value;return$this;}function
  2667. isDisabled(){return$this->disabled;}function
  2668. getControl(){$this->setOption('rendered',TRUE);$control=clone$this->control;$control->name=$this->getHtmlName();$control->disabled=$this->disabled;$control->id=$this->getHtmlId();return$control;}function
  2669. getLabel($caption=NULL){$label=clone$this->label;$label->for=$this->getHtmlId();if($caption!==NULL){$label->setText($this->translate($caption));}elseif($this->caption
  2670. instanceof
  2671. Html){$label->add($this->caption);}else{$label->setText($this->translate($this->caption));}return$label;}final
  2672. function
  2673. getControlPrototype(){return$this->control;}final
  2674. function
  2675. getLabelPrototype(){return$this->label;}function
  2676. setRendered($value=TRUE){$this->setOption('rendered',$value);return$this;}function
  2677. isRendered(){return!empty($this->options['rendered']);}function
  2678. addRule($operation,$message=NULL,$arg=NULL){$this->rules->addRule($operation,$message,$arg);return$this;}function
  2679. addCondition($operation,$value=NULL){return$this->rules->addCondition($operation,$value);}function
  2680. addConditionOn(IFormControl$control,$operation,$value=NULL){return$this->rules->addConditionOn($control,$operation,$value);}final
  2681. function
  2682. getRules(){return$this->rules;}final
  2683. function
  2684. setRequired($message=NULL){$this->rules->addRule(':Filled',$message);return$this;}final
  2685. function
  2686. isRequired(){return!empty($this->options['required']);}function
  2687. notifyRule(Rule$rule){if(is_string($rule->operation)&&strcasecmp($rule->operation,':filled')===0){$this->setOption('required',TRUE);}}static
  2688. function
  2689. validateEqual(IFormControl$control,$arg){$value=$control->getValue();foreach((is_array($value)?$value:array($value))as$val){foreach((is_array($arg)?$arg:array($arg))as$item){if((string)$val===(string)($item
  2690. instanceof
  2691. IFormControl?$item->value:$item)){return
  2692. TRUE;}}}return
  2693. FALSE;}static
  2694. function
  2695. validateFilled(IFormControl$control){return(string)$control->getValue()!=='';}static
  2696. function
  2697. validateValid(IFormControl$control){return$control->rules->validate(TRUE);}function
  2698. addError($message){if(!in_array($message,$this->errors,TRUE)){$this->errors[]=$message;}$this->getForm()->addError($message);}function
  2699. getErrors(){return$this->errors;}function
  2700. hasErrors(){return(bool)$this->errors;}function
  2701. cleanErrors(){$this->errors=array();}}class
  2702. Button
  2703. extends
  2704. FormControl{function
  2705. __construct($caption=NULL){parent::__construct($caption);$this->control->type='button';}function
  2706. getLabel($caption=NULL){return
  2707. NULL;}function
  2708. getControl($caption=NULL){$control=parent::getControl();$control->value=$this->translate($caption===NULL?$this->caption:$caption);return$control;}}class
  2709. Checkbox
  2710. extends
  2711. FormControl{function
  2712. __construct($label=NULL){parent::__construct($label);$this->control->type='checkbox';$this->value=FALSE;}function
  2713. setValue($value){$this->value=is_scalar($value)?(bool)$value:FALSE;return$this;}function
  2714. getControl(){return
  2715. parent::getControl()->checked($this->value);}}class
  2716. FileUpload
  2717. extends
  2718. FormControl{function
  2719. __construct($label=NULL){parent::__construct($label);$this->control->type='file';}protected
  2720. function
  2721. attached($form){if($form
  2722. instanceof
  2723. Form){if($form->getMethod()!==Form::POST){throw
  2724. new
  2725. InvalidStateException('File upload requires method POST.');}$form->getElementPrototype()->enctype='multipart/form-data';}parent::attached($form);}function
  2726. setValue($value){if(is_array($value)){$this->value=new
  2727. HttpUploadedFile($value);}elseif($value
  2728. instanceof
  2729. HttpUploadedFile){$this->value=$value;}else{$this->value=new
  2730. HttpUploadedFile(NULL);}return$this;}static
  2731. function
  2732. validateFilled(IFormControl$control){$file=$control->getValue();return$file
  2733. instanceof
  2734. HttpUploadedFile&&$file->isOK();}static
  2735. function
  2736. validateFileSize(FileUpload$control,$limit){$file=$control->getValue();return$file
  2737. instanceof
  2738. HttpUploadedFile&&$file->getSize()<=$limit;}static
  2739. function
  2740. validateMimeType(FileUpload$control,$mimeType){$file=$control->getValue();if($file
  2741. instanceof
  2742. HttpUploadedFile){$type=$file->getContentType();$type=strtolower(preg_replace('#\s*;.*$#','',$type));if(!$type){return
  2743. FALSE;}$mimeTypes=is_array($mimeType)?$mimeType:explode(',',$mimeType);if(in_array($type,$mimeTypes,TRUE)){return
  2744. TRUE;}if(in_array(preg_replace('#/.*#','/*',$type),$mimeTypes,TRUE)){return
  2745. TRUE;}}return
  2746. FALSE;}}class
  2747. HiddenField
  2748. extends
  2749. FormControl{private$forcedValue;function
  2750. __construct($forcedValue=NULL){parent::__construct();$this->control->type='hidden';$this->value=(string)$forcedValue;$this->forcedValue=$forcedValue;}function
  2751. getLabel($caption=NULL){return
  2752. NULL;}function
  2753. setValue($value){$this->value=is_scalar($value)?(string)$value:'';return$this;}function
  2754. getControl(){return
  2755. parent::getControl()->value($this->forcedValue===NULL?$this->value:$this->forcedValue);}}class
  2756. SubmitButton
  2757. extends
  2758. Button
  2759. implements
  2760. ISubmitterControl{public$onClick;public$onInvalidClick;private$validationScope=TRUE;function
  2761. __construct($caption=NULL){parent::__construct($caption);$this->control->type='submit';}function
  2762. setValue($value){$this->value=is_scalar($value)&&(bool)$value;$form=$this->getForm();if($this->value||!is_object($form->isSubmitted())){$this->value=TRUE;$form->setSubmittedBy($this);}return$this;}function
  2763. isSubmittedBy(){return$this->getForm()->isSubmitted()===$this;}function
  2764. setValidationScope($scope){$this->validationScope=(bool)$scope;return$this;}final
  2765. function
  2766. getValidationScope(){return$this->validationScope;}function
  2767. click(){$this->onClick($this);}static
  2768. function
  2769. validateSubmitted(ISubmitterControl$control){return$control->isSubmittedBy();}}class
  2770. ImageButton
  2771. extends
  2772. SubmitButton{function
  2773. __construct($src=NULL,$alt=NULL){parent::__construct();$this->control->type='image';$this->control->src=$src;$this->control->alt=$alt;}function
  2774. getHtmlName(){$name=parent::getHtmlName();return
  2775. strpos($name,'[')===FALSE?$name:$name.'[]';}function
  2776. loadHttpData(){$path=$this->getHtmlName();$path=explode('[',strtr(str_replace(']','',strpos($path,'[')===FALSE?$path.'.x':substr($path,0,-2)),'.','_'));$this->setValue(ArrayTools::get($this->getForm()->getHttpData(),$path)!==NULL);}}class
  2777. SelectBox
  2778. extends
  2779. FormControl{private$items=array();protected$allowed=array();private$skipFirst=FALSE;private$useKeys=TRUE;function
  2780. __construct($label=NULL,array$items=NULL,$size=NULL){parent::__construct($label);$this->control->setName('select');$this->control->size=$size>1?(int)$size:NULL;$this->control->onfocus='this.onmousewheel=function(){return false}';$this->label->onclick='document.getElementById(this.htmlFor).focus();return false';if($items!==NULL){$this->setItems($items);}}function
  2781. getValue(){$allowed=$this->allowed;if($this->skipFirst){$allowed=array_slice($allowed,1,count($allowed),TRUE);}return
  2782. is_scalar($this->value)&&isset($allowed[$this->value])?$this->value:NULL;}function
  2783. getRawValue(){return
  2784. is_scalar($this->value)?$this->value:NULL;}function
  2785. skipFirst($item=NULL){if(is_bool($item)){$this->skipFirst=$item;}else{$this->skipFirst=TRUE;if($item!==NULL){$this->items=array(''=>$item)+$this->items;$this->allowed=array(''=>'')+$this->allowed;}}return$this;}final
  2786. function
  2787. isFirstSkipped(){return$this->skipFirst;}final
  2788. function
  2789. areKeysUsed(){return$this->useKeys;}function
  2790. setItems(array$items,$useKeys=TRUE){$this->items=$items;$this->allowed=array();$this->useKeys=(bool)$useKeys;foreach($items
  2791. as$key=>$value){if(!is_array($value)){$value=array($key=>$value);}foreach($value
  2792. as$key2=>$value2){if(!$this->useKeys){if(!is_scalar($value2)){throw
  2793. new
  2794. InvalidArgumentException("All items must be scalars.");}$key2=$value2;}if(isset($this->allowed[$key2])){throw
  2795. new
  2796. InvalidArgumentException("Items contain duplication for key '$key2'.");}$this->allowed[$key2]=$value2;}}return$this;}final
  2797. function
  2798. getItems(){return$this->items;}function
  2799. getSelectedItem(){if(!$this->useKeys){return$this->getValue();}else{$value=$this->getValue();return$value===NULL?NULL:$this->allowed[$value];}}function
  2800. getControl(){$control=parent::getControl();$selected=$this->getValue();$selected=is_array($selected)?array_flip($selected):array($selected=>TRUE);$option=Html::el('option');foreach($this->items
  2801. as$key=>$value){if(!is_array($value)){$value=array($key=>$value);$dest=$control;}else{$dest=$control->create('optgroup')->label($key);}foreach($value
  2802. as$key2=>$value2){if($value2
  2803. instanceof
  2804. Html){$dest->add((string)$value2->selected(isset($selected[$key2])));}elseif($this->useKeys){$dest->add((string)$option->value($key2)->selected(isset($selected[$key2]))->setText($this->translate($value2)));}else{$dest->add((string)$option->selected(isset($selected[$value2]))->setText($this->translate($value2)));}}}return$control;}static
  2805. function
  2806. validateFilled(IFormControl$control){$value=$control->getValue();return
  2807. is_array($value)?count($value)>0:$value!==NULL;}}class
  2808. MultiSelectBox
  2809. extends
  2810. SelectBox{function
  2811. getValue(){$allowed=array_keys($this->allowed);if($this->isFirstSkipped()){unset($allowed[0]);}return
  2812. array_intersect($this->getRawValue(),$allowed);}function
  2813. getRawValue(){if(is_scalar($this->value)){$value=array($this->value);}elseif(!is_array($this->value)){$value=array();}else{$value=$this->value;}$res=array();foreach($value
  2814. as$val){if(is_scalar($val)){$res[]=$val;}}return$res;}function
  2815. getSelectedItem(){if(!$this->useKeys){return$this->getValue();}else{$res=array();foreach($this->getValue()as$value){$res[$value]=$this->allowed[$value];}return$res;}}function
  2816. getHtmlName(){return
  2817. parent::getHtmlName().'[]';}function
  2818. getControl(){$control=parent::getControl();$control->multiple=TRUE;return$control;}}class
  2819. RadioList
  2820. extends
  2821. FormControl{protected$separator;protected$container;protected$items=array();function
  2822. __construct($label=NULL,array$items=NULL){parent::__construct($label);$this->control->type='radio';$this->container=Html::el();$this->separator=Html::el('br');if($items!==NULL)$this->setItems($items);}function
  2823. getValue($raw=FALSE){return
  2824. is_scalar($this->value)&&($raw||isset($this->items[$this->value]))?$this->value:NULL;}function
  2825. setItems(array$items){$this->items=$items;return$this;}final
  2826. function
  2827. getItems(){return$this->items;}final
  2828. function
  2829. getSeparatorPrototype(){return$this->separator;}final
  2830. function
  2831. getContainerPrototype(){return$this->container;}function
  2832. getControl($key=NULL){if($key===NULL){$container=clone$this->container;$separator=(string)$this->separator;}elseif(!isset($this->items[$key])){return
  2833. NULL;}$control=parent::getControl();$id=$control->id;$counter=-1;$value=$this->value===NULL?NULL:(string)$this->getValue();$label=Html::el('label');foreach($this->items
  2834. as$k=>$val){$counter++;if($key!==NULL&&$key!=$k)continue;$control->id=$label->for=$id.'-'.$counter;$control->checked=(string)$k===$value;$control->value=$k;if($val
  2835. instanceof
  2836. Html){$label->setHtml($val);}else{$label->setText($this->translate($val));}if($key!==NULL){return(string)$control.(string)$label;}$container->add((string)$control.(string)$label.$separator);}return$container;}function
  2837. getLabel($caption=NULL){$label=parent::getLabel($caption);$label->for=NULL;return$label;}static
  2838. function
  2839. validateFilled(IFormControl$control){return$control->getValue()!==NULL;}}abstract
  2840. class
  2841. TextBase
  2842. extends
  2843. FormControl{protected$emptyValue='';protected$filters=array();function
  2844. setValue($value){$this->value=is_scalar($value)?(string)$value:'';return$this;}function
  2845. getValue(){$value=$this->value;foreach($this->filters
  2846. as$filter){$value=(string)$filter->invoke($value);}return$value===$this->translate($this->emptyValue)?'':$value;}function
  2847. setEmptyValue($value){$this->emptyValue=$value;return$this;}final
  2848. function
  2849. getEmptyValue(){return$this->emptyValue;}function
  2850. addFilter($filter){$this->filters[]=callback($filter);return$this;}function
  2851. notifyRule(Rule$rule){if(is_string($rule->operation)&&strcasecmp($rule->operation,':float')===0){$this->addFilter(array(__CLASS__,'filterFloat'));}parent::notifyRule($rule);}static
  2852. function
  2853. validateMinLength(TextBase$control,$length){return
  2854. iconv_strlen($control->getValue(),'UTF-8')>=$length;}static
  2855. function
  2856. validateMaxLength(TextBase$control,$length){return
  2857. iconv_strlen($control->getValue(),'UTF-8')<=$length;}static
  2858. function
  2859. validateLength(TextBase$control,$range){if(!is_array($range)){$range=array($range,$range);}$len=iconv_strlen($control->getValue(),'UTF-8');return($range[0]===NULL||$len>=$range[0])&&($range[1]===NULL||$len<=$range[1]);}static
  2860. function
  2861. validateEmail(TextBase$control){$atom="[-a-z0-9!#$%&'*+/=?^_`{|}~]";$localPart="(\"([ !\\x23-\\x5B\\x5D-\\x7E]*|\\\\[ -~])+\"|$atom+(\\.$atom+)*)";$chars="a-z0-9\x80-\xFF";$domain="[$chars]([-$chars]{0,61}[$chars])";return(bool)preg_match("(^$localPart@($domain?\\.)+[a-z]{2,14}\\z)i",$control->getValue());}static
  2862. function
  2863. validateUrl(TextBase$control){return(bool)preg_match('/^.+\.[a-z]{2,6}(\\/.*)?$/i',$control->getValue());}static
  2864. function
  2865. validateRegexp(TextBase$control,$regexp){return(bool)preg_match($regexp,$control->getValue());}static
  2866. function
  2867. validateInteger(TextBase$control){return(bool)preg_match('/^-?[0-9]+$/',$control->getValue());}static
  2868. function
  2869. validateFloat(TextBase$control){return(bool)preg_match('/^-?[0-9]*[.,]?[0-9]+$/',$control->getValue());}static
  2870. function
  2871. validateRange(TextBase$control,$range){return($range[0]===NULL||$control->getValue()>=$range[0])&&($range[1]===NULL||$control->getValue()<=$range[1]);}static
  2872. function
  2873. filterFloat($s){return
  2874. str_replace(array(' ',','),array('','.'),$s);}}class
  2875. TextArea
  2876. extends
  2877. TextBase{function
  2878. __construct($label=NULL,$cols=NULL,$rows=NULL){parent::__construct($label);$this->control->setName('textarea');$this->control->cols=$cols;$this->control->rows=$rows;$this->value='';}function
  2879. getControl(){$control=parent::getControl();$control->setText($this->getValue()===''?$this->translate($this->emptyValue):$this->value);return$control;}}class
  2880. TextInput
  2881. extends
  2882. TextBase{function
  2883. __construct($label=NULL,$cols=NULL,$maxLength=NULL){parent::__construct($label);$this->control->type='text';$this->control->size=$cols;$this->control->maxlength=$maxLength;$this->filters[]=callback('String','trim');$this->filters[]=callback($this,'checkMaxLength');$this->value='';}function
  2884. checkMaxLength($value){if($this->control->maxlength&&iconv_strlen($value,'UTF-8')>$this->control->maxlength){$value=iconv_substr($value,0,$this->control->maxlength,'UTF-8');}return$value;}function
  2885. setPasswordMode($mode=TRUE){$this->control->type=$mode?'password':'text';return$this;}function
  2886. getControl(){$control=parent::getControl();if($this->control->type!=='password'){$control->value=$this->getValue()===''?$this->translate($this->emptyValue):$this->value;}return$control;}function
  2887. notifyRule(Rule$rule){if(is_string($rule->operation)&&strcasecmp($rule->operation,':length')===0&&!$rule->isNegative){$this->control->maxlength=is_array($rule->arg)?$rule->arg[1]:$rule->arg;}elseif(is_string($rule->operation)&&strcasecmp($rule->operation,':maxLength')===0&&!$rule->isNegative){$this->control->maxlength=$rule->arg;}parent::notifyRule($rule);}}class
  2888. FormGroup
  2889. extends
  2890. Object{protected$controls;private$options=array();function
  2891. __construct(){$this->controls=new
  2892. SplObjectStorage;}function
  2893. add(){foreach(func_get_args()as$num=>$item){if($item
  2894. instanceof
  2895. IFormControl){$this->controls->attach($item);}elseif($item
  2896. instanceof
  2897. Traversable||is_array($item)){foreach($item
  2898. as$control){$this->controls->attach($control);}}else{throw
  2899. new
  2900. InvalidArgumentException("Only IFormControl items are allowed, the #$num parameter is invalid.");}}return$this;}function
  2901. getControls(){return
  2902. iterator_to_array($this->controls);}function
  2903. setOption($key,$value){if($value===NULL){unset($this->options[$key]);}else{$this->options[$key]=$value;}return$this;}final
  2904. function
  2905. getOption($key,$default=NULL){return
  2906. isset($this->options[$key])?$this->options[$key]:$default;}final
  2907. function
  2908. getOptions(){return$this->options;}}class
  2909. ConventionalRenderer
  2910. extends
  2911. Object
  2912. implements
  2913. IFormRenderer{public$wrappers=array('form'=>array('container'=>NULL,'errors'=>TRUE),'error'=>array('container'=>'ul class=error','item'=>'li'),'group'=>array('container'=>'fieldset','label'=>'legend','description'=>'p'),'controls'=>array('container'=>'table'),'pair'=>array('container'=>'tr','.required'=>'required','.optional'=>NULL,'.odd'=>NULL),'control'=>array('container'=>'td','.odd'=>NULL,'errors'=>FALSE,'description'=>'small','requiredsuffix'=>'','.required'=>'required','.text'=>'text','.password'=>'text','.file'=>'text','.submit'=>'button','.image'=>'imagebutton','.button'=>'button'),'label'=>array('container'=>'th','suffix'=>NULL,'requiredsuffix'=>''),'hidden'=>array('container'=>'div'));protected$form;protected$clientScript=TRUE;protected$counter;function
  2914. render(Form$form,$mode=NULL){if($this->form!==$form){$this->form=$form;$this->init();}$s='';if(!$mode||$mode==='begin'){$s.=$this->renderBegin();}if((!$mode&&$this->getValue('form errors'))||$mode==='errors'){$s.=$this->renderErrors();}if(!$mode||$mode==='body'){$s.=$this->renderBody();}if(!$mode||$mode==='end'){$s.=$this->renderEnd();}return$s;}function
  2915. setClientScript($clientScript=NULL){$this->clientScript=$clientScript;return$this;}function
  2916. getClientScript(){if($this->clientScript===TRUE){$this->clientScript=new
  2917. InstantClientScript($this->form);}return$this->clientScript;}protected
  2918. function
  2919. init(){$clientScript=$this->getClientScript();if($clientScript!==NULL){$clientScript->enable();}$wrapper=&$this->wrappers['control'];foreach($this->form->getControls()as$control){if($control->getOption('required')&&isset($wrapper['.required'])){$control->getLabelPrototype()->class($wrapper['.required'],TRUE);}$el=$control->getControlPrototype();if($el->getName()==='input'&&isset($wrapper['.'.$el->type])){$el->class($wrapper['.'.$el->type],TRUE);}}}function
  2920. renderBegin(){$this->counter=0;foreach($this->form->getControls()as$control){$control->setOption('rendered',FALSE);}if(strcasecmp($this->form->getMethod(),'get')===0){$el=clone$this->form->getElementPrototype();$uri=explode('?',(string)$el->action,2);$el->action=$uri[0];$s='';if(isset($uri[1])){foreach(preg_split('#[;&]#',$uri[1])as$param){$parts=explode('=',$param,2);$name=urldecode($parts[0]);if(!isset($this->form[$name])){$s.=Html::el('input',array('type'=>'hidden','name'=>$name,'value'=>urldecode($parts[1])));}}$s="\n\t".$this->getWrapper('hidden container')->setHtml($s);}return$el->startTag().$s;}else{return$this->form->getElementPrototype()->startTag();}}function
  2921. renderEnd(){$s='';foreach($this->form->getControls()as$control){if($control
  2922. instanceof
  2923. HiddenField&&!$control->getOption('rendered')){$s.=(string)$control->getControl();}}if($s){$s=$this->getWrapper('hidden container')->setHtml($s)."\n";}$s.=$this->form->getElementPrototype()->endTag()."\n";$clientScript=$this->getClientScript();if($clientScript!==NULL){$s.=$clientScript->renderClientScript()."\n";}return$s;}function
  2924. renderErrors(IFormControl$control=NULL){$errors=$control===NULL?$this->form->getErrors():$control->getErrors();if(count($errors)){$ul=$this->getWrapper('error container');$li=$this->getWrapper('error item');foreach($errors
  2925. as$error){$item=clone$li;if($error
  2926. instanceof
  2927. Html){$item->add($error);}else{$item->setText($error);}$ul->add($item);}return"\n".$ul->render(0);}}function
  2928. renderBody(){$s=$remains='';$defaultContainer=$this->getWrapper('group container');$translator=$this->form->getTranslator();foreach($this->form->getGroups()as$group){if(!$group->getControls()||!$group->getOption('visual'))continue;$container=$group->getOption('container',$defaultContainer);$container=$container
  2929. instanceof
  2930. Html?clone$container:Html::el($container);$s.="\n".$container->startTag();$text=$group->getOption('label');if($text
  2931. instanceof
  2932. Html){$s.=$text;}elseif(is_string($text)){if($translator!==NULL){$text=$translator->translate($text);}$s.="\n".$this->getWrapper('group label')->setText($text)."\n";}$text=$group->getOption('description');if($text
  2933. instanceof
  2934. Html){$s.=$text;}elseif(is_string($text)){if($translator!==NULL){$text=$translator->translate($text);}$s.=$this->getWrapper('group description')->setText($text)."\n";}$s.=$this->renderControls($group);$remains=$container->endTag()."\n".$remains;if(!$group->getOption('embedNext')){$s.=$remains;$remains='';}}$s.=$remains.$this->renderControls($this->form);$container=$this->getWrapper('form container');$container->setHtml($s);return$container->render(0);}function
  2935. renderControls($parent){if(!($parent
  2936. instanceof
  2937. FormContainer||$parent
  2938. instanceof
  2939. FormGroup)){throw
  2940. new
  2941. InvalidArgumentException("Argument must be FormContainer or FormGroup instance.");}$container=$this->getWrapper('controls container');$buttons=NULL;foreach($parent->getControls()as$control){if($control->getOption('rendered')||$control
  2942. instanceof
  2943. HiddenField||$control->getForm(FALSE)!==$this->form){}elseif($control
  2944. instanceof
  2945. Button){$buttons[]=$control;}else{if($buttons){$container->add($this->renderPairMulti($buttons));$buttons=NULL;}$container->add($this->renderPair($control));}}if($buttons){$container->add($this->renderPairMulti($buttons));}$s='';if(count($container)){$s.="\n".$container."\n";}return$s;}function
  2946. renderPair(IFormControl$control){$pair=$this->getWrapper('pair container');$pair->add($this->renderLabel($control));$pair->add($this->renderControl($control));$pair->class($this->getValue($control->getOption('required')?'pair .required':'pair .optional'),TRUE);$pair->class($control->getOption('class'),TRUE);if(++$this->counter
  2947. %
  2948. 2)$pair->class($this->getValue('pair .odd'),TRUE);$pair->id=$control->getOption('id');return$pair->render(0);}function
  2949. renderPairMulti(array$controls){$s=array();foreach($controls
  2950. as$control){if(!($control
  2951. instanceof
  2952. IFormControl)){throw
  2953. new
  2954. InvalidArgumentException("Argument must be array of IFormControl instances.");}$s[]=(string)$control->getControl();}$pair=$this->getWrapper('pair container');$pair->add($this->renderLabel($control));$pair->add($this->getWrapper('control container')->setHtml(implode(" ",$s)));return$pair->render(0);}function
  2955. renderLabel(IFormControl$control){$head=$this->getWrapper('label container');if($control
  2956. instanceof
  2957. Checkbox||$control
  2958. instanceof
  2959. Button){return$head->setHtml(($head->getName()==='td'||$head->getName()==='th')?'&nbsp;':'');}else{$label=$control->getLabel();$suffix=$this->getValue('label suffix').($control->getOption('required')?$this->getValue('label requiredsuffix'):'');if($label
  2960. instanceof
  2961. Html){$label->setHtml($label->getHtml().$suffix);$suffix='';}return$head->setHtml((string)$label.$suffix);}}function
  2962. renderControl(IFormControl$control){$body=$this->getWrapper('control container');if($this->counter
  2963. %
  2964. 2)$body->class($this->getValue('control .odd'),TRUE);$description=$control->getOption('description');if($description
  2965. instanceof
  2966. Html){$description=' '.$control->getOption('description');}elseif(is_string($description)){$description=' '.$this->getWrapper('control description')->setText($description);}else{$description='';}if($control->getOption('required')){$description=$this->getValue('control requiredsuffix').$description;}if($this->getValue('control errors')){$description.=$this->renderErrors($control);}if($control
  2967. instanceof
  2968. Checkbox||$control
  2969. instanceof
  2970. Button){return$body->setHtml((string)$control->getControl().(string)$control->getLabel().$description);}else{return$body->setHtml((string)$control->getControl().$description);}}protected
  2971. function
  2972. getWrapper($name){$data=$this->getValue($name);return$data
  2973. instanceof
  2974. Html?clone$data:Html::el($data);}protected
  2975. function
  2976. getValue($name){$name=explode(' ',$name);$data=&$this->wrappers[$name[0]][$name[1]];return$data;}}final
  2977. class
  2978. InstantClientScript
  2979. extends
  2980. Object{private$validateScripts;private$toggleScript;private$central;private$form;function
  2981. __construct(Form$form){$this->form=$form;}function
  2982. enable(){$el=$this->form->getElementPrototype();if(!$el->name){$el->name='frm-'.($this->form
  2983. instanceof
  2984. AppForm?$this->form->lookupPath('Nette\Application\Presenter',TRUE):$this->form->getName());}$this->validateScripts=array();$this->toggleScript='';$this->central=TRUE;foreach($this->form->getControls()as$control){$script=$this->getValidateScript($control->getRules());if($script){$this->validateScripts[$control->getHtmlName()]=$script;}$this->toggleScript.=$this->getToggleScript($control->getRules());if($control
  2985. instanceof
  2986. ISubmitterControl&&$control->getValidationScope()!==TRUE){$this->central=FALSE;}}if($this->validateScripts||$this->toggleScript){if($this->central){$this->form->getElementPrototype()->onsubmit("return nette.validateForm(this)",TRUE);}else{foreach($this->form->getComponents(TRUE,'Nette\Forms\ISubmitterControl')as$control){if($control->getValidationScope()){$control->getControlPrototype()->onclick("return nette.validateForm(this)",TRUE);}}}}}function
  2987. renderClientScript(){if(!$this->validateScripts&&!$this->toggleScript){return;}$formName=json_encode((string)$this->form->getElementPrototype()->name);ob_start();?>
  2988. <script type="text/javascript">
  2989. /* <![CDATA[ */
  2990. var nette = nette || { };
  2991. nette.getValue = function(elem) {
  2992. if (!elem) {
  2993. var undefined;
  2994. return undefined;
  2995. }
  2996. if (!elem.nodeName) { // radio
  2997. for (var i = 0, len = elem.length; i < len; i++) {
  2998. if (elem[i].checked) {
  2999. return elem[i].value;
  3000. }
  3001. }
  3002. return null;
  3003. }
  3004. if (elem.nodeName.toLowerCase() === 'select') {
  3005. var index = elem.selectedIndex, options = elem.options;
  3006. if (index < 0) {
  3007. return null;
  3008. } else if (elem.type === 'select-one') {
  3009. return options[index].value;
  3010. }
  3011. for (var i = 0, values = [], len = options.length; i < len; i++) {
  3012. if (options[i].selected) {
  3013. values.push(options[i].value);
  3014. }
  3015. }
  3016. return values;
  3017. }
  3018. if (elem.type === 'checkbox') {
  3019. return elem.checked;
  3020. }
  3021. return elem.value.replace(/^\s+|\s+$/g, '');
  3022. }
  3023. nette.getFormValidators = function(form) {
  3024. var name = form.getAttributeNode('name').nodeValue;
  3025. return this.forms[name] ? this.forms[name].validators : [];
  3026. }
  3027. nette.validateControl = function(control) {
  3028. var validator = this.getFormValidators(control.form)[control.name];
  3029. return validator ? validator(control) : null;
  3030. }
  3031. nette.validateForm = function(sender) {
  3032. var form = sender.form || sender;
  3033. var validators = this.getFormValidators(form);
  3034. for (var name in validators) {
  3035. var error = validators[name](sender);
  3036. if (error) {
  3037. if (form[name].focus) {
  3038. form[name].focus();
  3039. }
  3040. alert(error);
  3041. return false;
  3042. }
  3043. }
  3044. return true;
  3045. }
  3046. nette.toggle = function(id, visible) {
  3047. var elem = document.getElementById(id);
  3048. if (elem) {
  3049. elem.style.display = visible ? "" : "none";
  3050. }
  3051. }
  3052. nette.forms = nette.forms || { };
  3053. nette.forms[<?php echo$formName?>] = {
  3054. validators: {
  3055. <?php $count=count($this->validateScripts);?>
  3056. <?php foreach($this->validateScripts
  3057. as$name=>$validateScript):?>
  3058. <?php echo
  3059. json_encode((string)$name)?>: function(sender) {
  3060. var res, form = sender.form || sender;
  3061. <?php echo
  3062. String::indent($validateScript,3)?>
  3063. }<?php echo--$count?',':''?>
  3064. <?php endforeach?>
  3065. },
  3066. toggle: function(sender) {
  3067. var visible, res, form = document.forms[<?php echo$formName?>];
  3068. <?php echo
  3069. String::indent($this->toggleScript,2)?>
  3070. }
  3071. }
  3072. <?php if($this->toggleScript):?>
  3073. nette.forms[<?php echo$formName?>].toggle();
  3074. <?php endif?>
  3075. /* ]]> */
  3076. </script>
  3077. <?php
  3078. return
  3079. ob_get_clean();}private
  3080. function
  3081. getValidateScript(Rules$rules){$res='';foreach($rules
  3082. as$rule){if(!is_string($rule->operation))continue;if(strcasecmp($rule->operation,'Nette\Forms\InstantClientScript::javascript')===0){$res.="$rule->arg\n";continue;}$script=$this->getClientScript($rule->control,$rule->operation,$rule->arg);if(!$script)continue;if(!empty($rule->message)){$res.="$script\n"."if (".($rule->isNegative?'':'!')."res) "."return ".json_encode((string)vsprintf($rule->control->translate($rule->message,is_int($rule->arg)?$rule->arg:NULL),(array)$rule->arg)).";\n";}if($rule->type===Rule::CONDITION){$innerScript=$this->getValidateScript($rule->subRules);if($innerScript){$res.="$script\nif (".($rule->isNegative?'!':'')."res) {\n".String::indent($innerScript)."}\n";if($rule->control
  3083. instanceof
  3084. ISubmitterControl){$this->central=FALSE;}}}}return$res;}private
  3085. function
  3086. getToggleScript(Rules$rules,$cond=NULL){$s='';foreach($rules->getToggles()as$id=>$visible){$s.="visible = true; {$cond}\n"."nette.toggle(".json_encode((string)$id).", ".($visible?'':'!')."visible);\n";}$formName=json_encode((string)$this->form->getElementPrototype()->name);foreach($rules
  3087. as$rule){if($rule->type===Rule::CONDITION&&is_string($rule->operation)){$script=$this->getClientScript($rule->control,$rule->operation,$rule->arg);if($script){$res=$this->getToggleScript($rule->subRules,$cond."$script visible = visible && ".($rule->isNegative?'!':'')."res;\n");if($res){$el=$rule->control->getControlPrototype();if($el->getName()==='select'){$el->onchange("nette.forms[$formName].toggle(this)",TRUE);}else{$el->onclick("nette.forms[$formName].toggle(this)",TRUE);}$s.=$res;}}}}return$s;}private
  3088. function
  3089. getClientScript(IFormControl$control,$operation,$arg){$operation=strtolower($operation);$elem='form['.json_encode($control->getHtmlName()).']';switch(TRUE){case$control
  3090. instanceof
  3091. HiddenField||$control->isDisabled():return
  3092. NULL;case$operation===':filled'&&$control
  3093. instanceof
  3094. RadioList:return"res = nette.getValue($elem) !== null;";case$operation===':submitted'&&$control
  3095. instanceof
  3096. SubmitButton:return"res=sender && sender.name==".json_encode($control->getHtmlName()).";";case$operation===':equal'&&$control
  3097. instanceof
  3098. MultiSelectBox:$tmp=array();foreach((is_array($arg)?$arg:array($arg))as$item){$tmp[]="options[i].value==".json_encode((string)$item);}$first=$control->isFirstSkipped()?1:0;return"var options = $elem.options; res = false;\n"."for (var i=$first, len=options.length; i<len; i++)\n\t"."if (options[i].selected && (".implode(' || ',$tmp).")) { res = true; break; }";case$operation===':filled'&&$control
  3099. instanceof
  3100. SelectBox:return"res = $elem.selectedIndex >= ".($control->isFirstSkipped()?1:0).";";case$operation===':filled'&&$control
  3101. instanceof
  3102. TextBase:return"var val = nette.getValue($elem); res = val!='' && val!=".json_encode((string)$control->getEmptyValue()).";";case$operation===':minlength'&&$control
  3103. instanceof
  3104. TextBase:return"res = nette.getValue($elem).length>=".(int)$arg.";";case$operation===':maxlength'&&$control
  3105. instanceof
  3106. TextBase:return"res = nette.getValue($elem).length<=".(int)$arg.";";case$operation===':length'&&$control
  3107. instanceof
  3108. TextBase:if(!is_array($arg)){$arg=array($arg,$arg);}return"var val = nette.getValue($elem); res = ".($arg[0]===NULL?"true":"val.length>=".(int)$arg[0])." && ".($arg[1]===NULL?"true":"val.length<=".(int)$arg[1]).";";case$operation===':email'&&$control
  3109. instanceof
  3110. TextBase:return'res = /^[^@\s]+@[^@\s]+\.[a-z]{2,10}$/i.test(nette.getValue('.$elem.'));';case$operation===':url'&&$control
  3111. instanceof
  3112. TextBase:return'res = /^.+\.[a-z]{2,6}(\\/.*)?$/i.test(nette.getValue('.$elem.'));';case$operation===':regexp'&&$control
  3113. instanceof
  3114. TextBase:if(!preg_match('#^(/.*/)([imu]*)$#',$arg,$matches)){return
  3115. NULL;}$arg=$matches[1].str_replace('u','',$matches[2]);return"res = $arg.test(nette.getValue($elem));";case$operation===':integer'&&$control
  3116. instanceof
  3117. TextBase:return"res = /^-?[0-9]+$/.test(nette.getValue($elem));";case$operation===':float'&&$control
  3118. instanceof
  3119. TextBase:return"res = /^-?[0-9]*[.,]?[0-9]+$/.test(nette.getValue($elem));";case$operation===':range'&&$control
  3120. instanceof
  3121. TextBase:return"var val = nette.getValue($elem); res = ".($arg[0]===NULL?"true":"parseFloat(val)>=".json_encode((float)$arg[0]))." && ".($arg[1]===NULL?"true":"parseFloat(val)<=".json_encode((float)$arg[1])).";";case$operation===':filled'&&$control
  3122. instanceof
  3123. FormControl:return"res = nette.getValue($elem) != '';";case$operation===':valid'&&$control
  3124. instanceof
  3125. FormControl:return"res = !this[".json_encode($control->getHtmlName())."](sender);";case$operation===':equal'&&$control
  3126. instanceof
  3127. FormControl:if($control
  3128. instanceof
  3129. Checkbox)$arg=(bool)$arg;$tmp=array();foreach((is_array($arg)?$arg:array($arg))as$item){if($item
  3130. instanceof
  3131. IFormControl){$tmp[]="val==nette.getValue(form[".json_encode($item->getHtmlName())."])";}else{$tmp[]="val==".json_encode($item);}}return"var val = nette.getValue($elem); res = (".implode(' || ',$tmp).");";}}static
  3132. function
  3133. javascript(){return
  3134. TRUE;}}final
  3135. class
  3136. Rule
  3137. extends
  3138. Object{const
  3139. CONDITION=1;const
  3140. VALIDATOR=2;const
  3141. FILTER=3;const
  3142. TERMINATOR=4;public$control;public$operation;public$arg;public$type;public$isNegative=FALSE;public$message;public$breakOnFailure=TRUE;public$subRules;}final
  3143. class
  3144. Rules
  3145. extends
  3146. Object
  3147. implements
  3148. IteratorAggregate{const
  3149. VALIDATE_PREFIX='validate';public
  3150. static$defaultMessages=array();private$rules=array();private$parent;private$toggles=array();private$control;function
  3151. __construct(IFormControl$control){$this->control=$control;}function
  3152. addRule($operation,$message=NULL,$arg=NULL){$rule=new
  3153. Rule;$rule->control=$this->control;$rule->operation=$operation;$this->adjustOperation($rule);$rule->arg=$arg;$rule->type=Rule::VALIDATOR;if($message===NULL&&isset(self::$defaultMessages[$rule->operation])){$rule->message=self::$defaultMessages[$rule->operation];}else{$rule->message=$message;}if($this->parent===NULL){$this->control->notifyRule($rule);}$this->rules[]=$rule;return$this;}function
  3154. addCondition($operation,$arg=NULL){return$this->addConditionOn($this->control,$operation,$arg);}function
  3155. addConditionOn(IFormControl$control,$operation,$arg=NULL){$rule=new
  3156. Rule;$rule->control=$control;$rule->operation=$operation;$this->adjustOperation($rule);$rule->arg=$arg;$rule->type=Rule::CONDITION;$rule->subRules=new
  3157. self($this->control);$rule->subRules->parent=$this;$this->rules[]=$rule;return$rule->subRules;}function
  3158. elseCondition(){$rule=clone
  3159. end($this->parent->rules);$rule->isNegative=!$rule->isNegative;$rule->subRules=new
  3160. self($this->parent->control);$rule->subRules->parent=$this->parent;$this->parent->rules[]=$rule;return$rule->subRules;}function
  3161. endCondition(){return$this->parent;}function
  3162. toggle($id,$hide=TRUE){$this->toggles[$id]=$hide;return$this;}function
  3163. validate($onlyCheck=FALSE){$valid=TRUE;foreach($this->rules
  3164. as$rule){if($rule->control->isDisabled())continue;$success=($rule->isNegative
  3165. xor$this->getCallback($rule)->invoke($rule->control,$rule->arg));if($rule->type===Rule::CONDITION&&$success){$success=$rule->subRules->validate($onlyCheck);$valid=$valid&&$success;}elseif($rule->type===Rule::VALIDATOR&&!$success){if($onlyCheck){return
  3166. FALSE;}$rule->control->addError(vsprintf($rule->control->translate($rule->message,is_int($rule->arg)?$rule->arg:NULL),(array)$rule->arg));$valid=FALSE;if($rule->breakOnFailure){break;}}}return$valid;}final
  3167. function
  3168. getIterator(){return
  3169. new
  3170. ArrayIterator($this->rules);}final
  3171. function
  3172. getToggles(){return$this->toggles;}private
  3173. function
  3174. adjustOperation($rule){if(is_string($rule->operation)&&ord($rule->operation[0])>127){$rule->isNegative=TRUE;$rule->operation=~$rule->operation;}if(!$this->getCallback($rule)->isCallable()){$operation=is_scalar($rule->operation)?" '$rule->operation'":'';throw
  3175. new
  3176. InvalidArgumentException("Unknown operation$operation for control '{$rule->control->name}'.");}}private
  3177. function
  3178. getCallback($rule){$op=$rule->operation;if(is_string($op)&&strncmp($op,':',1)===0){return
  3179. callback(get_class($rule->control),self::VALIDATE_PREFIX.ltrim($op,':'));}else{return
  3180. callback($op);}}}class
  3181. Image
  3182. extends
  3183. Object{const
  3184. ENLARGE=1;const
  3185. STRETCH=2;const
  3186. FIT=0;const
  3187. FILL=4;const
  3188. JPEG=IMAGETYPE_JPEG;const
  3189. PNG=IMAGETYPE_PNG;const
  3190. GIF=IMAGETYPE_GIF;const
  3191. EMPTY_GIF="GIF89a\x01\x00\x01\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00!\xf9\x04\x01\x00\x00\x00\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02D\x01\x00;";public
  3192. static$useImageMagick=FALSE;private$image;static
  3193. function
  3194. rgb($red,$green,$blue,$transparency=0){return
  3195. array('red'=>max(0,min(255,(int)$red)),'green'=>max(0,min(255,(int)$green)),'blue'=>max(0,min(255,(int)$blue)),'alpha'=>max(0,min(127,(int)$transparency)));}static
  3196. function
  3197. fromFile($file,&$format=NULL){if(!extension_loaded('gd')){throw
  3198. new
  3199. Exception("PHP extension GD is not loaded.");}$info=@getimagesize($file);if(self::$useImageMagick&&(empty($info)||$info[0]*$info[1]>9e5)){return
  3200. new
  3201. ImageMagick($file,$format);}switch($format=$info[2]){case
  3202. self::JPEG:return
  3203. new
  3204. self(imagecreatefromjpeg($file));case
  3205. self::PNG:return
  3206. new
  3207. self(imagecreatefrompng($file));case
  3208. self::GIF:return
  3209. new
  3210. self(imagecreatefromgif($file));default:if(self::$useImageMagick){return
  3211. new
  3212. ImageMagick($file,$format);}throw
  3213. new
  3214. Exception("Unknown image type or file '$file' not found.");}}static
  3215. function
  3216. fromString($s,&$format=NULL){if(!extension_loaded('gd')){throw
  3217. new
  3218. Exception("PHP extension GD is not loaded.");}if(strncmp($s,"\xff\xd8",2)===0){$format=self::JPEG;}elseif(strncmp($s,"\x89PNG",4)===0){$format=self::PNG;}elseif(strncmp($s,"GIF",3)===0){$format=self::GIF;}else{$format=NULL;}return
  3219. new
  3220. self(imagecreatefromstring($s));}static
  3221. function
  3222. fromBlank($width,$height,$color=NULL){if(!extension_loaded('gd')){throw
  3223. new
  3224. Exception("PHP extension GD is not loaded.");}$width=(int)$width;$height=(int)$height;if($width<1||$height<1){throw
  3225. new
  3226. InvalidArgumentException('Image width and height must be greater than zero.');}$image=imagecreatetruecolor($width,$height);if(is_array($color)){$color+=array('alpha'=>0);$color=imagecolorallocatealpha($image,$color['red'],$color['green'],$color['blue'],$color['alpha']);imagealphablending($image,FALSE);imagefilledrectangle($image,0,0,$width-1,$height-1,$color);imagealphablending($image,TRUE);}return
  3227. new
  3228. self($image);}function
  3229. __construct($image){$this->setImageResource($image);}function
  3230. getWidth(){return
  3231. imagesx($this->image);}function
  3232. getHeight(){return
  3233. imagesy($this->image);}protected
  3234. function
  3235. setImageResource($image){if(!is_resource($image)||get_resource_type($image)!=='gd'){throw
  3236. new
  3237. InvalidArgumentException('Image is not valid.');}$this->image=$image;return$this;}function
  3238. getImageResource(){return$this->image;}function
  3239. resize($width,$height,$flags=self::FIT){list($newWidth,$newHeight)=self::calculateSize($this->getWidth(),$this->getHeight(),$width,$height,$flags);if($newWidth!==$this->getWidth()||$newHeight!==$this->getHeight()){$newImage=self::fromBlank($newWidth,$newHeight,self::RGB(0,0,0,127))->getImageResource();imagecopyresampled($newImage,$this->getImageResource(),0,0,0,0,$newWidth,$newHeight,$this->getWidth(),$this->getHeight());$this->image=$newImage;}if($width<0||$height<0){$newImage=self::fromBlank($newWidth,$newHeight,self::RGB(0,0,0,127))->getImageResource();imagecopyresampled($newImage,$this->getImageResource(),0,0,$width<0?$newWidth-1:0,$height<0?$newHeight-1:0,$newWidth,$newHeight,$width<0?-$newWidth:$newWidth,$height<0?-$newHeight:$newHeight);$this->image=$newImage;}return$this;}static
  3240. function
  3241. calculateSize($srcWidth,$srcHeight,$newWidth,$newHeight,$flags=self::FIT){if(substr($newWidth,-1)==='%'){$newWidth=round($srcWidth/100*abs($newWidth));$flags|=self::ENLARGE;$percents=TRUE;}else{$newWidth=(int)abs($newWidth);}if(substr($newHeight,-1)==='%'){$newHeight=round($srcHeight/100*abs($newHeight));$flags|=empty($percents)?self::ENLARGE:self::STRETCH;}else{$newHeight=(int)abs($newHeight);}if($flags&self::STRETCH){if(empty($newWidth)||empty($newHeight)){throw
  3242. new
  3243. InvalidArgumentException('For stretching must be both width and height specified.');}if(($flags&self::ENLARGE)===0){$newWidth=round($srcWidth*min(1,$newWidth/$srcWidth));$newHeight=round($srcHeight*min(1,$newHeight/$srcHeight));}}else{if(empty($newWidth)&&empty($newHeight)){throw
  3244. new
  3245. InvalidArgumentException('At least width or height must be specified.');}$scale=array();if($newWidth>0){$scale[]=$newWidth/$srcWidth;}if($newHeight>0){$scale[]=$newHeight/$srcHeight;}if($flags&self::FILL){$scale=array(max($scale));}if(($flags&self::ENLARGE)===0){$scale[]=1;}$scale=min($scale);$newWidth=round($srcWidth*$scale);$newHeight=round($srcHeight*$scale);}return
  3246. array((int)$newWidth,(int)$newHeight);}function
  3247. crop($left,$top,$width,$height){if(substr($left,-1)==='%'){$left=round(($this->getWidth()-$width)/100*$left);}if(substr($top,-1)==='%'){$top=round(($this->getHeight()-$height)/100*$top);}$left=max(0,(int)$left);$top=max(0,(int)$top);$width=min((int)$width,$this->getWidth()-$left);$height=min((int)$height,$this->getHeight()-$top);$newImage=self::fromBlank($width,$height,self::RGB(0,0,0,127))->getImageResource();imagecopy($newImage,$this->getImageResource(),0,0,$left,$top,$width,$height);$this->image=$newImage;return$this;}function
  3248. sharpen(){imageconvolution($this->getImageResource(),array(array(-1,-1,-1),array(-1,24,-1),array(-1,-1,-1)),16,0);return$this;}function
  3249. place(Image$image,$left=0,$top=0,$opacity=100){$opacity=max(0,min(100,(int)$opacity));if(substr($left,-1)==='%'){$left=round(($this->getWidth()-$image->getWidth())/100*$left);}if(substr($top,-1)==='%'){$top=round(($this->getHeight()-$image->getHeight())/100*$top);}if($opacity===100){imagecopy($this->getImageResource(),$image->getImageResource(),$left,$top,0,0,$image->getWidth(),$image->getHeight());}elseif($opacity<>0){imagecopymerge($this->getImageResource(),$image->getImageResource(),$left,$top,0,0,$image->getWidth(),$image->getHeight(),$opacity);}return$this;}function
  3250. save($file=NULL,$quality=NULL,$type=NULL){if($type===NULL){switch(strtolower(pathinfo($file,PATHINFO_EXTENSION))){case'jpg':case'jpeg':$type=self::JPEG;break;case'png':$type=self::PNG;break;case'gif':$type=self::GIF;}}switch($type){case
  3251. self::JPEG:$quality=$quality===NULL?85:max(0,min(100,(int)$quality));return
  3252. imagejpeg($this->getImageResource(),$file,$quality);case
  3253. self::PNG:$quality=$quality===NULL?9:max(0,min(9,(int)$quality));return
  3254. imagepng($this->getImageResource(),$file,$quality);case
  3255. self::GIF:return$file===NULL?imagegif($this->getImageResource()):imagegif($this->getImageResource(),$file);default:throw
  3256. new
  3257. Exception("Unsupported image type.");}}function
  3258. toString($type=self::JPEG,$quality=NULL){ob_start();$this->save(NULL,$quality,$type);return
  3259. ob_get_clean();}function
  3260. __toString(){try{return$this->toString();}catch(Exception$e){Debug::toStringException($e);}}function
  3261. send($type=self::JPEG,$quality=NULL){if($type!==self::GIF&&$type!==self::PNG&&$type!==self::JPEG){throw
  3262. new
  3263. Exception("Unsupported image type.");}header('Content-Type: '.image_type_to_mime_type($type));return$this->save(NULL,$quality,$type);}function
  3264. __call($name,$args){$function='image'.$name;if(function_exists($function)){foreach($args
  3265. as$key=>$value){if($value
  3266. instanceof
  3267. self){$args[$key]=$value->getImageResource();}elseif(is_array($value)&&isset($value['red'])){$args[$key]=imagecolorallocatealpha($this->getImageResource(),$value['red'],$value['green'],$value['blue'],$value['alpha']);}}array_unshift($args,$this->getImageResource());$res=call_user_func_array($function,$args);return
  3268. is_resource($res)?new
  3269. self($res):$res;}return
  3270. parent::__call($name,$args);}}class
  3271. ImageMagick
  3272. extends
  3273. Image{public
  3274. static$path='';public
  3275. static$tempDir;private$file;private$isTemporary=FALSE;private$width;private$height;function
  3276. __construct($file,&$format=NULL){if(!is_file($file)){throw
  3277. new
  3278. InvalidArgumentException("File '$file' not found.");}$format=$this->setFile(realpath($file));if($format==='JPEG')$format=self::JPEG;elseif($format==='PNG')$format=self::PNG;elseif($format==='GIF')$format=self::GIF;}function
  3279. getWidth(){return$this->file===NULL?parent::getWidth():$this->width;}function
  3280. getHeight(){return$this->file===NULL?parent::getHeight():$this->height;}function
  3281. getImageResource(){if($this->file!==NULL){if(!$this->isTemporary){$this->execute("convert -strip %input %output",self::PNG);}$this->setImageResource(imagecreatefrompng($this->file));if($this->isTemporary){unlink($this->file);}$this->file=NULL;}return
  3282. parent::getImageResource();}function
  3283. resize($width,$height,$flags=self::FIT){if($this->file===NULL){return
  3284. parent::resize($newWidth,$newHeight,$flags);}$mirror='';if($width<0)$mirror.=' -flop';if($height<0)$mirror.=' -flip';list($newWidth,$newHeight)=self::calculateSize($this->getWidth(),$this->getHeight(),$width,$height,$flags);$this->execute("convert -resize {$newWidth}x{$newHeight}! {$mirror} -strip %input %output",self::PNG);return$this;}function
  3285. crop($left,$top,$width,$height){if($this->file===NULL){return
  3286. parent::crop($left,$top,$width,$height);}$left=max(0,(int)$left);$top=max(0,(int)$top);$width=min((int)$width,$this->getWidth()-$left);$height=min((int)$height,$this->getHeight()-$top);$this->execute("convert -crop {$width}x{$height}+{$left}+{$top} -strip %input %output",self::PNG);return$this;}function
  3287. save($file=NULL,$quality=NULL,$type=NULL){if($this->file===NULL){return
  3288. parent::save($file,$quality,$type);}$quality=$quality===NULL?'':'-quality '.max(0,min(100,(int)$quality));if($file===NULL){$this->execute("convert $quality -strip %input %output",$type===NULL?self::PNG:$type);readfile($this->file);}else{$this->execute("convert $quality -strip %input %output",(string)$file);}return
  3289. TRUE;}private
  3290. function
  3291. setFile($file){$this->file=$file;$res=$this->execute('identify -format "%w,%h,%m" '.escapeshellarg($this->file));if(!$res){throw
  3292. new
  3293. Exception("Unknown image type in file '$file' or ImageMagick not available.");}list($this->width,$this->height,$format)=explode(',',$res,3);return$format;}private
  3294. function
  3295. execute($command,$output=NULL){$command=str_replace('%input',escapeshellarg($this->file),$command);if($output){$newFile=is_string($output)?$output:(self::$tempDir?self::$tempDir:dirname($this->file)).'/'.uniqid('_tempimage',TRUE).image_type_to_extension($output);$command=str_replace('%output',escapeshellarg($newFile),$command);}$lines=array();exec(self::$path.$command,$lines,$status);if($output){if($status!=0){throw
  3296. new
  3297. Exception("Unknown error while calling ImageMagick.");}if($this->isTemporary){unlink($this->file);}$this->setFile($newFile);$this->isTemporary=!is_string($output);}return$lines?$lines[0]:FALSE;}function
  3298. __destruct(){if($this->file!==NULL&&$this->isTemporary){unlink($this->file);}}}class
  3299. InstanceFilterIterator
  3300. extends
  3301. FilterIterator
  3302. implements
  3303. Countable{private$type;function
  3304. __construct(Iterator$iterator,$type){$this->type=$type;parent::__construct($iterator);}function
  3305. accept(){return$this->current()instanceof$this->type;}function
  3306. count(){return
  3307. iterator_count($this);}}final
  3308. class
  3309. SafeStream{const
  3310. PROTOCOL='safe';private$handle;private$filePath;private$tempFile;private$startPos=0;private$writeError=FALSE;static
  3311. function
  3312. register(){return
  3313. stream_wrapper_register(self::PROTOCOL,__CLASS__);}function
  3314. stream_open($path,$mode,$options,&$opened_path){$path=substr($path,strlen(self::PROTOCOL)+3);$flag=trim($mode,'rwax+');$mode=trim($mode,'tb');$use_path=(bool)(STREAM_USE_PATH&$options);$append=FALSE;switch($mode){case'r':case'r+':$handle=@fopen($path,$mode.$flag,$use_path);if(!$handle)return
  3315. FALSE;if(flock($handle,$mode=='r'?LOCK_SH:LOCK_EX)){$this->handle=$handle;return
  3316. TRUE;}fclose($handle);return
  3317. FALSE;case'a':case'a+':$append=TRUE;case'w':case'w+':$handle=@fopen($path,'r+'.$flag,$use_path);if($handle){if(flock($handle,LOCK_EX)){if($append){fseek($handle,0,SEEK_END);$this->startPos=ftell($handle);}else{ftruncate($handle,0);}$this->handle=$handle;return
  3318. TRUE;}fclose($handle);}$mode{0}='x';case'x':case'x+':if(file_exists($path))return
  3319. FALSE;$tmp='~~'.time().'.tmp';$handle=@fopen($path.$tmp,$mode.$flag,$use_path);if($handle){if(flock($handle,LOCK_EX)){$this->handle=$handle;if(!@rename($path.$tmp,$path)){$this->tempFile=realpath($path.$tmp);$this->filePath=substr($this->tempFile,0,-strlen($tmp));}return
  3320. TRUE;}fclose($handle);unlink($path.$tmp);}return
  3321. FALSE;default:trigger_error("Unsupported mode $mode",E_USER_WARNING);return
  3322. FALSE;}}function
  3323. stream_close(){if($this->writeError){ftruncate($this->handle,$this->startPos);}fclose($this->handle);if($this->tempFile){if(!@rename($this->tempFile,$this->filePath)){unlink($this->tempFile);}}}function
  3324. stream_read($length){return
  3325. fread($this->handle,$length);}function
  3326. stream_write($data){$len=strlen($data);$res=fwrite($this->handle,$data,$len);if($res!==$len){$this->writeError=TRUE;}return$res;}function
  3327. stream_tell(){return
  3328. ftell($this->handle);}function
  3329. stream_eof(){return
  3330. feof($this->handle);}function
  3331. stream_seek($offset,$whence){return
  3332. fseek($this->handle,$offset,$whence)===0;}function
  3333. stream_stat(){return
  3334. fstat($this->handle);}function
  3335. url_stat($path,$flags){$path=substr($path,strlen(self::PROTOCOL)+3);return($flags&STREAM_URL_STAT_LINK)?@lstat($path):@stat($path);}function
  3336. unlink($path){$path=substr($path,strlen(self::PROTOCOL)+3);return
  3337. unlink($path);}}class
  3338. RobotLoader
  3339. extends
  3340. AutoLoader{public$scanDirs;public$ignoreDirs='.*, *.old, *.bak, *.tmp, temp';public$acceptFiles='*.php, *.php5';public$autoRebuild;private$list=array();private$timestamps;private$rebuilded=FALSE;private$acceptMask;private$ignoreMask;function
  3341. __construct(){if(!extension_loaded('tokenizer')){throw
  3342. new
  3343. Exception("PHP extension Tokenizer is not loaded.");}}function
  3344. register(){$cache=$this->getCache();$key=$this->getKey();if(isset($cache[$key])){$this->list=$cache[$key];}else{$this->rebuild();}if(isset($this->list[strtolower(__CLASS__)])&&class_exists('NetteLoader',FALSE)){NetteLoader::getInstance()->unregister();}parent::register();}function
  3345. tryLoad($type){$type=strtolower($type);if(isset($this->list[$type])){if($this->list[$type]!==FALSE){LimitedScope::load($this->list[$type]);self::$count++;}}else{$this->list[$type]=FALSE;if($this->autoRebuild===NULL){$this->autoRebuild=!$this->isProduction();}if($this->autoRebuild){$this->rebuild(FALSE);}if($this->list[$type]!==FALSE){LimitedScope::load($this->list[$type]);self::$count++;}}}function
  3346. rebuild($force=TRUE){$cache=$this->getCache();$key=$this->getKey();$this->acceptMask=self::wildcards2re($this->acceptFiles);$this->ignoreMask=self::wildcards2re($this->ignoreDirs);$this->timestamps=$cache[$key.'ts'];if($force||!$this->rebuilded){foreach(array_unique($this->scanDirs)as$dir){$this->scanDirectory($dir);}}$this->rebuilded=TRUE;$cache[$key]=$this->list;$cache[$key.'ts']=$this->timestamps;$this->timestamps=NULL;}function
  3347. addDirectory($path){foreach((array)$path
  3348. as$val){$real=realpath($val);if($real===FALSE){throw
  3349. new
  3350. DirectoryNotFoundException("Directory '$val' not found.");}$this->scanDirs[]=$real;}}function
  3351. addClass($class,$file){$class=strtolower($class);if(!empty($this->list[$class])&&$this->list[$class]!==$file){spl_autoload_call($class);throw
  3352. new
  3353. InvalidStateException("Ambiguous class '$class' resolution; defined in $file and in ".$this->list[$class].".");}$this->list[$class]=$file;}private
  3354. function
  3355. scanDirectory($dir){$iterator=dir($dir);if(!$iterator)return;$disallow=array();if(is_file($dir.'/netterobots.txt')){foreach(file($dir.'/netterobots.txt')as$s){if(preg_match('#^disallow\\s*:\\s*(\\S+)#i',$s,$m)){$disallow[trim($m[1],'/')]=TRUE;}}if(isset($disallow['']))return;}while(FALSE!==($entry=$iterator->read())){if($entry=='.'||$entry=='..'||isset($disallow[$entry]))continue;$path=$dir.DIRECTORY_SEPARATOR.$entry;if(is_dir($path)){if(!preg_match($this->ignoreMask,$entry)){$this->scanDirectory($path);}continue;}if(is_file($path)&&preg_match($this->acceptMask,$entry)){$time=filemtime($path);if(!isset($this->timestamps[$path])||$this->timestamps[$path]!==$time){$this->timestamps[$path]=$time;$this->scanScript($path);}}}$iterator->close();}private
  3356. function
  3357. scanScript($file){if(!defined('T_NAMESPACE')){define('T_NAMESPACE',-1);define('T_NS_SEPARATOR',-1);}$expected=FALSE;$namespace='';$level=0;$s=file_get_contents($file);if(preg_match('#//nette'.'loader=(\S*)#',$s,$matches)){foreach(explode(',',$matches[1])as$name){$this->addClass($name,$file);}return;}foreach(token_get_all($s)as$token){if(is_array($token)){switch($token[0]){case
  3358. T_COMMENT:case
  3359. T_DOC_COMMENT:case
  3360. T_WHITESPACE:continue
  3361. 2;case
  3362. T_NS_SEPARATOR:case
  3363. T_STRING:if($expected){$name.=$token[1];}continue
  3364. 2;case
  3365. T_NAMESPACE:case
  3366. T_CLASS:case
  3367. T_INTERFACE:$expected=$token[0];$name='';continue
  3368. 2;case
  3369. T_CURLY_OPEN:case
  3370. T_DOLLAR_OPEN_CURLY_BRACES:$level++;}}if($expected){switch($expected){case
  3371. T_CLASS:case
  3372. T_INTERFACE:if($level===0){$this->addClass($namespace.$name,$file);}break;case
  3373. T_NAMESPACE:$namespace=$name.'\\';}$expected=NULL;}if($token==='{'){$level++;}elseif($token==='}'){$level--;}}}private
  3374. static
  3375. function
  3376. wildcards2re($wildcards){$mask=array();foreach(explode(',',$wildcards)as$wildcard){$wildcard=trim($wildcard);$wildcard=addcslashes($wildcard,'.\\+[^]$(){}=!><|:#');$wildcard=strtr($wildcard,array('*'=>'.*','?'=>'.'));$mask[]=$wildcard;}return'#^('.implode('|',$mask).')$#i';}protected
  3377. function
  3378. getCache(){return
  3379. Environment::getCache('Nette.RobotLoader');}protected
  3380. function
  3381. getKey(){return
  3382. md5("$this->ignoreDirs|$this->acceptFiles|".implode('|',$this->scanDirs));}protected
  3383. function
  3384. isProduction(){return
  3385. Environment::isProduction();}}class
  3386. MailMimePart
  3387. extends
  3388. Object{const
  3389. ENCODING_BASE64='base64';const
  3390. ENCODING_7BIT='7bit';const
  3391. ENCODING_8BIT='8bit';const
  3392. ENCODING_QUOTED_PRINTABLE='quoted-printable';const
  3393. EOL="\r\n";const
  3394. LINE_LENGTH=76;private$headers=array();private$parts=array();private$body;function
  3395. setHeader($name,$value,$append=FALSE){if(!$name||preg_match('#[^a-z0-9-]#i',$name)){throw
  3396. new
  3397. InvalidArgumentException("Header name must be non-empty alphanumeric string, '$name' given.");}if($value==NULL){if(!$append){unset($this->headers[$name]);}}elseif(is_array($value)){$tmp=&$this->headers[$name];if(!$append||!is_array($tmp)){$tmp=array();}foreach($value
  3398. as$email=>$name){if(!preg_match('#^[^@",\s]+@[^@",\s]+\.[a-z]{2,10}$#i',$email)){throw
  3399. new
  3400. InvalidArgumentException("Email address '$email' is not valid.");}if(preg_match('#[\r\n]#',$name)){throw
  3401. new
  3402. InvalidArgumentException("Name cannot contain the line separator.");}$tmp[$email]=$name;}}else{$this->headers[$name]=preg_replace('#[\r\n]+#',' ',$value);}return$this;}function
  3403. getHeader($name){return
  3404. isset($this->headers[$name])?$this->headers[$name]:NULL;}function
  3405. clearHeader($name){unset($this->headers[$name]);return$this;}function
  3406. getEncodedHeader($name,$charset='UTF-8'){$len=strlen($name)+2;if(!isset($this->headers[$name])){return
  3407. NULL;}elseif(is_array($this->headers[$name])){$s='';foreach($this->headers[$name]as$email=>$name){if($name!=NULL){$s.=self::encodeQuotedPrintableHeader(strspn($name,'.,;<@>()[]"=?')?'"'.addcslashes($name,'"\\').'"':$name,$charset,$len);$email=" <$email>";}if($len+strlen($email)+1>self::LINE_LENGTH){$s.=self::EOL."\t";$len=1;}$s.="$email,";$len+=strlen($email)+1;}return
  3408. substr($s,0,-1);}else{return
  3409. self::encodeQuotedPrintableHeader($this->headers[$name],$charset,$len);}}function
  3410. getHeaders(){return$this->headers;}function
  3411. setContentType($contentType,$charset=NULL){$this->setHeader('Content-Type',$contentType.($charset?"; charset=$charset":''));return$this;}function
  3412. setEncoding($encoding){$this->setHeader('Content-Transfer-Encoding',$encoding);return$this;}function
  3413. getEncoding(){return$this->getHeader('Content-Transfer-Encoding');}function
  3414. addPart(MailMimePart$part=NULL){return$this->parts[]=$part===NULL?new
  3415. self:$part;}function
  3416. setBody($body){$this->body=$body;return$this;}function
  3417. getBody(){return$this->body;}function
  3418. generateMessage(){$output='';$boundary='--------'.md5(uniqid('',TRUE));foreach($this->headers
  3419. as$name=>$value){$output.=$name.': '.$this->getEncodedHeader($name);if($this->parts&&$name==='Content-Type'){$output.=';'.self::EOL."\tboundary=\"$boundary\"";}$output.=self::EOL;}$output.=self::EOL;$body=(string)$this->body;if($body!==''){switch($this->getEncoding()){case
  3420. self::ENCODING_QUOTED_PRINTABLE:$output.=function_exists('quoted_printable_encode')?quoted_printable_encode($body):self::encodeQuotedPrintable($body);break;case
  3421. self::ENCODING_BASE64:$output.=rtrim(chunk_split(base64_encode($body),self::LINE_LENGTH,self::EOL));break;case
  3422. self::ENCODING_7BIT:$body=preg_replace('#[\x80-\xFF]+#','',$body);case
  3423. self::ENCODING_8BIT:$body=str_replace(array("\x00","\r"),'',$body);$body=str_replace("\n",self::EOL,$body);$output.=$body;break;default:throw
  3424. new
  3425. InvalidStateException('Unknown encoding');}}if($this->parts){if(substr($output,-strlen(self::EOL))!==self::EOL)$output.=self::EOL;foreach($this->parts
  3426. as$part){$output.='--'.$boundary.self::EOL.$part->generateMessage().self::EOL;}$output.='--'.$boundary.'--';}return$output;}private
  3427. static
  3428. function
  3429. encodeQuotedPrintableHeader($s,$charset='UTF-8',&$len=0){$range='!"#$%&\'()*+,-./0123456789:;<>@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^`abcdefghijklmnopqrstuvwxyz{|}';if(strspn($s,$range."=? _\r\n\t")===strlen($s)){return$s;}$prefix="=?$charset?Q?";$pos=0;$len+=strlen($prefix);$o=$prefix;$size=strlen($s);while($pos<$size){if($l=strspn($s,$range,$pos)){while($len+$l>self::LINE_LENGTH-2){$lx=self::LINE_LENGTH-$len-2;$o.=substr($s,$pos,$lx).'?='.self::EOL."\t".$prefix;$pos+=$lx;$l-=$lx;$len=strlen($prefix)+1;}$o.=substr($s,$pos,$l);$len+=$l;$pos+=$l;}else{$len+=3;if(($s[$pos]&"\xC0")!=="\x80"&&$len>self::LINE_LENGTH-2-9){$o.='?='.self::EOL."\t".$prefix;$len=strlen($prefix)+1+3;}$o.='='.strtoupper(bin2hex($s[$pos]));$pos++;}}return$o.'?=';}static
  3430. function
  3431. encodeQuotedPrintable($s){$range='!"#$%&\'()*+,-./0123456789:;<>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}';$pos=0;$len=0;$o='';$size=strlen($s);while($pos<$size){if($l=strspn($s,$range,$pos)){while($len+$l>self::LINE_LENGTH-1){$lx=self::LINE_LENGTH-$len-1;$o.=substr($s,$pos,$lx).'='.self::EOL;$pos+=$lx;$l-=$lx;$len=0;}$o.=substr($s,$pos,$l);$len+=$l;$pos+=$l;}else{$len+=3;if($len>self::LINE_LENGTH-1){$o.='='.self::EOL;$len=3;}$o.='='.strtoupper(bin2hex($s[$pos]));$pos++;}}return
  3432. rtrim($o,'='.self::EOL);}}class
  3433. Mail
  3434. extends
  3435. MailMimePart{const
  3436. HIGH=1;const
  3437. NORMAL=3;const
  3438. LOW=5;public
  3439. static$defaultMailer='Nette\Mail\SendmailMailer';public
  3440. static$defaultHeaders=array('MIME-Version'=>'1.0','X-Mailer'=>'Nette Framework');private$mailer;private$charset='UTF-8';private$attachments=array();private$inlines=array();private$html;private$basePath;function
  3441. __construct(){foreach(self::$defaultHeaders
  3442. as$name=>$value){$this->setHeader($name,$value);}$this->setHeader('Date',date('r'));}function
  3443. setFrom($email,$name=NULL){$this->setHeader('From',$this->formatEmail($email,$name));return$this;}function
  3444. getFrom(){return$this->getHeader('From');}function
  3445. addReplyTo($email,$name=NULL){$this->setHeader('Reply-To',$this->formatEmail($email,$name),TRUE);return$this;}function
  3446. setSubject($subject){$this->setHeader('Subject',$subject);return$this;}function
  3447. getSubject(){return$this->getHeader('Subject');}function
  3448. addTo($email,$name=NULL){$this->setHeader('To',$this->formatEmail($email,$name),TRUE);return$this;}function
  3449. addCc($email,$name=NULL){$this->setHeader('Cc',$this->formatEmail($email,$name),TRUE);return$this;}function
  3450. addBcc($email,$name=NULL){$this->setHeader('Bcc',$this->formatEmail($email,$name),TRUE);return$this;}private
  3451. function
  3452. formatEmail($email,$name){if(!$name&&preg_match('#^(.+) +<(.*)>$#',$email,$matches)){return
  3453. array($matches[2]=>$matches[1]);}else{return
  3454. array($email=>$name);}}function
  3455. setReturnPath($email){$this->setHeader('Return-Path',$email);return$this;}function
  3456. getReturnPath(){return$this->getHeader('From');}function
  3457. setPriority($priority){$this->setHeader('X-Priority',(int)$priority);return$this;}function
  3458. getPriority(){return$this->getHeader('X-Priority');}function
  3459. setHtmlBody($html,$basePath=NULL){$this->html=$html;$this->basePath=$basePath;return$this;}function
  3460. getHtmlBody(){return$this->html;}function
  3461. addEmbeddedFile($file,$content=NULL,$contentType=NULL){$part=new
  3462. MailMimePart;$part->setBody($content===NULL?$this->readFile($file,$contentType):(string)$content);$part->setContentType($contentType?$contentType:'application/octet-stream');$part->setEncoding(self::ENCODING_BASE64);$part->setHeader('Content-Disposition','inline; filename="'.basename($file).'"');$part->setHeader('Content-ID','<'.md5(uniqid('',TRUE)).'>');return$this->inlines[$file]=$part;}function
  3463. addAttachment($file,$content=NULL,$contentType=NULL){$part=new
  3464. MailMimePart;$part->setBody($content===NULL?$this->readFile($file,$contentType):(string)$content);$part->setContentType($contentType?$contentType:'application/octet-stream');$part->setEncoding(self::ENCODING_BASE64);$part->setHeader('Content-Disposition','attachment; filename="'.basename($file).'"');return$this->attachments[]=$part;}private
  3465. function
  3466. readFile($file,&$contentType){if(!is_file($file)){throw
  3467. new
  3468. FileNotFoundException("File '$file' not found.");}if(!$contentType&&$info=getimagesize($file)){$contentType=$info['mime'];}return
  3469. file_get_contents($file);}function
  3470. send(){$this->getMailer()->send($this->build());}function
  3471. setMailer(IMailer$mailer){$this->mailer=$mailer;return$this;}function
  3472. getMailer(){if($this->mailer===NULL){Framework::fixNamespace(self::$defaultMailer);$this->mailer=is_object(self::$defaultMailer)?self::$defaultMailer:new
  3473. self::$defaultMailer;}return$this->mailer;}protected
  3474. function
  3475. build(){$mail=clone$this;$hostname=isset($_SERVER['HTTP_HOST'])?$_SERVER['HTTP_HOST']:isset($_SERVER['SERVER_NAME'])?$_SERVER['SERVER_NAME']:'localhost';$mail->setHeader('Message-ID','<'.md5(uniqid('',TRUE))."@$hostname>");$mail->buildHtml();$mail->buildText();$cursor=$mail;if($mail->attachments){$tmp=$cursor->setContentType('multipart/mixed');$cursor=$cursor->addPart();foreach($mail->attachments
  3476. as$value){$tmp->addPart($value);}}if($mail->html!=NULL){$tmp=$cursor->setContentType('multipart/alternative');$cursor=$cursor->addPart();$alt=$tmp->addPart();if($mail->inlines){$tmp=$alt->setContentType('multipart/related');$alt=$alt->addPart();foreach($mail->inlines
  3477. as$name=>$value){$tmp->addPart($value);}}$alt->setContentType('text/html',$mail->charset)->setEncoding(preg_match('#[\x80-\xFF]#',$mail->html)?self::ENCODING_8BIT:self::ENCODING_7BIT)->setBody($mail->html);}$text=$mail->getBody();$mail->setBody(NULL);$cursor->setContentType('text/plain',$mail->charset)->setEncoding(preg_match('#[\x80-\xFF]#',$text)?self::ENCODING_8BIT:self::ENCODING_7BIT)->setBody($text);return$mail;}protected
  3478. function
  3479. buildHtml(){if($this->html
  3480. instanceof
  3481. ITemplate){$this->html->mail=$this;if($this->basePath===NULL&&$this->html
  3482. instanceof
  3483. IFileTemplate){$this->basePath=dirname($this->html->getFile());}$this->html=$this->html->__toString(TRUE);}if($this->basePath!==FALSE){$cids=array();preg_match_all('#(src\s*=\s*|background\s*=\s*|url\()(["\'])(?![a-z]+:|[/\\#])(.+?)\\2#i',$this->html,$matches,PREG_SET_ORDER|PREG_OFFSET_CAPTURE);foreach(array_reverse($matches)as$m){$file=rtrim($this->basePath,'/\\').'/'.$m[3][0];$cid=isset($cids[$file])?$cids[$file]:$cids[$file]=substr($this->addEmbeddedFile($file)->getHeader("Content-ID"),1,-1);$this->html=substr_replace($this->html,"{$m[1][0]}{$m[2][0]}cid:$cid{$m[2][0]}",$m[0][1],strlen($m[0][0]));}}if(!$this->getSubject()&&preg_match('#<title>(.+?)</title>#is',$this->html,$matches)){$this->setSubject(html_entity_decode($matches[1],ENT_QUOTES,$this->charset));}}protected
  3484. function
  3485. buildText(){$text=$this->getBody();if($text
  3486. instanceof
  3487. ITemplate){$text->mail=$this;$this->setBody($text->__toString(TRUE));}elseif($text==NULL&&$this->html!=NULL){$text=preg_replace('#<(style|script|head).*</\\1>#Uis','',$this->html);$text=preg_replace('#<t[dh][ >]#i'," $0",$text);$text=preg_replace('#[ \t\r\n]+#',' ',$text);$text=preg_replace('#<(/?p|/?h\d|li|br|/tr)[ >]#i',"\n$0",$text);$text=html_entity_decode(strip_tags($text),ENT_QUOTES,$this->charset);$this->setBody(trim($text));}}}class
  3488. SendmailMailer
  3489. extends
  3490. Object
  3491. implements
  3492. IMailer{function
  3493. send(Mail$mail){$tmp=clone$mail;$tmp->setHeader('Subject',NULL);$tmp->setHeader('To',NULL);$parts=explode(Mail::EOL.Mail::EOL,$tmp->generateMessage(),2);$linux=strncasecmp(PHP_OS,'win',3);Tools::tryError();$res=mail($mail->getEncodedHeader('To'),$mail->getEncodedHeader('Subject'),$linux?str_replace(Mail::EOL,"\n",$parts[1]):$parts[1],$linux?str_replace(Mail::EOL,"\n",$parts[0]):$parts[0]);if(Tools::catchError($msg)){throw
  3494. new
  3495. InvalidStateException($msg);}elseif(!$res){throw
  3496. new
  3497. InvalidStateException('Unable to send email.');}}}class
  3498. Paginator
  3499. extends
  3500. Object{private$base=1;private$itemsPerPage;private$page;private$itemCount=0;function
  3501. setPage($page){$this->page=(int)$page;return$this;}function
  3502. getPage(){return$this->base+$this->getPageIndex();}function
  3503. getFirstPage(){return$this->base;}function
  3504. getLastPage(){return$this->base+max(0,$this->getPageCount()-1);}function
  3505. setBase($base){$this->base=(int)$base;return$this;}function
  3506. getBase(){return$this->base;}protected
  3507. function
  3508. getPageIndex(){return
  3509. min(max(0,$this->page-$this->base),max(0,$this->getPageCount()-1));}function
  3510. isFirst(){return$this->getPageIndex()===0;}function
  3511. isLast(){return$this->getPageIndex()===$this->getPageCount()-1;}function
  3512. getPageCount(){return(int)ceil($this->itemCount/$this->itemsPerPage);}function
  3513. setItemsPerPage($itemsPerPage){$this->itemsPerPage=max(1,(int)$itemsPerPage);return$this;}function
  3514. getItemsPerPage(){return$this->itemsPerPage;}function
  3515. setItemCount($itemCount){$this->itemCount=$itemCount===FALSE?PHP_INT_MAX:max(0,(int)$itemCount);return$this;}function
  3516. getItemCount(){return$this->itemCount;}function
  3517. getOffset(){return$this->getPageIndex()*$this->itemsPerPage;}function
  3518. getCountdownOffset(){return
  3519. max(0,$this->itemCount-($this->getPageIndex()+1)*$this->itemsPerPage);}function
  3520. getLength(){return
  3521. min($this->itemsPerPage,$this->itemCount-$this->getPageIndex()*$this->itemsPerPage);}}class
  3522. Annotation
  3523. extends
  3524. Object
  3525. implements
  3526. IAnnotation{function
  3527. __construct(array$values){foreach($values
  3528. as$k=>$v){$this->$k=$v;}}function
  3529. __toString(){return$this->value;}}/**
  3530. * Annotations support for PHP.
  3531. *
  3532. * @copyright Copyright (c) 2004, 2010 David Grudl
  3533. * @package Nette\Reflection
  3534. * @Annotation
  3535. */final
  3536. class
  3537. AnnotationsParser{const
  3538. RE_STRING='\'(?:\\\\.|[^\'\\\\])*\'|"(?:\\\\.|[^"\\\\])*"';const
  3539. RE_IDENTIFIER='[_a-zA-Z\x7F-\xFF][_a-zA-Z0-9\x7F-\xFF]*';public
  3540. static$useReflection;private
  3541. static$cache;private
  3542. static$timestamps;final
  3543. function
  3544. __construct(){throw
  3545. new
  3546. LogicException("Cannot instantiate static class ".get_class($this));}static
  3547. function
  3548. getAll(Reflector$r){if($r
  3549. instanceof
  3550. ReflectionClass){$type=$r->getName();$member='';}elseif($r
  3551. instanceof
  3552. ReflectionMethod){$type=$r->getDeclaringClass()->getName();$member=$r->getName();}else{$type=$r->getDeclaringClass()->getName();$member='$'.$r->getName();}if(!self::$useReflection){$file=$r
  3553. instanceof
  3554. ReflectionClass?$r->getFileName():$r->getDeclaringClass()->getFileName();if($file&&isset(self::$timestamps[$file])&&self::$timestamps[$file]!==filemtime($file)){unset(self::$cache[$type]);}unset(self::$timestamps[$file]);}if(isset(self::$cache[$type][$member])){return
  3555. self::$cache[$type][$member];}if(self::$useReflection===NULL){self::$useReflection=(bool)ClassReflection::from(__CLASS__)->getDocComment();}if(self::$useReflection){return
  3556. self::$cache[$type][$member]=self::parseComment($r->getDocComment());}else{if(self::$cache===NULL){self::$cache=(array)self::getCache()->offsetGet('list');self::$timestamps=isset(self::$cache['*'])?self::$cache['*']:array();}if(!isset(self::$cache[$type])&&$file){self::$cache['*'][$file]=filemtime($file);self::parseScript($file);self::getCache()->save('list',self::$cache);}if(isset(self::$cache[$type][$member])){return
  3557. self::$cache[$type][$member];}else{return
  3558. self::$cache[$type][$member]=array();}}}private
  3559. static
  3560. function
  3561. parseComment($comment){static$tokens=array('true'=>TRUE,'false'=>FALSE,'null'=>NULL,''=>TRUE);preg_match_all('~
  3562. @('.self::RE_IDENTIFIER.')[ \t]* ## annotation
  3563. (
  3564. \((?>'.self::RE_STRING.'|[^\'")@]+)+\)| ## (value)
  3565. [^(@\r\n][^@\r\n]*|) ## value
  3566. ~xi',trim($comment,'/*'),$matches,PREG_SET_ORDER);$res=array();foreach($matches
  3567. as$match){list(,$name,$value)=$match;if(substr($value,0,1)==='('){$items=array();$key='';$val=TRUE;$value[0]=',';while(preg_match('#\s*,\s*(?>('.self::RE_IDENTIFIER.')\s*=\s*)?('.self::RE_STRING.'|[^\'"),\s][^\'"),]*)#A',$value,$m)){$value=substr($value,strlen($m[0]));list(,$key,$val)=$m;if($val[0]==="'"||$val[0]==='"'){$val=substr($val,1,-1);}elseif(is_numeric($val)){$val=1*$val;}else{$lval=strtolower($val);$val=array_key_exists($lval,$tokens)?$tokens[$lval]:$val;}if($key===''){$items[]=$val;}else{$items[$key]=$val;}}$value=count($items)<2&&$key===''?$val:$items;}else{$value=trim($value);if(is_numeric($value)){$value=1*$value;}else{$lval=strtolower($value);$value=array_key_exists($lval,$tokens)?$tokens[$lval]:$value;}}$class=$name.'Annotation';if(class_exists($class)){$res[$name][]=new$class(is_array($value)?$value:array('value'=>$value));}else{$res[$name][]=is_array($value)?new
  3568. ArrayObject($value,ArrayObject::ARRAY_AS_PROPS):$value;}}return$res;}private
  3569. static
  3570. function
  3571. parseScript($file){if(!defined('T_NAMESPACE')){define('T_NAMESPACE',-1);define('T_NS_SEPARATOR',-1);}$s=file_get_contents($file);if(preg_match('#//nette'.'loader=(\S*)#',$s)){return;}$expected=$namespace=$class=$docComment=NULL;$level=$classLevel=0;foreach(token_get_all($s)as$token){if(is_array($token)){switch($token[0]){case
  3572. T_DOC_COMMENT:$docComment=$token[1];case
  3573. T_WHITESPACE:case
  3574. T_COMMENT:continue
  3575. 2;case
  3576. T_STRING:case
  3577. T_NS_SEPARATOR:case
  3578. T_VARIABLE:if($expected){$name.=$token[1];}continue
  3579. 2;case
  3580. T_FUNCTION:case
  3581. T_VAR:case
  3582. T_PUBLIC:case
  3583. T_PROTECTED:case
  3584. T_NAMESPACE:case
  3585. T_CLASS:case
  3586. T_INTERFACE:$expected=$token[0];$name=NULL;continue
  3587. 2;case
  3588. T_STATIC:case
  3589. T_ABSTRACT:case
  3590. T_FINAL:continue
  3591. 2;case
  3592. T_CURLY_OPEN:case
  3593. T_DOLLAR_OPEN_CURLY_BRACES:$level++;}}if($expected){switch($expected){case
  3594. T_CLASS:case
  3595. T_INTERFACE:$class=$namespace.$name;$classLevel=$level;$name='';case
  3596. T_FUNCTION:if($token==='&')continue
  3597. 2;case
  3598. T_VAR:case
  3599. T_PUBLIC:case
  3600. T_PROTECTED:if($class&&$name!==NULL&&$docComment){self::$cache[$class][$name]=self::parseComment($docComment);}break;case
  3601. T_NAMESPACE:$namespace=$name.'\\';}$expected=$docComment=NULL;}if($token===';'){$docComment=NULL;}elseif($token==='{'){$docComment=NULL;$level++;}elseif($token==='}'){$level--;if($level===$classLevel){$class=NULL;}}}}protected
  3602. static
  3603. function
  3604. getCache(){return
  3605. Environment::getCache('Nette.Annotations');}}class
  3606. ExtensionReflection
  3607. extends
  3608. ReflectionExtension{function
  3609. __toString(){return'Extension '.$this->getName();}static
  3610. function
  3611. import(ReflectionExtension$ref){return
  3612. new
  3613. self($ref->getName());}function
  3614. getClasses(){return
  3615. array_map(array('ClassReflection','import'),parent::getClasses());}function
  3616. getFunctions(){return
  3617. array_map(array('FunctionReflection','import'),parent::getFunctions());}function
  3618. getReflection(){return
  3619. new
  3620. ClassReflection($this);}function
  3621. __call($name,$args){return
  3622. ObjectMixin::call($this,$name,$args);}function&__get($name){return
  3623. ObjectMixin::get($this,$name);}function
  3624. __set($name,$value){return
  3625. ObjectMixin::set($this,$name,$value);}function
  3626. __isset($name){return
  3627. ObjectMixin::has($this,$name);}function
  3628. __unset($name){throw
  3629. new
  3630. MemberAccessException("Cannot unset the property {$this->reflection->name}::\$$name.");}}class
  3631. FunctionReflection
  3632. extends
  3633. ReflectionFunction{function
  3634. __toString(){return'Function '.$this->getName().'()';}static
  3635. function
  3636. import(ReflectionFunction$ref){return
  3637. new
  3638. self($ref->getName());}function
  3639. getExtension(){return($ref=parent::getExtension())?ExtensionReflection::import($ref):NULL;}function
  3640. getParameters(){return
  3641. array_map(array('MethodParameterReflection','import'),parent::getParameters());}function
  3642. getReflection(){return
  3643. new
  3644. ClassReflection($this);}function
  3645. __call($name,$args){return
  3646. ObjectMixin::call($this,$name,$args);}function&__get($name){return
  3647. ObjectMixin::get($this,$name);}function
  3648. __set($name,$value){return
  3649. ObjectMixin::set($this,$name,$value);}function
  3650. __isset($name){return
  3651. ObjectMixin::has($this,$name);}function
  3652. __unset($name){throw
  3653. new
  3654. MemberAccessException("Cannot unset the property {$this->reflection->name}::\$$name.");}}class
  3655. MethodParameterReflection
  3656. extends
  3657. ReflectionParameter{static
  3658. function
  3659. import(ReflectionParameter$ref){$method=$ref->getDeclaringFunction();return
  3660. new
  3661. self($method
  3662. instanceof
  3663. ReflectionMethod?array($ref->getDeclaringClass()->getName(),$method->getName()):$method->getName(),$ref->getName());}function
  3664. getClass(){return($ref=parent::getClass())?ClassReflection::import($ref):NULL;}function
  3665. getDeclaringClass(){return($ref=parent::getDeclaringClass())?ClassReflection::import($ref):NULL;}function
  3666. getDeclaringFunction(){return($ref=parent::getDeclaringFunction())instanceof
  3667. ReflectionMethod?MethodReflection::import($ref):FunctionReflection::import($ref);}function
  3668. getReflection(){return
  3669. new
  3670. ClassReflection($this);}function
  3671. __call($name,$args){return
  3672. ObjectMixin::call($this,$name,$args);}function&__get($name){return
  3673. ObjectMixin::get($this,$name);}function
  3674. __set($name,$value){return
  3675. ObjectMixin::set($this,$name,$value);}function
  3676. __isset($name){return
  3677. ObjectMixin::has($this,$name);}function
  3678. __unset($name){throw
  3679. new
  3680. MemberAccessException("Cannot unset the property {$this->reflection->name}::\$$name.");}}class
  3681. MethodReflection
  3682. extends
  3683. ReflectionMethod{static
  3684. function
  3685. from($class,$method){return
  3686. new
  3687. self(is_object($class)?get_class($class):$class,$method);}function
  3688. getDefaultParameters(){$res=array();foreach(parent::getParameters()as$param){$res[$param->getName()]=$param->isDefaultValueAvailable()?$param->getDefaultValue():NULL;if($param->isArray()){settype($res[$param->getName()],'array');}}return$res;}function
  3689. invokeNamedArgs($object,$args){$res=array();$i=0;foreach($this->getDefaultParameters()as$name=>$def){if(isset($args[$name])){$val=$args[$name];if($def!==NULL){settype($val,gettype($def));}$res[$i++]=$val;}else{$res[$i++]=$def;}}return$this->invokeArgs($object,$res);}function
  3690. getCallback(){return
  3691. new
  3692. Callback(parent::getDeclaringClass()->getName(),$this->getName());}function
  3693. __toString(){return'Method '.parent::getDeclaringClass()->getName().'::'.$this->getName().'()';}static
  3694. function
  3695. import(ReflectionMethod$ref){return
  3696. new
  3697. self($ref->getDeclaringClass()->getName(),$ref->getName());}function
  3698. getDeclaringClass(){return
  3699. ClassReflection::import(parent::getDeclaringClass());}function
  3700. getExtension(){return($ref=parent::getExtension())?ExtensionReflection::import($ref):NULL;}function
  3701. getParameters(){return
  3702. array_map(array('MethodParameterReflection','import'),parent::getParameters());}function
  3703. hasAnnotation($name){$res=AnnotationsParser::getAll($this);return!empty($res[$name]);}function
  3704. getAnnotation($name){$res=AnnotationsParser::getAll($this);return
  3705. isset($res[$name])?end($res[$name]):NULL;}function
  3706. getAnnotations(){return
  3707. AnnotationsParser::getAll($this);}function
  3708. getReflection(){return
  3709. new
  3710. ClassReflection($this);}function
  3711. __call($name,$args){return
  3712. ObjectMixin::call($this,$name,$args);}function&__get($name){return
  3713. ObjectMixin::get($this,$name);}function
  3714. __set($name,$value){return
  3715. ObjectMixin::set($this,$name,$value);}function
  3716. __isset($name){return
  3717. ObjectMixin::has($this,$name);}function
  3718. __unset($name){throw
  3719. new
  3720. MemberAccessException("Cannot unset the property {$this->reflection->name}::\$$name.");}}class
  3721. PropertyReflection
  3722. extends
  3723. ReflectionProperty{function
  3724. __toString(){return'Property '.parent::getDeclaringClass()->getName().'::$'.$this->getName();}static
  3725. function
  3726. import(ReflectionProperty$ref){return
  3727. new
  3728. self($ref->getDeclaringClass()->getName(),$ref->getName());}function
  3729. getDeclaringClass(){return
  3730. ClassReflection::import(parent::getDeclaringClass());}function
  3731. hasAnnotation($name){$res=AnnotationsParser::getAll($this);return!empty($res[$name]);}function
  3732. getAnnotation($name){$res=AnnotationsParser::getAll($this);return
  3733. isset($res[$name])?end($res[$name]):NULL;}function
  3734. getAnnotations(){return
  3735. AnnotationsParser::getAll($this);}function
  3736. getReflection(){return
  3737. new
  3738. ClassReflection($this);}function
  3739. __call($name,$args){return
  3740. ObjectMixin::call($this,$name,$args);}function&__get($name){return
  3741. ObjectMixin::get($this,$name);}function
  3742. __set($name,$value){return
  3743. ObjectMixin::set($this,$name,$value);}function
  3744. __isset($name){return
  3745. ObjectMixin::has($this,$name);}function
  3746. __unset($name){throw
  3747. new
  3748. MemberAccessException("Cannot unset the property {$this->reflection->name}::\$$name.");}}class
  3749. AuthenticationException
  3750. extends
  3751. Exception{}class
  3752. Identity
  3753. extends
  3754. FreezableObject
  3755. implements
  3756. IIdentity{private$name;private$roles;private$data;function
  3757. __construct($name,$roles=NULL,$data=NULL){$this->setName($name);$this->setRoles((array)$roles);$this->data=(array)$data;}function
  3758. setName($name){$this->updating();$this->name=(string)$name;return$this;}function
  3759. getName(){return$this->name;}function
  3760. setRoles(array$roles){$this->updating();$this->roles=$roles;return$this;}function
  3761. getRoles(){return$this->roles;}function
  3762. getData(){return$this->data;}function
  3763. __set($key,$value){$this->updating();if($key==='name'||$key==='roles'){parent::__set($key,$value);}else{$this->data[$key]=$value;}}function&__get($key){if($key==='name'||$key==='roles'){return
  3764. parent::__get($key);}else{return$this->data[$key];}}}class
  3765. Permission
  3766. extends
  3767. Object
  3768. implements
  3769. IAuthorizator{private$roles=array();private$resources=array();private$rules=array('allResources'=>array('allRoles'=>array('allPrivileges'=>array('type'=>self::DENY,'assert'=>NULL),'byPrivilege'=>array()),'byRole'=>array()),'byResource'=>array());private$queriedRole,$queriedResource;function
  3770. addRole($role,$parents=NULL){$this->checkRole($role,FALSE);if(isset($this->roles[$role])){throw
  3771. new
  3772. InvalidStateException("Role '$role' already exists in the list.");}$roleParents=array();if($parents!==NULL){if(!is_array($parents)){$parents=array($parents);}foreach($parents
  3773. as$parent){$this->checkRole($parent);$roleParents[$parent]=TRUE;$this->roles[$parent]['children'][$role]=TRUE;}}$this->roles[$role]=array('parents'=>$roleParents,'children'=>array());return$this;}function
  3774. hasRole($role){$this->checkRole($role,FALSE);return
  3775. isset($this->roles[$role]);}private
  3776. function
  3777. checkRole($role,$need=TRUE){if(!is_string($role)||$role===''){throw
  3778. new
  3779. InvalidArgumentException("Role must be a non-empty string.");}elseif($need&&!isset($this->roles[$role])){throw
  3780. new
  3781. InvalidStateException("Role '$role' does not exist.");}}function
  3782. getRoleParents($role){$this->checkRole($role);return
  3783. array_keys($this->roles[$role]['parents']);}function
  3784. roleInheritsFrom($role,$inherit,$onlyParents=FALSE){$this->checkRole($role);$this->checkRole($inherit);$inherits=isset($this->roles[$role]['parents'][$inherit]);if($inherits||$onlyParents){return$inherits;}foreach($this->roles[$role]['parents']as$parent=>$foo){if($this->roleInheritsFrom($parent,$inherit)){return
  3785. TRUE;}}return
  3786. FALSE;}function
  3787. removeRole($role){$this->checkRole($role);foreach($this->roles[$role]['children']as$child=>$foo)unset($this->roles[$child]['parents'][$role]);foreach($this->roles[$role]['parents']as$parent=>$foo)unset($this->roles[$parent]['children'][$role]);unset($this->roles[$role]);foreach($this->rules['allResources']['byRole']as$roleCurrent=>$rules){if($role===$roleCurrent){unset($this->rules['allResources']['byRole'][$roleCurrent]);}}foreach($this->rules['byResource']as$resourceCurrent=>$visitor){if(isset($visitor['byRole'])){foreach($visitor['byRole']as$roleCurrent=>$rules){if($role===$roleCurrent){unset($this->rules['byResource'][$resourceCurrent]['byRole'][$roleCurrent]);}}}}return$this;}function
  3788. removeAllRoles(){$this->roles=array();foreach($this->rules['allResources']['byRole']as$roleCurrent=>$rules)unset($this->rules['allResources']['byRole'][$roleCurrent]);foreach($this->rules['byResource']as$resourceCurrent=>$visitor){foreach($visitor['byRole']as$roleCurrent=>$rules){unset($this->rules['byResource'][$resourceCurrent]['byRole'][$roleCurrent]);}}return$this;}function
  3789. addResource($resource,$parent=NULL){$this->checkResource($resource,FALSE);if(isset($this->resources[$resource])){throw
  3790. new
  3791. InvalidStateException("Resource '$resource' already exists in the list.");}if($parent!==NULL){$this->checkResource($parent);$this->resources[$parent]['children'][$resource]=TRUE;}$this->resources[$resource]=array('parent'=>$parent,'children'=>array());return$this;}function
  3792. hasResource($resource){$this->checkResource($resource,FALSE);return
  3793. isset($this->resources[$resource]);}private
  3794. function
  3795. checkResource($resource,$need=TRUE){if(!is_string($resource)||$resource===''){throw
  3796. new
  3797. InvalidArgumentException("Resource must be a non-empty string.");}elseif($need&&!isset($this->resources[$resource])){throw
  3798. new
  3799. InvalidStateException("Resource '$resource' does not exist.");}}function
  3800. resourceInheritsFrom($resource,$inherit,$onlyParent=FALSE){$this->checkResource($resource);$this->checkResource($inherit);if($this->resources[$resource]['parent']===NULL){return
  3801. FALSE;}$parent=$this->resources[$resource]['parent'];if($inherit===$parent){return
  3802. TRUE;}elseif($onlyParent){return
  3803. FALSE;}while($this->resources[$parent]['parent']!==NULL){$parent=$this->resources[$parent]['parent'];if($inherit===$parent){return
  3804. TRUE;}}return
  3805. FALSE;}function
  3806. removeResource($resource){$this->checkResource($resource);$parent=$this->resources[$resource]['parent'];if($parent!==NULL){unset($this->resources[$parent]['children'][$resource]);}$removed=array($resource);foreach($this->resources[$resource]['children']as$child=>$foo){$this->removeResource($child);$removed[]=$child;}foreach($removed
  3807. as$resourceRemoved){foreach($this->rules['byResource']as$resourceCurrent=>$rules){if($resourceRemoved===$resourceCurrent){unset($this->rules['byResource'][$resourceCurrent]);}}}unset($this->resources[$resource]);return$this;}function
  3808. removeAllResources(){foreach($this->resources
  3809. as$resource=>$foo){foreach($this->rules['byResource']as$resourceCurrent=>$rules){if($resource===$resourceCurrent){unset($this->rules['byResource'][$resourceCurrent]);}}}$this->resources=array();return$this;}function
  3810. allow($roles=self::ALL,$resources=self::ALL,$privileges=self::ALL,IPermissionAssertion$assertion=NULL){$this->setRule(TRUE,self::ALLOW,$roles,$resources,$privileges,$assertion);return$this;}function
  3811. deny($roles=self::ALL,$resources=self::ALL,$privileges=self::ALL,IPermissionAssertion$assertion=NULL){$this->setRule(TRUE,self::DENY,$roles,$resources,$privileges,$assertion);return$this;}function
  3812. removeAllow($roles=self::ALL,$resources=self::ALL,$privileges=self::ALL){$this->setRule(FALSE,self::ALLOW,$roles,$resources,$privileges);return$this;}function
  3813. removeDeny($roles=self::ALL,$resources=self::ALL,$privileges=self::ALL){$this->setRule(FALSE,self::DENY,$roles,$resources,$privileges);return$this;}protected
  3814. function
  3815. setRule($toAdd,$type,$roles,$resources,$privileges,IPermissionAssertion$assertion=NULL){if($roles===self::ALL){$roles=array(self::ALL);}else{if(!is_array($roles)){$roles=array($roles);}foreach($roles
  3816. as$role){$this->checkRole($role);}}if($resources===self::ALL){$resources=array(self::ALL);}else{if(!is_array($resources)){$resources=array($resources);}foreach($resources
  3817. as$resource){$this->checkResource($resource);}}if($privileges===self::ALL){$privileges=array();}elseif(!is_array($privileges)){$privileges=array($privileges);}if($toAdd){foreach($resources
  3818. as$resource){foreach($roles
  3819. as$role){$rules=&$this->getRules($resource,$role,TRUE);if(count($privileges)===0){$rules['allPrivileges']['type']=$type;$rules['allPrivileges']['assert']=$assertion;if(!isset($rules['byPrivilege'])){$rules['byPrivilege']=array();}}else{foreach($privileges
  3820. as$privilege){$rules['byPrivilege'][$privilege]['type']=$type;$rules['byPrivilege'][$privilege]['assert']=$assertion;}}}}}else{foreach($resources
  3821. as$resource){foreach($roles
  3822. as$role){$rules=&$this->getRules($resource,$role);if($rules===NULL){continue;}if(count($privileges)===0){if($resource===self::ALL&&$role===self::ALL){if($type===$rules['allPrivileges']['type']){$rules=array('allPrivileges'=>array('type'=>self::DENY,'assert'=>NULL),'byPrivilege'=>array());}continue;}if($type===$rules['allPrivileges']['type']){unset($rules['allPrivileges']);}}else{foreach($privileges
  3823. as$privilege){if(isset($rules['byPrivilege'][$privilege])&&$type===$rules['byPrivilege'][$privilege]['type']){unset($rules['byPrivilege'][$privilege]);}}}}}}return$this;}function
  3824. isAllowed($role=self::ALL,$resource=self::ALL,$privilege=self::ALL){$this->queriedRole=$role;if($role!==self::ALL){if($role
  3825. instanceof
  3826. IRole){$role=$role->getRoleId();}$this->checkRole($role);}$this->queriedResource=$resource;if($resource!==self::ALL){if($resource
  3827. instanceof
  3828. IResource){$resource=$resource->getResourceId();}$this->checkResource($resource);}if($privilege===self::ALL){do{if($role!==NULL&&NULL!==($result=$this->roleDFSAllPrivileges($role,$resource))){break;}if(NULL!==($rules=$this->getRules($resource,self::ALL))){foreach($rules['byPrivilege']as$privilege=>$rule){if(self::DENY===($ruleTypeOnePrivilege=$this->getRuleType($resource,NULL,$privilege))){$result=self::DENY;break
  3829. 2;}}if(NULL!==($ruleTypeAllPrivileges=$this->getRuleType($resource,NULL,NULL))){$result=self::ALLOW===$ruleTypeAllPrivileges;break;}}$resource=$this->resources[$resource]['parent'];}while(TRUE);}else{do{if($role!==NULL&&NULL!==($result=$this->roleDFSOnePrivilege($role,$resource,$privilege))){break;}if(NULL!==($ruleType=$this->getRuleType($resource,NULL,$privilege))){$result=self::ALLOW===$ruleType;break;}elseif(NULL!==($ruleTypeAllPrivileges=$this->getRuleType($resource,NULL,NULL))){$result=self::ALLOW===$ruleTypeAllPrivileges;break;}$resource=$this->resources[$resource]['parent'];}while(TRUE);}$this->queriedRole=$this->queriedResource=NULL;return$result;}function
  3830. getQueriedRole(){return$this->queriedRole;}function
  3831. getQueriedResource(){return$this->queriedResource;}private
  3832. function
  3833. roleDFSAllPrivileges($role,$resource){$dfs=array('visited'=>array(),'stack'=>array($role));while(NULL!==($role=array_pop($dfs['stack']))){if(!isset($dfs['visited'][$role])){if(NULL!==($result=$this->roleDFSVisitAllPrivileges($role,$resource,$dfs))){return$result;}}}return
  3834. NULL;}private
  3835. function
  3836. roleDFSVisitAllPrivileges($role,$resource,&$dfs){if(NULL!==($rules=$this->getRules($resource,$role))){foreach($rules['byPrivilege']as$privilege=>$rule){if(self::DENY===$this->getRuleType($resource,$role,$privilege)){return
  3837. self::DENY;}}if(NULL!==($type=$this->getRuleType($resource,$role,NULL))){return
  3838. self::ALLOW===$type;}}$dfs['visited'][$role]=TRUE;foreach($this->roles[$role]['parents']as$roleParent=>$foo){$dfs['stack'][]=$roleParent;}return
  3839. NULL;}private
  3840. function
  3841. roleDFSOnePrivilege($role,$resource,$privilege){$dfs=array('visited'=>array(),'stack'=>array($role));while(NULL!==($role=array_pop($dfs['stack']))){if(!isset($dfs['visited'][$role])){if(NULL!==($result=$this->roleDFSVisitOnePrivilege($role,$resource,$privilege,$dfs))){return$result;}}}return
  3842. NULL;}private
  3843. function
  3844. roleDFSVisitOnePrivilege($role,$resource,$privilege,&$dfs){if(NULL!==($type=$this->getRuleType($resource,$role,$privilege))){return
  3845. self::ALLOW===$type;}if(NULL!==($type=$this->getRuleType($resource,$role,NULL))){return
  3846. self::ALLOW===$type;}$dfs['visited'][$role]=TRUE;foreach($this->roles[$role]['parents']as$roleParent=>$foo)$dfs['stack'][]=$roleParent;return
  3847. NULL;}private
  3848. function
  3849. getRuleType($resource,$role,$privilege){if(NULL===($rules=$this->getRules($resource,$role))){return
  3850. NULL;}if($privilege===self::ALL){if(isset($rules['allPrivileges'])){$rule=$rules['allPrivileges'];}else{return
  3851. NULL;}}elseif(!isset($rules['byPrivilege'][$privilege])){return
  3852. NULL;}else{$rule=$rules['byPrivilege'][$privilege];}if($rule['assert']===NULL||$rule['assert']->assert($this,$role,$resource,$privilege)){return$rule['type'];}elseif($resource!==self::ALL||$role!==self::ALL||$privilege!==self::ALL){return
  3853. NULL;}elseif(self::ALLOW===$rule['type']){return
  3854. self::DENY;}else{return
  3855. self::ALLOW;}}private
  3856. function&getRules($resource,$role,$create=FALSE){if($resource===self::ALL){$visitor=&$this->rules['allResources'];}else{if(!isset($this->rules['byResource'][$resource])){if(!$create){$null=NULL;return$null;}$this->rules['byResource'][$resource]=array();}$visitor=&$this->rules['byResource'][$resource];}if($role===self::ALL){if(!isset($visitor['allRoles'])){if(!$create){$null=NULL;return$null;}$visitor['allRoles']['byPrivilege']=array();}return$visitor['allRoles'];}if(!isset($visitor['byRole'][$role])){if(!$create){$null=NULL;return$null;}$visitor['byRole'][$role]['byPrivilege']=array();}return$visitor['byRole'][$role];}}class
  3857. SimpleAuthenticator
  3858. extends
  3859. Object
  3860. implements
  3861. IAuthenticator{private$userlist;function
  3862. __construct(array$userlist){$this->userlist=$userlist;}function
  3863. authenticate(array$credentials){$username=$credentials[self::USERNAME];foreach($this->userlist
  3864. as$name=>$pass){if(strcasecmp($name,$credentials[self::USERNAME])===0){if(strcasecmp($pass,$credentials[self::PASSWORD])===0){return
  3865. new
  3866. Identity($name);}throw
  3867. new
  3868. AuthenticationException("Invalid password.",self::INVALID_CREDENTIAL);}}throw
  3869. new
  3870. AuthenticationException("User '$username' not found.",self::IDENTITY_NOT_FOUND);}}class
  3871. ServiceLocator
  3872. extends
  3873. Object
  3874. implements
  3875. IServiceLocator{private$parent;private$registry=array();private$factories=array();function
  3876. __construct(IServiceLocator$parent=NULL){$this->parent=$parent;}function
  3877. addService($name,$service,$singleton=TRUE,array$options=NULL){if(!is_string($name)||$name===''){throw
  3878. new
  3879. InvalidArgumentException("Service name must be a non-empty string, ".gettype($name)." given.");}$lower=strtolower($name);if(isset($this->registry[$lower])){throw
  3880. new
  3881. AmbiguousServiceException("Service named '$name' has been already registered.");}if(is_object($service)){if(!$singleton||$options){throw
  3882. new
  3883. InvalidArgumentException("Service named '$name' is an instantiated object and must therefore be singleton without options.");}$this->registry[$lower]=$service;}else{if(!$service){throw
  3884. new
  3885. InvalidArgumentException("Service named '$name' is empty.");}$this->factories[$lower]=array($service,$singleton,$options);}}function
  3886. removeService($name){if(!is_string($name)||$name===''){throw
  3887. new
  3888. InvalidArgumentException("Service name must be a non-empty string, ".gettype($name)." given.");}$lower=strtolower($name);unset($this->registry[$lower],$this->factories[$lower]);}function
  3889. getService($name,array$options=NULL){if(!is_string($name)||$name===''){throw
  3890. new
  3891. InvalidArgumentException("Service name must be a non-empty string, ".gettype($name)." given.");}$lower=strtolower($name);if(isset($this->registry[$lower])){if($options){throw
  3892. new
  3893. InvalidArgumentException("Service named '$name' is singleton and therefore can not have options.");}return$this->registry[$lower];}elseif(isset($this->factories[$lower])){list($factory,$singleton,$defOptions)=$this->factories[$lower];if($singleton&&$options){throw
  3894. new
  3895. InvalidArgumentException("Service named '$name' is singleton and therefore can not have options.");}elseif($defOptions){$options=$options?$options+$defOptions:$defOptions;}if(is_string($factory)&&strpos($factory,':')===FALSE){Framework::fixNamespace($factory);if(!class_exists($factory)){throw
  3896. new
  3897. AmbiguousServiceException("Cannot instantiate service '$name', class '$factory' not found.");}$service=new$factory;if($options&&method_exists($service,'setOptions')){$service->setOptions($options);}}else{$factory=callback($factory);if(!$factory->isCallable()){throw
  3898. new
  3899. InvalidStateException("Cannot instantiate service '$name', handler '$factory' is not callable.");}$service=$factory->invoke($options);if(!is_object($service)){throw
  3900. new
  3901. AmbiguousServiceException("Cannot instantiate service '$name', value returned by '$factory' is not object.");}}if($singleton){$this->registry[$lower]=$service;unset($this->factories[$lower]);}return$service;}if($this->parent!==NULL){return$this->parent->getService($name,$options);}else{throw
  3902. new
  3903. InvalidStateException("Service '$name' not found.");}}function
  3904. hasService($name,$created=FALSE){if(!is_string($name)||$name===''){throw
  3905. new
  3906. InvalidArgumentException("Service name must be a non-empty string, ".gettype($name)." given.");}$lower=strtolower($name);return
  3907. isset($this->registry[$lower])||(!$created&&isset($this->factories[$lower]))||($this->parent!==NULL&&$this->parent->hasService($name,$created));}function
  3908. getParent(){return$this->parent;}}class
  3909. AmbiguousServiceException
  3910. extends
  3911. Exception{}class
  3912. SmartCachingIterator
  3913. extends
  3914. CachingIterator
  3915. implements
  3916. Countable{private$counter=0;function
  3917. __construct($iterator){if(is_array($iterator)||$iterator
  3918. instanceof
  3919. stdClass){parent::__construct(new
  3920. ArrayIterator($iterator),0);}elseif($iterator
  3921. instanceof
  3922. IteratorAggregate){parent::__construct($iterator->getIterator(),0);}elseif($iterator
  3923. instanceof
  3924. Iterator){parent::__construct($iterator,0);}else{throw
  3925. new
  3926. InvalidArgumentException("Invalid argument passed to foreach resp. ".__CLASS__."; array or Iterator expected, ".(is_object($iterator)?get_class($iterator):gettype($iterator))." given.");}}function
  3927. isFirst($width=NULL){return$width===NULL?$this->counter===1:($this->counter
  3928. %$width)===1;}function
  3929. isLast($width=NULL){return!$this->hasNext()||($width!==NULL&&($this->counter
  3930. %$width)===0);}function
  3931. isEmpty(){return$this->counter===0;}function
  3932. isOdd(){return$this->counter
  3933. %
  3934. 2===1;}function
  3935. isEven(){return$this->counter
  3936. %
  3937. 2===0;}function
  3938. getCounter(){return$this->counter;}function
  3939. count(){$inner=$this->getInnerIterator();if($inner
  3940. instanceof
  3941. Countable){return$inner->count();}else{throw
  3942. new
  3943. NotSupportedException('Iterator is not countable.');}}function
  3944. next(){parent::next();if(parent::valid()){$this->counter++;}}function
  3945. rewind(){parent::rewind();$this->counter=parent::valid()?1:0;}function
  3946. getNextKey(){return$this->getInnerIterator()->key();}function
  3947. getNextValue(){return$this->getInnerIterator()->current();}function
  3948. __call($name,$args){return
  3949. ObjectMixin::call($this,$name,$args);}function&__get($name){return
  3950. ObjectMixin::get($this,$name);}function
  3951. __set($name,$value){return
  3952. ObjectMixin::set($this,$name,$value);}function
  3953. __isset($name){return
  3954. ObjectMixin::has($this,$name);}function
  3955. __unset($name){$class=get_class($this);throw
  3956. new
  3957. MemberAccessException("Cannot unset the property $class::\$$name.");}}final
  3958. class
  3959. String{final
  3960. function
  3961. __construct(){throw
  3962. new
  3963. LogicException("Cannot instantiate static class ".get_class($this));}static
  3964. function
  3965. checkEncoding($s,$encoding='UTF-8'){return$s===self::fixEncoding($s,$encoding);}static
  3966. function
  3967. fixEncoding($s,$encoding='UTF-8'){return@iconv('UTF-16',$encoding.'//IGNORE',iconv($encoding,'UTF-16//IGNORE',$s));}static
  3968. function
  3969. chr($code,$encoding='UTF-8'){return
  3970. iconv('UTF-32BE',$encoding.'//IGNORE',pack('N',$code));}static
  3971. function
  3972. startsWith($haystack,$needle){return
  3973. strncmp($haystack,$needle,strlen($needle))===0;}static
  3974. function
  3975. endsWith($haystack,$needle){return
  3976. strlen($needle)===0||substr($haystack,-strlen($needle))===$needle;}static
  3977. function
  3978. normalize($s){$s=str_replace("\r\n","\n",$s);$s=strtr($s,"\r","\n");$s=preg_replace('#[\x00-\x08\x0B-\x1F]+#','',$s);$s=preg_replace("#[\t ]+$#m",'',$s);$s=trim($s,"\n");return$s;}static
  3979. function
  3980. webalize($s,$charlist=NULL,$lower=TRUE){$s=strtr($s,'`\'"^~','-----');if(ICONV_IMPL==='glibc'){$s=@iconv('UTF-8','WINDOWS-1250//TRANSLIT',$s);$s=strtr($s,"\xa5\xa3\xbc\x8c\xa7\x8a\xaa\x8d\x8f\x8e\xaf\xb9\xb3\xbe\x9c\x9a\xba\x9d\x9f\x9e\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2"."\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf8\xf9\xfa\xfb\xfc\xfd\xfe","ALLSSSSTZZZallssstzzzRAAAALCCCEEEEIIDDNNOOOOxRUUUUYTsraaaalccceeeeiiddnnooooruuuuyt");}else{$s=@iconv('UTF-8','ASCII//TRANSLIT',$s);}$s=str_replace(array('`',"'",'"','^','~'),'',$s);if($lower)$s=strtolower($s);$s=preg_replace('#[^a-z0-9'.preg_quote($charlist,'#').']+#i','-',$s);$s=trim($s,'-');return$s;}static
  3981. function
  3982. truncate($s,$maxLen,$append="\xE2\x80\xA6"){if(iconv_strlen($s,'UTF-8')>$maxLen){$maxLen=$maxLen-iconv_strlen($append,'UTF-8');if($maxLen<1){return$append;}elseif(preg_match('#^.{1,'.$maxLen.'}(?=[\s\x00-@\[-`{-~])#us',$s,$matches)){return$matches[0].$append;}else{return
  3983. iconv_substr($s,0,$maxLen,'UTF-8').$append;}}return$s;}static
  3984. function
  3985. indent($s,$level=1,$chars="\t"){return$level<1?$s:preg_replace('#(?:^|[\r\n]+)(?=[^\r\n])#','$0'.str_repeat($chars,$level),$s);}static
  3986. function
  3987. lower($s){return
  3988. mb_strtolower($s,'UTF-8');}static
  3989. function
  3990. upper($s){return
  3991. mb_strtoupper($s,'UTF-8');}static
  3992. function
  3993. capitalize($s){return
  3994. mb_convert_case($s,MB_CASE_TITLE,'UTF-8');}static
  3995. function
  3996. trim($s,$charlist=" \t\n\r\0\x0B\xC2\xA0"){$charlist=preg_quote($charlist,'#');return
  3997. preg_replace('#^['.$charlist.']+|['.$charlist.']+$#u','',$s);}static
  3998. function
  3999. padLeft($s,$length,$pad=' '){$length=max(0,$length-iconv_strlen($s,'UTF-8'));$padLen=iconv_strlen($pad,'UTF-8');return
  4000. str_repeat($pad,$length/$padLen).iconv_substr($pad,0,$length
  4001. %$padLen,'UTF-8').$s;}static
  4002. function
  4003. padRight($s,$length,$pad=' '){$length=max(0,$length-iconv_strlen($s,'UTF-8'));$padLen=iconv_strlen($pad,'UTF-8');return$s.str_repeat($pad,$length/$padLen).iconv_substr($pad,0,$length
  4004. %$padLen,'UTF-8');}}abstract
  4005. class
  4006. BaseTemplate
  4007. extends
  4008. Object
  4009. implements
  4010. ITemplate{public$warnOnUndefined=TRUE;public$onPrepareFilters=array();private$params=array();private$filters=array();private$helpers=array();private$helperLoaders=array();function
  4011. registerFilter($callback){$callback=callback($callback);if(in_array($callback,$this->filters)){throw
  4012. new
  4013. InvalidStateException("Filter '$callback' was registered twice.");}$this->filters[]=$callback;}final
  4014. function
  4015. getFilters(){return$this->filters;}function
  4016. render(){}function
  4017. __toString(){ob_start();try{$this->render();return
  4018. ob_get_clean();}catch(Exception$e){ob_end_clean();if(func_num_args()&&func_get_arg(0)){throw$e;}else{Debug::toStringException($e);}}}protected
  4019. function
  4020. compile($content,$label=NULL){if(!$this->filters){$this->onPrepareFilters($this);}try{foreach($this->filters
  4021. as$filter){$content=self::extractPhp($content,$blocks);$content=$filter->invoke($content);$content=strtr($content,$blocks);}}catch(Exception$e){throw
  4022. new
  4023. InvalidStateException("Filter $filter: ".$e->getMessage().($label?" (in $label)":''),0,$e);}if($label){$content="<?php\n// $label\n//\n?>$content";}return
  4024. self::optimizePhp($content);}function
  4025. registerHelper($name,$callback){$this->helpers[strtolower($name)]=callback($callback);}function
  4026. registerHelperLoader($callback){$this->helperLoaders[]=callback($callback);}final
  4027. function
  4028. getHelpers(){return$this->helpers;}function
  4029. __call($name,$args){$lname=strtolower($name);if(!isset($this->helpers[$lname])){foreach($this->helperLoaders
  4030. as$loader){$helper=$loader->invoke($lname);if($helper){$this->registerHelper($lname,$helper);return$this->helpers[$lname]->invokeArgs($args);}}return
  4031. parent::__call($name,$args);}return$this->helpers[$lname]->invokeArgs($args);}function
  4032. setTranslator(ITranslator$translator=NULL){$this->registerHelper('translate',$translator===NULL?NULL:array($translator,'translate'));return$this;}function
  4033. add($name,$value){if(array_key_exists($name,$this->params)){throw
  4034. new
  4035. InvalidStateException("The variable '$name' exists yet.");}$this->params[$name]=$value;}function
  4036. setParams(array$params){$this->params=$params;return$this;}function
  4037. getParams(){return$this->params;}function
  4038. __set($name,$value){$this->params[$name]=$value;}function&__get($name){if($this->warnOnUndefined&&!array_key_exists($name,$this->params)){trigger_error("The variable '$name' does not exist in template.",E_USER_NOTICE);}return$this->params[$name];}function
  4039. __isset($name){return
  4040. isset($this->params[$name]);}function
  4041. __unset($name){unset($this->params[$name]);}private
  4042. static
  4043. function
  4044. extractPhp($source,&$blocks){$res='';$blocks=array();$tokens=token_get_all($source);foreach($tokens
  4045. as$n=>$token){if(is_array($token)){if($token[0]===T_INLINE_HTML){$res.=$token[1];continue;}elseif($token[0]===T_OPEN_TAG&&$token[1]==='<?'&&isset($tokens[$n+1][1])&&$tokens[$n+1][1]==='xml'){$php=&$res;$token[1]='<<?php ?>?';}elseif($token[0]===T_OPEN_TAG||$token[0]===T_OPEN_TAG_WITH_ECHO){$res.=$id="\x01@php:p".count($blocks)."@\x02";$php=&$blocks[$id];}$php.=$token[1];}else{$php.=$token;}}return$res;}static
  4046. function
  4047. optimizePhp($source){$res=$php='';$lastChar=';';$tokens=new
  4048. ArrayIterator(token_get_all($source));foreach($tokens
  4049. as$key=>$token){if(is_array($token)){if($token[0]===T_INLINE_HTML){$lastChar='';$res.=$token[1];}elseif($token[0]===T_CLOSE_TAG){$next=isset($tokens[$key+1])?$tokens[$key+1]:NULL;if(substr($res,-1)!=='<'&&preg_match('#^<\?php\s*$#',$php)){$php='';}elseif(is_array($next)&&$next[0]===T_OPEN_TAG){if($lastChar!==';'&&$lastChar!=='{'&&$lastChar!=='}'&&$lastChar!==':'&&$lastChar!=='/')$php.=$lastChar=';';if(substr($next[1],-1)==="\n")$php.="\n";$tokens->next();}elseif($next){$res.=preg_replace('#;?(\s)*$#','$1',$php).$token[1];$php='';}else{if($lastChar!=='}'&&$lastChar!==';')$php.=';';}}elseif($token[0]===T_ELSE||$token[0]===T_ELSEIF){if($tokens[$key+1]===':'&&$lastChar==='}')$php.=';';$lastChar='';$php.=$token[1];}else{if(!in_array($token[0],array(T_WHITESPACE,T_COMMENT,T_DOC_COMMENT,T_OPEN_TAG)))$lastChar='';$php.=$token[1];}}else{$php.=$lastChar=$token;}}return$res.$php;}}class
  4050. CachingHelper
  4051. extends
  4052. Object{private$frame;private$key;static
  4053. function
  4054. create($key,$file,$tags){$cache=self::getCache();if(isset($cache[$key])){echo$cache[$key];return
  4055. FALSE;}else{$obj=new
  4056. self;$obj->key=$key;$obj->frame=array(Cache::FILES=>array($file),Cache::TAGS=>$tags,Cache::EXPIRE=>rand(86400*4,86400*7));ob_start();return$obj;}}function
  4057. save(){$this->getCache()->save($this->key,ob_get_flush(),$this->frame);$this->key=$this->frame=NULL;}function
  4058. addFile($file){$this->frame[Cache::FILES][]=$file;}function
  4059. addItem($item){$this->frame[Cache::ITEMS][]=$item;}protected
  4060. static
  4061. function
  4062. getCache(){return
  4063. Environment::getCache('Nette.Template.Curly');}}class
  4064. LatteFilter
  4065. extends
  4066. Object{const
  4067. RE_STRING='\'(?:\\\\.|[^\'\\\\])*\'|"(?:\\\\.|[^"\\\\])*"';const
  4068. RE_IDENTIFIER='[_a-zA-Z\x7F-\xFF][_a-zA-Z0-9\x7F-\xFF]*';const
  4069. HTML_PREFIX='n:';private$handler;private$macroRe;private$input,$output;private$offset;private$quote;private$tags;public$context,$escape;const
  4070. CONTEXT_TEXT='text';const
  4071. CONTEXT_CDATA='cdata';const
  4072. CONTEXT_TAG='tag';const
  4073. CONTEXT_ATTRIBUTE='attribute';const
  4074. CONTEXT_NONE='none';const
  4075. CONTEXT_COMMENT='comment';function
  4076. setHandler($handler){$this->handler=$handler;return$this;}function
  4077. getHandler(){if($this->handler===NULL){$this->handler=new
  4078. LatteMacros;}return$this->handler;}function
  4079. __invoke($s){if(!$this->macroRe){$this->setDelimiters('\\{(?![\\s\'"{}])','\\}');}$this->context=LatteFilter::CONTEXT_NONE;$this->escape='$template->escape';$this->getHandler()->initialize($this,$s);$s=$this->parse("\n".$s);$this->getHandler()->finalize($s);return$s;}private
  4080. function
  4081. parse($s){$this->input=&$s;$this->offset=0;$this->output='';$this->tags=array();$len=strlen($s);while($this->offset<$len){$matches=$this->{"context$this->context"}();if(!$matches){break;}elseif(!empty($matches['macro'])){preg_match('#^(/?[a-z]+)?(.*?)(\\|[a-z](?:'.self::RE_STRING.'|[^\'"\s]+)*)?$()#is',$matches['macro'],$m2);list(,$macro,$value,$modifiers)=$m2;$code=$this->handler->macro($macro,trim($value),isset($modifiers)?$modifiers:'');if($code===NULL){throw
  4082. new
  4083. InvalidStateException("Unknown macro {{$matches['macro']}} on line $this->line.");}$nl=isset($matches['newline'])?"\n":'';if($nl&&$matches['indent']&&strncmp($code,'<?php echo ',11)){$this->output.="\n".$code;}else{$this->output.=$matches['indent'].$code.(substr($code,-2)==='?>'?$nl:'');}}else{$this->output.=$matches[0];}}foreach($this->tags
  4084. as$tag){if(!$tag->isMacro&&!empty($tag->attrs)){throw
  4085. new
  4086. InvalidStateException("Missing end tag </$tag->name> for macro-attribute ".self::HTML_PREFIX.implode(' and '.self::HTML_PREFIX,array_keys($tag->attrs)).".");}}return$this->output.substr($this->input,$this->offset);}private
  4087. function
  4088. contextText(){$matches=$this->match('~
  4089. (?:\n[ \t]*)?<(?P<closing>/?)(?P<tag>[a-z0-9:]+)| ## begin of HTML tag <tag </tag - ignores <!DOCTYPE
  4090. <(?P<comment>!--)| ## begin of HTML comment <!--
  4091. '.$this->macroRe.' ## curly tag
  4092. ~xsi');if(!$matches||!empty($matches['macro'])){}elseif(!empty($matches['comment'])){$this->context=self::CONTEXT_COMMENT;$this->escape='TemplateHelpers::escapeHtmlComment';}elseif(empty($matches['closing'])){$tag=$this->tags[]=(object)NULL;$tag->name=$matches['tag'];$tag->closing=FALSE;$tag->isMacro=String::startsWith($tag->name,self::HTML_PREFIX);$tag->attrs=array();$tag->pos=strlen($this->output);$this->context=self::CONTEXT_TAG;$this->escape='TemplateHelpers::escapeHtml';}else{do{$tag=array_pop($this->tags);if(!$tag){$tag=(object)NULL;$tag->name=$matches['tag'];$tag->isMacro=String::startsWith($tag->name,self::HTML_PREFIX);}}while(strcasecmp($tag->name,$matches['tag']));$this->tags[]=$tag;$tag->closing=TRUE;$tag->pos=strlen($this->output);$this->context=self::CONTEXT_TAG;$this->escape='TemplateHelpers::escapeHtml';}return$matches;}private
  4093. function
  4094. contextCData(){$tag=end($this->tags);$matches=$this->match('~
  4095. </'.$tag->name.'(?![a-z0-9:])| ## end HTML tag </tag
  4096. '.$this->macroRe.' ## curly tag
  4097. ~xsi');if($matches&&empty($matches['macro'])){$tag->closing=TRUE;$tag->pos=strlen($this->output);$this->context=self::CONTEXT_TAG;$this->escape='TemplateHelpers::escapeHtml';}return$matches;}private
  4098. function
  4099. contextTag(){$matches=$this->match('~
  4100. (?P<end>/?>)(?P<tagnewline>[\ \t]*(?=\r|\n))?| ## end of HTML tag
  4101. '.$this->macroRe.'| ## curly tag
  4102. \s*(?P<attr>[^\s/>={]+)(?:\s*=\s*(?P<value>["\']|[^\s/>{]+))? ## begin of HTML attribute
  4103. ~xsi');if(!$matches||!empty($matches['macro'])){}elseif(!empty($matches['end'])){$tag=end($this->tags);$isEmpty=!$tag->closing&&($matches['end'][0]==='/'||isset(Html::$emptyElements[strtolower($tag->name)]));if($tag->isMacro||!empty($tag->attrs)){if($tag->isMacro){$code=$this->handler->tagMacro(substr($tag->name,strlen(self::HTML_PREFIX)),$tag->attrs,$tag->closing);if($code===NULL){throw
  4104. new
  4105. InvalidStateException("Unknown tag-macro <$tag->name> on line $this->line.");}if($isEmpty){$code.=$this->handler->tagMacro(substr($tag->name,strlen(self::HTML_PREFIX)),$tag->attrs,TRUE);}}else{$code=substr($this->output,$tag->pos).$matches[0].(isset($matches['tagnewline'])?"\n":'');$code=$this->handler->attrsMacro($code,$tag->attrs,$tag->closing);if($code===NULL){throw
  4106. new
  4107. InvalidStateException("Unknown macro-attribute ".self::HTML_PREFIX.implode(' or '.self::HTML_PREFIX,array_keys($tag->attrs))." on line $this->line.");}if($isEmpty){$code=$this->handler->attrsMacro($code,$tag->attrs,TRUE);}}$this->output=substr_replace($this->output,$code,$tag->pos);$matches[0]='';}if($isEmpty){$tag->closing=TRUE;}if(!$tag->closing&&(strcasecmp($tag->name,'script')===0||strcasecmp($tag->name,'style')===0)){$this->context=self::CONTEXT_CDATA;$this->escape=strcasecmp($tag->name,'style')?'TemplateHelpers::escapeJs':'TemplateHelpers::escapeCss';}else{$this->context=self::CONTEXT_TEXT;$this->escape='TemplateHelpers::escapeHtml';if($tag->closing)array_pop($this->tags);}}else{$name=$matches['attr'];$value=empty($matches['value'])?TRUE:$matches['value'];if($isSpecial=String::startsWith($name,self::HTML_PREFIX)){$name=substr($name,strlen(self::HTML_PREFIX));}$tag=end($this->tags);if($isSpecial||$tag->isMacro){if($value==='"'||$value==="'"){if($matches=$this->match('~(.*?)'.$value.'~xsi')){$value=$matches[1];}}$tag->attrs[$name]=$value;$matches[0]='';}elseif($value==='"'||$value==="'"){$this->context=self::CONTEXT_ATTRIBUTE;$this->quote=$value;$this->escape=strncasecmp($name,'on',2)?(strcasecmp($name,'style')?'TemplateHelpers::escapeHtml':'TemplateHelpers::escapeHtmlCss'):'TemplateHelpers::escapeHtmlJs';}}return$matches;}private
  4108. function
  4109. contextAttribute(){$matches=$this->match('~
  4110. ('.$this->quote.')| ## 1) end of HTML attribute
  4111. '.$this->macroRe.' ## curly tag
  4112. ~xsi');if($matches&&empty($matches['macro'])){$this->context=self::CONTEXT_TAG;$this->escape='TemplateHelpers::escapeHtml';}return$matches;}private
  4113. function
  4114. contextComment(){$matches=$this->match('~
  4115. (--\s*>)| ## 1) end of HTML comment
  4116. '.$this->macroRe.' ## curly tag
  4117. ~xsi');if($matches&&empty($matches['macro'])){$this->context=self::CONTEXT_TEXT;$this->escape='TemplateHelpers::escapeHtml';}return$matches;}private
  4118. function
  4119. contextNone(){$matches=$this->match('~
  4120. '.$this->macroRe.' ## curly tag
  4121. ~xsi');return$matches;}private
  4122. function
  4123. match($re){if(preg_match($re,$this->input,$matches,PREG_OFFSET_CAPTURE,$this->offset)){$this->output.=substr($this->input,$this->offset,$matches[0][1]-$this->offset);$this->offset=$matches[0][1]+strlen($matches[0][0]);foreach($matches
  4124. as$k=>$v)$matches[$k]=$v[0];}return$matches;}function
  4125. getLine(){return
  4126. substr_count($this->input,"\n",0,$this->offset);}function
  4127. setDelimiters($left,$right){$this->macroRe='
  4128. (?P<indent>\n[\ \t]*)?
  4129. '.$left.'
  4130. (?P<macro>(?:'.self::RE_STRING.'|[^\'"]+?)*?)
  4131. '.$right.'
  4132. (?P<newline>[\ \t]*(?=\r|\n))?
  4133. ';return$this;}static
  4134. function
  4135. formatModifiers($var,$modifiers){if(!$modifiers)return$var;preg_match_all('~
  4136. '.self::RE_STRING.'| ## single or double quoted string
  4137. [^\'"|:,]+| ## symbol
  4138. [|:,] ## separator
  4139. ~xs',$modifiers.'|',$tokens);$inside=FALSE;$prev='';foreach($tokens[0]as$token){if($token==='|'||$token===':'||$token===','){if($prev===''){}elseif(!$inside){if(!preg_match('#^'.self::RE_IDENTIFIER.'$#',$prev)){throw
  4140. new
  4141. InvalidStateException("Modifier name must be alphanumeric string, '$prev' given.");}$var="\$template->$prev($var";$prev='';$inside=TRUE;}else{$var.=', '.self::formatString($prev);$prev='';}if($token==='|'&&$inside){$var.=')';$inside=FALSE;}}else{$prev.=$token;}}return$var;}static
  4142. function
  4143. fetchToken(&$s){if(preg_match('#^((?>'.self::RE_STRING.'|[^\'"\s,]+)+)\s*,?\s*(.*)$#',$s,$matches)){$s=$matches[2];return$matches[1];}return
  4144. NULL;}static
  4145. function
  4146. formatArray($s,$prefix=''){$s=preg_replace_callback('~
  4147. '.self::RE_STRING.'| ## single or double quoted string
  4148. (?<=[,=(]|=>|^)\s*([a-z\d_]+)(?=\s*[,=)]|$) ## 1) symbol
  4149. ~xi',array(__CLASS__,'cbArgs'),trim($s));return$s===''?'':$prefix."array($s)";}private
  4150. static
  4151. function
  4152. cbArgs($matches){if(!empty($matches[1])){list(,$symbol)=$matches;static$keywords=array('true'=>1,'false'=>1,'null'=>1,'and'=>1,'or'=>1,'xor'=>1,'clone'=>1,'new'=>1);return
  4153. is_numeric($symbol)||isset($keywords[strtolower($symbol)])?$matches[0]:"'$symbol'";}else{return$matches[0];}}static
  4154. function
  4155. formatString($s){return(is_numeric($s)||strspn($s,'\'"$'))?$s:'"'.$s.'"';}static
  4156. function
  4157. invoke($s){trigger_error(__METHOD__.'() is deprecated; use non-static __invoke() instead.',E_USER_WARNING);$filter=new
  4158. self;return$filter->__invoke($s);}}class
  4159. CurlyBracketsFilter
  4160. extends
  4161. LatteFilter{}class
  4162. CurlyBracketsMacros
  4163. extends
  4164. LatteMacros{}class
  4165. LatteMacros
  4166. extends
  4167. Object{public
  4168. static$defaultMacros=array('syntax'=>'%:macroSyntax%','/syntax'=>'%:macroSyntax%','block'=>'<?php %:macroBlock% ?>','/block'=>'<?php %:macroBlockEnd% ?>','capture'=>'<?php %:macroCapture% ?>','/capture'=>'<?php %:macroCaptureEnd% ?>','snippet'=>'<?php %:macroSnippet% ?>','/snippet'=>'<?php %:macroSnippetEnd% ?>','cache'=>'<?php if ($_cb->foo = CachingHelper::create($_cb->key = md5(__FILE__) . __LINE__, $template->getFile(), array(%%))) { $_cb->caches[] = $_cb->foo ?>','/cache'=>'<?php array_pop($_cb->caches)->save(); } if (!empty($_cb->caches)) end($_cb->caches)->addItem($_cb->key) ?>','if'=>'<?php if (%%): ?>','elseif'=>'<?php elseif (%%): ?>','else'=>'<?php else: ?>','/if'=>'<?php endif ?>','ifset'=>'<?php if (isset(%%)): ?>','/ifset'=>'<?php endif ?>','elseifset'=>'<?php elseif (isset(%%)): ?>','foreach'=>'<?php foreach (%:macroForeach%): ?>','/foreach'=>'<?php endforeach; array_pop($_cb->its); $iterator = end($_cb->its) ?>','for'=>'<?php for (%%): ?>','/for'=>'<?php endfor ?>','while'=>'<?php while (%%): ?>','/while'=>'<?php endwhile ?>','continueIf'=>'<?php if (%%) continue ?>','breakIf'=>'<?php if (%%) break ?>','include'=>'<?php %:macroInclude% ?>','extends'=>'<?php %:macroExtends% ?>','layout'=>'<?php %:macroExtends% ?>','plink'=>'<?php echo %:macroEscape%(%:macroPlink%) ?>','link'=>'<?php echo %:macroEscape%(%:macroLink%) ?>','ifCurrent'=>'<?php %:macroIfCurrent%; if ($presenter->getLastCreatedRequestFlag("current")): ?>','widget'=>'<?php %:macroWidget% ?>','control'=>'<?php %:macroWidget% ?>','attr'=>'<?php echo Html::el(NULL)->%:macroAttr%attributes() ?>','contentType'=>'<?php %:macroContentType% ?>','status'=>'<?php Environment::getHttpResponse()->setCode(%%) ?>','assign'=>'<?php %:macroAssign% ?>','default'=>'<?php %:macroDefault% ?>','dump'=>'<?php Debug::consoleDump(%:macroDump%, "Template " . str_replace(Environment::getVariable("appDir"), "\xE2\x80\xA6", $template->getFile())) ?>','debugbreak'=>'<?php if (function_exists("debugbreak")) debugbreak(); elseif (function_exists("xdebug_break")) xdebug_break() ?>','!_'=>'<?php echo %:macroTranslate% ?>','!='=>'<?php echo %:macroModifiers% ?>','_'=>'<?php echo %:macroEscape%(%:macroTranslate%) ?>','='=>'<?php echo %:macroEscape%(%:macroModifiers%) ?>','!$'=>'<?php echo %:macroVar% ?>','!'=>'<?php echo %:macroVar% ?>','$'=>'<?php echo %:macroEscape%(%:macroVar%) ?>','?'=>'<?php %:macroModifiers% ?>');public$macros;private$filter;private$current;private$blocks=array();private$namedBlocks=array();private$extends;private$uniq;const
  4169. BLOCK_NAMED=1;const
  4170. BLOCK_CAPTURE=2;const
  4171. BLOCK_ANONYMOUS=3;function
  4172. __construct(){$this->macros=self::$defaultMacros;}function
  4173. initialize($filter,&$s){$this->filter=$filter;$this->blocks=array();$this->namedBlocks=array();$this->extends=NULL;$this->uniq=substr(md5(uniqid('',TRUE)),0,10);$filter->context=LatteFilter::CONTEXT_TEXT;$filter->escape='TemplateHelpers::escapeHtml';$s=preg_replace('#\\{\\*.*?\\*\\}[\r\n]*#s','',$s);$s=preg_replace('#@(\\{[^}]+?\\})#s','<?php } ?>$1<?php if (SnippetHelper::\\$outputAllowed) { ?>',$s);}function
  4174. finalize(&$s){if(count($this->blocks)===1){$s.=$this->macro('/block','','');}elseif($this->blocks){throw
  4175. new
  4176. InvalidStateException("There are some unclosed blocks.");}$s="<?php\nif (SnippetHelper::\$outputAllowed) {\n?>$s<?php\n}\n?>";if($this->namedBlocks||$this->extends){$s="<?php\n".'if ($_cb->extends) { ob_start(); }'."\n".'?>'.$s."<?php\n".'if ($_cb->extends) { ob_end_clean(); LatteMacros::includeTemplate($_cb->extends, get_defined_vars(), $template)->render(); }'."\n";}if($this->namedBlocks){foreach(array_reverse($this->namedBlocks,TRUE)as$name=>$foo){$name=preg_quote($name,'#');$s=preg_replace_callback("#{block ($name)} \?>(.*)<\?php {/block $name}#sU",array($this,'cbNamedBlocks'),$s);}$s="<?php\n\n".implode("\n\n\n",$this->namedBlocks)."\n\n//\n// end of blocks\n//\n?>".$s;}$s="<?php\n"."\$_cb = LatteMacros::initRuntime(\$template, ".var_export($this->extends,TRUE).", ".var_export($this->uniq,TRUE)."); unset(\$_extends);\n".'?>'.$s;}function
  4177. macro($macro,$content,$modifiers){if($macro===''){$macro=substr($content,0,2);if(!isset($this->macros[$macro])){$macro=substr($content,0,1);if(!isset($this->macros[$macro])){return
  4178. NULL;}}$content=substr($content,strlen($macro));}elseif(!isset($this->macros[$macro])){return
  4179. NULL;}$this->current=array($content,$modifiers);return
  4180. preg_replace_callback('#%(.*?)%#',array($this,'cbMacro'),$this->macros[$macro]);}private
  4181. function
  4182. cbMacro($m){list($content,$modifiers)=$this->current;if($m[1]){return
  4183. callback($m[1][0]===':'?array($this,substr($m[1],1)):$m[1])->invoke($content,$modifiers);}else{return$content;}}function
  4184. tagMacro($name,$attrs,$closing){$knownTags=array('include'=>'block','for'=>'each','block'=>'name','if'=>'cond','elseif'=>'cond');return$this->macro($closing?"/$name":$name,isset($knownTags[$name],$attrs[$knownTags[$name]])?$attrs[$knownTags[$name]]:substr(var_export($attrs,TRUE),8,-1),isset($attrs['modifiers'])?$attrs['modifiers']:'');}function
  4185. attrsMacro($code,$attrs,$closing){$left=$right='';foreach($this->macros
  4186. as$name=>$foo){if(!isset($this->macros["/$name"])){continue;}$macro=$closing?"/$name":$name;if(isset($attrs[$name])){if($closing){$right.=$this->macro($macro,'','');}else{$left=$this->macro($macro,$attrs[$name],'').$left;}}$innerName="inner-$name";if(isset($attrs[$innerName])){if($closing){$left.=$this->macro($macro,'','');}else{$right=$this->macro($macro,$attrs[$innerName],'').$right;}}$tagName="tag-$name";if(isset($attrs[$tagName])){$left=$this->macro($name,$attrs[$tagName],'').$left;$right.=$this->macro("/$name",'','');}unset($attrs[$name],$attrs[$innerName],$attrs[$tagName]);}return$attrs?NULL:$left.$code.$right;}function
  4187. macroVar($var,$modifiers){return
  4188. LatteFilter::formatModifiers('$'.$var,$modifiers);}function
  4189. macroTranslate($var,$modifiers){return
  4190. LatteFilter::formatModifiers($var,'translate|'.$modifiers);}function
  4191. macroSyntax($var){switch($var){case'':case'latte':$this->filter->setDelimiters('\\{(?![\\s\'"{}])','\\}');break;case'double':$this->filter->setDelimiters('\\{\\{(?![\\s\'"{}])','\\}\\}');break;case'asp':$this->filter->setDelimiters('<%\s*','\s*%>');break;case'python':$this->filter->setDelimiters('\\{[{%]\s*','\s*[%}]\\}');break;case'off':$this->filter->setDelimiters('[^\x00-\xFF]','');break;default:throw
  4192. new
  4193. InvalidStateException("Unknown macro syntax '$var' on line {$this->filter->line}.");}}function
  4194. macroInclude($content,$modifiers){$destination=LatteFilter::fetchToken($content);$params=LatteFilter::formatArray($content).($content?' + ':'');if($destination===NULL){throw
  4195. new
  4196. InvalidStateException("Missing destination in {include} on line {$this->filter->line}.");}elseif($destination[0]==='#'){$destination=ltrim($destination,'#');if(!preg_match('#^'.LatteFilter::RE_IDENTIFIER.'$#',$destination)){throw
  4197. new
  4198. InvalidStateException("Included block name must be alphanumeric string, '$destination' given on line {$this->filter->line}.");}$parent=$destination==='parent';if($destination==='parent'||$destination==='this'){$item=end($this->blocks);while($item&&$item[0]!==self::BLOCK_NAMED)$item=prev($this->blocks);if(!$item){throw
  4199. new
  4200. InvalidStateException("Cannot include $destination block outside of any block on line {$this->filter->line}.");}$destination=$item[1];}$name=var_export($destination,TRUE);$params.='get_defined_vars()';$cmd=isset($this->namedBlocks[$destination])&&!$parent?"call_user_func(reset(\$_cb->blocks[$name]), $params)":"LatteMacros::callBlock".($parent?'Parent':'')."(\$_cb->blocks, $name, $params)";return$modifiers?"ob_start(); $cmd; echo ".LatteFilter::formatModifiers('ob_get_clean()',$modifiers):$cmd;}else{$destination=LatteFilter::formatString($destination);$params.='$template->getParams()';return$modifiers?'echo '.LatteFilter::formatModifiers('LatteMacros::includeTemplate('.$destination.', '.$params.', $_cb->templates['.var_export($this->uniq,TRUE).'])->__toString(TRUE)',$modifiers):'LatteMacros::includeTemplate('.$destination.', '.$params.', $_cb->templates['.var_export($this->uniq,TRUE).'])->render()';}}function
  4201. macroExtends($content){$destination=LatteFilter::fetchToken($content);if($destination===NULL){throw
  4202. new
  4203. InvalidStateException("Missing destination in {extends} on line {$this->filter->line}.");}if(!empty($this->blocks)){throw
  4204. new
  4205. InvalidStateException("{extends} must be placed outside any block; on line {$this->filter->line}.");}if($this->extends!==NULL){throw
  4206. new
  4207. InvalidStateException("Multiple {extends} declarations are not allowed; on line {$this->filter->line}.");}$this->extends=$destination!=='none';return$this->extends?'$_cb->extends = '.LatteFilter::formatString($destination):'';}function
  4208. macroBlock($content,$modifiers){if(substr($content,0,1)==='$'){trigger_error("Capturing {block $content} is deprecated; use {capture $content} instead on line {$this->filter->line}.",E_USER_WARNING);return$this->macroCapture($content,$modifiers);}$name=LatteFilter::fetchToken($content);if($name===NULL){$this->blocks[]=array(self::BLOCK_ANONYMOUS,NULL,$modifiers);return$modifiers===''?'':'ob_start()';}else{$name=ltrim($name,'#');if(!preg_match('#^'.LatteFilter::RE_IDENTIFIER.'$#',$name)){throw
  4209. new
  4210. InvalidStateException("Block name must be alphanumeric string, '$name' given on line {$this->filter->line}.");}elseif(isset($this->namedBlocks[$name])){throw
  4211. new
  4212. InvalidStateException("Cannot redeclare block '$name'; on line {$this->filter->line}.");}$top=empty($this->blocks);$this->namedBlocks[$name]=$name;$this->blocks[]=array(self::BLOCK_NAMED,$name,'');if(!$top){return$this->macroInclude('#'.$name,$modifiers)."{block $name}";}elseif($this->extends){return"{block $name}";}else{return'if (!$_cb->extends) { '.$this->macroInclude('#'.$name,$modifiers)."; } {block $name}";}}}function
  4213. macroBlockEnd($content){list($type,$name,$modifiers)=array_pop($this->blocks);if($type===self::BLOCK_CAPTURE){$this->blocks[]=array($type,$name,$modifiers);return$this->macroCaptureEnd($content);}if(($type!==self::BLOCK_NAMED&&$type!==self::BLOCK_ANONYMOUS)||($content&&$content!==$name)){throw
  4214. new
  4215. InvalidStateException("Tag {/block $content} was not expected here on line {$this->filter->line}.");}elseif($type===self::BLOCK_NAMED){return"{/block $name}";}else{return$modifiers===''?'':'echo '.LatteFilter::formatModifiers('ob_get_clean()',$modifiers);}}function
  4216. macroSnippet($content){$args=array('');if($snippet=LatteFilter::fetchToken($content)){$args[]=LatteFilter::formatString($snippet);}if($content){$args[]=LatteFilter::formatString($content);}return'} if ($_cb->foo = SnippetHelper::create($control'.implode(', ',$args).')) { $_cb->snippets[] = $_cb->foo';}function
  4217. macroSnippetEnd($content){return'array_pop($_cb->snippets)->finish(); } if (SnippetHelper::$outputAllowed) {';}function
  4218. macroCapture($content,$modifiers){$name=LatteFilter::fetchToken($content);if(substr($name,0,1)!=='$'){throw
  4219. new
  4220. InvalidStateException("Invalid capture block parameter '$name' on line {$this->filter->line}.");}$this->blocks[]=array(self::BLOCK_CAPTURE,$name,$modifiers);return'ob_start()';}function
  4221. macroCaptureEnd($content){list($type,$name,$modifiers)=array_pop($this->blocks);if($type!==self::BLOCK_CAPTURE||($content&&$content!==$name)){throw
  4222. new
  4223. InvalidStateException("Tag {/capture $content} was not expected here on line {$this->filter->line}.");}return$name.'='.LatteFilter::formatModifiers('ob_get_clean()',$modifiers);}private
  4224. function
  4225. cbNamedBlocks($matches){list(,$name,$content)=$matches;$func='_cbb'.substr(md5($this->uniq.$name),0,10).'_'.preg_replace('#[^a-z0-9_]#i','_',$name);$this->namedBlocks[$name]="//\n// block $name\n//\n"."if (!function_exists(\$_cb->blocks[".var_export($name,TRUE)."][] = '$func')) { function $func() { extract(func_get_arg(0))\n?>$content<?php\n}}";return'';}function
  4226. macroForeach($content){return'$iterator = $_cb->its[] = new SmartCachingIterator('.preg_replace('# +as +#i',') as ',$content,1);}function
  4227. macroAttr($content){return
  4228. preg_replace('#\)\s+#',')->',$content.' ');}function
  4229. macroContentType($content){if(strpos($content,'html')!==FALSE){$this->filter->escape='TemplateHelpers::escapeHtml';$this->filter->context=LatteFilter::CONTEXT_TEXT;}elseif(strpos($content,'xml')!==FALSE){$this->filter->escape='TemplateHelpers::escapeXml';$this->filter->context=LatteFilter::CONTEXT_NONE;}elseif(strpos($content,'javascript')!==FALSE){$this->filter->escape='TemplateHelpers::escapeJs';$this->filter->context=LatteFilter::CONTEXT_NONE;}elseif(strpos($content,'css')!==FALSE){$this->filter->escape='TemplateHelpers::escapeCss';$this->filter->context=LatteFilter::CONTEXT_NONE;}elseif(strpos($content,'plain')!==FALSE){$this->filter->escape='';$this->filter->context=LatteFilter::CONTEXT_NONE;}else{$this->filter->escape='$template->escape';$this->filter->context=LatteFilter::CONTEXT_NONE;}return
  4230. strpos($content,'/')?'Environment::getHttpResponse()->setHeader("Content-Type", "'.$content.'")':'';}function
  4231. macroDump($content){return$content?"array(".var_export($content,TRUE)." => $content)":'get_defined_vars()';}function
  4232. macroWidget($content){$pair=LatteFilter::fetchToken($content);if($pair===NULL){throw
  4233. new
  4234. InvalidStateException("Missing widget name in {widget} on line {$this->filter->line}.");}$pair=explode(':',$pair,2);$widget=LatteFilter::formatString($pair[0]);$method=isset($pair[1])?ucfirst($pair[1]):'';$method=preg_match('#^('.LatteFilter::RE_IDENTIFIER.'|)$#',$method)?"render$method":"{\"render$method\"}";$param=LatteFilter::formatArray($content);if(strpos($content,'=>')===FALSE)$param=substr($param,6,-1);return($widget[0]==='$'?"if (is_object($widget)) {$widget}->$method($param); else ":'')."\$control->getWidget($widget)->$method($param)";}function
  4235. macroLink($content,$modifiers){return
  4236. LatteFilter::formatModifiers('$control->link('.$this->formatLink($content).')',$modifiers);}function
  4237. macroPlink($content,$modifiers){return
  4238. LatteFilter::formatModifiers('$presenter->link('.$this->formatLink($content).')',$modifiers);}function
  4239. macroIfCurrent($content){return$content?'try { $presenter->link('.$this->formatLink($content).'); } catch (InvalidLinkException $e) {}':'';}private
  4240. function
  4241. formatLink($content){return
  4242. LatteFilter::formatString(LatteFilter::fetchToken($content)).LatteFilter::formatArray($content,', ');}function
  4243. macroAssign($content,$modifiers){if(!$content){throw
  4244. new
  4245. InvalidStateException("Missing arguments in {assign} on line {$this->filter->line}.");}if(strpos($content,'=>')===FALSE){return'$'.ltrim(LatteFilter::fetchToken($content),'$').' = '.LatteFilter::formatModifiers($content===''?'NULL':$content,$modifiers);}return'extract('.LatteFilter::formatArray($content).')';}function
  4246. macroDefault($content){if(!$content){throw
  4247. new
  4248. InvalidStateException("Missing arguments in {default} on line {$this->filter->line}.");}return'extract('.LatteFilter::formatArray($content).', EXTR_SKIP)';}function
  4249. macroEscape($content){return$this->filter->escape;}function
  4250. macroModifiers($content,$modifiers){return
  4251. LatteFilter::formatModifiers($content,$modifiers);}static
  4252. function
  4253. callBlock(&$blocks,$name,$params){if(empty($blocks[$name])){throw
  4254. new
  4255. InvalidStateException("Call to undefined block '$name'.");}$block=reset($blocks[$name]);$block($params);}static
  4256. function
  4257. callBlockParent(&$blocks,$name,$params){if(empty($blocks[$name])||($block=next($blocks[$name]))===FALSE){throw
  4258. new
  4259. InvalidStateException("Call to undefined parent block '$name'.");}$block($params);}static
  4260. function
  4261. includeTemplate($destination,$params,$template){if($destination
  4262. instanceof
  4263. ITemplate){$tpl=$destination;}elseif($destination==NULL){throw
  4264. new
  4265. InvalidArgumentException("Template file name was not specified.");}else{$tpl=clone$template;if($template
  4266. instanceof
  4267. IFileTemplate){if(substr($destination,0,1)!=='/'&&substr($destination,1,1)!==':'){$destination=dirname($template->getFile()).'/'.$destination;}$tpl->setFile($destination);}}$tpl->setParams($params);return$tpl;}static
  4268. function
  4269. initRuntime($template,$extends,$realFile){$cb=(object)NULL;if(isset($template->_cb)){$cb->blocks=&$template->_cb->blocks;$cb->templates=&$template->_cb->templates;}$cb->templates[$realFile]=$template;$cb->extends=is_bool($extends)?$extends:(empty($template->_extends)?FALSE:$template->_extends);unset($template->_cb,$template->_extends);if(!empty($cb->caches)){end($cb->caches)->addFile($template->getFile());}return$cb;}}class
  4270. SnippetHelper
  4271. extends
  4272. Object{public
  4273. static$outputAllowed=TRUE;private$id;private$tag;private$payload;private$level;static
  4274. function
  4275. create(Control$control,$name=NULL,$tag='div'){if(self::$outputAllowed){$obj=new
  4276. self;$obj->tag=trim($tag,'<>');if($obj->tag)echo'<',$obj->tag,' id="',$control->getSnippetId($name),'">';return$obj;}elseif($control->isControlInvalid($name)){$obj=new
  4277. self;$obj->id=$control->getSnippetId($name);$obj->payload=$control->getPresenter()->getPayload();ob_start();$obj->level=ob_get_level();self::$outputAllowed=TRUE;return$obj;}else{return
  4278. FALSE;}}function
  4279. finish(){if($this->tag!==NULL){if($this->tag)echo"</$this->tag>";}else{if($this->level!==ob_get_level()){throw
  4280. new
  4281. InvalidStateException("Snippet '$this->id' cannot be ended here.");}$this->payload->snippets[$this->id]=ob_get_clean();self::$outputAllowed=FALSE;}}}final
  4282. class
  4283. TemplateFilters{final
  4284. function
  4285. __construct(){throw
  4286. new
  4287. LogicException("Cannot instantiate static class ".get_class($this));}static
  4288. function
  4289. removePhp($s){return
  4290. preg_replace('#\x01@php:p\d+@\x02#','<?php ?>',$s);}static
  4291. function
  4292. relativeLinks($s){return
  4293. preg_replace('#(src|href|action)\s*=\s*(["\'])(?![a-z]+:|[\x01/\\#])#','$1=$2<?php echo \\$baseUri ?>',$s);}static
  4294. function
  4295. netteLinks($s){return
  4296. preg_replace_callback('#(src|href|action)\s*=\s*(["\'])(nette:.*?)([\#"\'])#',array(__CLASS__,'netteLinksCb'),$s);}private
  4297. static
  4298. function
  4299. netteLinksCb($m){list(,$attr,$quote,$uri,$fragment)=$m;$parts=parse_url($uri);if(isset($parts['scheme'])&&$parts['scheme']==='nette'){return$attr.'='.$quote.'<?php echo $template->escape($control->'."link('".(isset($parts['path'])?$parts['path']:'this!').(isset($parts['query'])?'?'.$parts['query']:'').'\'))?>'.$fragment;}else{return$m[0];}}public
  4300. static$texy;static
  4301. function
  4302. texyElements($s){return
  4303. preg_replace_callback('#<texy([^>]*)>(.*?)</texy>#s',array(__CLASS__,'texyCb'),$s);}private
  4304. static
  4305. function
  4306. texyCb($m){list(,$mAttrs,$mContent)=$m;$attrs=array();if($mAttrs){preg_match_all('#([a-z0-9:-]+)\s*(?:=\s*(\'[^\']*\'|"[^"]*"|[^\'"\s]+))?()#isu',$mAttrs,$arr,PREG_SET_ORDER);foreach($arr
  4307. as$m){$key=strtolower($m[1]);$val=$m[2];if($val==NULL)$attrs[$key]=TRUE;elseif($val{0}==='\''||$val{0}==='"')$attrs[$key]=html_entity_decode(substr($val,1,-1),ENT_QUOTES,'UTF-8');else$attrs[$key]=html_entity_decode($val,ENT_QUOTES,'UTF-8');}}return
  4308. self::$texy->process($m[2]);}}final
  4309. class
  4310. TemplateHelpers{final
  4311. function
  4312. __construct(){throw
  4313. new
  4314. LogicException("Cannot instantiate static class ".get_class($this));}static
  4315. function
  4316. loader($helper){$callback=callback('TemplateHelpers',$helper);if($callback->isCallable()){return$callback;}$callback=callback('String',$helper);if($callback->isCallable()){return$callback;}}static
  4317. function
  4318. escapeHtml($s){if(is_object($s)&&($s
  4319. instanceof
  4320. ITemplate||$s
  4321. instanceof
  4322. Html||$s
  4323. instanceof
  4324. Form)){return$s->__toString(TRUE);}return
  4325. htmlSpecialChars($s,ENT_QUOTES);}static
  4326. function
  4327. escapeHtmlComment($s){return
  4328. str_replace('--','--><!--',$s);}static
  4329. function
  4330. escapeXML($s){return
  4331. htmlSpecialChars(preg_replace('#[\x00-\x08\x0B\x0C\x0E-\x1F]+#','',$s),ENT_QUOTES);}static
  4332. function
  4333. escapeCss($s){return
  4334. addcslashes($s,"\x00..\x2C./:;<=>?@[\\]^`{|}~");}static
  4335. function
  4336. escapeHtmlCss($s){return
  4337. htmlSpecialChars(self::escapeCss($s),ENT_QUOTES);}static
  4338. function
  4339. escapeJs($s){if(is_object($s)&&($s
  4340. instanceof
  4341. ITemplate||$s
  4342. instanceof
  4343. Html||$s
  4344. instanceof
  4345. Form)){$s=$s->__toString(TRUE);}return
  4346. str_replace(']]>',']]\x3E',json_encode($s));}static
  4347. function
  4348. escapeHtmlJs($s){return
  4349. htmlSpecialChars(self::escapeJs($s),ENT_QUOTES);}static
  4350. function
  4351. strip($s){$s=preg_replace_callback('#<(textarea|pre|script).*?</\\1#si',array(__CLASS__,'indentCb'),$s);$s=trim(preg_replace('#[ \t\r\n]+#',' ',$s));return
  4352. strtr($s,"\x1F\x1E\x1D\x1A"," \t\r\n");}static
  4353. function
  4354. indent($s,$level=1,$chars="\t"){if($level>=1){$s=preg_replace_callback('#<(textarea|pre).*?</\\1#si',array(__CLASS__,'indentCb'),$s);$s=String::indent($s,$level,$chars);$s=strtr($s,"\x1F\x1E\x1D\x1A"," \t\r\n");}return$s;}private
  4355. static
  4356. function
  4357. indentCb($m){return
  4358. strtr($m[0]," \t\r\n","\x1F\x1E\x1D\x1A");}static
  4359. function
  4360. date($time,$format="%x"){if($time==NULL){return
  4361. NULL;}$time=Tools::createDateTime($time);return
  4362. strpos($format,'%')===FALSE?$time->format($format):strftime($format,$time->format('U'));}static
  4363. function
  4364. bytes($bytes,$precision=2){$bytes=round($bytes);$units=array('B','kB','MB','GB','TB','PB');foreach($units
  4365. as$unit){if(abs($bytes)<1024||$unit===end($units))break;$bytes=$bytes/1024;}return
  4366. round($bytes,$precision).' '.$unit;}static
  4367. function
  4368. length($var){return
  4369. is_string($var)?iconv_strlen($var,'UTF-8'):count($var);}static
  4370. function
  4371. replace($subject,$search,$replacement=''){return
  4372. str_replace($search,$replacement,$subject);}static
  4373. function
  4374. replaceRe($subject,$pattern,$replacement=''){return
  4375. preg_replace($pattern,$replacement,$subject);}static
  4376. function
  4377. null($value){return'';}}class
  4378. Template
  4379. extends
  4380. BaseTemplate
  4381. implements
  4382. IFileTemplate{public
  4383. static$cacheExpire=FALSE;private
  4384. static$cacheStorage;private$file;function
  4385. __construct($file=NULL){if($file!==NULL){$this->setFile($file);}}function
  4386. setFile($file){if(!is_file($file)){throw
  4387. new
  4388. FileNotFoundException("Missing template file '$file'.");}$this->file=$file;return$this;}function
  4389. getFile(){return$this->file;}function
  4390. render(){if($this->file==NULL){throw
  4391. new
  4392. InvalidStateException("Template file name was not specified.");}$this->__set('template',$this);$cache=new
  4393. Cache($this->getCacheStorage(),'Nette.Template');$key=md5($this->file).'.'.basename($this->file);$cached=$content=$cache[$key];if($content===NULL){if(!$this->getFilters()){$this->onPrepareFilters($this);}if(!$this->getFilters()){LimitedScope::load($this->file,$this->getParams());return;}try{$shortName=$this->file;$shortName=str_replace(Environment::getVariable('appDir'),"\xE2\x80\xA6",$shortName);}catch(Exception$foo){}$content=$this->compile(file_get_contents($this->file),"file $shortName");$cache->save($key,$content,array(Cache::FILES=>$this->file,Cache::EXPIRE=>self::$cacheExpire));$cached=$cache[$key];}if($cached!==NULL&&self::$cacheStorage
  4394. instanceof
  4395. TemplateCacheStorage){LimitedScope::load($cached['file'],$this->getParams());fclose($cached['handle']);}else{LimitedScope::evaluate($content,$this->getParams());}}static
  4396. function
  4397. setCacheStorage(ICacheStorage$storage){self::$cacheStorage=$storage;}static
  4398. function
  4399. getCacheStorage(){if(self::$cacheStorage===NULL){self::$cacheStorage=new
  4400. TemplateCacheStorage(Environment::getVariable('tempDir'));}return
  4401. self::$cacheStorage;}}class
  4402. TemplateCacheStorage
  4403. extends
  4404. FileStorage{protected
  4405. function
  4406. readData($meta){return
  4407. array('file'=>$meta[self::FILE],'handle'=>$meta[self::HANDLE]);}protected
  4408. function
  4409. getCacheFile($key){return
  4410. parent::getCacheFile($key).'.php';}}final
  4411. class
  4412. Tools{const
  4413. MINUTE=60;const
  4414. HOUR=3600;const
  4415. DAY=86400;const
  4416. WEEK=604800;const
  4417. MONTH=2629800;const
  4418. YEAR=31557600;final
  4419. function
  4420. __construct(){throw
  4421. new
  4422. LogicException("Cannot instantiate static class ".get_class($this));}static
  4423. function
  4424. createDateTime($time){if($time
  4425. instanceof
  4426. DateTime){return
  4427. clone$time;}elseif(is_numeric($time)){if($time<=self::YEAR){$time+=time();}return
  4428. new
  4429. DateTime53(date('Y-m-d H:i:s',$time));}else{return
  4430. new
  4431. DateTime53($time);}}static
  4432. function
  4433. iniFlag($var){$status=strtolower(ini_get($var));return$status==='on'||$status==='true'||$status==='yes'||$status
  4434. %
  4435. 256;}static
  4436. function
  4437. defaultize(&$var,$default){if($var===NULL)$var=$default;}static
  4438. function
  4439. glob($pattern,$flags=0){$files=glob($pattern,$flags);if(!is_array($files)){$files=array();}$dirs=glob(dirname($pattern).'/*',$flags|GLOB_ONLYDIR);if(is_array($dirs)){$mask=basename($pattern);foreach($dirs
  4440. as$dir){$files=array_merge($files,self::glob($dir.'/'.$mask,$flags));}}return$files;}private
  4441. static$errorMsg;static
  4442. function
  4443. tryError($level=E_ALL){set_error_handler(array(__CLASS__,'_errorHandler'),$level);self::$errorMsg=NULL;}static
  4444. function
  4445. catchError(&$message){restore_error_handler();$message=self::$errorMsg;self::$errorMsg=NULL;return$message!==NULL;}static
  4446. function
  4447. _errorHandler($code,$message){if(ini_get('html_errors')){$message=html_entity_decode(strip_tags($message),ENT_QUOTES,'UTF-8');}if(($a=strpos($message,': '))!==FALSE){$message=substr($message,$a+2);}self::$errorMsg=$message;}}class
  4448. Ftp
  4449. extends
  4450. Object{const
  4451. ASCII=FTP_ASCII;const
  4452. TEXT=FTP_TEXT;const
  4453. BINARY=FTP_BINARY;const
  4454. IMAGE=FTP_IMAGE;const
  4455. TIMEOUT_SEC=FTP_TIMEOUT_SEC;const
  4456. AUTOSEEK=FTP_AUTOSEEK;const
  4457. AUTORESUME=FTP_AUTORESUME;const
  4458. FAILED=FTP_FAILED;const
  4459. FINISHED=FTP_FINISHED;const
  4460. MOREDATA=FTP_MOREDATA;private$resource;private$state;function
  4461. __construct(){if(!extension_loaded('ftp')){throw
  4462. new
  4463. Exception("PHP extension FTP is not loaded.");}}function
  4464. __call($name,$args){$name=strtolower($name);$silent=strncmp($name,'try',3)===0;$func=$silent?substr($name,3):$name;static$aliases=array('sslconnect'=>'ssl_connect','getoption'=>'get_option','setoption'=>'set_option','nbcontinue'=>'nb_continue','nbfget'=>'nb_fget','nbfput'=>'nb_fput','nbget'=>'nb_get','nbput'=>'nb_put');$func='ftp_'.(isset($aliases[$func])?$aliases[$func]:$func);if(!function_exists($func)){return
  4465. parent::__call($name,$args);}Tools::tryError();if($func==='ftp_connect'||$func==='ftp_ssl_connect'){$this->state=array($name=>$args);$this->resource=call_user_func_array($func,$args);$res=NULL;}elseif(!is_resource($this->resource)){Tools::catchError($msg);throw
  4466. new
  4467. FtpException("Not connected to FTP server. Call connect() or ssl_connect() first.");}else{if($func==='ftp_login'||$func==='ftp_pasv'){$this->state[$name]=$args;}array_unshift($args,$this->resource);$res=call_user_func_array($func,$args);if($func==='ftp_chdir'||$func==='ftp_cdup'){$this->state['chdir']=array(ftp_pwd($this->resource));}}if(Tools::catchError($msg)&&!$silent){throw
  4468. new
  4469. FtpException($msg);}return$res;}function
  4470. reconnect(){@ftp_close($this->resource);foreach($this->state
  4471. as$name=>$args){call_user_func_array(array($this,$name),$args);}}function
  4472. fileExists($file){return
  4473. is_array($this->nlist($file));}function
  4474. isDir($dir){$current=$this->pwd();try{$this->chdir($dir);}catch(FtpException$e){}$this->chdir($current);return
  4475. empty($e);}function
  4476. mkDirRecursive($dir){$parts=explode('/',$dir);$path='';while(!empty($parts)){$path.=array_shift($parts);try{if($path!=='')$this->mkdir($path);}catch(FtpException$e){if(!$this->isDir($path)){throw
  4477. new
  4478. FtpException("Cannot create directory '$path'.");}}$path.='/';}}}class
  4479. FtpException
  4480. extends
  4481. Exception{}class
  4482. Html
  4483. extends
  4484. Object
  4485. implements
  4486. ArrayAccess,Countable,IteratorAggregate{private$name;private$isEmpty;public$attrs=array();protected$children=array();public
  4487. static$xhtml=TRUE;public
  4488. static$emptyElements=array('img'=>1,'hr'=>1,'br'=>1,'input'=>1,'meta'=>1,'area'=>1,'command'=>1,'keygen'=>1,'source'=>1,'base'=>1,'col'=>1,'link'=>1,'param'=>1,'basefont'=>1,'frame'=>1,'isindex'=>1,'wbr'=>1,'embed'=>1);static
  4489. function
  4490. el($name=NULL,$attrs=NULL){$el=new
  4491. self;$parts=explode(' ',$name,2);$el->setName($parts[0]);if(is_array($attrs)){$el->attrs=$attrs;}elseif($attrs!==NULL){$el->setText($attrs);}if(isset($parts[1])){preg_match_all('#([a-z0-9:-]+)(?:=(["\'])?(.*?)(?(2)\\2|\s))?#i',$parts[1].' ',$parts,PREG_SET_ORDER);foreach($parts
  4492. as$m){$el->attrs[$m[1]]=isset($m[3])?$m[3]:TRUE;}}return$el;}final
  4493. function
  4494. setName($name,$isEmpty=NULL){if($name!==NULL&&!is_string($name)){throw
  4495. new
  4496. InvalidArgumentException("Name must be string or NULL, ".gettype($name)." given.");}$this->name=$name;$this->isEmpty=$isEmpty===NULL?isset(self::$emptyElements[$name]):(bool)$isEmpty;return$this;}final
  4497. function
  4498. getName(){return$this->name;}final
  4499. function
  4500. isEmpty(){return$this->isEmpty;}final
  4501. function
  4502. __set($name,$value){$this->attrs[$name]=$value;}final
  4503. function&__get($name){return$this->attrs[$name];}final
  4504. function
  4505. __unset($name){unset($this->attrs[$name]);}final
  4506. function
  4507. __call($m,$args){$p=substr($m,0,3);if($p==='get'||$p==='set'||$p==='add'){$m=substr($m,3);$m[0]=$m[0]|"\x20";if($p==='get'){return
  4508. isset($this->attrs[$m])?$this->attrs[$m]:NULL;}elseif($p==='add'){$args[]=TRUE;}}if(count($args)===1){$this->attrs[$m]=$args[0];}elseif($args[0]==NULL){$tmp=&$this->attrs[$m];}elseif(!isset($this->attrs[$m])||is_array($this->attrs[$m])){$this->attrs[$m][$args[0]]=$args[1];}else{$this->attrs[$m]=array($this->attrs[$m],$args[0]=>$args[1]);}return$this;}final
  4509. function
  4510. href($path,$query=NULL){if($query){$query=http_build_query($query,NULL,'&');if($query!=='')$path.='?'.$query;}$this->attrs['href']=$path;return$this;}final
  4511. function
  4512. setHtml($html){if($html===NULL){$html='';}elseif(is_array($html)){throw
  4513. new
  4514. InvalidArgumentException("Textual content must be a scalar, ".gettype($html)." given.");}else{$html=(string)$html;}$this->removeChildren();$this->children[]=$html;return$this;}final
  4515. function
  4516. getHtml(){$s='';foreach($this->children
  4517. as$child){if(is_object($child)){$s.=$child->render();}else{$s.=$child;}}return$s;}final
  4518. function
  4519. setText($text){if(!is_array($text)){$text=str_replace(array('&','<','>'),array('&amp;','&lt;','&gt;'),(string)$text);}return$this->setHtml($text);}final
  4520. function
  4521. getText(){return
  4522. html_entity_decode(strip_tags($this->getHtml()),ENT_QUOTES,'UTF-8');}final
  4523. function
  4524. add($child){return$this->insert(NULL,$child);}final
  4525. function
  4526. create($name,$attrs=NULL){$this->insert(NULL,$child=self::el($name,$attrs));return$child;}function
  4527. insert($index,$child,$replace=FALSE){if($child
  4528. instanceof
  4529. Html||is_scalar($child)){if($index===NULL){$this->children[]=$child;}else{array_splice($this->children,(int)$index,$replace?1:0,array($child));}}else{throw
  4530. new
  4531. InvalidArgumentException("Child node must be scalar or Html object, ".(is_object($child)?get_class($child):gettype($child))." given.");}return$this;}final
  4532. function
  4533. offsetSet($index,$child){$this->insert($index,$child,TRUE);}final
  4534. function
  4535. offsetGet($index){return$this->children[$index];}final
  4536. function
  4537. offsetExists($index){return
  4538. isset($this->children[$index]);}function
  4539. offsetUnset($index){if(isset($this->children[$index])){array_splice($this->children,(int)$index,1);}}final
  4540. function
  4541. count(){return
  4542. count($this->children);}function
  4543. removeChildren(){$this->children=array();}final
  4544. function
  4545. getIterator($deep=FALSE){if($deep){$deep=$deep>0?RecursiveIteratorIterator::SELF_FIRST:RecursiveIteratorIterator::CHILD_FIRST;return
  4546. new
  4547. RecursiveIteratorIterator(new
  4548. RecursiveHtmlIterator($this->children),$deep);}else{return
  4549. new
  4550. RecursiveHtmlIterator($this->children);}}final
  4551. function
  4552. getChildren(){return$this->children;}final
  4553. function
  4554. render($indent=NULL){$s=$this->startTag();if(!$this->isEmpty){if($indent!==NULL){$indent++;}foreach($this->children
  4555. as$child){if(is_object($child)){$s.=$child->render($indent);}else{$s.=$child;}}$s.=$this->endTag();}if($indent!==NULL){return"\n".str_repeat("\t",$indent-1).$s."\n".str_repeat("\t",max(0,$indent-2));}return$s;}final
  4556. function
  4557. __toString(){return$this->render();}final
  4558. function
  4559. startTag(){if($this->name){return'<'.$this->name.$this->attributes().(self::$xhtml&&$this->isEmpty?' />':'>');}else{return'';}}final
  4560. function
  4561. endTag(){return$this->name&&!$this->isEmpty?'</'.$this->name.'>':'';}final
  4562. function
  4563. attributes(){if(!is_array($this->attrs)){return'';}$s='';foreach($this->attrs
  4564. as$key=>$value){if($value===NULL||$value===FALSE)continue;if($value===TRUE){if(self::$xhtml)$s.=' '.$key.'="'.$key.'"';else$s.=' '.$key;continue;}elseif(is_array($value)){$tmp=NULL;foreach($value
  4565. as$k=>$v){if($v==NULL)continue;$tmp[]=is_string($k)?($v===TRUE?$k:$k.':'.$v):$v;}if($tmp===NULL)continue;$value=implode($key==='style'||!strncmp($key,'on',2)?';':' ',$tmp);}else{$value=(string)$value;}$s.=' '.$key.'="'.str_replace(array('&','"','<','>','@'),array('&amp;','&quot;','&lt;','&gt;','&#64;'),$value).'"';}return$s;}function
  4566. __clone(){foreach($this->children
  4567. as$key=>$value){if(is_object($value)){$this->children[$key]=clone$value;}}}}class
  4568. RecursiveHtmlIterator
  4569. extends
  4570. RecursiveArrayIterator
  4571. implements
  4572. Countable{function
  4573. getChildren(){return$this->current()->getIterator();}function
  4574. count(){return
  4575. iterator_count($this);}}class
  4576. HttpContext
  4577. extends
  4578. Object{function
  4579. isModified($lastModified=NULL,$etag=NULL){$response=$this->getResponse();$request=$this->getRequest();if($lastModified){$response->setHeader('Last-Modified',$response->date($lastModified));}if($etag){$response->setHeader('ETag','"'.addslashes($etag).'"');}$ifNoneMatch=$request->getHeader('If-None-Match');if($ifNoneMatch==='*'){$match=TRUE;}elseif($ifNoneMatch!==NULL){$etag=$response->getHeader('ETag');if($etag==NULL||strpos(' '.strtr($ifNoneMatch,",\t",' '),' '.$etag)===FALSE){return
  4580. TRUE;}else{$match=TRUE;}}$ifModifiedSince=$request->getHeader('If-Modified-Since');if($ifModifiedSince!==NULL){$lastModified=$response->getHeader('Last-Modified');if($lastModified!=NULL&&strtotime($lastModified)<=strtotime($ifModifiedSince)){$match=TRUE;}else{return
  4581. TRUE;}}if(empty($match)){return
  4582. TRUE;}$response->setCode(IHttpResponse::S304_NOT_MODIFIED);return
  4583. FALSE;}function
  4584. getRequest(){return
  4585. Environment::getHttpRequest();}function
  4586. getResponse(){return
  4587. Environment::getHttpResponse();}}class
  4588. HttpRequest
  4589. extends
  4590. Object
  4591. implements
  4592. IHttpRequest{protected$query;protected$post;protected$files;protected$cookies;protected$uri;protected$originalUri;protected$headers;protected$uriFilter=array(PHP_URL_PATH=>array('#/{2,}#'=>'/'),0=>array());protected$encoding;final
  4593. function
  4594. getUri(){if($this->uri===NULL){$this->detectUri();}return$this->uri;}function
  4595. setUri(UriScript$uri){$this->uri=clone$uri;$this->query=NULL;$this->uri->canonicalize();$this->uri->freeze();return$this;}final
  4596. function
  4597. getOriginalUri(){if($this->originalUri===NULL){$this->detectUri();}return$this->originalUri;}function
  4598. addUriFilter($pattern,$replacement='',$component=NULL){$pattern='#'.$pattern.'#';$component=$component===PHP_URL_PATH?PHP_URL_PATH:0;if($replacement===NULL){unset($this->uriFilter[$component][$pattern]);}else{$this->uriFilter[$component][$pattern]=$replacement;}$this->uri=NULL;}final
  4599. function
  4600. getUriFilters(){return$this->uriFilter;}protected
  4601. function
  4602. detectUri(){$uri=$this->uri=new
  4603. UriScript;$uri->scheme=$this->isSecured()?'https':'http';$uri->user=isset($_SERVER['PHP_AUTH_USER'])?$_SERVER['PHP_AUTH_USER']:'';$uri->password=isset($_SERVER['PHP_AUTH_PW'])?$_SERVER['PHP_AUTH_PW']:'';if(isset($_SERVER['HTTP_HOST'])){$pair=explode(':',$_SERVER['HTTP_HOST']);}elseif(isset($_SERVER['SERVER_NAME'])){$pair=explode(':',$_SERVER['SERVER_NAME']);}else{$pair=array('');}$uri->host=$pair[0];if(isset($pair[1])){$uri->port=(int)$pair[1];}elseif(isset($_SERVER['SERVER_PORT'])){$uri->port=(int)$_SERVER['SERVER_PORT'];}if(isset($_SERVER['REQUEST_URI'])){$requestUri=$_SERVER['REQUEST_URI'];}elseif(isset($_SERVER['ORIG_PATH_INFO'])){$requestUri=$_SERVER['ORIG_PATH_INFO'];if(isset($_SERVER['QUERY_STRING'])&&$_SERVER['QUERY_STRING']!=''){$requestUri.='?'.$_SERVER['QUERY_STRING'];}}else{$requestUri='';}$tmp=explode('?',$requestUri,2);$this->originalUri=new
  4604. Uri($uri);$this->originalUri->path=$tmp[0];$this->originalUri->query=isset($tmp[1])?$tmp[1]:'';$this->originalUri->freeze();$requestUri=preg_replace(array_keys($this->uriFilter[0]),array_values($this->uriFilter[0]),$requestUri);$tmp=explode('?',$requestUri,2);$uri->path=preg_replace(array_keys($this->uriFilter[PHP_URL_PATH]),array_values($this->uriFilter[PHP_URL_PATH]),$tmp[0]);$uri->path=String::fixEncoding($uri->path);$uri->query=isset($tmp[1])?$tmp[1]:'';$uri->canonicalize();$filename=isset($_SERVER['SCRIPT_FILENAME'])?basename($_SERVER['SCRIPT_FILENAME']):NULL;$scriptPath='';if(isset($_SERVER['SCRIPT_NAME'])&&basename($_SERVER['SCRIPT_NAME'])===$filename){$scriptPath=rtrim($_SERVER['SCRIPT_NAME'],'/');}elseif(isset($_SERVER['PHP_SELF'])&&basename($_SERVER['PHP_SELF'])===$filename){$scriptPath=$_SERVER['PHP_SELF'];}elseif(isset($_SERVER['ORIG_SCRIPT_NAME'])&&basename($_SERVER['ORIG_SCRIPT_NAME'])===$filename){$scriptPath=$_SERVER['ORIG_SCRIPT_NAME'];}elseif(isset($_SERVER['PHP_SELF'],$_SERVER['SCRIPT_FILENAME'])){$path=$_SERVER['PHP_SELF'];$segs=explode('/',trim($_SERVER['SCRIPT_FILENAME'],'/'));$segs=array_reverse($segs);$index=0;$last=count($segs);do{$seg=$segs[$index];$scriptPath='/'.$seg.$scriptPath;$index++;}while(($last>$index)&&(FALSE!==($pos=strpos($path,$scriptPath)))&&(0!=$pos));}if(strncmp($uri->path,$scriptPath,strlen($scriptPath))===0){$uri->scriptPath=$scriptPath;}elseif(strncmp($uri->path,$scriptPath,strrpos($scriptPath,'/')+1)===0){$uri->scriptPath=substr($scriptPath,0,strrpos($scriptPath,'/')+1);}elseif(strpos($uri->path,basename($scriptPath))===FALSE){$uri->scriptPath='/';}elseif((strlen($uri->path)>=strlen($scriptPath))&&((FALSE!==($pos=strpos($uri->path,$scriptPath)))&&($pos!==0))){$uri->scriptPath=substr($uri->path,0,$pos+strlen($scriptPath));}else{$uri->scriptPath=$scriptPath;}$uri->freeze();}final
  4605. function
  4606. getQuery($key=NULL,$default=NULL){if($this->query===NULL){$this->initialize();}if(func_num_args()===0){return$this->query;}elseif(isset($this->query[$key])){return$this->query[$key];}else{return$default;}}final
  4607. function
  4608. getPost($key=NULL,$default=NULL){if($this->post===NULL){$this->initialize();}if(func_num_args()===0){return$this->post;}elseif(isset($this->post[$key])){return$this->post[$key];}else{return$default;}}function
  4609. getPostRaw(){return
  4610. file_get_contents('php://input');}final
  4611. function
  4612. getFile($key){if($this->files===NULL){$this->initialize();}$args=func_get_args();return
  4613. ArrayTools::get($this->files,$args);}final
  4614. function
  4615. getFiles(){if($this->files===NULL){$this->initialize();}return$this->files;}final
  4616. function
  4617. getCookie($key,$default=NULL){if($this->cookies===NULL){$this->initialize();}if(func_num_args()===0){return$this->cookies;}elseif(isset($this->cookies[$key])){return$this->cookies[$key];}else{return$default;}}final
  4618. function
  4619. getCookies(){if($this->cookies===NULL){$this->initialize();}return$this->cookies;}function
  4620. setEncoding($encoding){if(strcasecmp($encoding,$this->encoding)){$this->encoding=$encoding;$this->query=$this->post=$this->cookies=$this->files=NULL;}return$this;}function
  4621. initialize(){$filter=(!in_array(ini_get("filter.default"),array("","unsafe_raw"))||ini_get("filter.default_flags"));parse_str($this->getUri()->query,$this->query);if(!$this->query){$this->query=$filter?filter_input_array(INPUT_GET,FILTER_UNSAFE_RAW):(empty($_GET)?array():$_GET);}$this->post=$filter?filter_input_array(INPUT_POST,FILTER_UNSAFE_RAW):(empty($_POST)?array():$_POST);$this->cookies=$filter?filter_input_array(INPUT_COOKIE,FILTER_UNSAFE_RAW):(empty($_COOKIE)?array():$_COOKIE);$gpc=(bool)get_magic_quotes_gpc();$enc=(bool)$this->encoding;$old=error_reporting(error_reporting()^E_NOTICE);$nonChars='#[^\x09\x0A\x0D\x20-\x7E\xA0-\x{10FFFF}]#u';if($gpc||$enc){$utf=strcasecmp($this->encoding,'UTF-8')===0;$list=array(&$this->query,&$this->post,&$this->cookies);while(list($key,$val)=each($list)){foreach($val
  4622. as$k=>$v){unset($list[$key][$k]);if($gpc){$k=stripslashes($k);}if($enc&&is_string($k)&&(preg_match($nonChars,$k)||preg_last_error())){}elseif(is_array($v)){$list[$key][$k]=$v;$list[]=&$list[$key][$k];}else{if($gpc&&!$filter){$v=stripSlashes($v);}if($enc){if($utf){$v=String::fixEncoding($v);}else{if(!String::checkEncoding($v)){$v=iconv($this->encoding,'UTF-8//IGNORE',$v);}$v=html_entity_decode($v,ENT_QUOTES,'UTF-8');}$v=preg_replace($nonChars,'',$v);}$list[$key][$k]=$v;}}}unset($list,$key,$val,$k,$v);}$this->files=array();$list=array();if(!empty($_FILES)){foreach($_FILES
  4623. as$k=>$v){if($enc&&is_string($k)&&(preg_match($nonChars,$k)||preg_last_error()))continue;$v['@']=&$this->files[$k];$list[]=$v;}}while(list(,$v)=each($list)){if(!isset($v['name'])){continue;}elseif(!is_array($v['name'])){if($gpc){$v['name']=stripSlashes($v['name']);}if($enc){$v['name']=preg_replace($nonChars,'',String::fixEncoding($v['name']));}$v['@']=new
  4624. HttpUploadedFile($v);continue;}foreach($v['name']as$k=>$foo){if($enc&&is_string($k)&&(preg_match($nonChars,$k)||preg_last_error()))continue;$list[]=array('name'=>$v['name'][$k],'type'=>$v['type'][$k],'size'=>$v['size'][$k],'tmp_name'=>$v['tmp_name'][$k],'error'=>$v['error'][$k],'@'=>&$v['@'][$k]);}}error_reporting($old);}function
  4625. getMethod(){return
  4626. isset($_SERVER['REQUEST_METHOD'])?$_SERVER['REQUEST_METHOD']:NULL;}function
  4627. isMethod($method){return
  4628. isset($_SERVER['REQUEST_METHOD'])?strcasecmp($_SERVER['REQUEST_METHOD'],$method)===0:FALSE;}function
  4629. isPost(){return$this->isMethod('POST');}final
  4630. function
  4631. getHeader($header,$default=NULL){$header=strtolower($header);$headers=$this->getHeaders();if(isset($headers[$header])){return$headers[$header];}else{return$default;}}function
  4632. getHeaders(){if($this->headers===NULL){if(function_exists('apache_request_headers')){$this->headers=array_change_key_case(apache_request_headers(),CASE_LOWER);}else{$this->headers=array();foreach($_SERVER
  4633. as$k=>$v){if(strncmp($k,'HTTP_',5)==0){$this->headers[strtr(strtolower(substr($k,5)),'_','-')]=$v;}}}}return$this->headers;}final
  4634. function
  4635. getReferer(){$uri=self::getHeader('referer');return$uri?new
  4636. Uri($uri):NULL;}function
  4637. isSecured(){return
  4638. isset($_SERVER['HTTPS'])&&strcasecmp($_SERVER['HTTPS'],'off');}function
  4639. isAjax(){return$this->getHeader('X-Requested-With')==='XMLHttpRequest';}function
  4640. getRemoteAddress(){return
  4641. isset($_SERVER['REMOTE_ADDR'])?$_SERVER['REMOTE_ADDR']:NULL;}function
  4642. getRemoteHost(){if(!isset($_SERVER['REMOTE_HOST'])){if(!isset($_SERVER['REMOTE_ADDR'])){return
  4643. NULL;}$_SERVER['REMOTE_HOST']=getHostByAddr($_SERVER['REMOTE_ADDR']);}return$_SERVER['REMOTE_HOST'];}function
  4644. detectLanguage(array$langs){$header=$this->getHeader('accept-language');if(!$header)return
  4645. NULL;$s=strtolower($header);$s=strtr($s,'_','-');rsort($langs);preg_match_all('#('.implode('|',$langs).')(?:-[^\s,;=]+)?\s*(?:;\s*q=([0-9.]+))?#',$s,$matches);if(!$matches[0]){return
  4646. NULL;}$max=0;$lang=NULL;foreach($matches[1]as$key=>$value){$q=$matches[2][$key]===''?1.0:(float)$matches[2][$key];if($q>$max){$max=$q;$lang=$value;}}return$lang;}}final
  4647. class
  4648. HttpResponse
  4649. extends
  4650. Object
  4651. implements
  4652. IHttpResponse{private
  4653. static$fixIE=TRUE;public$cookieDomain='';public$cookiePath='/';public$cookieSecure=FALSE;private$code=self::S200_OK;function
  4654. setCode($code){$code=(int)$code;static$allowed=array(200=>1,201=>1,202=>1,203=>1,204=>1,205=>1,206=>1,300=>1,301=>1,302=>1,303=>1,304=>1,307=>1,400=>1,401=>1,403=>1,404=>1,406=>1,408=>1,410=>1,412=>1,415=>1,416=>1,500=>1,501=>1,503=>1,505=>1);if(!isset($allowed[$code])){throw
  4655. new
  4656. InvalidArgumentException("Bad HTTP response '$code'.");}elseif(headers_sent($file,$line)){throw
  4657. new
  4658. InvalidStateException("Cannot set HTTP code after HTTP headers have been sent".($file?" (output started at $file:$line).":"."));}else{$this->code=$code;$protocol=isset($_SERVER['SERVER_PROTOCOL'])?$_SERVER['SERVER_PROTOCOL']:'HTTP/1.1';header($protocol.' '.$code,TRUE,$code);}return$this;}function
  4659. getCode(){return$this->code;}function
  4660. setHeader($name,$value){if(headers_sent($file,$line)){throw
  4661. new
  4662. InvalidStateException("Cannot send header after HTTP headers have been sent".($file?" (output started at $file:$line).":"."));}if($value===NULL&&function_exists('header_remove')){header_remove($name);}else{header($name.': '.$value,TRUE,$this->code);}return$this;}function
  4663. addHeader($name,$value){if(headers_sent($file,$line)){throw
  4664. new
  4665. InvalidStateException("Cannot send header after HTTP headers have been sent".($file?" (output started at $file:$line).":"."));}header($name.': '.$value,FALSE,$this->code);}function
  4666. setContentType($type,$charset=NULL){$this->setHeader('Content-Type',$type.($charset?'; charset='.$charset:''));return$this;}function
  4667. redirect($url,$code=self::S302_FOUND){if(isset($_SERVER['SERVER_SOFTWARE'])&&preg_match('#^Microsoft-IIS/[1-5]#',$_SERVER['SERVER_SOFTWARE'])&&$this->getHeader('Set-Cookie')!==NULL){$this->setHeader('Refresh',"0;url=$url");return;}$this->setCode($code);$this->setHeader('Location',$url);echo"<h1>Redirect</h1>\n\n<p><a href=\"".htmlSpecialChars($url)."\">Please click here to continue</a>.</p>";}function
  4668. setExpiration($time){if(!$time){$this->setHeader('Cache-Control','s-maxage=0, max-age=0, must-revalidate');$this->setHeader('Expires','Mon, 23 Jan 1978 10:00:00 GMT');return$this;}$time=Tools::createDateTime($time);$this->setHeader('Cache-Control','max-age='.($time->format('U')-time()));$this->setHeader('Expires',self::date($time));return$this;}function
  4669. expire($seconds){trigger_error(__METHOD__.'() is deprecated; use setExpiration() instead.',E_USER_WARNING);$this->setExpiration($seconds);}function
  4670. isSent(){return
  4671. headers_sent();}function
  4672. getHeader($header,$default=NULL){$header.=':';$len=strlen($header);foreach(headers_list()as$item){if(strncasecmp($item,$header,$len)===0){return
  4673. ltrim(substr($item,$len));}}return$default;}function
  4674. getHeaders(){$headers=array();foreach(headers_list()as$header){$a=strpos($header,':');$headers[substr($header,0,$a)]=(string)substr($header,$a+2);}return$headers;}static
  4675. function
  4676. date($time=NULL){$time=Tools::createDateTime($time);$time->setTimezone(new
  4677. DateTimeZone('GMT'));return$time->format('D, d M Y H:i:s \G\M\T');}function
  4678. enableCompression(){if(headers_sent()){return
  4679. FALSE;}if($this->getHeader('Content-Encoding')!==NULL){return
  4680. FALSE;}$ok=ob_gzhandler('',PHP_OUTPUT_HANDLER_START);if($ok===FALSE){return
  4681. FALSE;}if(function_exists('ini_set')){ini_set('zlib.output_compression','Off');ini_set('zlib.output_compression_level','6');}ob_start('ob_gzhandler',1);return
  4682. TRUE;}function
  4683. __destruct(){if(self::$fixIE){if(!isset($_SERVER['HTTP_USER_AGENT'])||strpos($_SERVER['HTTP_USER_AGENT'],'MSIE ')===FALSE)return;if(!in_array($this->code,array(400,403,404,405,406,408,409,410,500,501,505),TRUE))return;if($this->getHeader('Content-Type','text/html')!=='text/html')return;$s=" \t\r\n";for($i=2e3;$i;$i--)echo$s{rand(0,3)};self::$fixIE=FALSE;}}function
  4684. setCookie($name,$value,$time,$path=NULL,$domain=NULL,$secure=NULL){if(headers_sent($file,$line)){throw
  4685. new
  4686. InvalidStateException("Cannot set cookie after HTTP headers have been sent".($file?" (output started at $file:$line).":"."));}setcookie($name,$value,$time?Tools::createDateTime($time)->format('U'):0,$path===NULL?$this->cookiePath:(string)$path,$domain===NULL?$this->cookieDomain:(string)$domain,$secure===NULL?$this->cookieSecure:(bool)$secure,TRUE);return$this;}function
  4687. deleteCookie($name,$path=NULL,$domain=NULL,$secure=NULL){if(headers_sent($file,$line)){throw
  4688. new
  4689. InvalidStateException("Cannot delete cookie after HTTP headers have been sent".($file?" (output started at $file:$line).":"."));}setcookie($name,FALSE,254400000,$path===NULL?$this->cookiePath:(string)$path,$domain===NULL?$this->cookieDomain:(string)$domain,$secure===NULL?$this->cookieSecure:(bool)$secure,TRUE);}}class
  4690. HttpUploadedFile
  4691. extends
  4692. Object{private$name;private$type;private$size;private$tmpName;private$error;function
  4693. __construct($value){foreach(array('name','type','size','tmp_name','error')as$key){if(!isset($value[$key])||!is_scalar($value[$key])){$this->error=UPLOAD_ERR_NO_FILE;return;}}$this->name=$value['name'];$this->size=$value['size'];$this->tmpName=$value['tmp_name'];$this->error=$value['error'];}function
  4694. getName(){return$this->name;}function
  4695. getContentType(){if($this->isOk()&&$this->type===NULL){$info=getimagesize($this->tmpName);if(isset($info['mime'])){$this->type=$info['mime'];}elseif(extension_loaded('fileinfo')){$this->type=finfo_file(finfo_open(FILEINFO_MIME),$this->tmpName);}elseif(function_exists('mime_content_type')){$this->type=mime_content_type($this->tmpName);}if(!$this->type){$this->type='application/octet-stream';}}return$this->type;}function
  4696. getSize(){return$this->size;}function
  4697. getTemporaryFile(){return$this->tmpName;}function
  4698. __toString(){return$this->tmpName;}function
  4699. getError(){return$this->error;}function
  4700. isOk(){return$this->error===UPLOAD_ERR_OK;}function
  4701. move($dest){$dir=dirname($dest);if(@mkdir($dir,0755,TRUE)){chmod($dir,0755);}$func=is_uploaded_file($this->tmpName)?'move_uploaded_file':'rename';if(!$func($this->tmpName,$dest)){throw
  4702. new
  4703. InvalidStateException("Unable to move uploaded file '$this->tmpName' to '$dest'.");}chmod($dest,0644);$this->tmpName=$dest;return$this;}function
  4704. isImage(){return
  4705. in_array($this->getContentType(),array('image/gif','image/png','image/jpeg'),TRUE);}function
  4706. getImage(){return
  4707. Image::fromFile($this->tmpName);}function
  4708. getImageSize(){return$this->isOk()?getimagesize($this->tmpName):NULL;}}class
  4709. Session
  4710. extends
  4711. Object{const
  4712. DEFAULT_FILE_LIFETIME=10800;public$verificationKeyGenerator;private$regenerationNeeded;private
  4713. static$started;private$options=array('referer_check'=>'','use_cookies'=>1,'use_only_cookies'=>1,'use_trans_sid'=>0,'cookie_lifetime'=>0,'cookie_path'=>'/','cookie_domain'=>'','cookie_secure'=>FALSE,'cookie_httponly'=>TRUE,'gc_maxlifetime'=>self::DEFAULT_FILE_LIFETIME,'cache_limiter'=>NULL,'cache_expire'=>NULL,'hash_function'=>NULL,'hash_bits_per_character'=>NULL);function
  4714. __construct(){$this->verificationKeyGenerator=array($this,'generateVerificationKey');}function
  4715. start(){if(self::$started){throw
  4716. new
  4717. InvalidStateException('Session has already been started.');}elseif(self::$started===NULL&&defined('SID')){throw
  4718. new
  4719. InvalidStateException('A session had already been started by session.auto-start or session_start().');}$verKey=NULL;if($this->verificationKeyGenerator){$verKey=(string)callback($this->verificationKeyGenerator)->invoke();}try{$this->configure($this->options);}catch(NotSupportedException$e){}Tools::tryError();session_start();if(Tools::catchError($msg)){@session_write_close();throw
  4720. new
  4721. InvalidStateException($msg);}self::$started=TRUE;if($this->regenerationNeeded){session_regenerate_id(TRUE);$this->regenerationNeeded=FALSE;}if(!isset($_SESSION['__NF']['V'])){$_SESSION['__NF']=array();$_SESSION['__NF']['C']=0;$_SESSION['__NF']['V']=$verKey;}else{$saved=&$_SESSION['__NF']['V'];if(!$this->verificationKeyGenerator||$verKey===$saved){$_SESSION['__NF']['C']++;}else{session_regenerate_id(TRUE);$_SESSION=array();$_SESSION['__NF']['C']=0;$_SESSION['__NF']['V']=$verKey;}}$nf=&$_SESSION['__NF'];unset($_SESSION['__NT'],$_SESSION['__NS'],$_SESSION['__NM']);$browserKey=$this->getHttpRequest()->getCookie('nette-browser');if(!$browserKey){$browserKey=(string)lcg_value();}$browserClosed=!isset($nf['B'])||$nf['B']!==$browserKey;$nf['B']=$browserKey;$this->sendCookie();if(isset($nf['META'])){$now=time();foreach($nf['META']as$namespace=>$metadata){if(is_array($metadata)){foreach($metadata
  4722. as$variable=>$value){if((!empty($value['B'])&&$browserClosed)||(!empty($value['T'])&&$now>$value['T'])||($variable!==''&&is_object($nf['DATA'][$namespace][$variable])&&(isset($value['V'])?$value['V']:NULL)!==ClassReflection::from($nf['DATA'][$namespace][$variable])->getAnnotation('serializationVersion'))){if($variable===''){unset($nf['META'][$namespace],$nf['DATA'][$namespace]);continue
  4723. 2;}unset($nf['META'][$namespace][$variable],$nf['DATA'][$namespace][$variable]);}}}}}register_shutdown_function(array($this,'clean'));}function
  4724. isStarted(){return(bool)self::$started;}function
  4725. close(){if(self::$started){$this->clean();session_write_close();self::$started=FALSE;}}function
  4726. destroy(){if(!self::$started){throw
  4727. new
  4728. InvalidStateException('Session is not started.');}session_destroy();$_SESSION=NULL;self::$started=FALSE;if(!$this->getHttpResponse()->isSent()){$params=session_get_cookie_params();$this->getHttpResponse()->deleteCookie(session_name(),$params['path'],$params['domain'],$params['secure']);}}function
  4729. exists(){return
  4730. self::$started||$this->getHttpRequest()->getCookie(session_name())!==NULL;}function
  4731. regenerateId(){if(self::$started){if(headers_sent($file,$line)){throw
  4732. new
  4733. InvalidStateException("Cannot regenerate session ID after HTTP headers have been sent".($file?" (output started at $file:$line).":"."));}session_regenerate_id(TRUE);}else{$this->regenerationNeeded=TRUE;}}function
  4734. getId(){return
  4735. session_id();}function
  4736. setName($name){if(!is_string($name)||!preg_match('#[^0-9.][^.]*$#A',$name)){throw
  4737. new
  4738. InvalidArgumentException('Session name must be a string and cannot contain dot.');}session_name($name);return$this->setOptions(array('name'=>$name));}function
  4739. getName(){return
  4740. session_name();}function
  4741. generateVerificationKey(){$httpRequest=$this->getHttpRequest();$key[]=$httpRequest->getHeader('Accept-Charset');$key[]=$httpRequest->getHeader('Accept-Encoding');$key[]=$httpRequest->getHeader('Accept-Language');$key[]=$httpRequest->getHeader('User-Agent');if(strpos($key[3],'MSIE 8.0')){$key[2]=substr($key[2],0,2);}return
  4742. md5(implode("\0",$key));}function
  4743. getNamespace($namespace,$class='SessionNamespace'){if(!is_string($namespace)||$namespace===''){throw
  4744. new
  4745. InvalidArgumentException('Session namespace must be a non-empty string.');}if(!self::$started){$this->start();}return
  4746. new$class($_SESSION['__NF']['DATA'][$namespace],$_SESSION['__NF']['META'][$namespace]);}function
  4747. hasNamespace($namespace){if($this->exists()&&!self::$started){$this->start();}return!empty($_SESSION['__NF']['DATA'][$namespace]);}function
  4748. getIterator(){if($this->exists()&&!self::$started){$this->start();}if(isset($_SESSION['__NF']['DATA'])){return
  4749. new
  4750. ArrayIterator(array_keys($_SESSION['__NF']['DATA']));}else{return
  4751. new
  4752. ArrayIterator;}}function
  4753. clean(){if(!self::$started||empty($_SESSION)){return;}$nf=&$_SESSION['__NF'];if(isset($nf['META'])&&is_array($nf['META'])){foreach($nf['META']as$name=>$foo){if(empty($nf['META'][$name])){unset($nf['META'][$name]);}}}if(empty($nf['META'])){unset($nf['META']);}if(empty($nf['DATA'])){unset($nf['DATA']);}if(empty($_SESSION)){}}function
  4754. setOptions(array$options){if(self::$started){$this->configure($options);}$this->options=$options+$this->options;return$this;}function
  4755. getOptions(){return$this->options;}private
  4756. function
  4757. configure(array$config){$special=array('cache_expire'=>1,'cache_limiter'=>1,'save_path'=>1,'name'=>1);foreach($config
  4758. as$key=>$value){if(!strncmp($key,'session.',8)){$key=substr($key,8);}if($value===NULL){continue;}elseif(isset($special[$key])){if(self::$started){throw
  4759. new
  4760. InvalidStateException("Unable to set '$key' when session has been started.");}$key="session_$key";$key($value);}elseif(strncmp($key,'cookie_',7)===0){if(!isset($cookie)){$cookie=session_get_cookie_params();}$cookie[substr($key,7)]=$value;}elseif(!function_exists('ini_set')){if(ini_get($key)!=$value){throw
  4761. new
  4762. NotSupportedException('Required function ini_set() is disabled.');}}else{if(self::$started){throw
  4763. new
  4764. InvalidStateException("Unable to set '$key' when session has been started.");}ini_set("session.$key",$value);}}if(isset($cookie)){session_set_cookie_params($cookie['lifetime'],$cookie['path'],$cookie['domain'],$cookie['secure'],$cookie['httponly']);if(self::$started){$this->sendCookie();}}}function
  4765. setExpiration($time){if(empty($time)){return$this->setOptions(array('gc_maxlifetime'=>self::DEFAULT_FILE_LIFETIME,'cookie_lifetime'=>0));}else{$time=Tools::createDateTime($time)->format('U');return$this->setOptions(array('gc_maxlifetime'=>$time,'cookie_lifetime'=>$time));}}function
  4766. setCookieParams($path,$domain=NULL,$secure=NULL){return$this->setOptions(array('cookie_path'=>$path,'cookie_domain'=>$domain,'cookie_secure'=>$secure));}function
  4767. getCookieParams(){return
  4768. session_get_cookie_params();}function
  4769. setSavePath($path){return$this->setOptions(array('save_path'=>$path));}private
  4770. function
  4771. sendCookie(){$cookie=$this->getCookieParams();$this->getHttpResponse()->setCookie(session_name(),session_id(),$cookie['lifetime'],$cookie['path'],$cookie['domain'],$cookie['secure'],$cookie['httponly']);$this->getHttpResponse()->setCookie('nette-browser',$_SESSION['__NF']['B'],HttpResponse::BROWSER,$cookie['path'],$cookie['domain'],$cookie['secure'],$cookie['httponly']);}protected
  4772. function
  4773. getHttpRequest(){return
  4774. Environment::getHttpRequest();}protected
  4775. function
  4776. getHttpResponse(){return
  4777. Environment::getHttpResponse();}}final
  4778. class
  4779. SessionNamespace
  4780. extends
  4781. Object
  4782. implements
  4783. IteratorAggregate,ArrayAccess{private$data;private$meta;public$warnOnUndefined=FALSE;function
  4784. __construct(&$data,&$meta){$this->data=&$data;$this->meta=&$meta;}function
  4785. getIterator(){if(isset($this->data)){return
  4786. new
  4787. ArrayIterator($this->data);}else{return
  4788. new
  4789. ArrayIterator;}}function
  4790. __set($name,$value){$this->data[$name]=$value;if(is_object($value)){$this->meta[$name]['V']=ClassReflection::from($value)->getAnnotation('serializationVersion');}}function&__get($name){if($this->warnOnUndefined&&!array_key_exists($name,$this->data)){trigger_error("The variable '$name' does not exist in session namespace",E_USER_NOTICE);}return$this->data[$name];}function
  4791. __isset($name){return
  4792. isset($this->data[$name]);}function
  4793. __unset($name){unset($this->data[$name],$this->meta[$name]);}function
  4794. offsetSet($name,$value){$this->__set($name,$value);}function
  4795. offsetGet($name){return$this->__get($name);}function
  4796. offsetExists($name){return$this->__isset($name);}function
  4797. offsetUnset($name){$this->__unset($name);}function
  4798. setExpiration($time,$variables=NULL){if(empty($time)){$time=NULL;$whenBrowserIsClosed=TRUE;}else{$time=Tools::createDateTime($time)->format('U');$whenBrowserIsClosed=FALSE;}if($variables===NULL){$this->meta['']['T']=$time;$this->meta['']['B']=$whenBrowserIsClosed;}elseif(is_array($variables)){foreach($variables
  4799. as$variable){$this->meta[$variable]['T']=$time;$this->meta[$variable]['B']=$whenBrowserIsClosed;}}else{$this->meta[$variables]['T']=$time;$this->meta[$variables]['B']=$whenBrowserIsClosed;}return$this;}function
  4800. removeExpiration($variables=NULL){if($variables===NULL){unset($this->meta['']['T'],$this->meta['']['B']);}elseif(is_array($variables)){foreach($variables
  4801. as$variable){unset($this->meta[$variable]['T'],$this->meta[$variable]['B']);}}else{unset($this->meta[$variables]['T'],$this->meta[$variable]['B']);}}function
  4802. remove(){$this->data=NULL;$this->meta=NULL;}}class
  4803. Uri
  4804. extends
  4805. FreezableObject{public
  4806. static$defaultPorts=array('http'=>80,'https'=>443,'ftp'=>21,'news'=>119,'nntp'=>119);private$scheme='';private$user='';private$pass='';private$host='';private$port=NULL;private$path='';private$query='';private$fragment='';function
  4807. __construct($uri=NULL){if(is_string($uri)){$parts=@parse_url($uri);if($parts===FALSE){throw
  4808. new
  4809. InvalidArgumentException("Malformed or unsupported URI '$uri'.");}foreach($parts
  4810. as$key=>$val){$this->$key=$val;}if(!$this->port&&isset(self::$defaultPorts[$this->scheme])){$this->port=self::$defaultPorts[$this->scheme];}}elseif($uri
  4811. instanceof
  4812. self){foreach($this
  4813. as$key=>$val){$this->$key=$uri->$key;}}}function
  4814. setScheme($value){$this->updating();$this->scheme=(string)$value;return$this;}function
  4815. getScheme(){return$this->scheme;}function
  4816. setUser($value){$this->updating();$this->user=(string)$value;return$this;}function
  4817. getUser(){return$this->user;}function
  4818. setPassword($value){$this->updating();$this->pass=(string)$value;return$this;}function
  4819. getPassword(){return$this->pass;}function
  4820. setPass($value){trigger_error(__METHOD__.'() is deprecated; use setPassword() instead.',E_USER_WARNING);$this->setPassword($value);}function
  4821. getPass(){trigger_error(__METHOD__.'() is deprecated; use getPassword() instead.',E_USER_WARNING);return$this->pass;}function
  4822. setHost($value){$this->updating();$this->host=(string)$value;return$this;}function
  4823. getHost(){return$this->host;}function
  4824. setPort($value){$this->updating();$this->port=(int)$value;return$this;}function
  4825. getPort(){return$this->port;}function
  4826. setPath($value){$this->updating();$this->path=(string)$value;return$this;}function
  4827. getPath(){return$this->path;}function
  4828. setQuery($value){$this->updating();$this->query=(string)(is_array($value)?http_build_query($value,'','&'):$value);return$this;}function
  4829. appendQuery($value){$this->updating();$value=(string)(is_array($value)?http_build_query($value,'','&'):$value);$this->query.=($this->query===''||$value==='')?$value:'&'.$value;}function
  4830. getQuery(){return$this->query;}function
  4831. setFragment($value){$this->updating();$this->fragment=(string)$value;return$this;}function
  4832. getFragment(){return$this->fragment;}function
  4833. getAbsoluteUri(){return$this->scheme.'://'.$this->getAuthority().$this->path.($this->query===''?'':'?'.$this->query).($this->fragment===''?'':'#'.$this->fragment);}function
  4834. getAuthority(){$authority=$this->host;if($this->port&&isset(self::$defaultPorts[$this->scheme])&&$this->port!==self::$defaultPorts[$this->scheme]){$authority.=':'.$this->port;}if($this->user!==''&&$this->scheme!=='http'&&$this->scheme!=='https'){$authority=$this->user.($this->pass===''?'':':'.$this->pass).'@'.$authority;}return$authority;}function
  4835. getHostUri(){return$this->scheme.'://'.$this->getAuthority();}function
  4836. isEqual($uri){$part=self::unescape(strtok($uri,'?#'),'%/');if(strncmp($part,'//',2)===0){if($part!=='//'.$this->getAuthority().$this->path)return
  4837. FALSE;}elseif(strncmp($part,'/',1)===0){if($part!==$this->path)return
  4838. FALSE;}else{if($part!==$this->scheme.'://'.$this->getAuthority().$this->path)return
  4839. FALSE;}$part=self::unescape(strtr((string)strtok('?#'),'+',' '),'%&;=+');return$part===$this->query;}function
  4840. canonicalize(){$this->updating();$this->path=$this->path===''?'/':self::unescape($this->path,'%/');$this->host=strtolower(rawurldecode($this->host));$this->query=self::unescape(strtr($this->query,'+',' '),'%&;=+');}function
  4841. __toString(){return$this->getAbsoluteUri();}static
  4842. function
  4843. unescape($s,$reserved='%;/?:@&=+$,'){preg_match_all('#(?<=%)[a-f0-9][a-f0-9]#i',$s,$matches,PREG_OFFSET_CAPTURE|PREG_SET_ORDER);foreach(array_reverse($matches)as$match){$ch=chr(hexdec($match[0][0]));if(strpos($reserved,$ch)===FALSE){$s=substr_replace($s,$ch,$match[0][1]-1,3);}}return$s;}}class
  4844. UriScript
  4845. extends
  4846. Uri{private$scriptPath='';function
  4847. setScriptPath($value){$this->updating();$this->scriptPath=(string)$value;return$this;}function
  4848. getScriptPath(){return$this->scriptPath;}function
  4849. getBasePath(){return(string)substr($this->scriptPath,0,strrpos($this->scriptPath,'/')+1);}function
  4850. getBaseUri(){return$this->scheme.'://'.$this->getAuthority().$this->getBasePath();}function
  4851. getRelativeUri(){return(string)substr($this->path,strrpos($this->scriptPath,'/')+1);}function
  4852. getPathInfo(){return(string)substr($this->path,strlen($this->scriptPath));}}class
  4853. User
  4854. extends
  4855. Object
  4856. implements
  4857. IUser{const
  4858. MANUAL=1;const
  4859. INACTIVITY=2;const
  4860. BROWSER_CLOSED=3;public$guestRole='guest';public$authenticatedRole='authenticated';public$onAuthenticated;public$onSignedOut;private$authenticationHandler;private$authorizationHandler;private$namespace='';private$session;function
  4861. authenticate($username,$password,$extra=NULL){$handler=$this->getAuthenticationHandler();if($handler===NULL){throw
  4862. new
  4863. InvalidStateException('Authentication handler has not been set.');}$this->signOut(TRUE);$credentials=array(IAuthenticator::USERNAME=>$username,IAuthenticator::PASSWORD=>$password,'extra'=>$extra);$this->setIdentity($handler->authenticate($credentials));$this->setAuthenticated(TRUE);$this->onAuthenticated($this);}final
  4864. function
  4865. signOut($clearIdentity=FALSE){if($this->isAuthenticated()){$this->setAuthenticated(FALSE);$this->onSignedOut($this);}if($clearIdentity){$this->setIdentity(NULL);}}final
  4866. function
  4867. isAuthenticated(){$session=$this->getSessionNamespace(FALSE);return$session&&$session->authenticated;}final
  4868. function
  4869. getIdentity(){$session=$this->getSessionNamespace(FALSE);return$session?$session->identity:NULL;}function
  4870. setAuthenticationHandler(IAuthenticator$handler){$this->authenticationHandler=$handler;return$this;}final
  4871. function
  4872. getAuthenticationHandler(){if($this->authenticationHandler===NULL){$this->authenticationHandler=Environment::getService('Nette\Security\IAuthenticator');}return$this->authenticationHandler;}function
  4873. setNamespace($namespace){if($this->namespace!==$namespace){$this->namespace=(string)$namespace;$this->session=NULL;}return$this;}final
  4874. function
  4875. getNamespace(){return$this->namespace;}function
  4876. setExpiration($time,$whenBrowserIsClosed=TRUE,$clearIdentity=FALSE){$session=$this->getSessionNamespace(TRUE);if($time){$time=Tools::createDateTime($time)->format('U');$session->expireTime=$time;$session->expireDelta=$time-time();}else{unset($session->expireTime,$session->expireDelta);}$session->expireIdentity=(bool)$clearIdentity;$session->expireBrowser=(bool)$whenBrowserIsClosed;$session->browserCheck=TRUE;$session->setExpiration(0,'browserCheck');return$this;}final
  4877. function
  4878. getSignOutReason(){$session=$this->getSessionNamespace(FALSE);return$session?$session->reason:NULL;}protected
  4879. function
  4880. getSessionNamespace($need){if($this->session!==NULL){return$this->session;}$sessionHandler=$this->getSession();if(!$need&&!$sessionHandler->exists()){return
  4881. NULL;}$this->session=$session=$sessionHandler->getNamespace('Nette.Web.User/'.$this->namespace);if(!($session->identity
  4882. instanceof
  4883. IIdentity)||!is_bool($session->authenticated)){$session->remove();}if($session->authenticated&&$session->expireBrowser&&!$session->browserCheck){$session->reason=self::BROWSER_CLOSED;$session->authenticated=FALSE;$this->onSignedOut($this);if($session->expireIdentity){unset($session->identity);}}if($session->authenticated&&$session->expireDelta>0){if($session->expireTime<time()){$session->reason=self::INACTIVITY;$session->authenticated=FALSE;$this->onSignedOut($this);if($session->expireIdentity){unset($session->identity);}}$session->expireTime=time()+$session->expireDelta;}if(!$session->authenticated){unset($session->expireTime,$session->expireDelta,$session->expireIdentity,$session->expireBrowser,$session->browserCheck,$session->authTime);}return$this->session;}protected
  4884. function
  4885. setAuthenticated($state){$session=$this->getSessionNamespace(TRUE);$session->authenticated=(bool)$state;$this->getSession()->regenerateId();if($state){$session->reason=NULL;$session->authTime=time();}else{$session->reason=self::MANUAL;$session->authTime=NULL;}return$this;}protected
  4886. function
  4887. setIdentity(IIdentity$identity=NULL){$this->getSessionNamespace(TRUE)->identity=$identity;return$this;}function
  4888. getRoles(){if(!$this->isAuthenticated()){return
  4889. array($this->guestRole);}$identity=$this->getIdentity();return$identity?$identity->getRoles():array($this->authenticatedRole);}final
  4890. function
  4891. isInRole($role){return
  4892. in_array($role,$this->getRoles(),TRUE);}function
  4893. isAllowed($resource=NULL,$privilege=NULL){$handler=$this->getAuthorizationHandler();if(!$handler){throw
  4894. new
  4895. InvalidStateException("Authorization handler has not been set.");}foreach($this->getRoles()as$role){if($handler->isAllowed($role,$resource,$privilege))return
  4896. TRUE;}return
  4897. FALSE;}function
  4898. setAuthorizationHandler(IAuthorizator$handler){$this->authorizationHandler=$handler;return$this;}final
  4899. function
  4900. getAuthorizationHandler(){if($this->authorizationHandler===NULL){$this->authorizationHandler=Environment::getService('Nette\Security\IAuthorizator');}return$this->authorizationHandler;}protected
  4901. function
  4902. getSession(){return
  4903. Environment::getSession();}}