PageRenderTime 134ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 2ms

/libs/NetteX/loader.php

https://github.com/OndrejBrejla/apigen
PHP | 4529 lines | 4423 code | 99 blank | 7 comment | 50 complexity | 28c45b1894815c6ce4c225733b4c6bdc MD5 | raw file
  1. <?php //netteloader=NetteX\IComponent
  2. namespace {/**
  3. * NetteX Framework (version 2.0-dev 45c4669 released on 2010-11-09)
  4. *
  5. * Copyright (c) 2004, 2010 David Grudl (http://davidgrudl.com)
  6. *
  7. * This source file is subject to the "NetteX license", and/or
  8. * GPL license. For more information please see http://nette.org
  9. */
  10. error_reporting(E_ALL|E_STRICT);@set_magic_quotes_runtime(FALSE);iconv_set_encoding('internal_encoding','UTF-8');extension_loaded('mbstring')&&mb_internal_encoding('UTF-8');@header('X-Powered-By: NetteX Framework');define('NETTEX',TRUE);define('NETTEX_DIR',__DIR__);define('NETTEX_VERSION_ID',20000);define('NETTEX_PACKAGE','5.3');function
  11. callbackX($callback,$m=NULL){return($m===NULL&&$callback
  12. instanceof
  13. NetteX\Callback)?$callback:new
  14. NetteX\Callback($callback,$m);}function
  15. dumpX($var){foreach(func_get_args()as$arg)NetteX\Debug::dump($arg);return$var;}}namespace NetteX{use
  16. NetteX;interface
  17. IComponent{const
  18. NAME_SEPARATOR='-';function
  19. getName();function
  20. getParent();function
  21. setParent(IComponentContainer$parent=NULL,$name=NULL);}interface
  22. IComponentContainer
  23. extends
  24. IComponent{function
  25. addComponent(IComponent$component,$name);function
  26. removeComponent(IComponent$component);function
  27. getComponent($name);function
  28. getComponents($deep=FALSE,$filterType=NULL);}}namespace NetteX\Application{use
  29. NetteX;interface
  30. ISignalReceiver{function
  31. signalReceived($signal);}interface
  32. IStatePersistent{function
  33. loadState(array$params);function
  34. saveState(array&$params);}interface
  35. IRenderable{function
  36. invalidateControl();function
  37. isControlInvalid();}interface
  38. IPartiallyRenderable
  39. extends
  40. IRenderable{}interface
  41. IPresenter{function
  42. run(PresenterRequest$request);}interface
  43. IPresenterLoader{function
  44. getPresenterClass(&$name);}interface
  45. IPresenterResponse{function
  46. send();}interface
  47. IRouter{const
  48. ONE_WAY=1;const
  49. SECURED=2;function
  50. match(NetteX\Web\IHttpRequest$httpRequest);function
  51. constructUrl(PresenterRequest$appRequest,NetteX\Web\Uri$refUri);}}namespace NetteX{use
  52. NetteX;interface
  53. IFreezable{function
  54. freeze();function
  55. isFrozen();}interface
  56. IDebugPanel{function
  57. getTab();function
  58. getPanel();function
  59. getId();}}namespace NetteX\Caching{use
  60. NetteX;interface
  61. ICacheStorage{function
  62. read($key);function
  63. write($key,$data,array$dependencies);function
  64. remove($key);function
  65. clean(array$conds);}interface
  66. ICacheJournal{function
  67. write($key,array$dependencies);function
  68. clean(array$conditions);}}namespace NetteX\Config{use
  69. NetteX;interface
  70. IConfigAdapter{static
  71. function
  72. load($file,$section=NULL);static
  73. function
  74. save($config,$file,$section=NULL);}}namespace NetteX\Forms{use
  75. NetteX;interface
  76. IFormControl{function
  77. loadHttpData();function
  78. setValue($value);function
  79. getValue();function
  80. getRules();function
  81. getErrors();function
  82. isDisabled();function
  83. translate($s,$count=NULL);}interface
  84. ISubmitterControl
  85. extends
  86. IFormControl{function
  87. isSubmittedBy();function
  88. getValidationScope();}interface
  89. IFormRenderer{function
  90. render(Form$form);}}namespace NetteX\Mail{use
  91. NetteX;interface
  92. IMailer{function
  93. send(Mail$mail);}}namespace NetteX\Reflection{use
  94. NetteX;interface
  95. IAnnotation{function
  96. __construct(array$values);}}namespace NetteX\Security{use
  97. NetteX;interface
  98. IAuthenticator{const
  99. USERNAME=0;const
  100. PASSWORD=1;const
  101. IDENTITY_NOT_FOUND=1;const
  102. INVALID_CREDENTIAL=2;const
  103. FAILURE=3;const
  104. NOT_APPROVED=4;function
  105. authenticate(array$credentials);}interface
  106. IAuthorizator{const
  107. ALL=NULL;const
  108. ALLOW=TRUE;const
  109. DENY=FALSE;function
  110. isAllowed($role,$resource,$privilege);}interface
  111. IIdentity{function
  112. getId();function
  113. getRoles();}interface
  114. IResource{function
  115. getResourceId();}interface
  116. IRole{function
  117. getRoleId();}}namespace NetteX\Templates{use
  118. NetteX;interface
  119. ITemplate{function
  120. render();}interface
  121. IFileTemplate
  122. extends
  123. ITemplate{function
  124. setFile($file);function
  125. getFile();}}namespace NetteX{use
  126. NetteX;interface
  127. IContext{function
  128. addService($name,$service,$singleton=TRUE,array$options=NULL);function
  129. getService($name,array$options=NULL);function
  130. removeService($name);function
  131. hasService($name);}interface
  132. ITranslator{function
  133. translate($message,$count=NULL);}}namespace NetteX\Web{use
  134. NetteX;interface
  135. IHttpRequest{const
  136. GET='GET',POST='POST',HEAD='HEAD',PUT='PUT',DELETE='DELETE';function
  137. getUri();function
  138. getQuery($key=NULL,$default=NULL);function
  139. getPost($key=NULL,$default=NULL);function
  140. getPostRaw();function
  141. getFile($key);function
  142. getFiles();function
  143. getCookie($key,$default=NULL);function
  144. getCookies();function
  145. getMethod();function
  146. isMethod($method);function
  147. getHeader($header,$default=NULL);function
  148. getHeaders();function
  149. isSecured();function
  150. isAjax();function
  151. getRemoteAddress();function
  152. getRemoteHost();}interface
  153. IHttpResponse{const
  154. PERMANENT=2116333333;const
  155. BROWSER=0;const
  156. 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
  157. setCode($code);function
  158. getCode();function
  159. setHeader($name,$value);function
  160. addHeader($name,$value);function
  161. setContentType($type,$charset=NULL);function
  162. redirect($url,$code=self::S302_FOUND);function
  163. setExpiration($seconds);function
  164. isSent();function
  165. getHeaders();function
  166. setCookie($name,$value,$expire,$path=NULL,$domain=NULL,$secure=NULL,$httpOnly=NULL);function
  167. deleteCookie($name,$path=NULL,$domain=NULL,$secure=NULL);}interface
  168. IUser{function
  169. login();function
  170. logout($clearIdentity=FALSE);function
  171. isLoggedIn();function
  172. getIdentity();function
  173. setAuthenticationHandler(NetteX\Security\IAuthenticator$handler);function
  174. getAuthenticationHandler();function
  175. setNamespace($namespace);function
  176. getNamespace();function
  177. getRoles();function
  178. isInRole($role);function
  179. isAllowed();function
  180. setAuthorizationHandler(NetteX\Security\IAuthorizator$handler);function
  181. getAuthorizationHandler();}}namespace {class
  182. XArgumentOutOfRangeException
  183. extends
  184. InvalidArgumentException{}class
  185. XInvalidStateException
  186. extends
  187. RuntimeException{}class
  188. XNotImplementedException
  189. extends
  190. LogicException{}class
  191. XNotSupportedException
  192. extends
  193. LogicException{}class
  194. XDeprecatedException
  195. extends
  196. XNotSupportedException{}class
  197. XMemberAccessException
  198. extends
  199. LogicException{}class
  200. XIOException
  201. extends
  202. RuntimeException{}class
  203. XFileNotFoundException
  204. extends
  205. XIOException{}class
  206. XDirectoryNotFoundException
  207. extends
  208. XIOException{}class
  209. XFatalErrorException
  210. extends
  211. ErrorException{function
  212. __construct($message,$code,$severity,$file,$line,$context){parent::__construct($message,$code,$severity,$file,$line);$this->context=$context;}}}namespace NetteX{use
  213. NetteX;final
  214. class
  215. Framework{const
  216. NAME='NetteX Framework';const
  217. VERSION='2.0-dev';const
  218. REVISION='45c4669 released on 2010-11-09';public
  219. static$iAmUsingBadHost=FALSE;final
  220. function
  221. __construct(){throw
  222. new\LogicException("Cannot instantiate static class ".get_class($this));}}abstract
  223. class
  224. Object{static
  225. function
  226. getReflection(){return
  227. new
  228. NetteX\Reflection\ClassReflection(get_called_class());}function
  229. __call($name,$args){return
  230. ObjectMixin::call($this,$name,$args);}static
  231. function
  232. __callStatic($name,$args){$class=get_called_class();throw
  233. new\XMemberAccessException("Call to undefined static method $class::$name().");}static
  234. function
  235. extensionMethod($name,$callback=NULL){if(strpos($name,'::')===FALSE){$class=get_called_class();}else{list($class,$name)=explode('::',$name);}$class=new
  236. NetteX\Reflection\ClassReflection($class);if($callback===NULL){return$class->getExtensionMethod($name);}else{$class->setExtensionMethod($name,$callback);}}function&__get($name){return
  237. ObjectMixin::get($this,$name);}function
  238. __set($name,$value){return
  239. ObjectMixin::set($this,$name,$value);}function
  240. __isset($name){return
  241. ObjectMixin::has($this,$name);}function
  242. __unset($name){throw
  243. new\XMemberAccessException("Cannot unset the property {$this->reflection->name}::\$$name.");}}final
  244. class
  245. ObjectMixin{private
  246. static$methods;final
  247. function
  248. __construct(){throw
  249. new\LogicException("Cannot instantiate static class ".get_class($this));}static
  250. function
  251. call($_this,$name,$args){$class=new
  252. NetteX\Reflection\ClassReflection($_this);if($name===''){throw
  253. new\XMemberAccessException("Call to class '$class->name' method without name.");}if($class->hasEventProperty($name)){if(is_array($list=$_this->$name)||$list
  254. instanceof\Traversable){foreach($list
  255. as$handler){callbackX($handler)->invokeArgs($args);}}return
  256. NULL;}if($cb=$class->getExtensionMethod($name)){array_unshift($args,$_this);return$cb->invokeArgs($args);}throw
  257. new\XMemberAccessException("Call to undefined method $class->name::$name().");}static
  258. function&get($_this,$name){$class=get_class($_this);if($name===''){throw
  259. new\XMemberAccessException("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
  260. new\XMemberAccessException("Cannot read an undeclared property $class::\$$name.");}static
  261. function
  262. set($_this,$name,$value){$class=get_class($_this);if($name===''){throw
  263. new\XMemberAccessException("Cannot write 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
  264. new\XMemberAccessException("Cannot write to a read-only property $class::\$$name.");}}$name=func_get_arg(1);throw
  265. new\XMemberAccessException("Cannot write to an undeclared property $class::\$$name.");}static
  266. function
  267. has($_this,$name){if($name===''){return
  268. 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
  269. isset(self::$methods[$class]['get'.$name])||isset(self::$methods[$class]['is'.$name]);}}final
  270. class
  271. Callback
  272. extends
  273. Object{private$cb;function
  274. __construct($t,$m=NULL){if($m===NULL){$this->cb=$t;}else{$this->cb=array($t,$m);}if(!is_callable($this->cb,TRUE)){throw
  275. new\InvalidArgumentException("Invalid callback.");}}function
  276. __invoke(){if(!is_callable($this->cb)){throw
  277. new\XInvalidStateException("Callback '$this' is not callable.");}$args=func_get_args();return
  278. call_user_func_array($this->cb,$args);}function
  279. invoke(){if(!is_callable($this->cb)){throw
  280. new\XInvalidStateException("Callback '$this' is not callable.");}$args=func_get_args();return
  281. call_user_func_array($this->cb,$args);}function
  282. invokeArgs(array$args){if(!is_callable($this->cb)){throw
  283. new\XInvalidStateException("Callback '$this' is not callable.");}return
  284. call_user_func_array($this->cb,$args);}function
  285. isCallable(){return
  286. is_callable($this->cb);}function
  287. getNative(){return$this->cb;}function
  288. __toString(){is_callable($this->cb,TRUE,$textual);return$textual;}}}namespace NetteX\Loaders{use
  289. NetteX;final
  290. class
  291. LimitedScope{private
  292. static$vars;final
  293. function
  294. __construct(){throw
  295. new\LogicException("Cannot instantiate static class ".get_class($this));}static
  296. function
  297. evaluate(){if(func_num_args()>1){self::$vars=func_get_arg(1);extract(self::$vars);}return
  298. eval('?>'.func_get_arg(0));}static
  299. function
  300. load(){if(func_num_args()>1){self::$vars=func_get_arg(1);extract(self::$vars);}return include func_get_arg(0);}}abstract
  301. class
  302. AutoLoader
  303. extends
  304. NetteX\Object{static
  305. private$loaders=array();public
  306. static$count=0;final
  307. static
  308. function
  309. load($type){foreach(func_get_args()as$type){if(!class_exists($type)){throw
  310. new\XInvalidStateException("Unable to load class or interface '$type'.");}}}final
  311. static
  312. function
  313. getLoaders(){return
  314. array_values(self::$loaders);}function
  315. register(){if(!function_exists('spl_autoload_register')){throw
  316. new\RuntimeException('spl_autoload does not exist in this PHP installation.');}spl_autoload_register(array($this,'tryLoad'));self::$loaders[spl_object_hash($this)]=$this;}function
  317. unregister(){unset(self::$loaders[spl_object_hash($this)]);return
  318. spl_autoload_unregister(array($this,'tryLoad'));}abstract
  319. function
  320. tryLoad($type);}}namespace NetteX{use
  321. NetteX;abstract
  322. class
  323. Component
  324. extends
  325. Object
  326. implements
  327. IComponent{private$parent;private$name;private$monitors=array();function
  328. __construct(IComponentContainer$parent=NULL,$name=NULL){if($parent!==NULL){$parent->addComponent($this,$name);}elseif(is_string($name)){$this->name=$name;}}function
  329. lookup($type,$need=TRUE){if(!isset($this->monitors[$type])){$obj=$this->parent;$path=self::NAME_SEPARATOR.$this->name;$depth=1;while($obj!==NULL){if($obj
  330. 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
  331. new\XInvalidStateException("Component '$this->name' is not attached to '$type'.");}return$this->monitors[$type][0];}function
  332. lookupPath($type,$need=TRUE){$this->lookup($type,$need);return$this->monitors[$type][2];}function
  333. monitor($type){if(empty($this->monitors[$type][3])){if($obj=$this->lookup($type,FALSE)){$this->attached($obj);}$this->monitors[$type][3]=TRUE;}}function
  334. unmonitor($type){unset($this->monitors[$type]);}protected
  335. function
  336. attached($obj){}protected
  337. function
  338. detached($obj){}final
  339. function
  340. getName(){return$this->name;}final
  341. function
  342. getParent(){return$this->parent;}function
  343. 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
  344. new\XInvalidStateException("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
  345. function
  346. validateParent(IComponentContainer$parent){}private
  347. function
  348. refreshMonitors($depth,&$missing=NULL,&$listeners=array()){if($this
  349. instanceof
  350. IComponentContainer){foreach($this->getComponents()as$component){if($component
  351. instanceof
  352. Component){$component->refreshMonitors($depth+1,$missing,$listeners);}}}if($missing===NULL){foreach($this->monitors
  353. 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
  354. 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
  355. as$item){$item[0]->$method($item[1]);}}}function
  356. __clone(){if($this->parent===NULL){return;}elseif($this->parent
  357. instanceof
  358. ComponentContainer){$this->parent=$this->parent->_isCloning();if($this->parent===NULL){$this->refreshMonitors(0);}}else{$this->parent=NULL;$this->refreshMonitors(0);}}final
  359. function
  360. __wakeup(){throw
  361. new\XNotImplementedException;}}class
  362. ComponentContainer
  363. extends
  364. Component
  365. implements
  366. IComponentContainer{private$components=array();private$cloning;function
  367. addComponent(IComponent$component,$name,$insertBefore=NULL){if($name===NULL){$name=$component->getName();}if(is_int($name)){$name=(string)$name;}elseif(!is_string($name)){throw
  368. new\InvalidArgumentException("Component name must be integer or string, ".gettype($name)." given.");}elseif(!preg_match('#^[a-zA-Z0-9_]+$#',$name)){throw
  369. new\InvalidArgumentException("Component name must be non-empty alphanumeric string, '$name' given.");}if(isset($this->components[$name])){throw
  370. new\XInvalidStateException("Component with name '$name' already exists.");}$obj=$this;do{if($obj===$component){throw
  371. new\XInvalidStateException("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
  372. 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
  373. removeComponent(IComponent$component){$name=$component->getName();if(!isset($this->components[$name])||$this->components[$name]!==$component){throw
  374. new\InvalidArgumentException("Component named '$name' is not located in this container.");}unset($this->components[$name]);$component->setParent(NULL);}final
  375. function
  376. getComponent($name,$need=TRUE){if(is_int($name)){$name=(string)$name;}elseif(!is_string($name)){throw
  377. new\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
  378. new\InvalidArgumentException("Component or subcomponent name must not be empty string.");}}if(!isset($this->components[$name])){$component=$this->createComponent($name);if($component
  379. instanceof
  380. 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
  381. IComponentContainer){return$this->components[$name]->getComponent($ext,$need);}elseif($need){throw
  382. new\InvalidArgumentException("Component with name '$name' is not container and cannot have '$ext' component.");}}elseif($need){throw
  383. new\InvalidArgumentException("Component with name '$name' does not exist.");}}protected
  384. function
  385. 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
  386. function
  387. getComponents($deep=FALSE,$filterType=NULL){$iterator=new
  388. RecursiveComponentIterator($this->components);if($deep){$deep=$deep>0?\RecursiveIteratorIterator::SELF_FIRST:\RecursiveIteratorIterator::CHILD_FIRST;$iterator=new\RecursiveIteratorIterator($iterator,$deep);}if($filterType){$iterator=new
  389. InstanceFilterIterator($iterator,$filterType);}return$iterator;}protected
  390. function
  391. validateChildComponent(IComponent$child){}function
  392. __clone(){if($this->components){$oldMyself=reset($this->components)->getParent();$oldMyself->cloning=$this;foreach($this->components
  393. as$name=>$component){$this->components[$name]=clone$component;}$oldMyself->cloning=NULL;}parent::__clone();}function
  394. _isCloning(){return$this->cloning;}}class
  395. RecursiveComponentIterator
  396. extends\RecursiveArrayIterator
  397. implements\Countable{function
  398. hasChildren(){return$this->current()instanceof
  399. IComponentContainer;}function
  400. getChildren(){return$this->current()->getComponents();}function
  401. count(){return
  402. iterator_count($this);}}}namespace NetteX\Forms{use
  403. NetteX;class
  404. FormContainer
  405. extends
  406. NetteX\ComponentContainer
  407. implements\ArrayAccess{public$onValidate;protected$currentGroup;protected$valid;function
  408. setDefaults($values,$erase=FALSE){$form=$this->getForm(FALSE);if(!$form||!$form->isAnchored()||!$form->isSubmitted()){$this->setValues($values,$erase);}return$this;}function
  409. setValues($values,$erase=FALSE){if($values
  410. instanceof\Traversable){$values=iterator_to_array($values);}elseif(!is_array($values)){throw
  411. new\InvalidArgumentException("First parameter must be an array, ".gettype($values)." given.");}$cursor=&$values;$iterator=$this->getComponents(TRUE);foreach($iterator
  412. as$name=>$control){$sub=$iterator->getSubIterator();if(!isset($sub->cursor)){$sub->cursor=&$cursor;}if($control
  413. instanceof
  414. IFormControl){if((is_array($sub->cursor)||$sub->cursor
  415. instanceof\ArrayAccess)&&array_key_exists($name,$sub->cursor)){$control->setValue($sub->cursor[$name]);}elseif($erase){$control->setValue(NULL);}}if($control
  416. instanceof
  417. FormContainer){if((is_array($sub->cursor)||$sub->cursor
  418. instanceof\ArrayAccess)&&isset($sub->cursor[$name])){$cursor=&$sub->cursor[$name];}else{unset($cursor);$cursor=NULL;}}}return$this;}function
  419. getValues(){$values=array();$cursor=&$values;$iterator=$this->getComponents(TRUE);foreach($iterator
  420. as$name=>$control){$sub=$iterator->getSubIterator();if(!isset($sub->cursor)){$sub->cursor=&$cursor;}if($control
  421. instanceof
  422. IFormControl&&!$control->isDisabled()&&!($control
  423. instanceof
  424. ISubmitterControl)){$sub->cursor[$name]=$control->getValue();}if($control
  425. instanceof
  426. FormContainer){$cursor=&$sub->cursor[$name];$cursor=array();}}return$values;}function
  427. isValid(){if($this->valid===NULL){$this->validate();}return$this->valid;}function
  428. validate(){$this->valid=TRUE;$this->onValidate($this);foreach($this->getControls()as$control){if(!$control->getRules()->validate()){$this->valid=FALSE;}}}function
  429. setCurrentGroup(FormGroup$group=NULL){$this->currentGroup=$group;return$this;}function
  430. getCurrentGroup(){return$this->currentGroup;}function
  431. addComponent(NetteX\IComponent$component,$name,$insertBefore=NULL){parent::addComponent($component,$name,$insertBefore);if($this->currentGroup!==NULL&&$component
  432. instanceof
  433. IFormControl){$this->currentGroup->add($component);}}function
  434. getControls(){return$this->getComponents(TRUE,'NetteX\Forms\IFormControl');}function
  435. getForm($need=TRUE){return$this->lookup('NetteX\Forms\Form',$need);}function
  436. addText($name,$label=NULL,$cols=NULL,$maxLength=NULL){return$this[$name]=new
  437. TextInput($label,$cols,$maxLength);}function
  438. addPassword($name,$label=NULL,$cols=NULL,$maxLength=NULL){$control=new
  439. TextInput($label,$cols,$maxLength);$control->setType('password');return$this[$name]=$control;}function
  440. addTextArea($name,$label=NULL,$cols=40,$rows=10){return$this[$name]=new
  441. TextArea($label,$cols,$rows);}function
  442. addFile($name,$label=NULL){return$this[$name]=new
  443. FileUpload($label);}function
  444. addHidden($name,$default=NULL){$control=new
  445. HiddenField;$control->setDefaultValue($default);return$this[$name]=$control;}function
  446. addCheckbox($name,$caption=NULL){return$this[$name]=new
  447. Checkbox($caption);}function
  448. addRadioList($name,$label=NULL,array$items=NULL){return$this[$name]=new
  449. RadioList($label,$items);}function
  450. addSelect($name,$label=NULL,array$items=NULL,$size=NULL){return$this[$name]=new
  451. SelectBox($label,$items,$size);}function
  452. addMultiSelect($name,$label=NULL,array$items=NULL,$size=NULL){return$this[$name]=new
  453. MultiSelectBox($label,$items,$size);}function
  454. addSubmit($name,$caption=NULL){return$this[$name]=new
  455. SubmitButton($caption);}function
  456. addButton($name,$caption){return$this[$name]=new
  457. Button($caption);}function
  458. addImage($name,$src=NULL,$alt=NULL){return$this[$name]=new
  459. ImageButton($src,$alt);}function
  460. addContainer($name){$control=new
  461. FormContainer;$control->currentGroup=$this->currentGroup;return$this[$name]=$control;}final
  462. function
  463. offsetSet($name,$component){$this->addComponent($component,$name);}final
  464. function
  465. offsetGet($name){return$this->getComponent($name,TRUE);}final
  466. function
  467. offsetExists($name){return$this->getComponent($name,FALSE)!==NULL;}final
  468. function
  469. offsetUnset($name){$component=$this->getComponent($name,FALSE);if($component!==NULL){$this->removeComponent($component);}}final
  470. function
  471. __clone(){throw
  472. new\XNotImplementedException('Form cloning is not supported yet.');}}class
  473. Form
  474. extends
  475. FormContainer{const
  476. EQUAL=':equal';const
  477. IS_IN=':equal';const
  478. FILLED=':filled';const
  479. VALID=':valid';const
  480. PROTECTION='NetteX\Forms\HiddenField::validateEqual';const
  481. SUBMITTED=':submitted';const
  482. MIN_LENGTH=':minLength';const
  483. MAX_LENGTH=':maxLength';const
  484. LENGTH=':length';const
  485. EMAIL=':email';const
  486. URL=':url';const
  487. REGEXP=':regexp';const
  488. PATTERN=':pattern';const
  489. INTEGER=':integer';const
  490. NUMERIC=':integer';const
  491. FLOAT=':float';const
  492. RANGE=':range';const
  493. MAX_FILE_SIZE=':fileSize';const
  494. MIME_TYPE=':mimeType';const
  495. IMAGE=':image';const
  496. GET='get';const
  497. POST='post';const
  498. TRACKER_ID='_form_';const
  499. PROTECTOR_ID='_token_';public$onSubmit;public$onInvalidSubmit;private$submittedBy;private$httpData;private$element;private$renderer;private$translator;private$groups=array();private$errors=array();function
  500. __construct($name=NULL){$this->element=NetteX\Web\Html::el('form');$this->element->action='';$this->element->method=self::POST;$this->element->id='frm-'.$name;$this->monitor(__CLASS__);if($name!==NULL){$tracker=new
  501. HiddenField($name);$tracker->unmonitor(__CLASS__);$this[self::TRACKER_ID]=$tracker;}parent::__construct(NULL,$name);}protected
  502. function
  503. attached($obj){if($obj
  504. instanceof
  505. self){throw
  506. new\XInvalidStateException('Nested forms are forbidden.');}}final
  507. function
  508. getForm($need=TRUE){return$this;}function
  509. setAction($url){$this->element->action=$url;return$this;}function
  510. getAction(){return$this->element->action;}function
  511. setMethod($method){if($this->httpData!==NULL){throw
  512. new\XInvalidStateException(__METHOD__.'() must be called until the form is empty.');}$this->element->method=strtolower($method);return$this;}function
  513. getMethod(){return$this->element->method;}function
  514. addProtection($message=NULL,$timeout=NULL){$session=$this->getSession()->getNamespace('NetteX.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
  515. HiddenField($token);$this[self::PROTECTOR_ID]->addRule(self::PROTECTION,$message,$token);}function
  516. addGroup($caption=NULL,$setAsCurrent=TRUE){$group=new
  517. 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
  518. removeGroup($name){if(is_string($name)&&isset($this->groups[$name])){$group=$this->groups[$name];}elseif($name
  519. instanceof
  520. FormGroup&&in_array($name,$this->groups,TRUE)){$group=$name;$name=array_search($group,$this->groups,TRUE);}else{throw
  521. new\InvalidArgumentException("Group not found in form '$this->name'");}foreach($group->getControls()as$control){$this->removeComponent($control);}unset($this->groups[$name]);}function
  522. getGroups(){return$this->groups;}function
  523. getGroup($name){return
  524. isset($this->groups[$name])?$this->groups[$name]:NULL;}function
  525. setTranslator(NetteX\ITranslator$translator=NULL){$this->translator=$translator;return$this;}final
  526. function
  527. getTranslator(){return$this->translator;}function
  528. isAnchored(){return
  529. TRUE;}final
  530. function
  531. isSubmitted(){if($this->submittedBy===NULL){$this->getHttpData();$this->submittedBy=!empty($this->httpData);}return$this->submittedBy;}function
  532. setSubmittedBy(ISubmitterControl$by=NULL){$this->submittedBy=$by===NULL?FALSE:$by;return$this;}final
  533. function
  534. getHttpData(){if($this->httpData===NULL){if(!$this->isAnchored()){throw
  535. new\XInvalidStateException('Form is not anchored and therefore can not determine whether it was submitted.');}$this->httpData=(array)$this->receiveHttpData();}return$this->httpData;}function
  536. fireEvents(){if(!$this->isSubmitted()){return;}elseif($this->submittedBy
  537. instanceof
  538. 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
  539. function
  540. receiveHttpData(){$httpRequest=$this->getHttpRequest();if(strcasecmp($this->getMethod(),$httpRequest->getMethod())){return;}$httpRequest->setEncoding('utf-8');if($httpRequest->isMethod('post')){$data=NetteX\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
  541. getValues(){$values=parent::getValues();unset($values[self::TRACKER_ID],$values[self::PROTECTOR_ID]);return$values;}function
  542. addError($message){$this->valid=FALSE;if($message!==NULL&&!in_array($message,$this->errors,TRUE)){$this->errors[]=$message;}}function
  543. getErrors(){return$this->errors;}function
  544. hasErrors(){return(bool)$this->getErrors();}function
  545. cleanErrors(){$this->errors=array();$this->valid=NULL;}function
  546. getElementPrototype(){return$this->element;}function
  547. setRenderer(IFormRenderer$renderer){$this->renderer=$renderer;return$this;}final
  548. function
  549. getRenderer(){if($this->renderer===NULL){$this->renderer=new
  550. ConventionalRenderer;}return$this->renderer;}function
  551. render(){$args=func_get_args();array_unshift($args,$this);echo
  552. call_user_func_array(array($this->getRenderer(),'render'),$args);}function
  553. __toString(){try{return$this->getRenderer()->render($this);}catch(\Exception$e){if(func_get_args()&&func_get_arg(0)){throw$e;}else{NetteX\Debug::toStringException($e);}}}protected
  554. function
  555. getHttpRequest(){return
  556. class_exists('NetteX\Environment')?NetteX\Environment::getHttpRequest():new
  557. NetteX\Web\HttpRequest;}protected
  558. function
  559. getSession(){return
  560. NetteX\Environment::getSession();}}}namespace NetteX\Application{use
  561. NetteX;class
  562. AppForm
  563. extends
  564. NetteX\Forms\Form
  565. implements
  566. ISignalReceiver{function
  567. __construct(NetteX\IComponentContainer$parent=NULL,$name=NULL){parent::__construct();$this->monitor('NetteX\Application\Presenter');if($parent!==NULL){$parent->addComponent($this,$name);}}function
  568. getPresenter($need=TRUE){return$this->lookup('NetteX\Application\Presenter',$need);}protected
  569. function
  570. attached($presenter){if($presenter
  571. instanceof
  572. Presenter){$name=$this->lookupPath('NetteX\Application\Presenter');if(!isset($this->getElementPrototype()->id)){$this->getElementPrototype()->id='frm-'.$name;}$this->setAction(new
  573. Link($presenter,$name.self::NAME_SEPARATOR.'submit!',array()));if($this->isSubmitted()){foreach($this->getControls()as$control){$control->loadHttpData();}}}parent::attached($presenter);}function
  574. isAnchored(){return(bool)$this->getPresenter(FALSE);}protected
  575. function
  576. 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
  577. NetteX\ArrayTools::mergeTree($request->getPost(),$request->getFiles());}else{return$request->getParams();}}function
  578. signalReceived($signal){if($signal==='submit'){$this->fireEvents();}else{throw
  579. new
  580. BadSignalException("Missing handler for signal '$signal' in {$this->reflection->name}.");}}}class
  581. Application
  582. extends
  583. NetteX\Object{public
  584. static$maxLoop=20;public$catchExceptions;public$errorPresenter;public$onStartup;public$onShutdown;public$onRequest;public$onResponse;public$onError;public$allowedMethods=array('GET','POST','HEAD','PUT','DELETE');private$requests=array();private$presenter;private$context;function
  585. run(){$httpRequest=$this->getHttpRequest();$httpResponse=$this->getHttpResponse();$httpRequest->setEncoding('UTF-8');$session=$this->getSession();if(!$session->isStarted()&&$session->exists()){$session->start();}if($this->allowedMethods){$method=$httpRequest->getMethod();if(!in_array($method,$this->allowedMethods,TRUE)){$httpResponse->setCode(NetteX\Web\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
  586. new
  587. ApplicationException('Too many loops detected in application life cycle.');}if(!$request){$this->onStartup($this);$router=$this->getRouter();NetteX\Debug::addPanel(new
  588. RoutingDebugger($router,$httpRequest));$request=$router->match($httpRequest);if(!($request
  589. instanceof
  590. PresenterRequest)){$request=NULL;throw
  591. new
  592. BadRequestException('No route for HTTP request.');}if(strcasecmp($request->getPresenterName(),$this->errorPresenter)===0){throw
  593. new
  594. BadRequestException('Invalid request. Presenter is not achievable.');}}$this->requests[]=$request;$this->onRequest($this,$request);$presenter=$request->getPresenterName();try{$class=$this->getPresenterLoader()->getPresenterClass($presenter);$request->setPresenterName($presenter);}catch(InvalidPresenterException$e){throw
  595. new
  596. BadRequestException($e->getMessage(),404,$e);}$request->freeze();$this->presenter=new$class;$response=$this->presenter->run($request);$this->onResponse($this,$response);if($response
  597. instanceof
  598. ForwardingResponse){$request=$response->getRequest();continue;}elseif($response
  599. instanceof
  600. IPresenterResponse){$response->send();}break;}catch(\Exception$e){$this->onError($this,$e);if(!$this->catchExceptions){$this->onShutdown($this,$e);throw$e;}if($repeatedError){$e=new
  601. ApplicationException('An error occured while executing error-presenter',0,$e);}if(!$httpResponse->isSent()){$httpResponse->setCode($e
  602. instanceof
  603. BadRequestException?$e->getCode():500);}if(!$repeatedError&&$this->errorPresenter){$repeatedError=TRUE;if($this->presenter){try{$this->presenter->forward(":$this->errorPresenter:",array('exception'=>$e));}catch(AbortException$foo){$request=$this->presenter->getLastCreatedRequest();}}else{$request=new
  604. PresenterRequest($this->errorPresenter,PresenterRequest::FORWARD,array('exception'=>$e));}}else{if($e
  605. instanceof
  606. BadRequestException){$code=$e->getCode();}else{$code=500;NetteX\Debug::log($e,NetteX\Debug::ERROR);}echo"<!DOCTYPE html><meta name=robots content=noindex><meta name=generator content='NetteX Framework'>\n\n";echo"<style>body{color:#333;background:white;width:500px;margin:100px auto}h1{font:bold 47px/1.5 sans-serif;margin:.6em 0}p{font:21px/1.5 Georgia,serif;margin:1.5em 0}small{font-size:70%;color:gray}</style>\n\n";static$messages=array(0=>array('Oops...','Your browser sent a request that this server could not understand or process.'),403=>array('Access Denied','You do not have permission to view this page. Please try contact the web site administrator if you believe you should be able to view this page.'),404=>array('Page Not Found','The page you requested could not be found. It is possible that the address is incorrect, or that the page no longer exists. Please use a search engine to find what you are looking for.'),405=>array('Method Not Allowed','The requested method is not allowed for the URL.'),410=>array('Page Not Found','The page you requested has been taken off the site. We apologize for the inconvenience.'),500=>array('Server Error','We\'re sorry! The server encountered an internal error and was unable to complete your request. Please try again later.'));$message=isset($messages[$code])?$messages[$code]:$messages[0];echo"<title>$message[0]</title>\n\n<h1>$message[0]</h1>\n\n<p>$message[1]</p>\n\n";if($code)echo"<p><small>error $code</small></p>";break;}}}while(1);$this->onShutdown($this,isset($e)?$e:NULL);}final
  607. function
  608. getRequests(){return$this->requests;}final
  609. function
  610. getPresenter(){return$this->presenter;}function
  611. setContext(NetteX\IContext$context){$this->context=$context;return$this;}final
  612. function
  613. getContext(){return$this->context;}final
  614. function
  615. getService($name,array$options=NULL){return$this->context->getService($name,$options);}function
  616. getRouter(){return$this->context->getService('NetteX\\Application\\IRouter');}function
  617. setRouter(IRouter$router){$this->context->addService('NetteX\\Application\\IRouter',$router);return$this;}function
  618. getPresenterLoader(){return$this->context->getService('NetteX\\Application\\IPresenterLoader');}protected
  619. function
  620. getHttpRequest(){return$this->context->getService('NetteX\\Web\\IHttpRequest');}protected
  621. function
  622. getHttpResponse(){return$this->context->getService('NetteX\\Web\\IHttpResponse');}protected
  623. function
  624. getSession($namespace=NULL){$handler=$this->context->getService('NetteX\\Web\\Session');return$namespace===NULL?$handler:$handler->getNamespace($namespace);}function
  625. storeRequest($expiration='+ 10 minutes'){$session=$this->getSession('NetteX.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
  626. restoreRequest($key){$session=$this->getSession('NetteX.Application/requests');if(isset($session[$key])){$request=clone$session[$key];unset($session[$key]);$request->setFlag(PresenterRequest::RESTORED,TRUE);$this->presenter->sendResponse(new
  627. ForwardingResponse($request));}}}abstract
  628. class
  629. PresenterComponent
  630. extends
  631. NetteX\ComponentContainer
  632. implements
  633. ISignalReceiver,IStatePersistent,\ArrayAccess{protected$params=array();function
  634. __construct(NetteX\IComponentContainer$parent=NULL,$name=NULL){$this->monitor('NetteX\Application\Presenter');parent::__construct($parent,$name);}function
  635. getPresenter($need=TRUE){return$this->lookup('NetteX\Application\Presenter',$need);}function
  636. getUniqueId(){return$this->lookupPath('NetteX\Application\Presenter',TRUE);}protected
  637. function
  638. attached($presenter){if($presenter
  639. instanceof
  640. Presenter){$this->loadState($presenter->popGlobalParams($this->getUniqueId()));}}protected
  641. function
  642. 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
  643. TRUE;}}return
  644. FALSE;}static
  645. function
  646. getReflection(){return
  647. new
  648. PresenterComponentReflection(get_called_class());}function
  649. 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
  650. 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
  651. instanceof$meta['since']){$val=$this->$nm;}else{continue;}if(is_object($val)){throw
  652. new\XInvalidStateException("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
  653. function
  654. 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
  655. function
  656. getParamId($name){$uid=$this->getUniqueId();return$uid===''?$name:$uid.self::NAME_SEPARATOR.$name;}static
  657. function
  658. getPersistentParams(){$rc=new
  659. NetteX\Reflection\ClassReflection(get_called_class());$params=array();foreach($rc->getProperties(\ReflectionProperty::IS_PUBLIC)as$rp){if(!$rp->isStatic()&&$rp->hasAnnotation('persistent')){$params[]=$rp->getName();}}return$params;}function
  660. signalReceived($signal){if(!$this->tryCall($this->formatSignalMethod($signal),$this->params)){throw
  661. new
  662. BadSignalException("There is no handler for signal '$signal' in class {$this->reflection->name}.");}}function
  663. formatSignalMethod($signal){return$signal==NULL?NULL:'handle'.$signal;}function
  664. 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
  665. lazyLink($destination,$args=array()){if(!is_array($args)){$args=func_get_args();array_shift($args);}return
  666. new
  667. Link($this,$destination,$args);}function
  668. 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
  669. function
  670. offsetSet($name,$component){$this->addComponent($component,$name);}final
  671. function
  672. offsetGet($name){return$this->getComponent($name,TRUE);}final
  673. function
  674. offsetExists($name){return$this->getComponent($name,FALSE)!==NULL;}final
  675. function
  676. offsetUnset($name){$component=$this->getComponent($name,FALSE);if($component!==NULL){$this->removeComponent($component);}}}abstract
  677. class
  678. Control
  679. extends
  680. PresenterComponent
  681. implements
  682. IPartiallyRenderable{private$template;private$invalidSnippets=array();final
  683. function
  684. getTemplate(){if($this->template===NULL){$value=$this->createTemplate();if(!($value
  685. instanceof
  686. NetteX\Templates\ITemplate||$value===NULL)){$class=get_class($value);throw
  687. new\UnexpectedValueException("Object returned by {$this->reflection->name}::createTemplate() must be instance of NetteX\\Templates\\ITemplate, '$class' given.");}$this->template=$value;}return$this->template;}protected
  688. function
  689. createTemplate(){$template=new
  690. NetteX\Templates\FileTemplate;$presenter=$this->getPresenter(FALSE);$template->onPrepareFilters[]=callbackX($this,'templatePrepareFilters');$template->control=$this;$template->presenter=$presenter;$template->user=NetteX\Environment::getUser();$template->baseUri=rtrim(NetteX\Environment::getVariable('baseUri',NULL),'/');$template->basePath=preg_replace('#https?://[^/]+#A','',$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','NetteX\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('replaceRE','NetteX\String::replace');$template->registerHelper('implode','implode');$template->registerHelper('number','number_format');$template->registerHelperLoader('NetteX\Templates\TemplateHelpers::loader');return$template;}function
  691. templatePrepareFilters($template){$template->registerFilter(new
  692. NetteX\Templates\LatteFilter);}function
  693. getWidget($name){return$this->getComponent($name);}function
  694. 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
  695. invalidateControl($snippet=NULL){$this->invalidSnippets[$snippet]=TRUE;}function
  696. validateControl($snippet=NULL){if($snippet===NULL){$this->invalidSnippets=array();}else{unset($this->invalidSnippets[$snippet]);}}function
  697. isControlInvalid($snippet=NULL){if($snippet===NULL){if(count($this->invalidSnippets)>0){return
  698. TRUE;}else{foreach($this->getComponents()as$component){if($component
  699. instanceof
  700. IRenderable&&$component->isControlInvalid()){return
  701. TRUE;}}return
  702. FALSE;}}else{return
  703. isset($this->invalidSnippets[NULL])||isset($this->invalidSnippets[$snippet]);}}function
  704. getSnippetId($name=NULL){return'snippet-'.$this->getUniqueId().'-'.$name;}}class
  705. AbortException
  706. extends\Exception{}class
  707. ApplicationException
  708. extends\Exception{}class
  709. BadRequestException
  710. extends\Exception{protected$defaultCode=404;function
  711. __construct($message='',$code=0,\Exception$previous=NULL){if($code<200||$code>504){$code=$this->defaultCode;}{parent::__construct($message,$code,$previous);}}}class
  712. BadSignalException
  713. extends
  714. BadRequestException{protected$defaultCode=403;}class
  715. ForbiddenRequestException
  716. extends
  717. BadRequestException{protected$defaultCode=403;}class
  718. InvalidLinkException
  719. extends\Exception{}class
  720. InvalidPresenterException
  721. extends
  722. InvalidLinkException{}class
  723. Link
  724. extends
  725. NetteX\Object{private$component;private$destination;private$params;function
  726. __construct(PresenterComponent$component,$destination,array$params){$this->component=$component;$this->destination=$destination;$this->params=$params;}function
  727. getDestination(){return$this->destination;}function
  728. setParam($key,$value){$this->params[$key]=$value;return$this;}function
  729. getParam($key){return
  730. isset($this->params[$key])?$this->params[$key]:NULL;}function
  731. getParams(){return$this->params;}function
  732. __toString(){try{return$this->component->link($this->destination,$this->params);}catch(\Exception$e){NetteX\Debug::toStringException($e);}}}use
  733. NetteX\Environment;abstract
  734. class
  735. Presenter
  736. extends
  737. Control
  738. implements
  739. IPresenter{const
  740. INVALID_LINK_SILENT=1;const
  741. INVALID_LINK_WARNING=2;const
  742. INVALID_LINK_EXCEPTION=3;const
  743. SIGNAL_KEY='do';const
  744. ACTION_KEY='action';const
  745. FLASH_KEY='_fid';public
  746. static$defaultAction='default';public
  747. static$invalidLinkMode;public$onShutdown;private$request;private$response;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
  748. function
  749. getRequest(){return$this->request;}final
  750. function
  751. getPresenter($need=TRUE){return$this;}final
  752. function
  753. getUniqueId(){return'';}function
  754. run(PresenterRequest$request){try{$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();throw
  755. new\XInvalidStateException("Method $class::startup() or its descendant doesn't call parent::startup().");}$this->tryCall($this->formatActionMethod($this->getAction()),$this->params);if($this->autoCanonicalize){$this->canonicalize();}if($this->getHttpRequest()->isMethod('head')){$this->terminate();}$this->processSignal();$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){}{if($this->isAjax())try{$hasPayload=(array)$this->payload;unset($hasPayload['state']);if($this->response
  756. instanceof
  757. RenderResponse&&($this->isControlInvalid()||$hasPayload)){$this->response->send();$this->sendPayload();}elseif(!$this->response&&$hasPayload){$this->sendPayload();}}catch(AbortException$e){}if($this->hasFlashSession()){$this->getFlashSession()->setExpiration($this->response
  758. instanceof
  759. RedirectingResponse?'+ 30 seconds':'+ 3 seconds');}$this->onShutdown($this,$this->response);$this->shutdown($this->response);return$this->response;}}protected
  760. function
  761. startup(){$this->startupCheck=TRUE;}protected
  762. function
  763. beforeRender(){}protected
  764. function
  765. afterRender(){}protected
  766. function
  767. shutdown($response){}function
  768. processSignal(){if($this->signal===NULL)return;$component=$this->signalReceiver===''?$this:$this->getComponent($this->signalReceiver,FALSE);if($component===NULL){throw
  769. new
  770. BadSignalException("The signal receiver component '$this->signalReceiver' is not found.");}elseif(!$component
  771. instanceof
  772. ISignalReceiver){throw
  773. new
  774. BadSignalException("The signal receiver component '$this->signalReceiver' is not ISignalReceiver implementor.");}$component->signalReceived($this->signal);$this->signal=NULL;}final
  775. function
  776. getSignal(){return$this->signal===NULL?NULL:array($this->signalReceiver,$this->signal);}final
  777. function
  778. isSignalReceiver($component,$signal=NULL){if($component
  779. instanceof
  780. NetteX\Component){$component=$component===$this?'':$component->lookupPath(__CLASS__,TRUE);}if($this->signal===NULL){return
  781. 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
  782. function
  783. getAction($fullyQualified=FALSE){return$fullyQualified?':'.$this->getName().':'.$this->action:$this->action;}function
  784. changeAction($action){if(NetteX\String::match($action,"#^[a-zA-Z0-9][a-zA-Z0-9_\x7f-\xff]*$#")){$this->action=$action;$this->view=$action;}else{throw
  785. new
  786. BadRequestException("Action name '$action' is not alphanumeric string.");}}final
  787. function
  788. getView(){return$this->view;}function
  789. setView($view){$this->view=(string)$view;return$this;}final
  790. function
  791. getLayout(){return$this->layout;}function
  792. setLayout($layout){$this->layout=$layout===FALSE?FALSE:(string)$layout;return$this;}function
  793. sendTemplate(){$template=$this->getTemplate();if(!$template)return;if($template
  794. instanceof
  795. NetteX\Templates\IFileTemplate&&!$template->getFile()){$files=$this->formatTemplateFiles($this->getName(),$this->view);foreach($files
  796. 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
  797. new
  798. BadRequestException("Page not found. Missing template '$file'.");}if($this->layout!==FALSE){$files=$this->formatLayoutTemplateFiles($this->getName(),$this->layout?$this->layout:'layout');foreach($files
  799. as$file){if(is_file($file)){$template->layout=$file;$template->_extends=$file;break;}}if(empty($template->layout)&&$this->layout!==NULL){$file=str_replace(Environment::getVariable('appDir'),"\xE2\x80\xA6",reset($files));throw
  800. new\XFileNotFoundException("Layout not found. Missing template '$file'.");}}}$this->sendResponse(new
  801. RenderResponse($template));}function
  802. formatLayoutTemplateFiles($presenter,$layout){$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
  803. formatTemplateFiles($presenter,$view){$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
  804. array("$appDir$pathP/$view.phtml","$appDir$pathP.$view.phtml","$appDir$path/@global.$view.phtml");}protected
  805. static
  806. function
  807. formatActionMethod($action){return'action'.$action;}protected
  808. static
  809. function
  810. formatRenderMethod($view){return'render'.$view;}final
  811. function
  812. getPayload(){return$this->payload;}function
  813. isAjax(){if($this->ajaxMode===NULL){$this->ajaxMode=$this->getHttpRequest()->isAjax();}return$this->ajaxMode;}function
  814. sendPayload(){$this->sendResponse(new
  815. JsonResponse($this->payload));}function
  816. sendResponse(IPresenterResponse$response){$this->response=$response;$this->terminate();}function
  817. terminate(){if(func_num_args()!==0){trigger_error(__METHOD__.' is not intended to send a PresenterResponse; use sendResponse() instead.',E_USER_WARNING);$this->sendResponse(func_get_arg(0));}throw
  818. new
  819. AbortException();}function
  820. forward($destination,$args=array()){if($destination
  821. instanceof
  822. PresenterRequest){$this->sendResponse(new
  823. ForwardingResponse($destination));}elseif(!is_array($args)){$args=func_get_args();array_shift($args);}$this->createRequest($this,$destination,$args,'forward');$this->sendResponse(new
  824. ForwardingResponse($this->lastCreatedRequest));}function
  825. redirectUri($uri,$code=NULL){if($this->isAjax()){$this->payload->redirect=(string)$uri;$this->sendPayload();}elseif(!$code){$code=$this->getHttpRequest()->isMethod('post')?NetteX\Web\IHttpResponse::S303_POST_GET:NetteX\Web\IHttpResponse::S302_FOUND;}$this->sendResponse(new
  826. RedirectingResponse($uri,$code));}function
  827. backlink(){return$this->getAction(TRUE);}function
  828. getLastCreatedRequest(){return$this->lastCreatedRequest;}function
  829. getLastCreatedRequestFlag($flag){return!empty($this->lastCreatedRequestFlag[$flag]);}function
  830. 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->sendResponse(new
  831. RedirectingResponse($uri,NetteX\Web\IHttpResponse::S301_MOVED_PERMANENTLY));}}}function
  832. 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
  833. protected
  834. function
  835. 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
  836. instanceof
  837. 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
  838. new
  839. InvalidLinkException("Signal must be non-empty string.");}$destination='this';}if($destination==NULL){throw
  840. new
  841. 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
  842. new
  843. 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
  844. PresenterComponentReflection(get_class($component));if($signal==='this'){$signal='';if(array_key_exists(0,$args)){throw
  845. new
  846. InvalidLinkException("Unable to pass parameters to 'this!' signal.");}}elseif(strpos($signal,self::NAME_SEPARATOR)===FALSE){$method=$component->formatSignalMethod($signal);if(!$reflection->hasCallableMethod($method)){throw
  847. new
  848. InvalidLinkException("Unknown signal '$signal', missing handler {$reflection->name}::$method()");}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
  849. as$key=>$val){unset($args[$key]);$args[$prefix.$key]=$val;}}}if(is_subclass_of($presenterClass,__CLASS__)){if($action===''){$action=$presenterClass::$defaultAction;}$current=($action==='*'||$action===$this->action)&&$presenterClass===get_class($this);$reflection=new
  850. PresenterComponentReflection($presenterClass);if($args||$destination==='this'){$method=$presenterClass::formatActionMethod($action);if(!$reflection->hasCallableMethod($method)){$method=$presenterClass::formatRenderMethod($action);if(!$reflection->hasCallableMethod($method)){$method=NULL;}}if($method===NULL){if(array_key_exists(0,$args)){throw
  851. new
  852. InvalidLinkException("Unable to pass parameters to action '$presenter:$action', missing corresponding method.");}}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
  853. 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
  854. PresenterRequest($presenter,PresenterRequest::FORWARD,$args,array(),array());$this->lastCreatedRequestFlag=array('current'=>$current);if($mode==='forward')return;$uri=$router->constructUrl($this->lastCreatedRequest,$httpRequest->getUri());if($uri===NULL){unset($args[self::ACTION_KEY]);$params=urldecode(http_build_query($args,NULL,', '));throw
  855. new
  856. 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
  857. static
  858. function
  859. argsToParams($class,$method,&$args,$supplemental=array()){static$cache;$params=&$cache[strtolower($class.':'.$method)];if($params===NULL){$params=NetteX\Reflection\MethodReflection::from($class,$method)->getDefaultParameters();}$i=0;foreach($params
  860. 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)){$method=NetteX\Reflection\MethodReflection::from($class,$method)->getName();throw
  861. new
  862. InvalidLinkException("Passed more parameters than method $class::$method() expects.");}}protected
  863. function
  864. 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
  865. function
  866. getPersistentComponents(){return(array)NetteX\Reflection\ClassReflection::from(get_called_class())->getAnnotation('persistent');}private
  867. function
  868. getGlobalState($forClass=NULL){$sinces=&$this->globalStateSinces;if($this->globalState===NULL){$state=array();foreach($this->globalParams
  869. as$id=>$params){$prefix=$id.self::NAME_SEPARATOR;foreach($params
  870. as$key=>$val){$state[$prefix.$key]=$val;}}$this->saveState($state,$forClass?new
  871. 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,'NetteX\Application\IStatePersistent');foreach($iterator
  872. 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
  873. as$key=>$val){$state[$prefix.$key]=$val;$sinces[$prefix.$key]=$since;}}}else{$state=$this->globalState;}if($forClass!==NULL){$since=NULL;foreach($state
  874. 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
  875. function
  876. saveGlobalState(){foreach($this->globalParams
  877. as$id=>$foo){$this->getComponent($id,FALSE);}$this->globalParams=array();$this->globalState=$this->getGlobalState();}private
  878. function
  879. initGlobalParams(){$this->globalParams=array();$selfParams=array();$params=$this->request->getParams();if($this->isAjax()){$params=$this->request->getPost()+$params;}foreach($params
  880. 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
  881. function
  882. popGlobalParams($id){if(isset($this->globalParams[$id])){$res=$this->globalParams[$id];unset($this->globalParams[$id]);return$res;}else{return
  883. array();}}function
  884. hasFlashSession(){return!empty($this->params[self::FLASH_KEY])&&$this->getSession()->hasNamespace('NetteX.Application.Flash/'.$this->params[self::FLASH_KEY]);}function
  885. getFlashSession(){if(empty($this->params[self::FLASH_KEY])){$this->params[self::FLASH_KEY]=substr(md5(lcg_value()),0,4);}return$this->getSession('NetteX.Application.Flash/'.$this->params[self::FLASH_KEY]);}protected
  886. function
  887. getHttpRequest(){return
  888. Environment::getHttpRequest();}protected
  889. function
  890. getHttpResponse(){return
  891. Environment::getHttpResponse();}protected
  892. function
  893. getHttpContext(){return
  894. Environment::getHttpContext();}function
  895. getApplication(){return
  896. Environment::getApplication();}function
  897. getSession($namespace=NULL){return
  898. Environment::getSession($namespace);}function
  899. getUser(){return
  900. Environment::getUser();}}}namespace NetteX\Reflection{use
  901. NetteX;use
  902. NetteX\ObjectMixin;class
  903. ClassReflection
  904. extends\ReflectionClass{private
  905. static$extMethods;static
  906. function
  907. from($class){return
  908. new
  909. static($class);}function
  910. __toString(){return'Class '.$this->getName();}function
  911. hasEventProperty($name){if(preg_match('#^on[A-Z]#',$name)&&$this->hasProperty($name)){$rp=$this->getProperty($name);return$rp->isPublic()&&!$rp->isStatic();}return
  912. FALSE;}function
  913. setExtensionMethod($name,$callback){$l=&self::$extMethods[strtolower($name)];$l[strtolower($this->getName())]=callbackX($callback);$l['']=NULL;return$this;}function
  914. getExtensionMethod($name){$class=strtolower($this->getName());$l=&self::$extMethods[strtolower($name)];if(empty($l)){return
  915. 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;}function
  916. getConstructor(){return($ref=parent::getConstructor())?MethodReflection::import($ref):NULL;}function
  917. getExtension(){return($name=$this->getExtensionName())?new
  918. ExtensionReflection($name):NULL;}function
  919. getInterfaces(){$res=array();foreach(parent::getInterfaceNames()as$val){$res[$val]=new
  920. static($val);}return$res;}function
  921. getMethod($name){return
  922. new
  923. MethodReflection($this->getName(),$name);}function
  924. getMethods($filter=-1){foreach($res=parent::getMethods($filter)as$key=>$val){$res[$key]=new
  925. MethodReflection($this->getName(),$val->getName());}return$res;}function
  926. getParentClass(){return($ref=parent::getParentClass())?new
  927. static($ref->getName()):NULL;}function
  928. getProperties($filter=-1){foreach($res=parent::getProperties($filter)as$key=>$val){$res[$key]=new
  929. PropertyReflection($this->getName(),$val->getName());}return$res;}function
  930. getProperty($name){return
  931. new
  932. PropertyReflection($this->getName(),$name);}function
  933. hasAnnotation($name){$res=AnnotationsParser::getAll($this);return!empty($res[$name]);}function
  934. getAnnotation($name){$res=AnnotationsParser::getAll($this);return
  935. isset($res[$name])?end($res[$name]):NULL;}function
  936. getAnnotations(){return
  937. AnnotationsParser::getAll($this);}static
  938. function
  939. getReflection(){return
  940. new
  941. NetteX\Reflection\ClassReflection(get_called_class());}function
  942. __call($name,$args){return
  943. ObjectMixin::call($this,$name,$args);}function&__get($name){return
  944. ObjectMixin::get($this,$name);}function
  945. __set($name,$value){return
  946. ObjectMixin::set($this,$name,$value);}function
  947. __isset($name){return
  948. ObjectMixin::has($this,$name);}function
  949. __unset($name){throw
  950. new\XMemberAccessException("Cannot unset the property {$this->reflection->name}::\$$name.");}}}namespace NetteX\Application{use
  951. NetteX;class
  952. PresenterComponentReflection
  953. extends
  954. NetteX\Reflection\ClassReflection{private
  955. static$ppCache=array();private
  956. static$pcCache=array();private
  957. static$mcCache=array();function
  958. 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,'NetteX\Application\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
  959. getPersistentComponents(){$class=$this->getName();$components=&self::$pcCache[$class];if($components!==NULL)return$components;$components=array();if(is_subclass_of($class,'NetteX\Application\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
  960. hasCallableMethod($method){$class=$this->getName();$cache=&self::$mcCache[strtolower($class.':'.$method)];if($cache===NULL)try{$cache=FALSE;$rm=NetteX\Reflection\MethodReflection::from($class,$method);$cache=$this->isInstantiable()&&$rm->isPublic()&&!$rm->isAbstract()&&!$rm->isStatic();}catch(\ReflectionException$e){}return$cache;}}class
  961. PresenterLoader
  962. implements
  963. IPresenterLoader{public$caseSensitive=FALSE;private$baseDir;private$cache=array();function
  964. __construct($baseDir){$this->baseDir=$baseDir;}function
  965. getPresenterClass(&$name){if(isset($this->cache[$name])){list($class,$name)=$this->cache[$name];return$class;}if(!is_string($name)||!NetteX\String::match($name,"#^[a-zA-Z\x7f-\xff][a-zA-Z0-9\x7f-\xff:]*$#")){throw
  966. new
  967. 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)){NetteX\Loaders\LimitedScope::load($file);}if(!class_exists($class)){throw
  968. new
  969. InvalidPresenterException("Cannot load presenter '$name', class '$class' was not found in '$file'.");}}$reflection=new
  970. NetteX\Reflection\ClassReflection($class);$class=$reflection->getName();if(!$reflection->implementsInterface('NetteX\Application\IPresenter')){throw
  971. new
  972. InvalidPresenterException("Cannot load presenter '$name', class '$class' is not NetteX\\Application\\IPresenter implementor.");}if($reflection->isAbstract()){throw
  973. new
  974. InvalidPresenterException("Cannot load presenter '$name', class '$class' is abstract.");}$realName=$this->unformatPresenterClass($class);if($name!==$realName){if($this->caseSensitive){throw
  975. new
  976. 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
  977. formatPresenterClass($presenter){return
  978. str_replace(':','Module\\',$presenter).'Presenter';}function
  979. unformatPresenterClass($class){return
  980. str_replace('Module\\',':',substr($class,0,-9));}function
  981. formatPresenterFile($presenter){$path='/'.str_replace(':','Module/',$presenter);return$this->baseDir.substr_replace($path,'/presenters',strrpos($path,'/'),0).'Presenter.php';}}}namespace NetteX{use
  982. NetteX;abstract
  983. class
  984. FreezableObject
  985. extends
  986. Object
  987. implements
  988. IFreezable{private$frozen=FALSE;function
  989. freeze(){$this->frozen=TRUE;}final
  990. function
  991. isFrozen(){return$this->frozen;}function
  992. __clone(){$this->frozen=FALSE;}protected
  993. function
  994. updating(){if($this->frozen){throw
  995. new\XInvalidStateException("Cannot modify a frozen object {$this->reflection->name}.");}}}}namespace NetteX\Application{use
  996. NetteX;final
  997. class
  998. PresenterRequest
  999. extends
  1000. NetteX\FreezableObject{const
  1001. FORWARD='FORWARD';const
  1002. SECURED='secured';const
  1003. RESTORED='restored';private$method;private$flags=array();private$name;private$params;private$post;private$files;function
  1004. __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
  1005. setPresenterName($name){$this->updating();$this->name=$name;return$this;}function
  1006. getPresenterName(){return$this->name;}function
  1007. setParams(array$params){$this->updating();$this->params=$params;return$this;}function
  1008. getParams(){return$this->params;}function
  1009. setPost(array$params){$this->updating();$this->post=$params;return$this;}function
  1010. getPost(){return$this->post;}function
  1011. setFiles(array$files){$this->updating();$this->files=$files;return$this;}function
  1012. getFiles(){return$this->files;}function
  1013. setMethod($method){$this->method=$method;return$this;}function
  1014. getMethod(){return$this->method;}function
  1015. isMethod($method){return
  1016. strcasecmp($this->method,$method)===0;}function
  1017. isPost(){return
  1018. strcasecmp($this->method,'post')===0;}function
  1019. setFlag($flag,$value=TRUE){$this->updating();$this->flags[$flag]=(bool)$value;return$this;}function
  1020. hasFlag($flag){return!empty($this->flags[$flag]);}}class
  1021. DownloadResponse
  1022. extends
  1023. NetteX\Object
  1024. implements
  1025. IPresenterResponse{private$file;private$contentType;private$name;function
  1026. __construct($file,$name=NULL,$contentType=NULL){if(!is_file($file)){throw
  1027. new
  1028. BadRequestException("File '$file' doesn't exist.");}$this->file=$file;$this->name=$name?$name:basename($file);$this->contentType=$contentType?$contentType:'application/octet-stream';}final
  1029. function
  1030. getFile(){return$this->file;}final
  1031. function
  1032. getName(){return$this->name;}final
  1033. function
  1034. getContentType(){return$this->contentType;}function
  1035. send(){NetteX\Environment::getHttpResponse()->setContentType($this->contentType);NetteX\Environment::getHttpResponse()->setHeader('Content-Disposition','attachment; filename="'.$this->name.'"');readfile($this->file);}}class
  1036. ForwardingResponse
  1037. extends
  1038. NetteX\Object
  1039. implements
  1040. IPresenterResponse{private$request;function
  1041. __construct(PresenterRequest$request){$this->request=$request;}final
  1042. function
  1043. getRequest(){return$this->request;}function
  1044. send(){}}class
  1045. JsonResponse
  1046. extends
  1047. NetteX\Object
  1048. implements
  1049. IPresenterResponse{private$payload;private$contentType;function
  1050. __construct($payload,$contentType=NULL){if(!is_array($payload)&&!($payload
  1051. instanceof\stdClass)){throw
  1052. new\InvalidArgumentException("Payload must be array or anonymous class, ".gettype($payload)." given.");}$this->payload=$payload;$this->contentType=$contentType?$contentType:'application/json';}final
  1053. function
  1054. getPayload(){return$this->payload;}function
  1055. send(){NetteX\Environment::getHttpResponse()->setContentType($this->contentType);NetteX\Environment::getHttpResponse()->setExpiration(FALSE);echo
  1056. NetteX\Json::encode($this->payload);}}class
  1057. RedirectingResponse
  1058. extends
  1059. NetteX\Object
  1060. implements
  1061. IPresenterResponse{private$uri;private$code;function
  1062. __construct($uri,$code=NetteX\Web\IHttpResponse::S302_FOUND){$this->uri=(string)$uri;$this->code=(int)$code;}final
  1063. function
  1064. getUri(){return$this->uri;}final
  1065. function
  1066. getCode(){return$this->code;}function
  1067. send(){NetteX\Environment::getHttpResponse()->redirect($this->uri,$this->code);}}class
  1068. RenderResponse
  1069. extends
  1070. NetteX\Object
  1071. implements
  1072. IPresenterResponse{private$source;function
  1073. __construct($source){$this->source=$source;}final
  1074. function
  1075. getSource(){return$this->source;}function
  1076. send(){if($this->source
  1077. instanceof
  1078. NetteX\Templates\ITemplate){$this->source->render();}else{echo$this->source;}}}class
  1079. CliRouter
  1080. extends
  1081. NetteX\Object
  1082. implements
  1083. IRouter{const
  1084. PRESENTER_KEY='action';private$defaults;function
  1085. __construct($defaults=array()){$this->defaults=$defaults;}function
  1086. match(NetteX\Web\IHttpRequest$httpRequest){if(empty($_SERVER['argv'])||!is_array($_SERVER['argv'])){return
  1087. NULL;}$names=array(self::PRESENTER_KEY);$params=$this->defaults;$args=$_SERVER['argv'];array_shift($args);$args[]='--';foreach($args
  1088. 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
  1089. new\XInvalidStateException('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
  1090. new
  1091. PresenterRequest($presenter,'CLI',$params);}function
  1092. constructUrl(PresenterRequest$appRequest,NetteX\Web\Uri$refUri){return
  1093. NULL;}function
  1094. getDefaults(){return$this->defaults;}}}namespace NetteX{use
  1095. NetteX;class
  1096. ArrayList
  1097. implements\ArrayAccess,\Countable,\IteratorAggregate{private$list=array();function
  1098. getIterator(){return
  1099. new\ArrayIterator($this->list);}function
  1100. count(){return
  1101. count($this->list);}function
  1102. offsetSet($index,$value){if($index===NULL){$this->list[]=$value;}elseif($index<0||$index>=count($this->list)){throw
  1103. new\OutOfRangeException("Offset invalid or out of range");}else{$this->list[(int)$index]=$value;}}function
  1104. offsetGet($index){if($index<0||$index>=count($this->list)){throw
  1105. new\OutOfRangeException("Offset invalid or out of range");}return$this->list[(int)$index];}function
  1106. offsetExists($index){return$index>=0&&$index<count($this->list);}function
  1107. offsetUnset($index){if($index<0||$index>=count($this->list)){throw
  1108. new\OutOfRangeException("Offset invalid or out of range");}array_splice($this->list,(int)$index,1);}}}namespace NetteX\Application{use
  1109. NetteX;class
  1110. MultiRouter
  1111. extends
  1112. NetteX\ArrayList
  1113. implements
  1114. IRouter{private$cachedRoutes;function
  1115. match(NetteX\Web\IHttpRequest$httpRequest){foreach($this
  1116. as$route){$appRequest=$route->match($httpRequest);if($appRequest!==NULL){return$appRequest;}}return
  1117. NULL;}function
  1118. constructUrl(PresenterRequest$appRequest,NetteX\Web\Uri$refUri){if($this->cachedRoutes===NULL){$routes=array();$routes['*']=array();foreach($this
  1119. as$route){$presenter=$route
  1120. instanceof
  1121. 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
  1122. 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,$refUri);if($uri!==NULL){return$uri;}}return
  1123. NULL;}function
  1124. offsetSet($index,$route){if(!($route
  1125. instanceof
  1126. IRouter)){throw
  1127. new\InvalidArgumentException("Argument must be IRouter descendant.");}parent::offsetSet($index,$route);}}use
  1128. NetteX\String;class
  1129. Route
  1130. extends
  1131. NetteX\Object
  1132. implements
  1133. IRouter{const
  1134. PRESENTER_KEY='presenter';const
  1135. MODULE_KEY='module';const
  1136. CASE_SENSITIVE=256;const
  1137. HOST=1;const
  1138. PATH=2;const
  1139. RELATIVE=3;const
  1140. VALUE='value';const
  1141. PATTERN='pattern';const
  1142. FILTER_IN='filterIn';const
  1143. FILTER_OUT='filterOut';const
  1144. FILTER_TABLE='filterTable';const
  1145. OPTIONAL=0;const
  1146. PATH_OPTIONAL=1;const
  1147. CONSTANT=2;public
  1148. static$defaultFlags=0;public
  1149. 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
  1150. __construct($mask,array$metadata=array(),$flags=0){$this->flags=$flags|self::$defaultFlags;$this->setMask($mask,$metadata);}function
  1151. match(NetteX\Web\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
  1152. NULL;}$path=(string)substr($uri->getPath(),strlen($basePath));}else{$path=$uri->getPath();}if($path!==''){$path=rtrim($path,'/').'/';}if(!$matches=String::match($path,$this->re)){return
  1153. NULL;}$params=array();foreach($matches
  1154. as$k=>$v){if(is_string($k)&&$v!==''){$params[str_replace('___','-',$k)]=$v;}}foreach($this->metadata
  1155. 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
  1156. 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
  1157. NULL;}}}elseif(isset($meta['fixity'])){$params[$name]=$meta[self::VALUE];}}if(!isset($params[self::PRESENTER_KEY])){throw
  1158. new\XInvalidStateException('Missing presenter in route definition.');}if(isset($this->metadata[self::MODULE_KEY])){if(!isset($params[self::MODULE_KEY])){throw
  1159. new\XInvalidStateException('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
  1160. new
  1161. PresenterRequest($presenter,$httpRequest->getMethod(),$params,$httpRequest->getPost(),$httpRequest->getFiles(),array(PresenterRequest::SECURED=>$httpRequest->isSecured()));}function
  1162. constructUrl(PresenterRequest$appRequest,NetteX\Web\Uri$refUri){if($this->flags&self::ONE_WAY){return
  1163. 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]='';}else{$params[self::MODULE_KEY]=substr($presenter,0,$a);$params[self::PRESENTER_KEY]=substr($presenter,$a+1);}}foreach($metadata
  1164. 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
  1165. 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
  1166. 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
  1167. 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='//'.$refUri->getAuthority().$refUri->getBasePath().$uri;}elseif($this->type===self::PATH){$uri='//'.$refUri->getAuthority().$uri;}if(strpos($uri,'//',2)!==FALSE){return
  1168. NULL;}$uri=($this->flags&self::SECURED?'https:':'http:').$uri;return$uri;}private
  1169. function
  1170. 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
  1171. as$name=>$meta){if(!is_array($meta)){$metadata[$name]=array(self::VALUE=>$meta,'fixity'=>self::CONSTANT);}elseif(array_key_exists(self::VALUE,$meta)){$metadata[$name]['fixity']=self::CONSTANT;}}$parts=String::split($mask,'/<([^># ]+) *([^>#]*)(#?[^>\[\]]*)>|(\[!?|\]|\s*\?.*)/');$this->xlat=array();$i=count($parts)-1;if(isset($parts[$i-1])&&substr(ltrim($parts[$i-1]),0,1)==='?'){$matches=String::matchAll($parts[$i-1],'/(?:([a-zA-Z0-9_.-]+)=)?<([^># ]+) *([^>#]*)(#?[^>]*)>/');foreach($matches
  1172. as$match){list(,$param,$name,$pattern,$class)=$match;if($class!==''){if(!isset(self::$styles[$class])){throw
  1173. new\XInvalidStateException("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]);$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
  1174. new\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
  1175. new\InvalidArgumentException("Parameter name must be alphanumeric string due to limitations of PCRE, '$name' given.");}if($class!==''){if(!isset(self::$styles[$class])){throw
  1176. new\XInvalidStateException("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
  1177. new\InvalidArgumentException("Missing closing ']' in mask '$mask'.");}$this->re='#'.$re.'/?$#A'.($this->flags&self::CASE_SENSITIVE?'':'iu');$this->metadata=$metadata;$this->sequence=$sequence;}function
  1178. getMask(){return$this->mask;}function
  1179. getDefaults(){$defaults=array();foreach($this->metadata
  1180. as$name=>$meta){if(isset($meta['fixity'])){$defaults[$name]=$meta[self::VALUE];}}return$defaults;}function
  1181. getTargetPresenter(){if($this->flags&self::ONE_WAY){return
  1182. 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
  1183. NULL;}}if(isset($m[self::PRESENTER_KEY]['fixity'])&&$m[self::PRESENTER_KEY]['fixity']===self::CONSTANT){return$module.$m[self::PRESENTER_KEY][self::VALUE];}return
  1184. NULL;}private
  1185. static
  1186. function
  1187. renameKeys($arr,$xlat){if(empty($xlat))return$arr;$res=array();$occupied=array_flip($xlat);foreach($arr
  1188. as$k=>$v){if(isset($xlat[$k])){$res[$xlat[$k]]=$v;}elseif(!isset($occupied[$k])){$res[$k]=$v;}}return$res;}private
  1189. static
  1190. function
  1191. action2path($s){$s=preg_replace('#(.)(?=[A-Z])#','$1-',$s);$s=strtolower($s);$s=rawurlencode($s);return$s;}private
  1192. static
  1193. function
  1194. path2action($s){$s=strtolower($s);$s=preg_replace('#-(?=[a-z])#',' ',$s);$s=substr(ucwords('x'.$s),1);$s=str_replace(' ','',$s);return$s;}private
  1195. static
  1196. function
  1197. presenter2path($s){$s=strtr($s,':','.');$s=preg_replace('#([^.])(?=[A-Z])#','$1-',$s);$s=strtolower($s);$s=rawurlencode($s);return$s;}private
  1198. static
  1199. function
  1200. 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
  1201. function
  1202. addStyle($style,$parent='#'){if(isset(self::$styles[$style])){throw
  1203. new\InvalidArgumentException("Style '$style' already exists.");}if($parent!==NULL){if(!isset(self::$styles[$parent])){throw
  1204. new\InvalidArgumentException("Parent style '$parent' doesn't exist.");}self::$styles[$style]=self::$styles[$parent];}else{self::$styles[$style]=array();}}static
  1205. function
  1206. setStyleProperty($style,$key,$value){if(!isset(self::$styles[$style])){throw
  1207. new\InvalidArgumentException("Style '$style' doesn't exist.");}self::$styles[$style][$key]=$value;}}class
  1208. SimpleRouter
  1209. extends
  1210. NetteX\Object
  1211. implements
  1212. IRouter{const
  1213. PRESENTER_KEY='presenter';const
  1214. MODULE_KEY='module';private$module='';private$defaults;private$flags;function
  1215. __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
  1216. match(NetteX\Web\IHttpRequest$httpRequest){if($httpRequest->getUri()->getPathInfo()!==''){return
  1217. NULL;}$params=$httpRequest->getQuery();$params+=$this->defaults;if(!isset($params[self::PRESENTER_KEY])){throw
  1218. new\XInvalidStateException('Missing presenter.');}$presenter=$this->module.$params[self::PRESENTER_KEY];unset($params[self::PRESENTER_KEY]);return
  1219. new
  1220. PresenterRequest($presenter,$httpRequest->getMethod(),$params,$httpRequest->getPost(),$httpRequest->getFiles(),array(PresenterRequest::SECURED=>$httpRequest->isSecured()));}function
  1221. constructUrl(PresenterRequest$appRequest,NetteX\Web\Uri$refUri){$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
  1222. NULL;}foreach($this->defaults
  1223. as$key=>$value){if(isset($params[$key])&&$params[$key]==$value){unset($params[$key]);}}$uri=($this->flags&self::SECURED?'https://':'http://').$refUri->getAuthority().$refUri->getPath();$sep=ini_get('arg_separator.input');$query=http_build_query($params,'',$sep?$sep[0]:'&');if($query!=''){$uri.='?'.$query;}return$uri;}function
  1224. getDefaults(){return$this->defaults;}}}namespace NetteX{class
  1225. DebugPanel
  1226. extends
  1227. Object
  1228. implements
  1229. IDebugPanel{private$id;private$tabCb;private$panelCb;function
  1230. __construct($id,$tabCb,$panelCb){$this->id=$id;$this->tabCb=$tabCb;$this->panelCb=$panelCb;}function
  1231. getId(){return$this->id;}function
  1232. getTab(){ob_start();call_user_func($this->tabCb,$this->id);return
  1233. ob_get_clean();}function
  1234. getPanel(){ob_start();call_user_func($this->panelCb,$this->id);return
  1235. ob_get_clean();}}}namespace NetteX\Application{use
  1236. NetteX;class
  1237. RoutingDebugger
  1238. extends
  1239. NetteX\DebugPanel{private$router;private$httpRequest;private$routers;private$request;function
  1240. __construct(IRouter$router,NetteX\Web\IHttpRequest$httpRequest){$this->router=$router;$this->httpRequest=$httpRequest;$this->routers=new\ArrayObject;parent::__construct('RoutingDebugger',array($this,'renderTab'),array($this,'renderPanel'));}function
  1241. renderTab(){$this->analyse($this->router);?>
  1242. <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJHSURBVDjLlZPNi81hFMc/z7137p1mTCFvNZfGSzLIWNjZKRvFRoqNhRCSYm8xS3+AxRRZ2JAFJWJHSQqTQkbEzYwIM+6Yid/znJfH4prLXShOnb6r8/nWOd8Tcs78bz0/f+KMu50y05nK/wy+uHDylbutqS5extvGcxaWqtoGDA8PZ3dnrs2srQc2Zko41UXLmLdyDW5OfvsUkUgbYGbU63UAQggdmvMzFmzZCgTi7CQmkZwdEaX0JwDgTnGbTCaE0G4zw80omhPI92lcEtkNkdgJCCHwJX7mZvNaB0A14SaYJlwTrpHsTkoFlV1nt2c3x5YYo1/vM9A/gKpxdfwyu/v3teCayKq4JEwT5EB2R6WgYmrs2bYbcUNNUVfEhIfFYy69uci+1fuRX84mkawFSxd/4nVWUopUVIykwlQxRTJBTIDA4Pp1jBZPuNW4wUAPmCqWIn29X1k4f5Ku8g9mpKCkakRLVEs1auVuauVuyqHMo8ejNCe+sWPVTkQKXCMmkeZUmUZjETF1tc6ooly+fgUVw9So1/tRN6YnZji46QghBFKKuAouERNhMlbAHZFE6e7pB+He8MMw+GGI4xtOMf1+lsl3TQ4NHf19BSlaO1DB9BfMHdX0O0iqSgiBbJkjm491hClJbA1LxCURgpPzXwAHhg63necAIi3XngXLcRU0fof8ETMljIyM5LGxMcbHxzvy/6fuXdWgt6+PWncv1e4euqo1ZmabvHs5+jn8yzufO7hiiZmuNpNBM13rbvVSpbrXJE7/BMkHtU9jFIC/AAAAAElFTkSuQmCC"
  1243. /><?php if(empty($this->request)):?>no route<?php else:echo$this->request->getPresenterName().':'.(isset($this->request->params[Presenter::ACTION_KEY])?$this->request->params[Presenter::ACTION_KEY]:Presenter::$defaultAction);endif?>
  1244. <?php }function
  1245. renderPanel(){?>
  1246. <style>#nette-debug-RoutingDebugger table{font:9pt/1.5 Consolas,monospace}#nette-debug-RoutingDebugger .yes td{color:green}#nette-debug-RoutingDebugger .may td{color:#67F}#nette-debug-RoutingDebugger pre,#nette-debug-RoutingDebugger code{display:inline}</style>
  1247. <h1>
  1248. <?php if(empty($this->request)):?>
  1249. no route
  1250. <?php else:?>
  1251. <?php echo$this->request->getPresenterName().':'.(isset($this->request->params[Presenter::ACTION_KEY])?$this->request->params[Presenter::ACTION_KEY]:Presenter::$defaultAction)?>
  1252. <?php endif?>
  1253. </h1>
  1254. <?php if(!empty($this->request)):?>
  1255. <?php $params=$this->request->getParams()?>
  1256. <?php if(empty($params)):?>
  1257. <p>No parameters.</p>
  1258. <?php else:?>
  1259. <table>
  1260. <thead>
  1261. <tr>
  1262. <th>Parameter</th>
  1263. <th>Value</th>
  1264. </tr>
  1265. </thead>
  1266. <tbody>
  1267. <?php unset($params[Presenter::ACTION_KEY])?>
  1268. <?php foreach($params
  1269. as$key=>$value):?>
  1270. <tr>
  1271. <td><code><?php echo
  1272. htmlSpecialChars($key)?></code></td>
  1273. <td><?php if(is_string($value)):?><code><?php echo
  1274. htmlSpecialChars($value)?></code><?php else:echo
  1275. NetteX\Debug::dump($value,TRUE);endif?></td>
  1276. </tr>
  1277. <?php endforeach?>
  1278. </tbody>
  1279. </table>
  1280. <?php endif?>
  1281. <?php endif?>
  1282. <h2>Routers</h2>
  1283. <?php if(empty($this->routers)):?>
  1284. <p>No routers defined.</p>
  1285. <?php else:?>
  1286. <div class="nette-inner">
  1287. <table>
  1288. <thead>
  1289. <tr>
  1290. <th>Matched?</th>
  1291. <th>Class</th>
  1292. <th>Mask</th>
  1293. <th>Defaults</th>
  1294. <th>Request</th>
  1295. </tr>
  1296. </thead>
  1297. <tbody>
  1298. <?php foreach($this->routers
  1299. as$router):?>
  1300. <tr class="<?php echo$router['matched']?>">
  1301. <td><?php echo$router['matched']?></td>
  1302. <td><code><?php echo
  1303. htmlSpecialChars($router['class'])?></code></td>
  1304. <td><code><strong><?php echo
  1305. htmlSpecialChars($router['mask'])?></strong></code></td>
  1306. <td><code>
  1307. <?php foreach($router['defaults']as$key=>$value):?>
  1308. <?php echo
  1309. htmlSpecialChars($key),"&nbsp;=&nbsp;",is_string($value)?htmlSpecialChars($value):str_replace("\n</pre",'</pre',NetteX\Debug::dump($value,TRUE))?><br />
  1310. <?php endforeach?>
  1311. </code></td>
  1312. <td><?php if($router['request']):?><code>
  1313. <?php $params=$router['request']->getParams();?>
  1314. <strong><?php echo
  1315. htmlSpecialChars($router['request']->getPresenterName().':'.(isset($params[Presenter::ACTION_KEY])?$params[Presenter::ACTION_KEY]:Presenter::$defaultAction))?></strong><br />
  1316. <?php unset($params[Presenter::ACTION_KEY])?>
  1317. <?php foreach($params
  1318. as$key=>$value):?>
  1319. <?php echo
  1320. htmlSpecialChars($key),"&nbsp;=&nbsp;",is_string($value)?htmlSpecialChars($value):str_replace("\n</pre",'</pre',NetteX\Debug::dump($value,TRUE))?><br />
  1321. <?php endforeach?>
  1322. </code><?php endif?></td>
  1323. </tr>
  1324. <?php endforeach?>
  1325. </tbody>
  1326. </table>
  1327. </div>
  1328. <?php endif?>
  1329. <?php }private
  1330. function
  1331. analyse($router){if($router
  1332. instanceof
  1333. MultiRouter){foreach($router
  1334. as$subRouter){$this->analyse($subRouter);}return;}$request=$router->match($this->httpRequest);$matched=$request===NULL?'no':'may';if($request!==NULL&&empty($this->request)){$this->request=$request;$matched='yes';}$this->routers[]=array('matched'=>$matched,'class'=>get_class($router),'defaults'=>$router
  1335. instanceof
  1336. Route||$router
  1337. instanceof
  1338. SimpleRouter?$router->getDefaults():array(),'mask'=>$router
  1339. instanceof
  1340. Route?$router->getMask():NULL,'request'=>$request);}}}namespace NetteX\Caching{use
  1341. NetteX;class
  1342. Cache
  1343. extends
  1344. NetteX\Object
  1345. implements\ArrayAccess{const
  1346. PRIORITY='priority';const
  1347. EXPIRATION='expire';const
  1348. EXPIRE='expire';const
  1349. SLIDING='sliding';const
  1350. TAGS='tags';const
  1351. FILES='files';const
  1352. ITEMS='items';const
  1353. CONSTS='consts';const
  1354. CALLBACKS='callbacks';const
  1355. ALL='all';const
  1356. NAMESPACE_SEPARATOR="\x00";private$storage;private$namespace;private$key;private$data;function
  1357. __construct(ICacheStorage$storage,$namespace=NULL){$this->storage=$storage;$this->namespace=(string)$namespace;if(strpos($this->namespace,self::NAMESPACE_SEPARATOR)!==FALSE){throw
  1358. new\InvalidArgumentException("Namespace name contains forbidden NUL character.");}}function
  1359. getStorage(){return$this->storage;}function
  1360. getNamespace(){return$this->namespace;}function
  1361. release(){$this->key=$this->data=NULL;}function
  1362. save($key,$data,array$dp=NULL){if(!is_string($key)&&!is_int($key)){throw
  1363. new\InvalidArgumentException("Cache key name must be string or integer, ".gettype($key)." given.");}$this->key=(string)$key;$key=$this->namespace.self::NAMESPACE_SEPARATOR.$key;if(isset($dp[Cache::EXPIRATION])){$dp[Cache::EXPIRATION]=NetteX\Tools::createDateTime($dp[Cache::EXPIRATION])->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($data
  1364. instanceof
  1365. NetteX\Callback||$data
  1366. instanceof\Closure){NetteX\Tools::enterCriticalSection();$data=$data->__invoke();NetteX\Tools::leaveCriticalSection();}if(is_object($data)){$dp[self::CALLBACKS][]=array(array(__CLASS__,'checkSerializationVersion'),get_class($data),NetteX\Reflection\ClassReflection::from($data)->getAnnotation('serializationVersion'));}$this->data=$data;if($data===NULL){$this->storage->remove($key);}else{$this->storage->write($key,$data,(array)$dp);}return$data;}function
  1367. clean(array$conds=NULL){$this->release();$this->storage->clean((array)$conds);}function
  1368. offsetSet($key,$data){$this->save($key,$data);}function
  1369. offsetGet($key){if(!is_string($key)&&!is_int($key)){throw
  1370. new\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
  1371. offsetExists($key){return$this->offsetGet($key)!==NULL;}function
  1372. offsetUnset($key){$this->save($key,NULL);}static
  1373. function
  1374. checkCallbacks($callbacks){foreach($callbacks
  1375. as$callback){$func=array_shift($callback);if(!call_user_func_array($func,$callback)){return
  1376. FALSE;}}return
  1377. TRUE;}private
  1378. static
  1379. function
  1380. checkConst($const,$value){return
  1381. defined($const)&&constant($const)===$value;}private
  1382. static
  1383. function
  1384. checkFile($file,$time){return@filemtime($file)==$time;}private
  1385. static
  1386. function
  1387. checkSerializationVersion($class,$value){return
  1388. NetteX\Reflection\ClassReflection::from($class)->getAnnotation('serializationVersion')===$value;}}class
  1389. DummyStorage
  1390. extends
  1391. NetteX\Object
  1392. implements
  1393. ICacheStorage{function
  1394. read($key){}function
  1395. write($key,$data,array$dp){}function
  1396. remove($key){}function
  1397. clean(array$conds){}}class
  1398. FileJournal
  1399. extends
  1400. NetteX\Object
  1401. implements
  1402. ICacheJournal{const
  1403. MAGIC=0x666a3030,FILE='fj',EXTNEW='.new',EXTLOG='.log',EXTLOGNEW='.log.new',LOGMAXSIZE=65536,INT32=4,TAGS=0x74616773,PRIORITY=0x7072696f,ENTRIES=0x656e7473,DELETE='d',ADD='a',CLEAN='c';private
  1404. static$ops=array(self::ADD=>self::DELETE,self::DELETE=>self::ADD);private$file;private$handle;private$mtime=0;private$sections=array();private$logHandle;private$isLogNew=FALSE;private$logMerge=array();private$logMergeP=0;function
  1405. __construct($dir){$this->file=$dir.'/'.self::FILE;$this->open();}function
  1406. __destruct(){if($this->handle){fclose($this->handle);}if($this->logHandle){fclose($this->logHandle);}}private
  1407. function
  1408. reload(){if(($mtime=@filemtime($this->file))===FALSE){$mtime=0;}if($this->mtime<$mtime){fclose($this->handle);fclose($this->logHandle);$this->handle=$this->logHandle=NULL;$this->open();}$this->logMerge=$this->mergeLogFile($this->logHandle,$this->logMergeP,$this->logMerge);}private
  1409. function
  1410. open(){$this->handle=$this->logHandle=NULL;$this->mtime=$this->logMergeP=0;$this->sections=$this->logMerge=array();clearstatcache();if(($this->mtime=@filemtime($this->file))===FALSE){$this->mtime=0;}$tries=3;do{if(!$tries--){throw
  1411. new\XInvalidStateException("Cannot open journal file '$this->file'.");}if(!($this->handle=@fopen($this->file,'rb'))){$this->handle=NULL;}else{list(,$magic,$sectionCount)=unpack('N2',fread($this->handle,2*self::INT32));if($magic!==self::MAGIC){fclose($this->handle);throw
  1412. new\XInvalidStateException("Malformed journal file '$this->file'.");}for($i=0;$i<$sectionCount;++$i){list(,$name,$offset,$keyLength,$keyCount)=unpack('N4',fread($this->handle,4*self::INT32));$this->sections[$name]=(object)array('offset'=>$offset,'keyLength'=>$keyLength,'keyCount'=>$keyCount);}}clearstatcache();if(($mtime=@filemtime($this->file))===FALSE){$mtime=0;}}while($this->mtime<$mtime);if(!($this->logHandle=@fopen($logfile=$this->file.self::EXTLOG,'a+b'))){throw
  1413. new\XInvalidStateException("Cannot open logfile '$logfile' for journal.");}$doMergeFirst=FALSE;$openNewLog=FALSE;$reopen=FALSE;if(flock($this->logHandle,LOCK_SH|LOCK_NB)){if(file_exists($logfile=$this->file.self::EXTLOGNEW)){if(($logmtime=@filemtime($this->file.self::EXTLOG))===FALSE){throw
  1414. new\XInvalidStateException("Cannot determine modification time of logfile '$this->file".self::EXTLOG."'.");}if($logmtime<$this->mtime){fclose($this->logHandle);if(!@rename($this->file.self::EXTLOGNEW,$this->file.self::EXTLOG)){clearstatcache();if(!file_exists($this->file.self::EXTLOGNEW)){$reopen=TRUE;}else{$openNewLog=TRUE;}}else{$reopen=TRUE;}}else{if(!$this->rebuild()){$doMergeFirst=TRUE;$openNewLog=TRUE;}}}}else{$doMergeFirst=TRUE;$openNewLog=TRUE;}if($reopen&&$openNewLog){throw
  1415. new\LogicException('Something bad with algorithm.');}if($doMergeFirst){$this->logMerge=$this->mergeLogFile($this->logHandle,0);}if($reopen){fclose($this->logHandle);if(!($this->logHandle=@fopen($logfile=$this->file.self::EXTLOG,'a+b'))){throw
  1416. new\XInvalidStateException("Cannot open logfile '$logfile'.");}if(!flock($this->logHandle,LOCK_SH)){throw
  1417. new\XInvalidStateException('Cannot acquite shared lock on log.');}}if($openNewLog){fclose($this->logHandle);if(!($this->logHandle=@fopen($logfile=$this->file.self::EXTLOGNEW,'a+b'))){throw
  1418. new\XInvalidStateException("Cannot open logfile '$logfile'.");}$this->isLogNew=TRUE;}$this->logMerge=$this->mergeLogFile($this->logHandle,0,$this->logMerge);$this->logMergeP=ftell($this->logHandle);if($this->logMergeP===0){if(!flock($this->logHandle,LOCK_EX)){throw
  1419. new\XInvalidStateException('Cannot acquite exclusive lock on log.');}$data=serialize(array());$data=pack('N',strlen($data)).$data;$written=fwrite($this->logHandle,$data);if($written===FALSE||$written!==strlen($data)){throw
  1420. new\XInvalidStateException('Cannot write empty packet to log.');}if(!flock($this->logHandle,LOCK_SH)){throw
  1421. new\XInvalidStateException('Cannot acquite shared lock on log.');}}}function
  1422. write($key,array$dependencies){$log=array();$delete=$this->get(self::ENTRIES,$key);if($delete!==NULL&&isset($delete[$key])){foreach($delete[$key]as$id){list($sectionName,$k)=explode(':',$id,2);$sectionName=intval($sectionName);if(!isset($log[$sectionName])){$log[$sectionName]=array();}if(!isset($log[$sectionName][self::DELETE])){$log[$sectionName][self::DELETE]=array();}$log[$sectionName][self::DELETE][$k][]=$key;}}if(!empty($dependencies[Cache::TAGS])){if(!isset($log[self::TAGS])){$log[self::TAGS]=array();}if(!isset($log[self::TAGS][self::ADD])){$log[self::TAGS][self::ADD]=array();}foreach((array)$dependencies[Cache::TAGS]as$tag){$log[self::TAGS][self::ADD][$tag]=(array)$key;}}if(!empty($dependencies[Cache::PRIORITY])){if(!isset($log[self::PRIORITY])){$log[self::PRIORITY]=array();}if(!isset($log[self::PRIORITY][self::ADD])){$log[self::PRIORITY][self::ADD]=array();}$log[self::PRIORITY][self::ADD][sprintf('%010u',(int)$dependencies[Cache::PRIORITY])]=(array)$key;}if(empty($log)){return;}$entriesSection=array(self::ADD=>array());foreach($log
  1423. as$sectionName=>$section){if(!isset($section[self::ADD])){continue;}foreach($section[self::ADD]as$k=>$_){$entriesSection[self::ADD][$key][]="$sectionName:$k";}}$entriesSection[self::ADD][$key][]=self::ENTRIES.':'.$key;$log[self::ENTRIES]=$entriesSection;$this->log($log);}private
  1424. function
  1425. log(array$data){$data=$this->mergeLogRecords(array(),$data);$data=serialize($data);$data=pack('N',strlen($data)).$data;$written=fwrite($this->logHandle,$data);if($written===FALSE||$written!==strlen($data)){throw
  1426. new\XInvalidStateException('Cannot write to log.');}if(!$this->isLogNew){fseek($this->logHandle,0,SEEK_END);$size=ftell($this->logHandle);if($size>self::LOGMAXSIZE){$this->rebuild();}}return
  1427. TRUE;}private
  1428. function
  1429. rebuild(){if(!flock($this->logHandle,LOCK_EX|LOCK_NB)){return
  1430. TRUE;}if(!($newhandle=@fopen($this->file.self::EXTNEW,'wb'))){flock($this->logHandle,LOCK_UN);return
  1431. FALSE;}$merged=$this->mergeLogFile($this->logHandle);$sections=array_unique(array_merge(array_keys($this->sections),array_keys($merged)),SORT_NUMERIC);sort($sections);$offset=4096;$newsections=array();foreach($sections
  1432. as$section){$maxKeyLength=0;$keyCount=0;if(isset($this->sections[$section])){$maxKeyLength=$this->sections[$section]->keyLength;$keyCount=$this->sections[$section]->keyCount;}if(isset($merged[$section][self::ADD])){foreach($merged[$section][self::ADD]as$k=>$_){if(($len=strlen((string)$k))>$maxKeyLength){$maxKeyLength=$len;}$keyCount++;}}$newsections[$section]=(object)array('keyLength'=>$maxKeyLength,'keyCount'=>$keyCount,'offset'=>$offset);$offset+=$keyCount*($maxKeyLength+2*self::INT32);}$dataOffset=$offset;$dataWrite=array();$clean=isset($merged[self::CLEAN]);unset($merged[self::CLEAN]);foreach($sections
  1433. as$section){fseek($newhandle,$newsections[$section]->offset,SEEK_SET);$pack='a'.$newsections[$section]->keyLength.'NN';$realKeyCount=0;foreach(self::$ops
  1434. as$op){if(isset($merged[$section][$op])){reset($merged[$section][$op]);}}if($this->handle&&isset($this->sections[$section])&&!$clean){$unpack='a'.$this->sections[$section]->keyLength.'key/NvalueOffset/NvalueLength';$recordSize=$this->sections[$section]->keyLength+2*self::INT32;$batchSize=intval(65536/$recordSize);$i=0;while($i<$this->sections[$section]->keyCount){fseek($this->handle,$this->sections[$section]->offset+$i*$recordSize,SEEK_SET);$size=min($batchSize,$this->sections[$section]->keyCount-$i);$data=stream_get_contents($this->handle,$size*$recordSize);if(!($data!==FALSE&&strlen($data)===$size*$recordSize)){flock($this->logHandle,LOCK_UN);fclose($newhandle);return
  1435. FALSE;}for($j=0;$j<$size&&$i<$this->sections[$section]->keyCount;++$j,++$i){$record=(object)unpack($unpack,substr($data,$j*$recordSize,$recordSize));$value=NULL;if(isset($merged[$section][self::DELETE])){while(current($merged[$section][self::DELETE])&&strcmp(key($merged[$section][self::DELETE]),$record->key)<0){next($merged[$section][self::DELETE]);}if(strcmp(key($merged[$section][self::DELETE]),$record->key)===0){fseek($this->handle,$record->valueOffset,SEEK_SET);$value=@unserialize(fread($this->handle,$record->valueLength));if($value===FALSE){flock($this->logHandle,LOCK_UN);fclose($newhandle);return
  1436. FALSE;}$value=array_flip($value);foreach(current($merged[$section][self::DELETE])as$delete){unset($value[$delete]);}$value=array_keys($value);next($merged[$section][self::DELETE]);}}if(isset($merged[$section][self::ADD])){while(current($merged[$section][self::ADD])&&strcmp(key($merged[$section][self::ADD]),$record->key)<0){$dataWrite[]=($serialized=serialize(current($merged[$section][self::ADD])));$packed=pack($pack,key($merged[$section][self::ADD]),$dataOffset,strlen($serialized));if(!$this->writeAll($newhandle,$packed)){flock($this->logHandle,LOCK_UN);fclose($newhandle);return
  1437. FALSE;}$realKeyCount++;$dataOffset+=strlen($serialized);next($merged[$section][self::ADD]);}if(strcmp(key($merged[$section][self::ADD]),$record->key)===0){if($value===NULL){$value=$this->loadValue($this->handle,$record->valueOffset,$record->valueLength);}if($value===NULL){flock($this->logHandle,LOCK_UN);fclose($newhandle);return
  1438. FALSE;}$value=array_unique(array_merge($value,current($merged[$section][self::ADD])));sort($value);next($merged[$section][self::ADD]);}}if(is_array($value)&&!empty($value)||$value===NULL){if($value!==NULL){$dataWrite[]=($serialized=serialize($value));$newValueLength=strlen($serialized);}else{$dataWrite[]=array($record->valueOffset,$record->valueLength);$newValueLength=$record->valueLength;}if(!$this->writeAll($newhandle,pack($pack,$record->key,$dataOffset,$newValueLength))){flock($this->logHandle,LOCK_UN);fclose($newhandle);return
  1439. FALSE;}$realKeyCount++;$dataOffset+=$newValueLength;}}}}while(isset($merged[$section][self::ADD])&&current($merged[$section][self::ADD])){$dataWrite[]=($serialized=serialize(current($merged[$section][self::ADD])));$valueLength=strlen($serialized);$packed=pack($pack,key($merged[$section][self::ADD]),$dataOffset,$valueLength);if(!$this->writeAll($newhandle,$packed)){flock($this->logHandle,LOCK_UN);fclose($newhandle);return
  1440. FALSE;}$realKeyCount++;$dataOffset+=$valueLength;next($merged[$section][self::ADD]);}$newsections[$section]->keyCount=$realKeyCount;if($realKeyCount<1){unset($newsections[$section]);}}fseek($newhandle,0,SEEK_SET);$data=pack('NN',self::MAGIC,count($newsections));foreach($newsections
  1441. as$name=>$section){$data.=pack('NNNN',$name,$section->offset,$section->keyLength,$section->keyCount);}if(!$this->writeAll($newhandle,$data)){flock($this->logHandle,LOCK_UN);fclose($newhandle);return
  1442. FALSE;}fseek($newhandle,$offset,SEEK_SET);reset($dataWrite);while(!empty($dataWrite)){$data=array_shift($dataWrite);if(is_string($data)){while(is_string(current($dataWrite))){$data.=array_shift($dataWrite);}if(!$this->writeAll($newhandle,$data)){flock($this->logHandle,LOCK_UN);fclose($newhandle);return
  1443. FALSE;}}else{if(!is_array($data)){throw
  1444. new\LogicException('Something bad with algorithm, it has to be array.');}list($readOffset,$readLength)=$data;while(!empty($dataWrite)&&is_array(current($dataWrite))){list($nextReadOffset,$nextReadLength)=current($dataWrite);if($readOffset+$readLength!==$nextReadOffset){break;}$readLength+=$nextReadLength;array_shift($dataWrite);}fseek($this->handle,$readOffset,SEEK_SET);while(($readLength-=stream_copy_to_stream($this->handle,$newhandle,$readLength))>0);}}fflush($newhandle);fclose($newhandle);$newhandle=NULL;if($this->handle){fclose($this->handle);$this->handle=NULL;}if(!@rename($this->file.self::EXTNEW,$this->file)){flock($this->logHandle,LOCK_UN);return
  1445. FALSE;}ftruncate($this->logHandle,4+strlen(serialize(array())));flock($this->logHandle,LOCK_UN);fclose($this->logHandle);if(!@rename($this->file.self::EXTLOGNEW,$this->file.self::EXTLOG)&&file_exists($this->file.self::EXTLOGNEW)){$this->isLogNew=TRUE;$logfile=$this->file.self::EXTLOGNEW;}else{$logfile=$this->file.self::EXTLOG;}if(!($this->logHandle=@fopen($logfile,'a+b'))){throw
  1446. new\XInvalidStateException("Cannot reopen logfile '$logfile'.");}$this->logMerge=array();$this->logMergeP=0;if(!($this->handle=@fopen($this->file,'rb'))){throw
  1447. new\XInvalidStateException("Cannot reopen file '$this->file'.");}clearstatcache();$this->mtime=(int)@filemtime($this->file);$this->sections=$newsections;return
  1448. TRUE;}private
  1449. function
  1450. writeAll($handle,$data){$bytesLeft=strlen($data);while($bytesLeft>0){$written=fwrite($handle,substr($data,strlen($data)-$bytesLeft));if($written===FALSE){return
  1451. FALSE;}$bytesLeft-=$written;}return
  1452. TRUE;}private
  1453. function
  1454. loadValue($handle,$offset,$length){fseek($handle,$offset,SEEK_SET);$data='';$bytesLeft=$length;while($bytesLeft>0){$read=fread($handle,$bytesLeft);if($read===FALSE){return
  1455. NULL;}$data.=$read;$bytesLeft-=strlen($read);}$value=@unserialize($data);if($value===FALSE){return
  1456. NULL;}return$value;}private
  1457. function
  1458. mergeLogFile($handle,$startp=0,$merged=array()){fseek($handle,$startp,SEEK_SET);while(!feof($handle)&&strlen($data=fread($handle,self::INT32))===self::INT32){list(,$size)=unpack('N',$data);$data=@unserialize(fread($handle,$size));if($data===FALSE){continue;}$merged=$this->mergeLogRecords($merged,$data);}ksort($merged);return$merged;}private
  1459. function
  1460. mergeLogRecords(array$a,array$b){$clean=isset($a[self::CLEAN]);unset($a[self::CLEAN],$b[self::CLEAN]);if(isset($b[self::CLEAN])){return$b;}foreach($b
  1461. as$section=>$data){if(!isset($a[$section])){$a[$section]=array();}foreach(self::$ops
  1462. as$op){if(!isset($data[$op])){continue;}if(!isset($a[$section][$op])){$a[$section][$op]=array();}foreach($data[$op]as$k=>$v){if(!isset($a[$section][$op][$k])){$a[$section][$op][$k]=array();}$a[$section][$op][$k]=array_unique(array_merge($a[$section][$op][$k],$v));if(isset($a[$section][self::$ops[$op]][$k])){$a[$section][self::$ops[$op]][$k]=array_flip($a[$section][self::$ops[$op]][$k]);foreach($v
  1463. as$unsetk){unset($a[$section][self::$ops[$op]][$k][$unsetk]);}$a[$section][self::$ops[$op]][$k]=array_keys($a[$section][self::$ops[$op]][$k]);}}}foreach(self::$ops
  1464. as$op){if(!isset($a[$section][$op])){continue;}foreach($a[$section][$op]as$k=>$v){if(empty($v)){unset($a[$section][$op][$k]);continue;}sort($a[$section][$op][$k]);}if(empty($a[$section][$op])){unset($a[$section][$op]);continue;}ksort($a[$section][$op]);}}if($clean){$a[self::CLEAN]=TRUE;}return$a;}function
  1465. clean(array$conditions){if(!empty($conditions[Cache::ALL])){$this->log(array(self::CLEAN=>TRUE));return
  1466. NULL;}else{$log=array();$entries=array();if(!empty($conditions[Cache::TAGS])){$tagEntries=array();foreach((array)$conditions[Cache::TAGS]as$tag){$tagEntries=array_merge($tagEntries,$tagEntry=$this->get(self::TAGS,$tag));if(isset($tagEntry[$tag])){foreach($tagEntry[$tag]as$entry){$entries[]=$entry;}}}if(!empty($tagEntries)){if(!isset($log[self::TAGS])){$log[self::TAGS]=array();}$log[self::TAGS][self::DELETE]=$tagEntries;}}if(isset($conditions[Cache::PRIORITY])){$priorityEntries=$this->getLte(self::PRIORITY,sprintf('%010u',(int)$conditions[Cache::PRIORITY]));foreach($priorityEntries
  1467. as$priorityEntry){foreach($priorityEntry
  1468. as$entry){$entries[]=$entry;}}if(!empty($priorityEntries)){if(!isset($log[self::PRIORITY])){$log[self::PRIORITY]=array();}$log[self::PRIORITY][self::DELETE]=$priorityEntries;}}if(!empty($log)){if(!$this->log($log)){return
  1469. array();}}return
  1470. array_values(array_unique($entries));}}private
  1471. function
  1472. get($section,$key){$this->reload();$ret=$this->logMerge;if(!isset($ret[self::CLEAN])){list($offset,$record)=$this->lowerBound($section,$key);if($offset!==-1&&$record->key===$key&&!isset($ret[self::CLEAN])){$entries=$this->loadValue($this->handle,$record->valueOffset,$record->valueLength);$ret=$this->mergeLogRecords(array($section=>array(self::ADD=>array($key=>$entries))),$ret);}}return
  1473. isset($ret[$section][self::ADD][$key])?array($key=>$ret[$section][self::ADD][$key]):array();}private
  1474. function
  1475. getLte($section,$key){$this->reload();$ret=array();if(!isset($this->logMerge[self::CLEAN])){list($offset,$record)=$this->lowerBound($section,$key);if($offset!==-1){$unpack='a'.$this->sections[$section]->keyLength.'key/NvalueOffset/NvalueLength';$recordSize=$this->sections[$section]->keyLength+2*self::INT32;$batchSize=intval(65536/$recordSize);$i=0;$count=($offset-$this->sections[$section]->offset)/$recordSize;if($record->key===$key){$count+=1;}while($i<$count){fseek($this->handle,$this->sections[$section]->offset+$i*$recordSize,SEEK_SET);$size=min($batchSize,$count-$i);$data=stream_get_contents($this->handle,$size*$recordSize);if(!($data!==FALSE&&strlen($data)===$size*$recordSize)){return
  1476. NULL;}for($j=0;$j<$size&&$i<$count;++$j,++$i){$record=(object)unpack($unpack,substr($data,$j*$recordSize,$recordSize));$ret[$record->key]=$this->loadValue($this->handle,$record->valueOffset,$record->valueLength);if($ret[$record->key]===NULL){unset($ret[$record->key]);}}}}}if(isset($this->logMerge[$section][self::DELETE])){$ret=$this->mergeLogRecords(array($section=>array(self::DELETE=>$this->logMerge[$section][self::DELETE])),array($section=>array(self::ADD=>$ret)));if(!isset($ret[$section][self::ADD])){$ret=array();}else{$ret=$ret[$section][self::ADD];}}if(isset($this->logMerge[$section][self::ADD])){foreach($this->logMerge[$section][self::ADD]as$k=>$v){if(strcmp($k,$key)>0){continue;}if(!isset($ret[$k])){$ret[$k]=array();}$ret[$k]=array_values(array_unique(array_merge($ret[$k],$v)));}}return$ret;}private
  1477. function
  1478. lowerBound($section,$key){if(!isset($this->sections[$section])){return
  1479. array(-1,NULL);}$l=0;$r=$this->sections[$section]->keyCount;$unpack='a'.$this->sections[$section]->keyLength.'key/NvalueOffset/NvalueLength';$recordSize=$this->sections[$section]->keyLength+2*self::INT32;while($l<$r){$m=intval(($l+$r)/2);fseek($this->handle,$this->sections[$section]->offset+$m*$recordSize);$data=stream_get_contents($this->handle,$recordSize);if(!($data!==FALSE&&strlen($data)===$recordSize)){return
  1480. array(-1,NULL);}$record=(object)unpack($unpack,$data);if(strcmp($record->key,$key)<0){$l=$m+1;}else{$r=$m;}}fseek($this->handle,$this->sections[$section]->offset+$l*$recordSize);$data=stream_get_contents($this->handle,$recordSize);if(!($data!==FALSE&&strlen($data)===$recordSize)){return
  1481. array(-1,NULL);}$record=(object)unpack($unpack,$data);return
  1482. array($this->sections[$section]->offset+$l*$recordSize,$record);}}class
  1483. FileStorage
  1484. extends
  1485. NetteX\Object
  1486. implements
  1487. ICacheStorage{const
  1488. META_HEADER_LEN=28;const
  1489. META_TIME='time';const
  1490. META_SERIALIZED='serialized';const
  1491. META_EXPIRE='expire';const
  1492. META_DELTA='delta';const
  1493. META_ITEMS='di';const
  1494. META_CALLBACKS='callbacks';const
  1495. FILE='file';const
  1496. HANDLE='handle';public
  1497. static$gcProbability=0.001;public
  1498. static$useDirectories;private$dir;private$useDirs;private$context;function
  1499. __construct($dir,NetteX\Context$context=NULL){if(self::$useDirectories===NULL){$uniq=uniqid('_',TRUE);umask(0000);if(!@mkdir("$dir/$uniq",0777)){throw
  1500. new\XInvalidStateException("Unable to write to directory '$dir'. Make this directory writable.");}self::$useDirectories=!ini_get('safe_mode');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;$this->context=$context;if(mt_rand()/mt_getrandmax()<self::$gcProbability){$this->clean(array());}}function
  1501. read($key){$meta=$this->readMeta($this->getCacheFile($key),LOCK_SH);if($meta&&$this->verify($meta)){return$this->readData($meta);}else{return
  1502. NULL;}}private
  1503. function
  1504. 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
  1505. 2;if($m&&!$this->verify($m))break
  1506. 2;}}return
  1507. TRUE;}while(FALSE);$this->delete($meta[self::FILE],$meta[self::HANDLE]);return
  1508. FALSE;}function
  1509. write($key,$data,array$dp){$meta=array(self::META_TIME=>microtime());if(isset($dp[Cache::EXPIRATION])){if(empty($dp[Cache::SLIDING])){$meta[self::META_EXPIRE]=$dp[Cache::EXPIRATION]+time();}else{$meta[self::META_DELTA]=(int)$dp[Cache::EXPIRATION];}}if(isset($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(isset($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)){return;}}$handle=@fopen($cacheFile,'r+b');if(!$handle){$handle=fopen($cacheFile,'wb');if(!$handle){return;}}if(isset($dp[Cache::TAGS])||isset($dp[Cache::PRIORITY])){if(!$this->context){throw
  1510. new\XInvalidStateException('CacheJournal has not been provided.');}$this->getJournal()->write($cacheFile,$dp);}flock($handle,LOCK_EX);ftruncate($handle,0);if(!is_string($data)){$data=serialize($data);$meta[self::META_SERIALIZED]=TRUE;}$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
  1511. TRUE;}while(FALSE);$this->delete($cacheFile,$handle);}function
  1512. remove($key){$this->delete($this->getCacheFile($key));}function
  1513. clean(array$conds){$all=!empty($conds[Cache::ALL]);$collector=empty($conds);if($all||$collector){$now=time();foreach(NetteX\Finder::find('*')->from($this->dir)->childFirst()as$entry){$path=(string)$entry;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($this->context){$this->getJournal()->clean($conds);}return;}if($this->context){foreach($this->getJournal()->clean($conds)as$file){$this->delete($file);}}}protected
  1514. function
  1515. readMeta($file,$lock){$handle=@fopen($file,'r+b');if(!$handle)return
  1516. 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
  1517. NULL;}protected
  1518. function
  1519. 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
  1520. function
  1521. getCacheFile($key){if($this->useDirs){$key=explode(Cache::NAMESPACE_SEPARATOR,$key,2);return$this->dir.'/'.(isset($key[1])?urlencode($key[0]).'/_'.urlencode($key[1]):'_'.urlencode($key[0]));}else{return$this->dir.'/_'.urlencode($key);}}private
  1522. static
  1523. function
  1524. 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
  1525. function
  1526. getJournal(){return$this->context->getService('NetteX\\Caching\\ICacheJournal');}}class
  1527. MemcachedStorage
  1528. extends
  1529. NetteX\Object
  1530. implements
  1531. ICacheStorage{const
  1532. META_CALLBACKS='callbacks';const
  1533. META_DATA='data';const
  1534. META_DELTA='delta';private$memcache;private$prefix;private$context;static
  1535. function
  1536. isAvailable(){return
  1537. extension_loaded('memcache');}function
  1538. __construct($host='localhost',$port=11211,$prefix='',NetteX\Context$context=NULL){if(!self::isAvailable()){throw
  1539. new\XNotSupportedException("PHP extension 'memcache' is not loaded.");}$this->prefix=$prefix;$this->context=$context;$this->memcache=new\Memcache;NetteX\Debug::tryError();$this->memcache->connect($host,$port);if(NetteX\Debug::catchError($e)){throw
  1540. new\XInvalidStateException($e->getMessage());}}function
  1541. read($key){$key=$this->prefix.$key;$meta=$this->memcache->get($key);if(!$meta)return
  1542. NULL;if(!empty($meta[self::META_CALLBACKS])&&!Cache::checkCallbacks($meta[self::META_CALLBACKS])){$this->memcache->delete($key,0);return
  1543. NULL;}if(!empty($meta[self::META_DELTA])){$this->memcache->replace($key,$meta,0,$meta[self::META_DELTA]+time());}return$meta[self::META_DATA];}function
  1544. write($key,$data,array$dp){if(isset($dp[Cache::ITEMS])){throw
  1545. new\XNotSupportedException('Dependent items are not supported by MemcachedStorage.');}$meta=array(self::META_DATA=>$data);$expire=0;if(isset($dp[Cache::EXPIRATION])){$expire=(int)$dp[Cache::EXPIRATION];if(!empty($dp[Cache::SLIDING])){$meta[self::META_DELTA]=$expire;}}if(isset($dp[Cache::CALLBACKS])){$meta[self::META_CALLBACKS]=$dp[Cache::CALLBACKS];}if(isset($dp[Cache::TAGS])||isset($dp[Cache::PRIORITY])){if(!$this->context){throw
  1546. new\XInvalidStateException('CacheJournal has not been provided.');}$this->getJournal()->write($this->prefix.$key,$dp);}$this->memcache->set($this->prefix.$key,$meta,0,$expire);}function
  1547. remove($key){$this->memcache->delete($this->prefix.$key,0);}function
  1548. clean(array$conds){if(!empty($conds[Cache::ALL])){$this->memcache->flush();}elseif($this->context){foreach($this->getJournal()->clean($conds)as$entry){$this->memcache->delete($entry,0);}}}protected
  1549. function
  1550. getJournal(){return$this->context->getService('NetteX\\Caching\\ICacheJournal');}}class
  1551. MemoryStorage
  1552. extends
  1553. NetteX\Object
  1554. implements
  1555. ICacheStorage{private$data=array();function
  1556. read($key){return
  1557. isset($this->data[$key])?$this->data[$key]:NULL;}function
  1558. write($key,$data,array$dp){$this->data[$key]=$data;}function
  1559. remove($key){unset($this->data[$key]);}function
  1560. clean(array$conds){if(!empty($conds[Cache::ALL])){$this->data=array();}}}class
  1561. SqliteJournal
  1562. extends
  1563. NetteX\Object
  1564. implements
  1565. ICacheJournal{private$database;static
  1566. function
  1567. isAvailable(){return
  1568. extension_loaded('sqlite');}function
  1569. __construct($file){if(!self::isAvailable()){throw
  1570. new\XNotSupportedException("SQLite or SQLite3 extension is required for storing tags and priorities.");}$this->database=extension_loaded('sqlite')?new
  1571. SQLiteMimic($file):new\SQLite3($file);@$this->database->exec('CREATE TABLE cache (entry VARCHAR NOT NULL, priority INTEGER, tag VARCHAR); '.'CREATE INDEX IDX_ENTRY ON cache (entry); '.'CREATE INDEX IDX_PRI ON cache (priority); '.'CREATE INDEX IDX_TAG ON cache (tag);');}function
  1572. write($key,array$dependencies){$entry=$this->database->escapeString($key);$query='';if(!empty($dependencies[Cache::TAGS])){foreach((array)$dependencies[Cache::TAGS]as$tag){$query.="INSERT INTO cache (entry, tag) VALUES ('$entry', '".$this->database->escapeString($tag)."'); ";}}if(!empty($dependencies[Cache::PRIORITY])){$query.="INSERT INTO cache (entry, priority) VALUES ('$entry', '".((int)$dependencies[Cache::PRIORITY])."'); ";}if(!$this->database->exec("BEGIN; DELETE FROM cache WHERE entry = '$entry'; $query COMMIT;")){$this->database->exec('ROLLBACK');return
  1573. FALSE;}return
  1574. TRUE;}function
  1575. clean(array$conditions){if(!empty($conditions[Cache::ALL])){$this->database->exec('DELETE FROM CACHE;');return;}$query=array();if(!empty($conditions[Cache::TAGS])){$tags=array();foreach((array)$conditions[Cache::TAGS]as$tag){$tags[]="'".$this->database->escapeString($tag)."'";}$query[]='tag IN('.implode(', ',$tags).')';}if(isset($conditions[Cache::PRIORITY])){$query[]='priority <= '.((int)$conditions[Cache::PRIORITY]);}$entries=array();if(!empty($query)){$query=implode(' OR ',$query);$result=$this->database->query("SELECT entry FROM cache WHERE $query");if($result
  1576. instanceof\SQLiteResult){while($entry=$result->fetchSingle())$entries[]=$entry;}else{while($entry=$result->fetchArray(SQLITE3_NUM))$entries[]=$entry[0];}$this->database->exec("DELETE FROM cache WHERE $query");}return$entries;}}if(class_exists('SQLiteDatabase')){class
  1577. SQLiteMimic
  1578. extends\SQLiteDatabase{function
  1579. exec($sql){return$this->queryExec($sql);}function
  1580. escapeString($s){return
  1581. sqlite_escape_string($s);}}}}namespace NetteX\Config{use
  1582. NetteX;class
  1583. Config
  1584. implements\ArrayAccess,\IteratorAggregate{private
  1585. static$extensions=array('ini'=>'NetteX\Config\ConfigAdapterIni');static
  1586. function
  1587. registerExtension($extension,$class){if(!class_exists($class)){throw
  1588. new\InvalidArgumentException("Class '$class' was not found.");}if(!NetteX\Reflection\ClassReflection::from($class)->implementsInterface('NetteX\Config\IConfigAdapter')){throw
  1589. new\InvalidArgumentException("Configuration adapter '$class' is not NetteX\\Config\\IConfigAdapter implementor.");}self::$extensions[strtolower($extension)]=$class;}static
  1590. function
  1591. fromFile($file,$section=NULL){$extension=strtolower(pathinfo($file,PATHINFO_EXTENSION));if(isset(self::$extensions[$extension])){$arr=call_user_func(array(self::$extensions[$extension],'load'),$file,$section);return
  1592. new
  1593. static($arr);}else{throw
  1594. new\InvalidArgumentException("Unknown file extension '$file'.");}}function
  1595. __construct($arr=NULL){foreach((array)$arr
  1596. as$k=>$v){$this->$k=is_array($v)?new
  1597. static($v):$v;}}function
  1598. save($file,$section=NULL){$extension=strtolower(pathinfo($file,PATHINFO_EXTENSION));if(isset(self::$extensions[$extension])){return
  1599. call_user_func(array(self::$extensions[$extension],'save'),$this,$file,$section);}else{throw
  1600. new\InvalidArgumentException("Unknown file extension '$file'.");}}function
  1601. __set($key,$value){if(!is_scalar($key)){throw
  1602. new\InvalidArgumentException("Key must be either a string or an integer.");}elseif($value===NULL){unset($this->$key);}else{$this->$key=$value;}}function&__get($key){if(!is_scalar($key)){throw
  1603. new\InvalidArgumentException("Key must be either a string or an integer.");}return$this->$key;}function
  1604. __isset($key){return
  1605. FALSE;}function
  1606. __unset($key){}function
  1607. offsetSet($key,$value){$this->__set($key,$value);}function
  1608. offsetGet($key){if(!is_scalar($key)){throw
  1609. new\InvalidArgumentException("Key must be either a string or an integer.");}elseif(!isset($this->$key)){return
  1610. NULL;}return$this->$key;}function
  1611. offsetExists($key){if(!is_scalar($key)){throw
  1612. new\InvalidArgumentException("Key must be either a string or an integer.");}return
  1613. isset($this->$key);}function
  1614. offsetUnset($key){if(!is_scalar($key)){throw
  1615. new\InvalidArgumentException("Key must be either a string or an integer.");}unset($this->$key);}function
  1616. getIterator(){return
  1617. new
  1618. NetteX\GenericRecursiveIterator(new\ArrayIterator($this));}function
  1619. toArray(){$arr=array();foreach($this
  1620. as$k=>$v){$arr[$k]=$v
  1621. instanceof
  1622. self?$v->toArray():$v;}return$arr;}}final
  1623. class
  1624. ConfigAdapterIni
  1625. implements
  1626. IConfigAdapter{public
  1627. static$keySeparator='.';public
  1628. static$sectionSeparator=' < ';public
  1629. static$rawSection='!';final
  1630. function
  1631. __construct(){throw
  1632. new\LogicException("Cannot instantiate static class ".get_class($this));}static
  1633. function
  1634. load($file,$section=NULL){if(!is_file($file)||!is_readable($file)){throw
  1635. new\XFileNotFoundException("File '$file' is missing or is not readable.");}NetteX\Debug::tryError();$ini=parse_ini_file($file,TRUE);if(NetteX\Debug::catchError($e)){throw$e;}$separator=trim(self::$sectionSeparator);$data=array();foreach($ini
  1636. 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
  1637. 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
  1638. new\XInvalidStateException("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
  1639. new\XInvalidStateException("Missing parent section [$parent] in '$file'.");}}$secData=NetteX\ArrayTools::mergeTree($secData,$cursor);}$secName=trim($parts[0]);if($secName===''){throw
  1640. new\XInvalidStateException("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
  1641. new\XInvalidStateException("Invalid section [$secName] in '$file'.");}}}else{$cursor=&$data[$secName];}if(is_array($secData)&&is_array($cursor)){$secData=NetteX\ArrayTools::mergeTree($secData,$cursor);}$cursor=$secData;}if($section===NULL){return$data;}elseif(!isset($data[$section])||!is_array($data[$section])){throw
  1642. new\XInvalidStateException("There is not section [$section] in '$file'.");}else{return$data[$section];}}static
  1643. function
  1644. save($config,$file,$section=NULL){$output=array();$output[]='; generated by NetteX';$output[]='';if($section===NULL){foreach($config
  1645. as$secName=>$secData){if(!(is_array($secData)||$secData
  1646. instanceof\Traversable)){throw
  1647. new\XInvalidStateException("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
  1648. new\XIOException("Cannot write file '$file'.");}}private
  1649. static
  1650. function
  1651. build($input,&$output,$prefix){foreach($input
  1652. as$key=>$val){if(is_array($val)||$val
  1653. instanceof\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
  1654. new\InvalidArgumentException("The '$prefix$key' item must be scalar or array, ".gettype($val)." given.");}}}}}namespace NetteX{use
  1655. NetteX;use
  1656. NetteX\Environment;final
  1657. class
  1658. Debug{public
  1659. static$productionMode;public
  1660. static$consoleMode;public
  1661. static$time;private
  1662. static$firebugDetected;private
  1663. static$ajaxDetected;public
  1664. static$source;public
  1665. static$maxDepth=3;public
  1666. static$maxLen=150;public
  1667. static$showLocation=FALSE;const
  1668. DEVELOPMENT=FALSE;const
  1669. PRODUCTION=TRUE;const
  1670. DETECT=NULL;public
  1671. static$strictMode=FALSE;public
  1672. static$scream=FALSE;public
  1673. static$onFatalError=array();public
  1674. static$logDirectory;public
  1675. static$email;public
  1676. static$mailer=array(__CLASS__,'defaultMailer');public
  1677. static$emailSnooze=172800;public
  1678. static$editor='editor://open/?file=%file&line=%line';private
  1679. static$enabled=FALSE;private
  1680. static$lastError=FALSE;public
  1681. static$showBar=TRUE;private
  1682. static$panels=array();private
  1683. static$dumps;private
  1684. static$errors;const
  1685. DEBUG='debug';const
  1686. INFO='info';const
  1687. WARNING='warning';const
  1688. ERROR='error';const
  1689. CRITICAL='critical';final
  1690. function
  1691. __construct(){throw
  1692. new\LogicException("Cannot instantiate static class ".get_class($this));}static
  1693. function
  1694. _init(){self::$time=microtime(TRUE);self::$consoleMode=PHP_SAPI==='cli';self::$productionMode=self::DETECT;if(self::$consoleMode){self::$source=empty($_SERVER['argv'])?'cli':'cli: '.$_SERVER['argv'][0];}else{self::$firebugDetected=isset($_SERVER['HTTP_X_FIRELOGGER']);self::$ajaxDetected=isset($_SERVER['HTTP_X_REQUESTED_WITH'])&&$_SERVER['HTTP_X_REQUESTED_WITH']==='XMLHttpRequest';if(isset($_SERVER['REQUEST_URI'])){self::$source=(isset($_SERVER['HTTPS'])&&strcasecmp($_SERVER['HTTPS'],'off')?'https://':'http://').(isset($_SERVER['HTTP_HOST'])?$_SERVER['HTTP_HOST']:(isset($_SERVER['SERVER_NAME'])?$_SERVER['SERVER_NAME']:'')).$_SERVER['REQUEST_URI'];}}$tab=array(__CLASS__,'renderTab');$panel=array(__CLASS__,'renderPanel');self::addPanel(new
  1695. DebugPanel('time',$tab,$panel));self::addPanel(new
  1696. DebugPanel('memory',$tab,$panel));self::addPanel(new
  1697. DebugPanel('errors',$tab,$panel));self::addPanel(new
  1698. DebugPanel('dumps',$tab,$panel));}static
  1699. function
  1700. dump($var,$return=FALSE){if(!$return&&self::$productionMode){return$var;}$output="<pre class=\"nette-dump\">".self::_dump($var,0)."</pre>\n";if(!$return&&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
  1701. function
  1702. barDump($var,$title=NULL){if(!self::$productionMode){$dump=array();foreach((is_array($var)?$var:array(''=>$var))as$key=>$val){$dump[$key]=self::_dump($val,0);}self::$dumps[]=array('title'=>$title,'dump'=>$dump);}return$var;}private
  1703. static
  1704. function
  1705. _dump(&$var,$level){static$tableUtf,$tableBin,$reBinary='#[^\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));}}$tableBin["\\"]='\\\\';$tableBin["\r"]='\\r';$tableBin["\n"]='\\n';$tableBin["\t"]='\\t';$tableUtf['\\x']=$tableBin['\\x']='\\\\x';}if(is_bool($var)){return($var?'TRUE':'FALSE')."\n";}elseif($var===NULL){return"NULL\n";}elseif(is_int($var)){return"$var\n";}elseif(is_float($var)){$var=(string)$var;if(strpos($var,'.')===FALSE)$var.='.0';return"$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($reBinary,$s)||preg_last_error()?$tableBin:$tableUtf);$len=strlen($var);return"\"$s\"".($len>1?" ($len)":"")."\n";}elseif(is_array($var)){$s="<span>array</span>(".count($var).") ";$space=str_repeat($space1=' ',$level);$brackets=range(0,count($var)-1)===array_keys($var)?"[]":"{}";static$marker;if($marker===NULL)$marker=uniqid("\x00",TRUE);if(empty($var)){}elseif(isset($var[$marker])){$brackets=$var[$marker];$s.="$brackets[0] *RECURSION* $brackets[1]";}elseif($level<self::$maxDepth||!self::$maxDepth){$s.="<code>$brackets[0]\n";$var[$marker]=$brackets;foreach($var
  1706. as$k=>&$v){if($k===$marker)continue;$k=is_int($k)?$k:'"'.strtr($k,preg_match($reBinary,$k)||preg_last_error()?$tableBin:$tableUtf).'"';$s.="$space$space1$k => ".self::_dump($v,$level+1);}unset($var[$marker]);$s.="$space$brackets[1]</code>";}else{$s.="$brackets[0] ... $brackets[1]";}return$s."\n";}elseif(is_object($var)){$arr=(array)$var;$s="<span>".get_class($var)."</span>(".count($arr).") ";$space=str_repeat($space1=' ',$level);static$list=array();if(empty($arr)){}elseif(in_array($var,$list,TRUE)){$s.="{ *RECURSION* }";}elseif($level<self::$maxDepth||!self::$maxDepth){$s.="<code>{\n";$list[]=$var;foreach($arr
  1707. 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($reBinary,$k)||preg_last_error()?$tableBin:$tableUtf);$s.="$space$space1\"$k\"$m => ".self::_dump($v,$level+1);}array_pop($list);$s.="$space}</code>";}else{$s.="{ ... }";}return$s."\n";}elseif(is_resource($var)){return"<span>".get_resource_type($var)." resource</span>\n";}else{return"<span>unknown type</span>\n";}}static
  1708. function
  1709. timer($name=NULL){static$time=array();$now=microtime(TRUE);$delta=isset($time[$name])?$now-$time[$name]:0;$time[$name]=$now;return$delta;}static
  1710. function
  1711. enable($mode=NULL,$logDirectory=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 127.0.0.1 ::1");}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('NetteX\Environment')){self::$productionMode=Environment::isProduction();}elseif(isset($_SERVER['SERVER_ADDR'])||isset($_SERVER['LOCAL_ADDR'])){$addrs=array();if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){$addrs=preg_split('#,\s*#',$_SERVER['HTTP_X_FORWARDED_FOR']);}if(isset($_SERVER['REMOTE_ADDR'])){$addrs[]=$_SERVER['REMOTE_ADDR'];}$addrs[]=isset($_SERVER['SERVER_ADDR'])?$_SERVER['SERVER_ADDR']:$_SERVER['LOCAL_ADDR'];self::$productionMode=FALSE;foreach($addrs
  1712. as$addr){$oct=explode('.',$addr);if($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')))){self::$productionMode=TRUE;break;}}}else{self::$productionMode=!self::$consoleMode;}}if(is_string($logDirectory)||$logDirectory===FALSE){self::$logDirectory=$logDirectory;}else{self::$logDirectory=defined('APP_DIR')?APP_DIR.'/../log':getcwd().'/log';}if(self::$logDirectory){ini_set('error_log',self::$logDirectory.'/php_error.log');}if(function_exists('ini_set')){ini_set('display_errors',!self::$productionMode);ini_set('html_errors',FALSE);ini_set('log_errors',FALSE);}elseif(ini_get('display_errors')!=!self::$productionMode&&ini_get('display_errors')!==(self::$productionMode?'stderr':'stdout')){throw
  1713. new\XNotSupportedException('Function ini_set() must be enabled.');}if($email){if(!is_string($email)){throw
  1714. new\InvalidArgumentException('E-mail address must be a string.');}self::$email=$email;}if(!defined('E_DEPRECATED')){define('E_DEPRECATED',8192);}if(!defined('E_USER_DEPRECATED')){define('E_USER_DEPRECATED',16384);}if(!self::$enabled){register_shutdown_function(array(__CLASS__,'_shutdownHandler'));set_exception_handler(array(__CLASS__,'_exceptionHandler'));set_error_handler(array(__CLASS__,'_errorHandler'));self::$enabled=TRUE;}}static
  1715. function
  1716. isEnabled(){return
  1717. self::$enabled;}static
  1718. function
  1719. log($message,$priority=self::INFO){if(self::$logDirectory===FALSE){return;}elseif(!self::$logDirectory){throw
  1720. new\XInvalidStateException('Logging directory is not specified in NetteX\Debug::$logDirectory.');}elseif(!is_dir(self::$logDirectory)){throw
  1721. new\XDirectoryNotFoundException("Directory '".self::$logDirectory."' is not found or is not directory.");}if($message
  1722. instanceof\Exception){$exception=$message;$message="PHP Fatal error: ".($message
  1723. instanceof\XFatalErrorException?$exception->getMessage():"Uncaught exception ".get_class($exception)." with message '".$exception->getMessage()."'")." in ".$exception->getFile().":".$exception->getLine();}error_log(@date('[Y-m-d H-i-s] ').trim($message).(self::$source?' @ '.self::$source:'').PHP_EOL,3,self::$logDirectory.'/'.strtolower($priority).'.log');if(($priority===self::ERROR||$priority===self::CRITICAL)&&self::$email&&@filemtime(self::$logDirectory.'/email-sent')+self::$emailSnooze<time()&&@file_put_contents(self::$logDirectory.'/email-sent','sent')){call_user_func(self::$mailer,$message);}if(isset($exception)){$hash=md5($exception);foreach(new\DirectoryIterator(self::$logDirectory)as$entry){if(strpos($entry,$hash)){$skip=TRUE;break;}}if(empty($skip)&&$logHandle=@fopen(self::$logDirectory."/exception ".@date('Y-m-d H-i-s')." $hash.html",'w')){ob_start();ob_start(function($buffer)use($logHandle){fwrite($logHandle,$buffer);},1);self::paintBlueScreen($exception);ob_end_flush();ob_end_clean();fclose($logHandle);}}}static
  1724. function
  1725. _shutdownHandler(){static$types=array(E_ERROR=>1,E_CORE_ERROR=>1,E_COMPILE_ERROR=>1,E_PARSE=>1);$error=error_get_last();if(isset($types[$error['type']])){self::_exceptionHandler(new\XFatalErrorException($error['message'],0,$error['type'],$error['file'],$error['line'],NULL));return;}if(self::$showBar&&!self::$productionMode&&!self::$ajaxDetected&&!self::$consoleMode&&(!preg_match('#^Content-Type: (?!text/html)#im',implode("\n",headers_list())))){self::paintDebugBar();}}static
  1726. function
  1727. _exceptionHandler(\Exception$exception){if(!headers_sent()){header('HTTP/1.1 500 Internal Server Error');}$htmlMode=!self::$ajaxDetected&&!preg_match('#^Content-Type: (?!text/html)#im',implode("\n",headers_list()));try{if(self::$productionMode){self::log($exception,self::ERROR);if(self::$consoleMode){echo"ERROR: the server encountered an internal error and was unable to complete your request.\n";}elseif($htmlMode){echo"<!DOCTYPE html><meta name=robots content=noindex><meta name=generator content='NetteX Framework'>\n\n";echo"<style>body{color:#333;background:white;width:500px;margin:100px auto}h1{font:bold 47px/1.5 sans-serif;margin:.6em 0}p{font:21px/1.5 Georgia,serif;margin:1.5em 0}small{font-size:70%;color:gray}</style>\n\n";echo"<title>Server Error</title>\n\n<h1>Server Error</h1>\n\n<p>We're sorry! The server encountered an internal error and was unable to complete your request. Please try again later.</p>\n\n<p><small>error 500</small></p>";}}else{if(self::$consoleMode){echo"$exception\n";}elseif($htmlMode){self::paintBlueScreen($exception);}elseif(!self::fireLog($exception,self::ERROR)){self::log($exception);}}foreach(self::$onFatalError
  1728. as$handler){call_user_func($handler,$exception);}}catch(\Exception$e){echo"\nNetteX\\Debug FATAL ERROR: thrown ",get_class($e),': ',$e->getMessage(),"\nwhile processing ",get_class($exception),': ',$exception->getMessage(),"\n";exit;}}static
  1729. function
  1730. _errorHandler($severity,$message,$file,$line,$context){if(self::$lastError!==FALSE){self::$lastError=new\ErrorException($message,0,$severity,$file,$line);return
  1731. NULL;}if(self::$scream){error_reporting(E_ALL|E_STRICT);}if($severity===E_RECOVERABLE_ERROR||$severity===E_USER_ERROR){throw
  1732. new\XFatalErrorException($message,0,$severity,$file,$line,$context);}elseif(($severity&error_reporting())!==$severity){return
  1733. FALSE;}elseif(self::$strictMode&&!self::$productionMode){self::_exceptionHandler(new\XFatalErrorException($message,0,$severity,$file,$line,$context));exit;}static$types=array(E_WARNING=>'Warning',E_COMPILE_WARNING=>'Warning',E_USER_WARNING=>'Warning',E_NOTICE=>'Notice',E_USER_NOTICE=>'Notice',E_STRICT=>'Strict standards',E_DEPRECATED=>'Deprecated',E_USER_DEPRECATED=>'Deprecated');$message='PHP '.(isset($types[$severity])?$types[$severity]:'Unknown error').": $message";$count=&self::$errors["$message|$file|$line"];if($count++){return
  1734. NULL;}elseif(self::$productionMode){self::log("$message in $file:$line",self::ERROR);return
  1735. NULL;}else{$ok=self::fireLog(new\ErrorException($message,0,$severity,$file,$line),self::WARNING);return
  1736. self::$consoleMode||(!self::$showBar&&!$ok)?FALSE:NULL;}return
  1737. FALSE;}static
  1738. function
  1739. processException(\Exception$exception){trigger_error(__METHOD__.'() is deprecated; use '.__CLASS__.'::log($exception, Debug::ERROR) instead.',E_USER_WARNING);self::log($exception,self::ERROR);}static
  1740. function
  1741. toStringException(\Exception$exception){if(self::$enabled){self::_exceptionHandler($exception);}else{trigger_error($exception->getMessage(),E_USER_ERROR);}exit;}static
  1742. function
  1743. paintBlueScreen(\Exception$exception){if(class_exists('NetteX\Environment',FALSE)){$application=Environment::getContext()->hasService('NetteX\\Application\\Application',TRUE)?Environment::getContext()->getService('NetteX\\Application\\Application'):NULL;}if(!function_exists('NetteX\_netteDebugPrintCode')){function
  1744. _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
  1745. as$n=>$s){$spans+=substr_count($s,'<span')-substr_count($s,'</span');$s=str_replace(array("\r","\n"),array('',''),$s);preg_match_all('#<[^>]+>#',$s,$tags);if($n===$line){printf("<span class='highlight'>%{$numWidth}s: %s\n</span>%s",$n,strip_tags($s),implode('',$tags[0]));}else{printf("<span class='line'>%{$numWidth}s:</span> %s\n",$n,$s);}}echo
  1746. str_repeat('</span>',$spans),'</code>';}function
  1747. _netteDump($dump){return'<pre class="nette-dump">'.preg_replace_callback('#^( *)((?>[^(]{1,200}))\((\d+)\) <code>#m',function($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">');},$dump).'</pre>';}function
  1748. _netteOpenPanel($name,$collapsed){static$id;$id++;?>
  1749. <div class="panel">
  1750. <h2><a href="#" onclick="return !netteToggle(this, 'netteBsPnl<?php echo$id?>')"><?php echo
  1751. htmlSpecialChars($name)?> <abbr><?php echo$collapsed?'&#x25ba;':'&#x25bc;'?></abbr></a></h2>
  1752. <div id="netteBsPnl<?php echo$id?>" class="<?php echo$collapsed?'collapsed ':''?>inner">
  1753. <?php
  1754. }function
  1755. _netteClosePanel(){?>
  1756. </div>
  1757. </div>
  1758. <?php
  1759. }}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
  1760. instanceof\XFatalErrorException&&isset($errorTypes[$exception->getSeverity()]))?$errorTypes[$exception->getSeverity()]:get_class($exception);$expandPath=NETTEX_DIR.DIRECTORY_SEPARATOR;if(headers_sent()){echo'</pre></xmp></table>';}?><!DOCTYPE html>
  1761. <html>
  1762. <head>
  1763. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  1764. <meta name="robots" content="noindex,noarchive">
  1765. <meta name="generator" content="NetteX Framework">
  1766. <title><?php echo
  1767. htmlspecialchars($title)?></title><!-- <?php
  1768. $ex=$exception;echo$ex->getMessage(),($ex->getCode()?' #'.$ex->getCode():'');while((method_exists($ex,'getPrevious')&&$ex=$ex->getPrevious())||(isset($ex->previous)&&$ex=$ex->previous))echo'; caused by ',get_class($ex),' ',$ex->getMessage(),($ex->getCode()?' #'.$ex->getCode():'');?> -->
  1769. <style type="text/css" class="nette">body{margin:0 0 2em;padding:0}#netteBluescreen{font:9pt/1.5 Verdana,sans-serif;background:white;color:#333;position:absolute;left:0;top:0;width:100%;z-index:23178;text-align:left}#netteBluescreen *{font:inherit;color:inherit;background:transparent;border:none;margin:0;padding:0;text-align:inherit;text-indent:0}#netteBluescreen b{font-weight:bold}#netteBluescreen i{font-style:italic}#netteBluescreenIcon{position:absolute;right:.5em;top:.5em;z-index:23179;text-decoration:none;background:#CD1818;padding:3px}#netteBluescreenError{background:#CD1818;color:white;font:13pt/1.5 Verdana,sans-serif!important;display:block}#netteBluescreen h1{font-size:18pt;font-weight:normal;text-shadow:1px 1px 0 rgba(0,0,0,.4);margin:.7em 0}#netteBluescreen h2{font:14pt/1.5 sans-serif!important;color:#888;margin:.6em 0}#netteBluescreen a{text-decoration:none;color:#328ADC;padding:2px 4px;margin:-2px -4px}#netteBluescreen a abbr{font-family:sans-serif;color:#BBB}#netteBluescreen h3{font:bold 10pt/1.5 Verdana,sans-serif!important;margin:1em 0;padding:0}#netteBluescreen p,#netteBluescreen pre{margin:.8em 0}#netteBluescreen pre,#netteBluescreen code,#netteBluescreen table{font:9pt/1.5 Consolas,monospace!important}#netteBluescreen pre,#netteBluescreen table{background:#FDF5CE;padding:.4em .7em;border:1px dotted silver;overflow:auto}#netteBluescreen table pre{padding:0;margin:0;border:none}#netteBluescreen pre.nette-dump span{color:#C22}#netteBluescreen pre.nette-dump a{color:#333}#netteBluescreen div.panel{padding:1px 25px}#netteBluescreen div.inner{background:#F4F3F1;padding:.1em 1em 1em;border-radius:8px;-moz-border-radius:8px;-webkit-border-radius:8px}#netteBluescreen table{border-collapse:collapse;width:100%}#netteBluescreen .outer{overflow:auto}#netteBluescreen td,#netteBluescreen th{vertical-align:top;text-align:left;padding:2px 6px;border:1px solid #e6dfbf}#netteBluescreen th{width:10%;font-weight:bold}#netteBluescreen tr:nth-child(2n),#netteBluescreen tr:nth-child(2n) pre{background-color:#F7F0CB}#netteBluescreen ol{margin:1em 0;padding-left:2.5em}#netteBluescreen ul{font:7pt/1.5 Verdana,sans-serif!important;padding:2em 4em;margin:1em 0 0;color:#777;background:#F6F5F3 url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFEAAAAjCAMAAADbuxbOAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADBQTFRF/fz24d7Y7Onj5uLd9vPu3drUzMvG09LN39zW8e7o2NbQ3NnT29jS0M7J1tXQAAAApvmsFgAAABB0Uk5T////////////////////AOAjXRkAAAKlSURBVHja7FbbsqQgDAwENEgc//9vN+SCWDtbtXPmZR/Wc6o02mlC58LA9ckFAOszvMV8xNgyUjyXhojfMVKvRL0ZHavxXYy5JrmchMdzou8YlTClxajtK8ZGGpWRoBr1+gFjKfHkJPbizabLgzE3pH7Iu4K980xgFvlrVzMZoVBWhtvouCDdcTDmTgMCJdVxJ9MKO6XxnliM7hxi5lbj2ZVM4l8DqYyKoNLYcfqBB1/LpHYxEcfVG6ZpMDgyFUVWY/Q1sSYPpIdSAKWqLWL0XqWiMWc4hpH0OQOMOAgdycY4N9Sb7wWANQs3rsDSdLAYiuxi5siVfOhBWIrtH0G3kNaF/8Q4kCPE1kMucG/ZMUBUCOgiKJkPuWWTLGVgLGpwns1DraUayCtoBqERyaYtVsm85NActRooezvSLO/sKZP/nq8n4+xcyjNsRu8zW6KWpdb7wjiQd4WrtFZYFiKHENSmWp6xshh96c2RQ+c7Lt+qbijyEjHWUJ/pZsy8MGIUuzNiPySK2Gqoh6ZTRF6ko6q3nVTkaA//itIrDpW6l3SLo8juOmqMXkYknu5FdQxWbhCfKHEGDhxxyTVaXJF3ZjSl3jMksjSOOKmne9pI+mcG5QvaUJhI9HpkmRo2NpCrDJvsktRhRE2MM6F2n7dt4OaMUq8bCctk0+PoMRzL+1l5PZ2eyM/Owr86gf8z/tOM53lom5+nVcFuB+eJVzlXwAYy9TZ9s537tfqcsJWbEU4nBngZo6FfO9T9CdhfBtmk2dLiAy8uS4zwOpMx2HqYbTC+amNeAYTpsP4SIgvWfUBWXxn3CMHW3ffd7k3+YIkx7w0t/CVGvcPejoeOlzOWzeGbawOHqXQGUTMZRcfj4XPCgW9y/fuvVn8zD9P1QHzv80uAAQA0i3Jer7Jr7gAAAABJRU5ErkJggg==') 99% 10px no-repeat;border-top:1px solid #DDD}#netteBluescreen .highlight{background:#CD1818;color:white;font-weight:bold;font-style:normal;display:block;padding:0 .4em;margin:0 -.4em}#netteBluescreen .line{color:#9F9C7F;font-weight:normal;font-style:normal}#netteBluescreen a[href^=editor\:]{color:inherit;border-bottom:1px dotted #328ADC}</style>
  1770. <script type="text/javascript">/*<![CDATA[*/function netteToggle(c,e){for(var b=c.getElementsByTagName("abbr")[0],a=e?document.getElementById(e):c.nextSibling;a.nodeType!==1;)a=a.nextSibling;var d=a.currentStyle?a.currentStyle.display=="none":getComputedStyle(a,null).display=="none";try{b.innerHTML=String.fromCharCode(d?9660:9658)}catch(f){}a.style.display=d?a.tagName.toLowerCase()==="code"?"inline":"block":"none";if(c.id==="netteBluescreenIcon"){b=0;for(a=document.styleSheets;b<a.length;b++)if((a[b].owningElement||a[b].ownerNode).className!==
  1771. "nette")a[b].disabled=d?true:a[b].oldDisabled}return true};/*]]>*/</script>
  1772. </head>
  1773. <body>
  1774. <div id="netteBluescreen">
  1775. <a id="netteBluescreenIcon" href="#" onclick="return !netteToggle(this)"><abbr>&#x25bc;</abbr></a
  1776. ><div>
  1777. <div id="netteBluescreenError" class="panel">
  1778. <h1><?php echo
  1779. htmlspecialchars($title),($exception->getCode()?' #'.$exception->getCode():'')?></h1>
  1780. <p><?php echo
  1781. htmlspecialchars($exception->getMessage())?></p>
  1782. </div>
  1783. <?php $ex=$exception;$level=0;?>
  1784. <?php do{?>
  1785. <?php if($level++):?>
  1786. <?php _netteOpenPanel('Caused by',$level>2)?>
  1787. <div class="panel">
  1788. <h1><?php echo
  1789. htmlspecialchars(get_class($ex)),($ex->getCode()?' #'.$ex->getCode():'')?></h1>
  1790. <p><b><?php echo
  1791. htmlspecialchars($ex->getMessage())?></b></p>
  1792. </div>
  1793. <?php endif?>
  1794. <?php $stack=$ex->getTrace();$expanded=NULL?>
  1795. <?php if(strpos($ex->getFile(),$expandPath)===0){foreach($stack
  1796. as$key=>$row){if(isset($row['file'])&&strpos($row['file'],$expandPath)!==0){$expanded=$key;break;}}}?>
  1797. <?php if(is_file($ex->getFile())):?>
  1798. <?php _netteOpenPanel('Source file',$expanded!==NULL)?>
  1799. <p><b>File:</b> <?php if(self::$editor)echo'<a href="',htmlspecialchars(strtr(self::$editor,array('%file'=>rawurlencode($ex->getFile()),'%line'=>$ex->getLine()))),'">'?>
  1800. <?php echo
  1801. htmlspecialchars($ex->getFile()),(self::$editor?'</a>':'')?> &nbsp; <b>Line:</b> <?php echo$ex->getLine()?></p>
  1802. <pre><?php _netteDebugPrintCode($ex->getFile(),$ex->getLine())?></pre>
  1803. <?php _netteClosePanel()?>
  1804. <?php endif?>
  1805. <?php if(isset($stack[0]['class'])&&$stack[0]['class']==='NetteX\Debug'&&($stack[0]['function']==='_shutdownHandler'||$stack[0]['function']==='_errorHandler'))unset($stack[0])?>
  1806. <?php if($stack):?>
  1807. <?php _netteOpenPanel('Call stack',FALSE)?>
  1808. <ol>
  1809. <?php foreach($stack
  1810. as$key=>$row):?>
  1811. <li><p>
  1812. <?php if(isset($row['file'])&&is_file($row['file'])):?>
  1813. <?php echo
  1814. self::$editor?'<a href="'.htmlspecialchars(strtr(self::$editor,array('%file'=>rawurlencode($row['file']),'%line'=>$row['line']))).'"':'<span';?> title="<?php echo
  1815. htmlSpecialChars($row['file'])?>">
  1816. <?php echo
  1817. htmlSpecialChars(basename(dirname($row['file']))),'/<b>',htmlSpecialChars(basename($row['file'])),'</b>',(self::$editor?'</a>':'</span>'),' (',$row['line'],')'?>
  1818. <?php else:?>
  1819. <i>inner-code</i><?php if(isset($row['line']))echo' (',$row['line'],')'?>
  1820. <?php endif?>
  1821. <?php if(isset($row['file'])&&is_file($row['file'])):?><a href="#" onclick="return !netteToggle(this, 'netteBsSrc<?php echo"$level-$key"?>')">source <abbr>&#x25ba;</abbr></a>&nbsp; <?php endif?>
  1822. <?php if(isset($row['class']))echo$row['class'].$row['type']?>
  1823. <?php echo$row['function']?>
  1824. (<?php if(!empty($row['args'])):?><a href="#" onclick="return !netteToggle(this, 'netteBsArgs<?php echo"$level-$key"?>')">arguments <abbr>&#x25ba;</abbr></a><?php endif?>)
  1825. </p>
  1826. <?php if(!empty($row['args'])):?>
  1827. <div class="collapsed outer" id="netteBsArgs<?php echo"$level-$key"?>">
  1828. <table>
  1829. <?php
  1830. try{$r=isset($row['class'])?new\ReflectionMethod($row['class'],$row['function']):new\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
  1831. _netteDump(self::_dump($v,0));echo"</td></tr>\n";}?>
  1832. </table>
  1833. </div>
  1834. <?php endif?>
  1835. <?php if(isset($row['file'])&&is_file($row['file'])):?>
  1836. <pre <?php if($expanded!==$key)echo'class="collapsed"';?> id="netteBsSrc<?php echo"$level-$key"?>"><?php _netteDebugPrintCode($row['file'],$row['line'])?></pre>
  1837. <?php endif?>
  1838. </li>
  1839. <?php endforeach?>
  1840. </ol>
  1841. <?php _netteClosePanel()?>
  1842. <?php endif?>
  1843. <?php if($ex
  1844. instanceof
  1845. IDebugPanel&&($tab=$ex->getTab())&&($panel=$ex->getPanel())):?>
  1846. <?php _netteOpenPanel($tab,FALSE)?>
  1847. <?php echo$panel?>
  1848. <?php _netteClosePanel()?>
  1849. <?php endif?>
  1850. <?php if(isset($ex->context)&&is_array($ex->context)):?>
  1851. <?php _netteOpenPanel('Variables',TRUE)?>
  1852. <div class="outer">
  1853. <table>
  1854. <?php
  1855. foreach($ex->context
  1856. as$k=>$v){echo'<tr><th>$',htmlspecialchars($k),'</th><td>',_netteDump(self::_dump($v,0)),"</td></tr>\n";}?>
  1857. </table>
  1858. </div>
  1859. <?php _netteClosePanel()?>
  1860. <?php endif?>
  1861. <?php }while((method_exists($ex,'getPrevious')&&$ex=$ex->getPrevious())||(isset($ex->previous)&&$ex=$ex->previous));?>
  1862. <?php while(--$level)_netteClosePanel()?>
  1863. <?php if(!empty($application)):?>
  1864. <?php _netteOpenPanel('NetteX Application',TRUE)?>
  1865. <h3>Requests</h3>
  1866. <?php $tmp=$application->getRequests();echo
  1867. _netteDump(self::_dump($tmp,0))?>
  1868. <h3>Presenter</h3>
  1869. <?php $tmp=$application->getPresenter();echo
  1870. _netteDump(self::_dump($tmp,0))?>
  1871. <?php _netteClosePanel()?>
  1872. <?php endif?>
  1873. <?php _netteOpenPanel('Environment',TRUE)?>
  1874. <?php
  1875. $list=get_defined_constants(TRUE);if(!empty($list['user'])):?>
  1876. <h3><a href="#" onclick="return !netteToggle(this, 'netteBsPnl-env-const')">Constants <abbr>&#x25bc;</abbr></a></h3>
  1877. <div class="outer">
  1878. <table id="netteBsPnl-env-const">
  1879. <?php
  1880. foreach($list['user']as$k=>$v){echo'<tr><th>',htmlspecialchars($k),'</th>';echo'<td>',_netteDump(self::_dump($v,0)),"</td></tr>\n";}?>
  1881. </table>
  1882. </div>
  1883. <?php endif?>
  1884. <h3><a href="#" onclick="return !netteToggle(this, 'netteBsPnl-env-files')">Included files <abbr>&#x25ba;</abbr></a> (<?php echo
  1885. count(get_included_files())?>)</h3>
  1886. <div class="outer">
  1887. <table id="netteBsPnl-env-files" class="collapsed">
  1888. <?php
  1889. foreach(get_included_files()as$v){echo'<tr><td>',htmlspecialchars($v),"</td></tr>\n";}?>
  1890. </table>
  1891. </div>
  1892. <h3>$_SERVER</h3>
  1893. <?php if(empty($_SERVER)):?>
  1894. <p><i>empty</i></p>
  1895. <?php else:?>
  1896. <div class="outer">
  1897. <table>
  1898. <?php
  1899. foreach($_SERVER
  1900. as$k=>$v)echo'<tr><th>',htmlspecialchars($k),'</th><td>',_netteDump(self::_dump($v,0)),"</td></tr>\n";?>
  1901. </table>
  1902. </div>
  1903. <?php endif?>
  1904. <?php _netteClosePanel()?>
  1905. <?php _netteOpenPanel('HTTP request',TRUE)?>
  1906. <?php if(function_exists('apache_request_headers')):?>
  1907. <h3>Headers</h3>
  1908. <div class="outer">
  1909. <table>
  1910. <?php
  1911. foreach(apache_request_headers()as$k=>$v)echo'<tr><th>',htmlspecialchars($k),'</th><td>',htmlspecialchars($v),"</td></tr>\n";?>
  1912. </table>
  1913. </div>
  1914. <?php endif?>
  1915. <?php foreach(array('_GET','_POST','_COOKIE')as$name):?>
  1916. <h3>$<?php echo$name?></h3>
  1917. <?php if(empty($GLOBALS[$name])):?>
  1918. <p><i>empty</i></p>
  1919. <?php else:?>
  1920. <div class="outer">
  1921. <table>
  1922. <?php
  1923. foreach($GLOBALS[$name]as$k=>$v)echo'<tr><th>',htmlspecialchars($k),'</th><td>',_netteDump(self::_dump($v,0)),"</td></tr>\n";?>
  1924. </table>
  1925. </div>
  1926. <?php endif?>
  1927. <?php endforeach?>
  1928. <?php _netteClosePanel()?>
  1929. <?php _netteOpenPanel('HTTP response',TRUE)?>
  1930. <h3>Headers</h3>
  1931. <?php if(headers_list()):?>
  1932. <pre><?php
  1933. foreach(headers_list()as$s)echo
  1934. htmlspecialchars($s),'<br>';?></pre>
  1935. <?php else:?>
  1936. <p><i>no headers</i></p>
  1937. <?php endif?>
  1938. <?php _netteClosePanel()?>
  1939. <ul>
  1940. <li>Report generated at <?php echo@date('Y/m/d H:i:s',self::$time)?></li>
  1941. <?php if(preg_match('#^https?://#',self::$source)):?>
  1942. <li><a href="<?php echo
  1943. htmlSpecialChars(self::$source)?>"><?php echo
  1944. htmlSpecialChars(self::$source)?></a></li>
  1945. <?php elseif(self::$source):?>
  1946. <li><?php echo
  1947. htmlSpecialChars(self::$source)?></li>
  1948. <?php endif?>
  1949. <li>PHP <?php echo
  1950. htmlSpecialChars(PHP_VERSION)?></li>
  1951. <?php if(isset($_SERVER['SERVER_SOFTWARE'])):?><li><?php echo
  1952. htmlSpecialChars($_SERVER['SERVER_SOFTWARE'])?></li><?php endif?>
  1953. <?php if(class_exists('NetteX\Framework')):?><li><?php echo
  1954. htmlSpecialChars('NetteX Framework '.Framework::VERSION)?> <i>(revision <?php echo
  1955. htmlSpecialChars(Framework::REVISION)?>)</i></li><?php endif?>
  1956. </ul>
  1957. </div>
  1958. </div>
  1959. <script type="text/javascript">/*<![CDATA[*/document.body.appendChild(document.getElementById("netteBluescreen"));document.onkeyup=function(a){a=a||window.event;if(a.keyCode==27)return document.getElementById("netteBluescreenIcon").onclick()};
  1960. for(var i=0,styles=document.styleSheets;i<styles.length;i++)if((styles[i].owningElement||styles[i].ownerNode).className!=="nette"){styles[i].oldDisabled=styles[i].disabled;styles[i].disabled=true}else styles[i].addRule?styles[i].addRule(".collapsed","display: none"):styles[i].insertRule(".collapsed { display: none }",0);/*]]>*/</script>
  1961. </body>
  1962. </html><?php }static
  1963. function
  1964. paintDebugBar(){$panels=array();foreach(self::$panels
  1965. as$panel){$panels[]=array('id'=>preg_replace('#[^a-z0-9]+#i','-',$panel->getId()),'tab'=>$tab=(string)$panel->getTab(),'panel'=>$tab?(string)$panel->getPanel():NULL);}?>
  1966. <!-- NetteX Debug Bar -->
  1967. <?php ob_start()?>
  1968. &nbsp;
  1969. <style id="nette-debug-style" class="nette">#nette-debug{display:none}body#nette-debug{margin:5px 5px 0;display:block}#nette-debug *{font:inherit;color:inherit;background:transparent;margin:0;padding:0;border:none;text-align:inherit;list-style:inherit}#nette-debug .nette-fixed-coords{position:fixed;_position:absolute;right:0;bottom:0}#nette-debug a{color:#125EAE;text-decoration:none}#nette-debug .nette-panel a{color:#125EAE;text-decoration:none}#nette-debug a:hover,#nette-debug a:active,#nette-debug a:focus{background-color:#125EAE;color:white}#nette-debug .nette-panel h2,#nette-debug .nette-panel h3,#nette-debug .nette-panel p{margin:.4em 0}#nette-debug .nette-panel table{border-collapse:collapse;background:#FDF5CE}#nette-debug .nette-panel tr:nth-child(2n) td{background:#F7F0CB}#nette-debug .nette-panel td,#nette-debug .nette-panel th{border:1px solid #E6DFBF;padding:2px 5px;vertical-align:top;text-align:left}#nette-debug .nette-panel th{background:#F4F3F1;color:#655E5E;font-size:90%;font-weight:bold}#nette-debug .nette-panel pre,#nette-debug .nette-panel code{font:9pt/1.5 Consolas,monospace}#nette-debug table .nette-right{text-align:right}.nette-hidden{display:none}#nette-debug-bar{font:normal normal 12px/21px Tahoma,sans-serif;color:#333;border:1px solid #c9c9c9;background:#EDEAE0 url('data:image/png;base64,R0lGODlhAQAVALMAAOTh1/Px6eHe1fHv5e/s4vLw6Ofk2u3q4PPw6PPx6PDt5PLw5+Dd1OXi2Ojm3Orn3iH5BAAAAAAALAAAAAABABUAAAQPMISEyhpYkfOcaQAgCEwEADs=') repeat-x bottom;position:relative;height:1.75em;min-height:21px;_float:left;min-width:50px;white-space:nowrap;z-index:23181;opacity:.9;border-radius:3px;-moz-border-radius:3px;box-shadow:1px 1px 10px rgba(0,0,0,.15);-moz-box-shadow:1px 1px 10px rgba(0,0,0,.15);-webkit-box-shadow:1px 1px 10px rgba(0,0,0,.15)}#nette-debug-bar:hover{opacity:1}#nette-debug-bar ul{list-style:none none;margin-left:4px}#nette-debug-bar li{float:left}#nette-debug-bar img{vertical-align:middle;position:relative;top:-1px;margin-right:3px}#nette-debug-bar li a{color:#000;display:block;padding:0 4px}#nette-debug-bar li a:hover{color:black;background:#c3c1b8}#nette-debug-bar li .nette-warning{color:#D32B2B;font-weight:bold}#nette-debug-bar li>span{padding:0 4px}#nette-debug-logo{background:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAPCAYAAABwfkanAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABiFJREFUSMe1VglPlGcQ5i+1xjZNqxREtGq8ahCPWsVGvEDBA1BBRQFBDjkE5BYUzwpovRBUREBEBbl3OVaWPfj2vi82eTrvbFHamLRJ4yYTvm+u95mZZ96PoKAv+LOatXBYZ+Bx6uFy6DGnt1m0EOKwSmQzwmHTgX5B/1W+yM9GYJ02CX6/B/5ZF+w2A4x6FYGTYDVp4PdY2Tbrs5N+mnRa2Km4/wV6rhPzQQj5fDc1mJM5nd0iYdZtQWtrCxobGnDpUiledTynbuvg99mgUMhw924Trl2rR01NNSTNJE9iDpTV8innv4K2kZPLroPXbYLHZeSu2K1aeF0muJ2GvwGzmNSwU2E+svm8ZrgdBliMaha/34Vx+RAKCgpwpa4OdbW1UE/L2cc/68WtWzdRVlaG6uoqtD1/BA/pA1MIxLvtes7pc5vhoDOE/rOgbVSdf9aJWa8dBp0Kyg+jdLiTx2vQKWEyqGmcNkqg4iTC1+dzQatWkK+cJqPD7KyFaKEjvRuNjY24fLkGdXW1ePjwAeX4QHonDNI0A75+/RpqqqshH+6F2UAUMaupYXouykV0mp6SQ60coxgL8Z4aMg/4x675/V60v3jKB+Xl5WJibIC4KPEIS0qKqWv5GOh7BZ/HSIk9kA33o7y8DOfPZ6GQOipkXDZAHXKxr4ipqqpkKS6+iIrycgz2dyMnJxtVlZUsotNZWZmor79KBbvgpdjm5sfIzc1hv4L8fKJPDTfJZZc+gRYKr8sAEy2DcBRdEEk62ltx9uwZ5qNILoDU1l6mbrvx5EkzUlKSuTiR7PHjR3x4fv4FyIbeIic7G5WVFUyN+qtX+Lnt2SPcvn2LfURjhF7kE4WPDr+Bx+NEUVEhkpNPoImm5CSOl5aUIC3tLOMR59gtAY4HidGIzj14cB8ZGRkM8kJeHk6cOI4xWR8vSl5uLlJTT6O74xnT5lB8PM6cSYXVqILb5UBWZiYSExMYkE4zzjqX00QHG+h9AjPqMei0k3ywy2khMdNiq6BVCf04T6ekuBgJCUdRUVHOBQwPvkNSUiLjaGi4Q/5qFgYtHgTXRJdTT59GenoaA5gY64deq0Bc3EGuNj4+DnppEheLijhZRkY6SktLsGPHdi6irOwSFTRAgO04deokTSIFsbExuHfvLnFSx8DevelAfFwcA0lJTqZi5PDS9aci/sbE7Oe4wsICbtD27b/ye1NTI3FeSX4W2gdFALRD3A4eM44ePcKViuD79/8gnZP5Kg4+cCAW2dnnqUM2Lujw4UM4ePAA2ztfPsHIYA/sdOt43A50d7UFCjkUj+joXVBMDJDeDhcVk08cjd61C3v37uFYp8PKXX3X8xJRUTtw7FgSn3Xzxg10d7ZCqRjkM+02C7pettDNogqAFjzxuI3YHR2Nffv2coXy0V44HGZERm7kJNu2/cK8bW9rwbp1axnMnj27uUijQQOb1QyTcYZ3YMOGn/Hbzp1crAAvaDfY38O5hW3//n0ce+TIYWiUcub1xo0R2Lp1y8cYsUMWM125VhPe93Zj7do1vEPi26GfUdBFbhK8tGHrli1YsWwpgoOD0dXRQqAtXMCy8DBs3rwJoSGLsWrVclylBdoUGYlVK1dg9eqVCFsSSs8/4btvvmUwEnE0KTERISE/IiIiAsGLF2HhwgU8qbc97QgPX8qFr1mzGgu+/opzdL5o5l1aEhqC9evXYWlYKFYsD6e/YVj0w/dMGZVyBDMqeaDTRuKpkxYjIz2dOyeup6H3r2kkOuJ1H3N5Z1QUzp3LQF9vJ4xGLQYHXiM9LY0pEhsTg+PHj9HNcJu4OcL3uaQZY86LiZw8mcJTkmhBTUYJbU8fcoygobgWR4Z6iKtTPLE7d35HYkICT1dIZuY59HQ9412StBPQTMvw8Z6WaMNFxy3Gab4TeQT0M9IHwUT/G0i0MGIJ9CTiJjBIH+iQaQbC7+QnfEXiQL6xgF09TjETHCt8RbeMuil+D8RNsV1LHdQoZfR/iJJzCZuYmEE/Bd3MJNs/+0UURgFWJJ//aQ8k+CsxVTqnVytHObkQrUoG8T4/bs4u4ubbxLPwFzYNPc8HI2zijLm84l39Dx8hfwJenFezFBKKQwAAAABJRU5ErkJggg==') 0 50% no-repeat;min-width:45px;cursor:move}#nette-debug-logo span{display:none}#nette-debug-bar-bgl,#nette-debug-bar-bgx,#nette-debug-bar-bgr{position:absolute;z-index:-1;top:-7px;height:37px}#nette-debug .nette-panel{font:normal normal 12px/1.5 sans-serif;background:white;color:#333}#nette-debug h1{font:normal normal 23px/1.4 Tahoma,sans-serif;color:#575753;background:#EDEAE0;margin:-5px -5px 5px;padding:0 25px 5px 5px}#nette-debug .nette-mode-peek .nette-inner,#nette-debug .nette-mode-float .nette-inner{max-width:700px;max-height:500px;overflow:auto}#nette-debug .nette-panel .nette-icons{display:none}#nette-debug .nette-mode-peek{display:none;position:relative;z-index:23180;padding:5px;min-width:150px;min-height:50px;border:5px solid #EDEAE0;border-radius:5px;-moz-border-radius:5px}#nette-debug .nette-mode-peek h1{cursor:move}#nette-debug .nette-mode-float{position:relative;z-index:23179;padding:5px;min-width:150px;min-height:50px;border:5px solid #EDEAE0;border-radius:5px;-moz-border-radius:5px;opacity:.9;box-shadow:1px 1px 6px #666;-moz-box-shadow:1px 1px 6px rgba(0,0,0,.45);-webkit-box-shadow:1px 1px 6px #666}#nette-debug .nette-focused{z-index:23180;opacity:1}#nette-debug .nette-mode-float h1{cursor:move}#nette-debug .nette-mode-float .nette-icons{display:block;position:absolute;top:0;right:0;font-size:18px}#nette-debug .nette-icons a{color:#575753}#nette-debug .nette-icons a:hover{color:white}</style>
  1970. <!--[if lt IE 8]><style class="nette">#nette-debug-bar img{display:none}#nette-debug-bar li{border-left:1px solid #DCD7C8;padding:0 3px}#nette-debug-logo span{background:#edeae0;display:inline}</style><![endif]-->
  1971. <script id="nette-debug-script">/*<![CDATA[*/var NetteX=NetteX||{};
  1972. (function(){NetteX.Class=function(a){var b=a.constructor||function(){},c;delete a.constructor;if(a.Extends){var d=function(){this.constructor=b};d.prototype=a.Extends.prototype;b.prototype=new d;delete a.Extends}if(a.Static){for(c in a.Static)b[c]=a.Static[c];delete a.Static}for(c in a)b.prototype[c]=a[c];return b};NetteX.Q=NetteX.Class({Static:{factory:function(a){return new NetteX.Q(a)},implement:function(a){var b,c=NetteX.Q.implement,d=NetteX.Q.prototype;for(b in a){c[b]=a[b];d[b]=function(f){return function(){return this.each(c[f],
  1973. arguments)}}(b)}}},constructor:function(a){if(typeof a==="string")a=this._find(document,a);else if(!a||a.nodeType||a.length===void 0||a===window)a=[a];for(var b=0,c=a.length;b<c;b++)if(a[b])this[this.length++]=a[b]},length:0,find:function(a){return new NetteX.Q(this._find(this[0],a))},_find:function(a,b){if(!a||!b)return[];else if(document.querySelectorAll)return a.querySelectorAll(b);else if(b.charAt(0)==="#")return[document.getElementById(b.substring(1))];else{b=b.split(".");var c=a.getElementsByTagName(b[0]||
  1974. "*");if(b[1]){for(var d=[],f=RegExp("(^|\\s)"+b[1]+"(\\s|$)"),i=0,k=c.length;i<k;i++)f.test(c[i].className)&&d.push(c[i]);return d}else return c}},dom:function(){return this[0]},each:function(a,b){for(var c=0,d;c<this.length;c++)if((d=a.apply(this[c],b||[]))!==void 0)return d;return this}});var h=NetteX.Q.factory,e=NetteX.Q.implement;e({bind:function(a,b){if(document.addEventListener&&(a==="mouseenter"||a==="mouseleave")){var c=b;a=a==="mouseenter"?"mouseover":"mouseout";b=function(g){for(var j=g.relatedTarget;j;j=
  1975. j.parentNode)if(j===this)return;c.call(this,g)}}var d=e.data.call(this);d=d.events=d.events||{};if(!d[a]){var f=this,i=d[a]=[],k=e.bind.genericHandler=function(g){if(!g.target)g.target=g.srcElement;if(!g.preventDefault)g.preventDefault=function(){g.returnValue=false};if(!g.stopPropagation)g.stopPropagation=function(){g.cancelBubble=true};g.stopImmediatePropagation=function(){this.stopPropagation();j=i.length};for(var j=0;j<i.length;j++)i[j].call(f,g)};if(document.addEventListener)this.addEventListener(a,
  1976. k,false);else document.attachEvent&&this.attachEvent("on"+a,k)}d[a].push(b)},addClass:function(a){this.className=this.className.replace(/^|\s+|$/g," ").replace(" "+a+" "," ")+" "+a},removeClass:function(a){this.className=this.className.replace(/^|\s+|$/g," ").replace(" "+a+" "," ")},hasClass:function(a){return this.className.replace(/^|\s+|$/g," ").indexOf(" "+a+" ")>-1},show:function(){var a=e.show.display=e.show.display||{},b=this.tagName;if(!a[b]){var c=document.body.appendChild(document.createElement(b));
  1977. a[b]=e.css.call(c,"display")}this.style.display=a[b]},hide:function(){this.style.display="none"},css:function(a){return this.currentStyle?this.currentStyle[a]:window.getComputedStyle?document.defaultView.getComputedStyle(this,null).getPropertyValue(a):void 0},data:function(){return this.nette=this.nette||{}},val:function(){if(!this.nodeName){for(var a=0,b=this.length;a<b;a++)if(this[a].checked)return this[a].value;return null}if(this.nodeName.toLowerCase()==="select"){a=this.selectedIndex;var c=this.options;
  1978. if(a<0)return null;else if(this.type==="select-one")return c[a].value;a=0;var d=[];for(b=c.length;a<b;a++)c[a].selected&&d.push(c[a].value);return d}if(this.type==="checkbox")return this.checked;return this.value.replace(/^\s+|\s+$/g,"")},_trav:function(a,b,c){for(b=b.split(".");a&&!(a.nodeType===1&&(!b[0]||a.tagName.toLowerCase()===b[0])&&(!b[1]||e.hasClass.call(a,b[1])));)a=a[c];return h(a)},closest:function(a){return e._trav(this,a,"parentNode")},prev:function(a){return e._trav(this.previousSibling,
  1979. a,"previousSibling")},next:function(a){return e._trav(this.nextSibling,a,"nextSibling")},offset:function(a){for(var b=this,c=a?{left:-a.left||0,top:-a.top||0}:e.position.call(b);b=b.offsetParent;){c.left+=b.offsetLeft;c.top+=b.offsetTop}if(a)e.position.call(this,{left:-c.left,top:-c.top});else return c},position:function(a){if(a){this.nette&&this.nette.onmove&&this.nette.onmove.call(this,a);this.style.left=(a.left||0)+"px";this.style.top=(a.top||0)+"px"}else return{left:this.offsetLeft,top:this.offsetTop,
  1980. width:this.offsetWidth,height:this.offsetHeight}},draggable:function(a){var b=h(this),c=document.documentElement,d;a=a||{};h(a.handle||this).bind("mousedown",function(f){f.preventDefault();f.stopPropagation();if(e.draggable.binded)return c.onmouseup(f);var i=b[0].offsetLeft-f.clientX,k=b[0].offsetTop-f.clientY;e.draggable.binded=true;d=false;c.onmousemove=function(g){g=g||event;if(!d){a.draggedClass&&b.addClass(a.draggedClass);a.start&&a.start(g,b);d=true}b.position({left:g.clientX+i,top:g.clientY+
  1981. k});return false};c.onmouseup=function(g){if(d){a.draggedClass&&b.removeClass(a.draggedClass);a.stop&&a.stop(g||event,b)}e.draggable.binded=c.onmousemove=c.onmouseup=null;return false}}).bind("click",function(f){if(d){f.stopImmediatePropagation();preventClick=false}})}})})();
  1982. (function(){NetteX.Debug={};var h=NetteX.Q.factory,e=NetteX.Debug.Panel=NetteX.Class({Extends:NetteX.Q,Static:{PEEK:"nette-mode-peek",FLOAT:"nette-mode-float",WINDOW:"nette-mode-window",FOCUSED:"nette-focused",factory:function(a){return new e(a)},_toggle:function(a){var b=a.rel;b=b.charAt(0)==="#"?h(b):h(a)[b.charAt(0)==="<"?"prev":"next"](b.substring(1));if(b.css("display")==="none"){b.show();a.innerHTML=a.innerHTML.replace("\u25ba","\u25bc")}else{b.hide();a.innerHTML=a.innerHTML.replace("\u25bc","\u25ba")}}},
  1983. constructor:function(a){NetteX.Q.call(this,"#nette-debug-panel-"+a.replace("nette-debug-panel-",""))},reposition:function(){if(this.hasClass(e.WINDOW))window.resizeBy(document.documentElement.scrollWidth-document.documentElement.clientWidth,document.documentElement.scrollHeight-document.documentElement.clientHeight);else{this.position(this.position());if(this.position().width)document.cookie=this.dom().id+"="+this.position().left+":"+this.position().top+"; path=/"}},focus:function(){if(this.hasClass(e.WINDOW))this.data().win.focus();
  1984. else{clearTimeout(this.data().blurTimeout);this.addClass(e.FOCUSED).show()}},blur:function(){this.removeClass(e.FOCUSED);if(this.hasClass(e.PEEK)){var a=this;this.data().blurTimeout=setTimeout(function(){a.hide()},50)}},toFloat:function(){this.removeClass(e.WINDOW).removeClass(e.PEEK).addClass(e.FLOAT).show().reposition();return this},toPeek:function(){this.removeClass(e.WINDOW).removeClass(e.FLOAT).addClass(e.PEEK).hide();document.cookie=this.dom().id+"=; path=/"},toWindow:function(){var a=this,
  1985. b,c;c=this.offset();var d=this.dom().id;c.left+=typeof window.screenLeft==="number"?window.screenLeft:window.screenX+10;c.top+=typeof window.screenTop==="number"?window.screenTop:window.screenY+50;if(b=window.open("",d.replace(/-/g,"_"),"left="+c.left+",top="+c.top+",width="+c.width+",height="+(c.height+15)+",resizable=yes,scrollbars=yes")){c=b.document;c.write('<!DOCTYPE html><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><style>'+h("#nette-debug-style").dom().innerHTML+"</style><script>"+
  1986. h("#nette-debug-script").dom().innerHTML+'<\/script><body id="nette-debug">');c.body.innerHTML='<div class="nette-panel nette-mode-window" id="'+d+'">'+this.dom().innerHTML+"</div>";b.NetteX.Debug.Panel.factory(d).initToggler().reposition();c.title=a.find("h1").dom().innerHTML;h([b]).bind("unload",function(){a.toPeek();b.close()});h(c).bind("keyup",function(f){f.keyCode===27&&b.close()});document.cookie=d+"=window; path=/";this.hide().removeClass(e.FLOAT).removeClass(e.PEEK).addClass(e.WINDOW).data().win=
  1987. b}},init:function(){var a=this,b;a.data().onmove=function(c){var d=document,f=window.innerWidth||d.documentElement.clientWidth||d.body.clientWidth;d=window.innerHeight||d.documentElement.clientHeight||d.body.clientHeight;c.left=Math.max(Math.min(c.left,0.8*this.offsetWidth),0.2*this.offsetWidth-f);c.top=Math.max(Math.min(c.top,0.8*this.offsetHeight),this.offsetHeight-d)};h(window).bind("resize",function(){a.reposition()});a.draggable({handle:a.find("h1"),stop:function(){a.toFloat()}}).bind("mouseenter",
  1988. function(){a.focus()}).bind("mouseleave",function(){a.blur()});this.initToggler();a.find(".nette-icons").find("a").bind("click",function(c){this.rel==="close"?a.toPeek():a.toWindow();c.preventDefault()});if(b=document.cookie.match(RegExp(a.dom().id+"=(window|(-?[0-9]+):(-?[0-9]+))")))b[2]?a.toFloat().position({left:b[2],top:b[3]}):a.toWindow();else a.addClass(e.PEEK)},initToggler:function(){var a=this;this.bind("click",function(b){var c=h(b.target).closest("a"),d=c.dom();if(d&&c.hasClass("nette-toggler")){e._toggle(d);
  1989. b.preventDefault();a.reposition()}});return this}});NetteX.Debug.Bar=NetteX.Class({Extends:NetteX.Q,constructor:function(){NetteX.Q.call(this,"#nette-debug-bar")},init:function(){var a=this,b;a.data().onmove=function(c){var d=document,f=window.innerWidth||d.documentElement.clientWidth||d.body.clientWidth;d=window.innerHeight||d.documentElement.clientHeight||d.body.clientHeight;c.left=Math.max(Math.min(c.left,0),this.offsetWidth-f);c.top=Math.max(Math.min(c.top,0),this.offsetHeight-d)};h(window).bind("resize",
  1990. function(){a.position(a.position())});a.draggable({draggedClass:"nette-dragged",stop:function(){document.cookie=a.dom().id+"="+a.position().left+":"+a.position().top+"; path=/"}});a.find("a").bind("click",function(c){if(this.rel==="close"){h("#nette-debug").hide();window.opera&&h("body").show()}else if(this.rel){var d=e.factory(this.rel);if(c.shiftKey)d.toFloat().toWindow();else if(d.hasClass(e.FLOAT)){var f=h(this).offset();d.offset({left:f.left-d.position().width+f.width+4,top:f.top-d.position().height-
  1991. 4}).toPeek()}else d.toFloat().position({left:d.position().left-Math.round(Math.random()*100)-20,top:d.position().top-Math.round(Math.random()*100)-20}).reposition()}c.preventDefault()}).bind("mouseenter",function(){if(!(!this.rel||this.rel==="close"||a.hasClass("nette-dragged"))){var c=e.factory(this.rel);c.focus();if(c.hasClass(e.PEEK)){var d=h(this).offset();c.offset({left:d.left-c.position().width+d.width+4,top:d.top-c.position().height-4})}}}).bind("mouseleave",function(){!this.rel||this.rel===
  1992. "close"||a.hasClass("nette-dragged")||e.factory(this.rel).blur()});if(b=document.cookie.match(RegExp(a.dom().id+"=(-?[0-9]+):(-?[0-9]+)")))a.position({left:b[1],top:b[2]});a.find("a").each(function(){!this.rel||this.rel==="close"||e.factory(this.rel).init()})}})})();/*]]>*/</script>
  1993. <?php foreach($panels
  1994. as$id=>$panel):?>
  1995. <div class="nette-fixed-coords">
  1996. <div class="nette-panel" id="nette-debug-panel-<?php echo$panel['id']?>">
  1997. <div id="nette-debug-<?php echo$panel['id']?>"><?php echo$panel['panel']?></div>
  1998. <div class="nette-icons">
  1999. <a href="#" title="open in window">&curren;</a>
  2000. <a href="#" rel="close" title="close window">&times;</a>
  2001. </div>
  2002. </div>
  2003. </div>
  2004. <?php endforeach?>
  2005. <div class="nette-fixed-coords">
  2006. <div id="nette-debug-bar">
  2007. <ul>
  2008. <li id="nette-debug-logo">&nbsp;<span>NetteX Framework</span></li>
  2009. <?php foreach($panels
  2010. as$panel):if(!$panel['tab'])continue;?>
  2011. <li><?php if($panel['panel']):?><a href="#" rel="<?php echo$panel['id']?>"><?php echo
  2012. trim($panel['tab'])?></a><?php else:echo'<span>',trim($panel['tab']),'</span>';endif?></li>
  2013. <?php endforeach?>
  2014. <li><a href="#" rel="close" title="close debug bar">&times;</a></li>
  2015. </ul>
  2016. </div>
  2017. </div>
  2018. <?php $output=ob_get_clean();?>
  2019. <div id="nette-debug"></div>
  2020. <script>
  2021. (function (onloadOrig) {
  2022. window.onload = function() {
  2023. if (typeof onloadOrig === 'function') onloadOrig();
  2024. var debug = document.getElementById('nette-debug');
  2025. document.body.appendChild(debug);
  2026. debug.innerHTML = <?php echo
  2027. json_encode(@iconv('UTF-16','UTF-8//IGNORE',iconv('UTF-8','UTF-16//IGNORE',$output)))?>;
  2028. for (var i = 0, scripts = debug.getElementsByTagName('script'); i < scripts.length; i++) eval(scripts[i].innerHTML);
  2029. (new NetteX.Debug.Bar).init();
  2030. NetteX.Q.factory(debug).show();
  2031. };
  2032. })(window.onload);
  2033. </script>
  2034. <!-- /NetteX Debug Bar -->
  2035. <?php }static
  2036. function
  2037. tryError(){if(!self::$enabled&&self::$lastError===FALSE){set_error_handler(array(__CLASS__,'_errorHandler'));}self::$lastError=NULL;}static
  2038. function
  2039. catchError(&$error){if(!self::$enabled&&self::$lastError!==FALSE){restore_error_handler();}$error=self::$lastError;self::$lastError=FALSE;return(bool)$error;}private
  2040. static
  2041. function
  2042. defaultMailer($message){$host=isset($_SERVER['HTTP_HOST'])?$_SERVER['HTTP_HOST']:(isset($_SERVER['SERVER_NAME'])?$_SERVER['SERVER_NAME']:'');$parts=str_replace(array("\r\n","\n"),array("\n",PHP_EOL),array('headers'=>"From: noreply@$host\nX-Mailer: NetteX Framework\n",'subject'=>"PHP: An error occurred on the server $host",'body'=>"[".@date('Y-m-d H:i:s')."] $message"));mail(self::$email,$parts['subject'],$parts['body'],$parts['headers']);}static
  2043. function
  2044. addPanel(IDebugPanel$panel){self::$panels[]=$panel;}static
  2045. function
  2046. renderTab($id){switch($id){case'time':?>
  2047. <span title="Execution time"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJ6SURBVDjLjZO7T1NhGMY7Mji6uJgYt8bElTjof6CDg4sMSqIxJsRGB5F4TwQSIg1QKC0KWmkZEEsKtEcSxF5ohV5pKSicXqX3aqGn957z+PUEGopiGJ583/A+v3znvPkJAAjWR0VNJG0kGhKahCFhXcN3YBFfx8Kry6ym4xIzce88/fbWGY2k5WRb77UTTbWuYA9gDGg7EVmSIOF4g5T7HZKuMcSW5djWDyL0uRf0dCc8inYYxTcw9fAiCMBYB3gVj1z7gLhNTjKCqHkYP79KENC9Bq3uxrrqORzy+9D3tPAAccspVx1gWg0KbaZFbGllWFM+xrKkFQudV0CeDfJsjN4+C2nracjunoPq5VXIBrowMK4V1gG1LGyWdbZwCalsBYUyh2KFQzpXxVqkAGswD3+qBDpZwow9iYE5v26/VwfUQnnznyhvjguQYabIIpKpYD1ahI8UTT92MUSFuP5Z/9TBTgOgFrVjp3nakaG/0VmEfpX58pwzjUEquNk362s+PP8XYD/KpYTBHmRg9Wch0QX1R80dCZhYipudYQY2Auib8RmODVCa4hfUK4ngaiiLNFNFdKeCWWscXZMbWy9Unv9/gsIQU09a4pwvUeA3Uapy2C2wCKXL0DqTePLexbWPOv79E8f0UWrencZ2poxciUWZlKssB4bcHeE83NsFuMgpo2iIpMuNa1TNu4XjhggWvb+R2K3wZdLlAZl8Fd9jRb5sD+Xx0RJBx5gdom6VsMEFDyWF0WyCeSOFcDKPnRxZYTQL5Rc/nn1w4oFsBaIhC3r6FRh5erPRhYMyHdeFw4C6zkRhmijM7CnMu0AUZonCDCnRJBqSus5/ABD6Ba5CkQS8AAAAAElFTkSuQmCC"
  2048. /><?php echo
  2049. number_format((microtime(TRUE)-self::$time)*1000,1,'.',' ')?>ms</span>
  2050. <?php
  2051. return;case'memory':?>
  2052. <span title="The peak of allocated memory"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGvSURBVDjLpZO7alZREEbXiSdqJJDKYJNCkPBXYq12prHwBezSCpaidnY+graCYO0DpLRTQcR3EFLl8p+9525xgkRIJJApB2bN+gZmqCouU+NZzVef9isyUYeIRD0RTz482xouBBBNHi5u4JlkgUfx+evhxQ2aJRrJ/oFjUWysXeG45cUBy+aoJ90Sj0LGFY6anw2o1y/mK2ZS5pQ50+2XiBbdCvPk+mpw2OM/Bo92IJMhgiGCox+JeNEksIC11eLwvAhlzuAO37+BG9y9x3FTuiWTzhH61QFvdg5AdAZIB3Mw50AKsaRJYlGsX0tymTzf2y1TR9WwbogYY3ZhxR26gBmocrxMuhZNE435FtmSx1tP8QgiHEvj45d3jNlONouAKrjjzWaDv4CkmmNu/Pz9CzVh++Yd2rIz5tTnwdZmAzNymXT9F5AtMFeaTogJYkJfdsaaGpyO4E62pJ0yUCtKQFxo0hAT1JU2CWNOJ5vvP4AIcKeao17c2ljFE8SKEkVdWWxu42GYK9KE4c3O20pzSpyyoCx4v/6ECkCTCqccKorNxR5uSXgQnmQkw2Xf+Q+0iqQ9Ap64TwAAAABJRU5ErkJggg=="
  2053. /><?php echo
  2054. function_exists('memory_get_peak_usage')?number_format(memory_get_peak_usage()/1000,1,'.',' '):'n/a';?> kB</span>
  2055. <?php
  2056. return;case'dumps':if(!Debug::$dumps)return;?>
  2057. <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIASURBVDjLpVPPaxNREJ6Vt01caH4oWk1T0ZKlGIo9RG+BUsEK4kEP/Q8qPXnpqRdPBf8A8Wahhx7FQ0GF9FJ6UksqwfTSBDGyB5HkkphC9tfb7jfbtyQQTx142byZ75v5ZnZWC4KALmICPy+2DkvKIX2f/POz83LxCL7nrz+WPNcll49DrhM9v7xdO9JW330DuXrrqkFSgig5iR2Cfv3t3gNxOnv5BwU+eZ5HuON5/PMPJZKJ+yKQfpW0S7TxdC6WJaWkyvff1LDaFRAeLZj05MHsiPTS6hua0PUqtwC5sHq9zv9RYWl+nu5cETcnJ1M0M5WlWq3GsX6/T+VymRzHDluZiGYAAsw0TQahV8uyyGq1qFgskm0bHIO/1+sx1rFtchJhArwEyIQ1Gg2WD2A6nWawHQJVDIWgIJfLhQowTIeE9D0mKAU8qPC0220afsWFQoH93W6X7yCDJ+DEBeBmsxnPIJVKxWQVUwry+XyUwBlKMKwA8jqdDhOVCqVAzQDVvXAXhOdGBFgymYwrGoZBmUyGjxCCdF0fSahaFdgoTHRxfTveMCXvWfkuE3Y+f40qhgT/nMitupzApdvT18bu+YeDQwY9Xl4aG9/d/URiMBhQq/dvZMeVghtT17lSZW9/rAKsvPa/r9Fc2dw+Pe0/xI6kM9mT5vtXy+Nw2kU/5zOGRpvuMIu0YAAAAABJRU5ErkJggg==" />variables
  2058. <?php
  2059. return;case'errors':if(!Debug::$errors)return;?>
  2060. <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIsSURBVDjLpVNLSJQBEP7+h6uu62vLVAJDW1KQTMrINQ1vPQzq1GOpa9EppGOHLh0kCEKL7JBEhVCHihAsESyJiE4FWShGRmauu7KYiv6Pma+DGoFrBQ7MzGFmPr5vmDFIYj1mr1WYfrHPovA9VVOqbC7e/1rS9ZlrAVDYHig5WB0oPtBI0TNrUiC5yhP9jeF4X8NPcWfopoY48XT39PjjXeF0vWkZqOjd7LJYrmGasHPCCJbHwhS9/F8M4s8baid764Xi0Ilfp5voorpJfn2wwx/r3l77TwZUvR+qajXVn8PnvocYfXYH6k2ioOaCpaIdf11ivDcayyiMVudsOYqFb60gARJYHG9DbqQFmSVNjaO3K2NpAeK90ZCqtgcrjkP9aUCXp0moetDFEeRXnYCKXhm+uTW0CkBFu4JlxzZkFlbASz4CQGQVBFeEwZm8geyiMuRVntzsL3oXV+YMkvjRsydC1U+lhwZsWXgHb+oWVAEzIwvzyVlk5igsi7DymmHlHsFQR50rjl+981Jy1Fw6Gu0ObTtnU+cgs28AKgDiy+Awpj5OACBAhZ/qh2HOo6i+NeA73jUAML4/qWux8mt6NjW1w599CS9xb0mSEqQBEDAtwqALUmBaG5FV3oYPnTHMjAwetlWksyByaukxQg2wQ9FlccaK/OXA3/uAEUDp3rNIDQ1ctSk6kHh1/jRFoaL4M4snEMeD73gQx4M4PsT1IZ5AfYH68tZY7zv/ApRMY9mnuVMvAAAAAElFTkSuQmCC"
  2061. /><span class="nette-warning"><?php echo
  2062. array_sum(self::$errors)?> errors</span>
  2063. <?php }}static
  2064. function
  2065. renderPanel($id){switch($id){case'dumps':if(!function_exists('NetteX\_netteDumpCb2')){function
  2066. _netteDumpCb2($m){return"$m[1]<a href='#' class='nette-toggler'>$m[2]($m[3]) ".($m[3]<7?'<abbr>&#x25bc;</abbr> </a><code>':'<abbr>&#x25ba;</abbr> </a><code class="nette-hidden">');}}?>
  2067. <style>#nette-debug-dumps h2{font:11pt/1.5 sans-serif;margin:0;padding:2px 8px;background:#3484d2;color:white}#nette-debug-dumps table{width:100%}#nette-debug #nette-debug-dumps a{color:#333;background:transparent}#nette-debug-dumps a abbr{font-family:sans-serif;color:#999}#nette-debug-dumps pre.nette-dump span{color:#c16549}</style>
  2068. <h1>Dumped variables</h1>
  2069. <div class="nette-inner">
  2070. <?php foreach(self::$dumps
  2071. as$item):?>
  2072. <?php if($item['title']):?>
  2073. <h2><?php echo
  2074. htmlspecialchars($item['title'])?></h2>
  2075. <?php endif?>
  2076. <table>
  2077. <?php $i=0?>
  2078. <?php foreach($item['dump']as$key=>$dump):?>
  2079. <tr class="<?php echo$i++%
  2080. 2?'nette-alt':''?>">
  2081. <th><?php echo
  2082. htmlspecialchars($key)?></th>
  2083. <td><pre class="nette-dump"><?php echo
  2084. preg_replace_callback('#^( *)((?>[^(]{1,200}))\((\d+)\) <code>#m','NetteX\_netteDumpCb2',$dump)?></pre></td>
  2085. </tr>
  2086. <?php endforeach?>
  2087. </table>
  2088. <?php endforeach?>
  2089. </div>
  2090. <?php
  2091. return;case'errors':?>
  2092. <h1>Errors</h1>
  2093. <?php $relative=isset($_SERVER['SCRIPT_FILENAME'])?strtr(dirname(dirname($_SERVER['SCRIPT_FILENAME'])),'/',DIRECTORY_SEPARATOR):NULL?>
  2094. <div class="nette-inner">
  2095. <table>
  2096. <?php $i=0?>
  2097. <?php foreach(self::$errors
  2098. as$item=>$count):list($message,$file,$line)=explode('|',$item)?>
  2099. <tr class="<?php echo$i++%
  2100. 2?'nette-alt':''?>">
  2101. <td class="nette-right"><?php echo$count?"$count\xC3\x97":''?></td>
  2102. <td><pre><?php echo
  2103. htmlspecialchars($message),' in ',(self::$editor?'<a href="'.htmlspecialchars(strtr(self::$editor,array('%file'=>rawurlencode($file),'%line'=>$line))).'">':''),htmlspecialchars(($relative?str_replace($relative,"...",$file):$file)),':',$line,(self::$editor?'</a>':'')?></pre></td>
  2104. </tr>
  2105. <?php endforeach?>
  2106. </table>
  2107. </div><?php }}static
  2108. function
  2109. fireLog($message){if(self::$productionMode){return;}elseif(!self::$firebugDetected||headers_sent()){return
  2110. FALSE;}static$payload=array('logs'=>array());$item=array('name'=>'PHP','level'=>'debug','order'=>count($payload['logs']),'time'=>str_pad(number_format((microtime(TRUE)-self::$time)*1000,1,'.',' '),8,'0',STR_PAD_LEFT).' ms','template'=>'','message'=>'','style'=>'background:#767ab6');$args=func_get_args();if(isset($args[0])&&is_string($args[0])){$item['template']=array_shift($args);}if(isset($args[0])&&$args[0]instanceof\Exception){$e=array_shift($args);$trace=$e->getTrace();if(isset($trace[0]['class'])&&$trace[0]['class']===__CLASS__&&($trace[0]['function']==='_shutdownHandler'||$trace[0]['function']==='_errorHandler')){unset($trace[0]);}$item['exc_info']=array($e->getMessage(),$e->getFile(),array());$item['exc_frames']=array();foreach($trace
  2111. as$frame){$frame+=array('file'=>null,'line'=>null,'class'=>null,'type'=>null,'function'=>null,'object'=>null,'args'=>null);$item['exc_info'][2][]=array($frame['file'],$frame['line'],"$frame[class]$frame[type]$frame[function]",$frame['object']);$item['exc_frames'][]=$frame['args'];};$file=str_replace(dirname(dirname(dirname($e->getFile()))),"\xE2\x80\xA6",$e->getFile());$item['template']=($e
  2112. instanceof\ErrorException?'':get_class($e).': ').$e->getMessage().($e->getCode()?' #'.$e->getCode():'').' in '.$file.':'.$e->getLine();array_unshift($trace,array('file'=>$e->getFile(),'line'=>$e->getLine()));}else{$trace=debug_backtrace();if(isset($trace[0]['class'])&&$trace[0]['class']===__CLASS__&&($trace[0]['function']==='_shutdownHandler'||$trace[0]['function']==='_errorHandler')){unset($trace[0]);}}if(isset($args[0])&&in_array($args[0],array(self::DEBUG,self::INFO,self::WARNING,self::ERROR,self::CRITICAL),TRUE)){$item['level']=array_shift($args);}$item['args']=$args;foreach($trace
  2113. as$frame){if(isset($frame['file'])&&is_file($frame['file'])){$item['pathname']=$frame['file'];$item['lineno']=$frame['line'];break;}}$payload['logs'][]=$item;foreach(str_split(base64_encode(@json_encode($payload)),4990)as$k=>$v){header("FireLogger-de11e-$k:$v");}return
  2114. TRUE;}private
  2115. static
  2116. function
  2117. fireDump(&$var,$level=0){if(is_bool($var)||is_null($var)||is_int($var)||is_float($var)){return$var;}elseif(is_string($var)){if(self::$maxLen&&strlen($var)>self::$maxLen){$var=substr($var,0,self::$maxLen)." \xE2\x80\xA6 ";}return@iconv('UTF-16','UTF-8//IGNORE',iconv('UTF-8','UTF-16//IGNORE',$var));}elseif(is_array($var)){static$marker;if($marker===NULL)$marker=uniqid("\x00",TRUE);if(isset($var[$marker])){return"\xE2\x80\xA6RECURSION\xE2\x80\xA6";}elseif($level<self::$maxDepth||!self::$maxDepth){$var[$marker]=TRUE;$res=array();foreach($var
  2118. as$k=>&$v){if($k!==$marker)$res[self::fireDump($k)]=self::fireDump($v,$level+1);}unset($var[$marker]);return$res;}else{return" \xE2\x80\xA6 ";}}elseif(is_object($var)){$arr=(array)$var;static$list=array();if(in_array($var,$list,TRUE)){return"\xE2\x80\xA6RECURSION\xE2\x80\xA6";}elseif($level<self::$maxDepth||!self::$maxDepth){$list[]=$var;$res=array(" \xC2\xBBclass\xC2\xAB"=>get_class($var));foreach($arr
  2119. as$k=>&$v){if($k[0]==="\x00"){$k=substr($k,strrpos($k,"\x00")+1);}$res[self::fireDump($k)]=self::fireDump($v,$level+1);}array_pop($list);return$res;}else{return" \xE2\x80\xA6 ";}}elseif(is_resource($var)){return"resource ".get_resource_type($var);}else{return"unknown type";}}}Debug::_init();use
  2120. NetteX\Config\Config;class
  2121. Configurator
  2122. extends
  2123. Object{public$defaultConfigFile='%appDir%/config.ini';public$defaultServices=array('NetteX\\Application\\Application'=>array(__CLASS__,'createApplication'),'NetteX\\Web\\HttpContext'=>'NetteX\Web\HttpContext','NetteX\\Web\\IHttpRequest'=>'NetteX\Web\HttpRequest','NetteX\\Web\\IHttpResponse'=>'NetteX\Web\HttpResponse','NetteX\\Web\\IUser'=>'NetteX\Web\User','NetteX\\Caching\\ICacheStorage'=>array(__CLASS__,'createCacheStorage'),'NetteX\\Caching\\ICacheJournal'=>array(__CLASS__,'createCacheJournal'),'NetteX\\Web\\Session'=>'NetteX\Web\Session','NetteX\\Loaders\\RobotLoader'=>array(__CLASS__,'createRobotLoader'));function
  2124. detect($name){switch($name){case'environment':if($this->detect('console')){return
  2125. Environment::CONSOLE;}else{return
  2126. Environment::getMode('production')?Environment::PRODUCTION:Environment::DEVELOPMENT;}case'production':if(PHP_SAPI==='cli'){return
  2127. FALSE;}elseif(isset($_SERVER['SERVER_ADDR'])||isset($_SERVER['LOCAL_ADDR'])){$addrs=array();if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){$addrs=preg_split('#,\s*#',$_SERVER['HTTP_X_FORWARDED_FOR']);}if(isset($_SERVER['REMOTE_ADDR'])){$addrs[]=$_SERVER['REMOTE_ADDR'];}$addrs[]=isset($_SERVER['SERVER_ADDR'])?$_SERVER['SERVER_ADDR']:$_SERVER['LOCAL_ADDR'];foreach($addrs
  2128. as$addr){$oct=explode('.',$addr);if($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')))){return
  2129. TRUE;}}return
  2130. FALSE;}else{return
  2131. TRUE;}case'console':return
  2132. PHP_SAPI==='cli';default:return
  2133. NULL;}}function
  2134. loadConfig($file){$name=Environment::getName();if($file
  2135. instanceof
  2136. Config){$config=$file;$file=NULL;}else{if($file===NULL){$file=$this->defaultConfigFile;}$file=Environment::expand($file);$config=Config::fromFile($file,$name);}if($config->variable
  2137. instanceof
  2138. Config){foreach($config->variable
  2139. as$key=>$value){Environment::setVariable($key,$value);}}$iterator=new\RecursiveIteratorIterator($config);foreach($iterator
  2140. as$key=>$value){$tmp=$iterator->getDepth()?$iterator->getSubIterator($iterator->getDepth()-1)->current():$config;$tmp[$key]=Environment::expand($value);}$runServices=array();$context=Environment::getContext();if($config->service
  2141. instanceof
  2142. Config){foreach($config->service
  2143. as$key=>$value){$key=strtr($key,'-','\\');if(is_string($value)){$context->removeService($key);$context->addService($key,$value);}else{if($value->factory){$context->removeService($key);$context->addService($key,$value->factory,isset($value->singleton)?$value->singleton:TRUE,(array)$value->option);}elseif(isset($this->defaultServices[$key])){$context->removeService($key);$context->addService($key,$this->defaultServices[$key],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
  2144. instanceof
  2145. Config){if(PATH_SEPARATOR!==';'&&isset($config->php->include_path)){$config->php->include_path=str_replace(';',PATH_SEPARATOR,$config->php->include_path);}foreach(clone$config->php
  2146. as$key=>$value){if($value
  2147. instanceof
  2148. Config){unset($config->php->$key);foreach($value
  2149. as$k=>$v){$config->php->{"$key.$k"}=$v;}}}foreach($config->php
  2150. as$key=>$value){$key=strtr($key,'-','.');if(!is_scalar($value)){throw
  2151. new\XInvalidStateException("Configuration value for directive '$key' is not scalar.");}if($key==='date.timezone'){date_default_timezone_set($value);}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
  2152. new\XNotSupportedException('Required function ini_set() is disabled.');}}}}}if($config->const
  2153. instanceof
  2154. Config){foreach($config->const
  2155. as$key=>$value){define($key,$value);}}if(isset($config->mode)){foreach($config->mode
  2156. as$mode=>$state){Environment::setMode($mode,$state);}}foreach($runServices
  2157. as$name){$context->getService($name);}return$config;}function
  2158. createContext(){$context=new
  2159. Context;foreach($this->defaultServices
  2160. as$name=>$service){$context->addService($name,$service);}return$context;}static
  2161. function
  2162. createApplication(){if(Environment::getVariable('baseUri',NULL)===NULL){Environment::setVariable('baseUri',Environment::getHttpRequest()->getUri()->getBaseUri());}$context=clone
  2163. Environment::getContext();$context->addService('NetteX\\Application\\IRouter','NetteX\Application\MultiRouter');if(!$context->hasService('NetteX\\Application\\IPresenterLoader')){$context->addService('NetteX\\Application\\IPresenterLoader',function(){return
  2164. new
  2165. NetteX\Application\PresenterLoader(Environment::getVariable('appDir'));});}$application=new
  2166. NetteX\Application\Application;$application->setContext($context);$application->catchExceptions=Environment::isProduction();return$application;}static
  2167. function
  2168. createCacheStorage(){$context=new
  2169. Context;$context->addService('NetteX\\Caching\\ICacheJournal',array(__CLASS__,'createCacheJournal'));$dir=Environment::getVariable('tempDir').'/cache';umask(0000);@mkdir($dir,0777);return
  2170. new
  2171. NetteX\Caching\FileStorage($dir,$context);}static
  2172. function
  2173. createCacheJournal(){{return
  2174. new
  2175. NetteX\Caching\FileJournal(Environment::getVariable('tempDir').'/cache');}}static
  2176. function
  2177. createRobotLoader($options){$loader=new
  2178. NetteX\Loaders\RobotLoader;$loader->autoRebuild=isset($options['autoRebuild'])?$options['autoRebuild']:!Environment::isProduction();$loader->setCacheStorage(Environment::getService('NetteX\\Caching\\ICacheStorage'));if(isset($options['directory'])){$loader->addDirectory($options['directory']);}else{foreach(array('appDir','libsDir')as$var){if($dir=Environment::getVariable($var,NULL)){$loader->addDirectory($dir);}}}$loader->register();return$loader;}}final
  2179. class
  2180. Environment{const
  2181. DEVELOPMENT='development';const
  2182. PRODUCTION='production';const
  2183. CONSOLE='console';private
  2184. static$configurator;private
  2185. static$modes=array();private
  2186. static$config;private
  2187. static$context;private
  2188. static$vars=array();private
  2189. static$aliases=array('getHttpContext'=>'NetteX\\Web\\HttpContext','getHttpRequest'=>'NetteX\\Web\\IHttpRequest','getHttpResponse'=>'NetteX\\Web\\IHttpResponse','getApplication'=>'NetteX\\Application\\Application','getUser'=>'NetteX\\Web\\IUser','getRobotLoader'=>'NetteX\\Loaders\\RobotLoader');final
  2190. function
  2191. __construct(){throw
  2192. new\LogicException("Cannot instantiate static class ".get_class($this));}static
  2193. function
  2194. setConfigurator(Configurator$configurator){self::$configurator=$configurator;}static
  2195. function
  2196. getConfigurator(){if(self::$configurator===NULL){self::$configurator=new
  2197. Configurator;}return
  2198. self::$configurator;}static
  2199. function
  2200. setName($name){if(!isset(self::$vars['environment'])){self::setVariable('environment',$name,FALSE);}else{throw
  2201. new\XInvalidStateException('Environment name has already been set.');}}static
  2202. function
  2203. getName(){$name=self::getVariable('environment',NULL);if($name===NULL){$name=self::getConfigurator()->detect('environment');self::setVariable('environment',$name,FALSE);}return$name;}static
  2204. function
  2205. setMode($mode,$value=TRUE){self::$modes[$mode]=(bool)$value;}static
  2206. function
  2207. getMode($mode){if(isset(self::$modes[$mode])){return
  2208. self::$modes[$mode];}else{return
  2209. self::$modes[$mode]=self::getConfigurator()->detect($mode);}}static
  2210. function
  2211. isConsole(){return
  2212. self::getMode('console');}static
  2213. function
  2214. isProduction(){return
  2215. self::getMode('production');}static
  2216. function
  2217. setVariable($name,$value,$expand=TRUE){if(!is_string($value)){$expand=FALSE;}self::$vars[$name]=array($value,(bool)$expand);}static
  2218. function
  2219. 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];}elseif(func_num_args()>1){return$default;}else{throw
  2220. new\XInvalidStateException("Unknown environment variable '$name'.");}}}static
  2221. function
  2222. getVariables(){$res=array();foreach(self::$vars
  2223. as$name=>$foo){$res[$name]=self::getVariable($name);}return$res;}static
  2224. function
  2225. expand($var){static$livelock;if(is_string($var)&&strpos($var,'%')!==FALSE){return@preg_replace_callback('#%([a-z0-9_-]*)%#i',function($m)use(&$livelock){list(,$var)=$m;if($var==='')return'%';if(isset($livelock[$var])){throw
  2226. new\XInvalidStateException("Circular reference detected for variables: ".implode(', ',array_keys($livelock)).".");}try{$livelock[$var]=TRUE;$val=Environment::getVariable($var);unset($livelock[$var]);}catch(\Exception$e){$livelock=array();throw$e;}if(!is_scalar($val)){throw
  2227. new\XInvalidStateException("Environment variable '$var' is not scalar.");}return$val;},$var);}return$var;}static
  2228. function
  2229. getContext(){if(self::$context===NULL){self::$context=self::getConfigurator()->createContext();}return
  2230. self::$context;}static
  2231. function
  2232. getService($name,array$options=NULL){return
  2233. self::getContext()->getService($name,$options);}static
  2234. function
  2235. setServiceAlias($service,$alias){self::$aliases['get'.ucfirst($alias)]=$service;}static
  2236. function
  2237. __callStatic($name,$args){if(isset(self::$aliases[$name])){return
  2238. self::getContext()->getService(self::$aliases[$name],$args);}else{throw
  2239. new\XMemberAccessException("Call to undefined static method NetteX\\Environment::$name().");}}static
  2240. function
  2241. getHttpRequest(){return
  2242. self::getContext()->getService(self::$aliases[__FUNCTION__]);}static
  2243. function
  2244. getHttpContext(){return
  2245. self::getContext()->getService(self::$aliases[__FUNCTION__]);}static
  2246. function
  2247. getHttpResponse(){return
  2248. self::getContext()->getService(self::$aliases[__FUNCTION__]);}static
  2249. function
  2250. getApplication(){return
  2251. self::getContext()->getService(self::$aliases[__FUNCTION__]);}static
  2252. function
  2253. getUser(){return
  2254. self::getContext()->getService(self::$aliases[__FUNCTION__]);}static
  2255. function
  2256. getRobotLoader(){return
  2257. self::getContext()->getService(self::$aliases[__FUNCTION__]);}static
  2258. function
  2259. getCache($namespace=''){return
  2260. new
  2261. NetteX\Caching\Cache(self::getService('NetteX\\Caching\\ICacheStorage'),$namespace);}static
  2262. function
  2263. getSession($namespace=NULL){$handler=self::getService('NetteX\\Web\\Session');return$namespace===NULL?$handler:$handler->getNamespace($namespace);}static
  2264. function
  2265. loadConfig($file=NULL){return
  2266. self::$config=self::getConfigurator()->loadConfig($file);}static
  2267. function
  2268. getConfig($key=NULL,$default=NULL){if(func_num_args()){return
  2269. isset(self::$config[$key])?self::$config[$key]:$default;}else{return
  2270. self::$config;}}}}namespace NetteX\Forms{use
  2271. NetteX;use
  2272. NetteX\Web\Html;abstract
  2273. class
  2274. FormControl
  2275. extends
  2276. NetteX\Component
  2277. implements
  2278. IFormControl{public
  2279. 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
  2280. __construct($caption=NULL){$this->monitor('NetteX\Forms\Form');parent::__construct();$this->control=Html::el('input');$this->label=Html::el('label');$this->caption=$caption;$this->rules=new
  2281. Rules($this);}protected
  2282. function
  2283. attached($form){if(!$this->disabled&&$form
  2284. instanceof
  2285. Form&&$form->isAnchored()&&$form->isSubmitted()){$this->htmlName=NULL;$this->loadHttpData();}}function
  2286. getForm($need=TRUE){return$this->lookup('NetteX\Forms\Form',$need);}function
  2287. getHtmlName(){if($this->htmlName===NULL){$s='';$name=$this->getName();$obj=$this->lookup('NetteX\Forms\FormContainer',TRUE);while(!($obj
  2288. instanceof
  2289. Form)){$s="[$name]$s";$name=$obj->getName();$obj=$obj->lookup('NetteX\Forms\FormContainer',TRUE);}$name.=$s;if(is_numeric($name)||in_array($name,array('attributes','children','elements','focus','length','reset','style','submit','onsubmit'))){$name.='_';}$this->htmlName=$name;}return$this->htmlName;}function
  2290. setHtmlId($id){$this->htmlId=$id;return$this;}function
  2291. getHtmlId(){if($this->htmlId===FALSE){return
  2292. 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
  2293. setAttribute($name,$value=TRUE){$this->control->$name=$value;return$this;}function
  2294. setOption($key,$value){if($value===NULL){unset($this->options[$key]);}else{$this->options[$key]=$value;}return$this;}final
  2295. function
  2296. getOption($key,$default=NULL){return
  2297. isset($this->options[$key])?$this->options[$key]:$default;}final
  2298. function
  2299. getOptions(){return$this->options;}function
  2300. setTranslator(NetteX\ITranslator$translator=NULL){$this->translator=$translator;return$this;}final
  2301. function
  2302. getTranslator(){if($this->translator===TRUE){return$this->getForm(FALSE)?$this->getForm()->getTranslator():NULL;}return$this->translator;}function
  2303. translate($s,$count=NULL){$translator=$this->getTranslator();return$translator===NULL||$s==NULL?$s:$translator->translate($s,$count);}function
  2304. setValue($value){$this->value=$value;return$this;}function
  2305. getValue(){return$this->value;}function
  2306. isFilled(){return(string)$this->getValue()!=='';}function
  2307. setDefaultValue($value){$form=$this->getForm(FALSE);if(!$form||!$form->isAnchored()||!$form->isSubmitted()){$this->setValue($value);}return$this;}function
  2308. loadHttpData(){$path=explode('[',strtr(str_replace(array('[]',']'),'',$this->getHtmlName()),'.','_'));$this->setValue(NetteX\ArrayTools::get($this->getForm()->getHttpData(),$path));}function
  2309. setDisabled($value=TRUE){$this->disabled=(bool)$value;return$this;}function
  2310. isDisabled(){return$this->disabled;}function
  2311. getControl(){$this->setOption('rendered',TRUE);$control=clone$this->control;$control->name=$this->getHtmlName();$control->disabled=$this->disabled;$control->id=$this->getHtmlId();$control->required=$this->isRequired();$rules=self::exportRules($this->rules);$rules=substr(json_encode($rules),1,-1);$rules=preg_replace('#"([a-z0-9]+)":#i','$1:',$rules);$rules=preg_replace('#(?<!\\\\)"([^\\\\\',]*)"#i',"'$1'",$rules);$control->data('nette-rules',$rules?$rules:NULL);return$control;}function
  2312. getLabel($caption=NULL){$label=clone$this->label;$label->for=$this->getHtmlId();if($caption!==NULL){$label->setText($this->translate($caption));}elseif($this->caption
  2313. instanceof
  2314. Html){$label->add($this->caption);}else{$label->setText($this->translate($this->caption));}return$label;}final
  2315. function
  2316. getControlPrototype(){return$this->control;}final
  2317. function
  2318. getLabelPrototype(){return$this->label;}function
  2319. addRule($operation,$message=NULL,$arg=NULL){$this->rules->addRule($operation,$message,$arg);return$this;}function
  2320. addCondition($operation,$value=NULL){return$this->rules->addCondition($operation,$value);}function
  2321. addConditionOn(IFormControl$control,$operation,$value=NULL){return$this->rules->addConditionOn($control,$operation,$value);}final
  2322. function
  2323. getRules(){return$this->rules;}final
  2324. function
  2325. setRequired($message=NULL){return$this->addRule(Form::FILLED,$message);}final
  2326. function
  2327. isRequired(){foreach($this->rules
  2328. as$rule){if($rule->type===Rule::VALIDATOR&&!$rule->isNegative&&$rule->operation===Form::FILLED){return
  2329. TRUE;}}return
  2330. FALSE;}private
  2331. static
  2332. function
  2333. exportRules($rules){$payload=array();foreach($rules
  2334. as$rule){if(!is_string($rule->operation)){continue;}elseif($rule->type===Rule::VALIDATOR){$item=array('op'=>($rule->isNegative?'~':'').$rule->operation,'msg'=>$rules->formatMessage($rule,FALSE));}elseif($rule->type===Rule::CONDITION){$item=array('op'=>($rule->isNegative?'~':'').$rule->operation,'rules'=>self::exportRules($rule->subRules),'control'=>$rule->control->getHtmlName());if($rule->subRules->getToggles()){$item['toggle']=$rule->subRules->getToggles();}}if(is_array($rule->arg)){foreach($rule->arg
  2335. as$key=>$value){$item['arg'][$key]=$value
  2336. instanceof
  2337. IFormControl?(object)array('control'=>$value->getHtmlName()):$value;}}elseif($rule->arg!==NULL){$item['arg']=$rule->arg
  2338. instanceof
  2339. IFormControl?(object)array('control'=>$rule->arg->getHtmlName()):$rule->arg;}$payload[]=$item;}return$payload;}static
  2340. function
  2341. 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
  2342. instanceof
  2343. IFormControl?$item->value:$item)){return
  2344. TRUE;}}}return
  2345. FALSE;}static
  2346. function
  2347. validateFilled(IFormControl$control){return$control->isFilled();}static
  2348. function
  2349. validateValid(IFormControl$control){return$control->rules->validate(TRUE);}function
  2350. addError($message){if(!in_array($message,$this->errors,TRUE)){$this->errors[]=$message;}$this->getForm()->addError($message);}function
  2351. getErrors(){return$this->errors;}function
  2352. hasErrors(){return(bool)$this->errors;}function
  2353. cleanErrors(){$this->errors=array();}}class
  2354. Button
  2355. extends
  2356. FormControl{function
  2357. __construct($caption=NULL){parent::__construct($caption);$this->control->type='button';}function
  2358. getLabel($caption=NULL){return
  2359. NULL;}function
  2360. getControl($caption=NULL){$control=parent::getControl();$control->value=$this->translate($caption===NULL?$this->caption:$caption);return$control;}}class
  2361. Checkbox
  2362. extends
  2363. FormControl{function
  2364. __construct($label=NULL){parent::__construct($label);$this->control->type='checkbox';$this->value=FALSE;}function
  2365. setValue($value){$this->value=is_scalar($value)?(bool)$value:FALSE;return$this;}function
  2366. getControl(){return
  2367. parent::getControl()->checked($this->value);}}use
  2368. NetteX\Web\HttpUploadedFile;class
  2369. FileUpload
  2370. extends
  2371. FormControl{function
  2372. __construct($label=NULL){parent::__construct($label);$this->control->type='file';}protected
  2373. function
  2374. attached($form){if($form
  2375. instanceof
  2376. Form){if($form->getMethod()!==Form::POST){throw
  2377. new\XInvalidStateException('File upload requires method POST.');}$form->getElementPrototype()->enctype='multipart/form-data';}parent::attached($form);}function
  2378. setValue($value){if(is_array($value)){$this->value=new
  2379. HttpUploadedFile($value);}elseif($value
  2380. instanceof
  2381. HttpUploadedFile){$this->value=$value;}else{$this->value=new
  2382. HttpUploadedFile(NULL);}return$this;}function
  2383. isFilled(){return$this->value
  2384. instanceof
  2385. HttpUploadedFile&&$this->value->isOK();}static
  2386. function
  2387. validateFileSize(FileUpload$control,$limit){$file=$control->getValue();return$file
  2388. instanceof
  2389. HttpUploadedFile&&$file->getSize()<=$limit;}static
  2390. function
  2391. validateMimeType(FileUpload$control,$mimeType){$file=$control->getValue();if($file
  2392. instanceof
  2393. HttpUploadedFile){$type=strtolower($file->getContentType());$mimeTypes=is_array($mimeType)?$mimeType:explode(',',$mimeType);if(in_array($type,$mimeTypes,TRUE)){return
  2394. TRUE;}if(in_array(preg_replace('#/.*#','/*',$type),$mimeTypes,TRUE)){return
  2395. TRUE;}}return
  2396. FALSE;}static
  2397. function
  2398. validateImage(FileUpload$control){$file=$control->getValue();return$file
  2399. instanceof
  2400. HttpUploadedFile&&$file->isImage();}}class
  2401. HiddenField
  2402. extends
  2403. FormControl{private$forcedValue;function
  2404. __construct($forcedValue=NULL){parent::__construct();$this->control->type='hidden';$this->value=(string)$forcedValue;$this->forcedValue=$forcedValue;}function
  2405. getLabel($caption=NULL){return
  2406. NULL;}function
  2407. setValue($value){$this->value=is_scalar($value)?(string)$value:'';return$this;}function
  2408. getControl(){return
  2409. parent::getControl()->value($this->forcedValue===NULL?$this->value:$this->forcedValue)->data('nette-rules',NULL);}}class
  2410. SubmitButton
  2411. extends
  2412. Button
  2413. implements
  2414. ISubmitterControl{public$onClick;public$onInvalidClick;private$validationScope=TRUE;function
  2415. __construct($caption=NULL){parent::__construct($caption);$this->control->type='submit';}function
  2416. 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
  2417. isSubmittedBy(){return$this->getForm()->isSubmitted()===$this;}function
  2418. setValidationScope($scope){$this->validationScope=(bool)$scope;$this->control->formnovalidate=!$this->validationScope;return$this;}final
  2419. function
  2420. getValidationScope(){return$this->validationScope;}function
  2421. click(){$this->onClick($this);}static
  2422. function
  2423. validateSubmitted(ISubmitterControl$control){return$control->isSubmittedBy();}}class
  2424. ImageButton
  2425. extends
  2426. SubmitButton{function
  2427. __construct($src=NULL,$alt=NULL){parent::__construct();$this->control->type='image';$this->control->src=$src;$this->control->alt=$alt;}function
  2428. getHtmlName(){$name=parent::getHtmlName();return
  2429. strpos($name,'[')===FALSE?$name:$name.'[]';}function
  2430. loadHttpData(){$path=$this->getHtmlName();$path=explode('[',strtr(str_replace(']','',strpos($path,'[')===FALSE?$path.'.x':substr($path,0,-2)),'.','_'));$this->setValue(NetteX\ArrayTools::get($this->getForm()->getHttpData(),$path)!==NULL);}}class
  2431. SelectBox
  2432. extends
  2433. FormControl{private$items=array();protected$allowed=array();private$skipFirst=FALSE;private$useKeys=TRUE;function
  2434. __construct($label=NULL,array$items=NULL,$size=NULL){parent::__construct($label);$this->control->setName('select');$this->control->size=$size>1?(int)$size:NULL;if($items!==NULL){$this->setItems($items);}}function
  2435. getValue(){$allowed=$this->allowed;if($this->skipFirst){$allowed=array_slice($allowed,1,count($allowed),TRUE);}return
  2436. is_scalar($this->value)&&isset($allowed[$this->value])?$this->value:NULL;}function
  2437. getRawValue(){return
  2438. is_scalar($this->value)?$this->value:NULL;}function
  2439. isFilled(){$value=$this->getValue();return
  2440. is_array($value)?count($value)>0:$value!==NULL;}function
  2441. 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
  2442. function
  2443. isFirstSkipped(){return$this->skipFirst;}final
  2444. function
  2445. areKeysUsed(){return$this->useKeys;}function
  2446. setItems(array$items,$useKeys=TRUE){$this->items=$items;$this->allowed=array();$this->useKeys=(bool)$useKeys;foreach($items
  2447. as$key=>$value){if(!is_array($value)){$value=array($key=>$value);}foreach($value
  2448. as$key2=>$value2){if(!$this->useKeys){if(!is_scalar($value2)){throw
  2449. new\InvalidArgumentException("All items must be scalar.");}$key2=$value2;}if(isset($this->allowed[$key2])){throw
  2450. new\InvalidArgumentException("Items contain duplication for key '$key2'.");}$this->allowed[$key2]=$value2;}}return$this;}final
  2451. function
  2452. getItems(){return$this->items;}function
  2453. getSelectedItem(){if(!$this->useKeys){return$this->getValue();}else{$value=$this->getValue();return$value===NULL?NULL:$this->allowed[$value];}}function
  2454. getControl(){$control=parent::getControl();if($this->skipFirst){reset($this->items);$control->data('nette-empty-value',$this->useKeys?key($this->items):current($this->items));}$selected=$this->getValue();$selected=is_array($selected)?array_flip($selected):array($selected=>TRUE);$option=NetteX\Web\Html::el('option');foreach($this->items
  2455. as$key=>$value){if(!is_array($value)){$value=array($key=>$value);$dest=$control;}else{$dest=$control->create('optgroup')->label($key);}foreach($value
  2456. as$key2=>$value2){if($value2
  2457. instanceof
  2458. NetteX\Web\Html){$dest->add((string)$value2->selected(isset($selected[$key2])));}else{$key2=$this->useKeys?$key2:$value2;$value2=$this->translate($value2);$dest->add((string)$option->value($key2===$value2?NULL:$key2)->selected(isset($selected[$key2]))->setText($value2));}}}return$control;}}class
  2459. MultiSelectBox
  2460. extends
  2461. SelectBox{function
  2462. getValue(){$allowed=array_keys($this->allowed);if($this->isFirstSkipped()){unset($allowed[0]);}return
  2463. array_intersect($this->getRawValue(),$allowed);}function
  2464. 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
  2465. as$val){if(is_scalar($val)){$res[]=$val;}}return$res;}function
  2466. getSelectedItem(){if(!$this->areKeysUsed()){return$this->getValue();}else{$res=array();foreach($this->getValue()as$value){$res[$value]=$this->allowed[$value];}return$res;}}function
  2467. getHtmlName(){return
  2468. parent::getHtmlName().'[]';}function
  2469. getControl(){$control=parent::getControl();$control->multiple=TRUE;return$control;}}class
  2470. RadioList
  2471. extends
  2472. FormControl{protected$separator;protected$container;protected$items=array();function
  2473. __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
  2474. getValue($raw=FALSE){return
  2475. is_scalar($this->value)&&($raw||isset($this->items[$this->value]))?$this->value:NULL;}function
  2476. isFilled(){return$this->getValue()!==NULL;}function
  2477. setItems(array$items){$this->items=$items;return$this;}final
  2478. function
  2479. getItems(){return$this->items;}final
  2480. function
  2481. getSeparatorPrototype(){return$this->separator;}final
  2482. function
  2483. getContainerPrototype(){return$this->container;}function
  2484. getControl($key=NULL){if($key===NULL){$container=clone$this->container;$separator=(string)$this->separator;}elseif(!isset($this->items[$key])){return
  2485. NULL;}$control=parent::getControl();$id=$control->id;$counter=-1;$value=$this->value===NULL?NULL:(string)$this->getValue();$label=Html::el('label');foreach($this->items
  2486. 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
  2487. instanceof
  2488. 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);$control->data('nette-rules',NULL);}return$container;}function
  2489. getLabel($caption=NULL){$label=parent::getLabel($caption);$label->for=NULL;return$label;}}use
  2490. NetteX\String;abstract
  2491. class
  2492. TextBase
  2493. extends
  2494. FormControl{protected$emptyValue='';protected$filters=array();function
  2495. setValue($value){$this->value=is_scalar($value)?(string)$value:'';return$this;}function
  2496. getValue(){$value=$this->value;foreach($this->filters
  2497. as$filter){$value=(string)$filter($value);}return$value===$this->translate($this->emptyValue)?'':$value;}function
  2498. setEmptyValue($value){$this->emptyValue=(string)$value;return$this;}final
  2499. function
  2500. getEmptyValue(){return$this->emptyValue;}function
  2501. addFilter($filter){$this->filters[]=callbackX($filter);return$this;}function
  2502. getControl(){$control=parent::getControl();foreach($this->getRules()as$rule){if($rule->type===Rule::VALIDATOR&&!$rule->isNegative&&($rule->operation===Form::LENGTH||$rule->operation===Form::MAX_LENGTH)){$control->maxlength=is_array($rule->arg)?$rule->arg[1]:$rule->arg;}}if($this->emptyValue!==''){$control->data('nette-empty-value',$this->translate($this->emptyValue));}return$control;}function
  2503. addRule($operation,$message=NULL,$arg=NULL){if($operation===Form::FLOAT){$this->addFilter(callbackX(__CLASS__,'filterFloat'));}return
  2504. parent::addRule($operation,$message,$arg);}static
  2505. function
  2506. validateMinLength(TextBase$control,$length){return
  2507. String::length($control->getValue())>=$length;}static
  2508. function
  2509. validateMaxLength(TextBase$control,$length){return
  2510. String::length($control->getValue())<=$length;}static
  2511. function
  2512. validateLength(TextBase$control,$range){if(!is_array($range)){$range=array($range,$range);}$len=String::length($control->getValue());return($range[0]===NULL||$len>=$range[0])&&($range[1]===NULL||$len<=$range[1]);}static
  2513. function
  2514. 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)String::match($control->getValue(),"(^$localPart@(?:$domain?\\.)+[-$chars]{2,19}\\z)i");}static
  2515. function
  2516. validateUrl(TextBase$control){$chars="a-z0-9\x80-\xFF";return(bool)String::match($control->getValue(),"#^(?:https?://|)(?:[$chars](?:[-$chars]{0,61}[$chars])?\\.)+[-$chars]{2,19}(/\S*)?$#i");}static
  2517. function
  2518. validateRegexp(TextBase$control,$regexp){return(bool)String::match($control->getValue(),$regexp);}static
  2519. function
  2520. validatePattern(TextBase$control,$pattern){return(bool)String::match($control->getValue(),"\x01^($pattern)$\x01u");}static
  2521. function
  2522. validateInteger(TextBase$control){return(bool)String::match($control->getValue(),'/^-?[0-9]+$/');}static
  2523. function
  2524. validateFloat(TextBase$control){return(bool)String::match($control->getValue(),'/^-?[0-9]*[.,]?[0-9]+$/');}static
  2525. function
  2526. validateRange(TextBase$control,$range){return($range[0]===NULL||$control->getValue()>=$range[0])&&($range[1]===NULL||$control->getValue()<=$range[1]);}static
  2527. function
  2528. filterFloat($s){return
  2529. str_replace(array(' ',','),array('','.'),$s);}}class
  2530. TextArea
  2531. extends
  2532. TextBase{function
  2533. __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
  2534. getControl(){$control=parent::getControl();$control->setText($this->getValue()===''?$this->translate($this->emptyValue):$this->value);return$control;}}class
  2535. TextInput
  2536. extends
  2537. TextBase{function
  2538. __construct($label=NULL,$cols=NULL,$maxLength=NULL){parent::__construct($label);$this->control->type='text';$this->control->size=$cols;$this->control->maxlength=$maxLength;$this->filters[]=callbackX($this,'sanitize');$this->value='';}function
  2539. sanitize($value){if($this->control->maxlength&&NetteX\String::length($value)>$this->control->maxlength){$value=iconv_substr($value,0,$this->control->maxlength,'UTF-8');}return
  2540. NetteX\String::trim(strtr($value,"\r\n",' '));}function
  2541. setType($type){$this->control->type=$type;return$this;}function
  2542. setPasswordMode($mode=TRUE){$this->control->type=$mode?'password':'text';return$this;}function
  2543. getControl(){$control=parent::getControl();foreach($this->getRules()as$rule){if($rule->isNegative||$rule->type!==Rule::VALIDATOR){}elseif($rule->operation===Form::RANGE&&$control->type!=='text'){list($control->min,$control->max)=$rule->arg;}elseif($rule->operation===Form::PATTERN){$control->pattern=$rule->arg;}}if($control->type!=='password'){$control->value=$this->getValue()===''?$this->translate($this->emptyValue):$this->value;}return$control;}}class
  2544. FormGroup
  2545. extends
  2546. NetteX\Object{protected$controls;private$options=array();function
  2547. __construct(){$this->controls=new\SplObjectStorage;}function
  2548. add(){foreach(func_get_args()as$num=>$item){if($item
  2549. instanceof
  2550. IFormControl){$this->controls->attach($item);}elseif($item
  2551. instanceof\Traversable||is_array($item)){foreach($item
  2552. as$control){$this->controls->attach($control);}}else{throw
  2553. new\InvalidArgumentException("Only IFormControl items are allowed, the #$num parameter is invalid.");}}return$this;}function
  2554. getControls(){return
  2555. iterator_to_array($this->controls);}function
  2556. setOption($key,$value){if($value===NULL){unset($this->options[$key]);}else{$this->options[$key]=$value;}return$this;}final
  2557. function
  2558. getOption($key,$default=NULL){return
  2559. isset($this->options[$key])?$this->options[$key]:$default;}final
  2560. function
  2561. getOptions(){return$this->options;}}class
  2562. ConventionalRenderer
  2563. extends
  2564. NetteX\Object
  2565. implements
  2566. 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$counter;function
  2567. 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
  2568. setClientScript(){trigger_error(__METHOD__.'() is deprecated; use unobstructive JavaScript instead.',E_USER_WARNING);return$this;}protected
  2569. function
  2570. init(){$wrapper=&$this->wrappers['control'];foreach($this->form->getControls()as$control){if($control->isRequired()&&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
  2571. 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
  2572. renderEnd(){$s='';foreach($this->form->getControls()as$control){if($control
  2573. instanceof
  2574. HiddenField&&!$control->getOption('rendered')){$s.=(string)$control->getControl();}}if($s){$s=$this->getWrapper('hidden container')->setHtml($s)."\n";}return$s.$this->form->getElementPrototype()->endTag()."\n";}function
  2575. 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
  2576. as$error){$item=clone$li;if($error
  2577. instanceof
  2578. Html){$item->add($error);}else{$item->setText($error);}$ul->add($item);}return"\n".$ul->render(0);}}function
  2579. 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
  2580. instanceof
  2581. Html?clone$container:Html::el($container);$s.="\n".$container->startTag();$text=$group->getOption('label');if($text
  2582. instanceof
  2583. 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
  2584. instanceof
  2585. 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
  2586. renderControls($parent){if(!($parent
  2587. instanceof
  2588. FormContainer||$parent
  2589. instanceof
  2590. FormGroup)){throw
  2591. new\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
  2592. instanceof
  2593. HiddenField||$control->getForm(FALSE)!==$this->form){}elseif($control
  2594. instanceof
  2595. 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
  2596. renderPair(IFormControl$control){$pair=$this->getWrapper('pair container');$pair->add($this->renderLabel($control));$pair->add($this->renderControl($control));$pair->class($this->getValue($control->isRequired()?'pair .required':'pair .optional'),TRUE);$pair->class($control->getOption('class'),TRUE);if(++$this->counter
  2597. %
  2598. 2)$pair->class($this->getValue('pair .odd'),TRUE);$pair->id=$control->getOption('id');return$pair->render(0);}function
  2599. renderPairMulti(array$controls){$s=array();foreach($controls
  2600. as$control){if(!($control
  2601. instanceof
  2602. IFormControl)){throw
  2603. new\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
  2604. renderLabel(IFormControl$control){$head=$this->getWrapper('label container');if($control
  2605. instanceof
  2606. Checkbox||$control
  2607. instanceof
  2608. Button){return$head->setHtml(($head->getName()==='td'||$head->getName()==='th')?'&nbsp;':'');}else{$label=$control->getLabel();$suffix=$this->getValue('label suffix').($control->isRequired()?$this->getValue('label requiredsuffix'):'');if($label
  2609. instanceof
  2610. Html){$label->setHtml($label->getHtml().$suffix);$suffix='';}return$head->setHtml((string)$label.$suffix);}}function
  2611. renderControl(IFormControl$control){$body=$this->getWrapper('control container');if($this->counter
  2612. %
  2613. 2)$body->class($this->getValue('control .odd'),TRUE);$description=$control->getOption('description');if($description
  2614. instanceof
  2615. Html){$description=' '.$control->getOption('description');}elseif(is_string($description)){$description=' '.$this->getWrapper('control description')->setText($control->translate($description));}else{$description='';}if($control->isRequired()){$description=$this->getValue('control requiredsuffix').$description;}if($this->getValue('control errors')){$description.=$this->renderErrors($control);}if($control
  2616. instanceof
  2617. Checkbox||$control
  2618. instanceof
  2619. Button){return$body->setHtml((string)$control->getControl().(string)$control->getLabel().$description);}else{return$body->setHtml((string)$control->getControl().$description);}}protected
  2620. function
  2621. getWrapper($name){$data=$this->getValue($name);return$data
  2622. instanceof
  2623. Html?clone$data:Html::el($data);}protected
  2624. function
  2625. getValue($name){$name=explode(' ',$name);$data=&$this->wrappers[$name[0]][$name[1]];return$data;}}final
  2626. class
  2627. Rule
  2628. extends
  2629. NetteX\Object{const
  2630. CONDITION=1;const
  2631. VALIDATOR=2;const
  2632. FILTER=3;public$control;public$operation;public$arg;public$type;public$isNegative=FALSE;public$message;public$subRules;}final
  2633. class
  2634. Rules
  2635. extends
  2636. NetteX\Object
  2637. implements\IteratorAggregate{const
  2638. VALIDATE_PREFIX='validate';public
  2639. static$defaultMessages=array(Form::PROTECTION=>'Security token did not match. Possible CSRF attack.');private$rules=array();private$parent;private$toggles=array();private$control;function
  2640. __construct(IFormControl$control){$this->control=$control;}function
  2641. addRule($operation,$message=NULL,$arg=NULL){$rule=new
  2642. Rule;$rule->control=$this->control;$rule->operation=$operation;$this->adjustOperation($rule);$rule->arg=$arg;$rule->type=Rule::VALIDATOR;if($message===NULL&&is_string($rule->operation)&&isset(self::$defaultMessages[$rule->operation])){$rule->message=self::$defaultMessages[$rule->operation];}else{$rule->message=$message;}$this->rules[]=$rule;return$this;}function
  2643. addCondition($operation,$arg=NULL){return$this->addConditionOn($this->control,$operation,$arg);}function
  2644. addConditionOn(IFormControl$control,$operation,$arg=NULL){$rule=new
  2645. Rule;$rule->control=$control;$rule->operation=$operation;$this->adjustOperation($rule);$rule->arg=$arg;$rule->type=Rule::CONDITION;$rule->subRules=new
  2646. self($this->control);$rule->subRules->parent=$this;$this->rules[]=$rule;return$rule->subRules;}function
  2647. elseCondition(){$rule=clone
  2648. end($this->parent->rules);$rule->isNegative=!$rule->isNegative;$rule->subRules=new
  2649. self($this->parent->control);$rule->subRules->parent=$this->parent;$this->parent->rules[]=$rule;return$rule->subRules;}function
  2650. endCondition(){return$this->parent;}function
  2651. toggle($id,$hide=TRUE){$this->toggles[$id]=$hide;return$this;}function
  2652. validate($onlyCheck=FALSE){foreach($this->rules
  2653. as$rule){if($rule->control->isDisabled())continue;$success=($rule->isNegative
  2654. xor$this->getCallback($rule)->invoke($rule->control,$rule->arg));if($rule->type===Rule::CONDITION&&$success){if(!$rule->subRules->validate($onlyCheck)){return
  2655. FALSE;}}elseif($rule->type===Rule::VALIDATOR&&!$success){if(!$onlyCheck){$rule->control->addError(self::formatMessage($rule,TRUE));}return
  2656. FALSE;}}return
  2657. TRUE;}final
  2658. function
  2659. getIterator(){return
  2660. new\ArrayIterator($this->rules);}final
  2661. function
  2662. getToggles(){return$this->toggles;}private
  2663. function
  2664. 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
  2665. new\InvalidArgumentException("Unknown operation$operation for control '{$rule->control->name}'.");}}private
  2666. function
  2667. getCallback($rule){$op=$rule->operation;if(is_string($op)&&strncmp($op,':',1)===0){return
  2668. callbackX(get_class($rule->control),self::VALIDATE_PREFIX.ltrim($op,':'));}else{return
  2669. callbackX($op);}}static
  2670. function
  2671. formatMessage($rule,$withValue){$message=$rule->message;if(!isset($message)){$message=self::$defaultMessages[$rule->operation];}if($translator=$rule->control->getForm()->getTranslator()){$message=$translator->translate($message,is_int($rule->arg)?$rule->arg:NULL);}$message=vsprintf(preg_replace('#%(name|label|value)#','%$0',$message),(array)$rule->arg);$message=str_replace('%name',$rule->control->getName(),$message);$message=str_replace('%label',$rule->control->translate($rule->control->caption),$message);if($withValue&&strpos($message,'%value')!==FALSE){$message=str_replace('%value',$rule->control->getValue(),$message);}return$message;}}}namespace NetteX\Loaders{use
  2672. NetteX;use
  2673. NetteX\String;use
  2674. NetteX\Caching\Cache;class
  2675. RobotLoader
  2676. extends
  2677. AutoLoader{public$scanDirs;public$ignoreDirs='.*, *.old, *.bak, *.tmp, temp';public$acceptFiles='*.php, *.php5';public$autoRebuild=TRUE;private$list=array();private$files;private$rebuilt=FALSE;private$cacheStorage;function
  2678. __construct(){if(!extension_loaded('tokenizer')){throw
  2679. new\Exception("PHP extension Tokenizer is not loaded.");}}function
  2680. 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('NetteX\Loaders\NetteXLoader',FALSE)){NetteXLoader::getInstance()->unregister();}parent::register();}function
  2681. tryLoad($type){$type=ltrim(strtolower($type),'\\');if(isset($this->list[$type][0])&&!is_file($this->list[$type][0])){unset($this->list[$type]);}if(!isset($this->list[$type])){$trace=debug_backtrace();$initiator=&$trace[2]['function'];if($initiator==='class_exists'||$initiator==='interface_exists'){$this->list[$type]=FALSE;if($this->autoRebuild&&$this->rebuilt){$this->getCache()->save($this->getKey(),$this->list,array(Cache::CONSTS=>'NetteX\Framework::REVISION'));}}if($this->autoRebuild&&!$this->rebuilt){$this->rebuild();}}if(isset($this->list[$type][0])){LimitedScope::load($this->list[$type][0]);self::$count++;}}function
  2682. rebuild(){$this->getCache()->save($this->getKey(),callbackX($this,'_rebuildCallback'),array(Cache::CONSTS=>'NetteX\Framework::REVISION'));$this->rebuilt=TRUE;}function
  2683. _rebuildCallback(){foreach($this->list
  2684. as$pair){if($pair)$this->files[$pair[0]]=$pair[1];}foreach(array_unique($this->scanDirs)as$dir){$this->scanDirectory($dir);}$this->files=NULL;return$this->list;}function
  2685. getIndexedClasses(){$res=array();foreach($this->list
  2686. as$class=>$pair){if($pair)$res[$pair[2]]=$pair[0];}return$res;}function
  2687. addDirectory($path){foreach((array)$path
  2688. as$val){$real=realpath($val);if($real===FALSE){throw
  2689. new\XDirectoryNotFoundException("Directory '$val' not found.");}$this->scanDirs[]=$real;}}private
  2690. function
  2691. addClass($class,$file,$time){$lClass=strtolower($class);if(isset($this->list[$lClass][0])&&$this->list[$lClass][0]!==$file&&is_file($this->list[$lClass][0])){$e=new\XInvalidStateException("Ambiguous class '$class' resolution; defined in $file and in ".$this->list[$lClass][0].".");{throw$e;}}$this->list[$lClass]=array($file,$time,$class);}private
  2692. function
  2693. scanDirectory($dir){if(is_dir($dir)){$disallow=array();$iterator=NetteX\Finder::findFiles(String::split($this->acceptFiles,'#[,\s]+#'))->filter(function($file)use(&$disallow){return!isset($disallow[$file->getPathname()]);})->from($dir)->exclude(String::split($this->ignoreDirs,'#[,\s]+#'))->filter($filter=function($dir)use(&$disallow){$path=$dir->getPathname();if(is_file("$path/netterobots.txt")){foreach(file("$path/netterobots.txt")as$s){if($matches=String::match($s,'#^disallow\\s*:\\s*(\\S+)#i')){$disallow[$path.str_replace('/',DIRECTORY_SEPARATOR,rtrim('/'.ltrim($matches[1],'/'),'/'))]=TRUE;}}}return!isset($disallow[$path]);});$filter(new\SplFileInfo($dir));}else{$iterator=new\ArrayIterator(array(new\SplFileInfo($dir)));}foreach($iterator
  2694. as$entry){$path=$entry->getPathname();if(!isset($this->files[$path])||$this->files[$path]!==$entry->getMTime()){$this->scanScript($path);}}}private
  2695. function
  2696. scanScript($file){$T_NAMESPACE=PHP_VERSION_ID<50300?-1:T_NAMESPACE;$T_NS_SEPARATOR=PHP_VERSION_ID<50300?-1:T_NS_SEPARATOR;$expected=FALSE;$namespace='';$level=$minLevel=0;$time=filemtime($file);$s=file_get_contents($file);if($matches=String::match($s,'#//nette'.'loader=(\S*)#')){foreach(explode(',',$matches[1])as$name){$this->addClass($name,$file,$time);}return;}foreach(token_get_all($s)as$token){if(is_array($token)){switch($token[0]){case
  2697. T_COMMENT:case
  2698. T_DOC_COMMENT:case
  2699. T_WHITESPACE:continue
  2700. 2;case$T_NS_SEPARATOR:case
  2701. T_STRING:if($expected){$name.=$token[1];}continue
  2702. 2;case$T_NAMESPACE:case
  2703. T_CLASS:case
  2704. T_INTERFACE:$expected=$token[0];$name='';continue
  2705. 2;case
  2706. T_CURLY_OPEN:case
  2707. T_DOLLAR_OPEN_CURLY_BRACES:$level++;}}if($expected){switch($expected){case
  2708. T_CLASS:case
  2709. T_INTERFACE:if($level===$minLevel){$this->addClass($namespace.$name,$file,$time);}break;case$T_NAMESPACE:$namespace=$name?$name.'\\':'';$minLevel=$token==='{'?1:0;}$expected=NULL;}if($token==='{'){$level++;}elseif($token==='}'){$level--;}}}function
  2710. setCacheStorage(NetteX\Caching\ICacheStorage$storage){$this->cacheStorage=$storage;return$this;}function
  2711. getCacheStorage(){return$this->cacheStorage;}protected
  2712. function
  2713. getCache(){if(!$this->cacheStorage){trigger_error('Missing cache storage.',E_USER_WARNING);$this->cacheStorage=new
  2714. NetteX\Caching\DummyStorage;}return
  2715. new
  2716. Cache($this->cacheStorage,'NetteX.RobotLoader');}protected
  2717. function
  2718. getKey(){return
  2719. md5("v2|$this->ignoreDirs|$this->acceptFiles|".implode('|',$this->scanDirs));}}}namespace NetteX\Mail{use
  2720. NetteX;class
  2721. MailMimePart
  2722. extends
  2723. NetteX\Object{const
  2724. ENCODING_BASE64='base64';const
  2725. ENCODING_7BIT='7bit';const
  2726. ENCODING_8BIT='8bit';const
  2727. ENCODING_QUOTED_PRINTABLE='quoted-printable';const
  2728. EOL="\r\n";const
  2729. LINE_LENGTH=76;private$headers=array();private$parts=array();private$body;function
  2730. setHeader($name,$value,$append=FALSE){if(!$name||preg_match('#[^a-z0-9-]#i',$name)){throw
  2731. new\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
  2732. as$email=>$name){if($name!==NULL&&!NetteX\String::checkEncoding($name)){throw
  2733. new\InvalidArgumentException("Name is not valid UTF-8 string.");}if(!preg_match('#^[^@",\s]+@[^@",\s]+\.[a-z]{2,10}$#i',$email)){throw
  2734. new\InvalidArgumentException("Email address '$email' is not valid.");}if(preg_match('#[\r\n]#',$name)){throw
  2735. new\InvalidArgumentException("Name must not contain line separator.");}$tmp[$email]=$name;}}else{$value=(string)$value;if(!NetteX\String::checkEncoding($value)){throw
  2736. new\InvalidArgumentException("Header is not valid UTF-8 string.");}$this->headers[$name]=preg_replace('#[\r\n]+#',' ',$value);}return$this;}function
  2737. getHeader($name){return
  2738. isset($this->headers[$name])?$this->headers[$name]:NULL;}function
  2739. clearHeader($name){unset($this->headers[$name]);return$this;}function
  2740. getEncodedHeader($name){$offset=strlen($name)+2;if(!isset($this->headers[$name])){return
  2741. NULL;}elseif(is_array($this->headers[$name])){$s='';foreach($this->headers[$name]as$email=>$name){if($name!=NULL){$s.=self::encodeHeader(strpbrk($name,'.,;<@>()[]"=?')?'"'.addcslashes($name,'"\\').'"':$name,$offset);$email=" <$email>";}$email.=',';if($s!==''&&$offset+strlen($email)>self::LINE_LENGTH){$s.=self::EOL."\t";$offset=1;}$s.=$email;$offset+=strlen($email);}return
  2742. substr($s,0,-1);}else{return
  2743. self::encodeHeader($this->headers[$name],$offset);}}function
  2744. getHeaders(){return$this->headers;}function
  2745. setContentType($contentType,$charset=NULL){$this->setHeader('Content-Type',$contentType.($charset?"; charset=$charset":''));return$this;}function
  2746. setEncoding($encoding){$this->setHeader('Content-Transfer-Encoding',$encoding);return$this;}function
  2747. getEncoding(){return$this->getHeader('Content-Transfer-Encoding');}function
  2748. addPart(MailMimePart$part=NULL){return$this->parts[]=$part===NULL?new
  2749. self:$part;}function
  2750. setBody($body){$this->body=$body;return$this;}function
  2751. getBody(){return$this->body;}function
  2752. generateMessage(){$output='';$boundary='--------'.md5(uniqid('',TRUE));foreach($this->headers
  2753. 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
  2754. self::ENCODING_QUOTED_PRINTABLE:$output.=function_exists('quoted_printable_encode')?quoted_printable_encode($body):self::encodeQuotedPrintable($body);break;case
  2755. self::ENCODING_BASE64:$output.=rtrim(chunk_split(base64_encode($body),self::LINE_LENGTH,self::EOL));break;case
  2756. self::ENCODING_7BIT:$body=preg_replace('#[\x80-\xFF]+#','',$body);case
  2757. self::ENCODING_8BIT:$body=str_replace(array("\x00","\r"),'',$body);$body=str_replace("\n",self::EOL,$body);$output.=$body;break;default:throw
  2758. new\XInvalidStateException('Unknown encoding.');}}if($this->parts){if(substr($output,-strlen(self::EOL))!==self::EOL)$output.=self::EOL;foreach($this->parts
  2759. as$part){$output.='--'.$boundary.self::EOL.$part->generateMessage().self::EOL;}$output.='--'.$boundary.'--';}return$output;}private
  2760. static
  2761. function
  2762. encodeHeader($s,&$offset=0){if(strspn($s,"!\"#$%&\'()*+,-./0123456789:;<>@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^`abcdefghijklmnopqrstuvwxyz{|}=? _\r\n\t")===strlen($s)&&($offset+strlen($s)<=self::LINE_LENGTH)){$offset+=strlen($s);return$s;}$o=str_replace("\n ","\n\t",substr(iconv_mime_encode(str_repeat(' ',$offset),$s,array('scheme'=>'B','input-charset'=>'UTF-8','output-charset'=>'UTF-8')),$offset+2));$offset=strlen($o)-strrpos($o,"\n");return$o;}}use
  2763. NetteX\String;class
  2764. Mail
  2765. extends
  2766. MailMimePart{const
  2767. HIGH=1;const
  2768. NORMAL=3;const
  2769. LOW=5;public
  2770. static$defaultMailer='NetteX\Mail\SendmailMailer';public
  2771. static$defaultHeaders=array('MIME-Version'=>'1.0','X-Mailer'=>'NetteX Framework');private$mailer;private$attachments=array();private$inlines=array();private$html;private$basePath;function
  2772. __construct(){foreach(self::$defaultHeaders
  2773. as$name=>$value){$this->setHeader($name,$value);}$this->setHeader('Date',date('r'));}function
  2774. setFrom($email,$name=NULL){$this->setHeader('From',$this->formatEmail($email,$name));return$this;}function
  2775. getFrom(){return$this->getHeader('From');}function
  2776. addReplyTo($email,$name=NULL){$this->setHeader('Reply-To',$this->formatEmail($email,$name),TRUE);return$this;}function
  2777. setSubject($subject){$this->setHeader('Subject',$subject);return$this;}function
  2778. getSubject(){return$this->getHeader('Subject');}function
  2779. addTo($email,$name=NULL){$this->setHeader('To',$this->formatEmail($email,$name),TRUE);return$this;}function
  2780. addCc($email,$name=NULL){$this->setHeader('Cc',$this->formatEmail($email,$name),TRUE);return$this;}function
  2781. addBcc($email,$name=NULL){$this->setHeader('Bcc',$this->formatEmail($email,$name),TRUE);return$this;}private
  2782. function
  2783. formatEmail($email,$name){if(!$name&&preg_match('#^(.+) +<(.*)>$#',$email,$matches)){return
  2784. array($matches[2]=>$matches[1]);}else{return
  2785. array($email=>$name);}}function
  2786. setReturnPath($email){$this->setHeader('Return-Path',$email);return$this;}function
  2787. getReturnPath(){return$this->getHeader('From');}function
  2788. setPriority($priority){$this->setHeader('X-Priority',(int)$priority);return$this;}function
  2789. getPriority(){return$this->getHeader('X-Priority');}function
  2790. setHtmlBody($html,$basePath=NULL){$this->html=$html;$this->basePath=$basePath;return$this;}function
  2791. getHtmlBody(){return$this->html;}function
  2792. addEmbeddedFile($file,$content=NULL,$contentType=NULL){return$this->inlines[$file]=$this->createAttachment($file,$content,$contentType,'inline')->setHeader('Content-ID','<'.md5(uniqid('',TRUE)).'>');}function
  2793. addAttachment($file,$content=NULL,$contentType=NULL){return$this->attachments[]=$this->createAttachment($file,$content,$contentType,'attachment');}private
  2794. function
  2795. createAttachment($file,$content,$contentType,$disposition){$part=new
  2796. MailMimePart;if($content===NULL){if(!is_file($file)){throw
  2797. new\XFileNotFoundException("File '$file' not found.");}if(!$contentType&&$info=getimagesize($file)){$contentType=$info['mime'];}$part->setBody(file_get_contents($file));}else{$part->setBody((string)$content);}$part->setContentType($contentType?$contentType:'application/octet-stream');$part->setEncoding(preg_match('#(multipart|message)/#A',$contentType)?self::ENCODING_8BIT:self::ENCODING_BASE64);$part->setHeader('Content-Disposition',$disposition.'; filename="'.String::fixEncoding(basename($file)).'"');return$part;}function
  2798. send(){$this->getMailer()->send($this->build());}function
  2799. setMailer(IMailer$mailer){$this->mailer=$mailer;return$this;}function
  2800. getMailer(){if($this->mailer===NULL){$this->mailer=is_object(self::$defaultMailer)?self::$defaultMailer:new
  2801. self::$defaultMailer;}return$this->mailer;}protected
  2802. function
  2803. 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
  2804. 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
  2805. as$name=>$value){$tmp->addPart($value);}}$alt->setContentType('text/html','UTF-8')->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','UTF-8')->setEncoding(preg_match('#[\x80-\xFF]#',$text)?self::ENCODING_8BIT:self::ENCODING_7BIT)->setBody($text);return$mail;}protected
  2806. function
  2807. buildHtml(){if($this->html
  2808. instanceof
  2809. NetteX\Templates\ITemplate){$this->html->mail=$this;if($this->basePath===NULL&&$this->html
  2810. instanceof
  2811. NetteX\Templates\IFileTemplate){$this->basePath=dirname($this->html->getFile());}$this->html=$this->html->__toString(TRUE);}if($this->basePath!==FALSE){$cids=array();$matches=String::matchAll($this->html,'#(src\s*=\s*|background\s*=\s*|url\()(["\'])(?![a-z]+:|[/\\#])(.+?)\\2#i',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()&&$matches=String::match($this->html,'#<title>(.+?)</title>#is')){$this->setSubject(html_entity_decode($matches[1],ENT_QUOTES,'UTF-8'));}}protected
  2812. function
  2813. buildText(){$text=$this->getBody();if($text
  2814. instanceof
  2815. NetteX\Templates\ITemplate){$text->mail=$this;$this->setBody($text->__toString(TRUE));}elseif($text==NULL&&$this->html!=NULL){$text=String::replace($this->html,array('#<(style|script|head).*</\\1>#Uis'=>'','#<t[dh][ >]#i'=>" $0",'#[ \t\r\n]+#'=>' ','#<(/?p|/?h\d|li|br|/tr)[ >/]#i'=>"\n$0"));$text=html_entity_decode(strip_tags($text),ENT_QUOTES,'UTF-8');$this->setBody(trim($text));}}}class
  2816. SendmailMailer
  2817. extends
  2818. NetteX\Object
  2819. implements
  2820. IMailer{function
  2821. send(Mail$mail){$tmp=clone$mail;$tmp->setHeader('Subject',NULL);$tmp->setHeader('To',NULL);$parts=explode(Mail::EOL.Mail::EOL,$tmp->generateMessage(),2);NetteX\Debug::tryError();$res=mail(str_replace(Mail::EOL,PHP_EOL,$mail->getEncodedHeader('To')),str_replace(Mail::EOL,PHP_EOL,$mail->getEncodedHeader('Subject')),str_replace(Mail::EOL,PHP_EOL,$parts[1]),str_replace(Mail::EOL,PHP_EOL,$parts[0]));if(NetteX\Debug::catchError($e)){throw
  2822. new\XInvalidStateException($e->getMessage());}elseif(!$res){throw
  2823. new\XInvalidStateException('Unable to send email.');}}}class
  2824. SmtpMailer
  2825. extends
  2826. NetteX\Object
  2827. implements
  2828. IMailer{private$connection;private$host;private$port;private$username;private$password;private$secure;private$timeout;function
  2829. __construct(array$options=array()){if($options['host']){$this->host=$options['host'];$this->port=isset($options['port'])?(int)$options['port']:NULL;}else{$this->host=ini_get('SMTP');$this->port=(int)ini_get('smtp_port');}$this->username=isset($options['username'])?$options['username']:'';$this->password=isset($options['password'])?$options['password']:'';$this->secure=isset($options['secure'])?$options['secure']:'';$this->timeout=isset($options['timeout'])?(int)$options['timeout']:20;if(!$this->port){$this->port=$this->secure==='ssl'?465:25;}}function
  2830. send(Mail$mail){$data=$mail->generateMessage();$this->connect();$from=$mail->getHeader('From');if($from){$from=array_keys($from);$this->write("MAIL FROM:<$from[0]>",250);}$recipients=array_merge((array)$mail->getHeader('To'),(array)$mail->getHeader('Cc'),(array)$mail->getHeader('Bcc'));foreach($recipients
  2831. as$email=>$name){$this->write("RCPT TO:<$email>",array(250,251));}$this->write('DATA',354);$data=preg_replace('#^\.#m','..',$data);$this->write($data);$this->write('.',250);$this->write('QUIT',221);$this->disconnect();}private
  2832. function
  2833. connect(){$this->connection=@fsockopen(($this->secure==='ssl'?'ssl://':'').$this->host,$this->port,$errno,$error,$this->timeout);if(!$this->connection){throw
  2834. new
  2835. SmtpException($error,$errno);}stream_set_timeout($this->connection,$this->timeout,0);$this->read();$self=isset($_SERVER['SERVER_NAME'])?$_SERVER['SERVER_NAME']:'localhost';$this->write("EHLO $self");if((int)$this->read()!==250){$this->write("HELO $self",250);}if($this->secure==='tls'){$this->write('STARTTLS',220);if(!stream_socket_enable_crypto($this->connection,TRUE,STREAM_CRYPTO_METHOD_TLS_CLIENT)){throw
  2836. new
  2837. SmtpException('Unable to connect via TLS.');}}if($this->username!=NULL&&$this->password!=NULL){$this->write('AUTH LOGIN',334);$this->write(base64_encode($this->username),334,'username');$this->write(base64_encode($this->password),235,'password');}}private
  2838. function
  2839. disconnect(){fclose($this->connection);$this->connection=NULL;}private
  2840. function
  2841. write($line,$expectedCode=NULL,$message=NULL){fwrite($this->connection,$line.Mail::EOL);if($expectedCode&&!in_array((int)$this->read(),(array)$expectedCode)){throw
  2842. new
  2843. SmtpException('SMTP server did not accept '.($message?$message:$line));}}private
  2844. function
  2845. read(){$s='';while(($line=fgets($this->connection,1e3))!=NULL){$s.=$line;if(substr($line,3,1)===' '){break;}}return$s;}}class
  2846. SmtpException
  2847. extends\Exception{}}namespace NetteX\Reflection{use
  2848. NetteX;class
  2849. Annotation
  2850. extends
  2851. NetteX\Object
  2852. implements
  2853. IAnnotation{function
  2854. __construct(array$values){foreach($values
  2855. as$k=>$v){$this->$k=$v;}}function
  2856. __toString(){return$this->value;}}use
  2857. NetteX\String;/**
  2858. * Annotations support for PHP.
  2859. *
  2860. * @author David Grudl
  2861. * @Annotation
  2862. */final
  2863. class
  2864. AnnotationsParser{const
  2865. RE_STRING='\'(?:\\\\.|[^\'\\\\])*\'|"(?:\\\\.|[^"\\\\])*"';const
  2866. RE_IDENTIFIER='[_a-zA-Z\x7F-\xFF][_a-zA-Z0-9\x7F-\xFF-]*';public
  2867. static$useReflection;private
  2868. static$cache;private
  2869. static$timestamps;final
  2870. function
  2871. __construct(){throw
  2872. new\LogicException("Cannot instantiate static class ".get_class($this));}static
  2873. function
  2874. getAll(\Reflector$r){if($r
  2875. instanceof\ReflectionClass){$type=$r->getName();$member='';}elseif($r
  2876. instanceof\ReflectionMethod){$type=$r->getDeclaringClass()->getName();$member=$r->getName();}else{$type=$r->getDeclaringClass()->getName();$member='$'.$r->getName();}if(!self::$useReflection){$file=$r
  2877. instanceof\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
  2878. self::$cache[$type][$member];}if(self::$useReflection===NULL){self::$useReflection=(bool)NetteX\Reflection\ClassReflection::from(__CLASS__)->getDocComment();}if(self::$useReflection){return
  2879. 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
  2880. self::$cache[$type][$member];}else{return
  2881. self::$cache[$type][$member]=array();}}}private
  2882. static
  2883. function
  2884. parseComment($comment){static$tokens=array('true'=>TRUE,'false'=>FALSE,'null'=>NULL,''=>TRUE);$matches=String::matchAll(trim($comment,'/*'),'~
  2885. (?<=\s)@('.self::RE_IDENTIFIER.')[ \t]* ## annotation
  2886. (
  2887. \((?>'.self::RE_STRING.'|[^\'")@]+)+\)| ## (value)
  2888. [^(@\r\n][^@\r\n]*|) ## value
  2889. ~xi');$res=array();foreach($matches
  2890. as$match){list(,$name,$value)=$match;if(substr($value,0,1)==='('){$items=array();$key='';$val=TRUE;$value[0]=',';while($m=String::match($value,'#\s*,\s*(?>('.self::RE_IDENTIFIER.')\s*=\s*)?('.self::RE_STRING.'|[^\'"),\s][^\'"),]*)#A')){$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\ArrayObject($value,\ArrayObject::ARRAY_AS_PROPS):$value;}}return$res;}private
  2891. static
  2892. function
  2893. parseScript($file){$T_NAMESPACE=PHP_VERSION_ID<50300?-1:T_NAMESPACE;$T_NS_SEPARATOR=PHP_VERSION_ID<50300?-1:T_NS_SEPARATOR;$s=file_get_contents($file);if(String::match($s,'#//nette'.'loader=(\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
  2894. T_DOC_COMMENT:$docComment=$token[1];case
  2895. T_WHITESPACE:case
  2896. T_COMMENT:continue
  2897. 2;case
  2898. T_STRING:case$T_NS_SEPARATOR:case
  2899. T_VARIABLE:if($expected){$name.=$token[1];}continue
  2900. 2;case
  2901. T_FUNCTION:case
  2902. T_VAR:case
  2903. T_PUBLIC:case
  2904. T_PROTECTED:case$T_NAMESPACE:case
  2905. T_CLASS:case
  2906. T_INTERFACE:$expected=$token[0];$name=NULL;continue
  2907. 2;case
  2908. T_STATIC:case
  2909. T_ABSTRACT:case
  2910. T_FINAL:continue
  2911. 2;case
  2912. T_CURLY_OPEN:case
  2913. T_DOLLAR_OPEN_CURLY_BRACES:$level++;}}if($expected){switch($expected){case
  2914. T_CLASS:case
  2915. T_INTERFACE:$class=$namespace.$name;$classLevel=$level;$name='';case
  2916. T_FUNCTION:if($token==='&')continue
  2917. 2;case
  2918. T_VAR:case
  2919. T_PUBLIC:case
  2920. T_PROTECTED:if($class&&$name!==NULL&&$docComment){self::$cache[$class][$name]=self::parseComment($docComment);}break;case$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
  2921. static
  2922. function
  2923. getCache(){return
  2924. NetteX\Environment::getCache('NetteX.Annotations');}}use
  2925. NetteX\ObjectMixin;use
  2926. NetteX\Annotations;class
  2927. ExtensionReflection
  2928. extends\ReflectionExtension{function
  2929. __toString(){return'Extension '.$this->getName();}function
  2930. getClasses(){$res=array();foreach(parent::getClassNames()as$val){$res[$val]=new
  2931. ClassReflection($val);}return$res;}function
  2932. getFunctions(){foreach($res=parent::getFunctions()as$key=>$val){$res[$key]=new
  2933. FunctionReflection($key);}return$res;}static
  2934. function
  2935. getReflection(){return
  2936. new
  2937. NetteX\Reflection\ClassReflection(get_called_class());}function
  2938. __call($name,$args){return
  2939. ObjectMixin::call($this,$name,$args);}function&__get($name){return
  2940. ObjectMixin::get($this,$name);}function
  2941. __set($name,$value){return
  2942. ObjectMixin::set($this,$name,$value);}function
  2943. __isset($name){return
  2944. ObjectMixin::has($this,$name);}function
  2945. __unset($name){throw
  2946. new\XMemberAccessException("Cannot unset the property {$this->reflection->name}::\$$name.");}}class
  2947. FunctionReflection
  2948. extends\ReflectionFunction{private$value;function
  2949. __construct($name){parent::__construct($this->value=$name);}function
  2950. __toString(){return'Function '.$this->getName().'()';}function
  2951. getClosure(){return$this->isClosure()?$this->value:NULL;}function
  2952. getExtension(){return($name=$this->getExtensionName())?new
  2953. ExtensionReflection($name):NULL;}function
  2954. getParameters(){foreach($res=parent::getParameters()as$key=>$val){$res[$key]=new
  2955. ParameterReflection($this->value,$val->getName());}return$res;}static
  2956. function
  2957. getReflection(){return
  2958. new
  2959. NetteX\Reflection\ClassReflection(get_called_class());}function
  2960. __call($name,$args){return
  2961. ObjectMixin::call($this,$name,$args);}function&__get($name){return
  2962. ObjectMixin::get($this,$name);}function
  2963. __set($name,$value){return
  2964. ObjectMixin::set($this,$name,$value);}function
  2965. __isset($name){return
  2966. ObjectMixin::has($this,$name);}function
  2967. __unset($name){throw
  2968. new\XMemberAccessException("Cannot unset the property {$this->reflection->name}::\$$name.");}}class
  2969. MethodReflection
  2970. extends\ReflectionMethod{static
  2971. function
  2972. from($class,$method){return
  2973. new
  2974. static(is_object($class)?get_class($class):$class,$method);}function
  2975. 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
  2976. 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
  2977. getCallback(){return
  2978. new
  2979. NetteX\Callback(parent::getDeclaringClass()->getName(),$this->getName());}function
  2980. __toString(){return'Method '.parent::getDeclaringClass()->getName().'::'.$this->getName().'()';}function
  2981. getDeclaringClass(){return
  2982. new
  2983. ClassReflection(parent::getDeclaringClass()->getName());}function
  2984. getPrototype(){$prototype=parent::getPrototype();return
  2985. new
  2986. MethodReflection($prototype->getDeclaringClass()->getName(),$prototype->getName());}function
  2987. getExtension(){return($name=$this->getExtensionName())?new
  2988. ExtensionReflection($name):NULL;}function
  2989. getParameters(){$me=array(parent::getDeclaringClass()->getName(),$this->getName());foreach($res=parent::getParameters()as$key=>$val){$res[$key]=new
  2990. ParameterReflection($me,$val->getName());}return$res;}function
  2991. hasAnnotation($name){$res=AnnotationsParser::getAll($this);return!empty($res[$name]);}function
  2992. getAnnotation($name){$res=AnnotationsParser::getAll($this);return
  2993. isset($res[$name])?end($res[$name]):NULL;}function
  2994. getAnnotations(){return
  2995. AnnotationsParser::getAll($this);}static
  2996. function
  2997. getReflection(){return
  2998. new
  2999. NetteX\Reflection\ClassReflection(get_called_class());}function
  3000. __call($name,$args){return
  3001. ObjectMixin::call($this,$name,$args);}function&__get($name){return
  3002. ObjectMixin::get($this,$name);}function
  3003. __set($name,$value){return
  3004. ObjectMixin::set($this,$name,$value);}function
  3005. __isset($name){return
  3006. ObjectMixin::has($this,$name);}function
  3007. __unset($name){throw
  3008. new\XMemberAccessException("Cannot unset the property {$this->reflection->name}::\$$name.");}}class
  3009. ParameterReflection
  3010. extends\ReflectionParameter{private$function;function
  3011. __construct($function,$parameter){parent::__construct($this->function=$function,$parameter);}function
  3012. getClass(){return($ref=parent::getClass())?new
  3013. ClassReflection($ref->getName()):NULL;}function
  3014. getClassName(){return($tmp=NetteX\String::match($this,'#>\s+([a-z0-9_\\\\]+)#i'))?$tmp[1]:NULL;}function
  3015. getDeclaringClass(){return($ref=parent::getDeclaringClass())?new
  3016. ClassReflection($ref->getName()):NULL;}function
  3017. getDeclaringFunction(){return
  3018. is_array($this->function)?new
  3019. MethodReflection($this->function[0],$this->function[1]):new
  3020. FunctionReflection($this->function);}static
  3021. function
  3022. getReflection(){return
  3023. new
  3024. NetteX\Reflection\ClassReflection(get_called_class());}function
  3025. __call($name,$args){return
  3026. ObjectMixin::call($this,$name,$args);}function&__get($name){return
  3027. ObjectMixin::get($this,$name);}function
  3028. __set($name,$value){return
  3029. ObjectMixin::set($this,$name,$value);}function
  3030. __isset($name){return
  3031. ObjectMixin::has($this,$name);}function
  3032. __unset($name){throw
  3033. new\XMemberAccessException("Cannot unset the property {$this->reflection->name}::\$$name.");}}class
  3034. PropertyReflection
  3035. extends\ReflectionProperty{function
  3036. __toString(){return'Property '.parent::getDeclaringClass()->getName().'::$'.$this->getName();}function
  3037. getDeclaringClass(){return
  3038. new
  3039. ClassReflection(parent::getDeclaringClass()->getName());}function
  3040. hasAnnotation($name){$res=AnnotationsParser::getAll($this);return!empty($res[$name]);}function
  3041. getAnnotation($name){$res=AnnotationsParser::getAll($this);return
  3042. isset($res[$name])?end($res[$name]):NULL;}function
  3043. getAnnotations(){return
  3044. AnnotationsParser::getAll($this);}static
  3045. function
  3046. getReflection(){return
  3047. new
  3048. NetteX\Reflection\ClassReflection(get_called_class());}function
  3049. __call($name,$args){return
  3050. ObjectMixin::call($this,$name,$args);}function&__get($name){return
  3051. ObjectMixin::get($this,$name);}function
  3052. __set($name,$value){return
  3053. ObjectMixin::set($this,$name,$value);}function
  3054. __isset($name){return
  3055. ObjectMixin::has($this,$name);}function
  3056. __unset($name){throw
  3057. new\XMemberAccessException("Cannot unset the property {$this->reflection->name}::\$$name.");}}}namespace NetteX\Security{use
  3058. NetteX;class
  3059. AuthenticationException
  3060. extends\Exception{}class
  3061. Identity
  3062. extends
  3063. NetteX\FreezableObject
  3064. implements
  3065. IIdentity{private$id;private$roles;private$data;function
  3066. __construct($id,$roles=NULL,$data=NULL){$this->setId($id);$this->setRoles((array)$roles);$this->data=$data
  3067. instanceof\Traversable?iterator_to_array($data):(array)$data;}function
  3068. setId($id){$this->updating();$this->id=is_numeric($id)?1*$id:$id;return$this;}function
  3069. getId(){return$this->id;}function
  3070. setRoles(array$roles){$this->updating();$this->roles=$roles;return$this;}function
  3071. getRoles(){return$this->roles;}function
  3072. getData(){return$this->data;}function
  3073. __set($key,$value){$this->updating();if(parent::__isset($key)){parent::__set($key,$value);}else{$this->data[$key]=$value;}}function&__get($key){if(parent::__isset($key)){return
  3074. parent::__get($key);}else{return$this->data[$key];}}function
  3075. __isset($key){return
  3076. isset($this->data[$key])||parent::__isset($key);}function
  3077. __unset($name){throw
  3078. new\XMemberAccessException("Cannot unset the property {$this->reflection->name}::\$$name.");}}class
  3079. Permission
  3080. extends
  3081. NetteX\Object
  3082. implements
  3083. 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
  3084. addRole($role,$parents=NULL){$this->checkRole($role,FALSE);if(isset($this->roles[$role])){throw
  3085. new\XInvalidStateException("Role '$role' already exists in the list.");}$roleParents=array();if($parents!==NULL){if(!is_array($parents)){$parents=array($parents);}foreach($parents
  3086. 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
  3087. hasRole($role){$this->checkRole($role,FALSE);return
  3088. isset($this->roles[$role]);}private
  3089. function
  3090. checkRole($role,$need=TRUE){if(!is_string($role)||$role===''){throw
  3091. new\InvalidArgumentException("Role must be a non-empty string.");}elseif($need&&!isset($this->roles[$role])){throw
  3092. new\XInvalidStateException("Role '$role' does not exist.");}}function
  3093. getRoleParents($role){$this->checkRole($role);return
  3094. array_keys($this->roles[$role]['parents']);}function
  3095. 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
  3096. TRUE;}}return
  3097. FALSE;}function
  3098. 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
  3099. 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
  3100. addResource($resource,$parent=NULL){$this->checkResource($resource,FALSE);if(isset($this->resources[$resource])){throw
  3101. new\XInvalidStateException("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
  3102. hasResource($resource){$this->checkResource($resource,FALSE);return
  3103. isset($this->resources[$resource]);}private
  3104. function
  3105. checkResource($resource,$need=TRUE){if(!is_string($resource)||$resource===''){throw
  3106. new\InvalidArgumentException("Resource must be a non-empty string.");}elseif($need&&!isset($this->resources[$resource])){throw
  3107. new\XInvalidStateException("Resource '$resource' does not exist.");}}function
  3108. resourceInheritsFrom($resource,$inherit,$onlyParent=FALSE){$this->checkResource($resource);$this->checkResource($inherit);if($this->resources[$resource]['parent']===NULL){return
  3109. FALSE;}$parent=$this->resources[$resource]['parent'];if($inherit===$parent){return
  3110. TRUE;}elseif($onlyParent){return
  3111. FALSE;}while($this->resources[$parent]['parent']!==NULL){$parent=$this->resources[$parent]['parent'];if($inherit===$parent){return
  3112. TRUE;}}return
  3113. FALSE;}function
  3114. 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
  3115. as$resourceRemoved){foreach($this->rules['byResource']as$resourceCurrent=>$rules){if($resourceRemoved===$resourceCurrent){unset($this->rules['byResource'][$resourceCurrent]);}}}unset($this->resources[$resource]);return$this;}function
  3116. removeAllResources(){foreach($this->resources
  3117. as$resource=>$foo){foreach($this->rules['byResource']as$resourceCurrent=>$rules){if($resource===$resourceCurrent){unset($this->rules['byResource'][$resourceCurrent]);}}}$this->resources=array();return$this;}function
  3118. allow($roles=self::ALL,$resources=self::ALL,$privileges=self::ALL,$assertion=NULL){$this->setRule(TRUE,self::ALLOW,$roles,$resources,$privileges,$assertion);return$this;}function
  3119. deny($roles=self::ALL,$resources=self::ALL,$privileges=self::ALL,$assertion=NULL){$this->setRule(TRUE,self::DENY,$roles,$resources,$privileges,$assertion);return$this;}function
  3120. removeAllow($roles=self::ALL,$resources=self::ALL,$privileges=self::ALL){$this->setRule(FALSE,self::ALLOW,$roles,$resources,$privileges);return$this;}function
  3121. removeDeny($roles=self::ALL,$resources=self::ALL,$privileges=self::ALL){$this->setRule(FALSE,self::DENY,$roles,$resources,$privileges);return$this;}protected
  3122. function
  3123. setRule($toAdd,$type,$roles,$resources,$privileges,$assertion=NULL){if($roles===self::ALL){$roles=array(self::ALL);}else{if(!is_array($roles)){$roles=array($roles);}foreach($roles
  3124. as$role){$this->checkRole($role);}}if($resources===self::ALL){$resources=array(self::ALL);}else{if(!is_array($resources)){$resources=array($resources);}foreach($resources
  3125. as$resource){$this->checkResource($resource);}}if($privileges===self::ALL){$privileges=array();}elseif(!is_array($privileges)){$privileges=array($privileges);}$assertion=$assertion?callbackX($assertion):NULL;if($toAdd){foreach($resources
  3126. as$resource){foreach($roles
  3127. 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
  3128. as$privilege){$rules['byPrivilege'][$privilege]['type']=$type;$rules['byPrivilege'][$privilege]['assert']=$assertion;}}}}}else{foreach($resources
  3129. as$resource){foreach($roles
  3130. 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
  3131. as$privilege){if(isset($rules['byPrivilege'][$privilege])&&$type===$rules['byPrivilege'][$privilege]['type']){unset($rules['byPrivilege'][$privilege]);}}}}}}return$this;}function
  3132. isAllowed($role=self::ALL,$resource=self::ALL,$privilege=self::ALL){$this->queriedRole=$role;if($role!==self::ALL){if($role
  3133. instanceof
  3134. IRole){$role=$role->getRoleId();}$this->checkRole($role);}$this->queriedResource=$resource;if($resource!==self::ALL){if($resource
  3135. instanceof
  3136. 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
  3137. 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
  3138. getQueriedRole(){return$this->queriedRole;}function
  3139. getQueriedResource(){return$this->queriedResource;}private
  3140. function
  3141. 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
  3142. NULL;}private
  3143. function
  3144. 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
  3145. self::DENY;}}if(NULL!==($type=$this->getRuleType($resource,$role,NULL))){return
  3146. self::ALLOW===$type;}}$dfs['visited'][$role]=TRUE;foreach($this->roles[$role]['parents']as$roleParent=>$foo){$dfs['stack'][]=$roleParent;}return
  3147. NULL;}private
  3148. function
  3149. 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
  3150. NULL;}private
  3151. function
  3152. roleDFSVisitOnePrivilege($role,$resource,$privilege,&$dfs){if(NULL!==($type=$this->getRuleType($resource,$role,$privilege))){return
  3153. self::ALLOW===$type;}if(NULL!==($type=$this->getRuleType($resource,$role,NULL))){return
  3154. self::ALLOW===$type;}$dfs['visited'][$role]=TRUE;foreach($this->roles[$role]['parents']as$roleParent=>$foo)$dfs['stack'][]=$roleParent;return
  3155. NULL;}private
  3156. function
  3157. getRuleType($resource,$role,$privilege){if(NULL===($rules=$this->getRules($resource,$role))){return
  3158. NULL;}if($privilege===self::ALL){if(isset($rules['allPrivileges'])){$rule=$rules['allPrivileges'];}else{return
  3159. NULL;}}elseif(!isset($rules['byPrivilege'][$privilege])){return
  3160. NULL;}else{$rule=$rules['byPrivilege'][$privilege];}if($rule['assert']===NULL||$rule['assert']->__invoke($this,$role,$resource,$privilege)){return$rule['type'];}elseif($resource!==self::ALL||$role!==self::ALL||$privilege!==self::ALL){return
  3161. NULL;}elseif(self::ALLOW===$rule['type']){return
  3162. self::DENY;}else{return
  3163. self::ALLOW;}}private
  3164. 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
  3165. SimpleAuthenticator
  3166. extends
  3167. NetteX\Object
  3168. implements
  3169. IAuthenticator{private$userlist;function
  3170. __construct(array$userlist){$this->userlist=$userlist;}function
  3171. authenticate(array$credentials){list($username,$password)=$credentials;foreach($this->userlist
  3172. as$name=>$pass){if(strcasecmp($name,$username)===0){if($pass===$password){return
  3173. new
  3174. Identity($name);}else{throw
  3175. new
  3176. AuthenticationException("Invalid password.",self::INVALID_CREDENTIAL);}}}throw
  3177. new
  3178. AuthenticationException("User '$username' not found.",self::IDENTITY_NOT_FOUND);}}}namespace NetteX\Templates{use
  3179. NetteX;abstract
  3180. class
  3181. Template
  3182. extends
  3183. NetteX\Object
  3184. implements
  3185. ITemplate{public$warnOnUndefined=TRUE;public$onPrepareFilters=array();private$params=array();private$filters=array();private$helpers=array();private$helperLoaders=array();function
  3186. registerFilter($callback){$callback=callbackX($callback);if(in_array($callback,$this->filters)){throw
  3187. new\XInvalidStateException("Filter '$callback' was registered twice.");}$this->filters[]=$callback;}final
  3188. function
  3189. getFilters(){return$this->filters;}function
  3190. render(){}function
  3191. save($file){if(file_put_contents($file,$this->__toString(TRUE))===FALSE){throw
  3192. new\XIOException("Unable to save file '$file'.");}}function
  3193. __toString(){ob_start();try{$this->render();return
  3194. ob_get_clean();}catch(\Exception$e){ob_end_clean();if(func_num_args()&&func_get_arg(0)){throw$e;}else{NetteX\Debug::toStringException($e);}}}protected
  3195. function
  3196. compile($content,$label=NULL){if(!$this->filters){$this->onPrepareFilters($this);}try{foreach($this->filters
  3197. as$filter){$content=self::extractPhp($content,$blocks);$content=$filter($content);$content=strtr($content,$blocks);}}catch(\Exception$e){throw
  3198. new\XInvalidStateException("Filter $filter: ".$e->getMessage().($label?" (in $label)":''),0,$e);}if($label){$content="<?php\n// $label\n//\n?>$content";}return
  3199. self::optimizePhp($content);}function
  3200. registerHelper($name,$callback){$this->helpers[strtolower($name)]=callbackX($callback);}function
  3201. registerHelperLoader($callback){$this->helperLoaders[]=callbackX($callback);}final
  3202. function
  3203. getHelpers(){return$this->helpers;}function
  3204. __call($name,$args){$lname=strtolower($name);if(!isset($this->helpers[$lname])){foreach($this->helperLoaders
  3205. as$loader){$helper=$loader($lname);if($helper){$this->registerHelper($lname,$helper);return$this->helpers[$lname]->invokeArgs($args);}}return
  3206. parent::__call($name,$args);}return$this->helpers[$lname]->invokeArgs($args);}function
  3207. setTranslator(NetteX\ITranslator$translator=NULL){$this->registerHelper('translate',$translator===NULL?NULL:array($translator,'translate'));return$this;}function
  3208. add($name,$value){if(array_key_exists($name,$this->params)){throw
  3209. new\XInvalidStateException("The variable '$name' already exists.");}$this->params[$name]=$value;}function
  3210. setParams(array$params){$this->params=$params;return$this;}function
  3211. getParams(){return$this->params;}function
  3212. __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
  3213. __isset($name){return
  3214. isset($this->params[$name]);}function
  3215. __unset($name){unset($this->params[$name]);}private
  3216. static
  3217. function
  3218. extractPhp($source,&$blocks){$res='';$blocks=array();$tokens=token_get_all($source);foreach($tokens
  3219. 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
  3220. function
  3221. optimizePhp($source){$res=$php='';$lastChar=';';$tokens=new\ArrayIterator(token_get_all($source));foreach($tokens
  3222. 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;}}use
  3223. NetteX\Environment;use
  3224. NetteX\Caching\Cache;use
  3225. NetteX\Loaders\LimitedScope;class
  3226. FileTemplate
  3227. extends
  3228. Template
  3229. implements
  3230. IFileTemplate{public
  3231. static$cacheExpire=NULL;private
  3232. static$cacheStorage;private$file;function
  3233. __construct($file=NULL){if($file!==NULL){$this->setFile($file);}}function
  3234. setFile($file){if(!is_file($file)){throw
  3235. new\XFileNotFoundException("Missing template file '$file'.");}$this->file=$file;return$this;}function
  3236. getFile(){return$this->file;}function
  3237. render(){if($this->file==NULL){throw
  3238. new\XInvalidStateException("Template file name was not specified.");}$this->__set('template',$this);$shortName=str_replace(dirname(dirname($this->file)),'',$this->file);$cache=new
  3239. Cache($this->getCacheStorage(),'NetteX.FileTemplate');$key=trim(strtr($shortName,'\\/@','.._'),'.').'-'.md5($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;}$content=$this->compile(file_get_contents($this->file),"file \xE2\x80\xA6$shortName");$cache->save($key,$content,array(Cache::FILES=>$this->file,Cache::EXPIRATION=>self::$cacheExpire,Cache::CONSTS=>'NetteX\Framework::REVISION'));$cache->release();$cached=$cache[$key];}if($cached!==NULL&&self::$cacheStorage
  3240. instanceof
  3241. TemplateCacheStorage){LimitedScope::load($cached['file'],$this->getParams());fclose($cached['handle']);}else{LimitedScope::evaluate($content,$this->getParams());}}static
  3242. function
  3243. setCacheStorage(NetteX\Caching\ICacheStorage$storage){self::$cacheStorage=$storage;}static
  3244. function
  3245. getCacheStorage(){if(self::$cacheStorage===NULL){$dir=Environment::getVariable('tempDir').'/cache';umask(0000);@mkdir($dir,0777);self::$cacheStorage=new
  3246. TemplateCacheStorage($dir);}return
  3247. self::$cacheStorage;}}class
  3248. CachingHelper
  3249. extends
  3250. NetteX\Object{private$frame;private$key;static
  3251. function
  3252. create($key,&$parents,$args=NULL){if($args){$key.=md5(serialize(array_intersect_key($args,range(0,count($args)))));if(array_key_exists('if',$args)&&!$args['if']){return$parents[]=new
  3253. self;}}if($parents){end($parents)->frame[Cache::ITEMS][]=$key;}$cache=self::getCache();if(isset($cache[$key])){echo$cache[$key];return
  3254. FALSE;}else{$obj=new
  3255. self;$obj->key=$key;$obj->frame=array(Cache::TAGS=>isset($args['tags'])?$args['tags']:NULL,Cache::EXPIRATION=>isset($args['expire'])?$args['expire']:'+ 7 days');ob_start();return$parents[]=$obj;}}function
  3256. save(){if($this->key!==NULL){$this->getCache()->save($this->key,ob_get_flush(),$this->frame);}$this->key=$this->frame=NULL;}function
  3257. addFile($file){$this->frame[Cache::FILES][]=$file;}protected
  3258. static
  3259. function
  3260. getCache(){return
  3261. Environment::getCache('NetteX.Template.Cache');}}use
  3262. NetteX\String;use
  3263. NetteX\Tokenizer;class
  3264. LatteFilter
  3265. extends
  3266. NetteX\Object{const
  3267. RE_STRING='\'(?:\\\\.|[^\'\\\\])*\'|"(?:\\\\.|[^"\\\\])*"';const
  3268. HTML_PREFIX='n:';private$handler;private$macroRe;private$input,$output;private$offset;private$quote;private$tags;public$context,$escape;const
  3269. CONTEXT_TEXT='text';const
  3270. CONTEXT_CDATA='cdata';const
  3271. CONTEXT_TAG='tag';const
  3272. CONTEXT_ATTRIBUTE='attribute';const
  3273. CONTEXT_NONE='none';const
  3274. CONTEXT_COMMENT='comment';function
  3275. setHandler($handler){$this->handler=$handler;return$this;}function
  3276. getHandler(){if($this->handler===NULL){$this->handler=new
  3277. LatteMacros;}return$this->handler;}function
  3278. __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
  3279. function
  3280. 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'])){$code=$this->handler->macro($matches['macro']);if($code===FALSE){throw
  3281. new\XInvalidStateException("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
  3282. as$tag){if(!$tag->isMacro&&!empty($tag->attrs)){throw
  3283. new\XInvalidStateException("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
  3284. function
  3285. contextText(){$matches=$this->match('~
  3286. (?:\n[ \t]*)?<(?P<closing>/?)(?P<tag>[a-z0-9:]+)| ## begin of HTML tag <tag </tag - ignores <!DOCTYPE
  3287. <(?P<comment>!--)| ## begin of HTML comment <!--
  3288. '.$this->macroRe.' ## curly tag
  3289. ~xsi');if(!$matches||!empty($matches['macro'])){}elseif(!empty($matches['comment'])){$this->context=self::CONTEXT_COMMENT;$this->escape='NetteX\Templates\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='NetteX\Templates\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='NetteX\Templates\TemplateHelpers::escapeHtml';}return$matches;}private
  3290. function
  3291. contextCData(){$tag=end($this->tags);$matches=$this->match('~
  3292. </'.$tag->name.'(?![a-z0-9:])| ## end HTML tag </tag
  3293. '.$this->macroRe.' ## curly tag
  3294. ~xsi');if($matches&&empty($matches['macro'])){$tag->closing=TRUE;$tag->pos=strlen($this->output);$this->context=self::CONTEXT_TAG;$this->escape='NetteX\Templates\TemplateHelpers::escapeHtml';}return$matches;}private
  3295. function
  3296. contextTag(){$matches=$this->match('~
  3297. (?P<end>\ ?/?>)(?P<tagnewline>[\ \t]*(?=\r|\n))?| ## end of HTML tag
  3298. '.$this->macroRe.'| ## curly tag
  3299. \s*(?P<attr>[^\s/>={]+)(?:\s*=\s*(?P<value>["\']|[^\s/>{]+))? ## begin of HTML attribute
  3300. ~xsi');if(!$matches||!empty($matches['macro'])){}elseif(!empty($matches['end'])){$tag=end($this->tags);$isEmpty=!$tag->closing&&(strpos($matches['end'],'/')!==FALSE||isset(NetteX\Web\Html::$emptyElements[strtolower($tag->name)]));if($isEmpty){$matches[0]=(NetteX\Web\Html::$xhtml?' />':'>').(isset($matches['tagnewline'])?$matches['tagnewline']:'');}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===FALSE){throw
  3301. new\XInvalidStateException("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===FALSE){throw
  3302. new\XInvalidStateException("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')?'NetteX\Templates\TemplateHelpers::escapeJs':'NetteX\Templates\TemplateHelpers::escapeCss';}else{$this->context=self::CONTEXT_TEXT;$this->escape='NetteX\Templates\TemplateHelpers::escapeHtml';if($tag->closing)array_pop($this->tags);}}else{$name=$matches['attr'];$value=isset($matches['value'])?$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')?'NetteX\Templates\TemplateHelpers::escapeHtml':'NetteX\Templates\TemplateHelpers::escapeHtmlCss'):'NetteX\Templates\TemplateHelpers::escapeHtmlJs';}}return$matches;}private
  3303. function
  3304. contextAttribute(){$matches=$this->match('~
  3305. ('.$this->quote.')| ## 1) end of HTML attribute
  3306. '.$this->macroRe.' ## curly tag
  3307. ~xsi');if($matches&&empty($matches['macro'])){$this->context=self::CONTEXT_TAG;$this->escape='NetteX\Templates\TemplateHelpers::escapeHtml';}return$matches;}private
  3308. function
  3309. contextComment(){$matches=$this->match('~
  3310. (--\s*>)| ## 1) end of HTML comment
  3311. '.$this->macroRe.' ## curly tag
  3312. ~xsi');if($matches&&empty($matches['macro'])){$this->context=self::CONTEXT_TEXT;$this->escape='NetteX\Templates\TemplateHelpers::escapeHtml';}return$matches;}private
  3313. function
  3314. contextNone(){$matches=$this->match('~
  3315. '.$this->macroRe.' ## curly tag
  3316. ~xsi');return$matches;}private
  3317. function
  3318. match($re){if($matches=String::match($this->input,$re,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
  3319. as$k=>$v)$matches[$k]=$v[0];}return$matches;}function
  3320. getLine(){return
  3321. substr_count($this->input,"\n",0,$this->offset);}function
  3322. setDelimiters($left,$right){$this->macroRe='
  3323. (?P<indent>\n[\ \t]*)?
  3324. '.$left.'
  3325. (?P<macro>(?:'.self::RE_STRING.'|[^\'"]+?)*?)
  3326. '.$right.'
  3327. (?P<newline>[\ \t]*(?=\r|\n))?
  3328. ';return$this;}static
  3329. function
  3330. formatModifiers($var,$modifiers){trigger_error(__METHOD__.'() is deprecated; use LatteMacros::formatModifiers() instead.',E_USER_WARNING);return
  3331. LatteMacros::formatModifiers($var,$modifiers);}static
  3332. function
  3333. fetchToken(&$s){trigger_error(__METHOD__.'() is deprecated; use LatteMacros::fetchToken() instead.',E_USER_WARNING);return
  3334. LatteMacros::fetchToken($s);}static
  3335. function
  3336. formatArray($input,$prefix=''){trigger_error(__METHOD__.'() is deprecated; use LatteMacros::formatArray() instead.',E_USER_WARNING);return
  3337. LatteMacros::formatArray($input,$prefix);}static
  3338. function
  3339. formatString($s){trigger_error(__METHOD__.'() is deprecated; use LatteMacros::formatString() instead.',E_USER_WARNING);return
  3340. LatteMacros::formatString($s);}}class
  3341. LatteMacros
  3342. extends
  3343. NetteX\Object{public
  3344. 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 %:macroCache% ?>','/cache'=>'<?php array_pop($_l->g->caches)->save(); } ?>','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($_l->its); $iterator = end($_l->its) ?>','for'=>'<?php for (%%): ?>','/for'=>'<?php endfor ?>','while'=>'<?php while (%%): ?>','/while'=>'<?php endwhile ?>','continueIf'=>'<?php if (%%) continue ?>','breakIf'=>'<?php if (%%) break ?>','first'=>'<?php if ($iterator->isFirst(%%)): ?>','/first'=>'<?php endif ?>','last'=>'<?php if ($iterator->isLast(%%)): ?>','/last'=>'<?php endif ?>','sep'=>'<?php if (!$iterator->isLast(%%)): ?>','/sep'=>'<?php endif ?>','include'=>'<?php %:macroInclude% ?>','extends'=>'<?php %:macroExtends% ?>','layout'=>'<?php %:macroExtends% ?>','plink'=>'<?php echo %:escape%(%:macroPlink%) ?>','link'=>'<?php echo %:escape%(%:macroLink%) ?>','ifCurrent'=>'<?php %:macroIfCurrent% ?>','widget'=>'<?php %:macroControl% ?>','control'=>'<?php %:macroControl% ?>','@href'=>' href="<?php echo %:escape%(%:macroLink%) ?>"','@class'=>'<?php if ($_l->tmp = trim(implode(" ", array_unique(%:formatArray%)))) echo \' class="\' . %:escape%($_l->tmp) . \'"\' ?>','@attr'=>'<?php if (($_l->tmp = (string) (%%)) !== \'\') echo \' @@="\' . %:escape%($_l->tmp) . \'"\' ?>','attr'=>'<?php echo NetteX\Web\Html::el(NULL)->%:macroAttr%attributes() ?>','contentType'=>'<?php %:macroContentType% ?>','status'=>'<?php NetteX\Environment::getHttpResponse()->setCode(%%) ?>','var'=>'<?php %:macroVar% ?>','assign'=>'<?php %:macroVar% ?>','default'=>'<?php %:macroDefault% ?>','dump'=>'<?php %:macroDump% ?>','debugbreak'=>'<?php %:macroDebugbreak% ?>','l'=>'{','r'=>'}','!_'=>'<?php echo %:macroTranslate% ?>','_'=>'<?php echo %:escape%(%:macroTranslate%) ?>','!='=>'<?php echo %:macroModifiers% ?>','='=>'<?php echo %:escape%(%:macroModifiers%) ?>','!$'=>'<?php echo %:macroDollar% ?>','$'=>'<?php echo %:escape%(%:macroDollar%) ?>','?'=>'<?php %:macroModifiers% ?>');const
  3345. RE_IDENTIFIER='[_a-zA-Z\x7F-\xFF][_a-zA-Z0-9\x7F-\xFF]*';const
  3346. T_WHITESPACE=T_WHITESPACE;const
  3347. T_COMMENT=T_COMMENT;const
  3348. T_SYMBOL=-1;const
  3349. T_NUMBER=-2;const
  3350. T_VARIABLE=-3;public$macros;private$tokenizer;private$filter;private$blocks=array();private$namedBlocks=array();private$extends;private$uniq;private$cacheCounter;const
  3351. BLOCK_NAMED=1;const
  3352. BLOCK_CAPTURE=2;const
  3353. BLOCK_ANONYMOUS=3;function
  3354. __construct(){$this->macros=self::$defaultMacros;$this->tokenizer=new
  3355. NetteX\Tokenizer(array(self::T_WHITESPACE=>'\s+',self::T_COMMENT=>'/\*.*?\*/',LatteFilter::RE_STRING,'true|false|null|and|or|xor|clone|new|instanceof|\([a-z]+\)',self::T_VARIABLE=>'\$[_a-z0-9\x7F-\xFF]+',self::T_NUMBER=>'[+-]?[0-9]+(?:\.[0-9]+)?(?:e[0-9]+)?',self::T_SYMBOL=>'[_a-z0-9\x7F-\xFF]+(?:-[_a-z0-9\x7F-\xFF]+)*','::|=>|[^"\']'),'i');}function
  3356. initialize($filter,&$s){$this->filter=$filter;$this->blocks=array();$this->namedBlocks=array();$this->extends=NULL;$this->uniq=substr(md5(uniqid('',TRUE)),0,10);$this->cacheCounter=0;$filter->context=LatteFilter::CONTEXT_TEXT;$filter->escape='NetteX\Templates\TemplateHelpers::escapeHtml';$s=String::replace($s,'#\\{\\*.*?\\*\\}[\r\n]*#s','');}function
  3357. finalize(&$s){if(count($this->blocks)===1){$s.=$this->macro('/block');}elseif($this->blocks){throw
  3358. new\XInvalidStateException("There are unclosed blocks.");}if($this->namedBlocks||$this->extends){$s='<?php
  3359. if ($_l->extends) {
  3360. ob_start();
  3361. } elseif (isset($presenter, $control) && $presenter->isAjax()) {
  3362. return NetteX\Templates\LatteMacros::renderSnippets($control, $_l, get_defined_vars());
  3363. }
  3364. ?>'.$s.'<?php
  3365. if ($_l->extends) {
  3366. ob_end_clean();
  3367. NetteX\Templates\LatteMacros::includeTemplate($_l->extends, get_defined_vars(), $template)->render();
  3368. }
  3369. ';}else{$s='<?php
  3370. if (isset($presenter, $control) && $presenter->isAjax()) {
  3371. return NetteX\Templates\LatteMacros::renderSnippets($control, $_l, get_defined_vars());
  3372. }
  3373. ?>'.$s;}if($this->namedBlocks){$uniq=$this->uniq;foreach(array_reverse($this->namedBlocks,TRUE)as$name=>$foo){$code=&$this->namedBlocks[$name];$namere=preg_quote($name,'#');$s=String::replace($s,"#{block $namere} \?>(.*)<\?php {/block $namere}#sU",function($matches)use($name,&$code,$uniq){list(,$content)=$matches;$func='_lb'.substr(md5($uniq.$name),0,10).'_'.preg_replace('#[^a-z0-9_]#i','_',$name);$code="//\n// block $name\n//\n"."if (!function_exists(\$_l->blocks[".var_export($name,TRUE)."][] = '$func')) { "."function $func(\$_l, \$_args) { extract(\$_args)\n?>$content<?php\n}}";return'';});}$s="<?php\n\n".implode("\n\n\n",$this->namedBlocks)."\n\n//\n// end of blocks\n//\n?>".$s;}$s="<?php\n".'$_l = NetteX\Templates\LatteMacros::initRuntime($template, '.var_export($this->extends,TRUE).', '.var_export($this->uniq,TRUE).'); unset($_extends);'."\n?>".$s;}function
  3374. macro($macro,$content='',$modifiers=''){if(func_num_args()===1){list(,$macro,$content,$modifiers)=String::match($macro,'#^(/?[a-z0-9.:]+)?(.*?)(\\|[a-z](?:'.LatteFilter::RE_STRING.'|[^\'"]+)*)?$()#is');$content=trim($content);}if($macro===''){$macro=substr($content,0,2);if(!isset($this->macros[$macro])){$macro=substr($content,0,1);if(!isset($this->macros[$macro])){return
  3375. FALSE;}}$content=substr($content,strlen($macro));}elseif(!isset($this->macros[$macro])){return
  3376. FALSE;}$This=$this;return
  3377. String::replace($this->macros[$macro],'#%(.*?)%#',function($m)use($This,$content,$modifiers){if($m[1]){return
  3378. callbackX($m[1][0]===':'?array($This,substr($m[1],1)):$m[1])->invoke($content,$modifiers);}else{return$This->formatMacroArgs($content,'#');}});}function
  3379. 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]]:preg_replace("#'([^\\'$]+)'#",'$1',substr(var_export($attrs,TRUE),8,-1)),isset($attrs['modifiers'])?$attrs['modifiers']:'');}function
  3380. attrsMacro($code,$attrs,$closing){foreach($attrs
  3381. as$name=>$content){if(substr($name,0,5)==='attr-'){if(!$closing){$pos=strrpos($code,'>');if($code[$pos-1]==='/')$pos--;$code=substr_replace($code,str_replace('@@',substr($name,5),$this->macro("@attr",$content)),$pos,0);}unset($attrs[$name]);}}$left=$right='';foreach($this->macros
  3382. as$name=>$foo){if($name[0]==='@'){$name=substr($name,1);if(isset($attrs[$name])){if(!$closing){$pos=strrpos($code,'>');if($code[$pos-1]==='/')$pos--;$code=substr_replace($code,$this->macro("@$name",$attrs[$name]),$pos,0);}unset($attrs[$name]);}}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?FALSE:$left.$code.$right;}function
  3383. macroDollar($var,$modifiers){return$this->formatModifiers($this->formatMacroArgs('$'.$var),$modifiers);}function
  3384. macroTranslate($var,$modifiers){return$this->formatModifiers($this->formatMacroArgs($var),'|translate'.$modifiers);}function
  3385. 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
  3386. new\XInvalidStateException("Unknown syntax '$var' on line {$this->filter->line}.");}}function
  3387. macroInclude($content,$modifiers,$isDefinition=FALSE){$destination=$this->fetchToken($content);$params=$this->formatArray($content).($content?' + ':'');if($destination===NULL){throw
  3388. new\XInvalidStateException("Missing destination in {include} on line {$this->filter->line}.");}elseif($destination[0]==='#'){$destination=ltrim($destination,'#');if(!String::match($destination,'#^'.self::RE_IDENTIFIER.'$#')){throw
  3389. new\XInvalidStateException("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
  3390. new\XInvalidStateException("Cannot include $destination block outside of any block on line {$this->filter->line}.");}$destination=$item[1];}$name=var_export($destination,TRUE);$params.=$isDefinition?'get_defined_vars()':'$template->getParams()';$cmd=isset($this->namedBlocks[$destination])&&!$parent?"call_user_func(reset(\$_l->blocks[$name]), \$_l, $params)":'NetteX\Templates\LatteMacros::callBlock'.($parent?'Parent':'')."(\$_l, $name, $params)";return$modifiers?"ob_start(); $cmd; echo ".$this->formatModifiers('ob_get_clean()',$modifiers):$cmd;}else{$destination=$this->formatString($destination);$cmd='NetteX\Templates\LatteMacros::includeTemplate('.$destination.', '.$params.'$template->getParams(), $_l->templates['.var_export($this->uniq,TRUE).'])';return$modifiers?'echo '.$this->formatModifiers($cmd.'->__toString(TRUE)',$modifiers):$cmd.'->render()';}}function
  3391. macroExtends($content){$destination=$this->fetchToken($content);if($destination===NULL){throw
  3392. new\XInvalidStateException("Missing destination in {extends} on line {$this->filter->line}.");}if(!empty($this->blocks)){throw
  3393. new\XInvalidStateException("{extends} must be placed outside any block; on line {$this->filter->line}.");}if($this->extends!==NULL){throw
  3394. new\XInvalidStateException("Multiple {extends} declarations are not allowed; on line {$this->filter->line}.");}$this->extends=$destination!=='none';return$this->extends?'$_l->extends = '.($destination==='auto'?'$layout':$this->formatString($destination)):'';}function
  3395. macroBlock($content,$modifiers){$name=$this->fetchToken($content);if($name===NULL){$this->blocks[]=array(self::BLOCK_ANONYMOUS,NULL,$modifiers);return$modifiers===''?'':'ob_start()';}else{$name=ltrim($name,'#');if(!String::match($name,'#^'.self::RE_IDENTIFIER.'$#')){throw
  3396. new\XInvalidStateException("Block name must be alphanumeric string, '$name' given on line {$this->filter->line}.");}elseif(isset($this->namedBlocks[$name])){throw
  3397. new\XInvalidStateException("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($name[0]==='_'){$tag=$this->fetchToken($content);$tag=trim($tag,'<>');$namePhp=var_export(substr($name,1),TRUE);if(!$tag)$tag='div';return"?><$tag id=\"<?php echo \$control->getSnippetId($namePhp) ?>\"><?php ".$this->macroInclude('#'.$name,$modifiers)." ?></$tag><?php {block $name}";}elseif(!$top){return$this->macroInclude('#'.$name,$modifiers,TRUE)."{block $name}";}elseif($this->extends){return"{block $name}";}else{return'if (!$_l->extends) { '.$this->macroInclude('#'.$name,$modifiers,TRUE)."; } {block $name}";}}}function
  3398. 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
  3399. new\XInvalidStateException("Tag {/block $content} was not expected here on line {$this->filter->line}.");}elseif($type===self::BLOCK_NAMED){return"{/block $name}";}else{return$modifiers===''?'':'echo '.$this->formatModifiers('ob_get_clean()',$modifiers);}}function
  3400. macroSnippet($content){return$this->macroBlock('_'.$content,'');}function
  3401. macroSnippetEnd($content){return$this->macroBlockEnd('','');}function
  3402. macroCapture($content,$modifiers){$name=$this->fetchToken($content);if(substr($name,0,1)!=='$'){throw
  3403. new\XInvalidStateException("Invalid capture block parameter '$name' on line {$this->filter->line}.");}$this->blocks[]=array(self::BLOCK_CAPTURE,$name,$modifiers);return'ob_start()';}function
  3404. macroCaptureEnd($content){list($type,$name,$modifiers)=array_pop($this->blocks);if($type!==self::BLOCK_CAPTURE||($content&&$content!==$name)){throw
  3405. new\XInvalidStateException("Tag {/capture $content} was not expected here on line {$this->filter->line}.");}return$name.'='.$this->formatModifiers('ob_get_clean()',$modifiers);}function
  3406. macroCache($content){return'if (NetteX\Templates\CachingHelper::create('.var_export($this->uniq.':'.$this->cacheCounter++,TRUE).', $_l->g->caches'.$this->formatArray($content,', ').')) {';}function
  3407. macroForeach($content){return'$iterator = $_l->its[] = new NetteX\SmartCachingIterator('.preg_replace('# +as +#i',') as ',$this->formatMacroArgs($content),1);}function
  3408. macroAttr($content){return
  3409. String::replace($content.' ','#\)\s+#',')->');}function
  3410. macroContentType($content){if(strpos($content,'html')!==FALSE){$this->filter->escape='NetteX\Templates\TemplateHelpers::escapeHtml';$this->filter->context=LatteFilter::CONTEXT_TEXT;}elseif(strpos($content,'xml')!==FALSE){$this->filter->escape='NetteX\Templates\TemplateHelpers::escapeXml';$this->filter->context=LatteFilter::CONTEXT_NONE;}elseif(strpos($content,'javascript')!==FALSE){$this->filter->escape='NetteX\Templates\TemplateHelpers::escapeJs';$this->filter->context=LatteFilter::CONTEXT_NONE;}elseif(strpos($content,'css')!==FALSE){$this->filter->escape='NetteX\Templates\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
  3411. strpos($content,'/')?'NetteX\Environment::getHttpResponse()->setHeader("Content-Type", "'.$content.'")':'';}function
  3412. macroDump($content){return'NetteX\Debug::barDump('.($content?'array('.var_export($this->formatMacroArgs($content),TRUE)." => $content)":'get_defined_vars()').', "Template " . str_replace(dirname(dirname($template->getFile())), "\xE2\x80\xA6", $template->getFile()))';}function
  3413. macroDebugbreak(){return'if (function_exists("debugbreak")) debugbreak(); elseif (function_exists("xdebug_break")) xdebug_break()';}function
  3414. macroControl($content){$pair=$this->fetchToken($content);if($pair===NULL){throw
  3415. new\XInvalidStateException("Missing control name in {control} on line {$this->filter->line}.");}$pair=explode(':',$pair,2);$name=$this->formatString($pair[0]);$method=isset($pair[1])?ucfirst($pair[1]):'';$method=String::match($method,'#^('.self::RE_IDENTIFIER.'|)$#')?"render$method":"{\"render$method\"}";$param=$this->formatArray($content);if(strpos($content,'=>')===FALSE)$param=substr($param,6,-1);return($name[0]==='$'?"if (is_object($name)) {$name}->$method($param); else ":'')."\$control->getWidget($name)->$method($param)";}function
  3416. macroLink($content,$modifiers){return$this->formatModifiers('$control->link('.$this->formatLink($content).')',$modifiers);}function
  3417. macroPlink($content,$modifiers){return$this->formatModifiers('$presenter->link('.$this->formatLink($content).')',$modifiers);}function
  3418. macroIfCurrent($content){return($content?'try { $presenter->link('.$this->formatLink($content).'); } catch (NetteX\Application\InvalidLinkException $e) {}':'').'; if ($presenter->getLastCreatedRequestFlag("current")):';}private
  3419. function
  3420. formatLink($content){return$this->formatString($this->fetchToken($content)).$this->formatArray($content,', ');}function
  3421. macroVar($content,$modifiers,$extract=FALSE){$out='';$var=TRUE;foreach($this->parseMacro($content)as$rec){list($token,$name,$depth)=$rec;if($var&&($name===self::T_SYMBOL||$name===self::T_VARIABLE)){if($extract){$token="'".trim($token,"'$")."'";}else{$token='$'.trim($token,"'$");}}elseif(($token==='='||$token==='=>')&&$depth===0){$token=$extract?'=>':'=';$var=FALSE;}elseif($token===','&&$depth===0){$token=$extract?',':';';$var=TRUE;}$out.=$token;}return$out;}function
  3422. macroDefault($content){return'extract(array('.$this->macroVar($content,'',TRUE).'), EXTR_SKIP)';}function
  3423. macroModifiers($content,$modifiers){return$this->formatModifiers($this->formatMacroArgs($content),$modifiers);}function
  3424. escape($content){return$this->filter->escape;}function
  3425. formatModifiers($var,$modifiers){if(!$modifiers)return$var;$inside=FALSE;foreach($this->parseMacro(ltrim($modifiers,'|'))as$rec){list($token,$name)=$rec;if($name===self::T_WHITESPACE){$var=rtrim($var).' ';}elseif(!$inside){if($name===self::T_SYMBOL){$var="\$template->".trim($token,"'")."($var";$inside=TRUE;}else{throw
  3426. new\XInvalidStateException("Modifier name must be alphanumeric string, '$token' given.");}}else{if($token===':'||$token===','){$var=$var.', ';}elseif($token==='|'){$var=$var.')';$inside=FALSE;}else{$var.=$token;}}}return$inside?"$var)":$var;}function
  3427. fetchToken(&$s){if($matches=String::match($s,'#^((?>'.LatteFilter::RE_STRING.'|[^\'"\s,]+)+)\s*,?\s*(.*)$#')){$s=$matches[2];return$matches[1];}return
  3428. NULL;}function
  3429. formatMacroArgs($input){$out='';foreach($this->parseMacro($input)as$token){$out.=$token[0];}return$out;}function
  3430. formatArray($input,$prefix=''){$tokens=$this->parseMacro($input);if(!$tokens){return'';}$out='';$expand=NULL;$tokens[]=NULL;foreach($tokens
  3431. as$rec){list($token,$name,$depth)=$rec;if($token==='(expand)'&&$depth===0){$expand=TRUE;$token='),';}elseif($expand&&($token===','||$token===NULL)&&!$depth){$expand=FALSE;$token=', array(';}$out.=$token;}return$prefix.($expand===NULL?"array($out)":"array_merge(array($out))");}function
  3432. formatString($s){static$keywords=array('true'=>1,'false'=>1,'null'=>1);return(is_numeric($s)||strspn($s,'\'"$')||isset($keywords[strtolower($s)]))?$s:'"'.$s.'"';}private
  3433. function
  3434. parseMacro($input){$this->tokenizer->tokenize($input);$this->tokenizer->tokens[]=NULL;$inTernary=$lastSymbol=$prev=NULL;$tokens=$arrays=array();$n=-1;while(++$n<count($this->tokenizer->tokens)){list($token,$name)=$current=$this->tokenizer->tokens[$n];$depth=count($arrays);if($name===self::T_COMMENT){continue;}elseif($name===self::T_WHITESPACE){$current[2]=$depth;$tokens[]=$current;continue;}elseif($name===self::T_SYMBOL&&in_array($prev[0],array(',','(','[','=','=>',':','?',NULL),TRUE)){$lastSymbol=count($tokens);}elseif(is_int($lastSymbol)&&in_array($token,array(',',')',']','=','=>',':','|',NULL),TRUE)){$tokens[$lastSymbol][0]="'".$tokens[$lastSymbol][0]."'";$lastSymbol=NULL;}else{$lastSymbol=NULL;}if($token==='?'){$inTernary=$depth;}elseif($token===':'){$inTernary=NULL;}elseif($inTernary===$depth&&($token===','||$token===')'||$token===']'||$token===NULL)){$tokens[]=array(':',NULL,$depth);$tokens[]=array('null',NULL,$depth);$inTernary=NULL;}if($token==='['){if($arrays[]=$prev[0]!==']'&&$prev[1]!==self::T_SYMBOL&&$prev[1]!==self::T_VARIABLE){$tokens[]=array('array',NULL,$depth);$current=array('(',NULL);}}elseif($token===']'){if(array_pop($arrays)===TRUE){$current=array(')',NULL);}}elseif($token==='('){$arrays[]='(';}elseif($token===')'){array_pop($arrays);}if($current){$current[2]=$depth;$tokens[]=$prev=$current;}}return$tokens;}static
  3435. function
  3436. callBlock($context,$name,$params){if(empty($context->blocks[$name])){throw
  3437. new\XInvalidStateException("Cannot include undefined block '$name'.");}$block=reset($context->blocks[$name]);$block($context,$params);}static
  3438. function
  3439. callBlockParent($context,$name,$params){if(empty($context->blocks[$name])||($block=next($context->blocks[$name]))===FALSE){throw
  3440. new\XInvalidStateException("Cannot include undefined parent block '$name'.");}$block($context,$params);}static
  3441. function
  3442. includeTemplate($destination,$params,$template){if($destination
  3443. instanceof
  3444. ITemplate){$tpl=$destination;}elseif($destination==NULL){throw
  3445. new\InvalidArgumentException("Template file name was not specified.");}else{$tpl=clone$template;if($template
  3446. instanceof
  3447. IFileTemplate){if(substr($destination,0,1)!=='/'&&substr($destination,1,1)!==':'){$destination=dirname($template->getFile()).'/'.$destination;}$tpl->setFile($destination);}}$tpl->setParams($params);return$tpl;}static
  3448. function
  3449. initRuntime($template,$extends,$realFile){$local=(object)NULL;if(isset($template->_l)){$local->blocks=&$template->_l->blocks;$local->templates=&$template->_l->templates;}$local->templates[$realFile]=$template;$local->extends=is_bool($extends)?$extends:(empty($template->_extends)?FALSE:$template->_extends);unset($template->_l,$template->_extends);if(!isset($template->_g)){$template->_g=(object)NULL;}$local->g=$template->_g;if(!empty($local->g->caches)){end($local->g->caches)->addFile($template->getFile());}return$local;}static
  3450. function
  3451. renderSnippets($control,$local,$params){$payload=$control->getPresenter()->getPayload();if(isset($local->blocks)){foreach($local->blocks
  3452. as$name=>$function){if($name[0]!=='_'||!$control->isControlInvalid(substr($name,1)))continue;ob_start();$function=reset($function);$function($local,$params);$payload->snippets[$control->getSnippetId(substr($name,1))]=ob_get_clean();}}if($control
  3453. instanceof
  3454. NetteX\Application\Control){foreach($control->getComponents(FALSE,'NetteX\Application\Control')as$child){if($child->isControlInvalid()){$child->render();}}}}}final
  3455. class
  3456. TemplateFilters{final
  3457. function
  3458. __construct(){throw
  3459. new\LogicException("Cannot instantiate static class ".get_class($this));}static
  3460. function
  3461. removePhp($s){return
  3462. String::replace($s,'#\x01@php:p\d+@\x02#','<?php ?>');}static
  3463. function
  3464. relativeLinks($s){return
  3465. String::replace($s,'#(src|href|action)\s*=\s*(["\'])(?![a-z]+:|[\x01/\\#])#','$1=$2<?php echo \\$baseUri ?>');}static
  3466. function
  3467. netteLinks($s){return
  3468. String::replace($s,'#(src|href|action)\s*=\s*(["\'])(nette:.*?)([\#"\'])#',function($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
  3469. static$texy;static
  3470. function
  3471. texyElements($s){return
  3472. String::replace($s,'#<texy([^>]*)>(.*?)</texy>#s',function($m){list(,$mAttrs,$mContent)=$m;$attrs=array();if($mAttrs){foreach(String::matchAll($mAttrs,'#([a-z0-9:-]+)\s*(?:=\s*(\'[^\']*\'|"[^"]*"|[^\'"\s]+))?()#isu')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
  3473. TemplateFilters::$texy->process($m[2]);});}}use
  3474. NetteX\Forms\Form;use
  3475. NetteX\Web\Html;final
  3476. class
  3477. TemplateHelpers{public
  3478. static$dateFormat='%x';final
  3479. function
  3480. __construct(){throw
  3481. new\LogicException("Cannot instantiate static class ".get_class($this));}static
  3482. function
  3483. loader($helper){$callback=callbackX('NetteX\Templates\TemplateHelpers',$helper);if($callback->isCallable()){return$callback;}$callback=callbackX('NetteX\String',$helper);if($callback->isCallable()){return$callback;}}static
  3484. function
  3485. escapeHtml($s){if(is_object($s)&&($s
  3486. instanceof
  3487. ITemplate||$s
  3488. instanceof
  3489. Html||$s
  3490. instanceof
  3491. Form)){return$s->__toString(TRUE);}return
  3492. htmlSpecialChars($s,ENT_QUOTES);}static
  3493. function
  3494. escapeHtmlComment($s){return
  3495. str_replace('--','--><!-- ',$s);}static
  3496. function
  3497. escapeXML($s){return
  3498. htmlSpecialChars(preg_replace('#[\x00-\x08\x0B\x0C\x0E-\x1F]+#','',$s),ENT_QUOTES);}static
  3499. function
  3500. escapeCss($s){return
  3501. addcslashes($s,"\x00..\x2C./:;<=>?@[\\]^`{|}~");}static
  3502. function
  3503. escapeHtmlCss($s){return
  3504. htmlSpecialChars(self::escapeCss($s),ENT_QUOTES);}static
  3505. function
  3506. escapeJs($s){if(is_object($s)&&($s
  3507. instanceof
  3508. ITemplate||$s
  3509. instanceof
  3510. Html||$s
  3511. instanceof
  3512. Form)){$s=$s->__toString(TRUE);}return
  3513. str_replace(']]>',']]\x3E',NetteX\Json::encode($s));}static
  3514. function
  3515. escapeHtmlJs($s){return
  3516. htmlSpecialChars(self::escapeJs($s),ENT_QUOTES);}static
  3517. function
  3518. strip($s){return
  3519. String::replace($s,'#(</textarea|</pre|</script|^).*?(?=<textarea|<pre|<script|$)#si',function($m){return
  3520. trim(preg_replace("#[ \t\r\n]+#"," ",$m[0]));});}static
  3521. function
  3522. indent($s,$level=1,$chars="\t"){if($level>=1){$s=String::replace($s,'#<(textarea|pre).*?</\\1#si',function($m){return
  3523. strtr($m[0]," \t\r\n","\x1F\x1E\x1D\x1A");});$s=String::indent($s,$level,$chars);$s=strtr($s,"\x1F\x1E\x1D\x1A"," \t\r\n");}return$s;}static
  3524. function
  3525. date($time,$format=NULL){if($time==NULL){return
  3526. NULL;}if(!isset($format)){$format=self::$dateFormat;}$time=NetteX\Tools::createDateTime($time);return
  3527. strpos($format,'%')===FALSE?$time->format($format):strftime($format,$time->format('U'));}static
  3528. function
  3529. bytes($bytes,$precision=2){$bytes=round($bytes);$units=array('B','kB','MB','GB','TB','PB');foreach($units
  3530. as$unit){if(abs($bytes)<1024||$unit===end($units))break;$bytes=$bytes/1024;}return
  3531. round($bytes,$precision).' '.$unit;}static
  3532. function
  3533. length($var){return
  3534. is_string($var)?String::length($var):count($var);}static
  3535. function
  3536. replace($subject,$search,$replacement=''){return
  3537. str_replace($search,$replacement,$subject);}static
  3538. function
  3539. null($value){return'';}}class
  3540. TemplateCacheStorage
  3541. extends
  3542. NetteX\Caching\FileStorage{protected
  3543. function
  3544. readData($meta){return
  3545. array('file'=>$meta[self::FILE],'handle'=>$meta[self::HANDLE]);}protected
  3546. function
  3547. getCacheFile($key){return
  3548. parent::getCacheFile($key).'.php';}}}namespace NetteX{use
  3549. NetteX;final
  3550. class
  3551. ArrayTools{final
  3552. function
  3553. __construct(){throw
  3554. new\LogicException("Cannot instantiate static class ".get_class($this));}static
  3555. function
  3556. 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
  3557. function&getRef(&$arr,$key){foreach(is_array($key)?$key:array($key)as$k){if(is_array($arr)||$arr===NULL){$arr=&$arr[$k];}else{throw
  3558. new\InvalidArgumentException('Traversed item is not an array.');}}return$arr;}static
  3559. function
  3560. 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
  3561. function
  3562. searchKey($arr,$key){$foo=array($key=>NULL);return
  3563. array_search(key($foo),array_keys($arr),TRUE);}static
  3564. function
  3565. 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
  3566. function
  3567. 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
  3568. function
  3569. 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);}}static
  3570. function
  3571. grep(array$arr,$pattern,$flags=0){Debug::tryError();$res=preg_grep($pattern,$arr,$flags);String::catchPregError($pattern);return$res;}}class
  3572. Context
  3573. extends
  3574. FreezableObject
  3575. implements
  3576. IContext{private$registry=array();private$factories=array();function
  3577. addService($name,$service,$singleton=TRUE,array$options=NULL){$this->updating();if(!is_string($name)||$name===''){throw
  3578. new\InvalidArgumentException("Service name must be a non-empty string, ".gettype($name)." given.");}$lower=strtolower($name);if(isset($this->registry[$lower])){throw
  3579. new
  3580. AmbiguousServiceException("Service named '$name' has already been registered.");}if(is_object($service)&&!($service
  3581. instanceof\Closure||$service
  3582. instanceof
  3583. Callback)){if(!$singleton||$options){throw
  3584. new\InvalidArgumentException("Service named '$name' is an instantiated object and must therefore be singleton without options.");}$this->registry[$lower]=$service;}else{if(!$service){throw
  3585. new\InvalidArgumentException("Service named '$name' is empty.");}$this->factories[$lower]=array($service,$singleton,$options);}}function
  3586. removeService($name){$this->updating();if(!is_string($name)||$name===''){throw
  3587. new\InvalidArgumentException("Service name must be a non-empty string, ".gettype($name)." given.");}$lower=strtolower($name);unset($this->registry[$lower],$this->factories[$lower]);}function
  3588. getService($name,array$options=NULL){if(!is_string($name)||$name===''){throw
  3589. new\InvalidArgumentException("Service name must be a non-empty string, ".gettype($name)." given.");}$lower=strtolower($name);if(isset($this->registry[$lower])){if($options){throw
  3590. new\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
  3591. new\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){if(!class_exists($factory)){throw
  3592. new
  3593. AmbiguousServiceException("Cannot instantiate service '$name', class '$factory' not found.");}$service=new$factory;if($options&&method_exists($service,'setOptions')){$service->setOptions($options);}}else{$factory=callbackX($factory);if(!$factory->isCallable()){throw
  3594. new\XInvalidStateException("Cannot instantiate service '$name', handler '$factory' is not callable.");}$service=$factory($options);if(!is_object($service)){throw
  3595. new
  3596. AmbiguousServiceException("Cannot instantiate service '$name', value returned by '$factory' is not object.");}}if($singleton){$this->registry[$lower]=$service;unset($this->factories[$lower]);}return$service;}else{throw
  3597. new\XInvalidStateException("Service '$name' not found.");}}function
  3598. hasService($name,$created=FALSE){if(!is_string($name)||$name===''){throw
  3599. new\InvalidArgumentException("Service name must be a non-empty string, ".gettype($name)." given.");}$lower=strtolower($name);return
  3600. isset($this->registry[$lower])||(!$created&&isset($this->factories[$lower]));}}class
  3601. AmbiguousServiceException
  3602. extends\Exception{}use
  3603. RecursiveIteratorIterator;class
  3604. Finder
  3605. extends
  3606. Object
  3607. implements\IteratorAggregate{private$paths=array();private$groups;private$exclude=array();private$order=RecursiveIteratorIterator::SELF_FIRST;private$maxDepth=-1;private$cursor;static
  3608. function
  3609. find($mask){if(!is_array($mask)){$mask=func_get_args();}$finder=new
  3610. self;return$finder->select(array(),'isDir')->select($mask,'isFile');}static
  3611. function
  3612. findFiles($mask){if(!is_array($mask)){$mask=func_get_args();}$finder=new
  3613. self;return$finder->select($mask,'isFile');}static
  3614. function
  3615. findDirectories($mask){if(!is_array($mask)){$mask=func_get_args();}$finder=new
  3616. self;return$finder->select($mask,'isDir');}private
  3617. function
  3618. select($masks,$type){$this->cursor=&$this->groups[];$pattern=self::buildPattern($masks);if($type||$pattern){$this->filter(function($file)use($type,$pattern){return(!$type||$file->$type())&&!$file->isDot()&&(!$pattern||preg_match($pattern,'/'.strtr($file->getSubPathName(),'\\','/')));});}return$this;}function
  3619. in($path){if(!is_array($path)){$path=func_get_args();}$this->maxDepth=0;return$this->from($path);}function
  3620. from($path){if($this->paths){throw
  3621. new\XInvalidStateException('Directory to search has already been specified.');}if(!is_array($path)){$path=func_get_args();}$this->paths=$path;$this->cursor=&$this->exclude;return$this;}function
  3622. childFirst(){$this->order=RecursiveIteratorIterator::CHILD_FIRST;return$this;}private
  3623. static
  3624. function
  3625. buildPattern($masks){$pattern=array();foreach($masks
  3626. as$mask){$mask=rtrim(strtr($mask,'\\','/'),'/');$prefix='';if($mask===''){continue;}elseif($mask==='*'){return
  3627. NULL;}elseif($mask[0]==='/'){$mask=ltrim($mask,'/');$prefix='(?<=^/)';}$pattern[]=$prefix.strtr(preg_quote($mask,'#'),array('\*\*'=>'.*','\*'=>'[^/]*','\?'=>'[^/]','\[\!'=>'[^','\['=>'[','\]'=>']','\-'=>'-'));}return$pattern?'#/('.implode('|',$pattern).')$#i':NULL;}function
  3628. getIterator(){if(!$this->paths){throw
  3629. new\XInvalidStateException('Call in() or from() to specify directory to search.');}elseif(count($this->paths)===1){return$this->buildIterator($this->paths[0]);}else{$iterator=new\AppendIterator();foreach($this->paths
  3630. as$path){$iterator->append($this->buildIterator($path));}return$iterator;}}private
  3631. function
  3632. buildIterator($path){if(PHP_VERSION_ID<50301){$iterator=new
  3633. RecursiveDirectoryIteratorFixed($path);}else{$iterator=new\RecursiveDirectoryIterator($path,\RecursiveDirectoryIterator::FOLLOW_SYMLINKS);}if($this->exclude){$filters=$this->exclude;$iterator=new
  3634. RecursiveCallbackFilterIterator($iterator,function($file)use($filters){if(!$file->isFile()){foreach($filters
  3635. as$filter){if(!call_user_func($filter,$file)){return
  3636. FALSE;}}}return
  3637. TRUE;});}if($this->maxDepth!==0){$iterator=new
  3638. RecursiveIteratorIterator($iterator,$this->order);$iterator->setMaxDepth($this->maxDepth);}if($this->groups){$groups=$this->groups;$iterator=new
  3639. CallbackFilterIterator($iterator,function($file)use($groups){foreach($groups
  3640. as$filters){foreach($filters
  3641. as$filter){if(!call_user_func($filter,$file)){continue
  3642. 2;}}return
  3643. TRUE;}return
  3644. FALSE;});}return$iterator;}function
  3645. exclude($masks){if(!is_array($masks)){$masks=func_get_args();}$pattern=self::buildPattern($masks);if($pattern){$this->filter(function($file)use($pattern){return!preg_match($pattern,'/'.strtr($file->getSubPathName(),'\\','/'));});}return$this;}function
  3646. filter($callback){$this->cursor[]=$callback;return$this;}function
  3647. limitDepth($depth){$this->maxDepth=$depth;return$this;}function
  3648. size($operator,$size=NULL){if(func_num_args()===1){if(!preg_match('#^(?:([=<>!]=?|<>)\s*)?((?:\d*\.)?\d+)\s*(K|M|G|)B?$#i',$operator,$matches)){throw
  3649. new\InvalidArgumentException('Invalid size predicate format.');}list(,$operator,$size,$unit)=$matches;static$units=array(''=>1,'k'=>1e3,'m'=>1e6,'g'=>1e9);$size*=$units[strtolower($unit)];$operator=$operator?$operator:'=';}return$this->filter(function($file)use($operator,$size){return
  3650. Tools::compare($file->getSize(),$operator,$size);});}function
  3651. date($operator,$date=NULL){if(func_num_args()===1){if(!preg_match('#^(?:([=<>!]=?|<>)\s*)?(.+)$#i',$operator,$matches)){throw
  3652. new\InvalidArgumentException('Invalid date predicate format.');}list(,$operator,$date)=$matches;$operator=$operator?$operator:'=';}$date=Tools::createDateTime($date)->format('U');return$this->filter(function($file)use($operator,$date){return
  3653. Tools::compare($file->getMTime(),$operator,$date);});}}if(PHP_VERSION_ID<50301){class
  3654. RecursiveDirectoryIteratorFixed
  3655. extends\RecursiveDirectoryIterator{function
  3656. hasChildren(){return
  3657. parent::hasChildren(TRUE);}}}class
  3658. Image
  3659. extends
  3660. Object{const
  3661. ENLARGE=1;const
  3662. STRETCH=2;const
  3663. FIT=0;const
  3664. FILL=4;const
  3665. JPEG=IMAGETYPE_JPEG;const
  3666. PNG=IMAGETYPE_PNG;const
  3667. GIF=IMAGETYPE_GIF;const
  3668. 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
  3669. static$useImageMagick=FALSE;private$image;static
  3670. function
  3671. rgb($red,$green,$blue,$transparency=0){return
  3672. 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
  3673. function
  3674. fromFile($file,&$format=NULL){if(!extension_loaded('gd')){throw
  3675. new\Exception("PHP extension GD is not loaded.");}$info=@getimagesize($file);if(self::$useImageMagick&&(empty($info)||$info[0]*$info[1]>9e5)){return
  3676. new
  3677. ImageMagick($file,$format);}switch($format=$info[2]){case
  3678. self::JPEG:return
  3679. new
  3680. static(imagecreatefromjpeg($file));case
  3681. self::PNG:return
  3682. new
  3683. static(imagecreatefrompng($file));case
  3684. self::GIF:return
  3685. new
  3686. static(imagecreatefromgif($file));default:if(self::$useImageMagick){return
  3687. new
  3688. ImageMagick($file,$format);}throw
  3689. new\Exception("Unknown image type or file '$file' not found.");}}static
  3690. function
  3691. getFormatFromString($s){if(strncmp($s,"\xff\xd8",2)===0){return
  3692. self::JPEG;}if(strncmp($s,"\x89PNG",4)===0){return
  3693. self::PNG;}if(strncmp($s,"GIF",3)===0){return
  3694. self::GIF;}return
  3695. NULL;}static
  3696. function
  3697. fromString($s,&$format=NULL){if(!extension_loaded('gd')){throw
  3698. new\Exception("PHP extension GD is not loaded.");}$format=static::getFormatFromString($s);return
  3699. new
  3700. static(imagecreatefromstring($s));}static
  3701. function
  3702. fromBlank($width,$height,$color=NULL){if(!extension_loaded('gd')){throw
  3703. new\Exception("PHP extension GD is not loaded.");}$width=(int)$width;$height=(int)$height;if($width<1||$height<1){throw
  3704. new\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
  3705. new
  3706. static($image);}function
  3707. __construct($image){$this->setImageResource($image);}function
  3708. getWidth(){return
  3709. imagesx($this->image);}function
  3710. getHeight(){return
  3711. imagesy($this->image);}protected
  3712. function
  3713. setImageResource($image){if(!is_resource($image)||get_resource_type($image)!=='gd'){throw
  3714. new\InvalidArgumentException('Image is not valid.');}$this->image=$image;return$this;}function
  3715. getImageResource(){return$this->image;}function
  3716. 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
  3717. function
  3718. 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
  3719. new\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
  3720. new\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
  3721. array((int)$newWidth,(int)$newHeight);}function
  3722. crop($left,$top,$width,$height){list($left,$top,$width,$height)=self::calculateCutout($this->getWidth(),$this->getHeight(),$left,$top,$width,$height);$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;}static
  3723. function
  3724. calculateCutout($srcWidth,$srcHeight,$left,$top,$newWidth,$newHeight){if(substr($newWidth,-1)==='%'){$newWidth=round($srcWidth/100*$newWidth);}if(substr($newHeight,-1)==='%'){$newHeight=round($srcHeight/100*$newHeight);}if(substr($left,-1)==='%'){$left=round(($srcWidth-$newWidth)/100*$left);}if(substr($top,-1)==='%'){$top=round(($srcHeight-$newHeight)/100*$top);}if($left<0){$newWidth+=$left;$left=0;}if($top<0){$newHeight+=$top;$top=0;}$newWidth=min((int)$newWidth,$srcWidth-$left);$newHeight=min((int)$newHeight,$srcHeight-$top);return
  3725. array($left,$top,$newWidth,$newHeight);}function
  3726. sharpen(){imageconvolution($this->getImageResource(),array(array(-1,-1,-1),array(-1,24,-1),array(-1,-1,-1)),16,0);return$this;}function
  3727. 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
  3728. 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
  3729. self::JPEG:$quality=$quality===NULL?85:max(0,min(100,(int)$quality));return
  3730. imagejpeg($this->getImageResource(),$file,$quality);case
  3731. self::PNG:$quality=$quality===NULL?9:max(0,min(9,(int)$quality));return
  3732. imagepng($this->getImageResource(),$file,$quality);case
  3733. self::GIF:return$file===NULL?imagegif($this->getImageResource()):imagegif($this->getImageResource(),$file);default:throw
  3734. new\Exception("Unsupported image type.");}}function
  3735. toString($type=self::JPEG,$quality=NULL){ob_start();$this->save(NULL,$quality,$type);return
  3736. ob_get_clean();}function
  3737. __toString(){try{return$this->toString();}catch(\Exception$e){Debug::toStringException($e);}}function
  3738. send($type=self::JPEG,$quality=NULL){if($type!==self::GIF&&$type!==self::PNG&&$type!==self::JPEG){throw
  3739. new\Exception("Unsupported image type.");}header('Content-Type: '.image_type_to_mime_type($type));return$this->save(NULL,$quality,$type);}function
  3740. __call($name,$args){$function='image'.$name;if(function_exists($function)){foreach($args
  3741. as$key=>$value){if($value
  3742. instanceof
  3743. 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
  3744. is_resource($res)&&get_resource_type($res)==='gd'?$this->setImageResource($res):$res;}return
  3745. parent::__call($name,$args);}}class
  3746. ImageMagick
  3747. extends
  3748. Image{public
  3749. static$path='';public
  3750. static$tempDir;private$file;private$isTemporary=FALSE;private$width;private$height;function
  3751. __construct($file,&$format=NULL){if(!is_file($file)){throw
  3752. new\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
  3753. getWidth(){return$this->file===NULL?parent::getWidth():$this->width;}function
  3754. getHeight(){return$this->file===NULL?parent::getHeight():$this->height;}function
  3755. 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
  3756. parent::getImageResource();}function
  3757. resize($width,$height,$flags=self::FIT){if($this->file===NULL){return
  3758. parent::resize($width,$height,$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
  3759. crop($left,$top,$width,$height){if($this->file===NULL){return
  3760. parent::crop($left,$top,$width,$height);}list($left,$top,$width,$height)=self::calculateCutout($this->getWidth(),$this->getHeight(),$left,$top,$width,$height);$this->execute("convert -crop {$width}x{$height}+{$left}+{$top} -strip %input %output",self::PNG);return$this;}function
  3761. save($file=NULL,$quality=NULL,$type=NULL){if($this->file===NULL){return
  3762. 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
  3763. TRUE;}private
  3764. function
  3765. setFile($file){$this->file=$file;$res=$this->execute('identify -format "%w,%h,%m" '.escapeshellarg($this->file));if(!$res){throw
  3766. new\Exception("Unknown image type in file '$file' or ImageMagick not available.");}list($this->width,$this->height,$format)=explode(',',$res,3);return$format;}private
  3767. function
  3768. 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
  3769. new\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
  3770. __destruct(){if($this->file!==NULL&&$this->isTemporary){unlink($this->file);}}}class
  3771. CallbackFilterIterator
  3772. extends\FilterIterator{private$callback;function
  3773. __construct(\Iterator$iterator,$callback){parent::__construct($iterator);$this->callback=$callback;}function
  3774. accept(){return
  3775. call_user_func($this->callback,$this);}}class
  3776. RecursiveCallbackFilterIterator
  3777. extends\FilterIterator
  3778. implements\RecursiveIterator{private$callback;private$childrenCallback;function
  3779. __construct(\RecursiveIterator$iterator,$callback,$childrenCallback=NULL){parent::__construct($iterator);$this->callback=$callback;$this->childrenCallback=$childrenCallback;}function
  3780. accept(){return$this->callback===NULL||call_user_func($this->callback,$this);}function
  3781. hasChildren(){return$this->getInnerIterator()->hasChildren()&&($this->childrenCallback===NULL||call_user_func($this->childrenCallback,$this));}function
  3782. getChildren(){return
  3783. new
  3784. self($this->getInnerIterator()->getChildren(),$this->callback,$this->childrenCallback);}}class
  3785. GenericRecursiveIterator
  3786. extends\IteratorIterator
  3787. implements\RecursiveIterator,\Countable{function
  3788. hasChildren(){$obj=$this->current();return($obj
  3789. instanceof\IteratorAggregate&&$obj->getIterator()instanceof\RecursiveIterator)||$obj
  3790. instanceof\RecursiveIterator;}function
  3791. getChildren(){$obj=$this->current();return$obj
  3792. instanceof\IteratorAggregate?$obj->getIterator():$obj;}function
  3793. count(){return
  3794. iterator_count($this);}}class
  3795. InstanceFilterIterator
  3796. extends\FilterIterator
  3797. implements\Countable{private$type;function
  3798. __construct(\Iterator$iterator,$type){$this->type=$type;parent::__construct($iterator);}function
  3799. accept(){return$this->current()instanceof$this->type;}function
  3800. count(){return
  3801. iterator_count($this);}}class
  3802. SmartCachingIterator
  3803. extends\CachingIterator
  3804. implements\Countable{private$counter=0;function
  3805. __construct($iterator){if(is_array($iterator)||$iterator
  3806. instanceof\stdClass){$iterator=new\ArrayIterator($iterator);}elseif($iterator
  3807. instanceof\Traversable){if($iterator
  3808. instanceof\IteratorAggregate){$iterator=$iterator->getIterator();}elseif(!($iterator
  3809. instanceof\Iterator)){$iterator=new\IteratorIterator($iterator);}}else{throw
  3810. new\InvalidArgumentException("Invalid argument passed to foreach resp. ".__CLASS__."; array or Traversable expected, ".(is_object($iterator)?get_class($iterator):gettype($iterator))." given.");}parent::__construct($iterator,0);}function
  3811. isFirst($width=NULL){return$this->counter===1||($width&&$this->counter!==0&&(($this->counter-1)%$width)===0);}function
  3812. isLast($width=NULL){return!$this->hasNext()||($width&&($this->counter
  3813. %$width)===0);}function
  3814. isEmpty(){return$this->counter===0;}function
  3815. isOdd(){return$this->counter
  3816. %
  3817. 2===1;}function
  3818. isEven(){return$this->counter
  3819. %
  3820. 2===0;}function
  3821. getCounter(){return$this->counter;}function
  3822. count(){$inner=$this->getInnerIterator();if($inner
  3823. instanceof\Countable){return$inner->count();}else{throw
  3824. new\XNotSupportedException('Iterator is not countable.');}}function
  3825. next(){parent::next();if(parent::valid()){$this->counter++;}}function
  3826. rewind(){parent::rewind();$this->counter=parent::valid()?1:0;}function
  3827. getNextKey(){return$this->getInnerIterator()->key();}function
  3828. getNextValue(){return$this->getInnerIterator()->current();}function
  3829. __call($name,$args){return
  3830. ObjectMixin::call($this,$name,$args);}function&__get($name){return
  3831. ObjectMixin::get($this,$name);}function
  3832. __set($name,$value){return
  3833. ObjectMixin::set($this,$name,$value);}function
  3834. __isset($name){return
  3835. ObjectMixin::has($this,$name);}function
  3836. __unset($name){$class=get_class($this);throw
  3837. new\XMemberAccessException("Cannot unset the property $class::\$$name.");}}final
  3838. class
  3839. Json{const
  3840. FORCE_ARRAY=1;private
  3841. static$messages=array(JSON_ERROR_DEPTH=>'The maximum stack depth has been exceeded',JSON_ERROR_STATE_MISMATCH=>'Syntax error, malformed JSON',JSON_ERROR_CTRL_CHAR=>'Unexpected control character found',JSON_ERROR_SYNTAX=>'Syntax error, malformed JSON');final
  3842. function
  3843. __construct(){throw
  3844. new\LogicException("Cannot instantiate static class ".get_class($this));}static
  3845. function
  3846. encode($value){Debug::tryError();if(function_exists('ini_set')){$old=ini_set('display_errors',0);$json=json_encode($value);ini_set('display_errors',$old);}else{$json=json_encode($value);}if(Debug::catchError($e)){throw
  3847. new
  3848. JsonException($e->getMessage());}return$json;}static
  3849. function
  3850. decode($json,$options=0){$json=(string)$json;$value=json_decode($json,(bool)($options&self::FORCE_ARRAY));if($value===NULL&&$json!==''&&strcasecmp($json,'null')){$error=PHP_VERSION_ID>=50300?json_last_error():0;throw
  3851. new
  3852. JsonException(isset(self::$messages[$error])?self::$messages[$error]:'Unknown error',$error);}return$value;}}class
  3853. JsonException
  3854. extends\Exception{}class
  3855. NeonParser
  3856. extends
  3857. Object{private
  3858. static$patterns=array('\'[^\'\n]*\'|"(?:\\\\.|[^"\\\\\n])*"','@[a-zA-Z_0-9\\\\]+','[:-](?=\s|$)|[,=[\]{}()]','?:#.*','\n *','[^#"\',:=@[\]{}()<>\s](?:[^#,:=\]})>\n]+|:(?!\s)|(?<!\s)#)*(?<!\s)','?: +');private
  3859. static$tokenizer;private
  3860. static$brackets=array('['=>']','{'=>'}','('=>')');private$n;function
  3861. parse($input){if(!self::$tokenizer){self::$tokenizer=new
  3862. Tokenizer(self::$patterns,'mi');}$input=str_replace("\r",'',$input);$input=strtr($input,"\t",' ');$input="\n".$input."\n";self::$tokenizer->tokenize($input);$this->n=0;$res=$this->_parse();while(isset(self::$tokenizer->tokens[$this->n])){if(self::$tokenizer->tokens[$this->n][0]==="\n"){$this->n++;}else{$this->error();}}return$res;}private
  3863. function
  3864. _parse($indent=NULL,$endBracket=NULL){$inlineParser=$endBracket!==NULL;$result=$inlineParser||$indent?array():NULL;$value=$key=$object=NULL;$hasValue=$hasKey=FALSE;$tokens=self::$tokenizer->tokens;$n=&$this->n;$count=count($tokens);for(;$n<$count;$n++){$t=$tokens[$n];if($t===','){if(!$hasValue||!$inlineParser){$this->error();}if($hasKey)$result[$key]=$value;else$result[]=$value;$hasKey=$hasValue=FALSE;}elseif($t===':'||$t==='='){if($hasKey||!$hasValue){$this->error();}$key=(string)$value;$hasKey=TRUE;$hasValue=FALSE;}elseif($t==='-'){if($hasKey||$hasValue||$inlineParser){$this->error();}$key=NULL;$hasKey=TRUE;}elseif(isset(self::$brackets[$t])){if($hasValue){$this->error();}$hasValue=TRUE;$value=$this->_parse(NULL,self::$brackets[$tokens[$n++]]);}elseif($t===']'||$t==='}'||$t===')'){if($t!==$endBracket){$this->error();}if($hasValue){if($hasKey)$result[$key]=$value;else$result[]=$value;}elseif($hasKey){$this->error();}return$result;}elseif($t[0]==='@'){$object=$t;}elseif($t[0]==="\n"){if($inlineParser){if($hasValue){if($hasKey)$result[$key]=$value;else$result[]=$value;$hasKey=$hasValue=FALSE;}}else{while(isset($tokens[$n+1])&&$tokens[$n+1][0]==="\n")$n++;$newIndent=strlen($tokens[$n])-1;if($indent===NULL){$indent=$newIndent;}if($newIndent>$indent){if($hasValue||!$hasKey){$this->error();}elseif($key===NULL){$result[]=$this->_parse($newIndent);}else{$result[$key]=$this->_parse($newIndent);}$newIndent=strlen($tokens[$n])-1;$hasKey=FALSE;}else{if($hasValue&&!$hasKey){if($result===NULL)return$value;$this->error();}elseif($hasKey){$value=$hasValue?$value:NULL;if($key===NULL)$result[]=$value;else$result[$key]=$value;$hasKey=$hasValue=FALSE;}}if($newIndent<$indent||!isset($tokens[$n+1])){return$result;}}}else{if($hasValue){$this->error();}if($t[0]==='"'){$value=json_decode($t);if($value===NULL){$this->error();}}elseif($t[0]==="'"){$value=substr($t,1,-1);}elseif($t==='true'||$t==='yes'||$t==='TRUE'||$t==='YES'){$value=TRUE;}elseif($t==='false'||$t==='no'||$t==='FALSE'||$t==='NO'){$value=FALSE;}elseif($t==='null'||$t==='NULL'){$value=NULL;}elseif(is_numeric($t)){$value=$t*1;}else{$value=$t;}$hasValue=TRUE;}}throw
  3865. new
  3866. NeonException('Unexpected end of file.');}private
  3867. function
  3868. error(){list(,$line,$col)=self::$tokenizer->getOffset($this->n);throw
  3869. new
  3870. NeonException("Unexpected '".str_replace("\n",'\n',substr(self::$tokenizer->tokens[$this->n],0,10))."' on line ".($line-1).", column $col.");}}class
  3871. NeonException
  3872. extends\Exception{}class
  3873. Paginator
  3874. extends
  3875. Object{private$base=1;private$itemsPerPage=1;private$page;private$itemCount=0;function
  3876. setPage($page){$this->page=(int)$page;return$this;}function
  3877. getPage(){return$this->base+$this->getPageIndex();}function
  3878. getFirstPage(){return$this->base;}function
  3879. getLastPage(){return$this->base+max(0,$this->getPageCount()-1);}function
  3880. setBase($base){$this->base=(int)$base;return$this;}function
  3881. getBase(){return$this->base;}protected
  3882. function
  3883. getPageIndex(){return
  3884. min(max(0,$this->page-$this->base),max(0,$this->getPageCount()-1));}function
  3885. isFirst(){return$this->getPageIndex()===0;}function
  3886. isLast(){return$this->getPageIndex()>=$this->getPageCount()-1;}function
  3887. getPageCount(){return(int)ceil($this->itemCount/$this->itemsPerPage);}function
  3888. setItemsPerPage($itemsPerPage){$this->itemsPerPage=max(1,(int)$itemsPerPage);return$this;}function
  3889. getItemsPerPage(){return$this->itemsPerPage;}function
  3890. setItemCount($itemCount){$this->itemCount=$itemCount===FALSE?PHP_INT_MAX:max(0,(int)$itemCount);return$this;}function
  3891. getItemCount(){return$this->itemCount;}function
  3892. getOffset(){return$this->getPageIndex()*$this->itemsPerPage;}function
  3893. getCountdownOffset(){return
  3894. max(0,$this->itemCount-($this->getPageIndex()+1)*$this->itemsPerPage);}function
  3895. getLength(){return
  3896. min($this->itemsPerPage,$this->itemCount-$this->getPageIndex()*$this->itemsPerPage);}}final
  3897. class
  3898. SafeStream{const
  3899. PROTOCOL='safe';private$handle;private$filePath;private$tempFile;private$startPos=0;private$writeError=FALSE;static
  3900. function
  3901. register(){return
  3902. stream_wrapper_register(self::PROTOCOL,__CLASS__);}function
  3903. 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
  3904. FALSE;if(flock($handle,$mode=='r'?LOCK_SH:LOCK_EX)){$this->handle=$handle;return
  3905. TRUE;}fclose($handle);return
  3906. 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
  3907. TRUE;}fclose($handle);}$mode{0}='x';case'x':case'x+':if(file_exists($path))return
  3908. 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
  3909. TRUE;}fclose($handle);unlink($path.$tmp);}return
  3910. FALSE;default:trigger_error("Unsupported mode $mode",E_USER_WARNING);return
  3911. FALSE;}}function
  3912. 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
  3913. stream_read($length){return
  3914. fread($this->handle,$length);}function
  3915. stream_write($data){$len=strlen($data);$res=fwrite($this->handle,$data,$len);if($res!==$len){$this->writeError=TRUE;}return$res;}function
  3916. stream_tell(){return
  3917. ftell($this->handle);}function
  3918. stream_eof(){return
  3919. feof($this->handle);}function
  3920. stream_seek($offset,$whence){return
  3921. fseek($this->handle,$offset,$whence)===0;}function
  3922. stream_stat(){return
  3923. fstat($this->handle);}function
  3924. url_stat($path,$flags){$path=substr($path,strlen(self::PROTOCOL)+3);return($flags&STREAM_URL_STAT_LINK)?@lstat($path):@stat($path);}function
  3925. unlink($path){$path=substr($path,strlen(self::PROTOCOL)+3);return
  3926. unlink($path);}}final
  3927. class
  3928. String{final
  3929. function
  3930. __construct(){throw
  3931. new\LogicException("Cannot instantiate static class ".get_class($this));}static
  3932. function
  3933. checkEncoding($s,$encoding='UTF-8'){return$s===self::fixEncoding($s,$encoding);}static
  3934. function
  3935. fixEncoding($s,$encoding='UTF-8'){return@iconv('UTF-16',$encoding.'//IGNORE',iconv($encoding,'UTF-16//IGNORE',$s));}static
  3936. function
  3937. chr($code,$encoding='UTF-8'){return
  3938. iconv('UTF-32BE',$encoding.'//IGNORE',pack('N',$code));}static
  3939. function
  3940. startsWith($haystack,$needle){return
  3941. strncmp($haystack,$needle,strlen($needle))===0;}static
  3942. function
  3943. endsWith($haystack,$needle){return
  3944. strlen($needle)===0||substr($haystack,-strlen($needle))===$needle;}static
  3945. function
  3946. 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
  3947. function
  3948. toAscii($s){$s=preg_replace('#[^\x09\x0A\x0D\x20-\x7E\xA0-\x{10FFFF}]#u','',$s);$s=strtr($s,'`\'"^~',"\x01\x02\x03\x04\x05");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);return
  3949. strtr($s,"\x01\x02\x03\x04\x05",'`\'"^~');}static
  3950. function
  3951. webalize($s,$charlist=NULL,$lower=TRUE){$s=self::toAscii($s);if($lower)$s=strtolower($s);$s=preg_replace('#[^a-z0-9'.preg_quote($charlist,'#').']+#i','-',$s);$s=trim($s,'-');return$s;}static
  3952. function
  3953. truncate($s,$maxLen,$append="\xE2\x80\xA6"){if(self::length($s)>$maxLen){$maxLen=$maxLen-self::length($append);if($maxLen<1){return$append;}elseif($matches=self::match($s,'#^.{1,'.$maxLen.'}(?=[\s\x00-/:-@\[-`{-~])#us')){return$matches[0].$append;}else{return
  3954. iconv_substr($s,0,$maxLen,'UTF-8').$append;}}return$s;}static
  3955. function
  3956. indent($s,$level=1,$chars="\t"){return$level<1?$s:self::replace($s,'#(?:^|[\r\n]+)(?=[^\r\n])#','$0'.str_repeat($chars,$level));}static
  3957. function
  3958. lower($s){return
  3959. mb_strtolower($s,'UTF-8');}static
  3960. function
  3961. upper($s){return
  3962. mb_strtoupper($s,'UTF-8');}static
  3963. function
  3964. capitalize($s){return
  3965. mb_convert_case($s,MB_CASE_TITLE,'UTF-8');}static
  3966. function
  3967. compare($left,$right,$len=NULL){if($len<0){$left=iconv_substr($left,$len,-$len,'UTF-8');$right=iconv_substr($right,$len,-$len,'UTF-8');}elseif($len!==NULL){$left=iconv_substr($left,0,$len,'UTF-8');$right=iconv_substr($right,0,$len,'UTF-8');}return
  3968. self::lower($left)===self::lower($right);}static
  3969. function
  3970. length($s){return
  3971. function_exists('mb_strlen')?mb_strlen($s,'UTF-8'):strlen(utf8_decode($s));}static
  3972. function
  3973. trim($s,$charlist=" \t\n\r\0\x0B\xC2\xA0"){$charlist=preg_quote($charlist,'#');return
  3974. self::replace($s,'#^['.$charlist.']+|['.$charlist.']+$#u','');}static
  3975. function
  3976. padLeft($s,$length,$pad=' '){$length=max(0,$length-self::length($s));$padLen=self::length($pad);return
  3977. str_repeat($pad,$length/$padLen).iconv_substr($pad,0,$length
  3978. %$padLen,'UTF-8').$s;}static
  3979. function
  3980. padRight($s,$length,$pad=' '){$length=max(0,$length-self::length($s));$padLen=self::length($pad);return$s.str_repeat($pad,$length/$padLen).iconv_substr($pad,0,$length
  3981. %$padLen,'UTF-8');}static
  3982. function
  3983. split($subject,$pattern,$flags=0){Debug::tryError();$res=preg_split($pattern,$subject,-1,$flags|PREG_SPLIT_DELIM_CAPTURE);self::catchPregError($pattern);return$res;}static
  3984. function
  3985. match($subject,$pattern,$flags=0,$offset=0){Debug::tryError();$res=preg_match($pattern,$subject,$m,$flags,$offset);self::catchPregError($pattern);if($res){return$m;}}static
  3986. function
  3987. matchAll($subject,$pattern,$flags=0,$offset=0){Debug::tryError();$res=preg_match_all($pattern,$subject,$m,($flags&PREG_PATTERN_ORDER)?$flags:($flags|PREG_SET_ORDER),$offset);self::catchPregError($pattern);return$m;}static
  3988. function
  3989. replace($subject,$pattern,$replacement=NULL,$limit=-1){Debug::tryError();if(is_object($replacement)||is_array($replacement)){if($replacement
  3990. instanceof
  3991. Callback){$replacement=$replacement->getNative();}if(!is_callable($replacement,FALSE,$textual)){Debug::catchError($foo);throw
  3992. new\XInvalidStateException("Callback '$textual' is not callable.");}$res=preg_replace_callback($pattern,$replacement,$subject,$limit);if(Debug::catchError($e)){$trace=$e->getTrace();if(isset($trace[2]['class'])&&$trace[2]['class']===__CLASS__){throw
  3993. new
  3994. RegexpException($e->getMessage()." in pattern: $pattern");}}}elseif(is_array($pattern)){$res=preg_replace(array_keys($pattern),array_values($pattern),$subject,$limit);}else{$res=preg_replace($pattern,$replacement,$subject,$limit);}self::catchPregError($pattern);return$res;}static
  3995. function
  3996. catchPregError($pattern){if(Debug::catchError($e)){throw
  3997. new
  3998. RegexpException($e->getMessage()." in pattern: $pattern");}elseif(preg_last_error()){static$messages=array(PREG_INTERNAL_ERROR=>'Internal error',PREG_BACKTRACK_LIMIT_ERROR=>'Backtrack limit was exhausted',PREG_RECURSION_LIMIT_ERROR=>'Recursion limit was exhausted',PREG_BAD_UTF8_ERROR=>'Malformed UTF-8 data',5=>'Offset didn\'t correspond to the begin of a valid UTF-8 code point');$code=preg_last_error();throw
  3999. new
  4000. RegexpException((isset($messages[$code])?$messages[$code]:'Unknown error')." (pattern: $pattern)",$code);}}}class
  4001. RegexpException
  4002. extends\Exception{}class
  4003. Tokenizer
  4004. extends
  4005. Object{private$input;public$tokens;private$re;private$names;function
  4006. __construct(array$patterns,$flags=''){$this->re='~('.implode(')|(',$patterns).')~A'.$flags;$keys=array_keys($patterns);$this->names=$keys===range(0,count($patterns)-1)?FALSE:$keys;}function
  4007. tokenize($input){$this->input=$input;if($this->names){$this->tokens=String::matchAll($input,$this->re);$len=0;foreach($this->tokens
  4008. as&$match){$name=NULL;for($i=1;$i<count($this->names);$i++){if(!isset($match[$i])){break;}elseif($match[$i]!=NULL){$name=$this->names[$i-1];break;}}$match=array($match[0],$name);$len+=strlen($match[0]);}if($len!==strlen($input)){$errorOffset=$len;}}else{$this->tokens=String::split($input,$this->re,PREG_SPLIT_NO_EMPTY);if($this->tokens&&!String::match(end($this->tokens),$this->re)){$tmp=String::split($this->input,$this->re,PREG_SPLIT_NO_EMPTY|PREG_SPLIT_OFFSET_CAPTURE);list(,$errorOffset)=end($tmp);}}if(isset($errorOffset)){$line=$errorOffset?substr_count($this->input,"\n",0,$errorOffset)+1:1;$col=$errorOffset-strrpos(substr($this->input,0,$errorOffset),"\n")+1;$token=str_replace("\n",'\n',substr($input,$errorOffset,10));throw
  4009. new
  4010. TokenizerException("Unexpected '$token' on line $line, column $col.");}return$this->tokens;}function
  4011. getOffset($i){$tokens=String::split($this->input,$this->re,PREG_SPLIT_NO_EMPTY|PREG_SPLIT_OFFSET_CAPTURE);list(,$offset)=$tokens[$i];return
  4012. array($offset,($offset?substr_count($this->input,"\n",0,$offset)+1:1),$offset-strrpos(substr($this->input,0,$offset),"\n"));}}class
  4013. TokenizerException
  4014. extends\Exception{}final
  4015. class
  4016. Tools{const
  4017. MINUTE=60;const
  4018. HOUR=3600;const
  4019. DAY=86400;const
  4020. WEEK=604800;const
  4021. MONTH=2629800;const
  4022. YEAR=31557600;private
  4023. static$criticalSections;final
  4024. function
  4025. __construct(){throw
  4026. new\LogicException("Cannot instantiate static class ".get_class($this));}static
  4027. function
  4028. createDateTime($time){if($time
  4029. instanceof\DateTime){return
  4030. clone$time;}elseif(is_numeric($time)){if($time<=self::YEAR){$time+=time();}return
  4031. new\DateTime(date('Y-m-d H:i:s',$time));}else{return
  4032. new\DateTime($time);}}static
  4033. function
  4034. iniFlag($var){$status=strtolower(ini_get($var));return$status==='on'||$status==='true'||$status==='yes'||(int)$status;}static
  4035. function
  4036. defaultize(&$var,$default){if($var===NULL)$var=$default;}static
  4037. function
  4038. compare($l,$operator,$r){switch($operator){case'>':return$l>$r;case'>=':return$l>=$r;case'<':return$l<$r;case'<=':return$l<=$r;case'=':case'==':return$l==$r;case'!':case'!=':case'<>':return$l!=$r;}throw
  4039. new\InvalidArgumentException("Unknown operator $operator.");}static
  4040. function
  4041. detectMimeType($file){if(!is_file($file)){throw
  4042. new\XFileNotFoundException("File '$file' not found.");}$info=@getimagesize($file);if(isset($info['mime'])){return$info['mime'];}elseif(extension_loaded('fileinfo')){$type=preg_replace('#[\s;].*$#','',finfo_file(finfo_open(FILEINFO_MIME),$file));}elseif(function_exists('mime_content_type')){$type=mime_content_type($file);}return
  4043. isset($type)&&preg_match('#^\S+/\S+$#',$type)?$type:'application/octet-stream';}static
  4044. function
  4045. enterCriticalSection(){if(self::$criticalSections){throw
  4046. new\XInvalidStateException('Critical section has already been entered.');}$handle=fopen(NETTEX_DIR.'/lockfile','r')?:fopen(NETTEX_DIR.'/lockfile','w');if(!$handle){throw
  4047. new\XInvalidStateException("Unable initialize critical section (missing file '".NETTEX_DIR."/lockfile').");}flock(self::$criticalSections=$handle,LOCK_EX);}static
  4048. function
  4049. leaveCriticalSection(){if(!self::$criticalSections){throw
  4050. new\XInvalidStateException('Critical section has not been initialized.');}fclose(self::$criticalSections);self::$criticalSections=NULL;}}}namespace NetteX\Web{use
  4051. NetteX;class
  4052. Html
  4053. extends
  4054. NetteX\Object
  4055. implements\ArrayAccess,\Countable,\IteratorAggregate{private$name;private$isEmpty;public$attrs=array();protected$children=array();public
  4056. static$xhtml=TRUE;public
  4057. 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
  4058. function
  4059. el($name=NULL,$attrs=NULL){$el=new
  4060. static;$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])){foreach(NetteX\String::matchAll($parts[1].' ','#([a-z0-9:-]+)(?:=(["\'])?(.*?)(?(2)\\2|\s))?#i')as$m){$el->attrs[$m[1]]=isset($m[3])?$m[3]:TRUE;}}return$el;}final
  4061. function
  4062. setName($name,$isEmpty=NULL){if($name!==NULL&&!is_string($name)){throw
  4063. new\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
  4064. function
  4065. getName(){return$this->name;}final
  4066. function
  4067. isEmpty(){return$this->isEmpty;}final
  4068. function
  4069. __set($name,$value){$this->attrs[$name]=$value;}final
  4070. function&__get($name){return$this->attrs[$name];}final
  4071. function
  4072. __unset($name){unset($this->attrs[$name]);}final
  4073. function
  4074. __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
  4075. isset($this->attrs[$m])?$this->attrs[$m]:NULL;}elseif($p==='add'){$args[]=TRUE;}}if(count($args)===0){}elseif(count($args)===1){$this->attrs[$m]=$args[0];}elseif((string)$args[0]===''){$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
  4076. function
  4077. href($path,$query=NULL){if($query){$query=http_build_query($query,NULL,'&');if($query!=='')$path.='?'.$query;}$this->attrs['href']=$path;return$this;}final
  4078. function
  4079. setHtml($html){if($html===NULL){$html='';}elseif(is_array($html)){throw
  4080. new\InvalidArgumentException("Textual content must be a scalar, ".gettype($html)." given.");}else{$html=(string)$html;}$this->removeChildren();$this->children[]=$html;return$this;}final
  4081. function
  4082. getHtml(){$s='';foreach($this->children
  4083. as$child){if(is_object($child)){$s.=$child->render();}else{$s.=$child;}}return$s;}final
  4084. function
  4085. setText($text){if(!is_array($text)){$text=htmlspecialchars((string)$text,ENT_NOQUOTES);}return$this->setHtml($text);}final
  4086. function
  4087. getText(){return
  4088. html_entity_decode(strip_tags($this->getHtml()),ENT_QUOTES,'UTF-8');}final
  4089. function
  4090. add($child){return$this->insert(NULL,$child);}final
  4091. function
  4092. create($name,$attrs=NULL){$this->insert(NULL,$child=static::el($name,$attrs));return$child;}function
  4093. insert($index,$child,$replace=FALSE){if($child
  4094. instanceof
  4095. Html||is_scalar($child)){if($index===NULL){$this->children[]=$child;}else{array_splice($this->children,(int)$index,$replace?1:0,array($child));}}else{throw
  4096. new\InvalidArgumentException("Child node must be scalar or Html object, ".(is_object($child)?get_class($child):gettype($child))." given.");}return$this;}final
  4097. function
  4098. offsetSet($index,$child){$this->insert($index,$child,TRUE);}final
  4099. function
  4100. offsetGet($index){return$this->children[$index];}final
  4101. function
  4102. offsetExists($index){return
  4103. isset($this->children[$index]);}function
  4104. offsetUnset($index){if(isset($this->children[$index])){array_splice($this->children,(int)$index,1);}}final
  4105. function
  4106. count(){return
  4107. count($this->children);}function
  4108. removeChildren(){$this->children=array();}final
  4109. function
  4110. getIterator($deep=FALSE){if($deep){$deep=$deep>0?\RecursiveIteratorIterator::SELF_FIRST:\RecursiveIteratorIterator::CHILD_FIRST;return
  4111. new\RecursiveIteratorIterator(new
  4112. NetteX\GenericRecursiveIterator(new\ArrayIterator($this->children)),$deep);}else{return
  4113. new
  4114. NetteX\GenericRecursiveIterator(new\ArrayIterator($this->children));}}final
  4115. function
  4116. getChildren(){return$this->children;}final
  4117. function
  4118. render($indent=NULL){$s=$this->startTag();if(!$this->isEmpty){if($indent!==NULL){$indent++;}foreach($this->children
  4119. 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
  4120. function
  4121. __toString(){return$this->render();}final
  4122. function
  4123. startTag(){if($this->name){return'<'.$this->name.$this->attributes().(self::$xhtml&&$this->isEmpty?' />':'>');}else{return'';}}final
  4124. function
  4125. endTag(){return$this->name&&!$this->isEmpty?'</'.$this->name.'>':'';}final
  4126. function
  4127. attributes(){if(!is_array($this->attrs)){return'';}$s='';foreach($this->attrs
  4128. 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)){if($key==='data'){foreach($value
  4129. as$k=>$v){if($v!==NULL&&$v!==FALSE){$s.=' data-'.$k.'="'.htmlspecialchars((string)$v).'"';}}continue;}$tmp=NULL;foreach($value
  4130. as$k=>$v){if($v==NULL)continue;$tmp[]=$v===TRUE?$k:(is_string($k)?$k.':'.$v:$v);}if($tmp===NULL)continue;$value=implode($key==='style'||!strncmp($key,'on',2)?';':' ',$tmp);}else{$value=(string)$value;}$s.=' '.$key.'="'.htmlspecialchars($value).'"';}$s=str_replace('@','&#64;',$s);return$s;}function
  4131. __clone(){foreach($this->children
  4132. as$key=>$value){if(is_object($value)){$this->children[$key]=clone$value;}}}}class
  4133. HttpContext
  4134. extends
  4135. NetteX\Object{function
  4136. 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
  4137. 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
  4138. TRUE;}}if(empty($match)){return
  4139. TRUE;}$response->setCode(IHttpResponse::S304_NOT_MODIFIED);return
  4140. FALSE;}function
  4141. getRequest(){return
  4142. NetteX\Environment::getHttpRequest();}function
  4143. getResponse(){return
  4144. NetteX\Environment::getHttpResponse();}}use
  4145. NetteX\String;class
  4146. HttpRequest
  4147. extends
  4148. NetteX\Object
  4149. implements
  4150. 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
  4151. function
  4152. getUri(){if($this->uri===NULL){$this->detectUri();}return$this->uri;}function
  4153. setUri(UriScript$uri){$this->uri=clone$uri;$this->query=NULL;$this->uri->canonicalize();$this->uri->freeze();return$this;}final
  4154. function
  4155. getOriginalUri(){if($this->originalUri===NULL){$this->detectUri();}return$this->originalUri;}function
  4156. 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
  4157. function
  4158. getUriFilters(){return$this->uriFilter;}protected
  4159. function
  4160. detectUri(){$uri=$this->uri=new
  4161. 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=preg_match('#^[-.a-z0-9]+$#',$pair[0])?$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
  4162. Uri($uri);$this->originalUri->path=$tmp[0];$this->originalUri->query=isset($tmp[1])?$tmp[1]:'';$this->originalUri->freeze();$requestUri=String::replace($requestUri,$this->uriFilter[0]);$tmp=explode('?',$requestUri,2);$uri->path=String::replace($tmp[0],$this->uriFilter[PHP_URL_PATH]);$uri->query=isset($tmp[1])?$tmp[1]:'';$uri->canonicalize();$uri->path=String::fixEncoding($uri->path);$uri->scriptPath='/';if(isset($_SERVER['SCRIPT_NAME'])){$script=$_SERVER['SCRIPT_NAME'];if(strncmp($uri->path.'/',$script.'/',strlen($script)+1)===0){$uri->scriptPath=$script;}elseif(strncmp($uri->path,$script,strrpos($script,'/')+1)===0){$uri->scriptPath=substr($script,0,strrpos($script,'/')+1);}}$uri->freeze();}final
  4163. function
  4164. 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
  4165. function
  4166. 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
  4167. getPostRaw(){return
  4168. file_get_contents('php://input');}final
  4169. function
  4170. getFile($key){if($this->files===NULL){$this->initialize();}$args=func_get_args();return
  4171. NetteX\ArrayTools::get($this->files,$args);}final
  4172. function
  4173. getFiles(){if($this->files===NULL){$this->initialize();}return$this->files;}final
  4174. function
  4175. 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
  4176. function
  4177. getCookies(){if($this->cookies===NULL){$this->initialize();}return$this->cookies;}function
  4178. setEncoding($encoding){if(strcasecmp($encoding,$this->encoding)){$this->encoding=$encoding;$this->query=$this->post=$this->cookies=$this->files=NULL;}return$this;}function
  4179. 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
  4180. 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
  4181. 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
  4182. 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
  4183. getMethod(){return
  4184. isset($_SERVER['REQUEST_METHOD'])?$_SERVER['REQUEST_METHOD']:NULL;}function
  4185. isMethod($method){return
  4186. isset($_SERVER['REQUEST_METHOD'])?strcasecmp($_SERVER['REQUEST_METHOD'],$method)===0:FALSE;}function
  4187. isPost(){return$this->isMethod('POST');}final
  4188. function
  4189. getHeader($header,$default=NULL){$header=strtolower($header);$headers=$this->getHeaders();if(isset($headers[$header])){return$headers[$header];}else{return$default;}}function
  4190. 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
  4191. as$k=>$v){if(strncmp($k,'HTTP_',5)==0){$k=substr($k,5);}elseif(strncmp($k,'CONTENT_',8)){continue;}$this->headers[strtr(strtolower($k),'_','-')]=$v;}}}return$this->headers;}final
  4192. function
  4193. getReferer(){$uri=self::getHeader('referer');return$uri?new
  4194. Uri($uri):NULL;}function
  4195. isSecured(){return
  4196. isset($_SERVER['HTTPS'])&&strcasecmp($_SERVER['HTTPS'],'off');}function
  4197. isAjax(){return$this->getHeader('X-Requested-With')==='XMLHttpRequest';}function
  4198. getRemoteAddress(){return
  4199. isset($_SERVER['REMOTE_ADDR'])?$_SERVER['REMOTE_ADDR']:NULL;}function
  4200. getRemoteHost(){if(!isset($_SERVER['REMOTE_HOST'])){if(!isset($_SERVER['REMOTE_ADDR'])){return
  4201. NULL;}$_SERVER['REMOTE_HOST']=getHostByAddr($_SERVER['REMOTE_ADDR']);}return$_SERVER['REMOTE_HOST'];}function
  4202. detectLanguage(array$langs){$header=$this->getHeader('accept-language');if(!$header)return
  4203. 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
  4204. 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
  4205. class
  4206. HttpResponse
  4207. extends
  4208. NetteX\Object
  4209. implements
  4210. IHttpResponse{private
  4211. static$fixIE=TRUE;public$cookieDomain='';public$cookiePath='/';public$cookieSecure=FALSE;public$cookieHttpOnly=TRUE;private$code=self::S200_OK;function
  4212. 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
  4213. new\InvalidArgumentException("Bad HTTP response '$code'.");}elseif(headers_sent($file,$line)){throw
  4214. new\XInvalidStateException("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
  4215. getCode(){return$this->code;}function
  4216. setHeader($name,$value){if(headers_sent($file,$line)){throw
  4217. new\XInvalidStateException("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
  4218. addHeader($name,$value){if(headers_sent($file,$line)){throw
  4219. new\XInvalidStateException("Cannot send header after HTTP headers have been sent".($file?" (output started at $file:$line).":"."));}header($name.': '.$value,FALSE,$this->code);}function
  4220. setContentType($type,$charset=NULL){$this->setHeader('Content-Type',$type.($charset?'; charset='.$charset:''));return$this;}function
  4221. 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
  4222. 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=NetteX\Tools::createDateTime($time);$this->setHeader('Cache-Control','max-age='.($time->format('U')-time()));$this->setHeader('Expires',self::date($time));return$this;}function
  4223. isSent(){return
  4224. headers_sent();}function
  4225. getHeader($header,$default=NULL){$header.=':';$len=strlen($header);foreach(headers_list()as$item){if(strncasecmp($item,$header,$len)===0){return
  4226. ltrim(substr($item,$len));}}return$default;}function
  4227. getHeaders(){$headers=array();foreach(headers_list()as$header){$a=strpos($header,':');$headers[substr($header,0,$a)]=(string)substr($header,$a+2);}return$headers;}static
  4228. function
  4229. date($time=NULL){$time=NetteX\Tools::createDateTime($time);$time->setTimezone(new\DateTimeZone('GMT'));return$time->format('D, d M Y H:i:s \G\M\T');}function
  4230. __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
  4231. setCookie($name,$value,$time,$path=NULL,$domain=NULL,$secure=NULL,$httpOnly=NULL){if(headers_sent($file,$line)){throw
  4232. new\XInvalidStateException("Cannot set cookie after HTTP headers have been sent".($file?" (output started at $file:$line).":"."));}setcookie($name,$value,$time?NetteX\Tools::createDateTime($time)->format('U'):0,$path===NULL?$this->cookiePath:(string)$path,$domain===NULL?$this->cookieDomain:(string)$domain,$secure===NULL?$this->cookieSecure:(bool)$secure,$httpOnly===NULL?$this->cookieHttpOnly:(bool)$httpOnly);return$this;}function
  4233. deleteCookie($name,$path=NULL,$domain=NULL,$secure=NULL){if(headers_sent($file,$line)){throw
  4234. new\XInvalidStateException("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
  4235. HttpUploadedFile
  4236. extends
  4237. NetteX\Object{private$name;private$type;private$size;private$tmpName;private$error;function
  4238. __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
  4239. getName(){return$this->name;}function
  4240. getContentType(){if($this->isOk()&&$this->type===NULL){$this->type=NetteX\Tools::detectMimeType($this->tmpName);}return$this->type;}function
  4241. getSize(){return$this->size;}function
  4242. getTemporaryFile(){return$this->tmpName;}function
  4243. __toString(){return$this->tmpName;}function
  4244. getError(){return$this->error;}function
  4245. isOk(){return$this->error===UPLOAD_ERR_OK;}function
  4246. 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
  4247. new\XInvalidStateException("Unable to move uploaded file '$this->tmpName' to '$dest'.");}chmod($dest,0644);$this->tmpName=$dest;return$this;}function
  4248. isImage(){return
  4249. in_array($this->getContentType(),array('image/gif','image/png','image/jpeg'),TRUE);}function
  4250. toImage(){return
  4251. NetteX\Image::fromFile($this->tmpName);}function
  4252. getImageSize(){return$this->isOk()?@getimagesize($this->tmpName):NULL;}function
  4253. getContents(){return$this->isOk()?file_get_contents($this->tmpName):NULL;}}class
  4254. Session
  4255. extends
  4256. NetteX\Object{const
  4257. DEFAULT_FILE_LIFETIME=10800;private$regenerationNeeded;private
  4258. 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
  4259. start(){if(self::$started){return;}elseif(self::$started===NULL&&defined('SID')){throw
  4260. new\XInvalidStateException('A session had already been started by session.auto-start or session_start().');}$this->configure($this->options);NetteX\Debug::tryError();session_start();if(NetteX\Debug::catchError($e)){@session_write_close();throw
  4261. new\XInvalidStateException($e->getMessage());}self::$started=TRUE;if($this->regenerationNeeded){session_regenerate_id(TRUE);$this->regenerationNeeded=FALSE;}unset($_SESSION['__NT'],$_SESSION['__NS'],$_SESSION['__NM']);$nf=&$_SESSION['__NF'];if(empty($nf)){$nf=array('C'=>0);}else{$nf['C']++;}$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
  4262. 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)!==NetteX\Reflection\ClassReflection::from($nf['DATA'][$namespace][$variable])->getAnnotation('serializationVersion'))){if($variable===''){unset($nf['META'][$namespace],$nf['DATA'][$namespace]);continue
  4263. 2;}unset($nf['META'][$namespace][$variable],$nf['DATA'][$namespace][$variable]);}}}}}register_shutdown_function(array($this,'clean'));}function
  4264. isStarted(){return(bool)self::$started;}function
  4265. close(){if(self::$started){$this->clean();session_write_close();self::$started=FALSE;}}function
  4266. destroy(){if(!self::$started){throw
  4267. new\XInvalidStateException('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
  4268. exists(){return
  4269. self::$started||$this->getHttpRequest()->getCookie(session_name())!==NULL;}function
  4270. regenerateId(){if(self::$started){if(headers_sent($file,$line)){throw
  4271. new\XInvalidStateException("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
  4272. getId(){return
  4273. session_id();}function
  4274. setName($name){if(!is_string($name)||!preg_match('#[^0-9.][^.]*$#A',$name)){throw
  4275. new\InvalidArgumentException('Session name must be a string and cannot contain dot.');}session_name($name);return$this->setOptions(array('name'=>$name));}function
  4276. getName(){return
  4277. session_name();}function
  4278. getNamespace($namespace,$class='NetteX\Web\SessionNamespace'){if(!is_string($namespace)||$namespace===''){throw
  4279. new\InvalidArgumentException('Session namespace must be a non-empty string.');}if(!self::$started){$this->start();}return
  4280. new$class($_SESSION['__NF']['DATA'][$namespace],$_SESSION['__NF']['META'][$namespace]);}function
  4281. hasNamespace($namespace){if($this->exists()&&!self::$started){$this->start();}return!empty($_SESSION['__NF']['DATA'][$namespace]);}function
  4282. getIterator(){if($this->exists()&&!self::$started){$this->start();}if(isset($_SESSION['__NF']['DATA'])){return
  4283. new\ArrayIterator(array_keys($_SESSION['__NF']['DATA']));}else{return
  4284. new\ArrayIterator;}}function
  4285. 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
  4286. setOptions(array$options){if(self::$started){$this->configure($options);}$this->options=$options+$this->options;return$this;}function
  4287. getOptions(){return$this->options;}private
  4288. function
  4289. configure(array$config){$special=array('cache_expire'=>1,'cache_limiter'=>1,'save_path'=>1,'name'=>1);foreach($config
  4290. as$key=>$value){if(!strncmp($key,'session.',8)){$key=substr($key,8);}if($value===NULL){continue;}elseif(isset($special[$key])){if(self::$started){throw
  4291. new\XInvalidStateException("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&&!NetteX\Framework::$iAmUsingBadHost){throw
  4292. new\XNotSupportedException('Required function ini_set() is disabled.');}}else{if(self::$started){throw
  4293. new\XInvalidStateException("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
  4294. setExpiration($time){if(empty($time)){return$this->setOptions(array('gc_maxlifetime'=>self::DEFAULT_FILE_LIFETIME,'cookie_lifetime'=>0));}else{$time=NetteX\Tools::createDateTime($time)->format('U');return$this->setOptions(array('gc_maxlifetime'=>$time,'cookie_lifetime'=>$time));}}function
  4295. setCookieParams($path,$domain=NULL,$secure=NULL){return$this->setOptions(array('cookie_path'=>$path,'cookie_domain'=>$domain,'cookie_secure'=>$secure));}function
  4296. getCookieParams(){return
  4297. session_get_cookie_params();}function
  4298. setSavePath($path){return$this->setOptions(array('save_path'=>$path));}private
  4299. function
  4300. 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
  4301. function
  4302. getHttpRequest(){return
  4303. NetteX\Environment::getHttpRequest();}protected
  4304. function
  4305. getHttpResponse(){return
  4306. NetteX\Environment::getHttpResponse();}}final
  4307. class
  4308. SessionNamespace
  4309. extends
  4310. NetteX\Object
  4311. implements\IteratorAggregate,\ArrayAccess{private$data;private$meta;public$warnOnUndefined=FALSE;function
  4312. __construct(&$data,&$meta){$this->data=&$data;$this->meta=&$meta;}function
  4313. getIterator(){if(isset($this->data)){return
  4314. new\ArrayIterator($this->data);}else{return
  4315. new\ArrayIterator;}}function
  4316. __set($name,$value){$this->data[$name]=$value;if(is_object($value)){$this->meta[$name]['V']=NetteX\Reflection\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
  4317. __isset($name){return
  4318. isset($this->data[$name]);}function
  4319. __unset($name){unset($this->data[$name],$this->meta[$name]);}function
  4320. offsetSet($name,$value){$this->__set($name,$value);}function
  4321. offsetGet($name){return$this->__get($name);}function
  4322. offsetExists($name){return$this->__isset($name);}function
  4323. offsetUnset($name){$this->__unset($name);}function
  4324. setExpiration($time,$variables=NULL){if(empty($time)){$time=NULL;$whenBrowserIsClosed=TRUE;}else{$time=NetteX\Tools::createDateTime($time)->format('U');$whenBrowserIsClosed=FALSE;}if($variables===NULL){$this->meta['']['T']=$time;$this->meta['']['B']=$whenBrowserIsClosed;}elseif(is_array($variables)){foreach($variables
  4325. 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
  4326. removeExpiration($variables=NULL){if($variables===NULL){unset($this->meta['']['T'],$this->meta['']['B']);}elseif(is_array($variables)){foreach($variables
  4327. as$variable){unset($this->meta[$variable]['T'],$this->meta[$variable]['B']);}}else{unset($this->meta[$variables]['T'],$this->meta[$variable]['B']);}}function
  4328. remove(){$this->data=NULL;$this->meta=NULL;}}class
  4329. Uri
  4330. extends
  4331. NetteX\FreezableObject{public
  4332. 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
  4333. __construct($uri=NULL){if(is_string($uri)){$parts=@parse_url($uri);if($parts===FALSE){throw
  4334. new\InvalidArgumentException("Malformed or unsupported URI '$uri'.");}foreach($parts
  4335. as$key=>$val){$this->$key=$val;}if(!$this->port&&isset(self::$defaultPorts[$this->scheme])){$this->port=self::$defaultPorts[$this->scheme];}if($this->path===''&&($this->scheme==='http'||$this->scheme==='https')){$this->path='/';}}elseif($uri
  4336. instanceof
  4337. self){foreach($this
  4338. as$key=>$val){$this->$key=$uri->$key;}}}function
  4339. setScheme($value){$this->updating();$this->scheme=(string)$value;return$this;}function
  4340. getScheme(){return$this->scheme;}function
  4341. setUser($value){$this->updating();$this->user=(string)$value;return$this;}function
  4342. getUser(){return$this->user;}function
  4343. setPassword($value){$this->updating();$this->pass=(string)$value;return$this;}function
  4344. getPassword(){return$this->pass;}function
  4345. setHost($value){$this->updating();$this->host=(string)$value;return$this;}function
  4346. getHost(){return$this->host;}function
  4347. setPort($value){$this->updating();$this->port=(int)$value;return$this;}function
  4348. getPort(){return$this->port;}function
  4349. setPath($value){$this->updating();$this->path=(string)$value;return$this;}function
  4350. getPath(){return$this->path;}function
  4351. setQuery($value){$this->updating();$this->query=(string)(is_array($value)?http_build_query($value,'','&'):$value);return$this;}function
  4352. appendQuery($value){$this->updating();$value=(string)(is_array($value)?http_build_query($value,'','&'):$value);$this->query.=($this->query===''||$value==='')?$value:'&'.$value;}function
  4353. getQuery(){return$this->query;}function
  4354. setFragment($value){$this->updating();$this->fragment=(string)$value;return$this;}function
  4355. getFragment(){return$this->fragment;}function
  4356. getAbsoluteUri(){return$this->scheme.'://'.$this->getAuthority().$this->path.($this->query===''?'':'?'.$this->query).($this->fragment===''?'':'#'.$this->fragment);}function
  4357. 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
  4358. getHostUri(){return$this->scheme.'://'.$this->getAuthority();}function
  4359. getBasePath(){$pos=strrpos($this->path,'/');return$pos===FALSE?'':substr($this->path,0,$pos+1);}function
  4360. getBaseUri(){return$this->scheme.'://'.$this->getAuthority().$this->getBasePath();}function
  4361. getRelativeUri(){return(string)substr($this->getAbsoluteUri(),strlen($this->getBaseUri()));}function
  4362. isEqual($uri){$part=self::unescape(strtok($uri,'?#'),'%/');if(strncmp($part,'//',2)===0){if($part!=='//'.$this->getAuthority().$this->path)return
  4363. FALSE;}elseif(strncmp($part,'/',1)===0){if($part!==$this->path)return
  4364. FALSE;}else{if($part!==$this->scheme.'://'.$this->getAuthority().$this->path)return
  4365. FALSE;}$part=preg_split('#[&;]#',self::unescape(strtr((string)strtok('?#'),'+',' '),'%&;=+'));sort($part);$query=preg_split('#[&;]#',$this->query);sort($query);return$part===$query;}function
  4366. 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
  4367. __toString(){return$this->getAbsoluteUri();}static
  4368. function
  4369. 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
  4370. UriScript
  4371. extends
  4372. Uri{private$scriptPath='/';function
  4373. setScriptPath($value){$this->updating();$this->scriptPath=(string)$value;return$this;}function
  4374. getScriptPath(){return$this->scriptPath;}function
  4375. getBasePath(){$pos=strrpos($this->scriptPath,'/');return$pos===FALSE?'':substr($this->path,0,$pos+1);}function
  4376. getPathInfo(){return(string)substr($this->path,strlen($this->scriptPath));}}use
  4377. NetteX\Environment;use
  4378. NetteX\Security\IAuthenticator;use
  4379. NetteX\Security\IAuthorizator;use
  4380. NetteX\Security\IIdentity;class
  4381. User
  4382. extends
  4383. NetteX\Object
  4384. implements
  4385. IUser{const
  4386. MANUAL=1;const
  4387. INACTIVITY=2;const
  4388. BROWSER_CLOSED=3;public$guestRole='guest';public$authenticatedRole='authenticated';public$onLoggedIn;public$onLoggedOut;private$authenticationHandler;private$authorizationHandler;private$namespace='';private$session;function
  4389. login($username=NULL,$password=NULL){$handler=$this->getAuthenticationHandler();if($handler===NULL){throw
  4390. new\XInvalidStateException('Authentication handler has not been set.');}$this->logout(TRUE);$credentials=func_get_args();$this->setIdentity($handler->authenticate($credentials));$this->setAuthenticated(TRUE);$this->onLoggedIn($this);}final
  4391. function
  4392. logout($clearIdentity=FALSE){if($this->isLoggedIn()){$this->setAuthenticated(FALSE);$this->onLoggedOut($this);}if($clearIdentity){$this->setIdentity(NULL);}}final
  4393. function
  4394. isLoggedIn(){$session=$this->getSessionNamespace(FALSE);return$session&&$session->authenticated;}final
  4395. function
  4396. getIdentity(){$session=$this->getSessionNamespace(FALSE);return$session?$session->identity:NULL;}function
  4397. getId(){$identity=$this->getIdentity();return$identity?$identity->getId():NULL;}function
  4398. setAuthenticationHandler(IAuthenticator$handler){$this->authenticationHandler=$handler;return$this;}final
  4399. function
  4400. getAuthenticationHandler(){if($this->authenticationHandler===NULL){$this->authenticationHandler=Environment::getService('NetteX\\Security\\IAuthenticator');}return$this->authenticationHandler;}function
  4401. setNamespace($namespace){if($this->namespace!==$namespace){$this->namespace=(string)$namespace;$this->session=NULL;}return$this;}final
  4402. function
  4403. getNamespace(){return$this->namespace;}function
  4404. setExpiration($time,$whenBrowserIsClosed=TRUE,$clearIdentity=FALSE){$session=$this->getSessionNamespace(TRUE);if($time){$time=NetteX\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
  4405. function
  4406. getLogoutReason(){$session=$this->getSessionNamespace(FALSE);return$session?$session->reason:NULL;}protected
  4407. function
  4408. getSessionNamespace($need){if($this->session!==NULL){return$this->session;}$sessionHandler=$this->getSession();if(!$need&&!$sessionHandler->exists()){return
  4409. NULL;}$this->session=$session=$sessionHandler->getNamespace('NetteX.Web.User/'.$this->namespace);if(!($session->identity
  4410. instanceof
  4411. IIdentity)||!is_bool($session->authenticated)){$session->remove();}if($session->authenticated&&$session->expireBrowser&&!$session->browserCheck){$session->reason=self::BROWSER_CLOSED;$session->authenticated=FALSE;$this->onLoggedOut($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->onLoggedOut($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
  4412. function
  4413. 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
  4414. function
  4415. setIdentity(IIdentity$identity=NULL){$this->getSessionNamespace(TRUE)->identity=$identity;return$this;}function
  4416. getRoles(){if(!$this->isLoggedIn()){return
  4417. array($this->guestRole);}$identity=$this->getIdentity();return$identity?$identity->getRoles():array($this->authenticatedRole);}final
  4418. function
  4419. isInRole($role){return
  4420. in_array($role,$this->getRoles(),TRUE);}function
  4421. isAllowed($resource=IAuthorizator::ALL,$privilege=IAuthorizator::ALL){$handler=$this->getAuthorizationHandler();if(!$handler){throw
  4422. new\XInvalidStateException("Authorization handler has not been set.");}foreach($this->getRoles()as$role){if($handler->isAllowed($role,$resource,$privilege))return
  4423. TRUE;}return
  4424. FALSE;}function
  4425. setAuthorizationHandler(IAuthorizator$handler){$this->authorizationHandler=$handler;return$this;}final
  4426. function
  4427. getAuthorizationHandler(){if($this->authorizationHandler===NULL){$this->authorizationHandler=Environment::getService('NetteX\\Security\\IAuthorizator');}return$this->authorizationHandler;}protected
  4428. function
  4429. getSession(){return
  4430. Environment::getSession();}}}