PageRenderTime 88ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 3ms

/nette_example/libs/Nette/loader.php

https://github.com/peci1/nSMTPMailer
PHP | 5560 lines | 5418 code | 134 blank | 8 comment | 63 complexity | 790771a310173a044a9f3ba9702edabb MD5 | raw file
  1. <?php //netteloader=Nette\Framework
  2. namespace {/**
  3. * Nette Framework (version 2.0.10 released on 2013-03-08, http://nette.org)
  4. *
  5. * Copyright (c) 2004, 2013 David Grudl (http://davidgrudl.com)
  6. *
  7. * For the full copyright and license information, please view
  8. * the file license.txt that was distributed with this source code.
  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');umask(0);@header('X-Powered-By: Nette Framework');@header('Content-Type: text/html; charset=utf-8');define('NETTE',TRUE);define('NETTE_DIR',__DIR__);define('NETTE_VERSION_ID',20010);define('NETTE_PACKAGE','5.3');}namespace Nette\Diagnostics{use
  11. Nette;interface
  12. IBarPanel{function
  13. getTab();function
  14. getPanel();}}namespace Nette\Application{use
  15. Nette;interface
  16. IPresenter{function
  17. run(Request$request);}interface
  18. IPresenterFactory{function
  19. getPresenterClass(&$name);function
  20. createPresenter($name);}interface
  21. IResponse{function
  22. send(Nette\Http\IRequest$httpRequest,Nette\Http\IResponse$httpResponse);}interface
  23. IRouter{const
  24. ONE_WAY=1;const
  25. SECURED=2;function
  26. match(Nette\Http\IRequest$httpRequest);function
  27. constructUrl(Request$appRequest,Nette\Http\Url$refUrl);}}namespace Nette{use
  28. Nette;interface
  29. IFreezable{function
  30. freeze();function
  31. isFrozen();}}namespace Nette\ComponentModel{use
  32. Nette;interface
  33. IComponent{const
  34. NAME_SEPARATOR='-';function
  35. getName();function
  36. getParent();function
  37. setParent(IContainer$parent=NULL,$name=NULL);}interface
  38. IContainer
  39. extends
  40. IComponent{function
  41. addComponent(IComponent$component,$name);function
  42. removeComponent(IComponent$component);function
  43. getComponent($name);function
  44. getComponents($deep=FALSE,$filterType=NULL);}}namespace Nette\Application\UI{use
  45. Nette;interface
  46. ISignalReceiver{function
  47. signalReceived($signal);}interface
  48. IStatePersistent{function
  49. loadState(array$params);function
  50. saveState(array&$params);}interface
  51. IRenderable{function
  52. invalidateControl();function
  53. isControlInvalid();}}namespace Nette\Caching{use
  54. Nette;interface
  55. IStorage{function
  56. read($key);function
  57. lock($key);function
  58. write($key,$data,array$dependencies);function
  59. remove($key);function
  60. clean(array$conditions);}}namespace Nette\Caching\Storages{use
  61. Nette;interface
  62. IJournal{function
  63. write($key,array$dependencies);function
  64. clean(array$conditions);}}namespace Nette\Config{use
  65. Nette;interface
  66. IAdapter{function
  67. load($file);function
  68. dump(array$data);}}namespace Nette\Database{use
  69. Nette;interface
  70. ISupplementalDriver{const
  71. SUPPORT_COLUMNS_META='meta',SUPPORT_SEQUENCE='sequence',SUPPORT_SELECT_UNGROUPED_COLUMNS='ungrouped_cols';function
  72. delimite($name);function
  73. formatDateTime(\DateTime$value);function
  74. formatLike($value,$pos);function
  75. applyLimit(&$sql,$limit,$offset);function
  76. normalizeRow($row,$statement);function
  77. getTables();function
  78. getColumns($table);function
  79. getIndexes($table);function
  80. getForeignKeys($table);function
  81. isSupported($item);}interface
  82. IReflection{const
  83. FIELD_TEXT='string',FIELD_BINARY='bin',FIELD_BOOL='bool',FIELD_INTEGER='int',FIELD_FLOAT='float',FIELD_DATE='date',FIELD_TIME='time',FIELD_DATETIME='datetime';function
  84. getPrimary($table);function
  85. getHasManyReference($table,$key);function
  86. getBelongsToReference($table,$key);function
  87. setConnection(Connection$connection);}}namespace Nette\DI{use
  88. Nette;interface
  89. IContainer{function
  90. addService($name,$service);function
  91. getService($name);function
  92. removeService($name);function
  93. hasService($name);}}namespace Nette\Forms{use
  94. Nette;interface
  95. IControl{function
  96. loadHttpData();function
  97. setValue($value);function
  98. getValue();function
  99. getRules();function
  100. getErrors();function
  101. isDisabled();function
  102. translate($s,$count=NULL);}interface
  103. ISubmitterControl
  104. extends
  105. IControl{function
  106. isSubmittedBy();function
  107. getValidationScope();}interface
  108. IFormRenderer{function
  109. render(Form$form);}}namespace Nette\Http{use
  110. Nette;interface
  111. IRequest{const
  112. GET='GET',POST='POST',HEAD='HEAD',PUT='PUT',DELETE='DELETE';function
  113. getUrl();function
  114. getQuery($key=NULL,$default=NULL);function
  115. getPost($key=NULL,$default=NULL);function
  116. getFile($key);function
  117. getFiles();function
  118. getCookie($key,$default=NULL);function
  119. getCookies();function
  120. getMethod();function
  121. isMethod($method);function
  122. getHeader($header,$default=NULL);function
  123. getHeaders();function
  124. isSecured();function
  125. isAjax();function
  126. getRemoteAddress();function
  127. getRemoteHost();}interface
  128. IResponse{const
  129. PERMANENT=2116333333;const
  130. BROWSER=0;const
  131. 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
  132. setCode($code);function
  133. getCode();function
  134. setHeader($name,$value);function
  135. addHeader($name,$value);function
  136. setContentType($type,$charset=NULL);function
  137. redirect($url,$code=self::S302_FOUND);function
  138. setExpiration($seconds);function
  139. isSent();function
  140. getHeaders();function
  141. setCookie($name,$value,$expire,$path=NULL,$domain=NULL,$secure=NULL,$httpOnly=NULL);function
  142. deleteCookie($name,$path=NULL,$domain=NULL,$secure=NULL);}interface
  143. ISessionStorage{function
  144. open($savePath,$sessionName);function
  145. close();function
  146. read($id);function
  147. write($id,$data);function
  148. remove($id);function
  149. clean($maxlifetime);}}namespace Nette\Security{use
  150. Nette;interface
  151. IUserStorage{const
  152. MANUAL=1,INACTIVITY=2,BROWSER_CLOSED=4;const
  153. CLEAR_IDENTITY=8;function
  154. setAuthenticated($state);function
  155. isAuthenticated();function
  156. setIdentity(IIdentity$identity=NULL);function
  157. getIdentity();function
  158. setExpiration($time,$flags=0);function
  159. getLogoutReason();}}namespace Nette\Latte{use
  160. Nette;interface
  161. IMacro{function
  162. initialize();function
  163. finalize();function
  164. nodeOpened(MacroNode$node);function
  165. nodeClosed(MacroNode$node);}}namespace Nette\Localization{use
  166. Nette;interface
  167. ITranslator{function
  168. translate($message,$count=NULL);}}namespace Nette\Mail{use
  169. Nette;interface
  170. IMailer{function
  171. send(Message$mail);}}namespace Nette\Reflection{use
  172. Nette;interface
  173. IAnnotation{function
  174. __construct(array$values);}}namespace Nette\Security{use
  175. Nette;interface
  176. IAuthenticator{const
  177. USERNAME=0,PASSWORD=1;const
  178. IDENTITY_NOT_FOUND=1,INVALID_CREDENTIAL=2,FAILURE=3,NOT_APPROVED=4;function
  179. authenticate(array$credentials);}interface
  180. IAuthorizator{const
  181. ALL=NULL;const
  182. ALLOW=TRUE;const
  183. DENY=FALSE;function
  184. isAllowed($role,$resource,$privilege);}interface
  185. IIdentity{function
  186. getId();function
  187. getRoles();}interface
  188. IResource{function
  189. getResourceId();}interface
  190. IRole{function
  191. getRoleId();}}namespace Nette\Templating{use
  192. Nette;interface
  193. ITemplate{function
  194. render();}interface
  195. IFileTemplate
  196. extends
  197. ITemplate{function
  198. setFile($file);function
  199. getFile();}}namespace Nette{use
  200. Nette;class
  201. ArgumentOutOfRangeException
  202. extends\InvalidArgumentException{}class
  203. InvalidStateException
  204. extends\RuntimeException{}class
  205. NotImplementedException
  206. extends\LogicException{}class
  207. NotSupportedException
  208. extends\LogicException{}class
  209. DeprecatedException
  210. extends
  211. NotSupportedException{}class
  212. MemberAccessException
  213. extends\LogicException{}class
  214. IOException
  215. extends\RuntimeException{}class
  216. FileNotFoundException
  217. extends
  218. IOException{}class
  219. DirectoryNotFoundException
  220. extends
  221. IOException{}class
  222. InvalidArgumentException
  223. extends\InvalidArgumentException{}class
  224. OutOfRangeException
  225. extends\OutOfRangeException{}class
  226. UnexpectedValueException
  227. extends\UnexpectedValueException{}class
  228. StaticClassException
  229. extends\LogicException{}class
  230. FatalErrorException
  231. extends\ErrorException{function
  232. __construct($message,$code,$severity,$file,$line,$context,\Exception$previous=NULL){parent::__construct($message,$code,$severity,$file,$line,$previous);$this->context=$context;}}abstract
  233. class
  234. Object{static
  235. function
  236. getReflection(){return
  237. new
  238. Reflection\ClassType(get_called_class());}function
  239. __call($name,$args){return
  240. ObjectMixin::call($this,$name,$args);}static
  241. function
  242. __callStatic($name,$args){return
  243. ObjectMixin::callStatic(get_called_class(),$name,$args);}static
  244. function
  245. extensionMethod($name,$callback=NULL){if(strpos($name,'::')===FALSE){$class=get_called_class();}else{list($class,$name)=explode('::',$name);}$class=new
  246. Reflection\ClassType($class);if($callback===NULL){return$class->getExtensionMethod($name);}else{$class->setExtensionMethod($name,$callback);}}function&__get($name){return
  247. ObjectMixin::get($this,$name);}function
  248. __set($name,$value){return
  249. ObjectMixin::set($this,$name,$value);}function
  250. __isset($name){return
  251. ObjectMixin::has($this,$name);}function
  252. __unset($name){ObjectMixin::remove($this,$name);}}}namespace Nette\Utils{use
  253. Nette;final
  254. class
  255. LimitedScope{private
  256. static$vars;final
  257. function
  258. __construct(){throw
  259. new
  260. Nette\StaticClassException;}static
  261. function
  262. evaluate(){if(func_num_args()>1){self::$vars=func_get_arg(1);extract(self::$vars);}$res=eval('?>'.func_get_arg(0));if($res===FALSE&&($error=error_get_last())&&$error['type']===E_PARSE){throw
  263. new
  264. Nette\FatalErrorException($error['message'],0,$error['type'],$error['file'],$error['line'],NULL);}return$res;}static
  265. function
  266. load(){if(func_num_args()>1){self::$vars=func_get_arg(1);if(self::$vars===TRUE){return include_once func_get_arg(0);}extract(self::$vars);}return include func_get_arg(0);}}}namespace Nette\Loaders{use
  267. Nette;abstract
  268. class
  269. AutoLoader
  270. extends
  271. Nette\Object{static
  272. private$loaders=array();public
  273. static$count=0;final
  274. static
  275. function
  276. load($type){foreach(func_get_args()as$type){if(!class_exists($type)){throw
  277. new
  278. Nette\InvalidStateException("Unable to load class or interface '$type'.");}}}final
  279. static
  280. function
  281. getLoaders(){return
  282. array_values(self::$loaders);}function
  283. register(){if(!function_exists('spl_autoload_register')){throw
  284. new
  285. Nette\NotSupportedException('spl_autoload does not exist in this PHP installation.');}spl_autoload_register(array($this,'tryLoad'));self::$loaders[spl_object_hash($this)]=$this;}function
  286. unregister(){unset(self::$loaders[spl_object_hash($this)]);return
  287. spl_autoload_unregister(array($this,'tryLoad'));}abstract
  288. function
  289. tryLoad($type);}}namespace Nette\Diagnostics{use
  290. Nette;final
  291. class
  292. Helpers{static
  293. function
  294. editorLink($file,$line){if(Debugger::$editor&&is_file($file)){$dir=dirname(strtr($file,'/',DIRECTORY_SEPARATOR));$base=isset($_SERVER['SCRIPT_FILENAME'])?dirname(dirname(strtr($_SERVER['SCRIPT_FILENAME'],'/',DIRECTORY_SEPARATOR))):dirname($dir);if(substr($dir,0,strlen($base))===$base){$dir='...'.substr($dir,strlen($base));}return
  295. Nette\Utils\Html::el('a')->href(strtr(Debugger::$editor,array('%file'=>rawurlencode($file),'%line'=>$line)))->title("$file:$line")->setHtml(htmlSpecialChars(rtrim($dir,DIRECTORY_SEPARATOR)).DIRECTORY_SEPARATOR.'<b>'.htmlSpecialChars(basename($file)).'</b>');}else{return
  296. Nette\Utils\Html::el('span')->setText($file);}}static
  297. function
  298. htmlDump(&$var,$level=0){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'<span class="php-bool">'.($var?'TRUE':'FALSE')."</span>\n";}elseif($var===NULL){return"<span class=\"php-null\">NULL</span>\n";}elseif(is_int($var)){return"<span class=\"php-int\">$var</span>\n";}elseif(is_float($var)){$var=var_export($var,TRUE);if(strpos($var,'.')===FALSE){$var.='.0';}return"<span class=\"php-float\">$var</span>\n";}elseif(is_string($var)){if(Debugger::$maxLen&&strlen($var)>Debugger::$maxLen){$s=htmlSpecialChars(substr($var,0,Debugger::$maxLen),ENT_NOQUOTES,'ISO-8859-1').' ... ';}else{$s=htmlSpecialChars($var,ENT_NOQUOTES,'ISO-8859-1');}$s=strtr($s,preg_match($reBinary,$s)||preg_last_error()?$tableBin:$tableUtf);$len=strlen($var);return"<span class=\"php-string\">\"$s\"</span>".($len>1?" ($len)":"")."\n";}elseif(is_array($var)){$s='<span class="php-array">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<Debugger::$maxDepth||!Debugger::$maxDepth){$s.="<code>$brackets[0]\n";$var[$marker]=$brackets;foreach($var
  299. as$k=>&$v){if($k===$marker){continue;}$k=strtr($k,preg_match($reBinary,$k)||preg_last_error()?$tableBin:$tableUtf);$k=htmlSpecialChars(preg_match('#^\w+$#',$k)?$k:"\"$k\"");$s.="$space$space1<span class=\"php-key\">$k</span> => ".self::htmlDump($v,$level+1);}unset($var[$marker]);$s.="$space$brackets[1]</code>";}else{$s.="$brackets[0] ... $brackets[1]";}return$s."\n";}elseif(is_object($var)){if($var
  300. instanceof\Closure){$rc=new\ReflectionFunction($var);$arr=array();foreach($rc->getParameters()as$param){$arr[]='$'.$param->getName();}$arr=array('file'=>$rc->getFileName(),'line'=>$rc->getStartLine(),'parameters'=>implode(', ',$arr));}else{$arr=(array)$var;}$s='<span class="php-object">'.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<Debugger::$maxDepth||!Debugger::$maxDepth||$var
  301. instanceof\Closure){$s.="<code>{\n";$list[]=$var;foreach($arr
  302. as$k=>&$v){$m='';if($k[0]==="\x00"){$m=' <span class="php-visibility">'.($k[1]==='*'?'protected':'private').'</span>';$k=substr($k,strrpos($k,"\x00")+1);}$k=strtr($k,preg_match($reBinary,$k)||preg_last_error()?$tableBin:$tableUtf);$k=htmlSpecialChars(preg_match('#^\w+$#',$k)?$k:"\"$k\"");$s.="$space$space1<span class=\"php-key\">$k</span>$m => ".self::htmlDump($v,$level+1);}array_pop($list);$s.="$space}</code>";}else{$s.="{ ... }";}return$s."\n";}elseif(is_resource($var)){$type=get_resource_type($var);$s='<span class="php-resource">'.htmlSpecialChars($type)." resource</span> ";static$info=array('stream'=>'stream_get_meta_data','curl'=>'curl_getinfo');if(isset($info[$type])){$space=str_repeat($space1=' ',$level);$s.="<code>{\n";foreach(call_user_func($info[$type],$var)as$k=>$v){$s.=$space.$space1.'<span class="php-key">'.htmlSpecialChars($k)."</span> => ".self::htmlDump($v,$level+1);}$s.="$space}</code>";}return$s."\n";}else{return"<span>unknown type</span>\n";}}static
  303. function
  304. clickableDump($dump,$collapsed=FALSE){return'<pre class="nette-dump">'.preg_replace_callback('#^( *)((?>[^(\r\n]{1,200}))\((\d+)\) <code>#m',function($m)use($collapsed){return"$m[1]<a href='#' rel='next'>$m[2]($m[3]) ".(($m[1]||!$collapsed)&&($m[3]<7)?'<abbr>&#x25bc;</abbr> </a><code>':'<abbr>&#x25ba;</abbr> </a><code class="nette-collapsed">');},self::htmlDump($dump)).'</pre>';}static
  305. function
  306. findTrace(array$trace,$method,&$index=NULL){$m=explode('::',$method);foreach($trace
  307. as$i=>$item){if(isset($item['function'])&&$item['function']===end($m)&&isset($item['class'])===isset($m[1])&&(!isset($item['class'])||$item['class']===$m[0]||$m[0]==='*'||is_subclass_of($item['class'],$m[0]))){$index=$i;return$item;}}}}}namespace Nette\Utils{use
  308. Nette;class
  309. Html
  310. extends
  311. Nette\Object
  312. implements\ArrayAccess,\Countable,\IteratorAggregate{private$name;private$isEmpty;public$attrs=array();protected$children=array();public
  313. static$xhtml=TRUE;public
  314. static$emptyElements=array('img'=>1,'hr'=>1,'br'=>1,'input'=>1,'meta'=>1,'area'=>1,'embed'=>1,'keygen'=>1,'source'=>1,'base'=>1,'col'=>1,'link'=>1,'param'=>1,'basefont'=>1,'frame'=>1,'isindex'=>1,'wbr'=>1,'command'=>1);static
  315. function
  316. el($name=NULL,$attrs=NULL){$el=new
  317. 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(Strings::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
  318. function
  319. setName($name,$isEmpty=NULL){if($name!==NULL&&!is_string($name)){throw
  320. new
  321. Nette\InvalidArgumentException("Name must be string or NULL, ".gettype($name)." given.");}$this->name=$name;$this->isEmpty=$isEmpty===NULL?isset(static::$emptyElements[$name]):(bool)$isEmpty;return$this;}final
  322. function
  323. getName(){return$this->name;}final
  324. function
  325. isEmpty(){return$this->isEmpty;}function
  326. addAttributes(array$attrs){$this->attrs=$attrs+$this->attrs;return$this;}final
  327. function
  328. __set($name,$value){$this->attrs[$name]=$value;}final
  329. function&__get($name){return$this->attrs[$name];}final
  330. function
  331. __isset($name){return
  332. isset($this->attrs[$name]);}final
  333. function
  334. __unset($name){unset($this->attrs[$name]);}final
  335. function
  336. __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
  337. 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
  338. function
  339. href($path,$query=NULL){if($query){$query=http_build_query($query,NULL,'&');if($query!==''){$path.='?'.$query;}}$this->attrs['href']=$path;return$this;}final
  340. function
  341. setHtml($html){if($html===NULL){$html='';}elseif(is_array($html)){throw
  342. new
  343. Nette\InvalidArgumentException("Textual content must be a scalar, ".gettype($html)." given.");}else{$html=(string)$html;}$this->removeChildren();$this->children[]=$html;return$this;}final
  344. function
  345. getHtml(){$s='';foreach($this->children
  346. as$child){if(is_object($child)){$s.=$child->render();}else{$s.=$child;}}return$s;}final
  347. function
  348. setText($text){if(!is_array($text)){$text=htmlspecialchars((string)$text,ENT_NOQUOTES);}return$this->setHtml($text);}final
  349. function
  350. getText(){return
  351. html_entity_decode(strip_tags($this->getHtml()),ENT_QUOTES,'UTF-8');}final
  352. function
  353. add($child){return$this->insert(NULL,$child);}final
  354. function
  355. create($name,$attrs=NULL){$this->insert(NULL,$child=static::el($name,$attrs));return$child;}function
  356. insert($index,$child,$replace=FALSE){if($child
  357. instanceof
  358. Html||is_scalar($child)){if($index===NULL){$this->children[]=$child;}else{array_splice($this->children,(int)$index,$replace?1:0,array($child));}}else{throw
  359. new
  360. Nette\InvalidArgumentException("Child node must be scalar or Html object, ".(is_object($child)?get_class($child):gettype($child))." given.");}return$this;}final
  361. function
  362. offsetSet($index,$child){$this->insert($index,$child,TRUE);}final
  363. function
  364. offsetGet($index){return$this->children[$index];}final
  365. function
  366. offsetExists($index){return
  367. isset($this->children[$index]);}function
  368. offsetUnset($index){if(isset($this->children[$index])){array_splice($this->children,(int)$index,1);}}final
  369. function
  370. count(){return
  371. count($this->children);}function
  372. removeChildren(){$this->children=array();}final
  373. function
  374. getIterator($deep=FALSE){if($deep){$deep=$deep>0?\RecursiveIteratorIterator::SELF_FIRST:\RecursiveIteratorIterator::CHILD_FIRST;return
  375. new\RecursiveIteratorIterator(new
  376. Nette\Iterators\Recursor(new\ArrayIterator($this->children)),$deep);}else{return
  377. new
  378. Nette\Iterators\Recursor(new\ArrayIterator($this->children));}}final
  379. function
  380. getChildren(){return$this->children;}final
  381. function
  382. render($indent=NULL){$s=$this->startTag();if(!$this->isEmpty){if($indent!==NULL){$indent++;}foreach($this->children
  383. 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
  384. function
  385. __toString(){return$this->render();}final
  386. function
  387. startTag(){if($this->name){return'<'.$this->name.$this->attributes().(static::$xhtml&&$this->isEmpty?' />':'>');}else{return'';}}final
  388. function
  389. endTag(){return$this->name&&!$this->isEmpty?'</'.$this->name.'>':'';}final
  390. function
  391. attributes(){if(!is_array($this->attrs)){return'';}$s='';foreach($this->attrs
  392. as$key=>$value){if($value===NULL||$value===FALSE){continue;}elseif($value===TRUE){if(static::$xhtml){$s.=' '.$key.'="'.$key.'"';}else{$s.=' '.$key;}continue;}elseif(is_array($value)){if($key==='data'){foreach($value
  393. as$k=>$v){if($v!==NULL&&$v!==FALSE){$s.=' data-'.$k.'="'.htmlspecialchars((string)$v).'"';}}continue;}$tmp=NULL;foreach($value
  394. as$k=>$v){if($v!=NULL){$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
  395. __clone(){foreach($this->children
  396. as$key=>$value){if(is_object($value)){$this->children[$key]=clone$value;}}}}}namespace Nette\Diagnostics{use
  397. Nette;final
  398. class
  399. Debugger{public
  400. static$productionMode;public
  401. static$consoleMode;public
  402. static$time;private
  403. static$ajaxDetected;public
  404. static$source;public
  405. static$editor='editor://open/?file=%file&line=%line';public
  406. static$browser;public
  407. static$maxDepth=3;public
  408. static$maxLen=150;public
  409. static$showLocation=FALSE;public
  410. static$consoleColors=array('bool'=>'1;33','null'=>'1;33','int'=>'1;36','float'=>'1;36','string'=>'1;32','array'=>'1;31','key'=>'1;37','object'=>'1;31','visibility'=>'1;30','resource'=>'1;37');const
  411. DEVELOPMENT=FALSE,PRODUCTION=TRUE,DETECT=NULL;public
  412. static$blueScreen;public
  413. static$strictMode=FALSE;public
  414. static$scream=FALSE;public
  415. static$onFatalError=array();private
  416. static$enabled=FALSE;private
  417. static$lastError=FALSE;public
  418. static$logger;public
  419. static$fireLogger;public
  420. static$logDirectory;public
  421. static$email;public
  422. static$mailer;public
  423. static$emailSnooze;public
  424. static$bar;private
  425. static$errorPanel;private
  426. static$dumpPanel;const
  427. DEBUG='debug',INFO='info',WARNING='warning',ERROR='error',CRITICAL='critical';final
  428. function
  429. __construct(){throw
  430. new
  431. Nette\StaticClassException;}static
  432. function
  433. _init(){self::$time=isset($_SERVER['REQUEST_TIME_FLOAT'])?$_SERVER['REQUEST_TIME_FLOAT']:microtime(TRUE);self::$consoleMode=PHP_SAPI==='cli';self::$productionMode=self::DETECT;if(self::$consoleMode){self::$source=empty($_SERVER['argv'])?'cli':'cli: '.implode(' ',$_SERVER['argv']);}else{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'];}}self::$logger=new
  434. Logger;self::$logDirectory=&self::$logger->directory;self::$email=&self::$logger->email;self::$mailer=&self::$logger->mailer;self::$emailSnooze=&Logger::$emailSnooze;self::$fireLogger=new
  435. FireLogger;self::$blueScreen=new
  436. BlueScreen;self::$blueScreen->addPanel(function($e){if($e
  437. instanceof
  438. Nette\Templating\FilterException){return
  439. array('tab'=>'Template','panel'=>'<p><b>File:</b> '.Helpers::editorLink($e->sourceFile,$e->sourceLine).'&nbsp; <b>Line:</b> '.($e->sourceLine?$e->sourceLine:'n/a').'</p>'.($e->sourceLine?BlueScreen::highlightFile($e->sourceFile,$e->sourceLine):''));}elseif($e
  440. instanceof
  441. Nette\Utils\NeonException&&preg_match('#line (\d+)#',$e->getMessage(),$m)){if($item=Helpers::findTrace($e->getTrace(),'Nette\Config\Adapters\NeonAdapter::load')){return
  442. array('tab'=>'NEON','panel'=>'<p><b>File:</b> '.Helpers::editorLink($item['args'][0],$m[1]).'&nbsp; <b>Line:</b> '.$m[1].'</p>'.BlueScreen::highlightFile($item['args'][0],$m[1]));}elseif($item=Helpers::findTrace($e->getTrace(),'Nette\Utils\Neon::decode')){return
  443. array('tab'=>'NEON','panel'=>BlueScreen::highlightPhp($item['args'][0],$m[1]));}}});self::$bar=new
  444. Bar;self::$bar->addPanel(new
  445. DefaultBarPanel('time'));self::$bar->addPanel(new
  446. DefaultBarPanel('memory'));self::$bar->addPanel(self::$errorPanel=new
  447. DefaultBarPanel('errors'));self::$bar->addPanel(self::$dumpPanel=new
  448. DefaultBarPanel('dumps'));}static
  449. function
  450. enable($mode=NULL,$logDirectory=NULL,$email=NULL){error_reporting(E_ALL|E_STRICT);if(is_bool($mode)){self::$productionMode=$mode;}elseif($mode!==self::DETECT||self::$productionMode===NULL){$list=is_string($mode)?preg_split('#[,\s]+#',$mode):(array)$mode;if(!isset($_SERVER['HTTP_X_FORWARDED_FOR'])){$list[]='127.0.0.1';$list[]='::1';}self::$productionMode=!in_array(isset($_SERVER['REMOTE_ADDR'])?$_SERVER['REMOTE_ADDR']:php_uname('n'),$list,TRUE);}if(is_string($logDirectory)){self::$logDirectory=realpath($logDirectory);if(self::$logDirectory===FALSE){echo
  451. __METHOD__."() error: Log directory is not found or is not directory.\n";exit(254);}}elseif($logDirectory===FALSE){self::$logDirectory=FALSE;}elseif(self::$logDirectory===NULL){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')){echo
  452. __METHOD__."() error: Unable to set 'display_errors' because function ini_set() is disabled.\n";exit(254);}if($email){if(!is_string($email)){echo
  453. __METHOD__."() error: Email address must be a string.\n";exit(254);}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
  454. function
  455. isEnabled(){return
  456. self::$enabled;}static
  457. function
  458. log($message,$priority=self::INFO){if(self::$logDirectory===FALSE){return;}elseif(!self::$logDirectory){throw
  459. new
  460. Nette\InvalidStateException('Logging directory is not specified in Nette\Diagnostics\Debugger::$logDirectory.');}if($message
  461. instanceof\Exception){$exception=$message;$message=($message
  462. instanceof
  463. Nette\FatalErrorException?'Fatal error: '.$exception->getMessage():get_class($exception).": ".$exception->getMessage())." in ".$exception->getFile().":".$exception->getLine();$hash=md5($exception);$exceptionFilename="exception-".@date('Y-m-d-H-i-s')."-$hash.html";foreach(new\DirectoryIterator(self::$logDirectory)as$entry){if(strpos($entry,$hash)){$exceptionFilename=$entry;$saved=TRUE;break;}}}self::$logger->log(array(@date('[Y-m-d H-i-s]'),trim($message),self::$source?' @ '.self::$source:NULL,!empty($exceptionFilename)?' @@ '.$exceptionFilename:NULL),$priority);if(!empty($exceptionFilename)){$exceptionFilename=self::$logDirectory.'/'.$exceptionFilename;if(empty($saved)&&$logHandle=@fopen($exceptionFilename,'w')){ob_start();ob_start(function($buffer)use($logHandle){fwrite($logHandle,$buffer);},4096);self::$blueScreen->render($exception);ob_end_flush();ob_end_clean();fclose($logHandle);}return
  464. strtr($exceptionFilename,'\\/',DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR);}}static
  465. function
  466. _shutdownHandler(){if(!self::$enabled){return;}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
  467. Nette\FatalErrorException($error['message'],0,$error['type'],$error['file'],$error['line'],NULL));}if(self::$bar&&!self::$productionMode&&self::isHtmlMode()){self::$bar->render();}}static
  468. function
  469. _exceptionHandler(\Exception$exception){if(!headers_sent()){$protocol=isset($_SERVER['SERVER_PROTOCOL'])?$_SERVER['SERVER_PROTOCOL']:'HTTP/1.1';header($protocol.' 500',TRUE,500);}try{if(self::$productionMode){try{self::log($exception,self::ERROR);}catch(\Exception$e){echo'FATAL ERROR: unable to log error';}if(self::$consoleMode){echo"ERROR: the server encountered an internal error and was unable to complete your request.\n";}elseif(self::isHtmlMode()){?>
  470. <!DOCTYPE html>
  471. <meta charset="utf-8">
  472. <meta name=robots content=noindex>
  473. <meta name=generator content="Nette Framework">
  474. <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>
  475. <title>Server Error</title>
  476. <h1>Server Error</h1>
  477. <p>We're sorry! The server encountered an internal error and was unable to complete your request. Please try again later.</p>
  478. <p><small>error 500</small></p>
  479. <?php }}else{if(self::$consoleMode){echo"$exception\n";if($file=self::log($exception)){echo"(stored in $file)\n";if(self::$browser){exec(self::$browser.' '.escapeshellarg($file));}}}elseif(self::isHtmlMode()){self::$blueScreen->render($exception);if(self::$bar){self::$bar->render();}}elseif(!self::fireLog($exception)){$file=self::log($exception,self::ERROR);if(!headers_sent()){header("X-Nette-Error-Log: $file");}}}foreach(self::$onFatalError
  480. as$handler){call_user_func($handler,$exception);}}catch(\Exception$e){if(self::$productionMode){echo
  481. self::isHtmlMode()?'<meta name=robots content=noindex>FATAL ERROR':'FATAL ERROR';}else{echo"FATAL ERROR: thrown ",get_class($e),': ',$e->getMessage(),"\nwhile processing ",get_class($exception),': ',$exception->getMessage(),"\n";}}self::$enabled=FALSE;exit(254);}static
  482. function
  483. _errorHandler($severity,$message,$file,$line,$context){if(self::$scream){error_reporting(E_ALL|E_STRICT);}if(self::$lastError!==FALSE&&($severity&error_reporting())===$severity){self::$lastError=new\ErrorException($message,0,$severity,$file,$line);return
  484. NULL;}if($severity===E_RECOVERABLE_ERROR||$severity===E_USER_ERROR){if(Helpers::findTrace(debug_backtrace(FALSE),'*::__toString')){$previous=isset($context['e'])&&$context['e']instanceof\Exception?$context['e']:NULL;self::_exceptionHandler(new
  485. Nette\FatalErrorException($message,0,$severity,$file,$line,$context,$previous));}throw
  486. new
  487. Nette\FatalErrorException($message,0,$severity,$file,$line,$context);}elseif(($severity&error_reporting())!==$severity){return
  488. FALSE;}elseif(!self::$productionMode&&(is_bool(self::$strictMode)?self::$strictMode:((self::$strictMode&$severity)===$severity))){self::_exceptionHandler(new
  489. Nette\FatalErrorException($message,0,$severity,$file,$line,$context));}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::$errorPanel->data["$message|$file|$line"];if($count++){return
  490. NULL;}elseif(self::$productionMode){self::log("$message in $file:$line",self::ERROR);return
  491. NULL;}else{$ok=self::fireLog(new\ErrorException($message,0,$severity,$file,$line));return!self::isHtmlMode()||(!self::$bar&&!$ok)?FALSE:NULL;}return
  492. FALSE;}static
  493. function
  494. toStringException(\Exception$exception){if(self::$enabled){self::_exceptionHandler($exception);}else{trigger_error($exception->getMessage(),E_USER_ERROR);}}static
  495. function
  496. tryError(){if(!self::$enabled&&self::$lastError===FALSE){set_error_handler(array(__CLASS__,'_errorHandler'));}self::$lastError=NULL;}static
  497. function
  498. catchError(&$error){if(!self::$enabled&&self::$lastError!==FALSE){restore_error_handler();}$error=self::$lastError;self::$lastError=FALSE;return(bool)$error;}static
  499. function
  500. dump($var,$return=FALSE){if(!$return&&self::$productionMode){return$var;}$output="<pre class=\"nette-dump\">".Helpers::htmlDump($var)."</pre>\n";if(!$return){$trace=debug_backtrace(FALSE);$item=Helpers::findTrace($trace,'dump')?:Helpers::findTrace($trace,__CLASS__.'::dump');if(isset($item['file'],$item['line'])&&is_file($item['file'])){$lines=file($item['file']);preg_match('#dump\((.*)\)#',$lines[$item['line']-1],$m);$output=substr_replace($output,' title="'.htmlspecialchars((isset($m[0])?"$m[0] \n":'')."in file {$item['file']} on line {$item['line']}").'"',4,0);if(self::$showLocation){$output=substr_replace($output,' <small>in '.Helpers::editorLink($item['file'],$item['line']).":{$item['line']}</small>",-8,0);}}}if(self::$consoleMode){if(self::$consoleColors&&substr(getenv('TERM'),0,5)==='xterm'){$output=preg_replace_callback('#<span class="php-(\w+)">|</span>#',function($m){return"\033[".(isset($m[1],Debugger::$consoleColors[$m[1]])?Debugger::$consoleColors[$m[1]]:'0')."m";},$output);}$output=htmlspecialchars_decode(strip_tags($output),ENT_QUOTES);}if($return){return$output;}else{echo$output;return$var;}}static
  501. function
  502. timer($name=NULL){static$time=array();$now=microtime(TRUE);$delta=isset($time[$name])?$now-$time[$name]:0;$time[$name]=$now;return$delta;}static
  503. function
  504. barDump($var,$title=NULL){if(!self::$productionMode){$dump=array();foreach((is_array($var)?$var:array(''=>$var))as$key=>$val){$dump[$key]=Helpers::clickableDump($val);}self::$dumpPanel->data[]=array('title'=>$title,'dump'=>$dump);}return$var;}static
  505. function
  506. fireLog($message){if(!self::$productionMode){return
  507. self::$fireLogger->log($message);}}private
  508. static
  509. function
  510. isHtmlMode(){return!self::$ajaxDetected&&!self::$consoleMode&&!preg_match('#^Content-Type: (?!text/html)#im',implode("\n",headers_list()));}static
  511. function
  512. addPanel(IBarPanel$panel,$id=NULL){return
  513. self::$bar->addPanel($panel,$id);}}class
  514. Logger
  515. extends
  516. Nette\Object{const
  517. DEBUG='debug',INFO='info',WARNING='warning',ERROR='error',CRITICAL='critical';public
  518. static$emailSnooze=172800;public$mailer=array(__CLASS__,'defaultMailer');public$directory;public$email;function
  519. log($message,$priority=self::INFO){if(!is_dir($this->directory)){throw
  520. new
  521. Nette\DirectoryNotFoundException("Directory '$this->directory' is not found or is not directory.");}if(is_array($message)){$message=implode(' ',$message);}$res=error_log(trim($message).PHP_EOL,3,$this->directory.'/'.strtolower($priority).'.log');if(($priority===self::ERROR||$priority===self::CRITICAL)&&$this->email&&$this->mailer&&@filemtime($this->directory.'/email-sent')+self::$emailSnooze<time()&&@file_put_contents($this->directory.'/email-sent','sent')){Nette\Callback::create($this->mailer)->invoke($message,$this->email);}return$res;}static
  522. function
  523. defaultMailer($message,$email){$host=php_uname('n');foreach(array('HTTP_HOST','SERVER_NAME','HOSTNAME')as$item){if(isset($_SERVER[$item])){$host=$_SERVER[$item];break;}}$parts=str_replace(array("\r\n","\n"),array("\n",PHP_EOL),array('headers'=>implode("\n",array("From: noreply@$host",'X-Mailer: Nette Framework','Content-Type: text/plain; charset=UTF-8','Content-Transfer-Encoding: 8bit'))."\n",'subject'=>"PHP: An error occurred on the server $host",'body'=>"[".@date('Y-m-d H:i:s')."] $message"));mail($email,$parts['subject'],$parts['body'],$parts['headers']);}}class
  524. FireLogger
  525. extends
  526. Nette\Object{const
  527. DEBUG='debug',INFO='info',WARNING='warning',ERROR='error',CRITICAL='critical';private
  528. static$payload=array('logs'=>array());static
  529. function
  530. log($message,$priority=self::DEBUG){if(!isset($_SERVER['HTTP_X_FIRELOGGER'])||headers_sent()){return
  531. FALSE;}$item=array('name'=>'PHP','level'=>$priority,'order'=>count(self::$payload['logs']),'time'=>str_pad(number_format((microtime(TRUE)-Debugger::$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']==='Nette\Diagnostics\Debugger'&&($trace[0]['function']==='_shutdownHandler'||$trace[0]['function']==='_errorHandler')){unset($trace[0]);}$file=str_replace(dirname(dirname(dirname($e->getFile()))),"\xE2\x80\xA6",$e->getFile());$item['template']=($e
  532. instanceof\ErrorException?'':get_class($e).': ').$e->getMessage().($e->getCode()?' #'.$e->getCode():'').' in '.$file.':'.$e->getLine();$item['pathname']=$e->getFile();$item['lineno']=$e->getLine();}else{$trace=debug_backtrace();if(isset($trace[1]['class'])&&$trace[1]['class']==='Nette\Diagnostics\Debugger'&&($trace[1]['function']==='fireLog')){unset($trace[0]);}foreach($trace
  533. as$frame){if(isset($frame['file'])&&is_file($frame['file'])){$item['pathname']=$frame['file'];$item['lineno']=$frame['line'];break;}}}$item['exc_info']=array('','',array());$item['exc_frames']=array();foreach($trace
  534. 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'];}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;self::$payload['logs'][]=self::jsonDump($item,-1);foreach(str_split(base64_encode(@json_encode(self::$payload)),4990)as$k=>$v){header("FireLogger-de11e-$k:$v");}return
  535. TRUE;}private
  536. static
  537. function
  538. jsonDump(&$var,$level=0){if(is_bool($var)||is_null($var)||is_int($var)||is_float($var)){return$var;}elseif(is_string($var)){if(Debugger::$maxLen&&strlen($var)>Debugger::$maxLen){$var=substr($var,0,Debugger::$maxLen)." \xE2\x80\xA6 ";}return
  539. Nette\Utils\Strings::fixEncoding($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<Debugger::$maxDepth||!Debugger::$maxDepth){$var[$marker]=TRUE;$res=array();foreach($var
  540. as$k=>&$v){if($k!==$marker){$res[self::jsonDump($k)]=self::jsonDump($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<Debugger::$maxDepth||!Debugger::$maxDepth){$list[]=$var;$res=array("\x00"=>'(object) '.get_class($var));foreach($arr
  541. as$k=>&$v){if($k[0]==="\x00"){$k=substr($k,strrpos($k,"\x00")+1);}$res[self::jsonDump($k)]=self::jsonDump($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";}}}class
  542. BlueScreen
  543. extends
  544. Nette\Object{private$panels=array();function
  545. addPanel($panel){if(!in_array($panel,$this->panels,TRUE)){$this->panels[]=$panel;}return$this;}function
  546. render(\Exception$exception){$panels=$this->panels;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
  547. instanceof
  548. Nette\FatalErrorException&&isset($errorTypes[$exception->getSeverity()]))?$errorTypes[$exception->getSeverity()]:get_class($exception);$expandPath=NETTE_DIR.DIRECTORY_SEPARATOR;$counter=0;?><!DOCTYPE html><!-- "' --></script></style></pre></xmp></table>
  549. <html>
  550. <head>
  551. <meta charset="utf-8">
  552. <meta name="robots" content="noindex">
  553. <meta name="generator" content="Nette Framework">
  554. <title><?php echo
  555. htmlspecialchars($title)?></title><!-- <?php
  556. $ex=$exception;echo
  557. htmlspecialchars($ex->getMessage().($ex->getCode()?' #'.$ex->getCode():''));while((method_exists($ex,'getPrevious')&&$ex=$ex->getPrevious())||(isset($ex->previous)&&$ex=$ex->previous))echo
  558. htmlspecialchars('; caused by '.get_class($ex).' '.$ex->getMessage().($ex->getCode()?' #'.$ex->getCode():''));?> -->
  559. <style type="text/css" class="nette">html{overflow-y:scroll}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}#netteBluescreen a{text-decoration:none;color:#328ADC;padding:2px 4px;margin:-2px -4px}#netteBluescreen a:hover,#netteBluescreen a:active,#netteBluescreen a:focus{color:#085AA3}#netteBluescreen a abbr{font-family:sans-serif;color:#BBB}#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}#netteBluescreenError #netteBsSearch{color:#CD1818;font-size:.7em}#netteBluescreenError:hover #netteBsSearch{color:#ED8383}#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 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 pre div{min-width:100%;float:left;_float:none;white-space:pre}#netteBluescreen table pre{padding:0;margin:0;border:none}#netteBluescreen pre .php-array,#netteBluescreen pre .php-object{color:#C22}#netteBluescreen pre .php-string{color:#080}#netteBluescreen pre .php-int,#netteBluescreen pre .php-float,#netteBluescreen pre .php-null,#netteBluescreen pre .php-bool{color:#328ADC}#netteBluescreen pre .php-visibility{font-size:85%;color:#998}#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{font-weight:bold}#netteBluescreen tr>:first-child{width:20%}#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 #C1D2E1}#netteBluescreen .caused{float:right;padding:.3em .6em;background:#df8075;border-radius:0 0 0 8px;white-space:nowrap}#netteBluescreen .caused a{color:white}</style>
  560. </head>
  561. <body>
  562. <div id="netteBluescreen">
  563. <a id="netteBluescreenIcon" href="#" rel="next"><abbr>&#x25bc;</abbr></a
  564. ><div>
  565. <div id="netteBluescreenError" class="panel">
  566. <h1><?php echo
  567. htmlspecialchars($title),($exception->getCode()?' #'.$exception->getCode():'')?></h1>
  568. <p><?php echo
  569. htmlspecialchars($exception->getMessage())?> <a href="http://www.google.cz/search?sourceid=nette&amp;q=<?php echo
  570. urlencode($title.' '.preg_replace('#\'.*\'|".*"#Us','',$exception->getMessage()))?>" id="netteBsSearch">search&#x25ba;</a></p>
  571. </div>
  572. <?php if((method_exists($exception,'getPrevious')&&$prev=$exception->getPrevious())||(isset($exception->previous)&&$prev=$exception->previous)):?>
  573. <div class="caused">
  574. <a href="#netteCaused">Caused by <?php echo
  575. get_class($prev)?></a>
  576. </div>
  577. <?php endif?>
  578. <?php $ex=$exception;$level=0;?>
  579. <?php do{?>
  580. <?php if($level++):?>
  581. <div class="panel"<?php if($level===2)echo' id="netteCaused"'?>>
  582. <h2><a href="#" rel="netteBsPnl<?php echo++$counter?>">Caused by <abbr><?php echo($collapsed=$level>2)?'&#x25ba;':'&#x25bc;'?></abbr></a></h2>
  583. <div id="netteBsPnl<?php echo$counter?>" class="<?php echo$collapsed?'nette-collapsed ':''?>inner">
  584. <div class="panel">
  585. <h1><?php echo
  586. htmlspecialchars(get_class($ex).($ex->getCode()?' #'.$ex->getCode():''))?></h1>
  587. <p><b><?php echo
  588. htmlspecialchars($ex->getMessage())?></b></p>
  589. </div>
  590. <?php endif?>
  591. <?php foreach($panels
  592. as$panel):?>
  593. <?php $panel=call_user_func($panel,$ex);if(empty($panel['tab'])||empty($panel['panel']))continue;?>
  594. <?php if(!empty($panel['bottom'])){continue;}?>
  595. <div class="panel">
  596. <h2><a href="#" rel="netteBsPnl<?php echo++$counter?>"><?php echo
  597. htmlSpecialChars($panel['tab'])?> <abbr>&#x25bc;</abbr></a></h2>
  598. <div id="netteBsPnl<?php echo$counter?>" class="inner">
  599. <?php echo$panel['panel']?>
  600. </div></div>
  601. <?php endforeach?>
  602. <?php $stack=$ex->getTrace();$expanded=NULL?>
  603. <?php if(strpos($ex->getFile(),$expandPath)===0){foreach($stack
  604. as$key=>$row){if(isset($row['file'])&&strpos($row['file'],$expandPath)!==0){$expanded=$key;break;}}}?>
  605. <div class="panel">
  606. <h2><a href="#" rel="netteBsPnl<?php echo++$counter?>">Source file <abbr><?php echo($collapsed=$expanded!==NULL)?'&#x25ba;':'&#x25bc;'?></abbr></a></h2>
  607. <div id="netteBsPnl<?php echo$counter?>" class="<?php echo$collapsed?'nette-collapsed ':''?>inner">
  608. <p><b>File:</b> <?php echo
  609. Helpers::editorLink($ex->getFile(),$ex->getLine())?> &nbsp; <b>Line:</b> <?php echo$ex->getLine()?></p>
  610. <?php if(is_file($ex->getFile())):?><?php echo
  611. self::highlightFile($ex->getFile(),$ex->getLine(),15,isset($ex->context)?$ex->context:NULL)?><?php endif?>
  612. </div></div>
  613. <?php if(isset($stack[0]['class'])&&$stack[0]['class']==='Nette\Diagnostics\Debugger'&&($stack[0]['function']==='_shutdownHandler'||$stack[0]['function']==='_errorHandler'))unset($stack[0])?>
  614. <?php if($stack):?>
  615. <div class="panel">
  616. <h2><a href="#" rel="netteBsPnl<?php echo++$counter?>">Call stack <abbr>&#x25bc;</abbr></a></h2>
  617. <div id="netteBsPnl<?php echo$counter?>" class="inner">
  618. <ol>
  619. <?php foreach($stack
  620. as$key=>$row):?>
  621. <li><p>
  622. <?php if(isset($row['file'])&&is_file($row['file'])):?>
  623. <?php echo
  624. Helpers::editorLink($row['file'],$row['line']),':',$row['line']?>
  625. <?php else:?>
  626. <i>inner-code</i><?php if(isset($row['line']))echo':',$row['line']?>
  627. <?php endif?>
  628. <?php if(isset($row['file'])&&is_file($row['file'])):?><a href="#" rel="netteBsSrc<?php echo"$level-$key"?>">source <abbr>&#x25ba;</abbr></a>&nbsp; <?php endif?>
  629. <?php if(isset($row['class']))echo
  630. htmlspecialchars($row['class'].$row['type'])?>
  631. <?php echo
  632. htmlspecialchars($row['function'])?>
  633. (<?php if(!empty($row['args'])):?><a href="#" rel="netteBsArgs<?php echo"$level-$key"?>">arguments <abbr>&#x25ba;</abbr></a><?php endif?>)
  634. </p>
  635. <?php if(!empty($row['args'])):?>
  636. <div class="nette-collapsed outer" id="netteBsArgs<?php echo"$level-$key"?>">
  637. <table>
  638. <?php
  639. 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>',htmlspecialchars(isset($params[$k])?'$'.$params[$k]->name:"#$k"),'</th><td>';echo
  640. Helpers::clickableDump($v);echo"</td></tr>\n";}?>
  641. </table>
  642. </div>
  643. <?php endif?>
  644. <?php if(isset($row['file'])&&is_file($row['file'])):?>
  645. <div <?php if($expanded!==$key)echo'class="nette-collapsed"';?> id="netteBsSrc<?php echo"$level-$key"?>"><?php echo
  646. self::highlightFile($row['file'],$row['line'])?></div>
  647. <?php endif?>
  648. </li>
  649. <?php endforeach?>
  650. </ol>
  651. </div></div>
  652. <?php endif?>
  653. <?php if(isset($ex->context)&&is_array($ex->context)):?>
  654. <div class="panel">
  655. <h2><a href="#" rel="netteBsPnl<?php echo++$counter?>">Variables <abbr>&#x25ba;</abbr></a></h2>
  656. <div id="netteBsPnl<?php echo$counter?>" class="nette-collapsed inner">
  657. <div class="outer">
  658. <table>
  659. <?php
  660. foreach($ex->context
  661. as$k=>$v){echo'<tr><th>$',htmlspecialchars($k),'</th><td>',Helpers::clickableDump($v),"</td></tr>\n";}?>
  662. </table>
  663. </div>
  664. </div></div>
  665. <?php endif?>
  666. <?php }while((method_exists($ex,'getPrevious')&&$ex=$ex->getPrevious())||(isset($ex->previous)&&$ex=$ex->previous));?>
  667. <?php while(--$level)echo'</div></div>'?>
  668. <?php $bottomPanels=array()?>
  669. <?php foreach($panels
  670. as$panel):?>
  671. <?php $panel=call_user_func($panel,NULL);if(empty($panel['tab'])||empty($panel['panel']))continue;?>
  672. <?php if(!empty($panel['bottom'])){$bottomPanels[]=$panel;continue;}?>
  673. <div class="panel">
  674. <h2><a href="#" rel="netteBsPnl<?php echo++$counter?>"><?php echo
  675. htmlSpecialChars($panel['tab'])?> <abbr>&#x25ba;</abbr></a></h2>
  676. <div id="netteBsPnl<?php echo$counter?>" class="nette-collapsed inner">
  677. <?php echo$panel['panel']?>
  678. </div></div>
  679. <?php endforeach?>
  680. <div class="panel">
  681. <h2><a href="#" rel="netteBsPnl<?php echo++$counter?>">Environment <abbr>&#x25ba;</abbr></a></h2>
  682. <div id="netteBsPnl<?php echo$counter?>" class="nette-collapsed inner">
  683. <h3><a href="#" rel="netteBsPnl<?php echo++$counter?>">$_SERVER <abbr>&#x25bc;</abbr></a></h3>
  684. <div id="netteBsPnl<?php echo$counter?>" class="outer">
  685. <table>
  686. <?php
  687. foreach($_SERVER
  688. as$k=>$v)echo'<tr><th>',htmlspecialchars($k),'</th><td>',Helpers::clickableDump($v),"</td></tr>\n";?>
  689. </table>
  690. </div>
  691. <h3><a href="#" rel="netteBsPnl<?php echo++$counter?>">$_SESSION <abbr>&#x25bc;</abbr></a></h3>
  692. <div id="netteBsPnl<?php echo$counter?>" class="outer">
  693. <?php if(empty($_SESSION)):?>
  694. <p><i>empty</i></p>
  695. <?php else:?>
  696. <table>
  697. <?php
  698. foreach($_SESSION
  699. as$k=>$v)echo'<tr><th>',htmlspecialchars($k),'</th><td>',$k==='__NF'?'<i>Nette Session</i>':Helpers::clickableDump($v),"</td></tr>\n";?>
  700. </table>
  701. <?php endif?>
  702. </div>
  703. <?php if(!empty($_SESSION['__NF']['DATA'])):?>
  704. <h3><a href="#" rel="netteBsPnl<?php echo++$counter?>">Nette Session <abbr>&#x25bc;</abbr></a></h3>
  705. <div id="netteBsPnl<?php echo$counter?>" class="outer">
  706. <table>
  707. <?php
  708. foreach($_SESSION['__NF']['DATA']as$k=>$v)echo'<tr><th>',htmlspecialchars($k),'</th><td>',Helpers::clickableDump($v),"</td></tr>\n";?>
  709. </table>
  710. </div>
  711. <?php endif?>
  712. <?php
  713. $list=get_defined_constants(TRUE);if(!empty($list['user'])):?>
  714. <h3><a href="#" rel="netteBsPnl<?php echo++$counter?>">Constants <abbr>&#x25ba;</abbr></a></h3>
  715. <div id="netteBsPnl<?php echo$counter?>" class="outer nette-collapsed">
  716. <table>
  717. <?php
  718. foreach($list['user']as$k=>$v){echo'<tr><th>',htmlspecialchars($k),'</th>';echo'<td>',Helpers::clickableDump($v),"</td></tr>\n";}?>
  719. </table>
  720. </div>
  721. <?php endif?>
  722. <h3><a href="#" rel="netteBsPnl<?php echo++$counter?>">Included files <abbr>&#x25ba;</abbr></a> (<?php echo
  723. count(get_included_files())?>)</h3>
  724. <div id="netteBsPnl<?php echo$counter?>" class="outer nette-collapsed">
  725. <table>
  726. <?php
  727. foreach(get_included_files()as$v){echo'<tr><td>',htmlspecialchars($v),"</td></tr>\n";}?>
  728. </table>
  729. </div>
  730. <h3><a href="#" rel="netteBsPnl<?php echo++$counter?>">Configuration options <abbr>&#x25ba;</abbr></a></h3>
  731. <div id="netteBsPnl<?php echo$counter?>" class="outer nette-collapsed">
  732. <?php ob_start();@phpinfo(INFO_CONFIGURATION|INFO_MODULES);echo
  733. preg_replace('#^.+<body>|</body>.+\z#s','',ob_get_clean())?>
  734. </div>
  735. </div></div>
  736. <div class="panel">
  737. <h2><a href="#" rel="netteBsPnl<?php echo++$counter?>">HTTP request <abbr>&#x25ba;</abbr></a></h2>
  738. <div id="netteBsPnl<?php echo$counter?>" class="nette-collapsed inner">
  739. <?php if(function_exists('apache_request_headers')):?>
  740. <h3>Headers</h3>
  741. <div class="outer">
  742. <table>
  743. <?php
  744. foreach(apache_request_headers()as$k=>$v)echo'<tr><th>',htmlspecialchars($k),'</th><td>',htmlspecialchars($v),"</td></tr>\n";?>
  745. </table>
  746. </div>
  747. <?php endif?>
  748. <?php foreach(array('_GET','_POST','_COOKIE')as$name):?>
  749. <h3>$<?php echo
  750. htmlspecialchars($name)?></h3>
  751. <?php if(empty($GLOBALS[$name])):?>
  752. <p><i>empty</i></p>
  753. <?php else:?>
  754. <div class="outer">
  755. <table>
  756. <?php
  757. foreach($GLOBALS[$name]as$k=>$v)echo'<tr><th>',htmlspecialchars($k),'</th><td>',Helpers::clickableDump($v),"</td></tr>\n";?>
  758. </table>
  759. </div>
  760. <?php endif?>
  761. <?php endforeach?>
  762. </div></div>
  763. <div class="panel">
  764. <h2><a href="#" rel="netteBsPnl<?php echo++$counter?>">HTTP response <abbr>&#x25ba;</abbr></a></h2>
  765. <div id="netteBsPnl<?php echo$counter?>" class="nette-collapsed inner">
  766. <h3>Headers</h3>
  767. <?php if(headers_list()):?>
  768. <pre><?php
  769. foreach(headers_list()as$s)echo
  770. htmlspecialchars($s),'<br>';?></pre>
  771. <?php else:?>
  772. <p><i>no headers</i></p>
  773. <?php endif?>
  774. </div></div>
  775. <?php foreach($bottomPanels
  776. as$panel):?>
  777. <div class="panel">
  778. <h2><a href="#" rel="netteBsPnl<?php echo++$counter?>"><?php echo
  779. htmlSpecialChars($panel['tab'])?> <abbr>&#x25bc;</abbr></a></h2>
  780. <div id="netteBsPnl<?php echo$counter?>" class="inner">
  781. <?php echo$panel['panel']?>
  782. </div></div>
  783. <?php endforeach?>
  784. <ul>
  785. <li>Report generated at <?php echo@date('Y/m/d H:i:s',Debugger::$time)?></li>
  786. <?php if(preg_match('#^https?://#',Debugger::$source)):?>
  787. <li><a href="<?php echo
  788. htmlSpecialChars(Debugger::$source)?>"><?php echo
  789. htmlSpecialChars(Debugger::$source)?></a></li>
  790. <?php elseif(Debugger::$source):?>
  791. <li><?php echo
  792. htmlSpecialChars(Debugger::$source)?></li>
  793. <?php endif?>
  794. <li>PHP <?php echo
  795. htmlSpecialChars(PHP_VERSION)?></li>
  796. <?php if(isset($_SERVER['SERVER_SOFTWARE'])):?><li><?php echo
  797. htmlSpecialChars($_SERVER['SERVER_SOFTWARE'])?></li><?php endif?>
  798. <?php if(class_exists('Nette\Framework')):?><li><?php echo
  799. htmlSpecialChars('Nette Framework '.Nette\Framework::VERSION)?> <i>(revision <?php echo
  800. htmlSpecialChars(Nette\Framework::REVISION)?>)</i></li><?php endif?>
  801. </ul>
  802. </div>
  803. </div>
  804. <script type="text/javascript">/*<![CDATA[*/var bs=document.getElementById("netteBluescreen");document.body.appendChild(bs);document.onkeyup=function(b){b=b||window.event;if(27==b.keyCode&&!b.shiftKey&&!b.altKey&&!b.ctrlKey&&!b.metaKey)bs.onclick({target:document.getElementById("netteBluescreenIcon")})};
  805. for(var i=0,styles=document.styleSheets;i<styles.length;i++)"nette"!==(styles[i].owningElement||styles[i].ownerNode).className?(styles[i].oldDisabled=styles[i].disabled,styles[i].disabled=!0):styles[i].addRule?styles[i].addRule(".nette-collapsed","display: none"):styles[i].insertRule(".nette-collapsed { display: none }",0);
  806. bs.onclick=function(b){for(var b=b||window.event,a=b.target||b.srcElement;a&&a.tagName&&"a"!==a.tagName.toLowerCase();)a=a.parentNode;if(!a||!a.rel)return!0;for(var d=a.getElementsByTagName("abbr")[0],c="next"===a.rel?a.nextSibling:document.getElementById(a.rel);1!==c.nodeType;)c=c.nextSibling;b=c.currentStyle?"none"==c.currentStyle.display:"none"==getComputedStyle(c,null).display;try{d.innerHTML=String.fromCharCode(b?9660:9658)}catch(e){}c.style.display=b?"code"===c.tagName.toLowerCase()?"inline":
  807. "block":"none";if("netteBluescreenIcon"===a.id){a=0;for(d=document.styleSheets;a<d.length;a++)if("nette"!==(d[a].owningElement||d[a].ownerNode).className)d[a].disabled=b?!0:d[a].oldDisabled}return!1};/*]]>*/</script>
  808. </body>
  809. </html>
  810. <?php }static
  811. function
  812. highlightFile($file,$line,$lines=15,$vars=array()){$source=@file_get_contents($file);if($source){return
  813. static::highlightPhp($source,$line,$lines,$vars);}}static
  814. function
  815. highlightPhp($source,$line,$lines=15,$vars=array()){if(function_exists('ini_set')){ini_set('highlight.comment','#998; 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');}$source=str_replace(array("\r\n","\r"),"\n",$source);$source=explode("\n",highlight_string($source,TRUE));$spans=1;$out=$source[0];$source=explode('<br />',$source[1]);array_unshift($source,NULL);$start=$i=max(1,$line-floor($lines*2/3));while(--$i>=1){if(preg_match('#.*(</?span[^>]*>)#',$source[$i],$m)){if($m[1]!=='</span>'){$spans++;$out.=$m[1];}break;}}$source=array_slice($source,$start,$lines,TRUE);end($source);$numWidth=strlen((string)key($source));foreach($source
  816. 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){$out.=sprintf("<span class='highlight'>%{$numWidth}s: %s\n</span>%s",$n,strip_tags($s),implode('',$tags[0]));}else{$out.=sprintf("<span class='line'>%{$numWidth}s:</span> %s\n",$n,$s);}}$out.=str_repeat('</span>',$spans).'</code>';$out=preg_replace_callback('#">\$(\w+)(&nbsp;)?</span>#',function($m)use($vars){return
  817. isset($vars[$m[1]])?'" title="'.str_replace('"','&quot;',strip_tags(Helpers::htmlDump($vars[$m[1]]))).$m[0]:$m[0];},$out);return"<pre><div>$out</div></pre>";}}class
  818. Bar
  819. extends
  820. Nette\Object{private$panels=array();function
  821. addPanel(IBarPanel$panel,$id=NULL){if($id===NULL){$c=0;do{$id=get_class($panel).($c++?"-$c":'');}while(isset($this->panels[$id]));}$this->panels[$id]=$panel;return$this;}function
  822. render(){$obLevel=ob_get_level();$panels=array();foreach($this->panels
  823. as$id=>$panel){try{$panels[]=array('id'=>preg_replace('#[^a-z0-9]+#i','-',$id),'tab'=>$tab=(string)$panel->getTab(),'panel'=>$tab?(string)$panel->getPanel():NULL);}catch(\Exception$e){$panels[]=array('id'=>"error-".preg_replace('#[^a-z0-9]+#i','-',$id),'tab'=>"Error in $id",'panel'=>'<h1>Error: '.$id.'</h1><div class="nette-inner">'.nl2br(htmlSpecialChars($e)).'</div>');while(ob_get_level()>$obLevel){ob_end_clean();}}}?>
  824. <!-- Nette Debug Bar -->
  825. <?php ob_start()?>
  826. &nbsp;
  827. <style id="nette-debug-style" class="nette">#nette-debug{display:none;position:fixed}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;opacity:1;border-radius:0;box-shadow:none}#nette-debug b,#nette-debug strong{font-weight:bold}#nette-debug i,#nette-debug em{font-style:italic}#nette-debug .nette-fixed-coords{position:fixed;_position:absolute;right:0;bottom:0;max-width:100%}#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,.nette-collapsed{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=') top;position:relative;overflow:auto;min-height:21px;_float:left;min-width:50px;white-space:nowrap;z-index:23181;opacity:.9;border-radius:3px;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;text-align:left}#nette-debug h1{font:normal normal 23px/1.4 Tahoma,sans-serif;color:#575753;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:10px;min-width:150px;min-height:50px;border-radius:5px;box-shadow:1px 1px 20px rgba(102,102,102,0.36);border:1px solid rgba(0,0,0,0.1)}#nette-debug .nette-mode-peek h1{cursor:move}#nette-debug .nette-mode-float{position:relative;padding:10px;min-width:150px;min-height:50px;border-radius:5px;opacity:.95;box-shadow:1px 1px 30px rgba(102,102,102,0.36);border:1px solid rgba(0,0,0,0.1)}#nette-debug .nette-focused{opacity:1}#nette-debug .nette-mode-float h1{cursor:move}#nette-debug .nette-mode-float .nette-icons{display:block;position:absolute;top:0;right:5px;font-size:18px}#nette-debug .nette-icons a{color:#575753}#nette-debug .nette-icons a:hover{color:white}pre.nette-dump{color:#444;background:white}pre.nette-dump a,#nette-debug pre.nette-dump a{color:inherit;background:inherit}pre.nette-dump .php-array,pre.nette-dump .php-object,#nette-debug pre.nette-dump .php-array,#nette-debug pre.nette-dump .php-object{color:#C22}pre.nette-dump .php-string,#nette-debug pre.nette-dump .php-string{color:#080}pre.nette-dump .php-int,pre.nette-dump .php-float,#nette-debug pre.nette-dump .php-int,#nette-debug pre.nette-dump .php-float{color:#37D}pre.nette-dump .php-null,pre.nette-dump .php-bool,#nette-debug pre.nette-dump .php-null,#nette-debug pre.nette-dump .php-bool{color:black}pre.nette-dump .php-visibility,#nette-debug pre.nette-dump .php-visibility{font-size:85%;color:#999}@media print{#nette-debug *{display:none}}</style>
  828. <!--[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]-->
  829. <script id="nette-debug-script">/*<![CDATA[*/var Nette=Nette||{};
  830. (function(){Nette.Class=function(a){var b=Object.prototype.hasOwnProperty,c,d=b.call(a,"constructor")?a.constructor:function(){};delete a.constructor;if(a.Extends){var f=function(){this.constructor=d};f.prototype=a.Extends.prototype;d.prototype=new f;delete a.Extends}if(a.Static){for(c in a.Static)b.call(a.Static,c)&&(d[c]=a.Static[c]);delete a.Static}for(c in a)b.call(a,c)&&(d.prototype[c]=a[c]);return d};Nette.Q=Nette.Class({Static:{factory:function(a){return new Nette.Q(a)},implement:function(a){var b,
  831. c=Nette.Q.implement,d=Nette.Q.prototype,f=Object.prototype.hasOwnProperty;for(b in a)f.call(a,b)&&(c[b]=a[b],d[b]=function(a){return function(){return this.each(c[a],arguments)}}(b))}},constructor:function(a){if("string"===typeof a)a=this._find(document,a);else if(!a||a.nodeType||void 0===a.length||a===window)a=[a];for(var b=0,c=a.length;b<c;b++)a[b]&&(this[this.length++]=a[b])},length:0,find:function(a){return new Nette.Q(this._find(this[0],a))},_find:function(a,b){if(!a||!b)return[];if(document.querySelectorAll)return a.querySelectorAll(b);
  832. if("#"===b.charAt(0))return[document.getElementById(b.substring(1))];var b=b.split("."),c=a.getElementsByTagName(b[0]||"*");if(b[1]){for(var d=[],f=RegExp("(^|\\s)"+b[1]+"(\\s|$)"),e=0,h=c.length;e<h;e++)f.test(c[e].className)&&d.push(c[e]);return d}return c},dom:function(){return this[0]},each:function(a,b){for(var c=0,d;c<this.length;c++)if(void 0!==(d=a.apply(this[c],b||[])))return d;return this}});var i=Nette.Q.factory,e=Nette.Q.implement;e({bind:function(a,b){if(document.addEventListener&&("mouseenter"===
  833. a||"mouseleave"===a))var c=b,a="mouseenter"===a?"mouseover":"mouseout",b=function(a){for(var b=a.relatedTarget;b;b=b.parentNode)if(b===this)return;c.call(this,a)};var d=e.data.call(this),d=d.events=d.events||{};if(!d[a]){var f=this,g=d[a]=[],h=e.bind.genericHandler=function(a){a.target||(a.target=a.srcElement);a.preventDefault||(a.preventDefault=function(){a.returnValue=!1});a.stopPropagation||(a.stopPropagation=function(){a.cancelBubble=!0});a.stopImmediatePropagation=function(){this.stopPropagation();
  834. b=g.length};for(var b=0;b<g.length;b++)g[b].call(f,a)};document.addEventListener?this.addEventListener(a,h,!1):document.attachEvent&&this.attachEvent("on"+a,h)}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-1<this.className.replace(/^|\s+|$/g," ").indexOf(" "+a+" ")},show:function(){var a=e.show.display=
  835. e.show.display||{},b=this.tagName;if(!a[b]){var c=document.body.appendChild(document.createElement(b));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:this.nette={}},val:function(){var a,b,c;if(!this.nodeName){for(a=0,b=this.length;a<b;a++)if(this[a].checked)return this[a].value;
  836. return null}if("select"===this.nodeName.toLowerCase()){a=this.selectedIndex;var d=this.options;if(0>a)return null;if("select-one"===this.type)return d[a].value;for(a=0,c=[],b=d.length;a<b;a++)d[a].selected&&c.push(d[a].value);return c}return"checkbox"===this.type?this.checked:this.value.replace(/^\s+|\s+$/g,"")},_trav:function(a,b,c){for(b=b.split(".");a&&!(1===a.nodeType&&(!b[0]||a.tagName.toLowerCase()===b[0])&&(!b[1]||e.hasClass.call(a,b[1])));)a=a[c];return i(a)},closest:function(a){return e._trav(this,
  837. a,"parentNode")},prev:function(a){return e._trav(this.previousSibling,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=
  838. (a.top||0)+"px";else return{left:this.offsetLeft,top:this.offsetTop,width:this.offsetWidth,height:this.offsetHeight}},draggable:function(a){var b=i(this),c=document.documentElement,d,a=a||{};i(a.handle||this).bind("mousedown",function(f){f.preventDefault();f.stopPropagation();if(e.draggable.binded)return c.onmouseup(f);var g=b[0].offsetLeft-f.clientX,h=b[0].offsetTop-f.clientY;e.draggable.binded=!0;d=!1;c.onmousemove=function(c){c=c||event;d||(a.draggedClass&&b.addClass(a.draggedClass),a.start&&a.start(c,
  839. b),d=!0);b.position({left:c.clientX+g,top:c.clientY+h});return!1};c.onmouseup=function(f){d&&(a.draggedClass&&b.removeClass(a.draggedClass),a.stop&&a.stop(f||event,b));e.draggable.binded=c.onmousemove=c.onmouseup=null;return!1}}).bind("click",function(a){d&&a.stopImmediatePropagation()})}})})();
  840. (function(){Nette.Debug={};var i=2E4,e=Nette.Q.factory,a=Nette.Debug.Panel=Nette.Class({Extends:Nette.Q,Static:{PEEK:"nette-mode-peek",FLOAT:"nette-mode-float",WINDOW:"nette-mode-window",FOCUSED:"nette-focused",factory:function(b){return new a(b)},_toggle:function(a){var c=a.rel,c="#"===c.charAt(0)?e(c):e(a)["prev"===c?"prev":"next"](c.substring(4));"none"===c.css("display")?(c.show(),a.innerHTML=a.innerHTML.replace("â–º","â–¼")):(c.hide(),a.innerHTML=a.innerHTML.replace("â–¼","â–º"))}},constructor:function(a){Nette.Q.call(this,
  841. "#nette-debug-panel-"+a.replace("nette-debug-panel-",""))},reposition:function(){this.hasClass(a.WINDOW)?window.resizeBy(document.documentElement.scrollWidth-document.documentElement.clientWidth,document.documentElement.scrollHeight-document.documentElement.clientHeight):(this.position(this.position()),this.position().width&&(document.cookie=this.dom().id+"="+this.position().left+":"+this.position().top+"; path=/"))},focus:function(){this.hasClass(a.WINDOW)?this.data().win.focus():(clearTimeout(this.data().blurTimeout),
  842. this.addClass(a.FOCUSED).show(),this[0].style.zIndex=i++)},blur:function(){this.removeClass(a.FOCUSED);if(this.hasClass(a.PEEK)){var b=this;this.data().blurTimeout=setTimeout(function(){b.hide()},50)}},toFloat:function(){this.removeClass(a.WINDOW).removeClass(a.PEEK).addClass(a.FLOAT).show().reposition();return this},toPeek:function(){this.removeClass(a.WINDOW).removeClass(a.FLOAT).addClass(a.PEEK).hide();document.cookie=this.dom().id+"=; path=/"},toWindow:function(){var b=this,c,d;d=this.offset();
  843. var f=this.dom().id;d.left+="number"===typeof window.screenLeft?window.screenLeft:window.screenX+10;d.top+="number"===typeof window.screenTop?window.screenTop:window.screenY+50;if(c=window.open("",f.replace(/-/g,"_"),"left="+d.left+",top="+d.top+",width="+d.width+",height="+(d.height+15)+",resizable=yes,scrollbars=yes"))d=c.document,d.write('<!DOCTYPE html><meta charset="utf-8"><style>'+e("#nette-debug-style").dom().innerHTML+"</style><script>"+e("#nette-debug-script").dom().innerHTML+'<\/script><body id="nette-debug">'),
  844. d.body.innerHTML='<div class="nette-panel nette-mode-window" id="'+f+'">'+this.dom().innerHTML+"</div>",c.Nette.Debug.Panel.factory(f).initToggler().reposition(),d.title=b.find("h1").dom().innerHTML,e([c]).bind("unload",function(){b.toPeek();c.close()}),e(d).bind("keyup",function(a){27===a.keyCode&&!a.shiftKey&&!a.altKey&&!a.ctrlKey&&!a.metaKey&&c.close()}),document.cookie=f+"=window; path=/",this.hide().removeClass(a.FLOAT).removeClass(a.PEEK).addClass(a.WINDOW).data().win=c},init:function(){var b=
  845. this,c;b.data().onmove=function(a){var b=document,c=window.innerWidth||b.documentElement.clientWidth||b.body.clientWidth,b=window.innerHeight||b.documentElement.clientHeight||b.body.clientHeight;a.left=Math.max(Math.min(a.left,0.8*this.offsetWidth),0.2*this.offsetWidth-c);a.top=Math.max(Math.min(a.top,0.8*this.offsetHeight),this.offsetHeight-b)};e(window).bind("resize",function(){b.reposition()});b.draggable({handle:b.find("h1"),stop:function(){b.toFloat()}}).bind("mouseenter",function(){b.focus()}).bind("mouseleave",
  846. function(){b.blur()});this.initToggler();b.find(".nette-icons").find("a").bind("click",function(a){"close"===this.rel?b.toPeek():b.toWindow();a.preventDefault()});(c=document.cookie.match(RegExp(b.dom().id+"=(window|(-?[0-9]+):(-?[0-9]+))")))?c[2]?b.toFloat().position({left:c[2],top:c[3]}):b.toWindow():b.addClass(a.PEEK)},initToggler:function(){var b=this;this.bind("click",function(c){var d=e(c.target).closest("a").dom();d&&d.rel&&(a._toggle(d),c.preventDefault(),b.reposition())});return this}});
  847. Nette.Debug.Bar=Nette.Class({Extends:Nette.Q,constructor:function(){Nette.Q.call(this,"#nette-debug-bar")},init:function(){var b=this,c;b.data().onmove=function(a){var b=document,c=window.innerWidth||b.documentElement.clientWidth||b.body.clientWidth,b=window.innerHeight||b.documentElement.clientHeight||b.body.clientHeight;a.left=Math.max(Math.min(a.left,0),this.offsetWidth-c);a.top=Math.max(Math.min(a.top,0),this.offsetHeight-b)};e(window).bind("resize",function(){b.position(b.position())});b.draggable({draggedClass:"nette-dragged",
  848. stop:function(){document.cookie=b.dom().id+"="+b.position().left+":"+b.position().top+"; path=/"}});b.find("a").bind("click",function(b){if("close"===this.rel)e("#nette-debug").hide(),window.opera&&e("body").show();else if(this.rel){var c=a.factory(this.rel);if(b.shiftKey)c.toFloat().toWindow();else if(c.hasClass(a.FLOAT)){var g=e(this).offset();c.offset({left:g.left-c.position().width+g.width+4,top:g.top-c.position().height-4}).toPeek()}else c.toFloat().position({left:c.position().left-Math.round(100*
  849. Math.random())-20,top:c.position().top-Math.round(100*Math.random())-20}).reposition()}b.preventDefault()}).bind("mouseenter",function(){if(this.rel&&!("close"===this.rel||b.hasClass("nette-dragged"))){var c=a.factory(this.rel);c.focus();if(c.hasClass(a.PEEK)){var f=e(this).offset();c.offset({left:f.left-c.position().width+f.width+4,top:f.top-c.position().height-4})}}}).bind("mouseleave",function(){this.rel&&!("close"===this.rel||b.hasClass("nette-dragged"))&&a.factory(this.rel).blur()});(c=document.cookie.match(RegExp(b.dom().id+
  850. "=(-?[0-9]+):(-?[0-9]+)")))&&b.position({left:c[1],top:c[2]});b.find("a").each(function(){this.rel&&"close"!==this.rel&&a.factory(this.rel).init()})}})})();/*]]>*/</script>
  851. <?php foreach($panels
  852. as$id=>$panel):if(!$panel['panel'])continue;?>
  853. <div class="nette-fixed-coords">
  854. <div class="nette-panel" id="nette-debug-panel-<?php echo$panel['id']?>">
  855. <?php echo$panel['panel']?>
  856. <div class="nette-icons">
  857. <a href="#" title="open in window">&curren;</a>
  858. <a href="#" rel="close" title="close window">&times;</a>
  859. </div>
  860. </div>
  861. </div>
  862. <?php endforeach?>
  863. <div class="nette-fixed-coords">
  864. <div id="nette-debug-bar">
  865. <ul>
  866. <li id="nette-debug-logo" title="PHP <?php echo
  867. htmlSpecialChars(PHP_VERSION." |\n".(isset($_SERVER['SERVER_SOFTWARE'])?$_SERVER['SERVER_SOFTWARE']." |\n":'').(class_exists('Nette\Framework')?'Nette Framework '.Nette\Framework::VERSION.' ('.substr(Nette\Framework::REVISION,8).')':''))?>">&nbsp;<span>Nette Framework</span></li>
  868. <?php foreach($panels
  869. as$panel):if(!$panel['tab'])continue;?>
  870. <li><?php if($panel['panel']):?><a href="#" rel="<?php echo$panel['id']?>"><?php echo
  871. trim($panel['tab'])?></a><?php else:echo'<span>',trim($panel['tab']),'</span>';endif?></li>
  872. <?php endforeach?>
  873. <li><a href="#" rel="close" title="close debug bar">&times;</a></li>
  874. </ul>
  875. </div>
  876. </div>
  877. <?php $output=ob_get_clean();?>
  878. <div id="nette-debug"></div>
  879. <script>
  880. (function(onloadOrig) {
  881. window.onload = function() {
  882. if (typeof onloadOrig === 'function') onloadOrig();
  883. var debug = document.getElementById('nette-debug');
  884. document.body.appendChild(debug);
  885. debug.innerHTML = <?php echo
  886. json_encode(Nette\Utils\Strings::fixEncoding($output))?>;
  887. for (var i = 0, scripts = debug.getElementsByTagName('script'); i < scripts.length; i++) eval(scripts[i].innerHTML);
  888. (new Nette.Debug.Bar).init();
  889. Nette.Q.factory(debug).show();
  890. };
  891. })(window.onload);
  892. </script>
  893. <!-- /Nette Debug Bar -->
  894. <?php }}final
  895. class
  896. DefaultBarPanel
  897. extends
  898. Nette\Object
  899. implements
  900. IBarPanel{private$id;public$data;function
  901. __construct($id){$this->id=$id;}function
  902. getTab(){ob_start();$data=$this->data;if($this->id==='time'){?>
  903. <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"
  904. /><?php echo
  905. number_format((microtime(TRUE)-Debugger::$time)*1000,1,'.',' ')?> ms</span>
  906. <?php }elseif($this->id==='memory'){?>
  907. <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=="
  908. /><?php echo
  909. function_exists('memory_get_peak_usage')?number_format(memory_get_peak_usage()/1000000,2,'.',' '):'n/a';?> MB</span>
  910. <?php }elseif($this->id==='dumps'&&$this->data){?>
  911. <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
  912. <?php }elseif($this->id==='errors'&&$this->data){?>
  913. <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"
  914. /><span class="nette-warning"><?php echo
  915. array_sum($data)?> errors</span>
  916. <?php }return
  917. ob_get_clean();}function
  918. getPanel(){ob_start();$data=$this->data;if($this->id==='dumps'){?>
  919. <style>#nette-debug .nette-DumpPanel h2{font:11pt/1.5 sans-serif;margin:0;padding:2px 8px;background:#3484d2;color:white}#nette-debug .nette-DumpPanel table{width:100%}#nette-debug .nette-DumpPanel a{color:#333;background:transparent}#nette-debug .nette-DumpPanel a abbr{font-family:sans-serif;color:#999}#nette-debug .nette-DumpPanel pre .php-array,#nette-debug .nette-DumpPanel pre .php-object{color:#c16549}</style>
  920. <h1>Dumped variables</h1>
  921. <div class="nette-inner nette-DumpPanel">
  922. <?php foreach($data
  923. as$item):?>
  924. <?php if($item['title']):?>
  925. <h2><?php echo
  926. htmlspecialchars($item['title'])?></h2>
  927. <?php endif?>
  928. <table>
  929. <?php $i=0?>
  930. <?php foreach($item['dump']as$key=>$dump):?>
  931. <tr class="<?php echo$i++%
  932. 2?'nette-alt':''?>">
  933. <th><?php echo
  934. htmlspecialchars($key)?></th>
  935. <td><?php echo$dump?></td>
  936. </tr>
  937. <?php endforeach?>
  938. </table>
  939. <?php endforeach?>
  940. </div>
  941. <?php }elseif($this->id==='errors'){?>
  942. <h1>Errors</h1>
  943. <div class="nette-inner">
  944. <table>
  945. <?php $i=0?>
  946. <?php foreach($data
  947. as$item=>$count):list($message,$file,$line)=explode('|',$item)?>
  948. <tr class="<?php echo$i++%
  949. 2?'nette-alt':''?>">
  950. <td class="nette-right"><?php echo$count?"$count\xC3\x97":''?></td>
  951. <td><pre><?php echo
  952. htmlspecialchars(Nette\Utils\Strings::fixEncoding($message)),' in ',Helpers::editorLink($file,$line),':',$line?></pre></td>
  953. </tr>
  954. <?php endforeach?>
  955. </table>
  956. </div>
  957. <?php }return
  958. ob_get_clean();}}}namespace Nette\Utils{use
  959. Nette;final
  960. class
  961. SafeStream{const
  962. PROTOCOL='safe';private$handle;private$tempHandle;private$file;private$tempFile;private$deleteFile;private$writeError=FALSE;static
  963. function
  964. register(){return
  965. stream_wrapper_register(self::PROTOCOL,__CLASS__);}function
  966. stream_open($path,$mode,$options,&$opened_path){$path=substr($path,strlen(self::PROTOCOL)+3);$flag=trim($mode,'crwax+');$mode=trim($mode,'tb');$use_path=(bool)(STREAM_USE_PATH&$options);if($mode==='r'){return$this->checkAndLock($this->tempHandle=fopen($path,'r'.$flag,$use_path),LOCK_SH);}elseif($mode==='r+'){if(!$this->checkAndLock($this->handle=fopen($path,'r'.$flag,$use_path),LOCK_EX)){return
  967. FALSE;}}elseif($mode[0]==='x'){if(!$this->checkAndLock($this->handle=fopen($path,'x'.$flag,$use_path),LOCK_EX)){return
  968. FALSE;}$this->deleteFile=TRUE;}elseif($mode[0]==='w'||$mode[0]==='a'||$mode[0]==='c'){if($this->checkAndLock($this->handle=@fopen($path,'x'.$flag,$use_path),LOCK_EX)){$this->deleteFile=TRUE;}elseif(!$this->checkAndLock($this->handle=fopen($path,'a+'.$flag,$use_path),LOCK_EX)){return
  969. FALSE;}}else{trigger_error("Unknown mode $mode",E_USER_WARNING);return
  970. FALSE;}$tmp='~~'.lcg_value().'.tmp';if(!$this->tempHandle=fopen($path.$tmp,(strpos($mode,'+')?'x+':'x').$flag,$use_path)){$this->clean();return
  971. FALSE;}$this->tempFile=realpath($path.$tmp);$this->file=substr($this->tempFile,0,-strlen($tmp));if($mode==='r+'||$mode[0]==='a'||$mode[0]==='c'){$stat=fstat($this->handle);fseek($this->handle,0);if($stat['size']!==0&&stream_copy_to_stream($this->handle,$this->tempHandle)!==$stat['size']){$this->clean();return
  972. FALSE;}if($mode[0]==='a'){fseek($this->tempHandle,0,SEEK_END);}}return
  973. TRUE;}private
  974. function
  975. checkAndLock($handle,$lock){if(!$handle){return
  976. FALSE;}elseif(!flock($handle,$lock)){fclose($handle);return
  977. FALSE;}return
  978. TRUE;}private
  979. function
  980. clean(){flock($this->handle,LOCK_UN);fclose($this->handle);if($this->deleteFile){unlink($this->file);}if($this->tempHandle){fclose($this->tempHandle);unlink($this->tempFile);}}function
  981. stream_close(){if(!$this->tempFile){flock($this->tempHandle,LOCK_UN);fclose($this->tempHandle);return;}flock($this->handle,LOCK_UN);fclose($this->handle);fclose($this->tempHandle);if($this->writeError||!rename($this->tempFile,$this->file)){unlink($this->tempFile);if($this->deleteFile){unlink($this->file);}}}function
  982. stream_read($length){return
  983. fread($this->tempHandle,$length);}function
  984. stream_write($data){$len=strlen($data);$res=fwrite($this->tempHandle,$data,$len);if($res!==$len){$this->writeError=TRUE;}return$res;}function
  985. stream_tell(){return
  986. ftell($this->tempHandle);}function
  987. stream_eof(){return
  988. feof($this->tempHandle);}function
  989. stream_seek($offset,$whence){return
  990. fseek($this->tempHandle,$offset,$whence)===0;}function
  991. stream_stat(){return
  992. fstat($this->tempHandle);}function
  993. url_stat($path,$flags){$path=substr($path,strlen(self::PROTOCOL)+3);return($flags&STREAM_URL_STAT_LINK)?@lstat($path):@stat($path);}function
  994. unlink($path){$path=substr($path,strlen(self::PROTOCOL)+3);return
  995. unlink($path);}}}namespace Nette\Application{use
  996. Nette;class
  997. Application
  998. extends
  999. Nette\Object{public
  1000. static$maxLoop=20;public$catchExceptions;public$errorPresenter;public$onStartup;public$onShutdown;public$onRequest;public$onResponse;public$onError;public$allowedMethods;private$requests=array();private$presenter;private$httpRequest;private$httpResponse;private$presenterFactory;private$router;function
  1001. __construct(IPresenterFactory$presenterFactory,IRouter$router,Nette\Http\IRequest$httpRequest,Nette\Http\IResponse$httpResponse){$this->httpRequest=$httpRequest;$this->httpResponse=$httpResponse;$this->presenterFactory=$presenterFactory;$this->router=$router;}function
  1002. run(){$request=NULL;$repeatedError=FALSE;do{try{if(count($this->requests)>self::$maxLoop){throw
  1003. new
  1004. ApplicationException('Too many loops detected in application life cycle.');}if(!$request){$this->onStartup($this);$request=$this->router->match($this->httpRequest);if(!$request
  1005. instanceof
  1006. Request){$request=NULL;throw
  1007. new
  1008. BadRequestException('No route for HTTP request.');}if(strcasecmp($request->getPresenterName(),$this->errorPresenter)===0){throw
  1009. new
  1010. BadRequestException('Invalid request. Presenter is not achievable.');}}$this->requests[]=$request;$this->onRequest($this,$request);$presenterName=$request->getPresenterName();try{$this->presenter=$this->presenterFactory->createPresenter($presenterName);}catch(InvalidPresenterException$e){throw
  1011. new
  1012. BadRequestException($e->getMessage(),404,$e);}$this->presenterFactory->getPresenterClass($presenterName);$request->setPresenterName($presenterName);$request->freeze();$response=$this->presenter->run($request);if($response){$this->onResponse($this,$response);}if($response
  1013. instanceof
  1014. Responses\ForwardResponse){$request=$response->getRequest();continue;}elseif($response
  1015. instanceof
  1016. IResponse){$response->send($this->httpRequest,$this->httpResponse);}break;}catch(\Exception$e){$this->onError($this,$e);if(!$this->catchExceptions){$this->onShutdown($this,$e);throw$e;}if($repeatedError){$e=new
  1017. ApplicationException('An error occurred while executing error-presenter',0,$e);}if(!$this->httpResponse->isSent()){$this->httpResponse->setCode($e
  1018. instanceof
  1019. BadRequestException?$e->getCode():500);}if(!$repeatedError&&$this->errorPresenter){$repeatedError=TRUE;if($this->presenter
  1020. instanceof
  1021. UI\Presenter){try{$this->presenter->forward(":$this->errorPresenter:",array('exception'=>$e));}catch(AbortException$foo){$request=$this->presenter->getLastCreatedRequest();}}else{$request=new
  1022. Request($this->errorPresenter,Request::FORWARD,array('exception'=>$e));}}else{if($e
  1023. instanceof
  1024. BadRequestException){$code=$e->getCode();}else{$code=500;Nette\Diagnostics\Debugger::log($e,Nette\Diagnostics\Debugger::ERROR);}$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];?>
  1025. <!DOCTYPE html>
  1026. <meta charset="utf-8">
  1027. <meta name=robots content=noindex>
  1028. <meta name=generator content="Nette Framework">
  1029. <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>
  1030. <title><?php echo$message[0]?></title>
  1031. <h1><?php echo$message[0]?></h1>
  1032. <p><?php echo$message[1]?></p>
  1033. <?php if($code):?><p><small>error <?php echo$code?></small></p><?php endif?>
  1034. <?php
  1035. break;}}}while(1);$this->onShutdown($this,isset($e)?$e:NULL);}final
  1036. function
  1037. getRequests(){return$this->requests;}final
  1038. function
  1039. getPresenter(){return$this->presenter;}function
  1040. getRouter(){return$this->router;}function
  1041. getPresenterFactory(){return$this->presenterFactory;}function
  1042. storeRequest($expiration='+ 10 minutes'){return$this->presenter->storeRequest($expiration);}function
  1043. restoreRequest($key){return$this->presenter->restoreRequest($key);}}}namespace Nette\Application\Diagnostics{use
  1044. Nette;use
  1045. Nette\Application\Routers;use
  1046. Nette\Application\UI\Presenter;use
  1047. Nette\Diagnostics\Debugger;class
  1048. RoutingPanel
  1049. extends
  1050. Nette\Object
  1051. implements
  1052. Nette\Diagnostics\IBarPanel{private$router;private$httpRequest;private$routers=array();private$request;static
  1053. function
  1054. initializePanel(Nette\Application\Application$application){Debugger::$blueScreen->addPanel(function($e)use($application){return$e?NULL:array('tab'=>'Nette Application','panel'=>'<h3>Requests</h3>'.Nette\Diagnostics\Helpers::clickableDump($application->getRequests()).'<h3>Presenter</h3>'.Nette\Diagnostics\Helpers::clickableDump($application->getPresenter()));});}function
  1055. __construct(Nette\Application\IRouter$router,Nette\Http\IRequest$httpRequest){$this->router=$router;$this->httpRequest=$httpRequest;}function
  1056. getTab(){$this->analyse($this->router);ob_start();?>
  1057. <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"
  1058. /><?php if(empty($this->request)):?>no route<?php else:echo
  1059. htmlSpecialChars($this->request->getPresenterName().':'.(isset($this->request->parameters[Presenter::ACTION_KEY])?$this->request->parameters[Presenter::ACTION_KEY]:Presenter::DEFAULT_ACTION).(isset($this->request->parameters[Presenter::SIGNAL_KEY])?" {$this->request->parameters[Presenter::SIGNAL_KEY]}!":''));endif?>
  1060. <?php
  1061. return
  1062. ob_get_clean();}function
  1063. getPanel(){ob_start();?>
  1064. <style>#nette-debug .nette-RoutingPanel table{font:9pt/1.5 Consolas,monospace}#nette-debug .nette-RoutingPanel .yes td{color:green}#nette-debug .nette-RoutingPanel .may td{color:#67F}#nette-debug .nette-RoutingPanel pre,#nette-debug .nette-RoutingPanel code{display:inline}#nette-debug .nette-RoutingPanel code .nette-collapsed{display:none}</style>
  1065. <div class="nette-RoutingPanel">
  1066. <h1>
  1067. <?php if(empty($this->request)):?>
  1068. no route
  1069. <?php else:?>
  1070. <?php echo
  1071. htmlSpecialChars($this->request->getPresenterName().':'.(isset($this->request->parameters[Presenter::ACTION_KEY])?$this->request->parameters[Presenter::ACTION_KEY]:Presenter::DEFAULT_ACTION).(isset($this->request->parameters[Presenter::SIGNAL_KEY])?" {$this->request->parameters[Presenter::SIGNAL_KEY]}!":''))?>
  1072. <?php endif?>
  1073. </h1>
  1074. <?php if(!empty($this->request)):?>
  1075. <?php $params=$this->request->getParameters()?>
  1076. <?php if(empty($params)):?>
  1077. <p>No parameters.</p>
  1078. <?php else:?>
  1079. <table>
  1080. <thead>
  1081. <tr>
  1082. <th>Parameter</th>
  1083. <th>Value</th>
  1084. </tr>
  1085. </thead>
  1086. <tbody>
  1087. <?php unset($params[Presenter::ACTION_KEY],$params[Presenter::SIGNAL_KEY])?>
  1088. <?php foreach($params
  1089. as$key=>$value):?>
  1090. <tr>
  1091. <td><code><?php echo
  1092. htmlSpecialChars($key)?></code></td>
  1093. <td><?php if(is_string($value)):?><code><?php echo
  1094. htmlSpecialChars($value)?></code><?php else:echo
  1095. Debugger::dump($value,TRUE);endif?></td>
  1096. </tr>
  1097. <?php endforeach?>
  1098. </tbody>
  1099. </table>
  1100. <?php endif?>
  1101. <?php endif?>
  1102. <h2>Routers</h2>
  1103. <?php if(empty($this->routers)):?>
  1104. <p>No routers defined.</p>
  1105. <?php else:?>
  1106. <div class="nette-inner">
  1107. <table>
  1108. <thead>
  1109. <tr>
  1110. <th>Matched?</th>
  1111. <th>Class</th>
  1112. <th>Mask</th>
  1113. <th>Defaults</th>
  1114. <th>Module</th>
  1115. <th>Request</th>
  1116. </tr>
  1117. </thead>
  1118. <tbody>
  1119. <?php foreach($this->routers
  1120. as$router):?>
  1121. <tr class="<?php echo$router['matched']?>">
  1122. <td><?php echo$router['matched']?></td>
  1123. <td><code title="<?php echo
  1124. htmlSpecialChars($router['class'])?>"><?php echo
  1125. preg_replace('#.+\\\\#','',htmlSpecialChars($router['class']))?></code></td>
  1126. <td><code><strong><?php echo
  1127. htmlSpecialChars($router['mask'])?></strong></code></td>
  1128. <td><code>
  1129. <?php foreach($router['defaults']as$key=>$value):?>
  1130. <?php echo
  1131. htmlSpecialChars($key),"&nbsp;=&nbsp;",is_string($value)?htmlSpecialChars($value):str_replace("\n</pre",'</pre',Nette\Diagnostics\Helpers::clickableDump($value,TRUE))?><br />
  1132. <?php endforeach?>
  1133. </code></td>
  1134. <td><code><?php echo
  1135. htmlSpecialChars($router['module'])?></code></td>
  1136. <td><?php if($router['request']):?><code>
  1137. <?php $params=$router['request']->getParameters();?>
  1138. <strong><?php echo
  1139. htmlSpecialChars($router['request']->getPresenterName().':'.(isset($params[Presenter::ACTION_KEY])?$params[Presenter::ACTION_KEY]:Presenter::DEFAULT_ACTION))?></strong><br />
  1140. <?php unset($params[Presenter::ACTION_KEY])?>
  1141. <?php foreach($params
  1142. as$key=>$value):?>
  1143. <?php echo
  1144. htmlSpecialChars($key),"&nbsp;=&nbsp;",is_string($value)?htmlSpecialChars($value):str_replace("\n</pre",'</pre',Nette\Diagnostics\Helpers::clickableDump($value,TRUE))?><br />
  1145. <?php endforeach?>
  1146. </code><?php endif?></td>
  1147. </tr>
  1148. <?php endforeach?>
  1149. </tbody>
  1150. </table>
  1151. </div>
  1152. <?php endif?>
  1153. </div>
  1154. <?php
  1155. return
  1156. ob_get_clean();}private
  1157. function
  1158. analyse($router,$module=''){if($router
  1159. instanceof
  1160. Routers\RouteList){foreach($router
  1161. as$subRouter){$this->analyse($subRouter,$module.$router->getModule());}return;}$matched='no';$request=$router->match($this->httpRequest);if($request){$request->setPresenterName($module.$request->getPresenterName());$matched='may';if(empty($this->request)){$this->request=$request;$matched='yes';}}$this->routers[]=array('matched'=>$matched,'class'=>get_class($router),'defaults'=>$router
  1162. instanceof
  1163. Routers\Route||$router
  1164. instanceof
  1165. Routers\SimpleRouter?$router->getDefaults():array(),'mask'=>$router
  1166. instanceof
  1167. Routers\Route?$router->getMask():NULL,'request'=>$request,'module'=>rtrim($module,':'));}}}namespace Nette\Application{use
  1168. Nette;class
  1169. AbortException
  1170. extends\Exception{}class
  1171. ApplicationException
  1172. extends\Exception{}class
  1173. InvalidPresenterException
  1174. extends\Exception{}class
  1175. BadRequestException
  1176. extends\Exception{protected$defaultCode=404;function
  1177. __construct($message='',$code=0,\Exception$previous=NULL){if($code<200||$code>504){$code=$this->defaultCode;}{parent::__construct($message,$code,$previous);}}}class
  1178. ForbiddenRequestException
  1179. extends
  1180. BadRequestException{protected$defaultCode=403;}}namespace NetteModule{use
  1181. Nette;use
  1182. Nette\Application;use
  1183. Nette\Application\Responses;use
  1184. Nette\Http;class
  1185. MicroPresenter
  1186. extends
  1187. Nette\Object
  1188. implements
  1189. Application\IPresenter{private$context;private$request;function
  1190. __construct(Nette\DI\Container$context){$this->context=$context;}final
  1191. function
  1192. getContext(){return$this->context;}function
  1193. run(Application\Request$request){$this->request=$request;$httpRequest=$this->context->getByType('Nette\Http\IRequest');if(!$httpRequest->isAjax()&&($request->isMethod('get')||$request->isMethod('head'))){$refUrl=clone$httpRequest->getUrl();$url=$this->context->router->constructUrl($request,$refUrl->setPath($refUrl->getScriptPath()));if($url!==NULL&&!$httpRequest->getUrl()->isEqual($url)){return
  1194. new
  1195. Responses\RedirectResponse($url,Http\IResponse::S301_MOVED_PERMANENTLY);}}$params=$request->getParameters();if(!isset($params['callback'])){throw
  1196. new
  1197. Application\BadRequestException("Parameter callback is missing.");}$params['presenter']=$this;$callback=new
  1198. Nette\Callback($params['callback']);$response=$callback->invokeArgs(Application\UI\PresenterComponentReflection::combineArgs($callback->toReflection(),$params));if(is_string($response)){$response=array($response,array());}if(is_array($response)){if($response[0]instanceof\SplFileInfo){$response=$this->createTemplate('Nette\Templating\FileTemplate')->setParameters($response[1])->setFile($response[0]);}else{$response=$this->createTemplate('Nette\Templating\Template')->setParameters($response[1])->setSource($response[0]);}}if($response
  1199. instanceof
  1200. Nette\Templating\ITemplate){return
  1201. new
  1202. Responses\TextResponse($response);}else{return$response;}}function
  1203. createTemplate($class=NULL,$latteFactory=NULL){$template=$class?new$class:new
  1204. Nette\Templating\FileTemplate;$template->setParameters($this->request->getParameters());$template->presenter=$this;$template->context=$context=$this->context;$url=$context->getByType('Nette\Http\IRequest')->getUrl();$template->baseUrl=rtrim($url->getBaseUrl(),'/');$template->basePath=rtrim($url->getBasePath(),'/');$template->registerHelperLoader('Nette\Templating\Helpers::loader');$template->setCacheStorage($context->nette->templateCacheStorage);$template->onPrepareFilters[]=function($template)use($latteFactory,$context){$template->registerFilter($latteFactory?$latteFactory():new
  1205. Nette\Latte\Engine);};return$template;}function
  1206. redirectUrl($url,$code=Http\IResponse::S302_FOUND){return
  1207. new
  1208. Responses\RedirectResponse($url,$code);}function
  1209. error($message=NULL,$code=Http\IResponse::S404_NOT_FOUND){throw
  1210. new
  1211. Application\BadRequestException($message,$code);}function
  1212. getRequest(){return$this->request;}}}namespace Nette\Application{use
  1213. Nette;class
  1214. PresenterFactory
  1215. implements
  1216. IPresenterFactory{public$caseSensitive=FALSE;private$baseDir;private$cache=array();private$container;function
  1217. __construct($baseDir,Nette\DI\Container$container){$this->baseDir=$baseDir;$this->container=$container;}function
  1218. createPresenter($name){$presenter=$this->container->createInstance($this->getPresenterClass($name));if(method_exists($presenter,'setContext')){$this->container->callMethod(array($presenter,'setContext'));}foreach(array_reverse(get_class_methods($presenter))as$method){if(substr($method,0,6)==='inject'){$this->container->callMethod(array($presenter,$method));}}if($presenter
  1219. instanceof
  1220. UI\Presenter&&$presenter->invalidLinkMode===NULL){$presenter->invalidLinkMode=$this->container->parameters['debugMode']?UI\Presenter::INVALID_LINK_WARNING:UI\Presenter::INVALID_LINK_SILENT;}return$presenter;}function
  1221. getPresenterClass(&$name){if(isset($this->cache[$name])){list($class,$name)=$this->cache[$name];return$class;}if(!is_string($name)||!Nette\Utils\Strings::match($name,'#^[a-zA-Z\x7f-\xff][a-zA-Z0-9\x7f-\xff:]*\z#')){throw
  1222. new
  1223. 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)){Nette\Utils\LimitedScope::load($file,TRUE);}if(!class_exists($class)){throw
  1224. new
  1225. InvalidPresenterException("Cannot load presenter '$name', class '$class' was not found in '$file'.");}}$reflection=new
  1226. Nette\Reflection\ClassType($class);$class=$reflection->getName();if(!$reflection->implementsInterface('Nette\Application\IPresenter')){throw
  1227. new
  1228. InvalidPresenterException("Cannot load presenter '$name', class '$class' is not Nette\\Application\\IPresenter implementor.");}if($reflection->isAbstract()){throw
  1229. new
  1230. InvalidPresenterException("Cannot load presenter '$name', class '$class' is abstract.");}$realName=$this->unformatPresenterClass($class);if($name!==$realName){if($this->caseSensitive){throw
  1231. new
  1232. 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
  1233. formatPresenterClass($presenter){return
  1234. str_replace(':','Module\\',$presenter).'Presenter';}function
  1235. unformatPresenterClass($class){return
  1236. str_replace('Module\\',':',substr($class,0,-9));}function
  1237. formatPresenterFile($presenter){$path='/'.str_replace(':','Module/',$presenter);return$this->baseDir.substr_replace($path,'/presenters',strrpos($path,'/'),0).'Presenter.php';}}}namespace Nette{use
  1238. Nette;abstract
  1239. class
  1240. FreezableObject
  1241. extends
  1242. Object
  1243. implements
  1244. IFreezable{private$frozen=FALSE;function
  1245. freeze(){$this->frozen=TRUE;}final
  1246. function
  1247. isFrozen(){return$this->frozen;}function
  1248. __clone(){$this->frozen=FALSE;}protected
  1249. function
  1250. updating(){if($this->frozen){$class=get_class($this);throw
  1251. new
  1252. InvalidStateException("Cannot modify a frozen object $class.");}}}}namespace Nette\Application{use
  1253. Nette;final
  1254. class
  1255. Request
  1256. extends
  1257. Nette\FreezableObject{const
  1258. FORWARD='FORWARD';const
  1259. SECURED='secured';const
  1260. RESTORED='restored';private$method;private$flags=array();private$name;private$params;private$post;private$files;function
  1261. __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
  1262. setPresenterName($name){$this->updating();$this->name=$name;return$this;}function
  1263. getPresenterName(){return$this->name;}function
  1264. setParameters(array$params){$this->updating();$this->params=$params;return$this;}function
  1265. getParameters(){return$this->params;}function
  1266. setParams(array$params){trigger_error(__METHOD__.'() is deprecated; use setParameters() instead.',E_USER_WARNING);return$this->setParameters($params);}function
  1267. getParams(){trigger_error(__METHOD__.'() is deprecated; use getParameters() instead.',E_USER_WARNING);return$this->getParameters();}function
  1268. setPost(array$params){$this->updating();$this->post=$params;return$this;}function
  1269. getPost(){return$this->post;}function
  1270. setFiles(array$files){$this->updating();$this->files=$files;return$this;}function
  1271. getFiles(){return$this->files;}function
  1272. setMethod($method){$this->method=$method;return$this;}function
  1273. getMethod(){return$this->method;}function
  1274. isMethod($method){return
  1275. strcasecmp($this->method,$method)===0;}function
  1276. isPost(){return
  1277. strcasecmp($this->method,'post')===0;}function
  1278. setFlag($flag,$value=TRUE){$this->updating();$this->flags[$flag]=(bool)$value;return$this;}function
  1279. hasFlag($flag){return!empty($this->flags[$flag]);}}}namespace Nette\Application\Responses{use
  1280. Nette;class
  1281. FileResponse
  1282. extends
  1283. Nette\Object
  1284. implements
  1285. Nette\Application\IResponse{private$file;private$contentType;private$name;public$resuming=TRUE;function
  1286. __construct($file,$name=NULL,$contentType=NULL){if(!is_file($file)){throw
  1287. new
  1288. Nette\Application\BadRequestException("File '$file' doesn't exist.");}$this->file=$file;$this->name=$name?$name:basename($file);$this->contentType=$contentType?$contentType:'application/octet-stream';}final
  1289. function
  1290. getFile(){return$this->file;}final
  1291. function
  1292. getName(){return$this->name;}final
  1293. function
  1294. getContentType(){return$this->contentType;}function
  1295. send(Nette\Http\IRequest$httpRequest,Nette\Http\IResponse$httpResponse){$httpResponse->setContentType($this->contentType);$httpResponse->setHeader('Content-Disposition','attachment; filename="'.$this->name.'"');$filesize=$length=filesize($this->file);$handle=fopen($this->file,'r');if($this->resuming){$httpResponse->setHeader('Accept-Ranges','bytes');if(preg_match('#^bytes=(\d*)-(\d*)\z#',$httpRequest->getHeader('Range'),$matches)){list(,$start,$end)=$matches;if($start===''){$start=max(0,$filesize-$end);$end=$filesize-1;}elseif($end===''||$end>$filesize-1){$end=$filesize-1;}if($end<$start){$httpResponse->setCode(416);return;}$httpResponse->setCode(206);$httpResponse->setHeader('Content-Range','bytes '.$start.'-'.$end.'/'.$filesize);$length=$end-$start+1;fseek($handle,$start);}else{$httpResponse->setHeader('Content-Range','bytes 0-'.($filesize-1).'/'.$filesize);}}$httpResponse->setHeader('Content-Length',$length);while(!feof($handle)&&$length>0){echo$s=fread($handle,min(4e6,$length));$length-=strlen($s);}fclose($handle);}}class
  1296. ForwardResponse
  1297. extends
  1298. Nette\Object
  1299. implements
  1300. Nette\Application\IResponse{private$request;function
  1301. __construct(Nette\Application\Request$request){$this->request=$request;}final
  1302. function
  1303. getRequest(){return$this->request;}function
  1304. send(Nette\Http\IRequest$httpRequest,Nette\Http\IResponse$httpResponse){}}class
  1305. JsonResponse
  1306. extends
  1307. Nette\Object
  1308. implements
  1309. Nette\Application\IResponse{private$payload;private$contentType;function
  1310. __construct($payload,$contentType=NULL){if(!is_array($payload)&&!is_object($payload)){throw
  1311. new
  1312. Nette\InvalidArgumentException("Payload must be array or object class, ".gettype($payload)." given.");}$this->payload=$payload;$this->contentType=$contentType?$contentType:'application/json';}final
  1313. function
  1314. getPayload(){return$this->payload;}final
  1315. function
  1316. getContentType(){return$this->contentType;}function
  1317. send(Nette\Http\IRequest$httpRequest,Nette\Http\IResponse$httpResponse){$httpResponse->setContentType($this->contentType);$httpResponse->setExpiration(FALSE);echo
  1318. Nette\Utils\Json::encode($this->payload);}}use
  1319. Nette\Http;class
  1320. RedirectResponse
  1321. extends
  1322. Nette\Object
  1323. implements
  1324. Nette\Application\IResponse{private$url;private$code;function
  1325. __construct($url,$code=Http\IResponse::S302_FOUND){$this->url=(string)$url;$this->code=(int)$code;}final
  1326. function
  1327. getUrl(){return$this->url;}final
  1328. function
  1329. getCode(){return$this->code;}function
  1330. send(Http\IRequest$httpRequest,Http\IResponse$httpResponse){$httpResponse->redirect($this->url,$this->code);}}class
  1331. TextResponse
  1332. extends
  1333. Nette\Object
  1334. implements
  1335. Nette\Application\IResponse{private$source;function
  1336. __construct($source){$this->source=$source;}final
  1337. function
  1338. getSource(){return$this->source;}function
  1339. send(Nette\Http\IRequest$httpRequest,Nette\Http\IResponse$httpResponse){if($this->source
  1340. instanceof
  1341. Nette\Templating\ITemplate){$this->source->render();}else{echo$this->source;}}}}namespace Nette\Application\Routers{use
  1342. Nette;use
  1343. Nette\Application;class
  1344. CliRouter
  1345. extends
  1346. Nette\Object
  1347. implements
  1348. Application\IRouter{const
  1349. PRESENTER_KEY='action';private$defaults;function
  1350. __construct($defaults=array()){$this->defaults=$defaults;}function
  1351. match(Nette\Http\IRequest$httpRequest){if(empty($_SERVER['argv'])||!is_array($_SERVER['argv'])){return
  1352. NULL;}$names=array(self::PRESENTER_KEY);$params=$this->defaults;$args=$_SERVER['argv'];array_shift($args);$args[]='--';foreach($args
  1353. 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
  1354. new
  1355. Nette\InvalidStateException('Missing presenter & action in route definition.');}$presenter=$params[self::PRESENTER_KEY];if($a=strrpos($presenter,':')){$params[self::PRESENTER_KEY]=substr($presenter,$a+1);$presenter=substr($presenter,0,$a);}return
  1356. new
  1357. Application\Request($presenter,'CLI',$params);}function
  1358. constructUrl(Application\Request$appRequest,Nette\Http\Url$refUrl){return
  1359. NULL;}function
  1360. getDefaults(){return$this->defaults;}}use
  1361. Nette\Utils\Strings;class
  1362. Route
  1363. extends
  1364. Nette\Object
  1365. implements
  1366. Application\IRouter{const
  1367. PRESENTER_KEY='presenter';const
  1368. MODULE_KEY='module';const
  1369. CASE_SENSITIVE=256;const
  1370. HOST=1,PATH=2,RELATIVE=3;const
  1371. VALUE='value';const
  1372. PATTERN='pattern';const
  1373. FILTER_IN='filterIn';const
  1374. FILTER_OUT='filterOut';const
  1375. FILTER_TABLE='filterTable';const
  1376. FILTER_STRICT='filterStrict';const
  1377. OPTIONAL=0,PATH_OPTIONAL=1,CONSTANT=2;public
  1378. static$defaultFlags=0;public
  1379. static$styles=array('#'=>array(self::PATTERN=>'[^/]+',self::FILTER_IN=>'rawurldecode',self::FILTER_OUT=>array(__CLASS__,'param2path')),'?#'=>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
  1380. __construct($mask,$metadata=array(),$flags=0){if(is_string($metadata)){$a=strrpos($metadata,':');if(!$a){throw
  1381. new
  1382. Nette\InvalidArgumentException("Second argument must be array or string in format Presenter:action, '$metadata' given.");}$metadata=array(self::PRESENTER_KEY=>substr($metadata,0,$a),'action'=>$a===strlen($metadata)-1?NULL:substr($metadata,$a+1));}elseif($metadata
  1383. instanceof\Closure||$metadata
  1384. instanceof
  1385. Nette\Callback){$metadata=array(self::PRESENTER_KEY=>'Nette:Micro','callback'=>$metadata);}$this->flags=$flags|static::$defaultFlags;$this->setMask($mask,$metadata);}function
  1386. match(Nette\Http\IRequest$httpRequest){$url=$httpRequest->getUrl();if($this->type===self::HOST){$path='//'.$url->getHost().$url->getPath();}elseif($this->type===self::RELATIVE){$basePath=$url->getBasePath();if(strncmp($url->getPath(),$basePath,strlen($basePath))!==0){return
  1387. NULL;}$path=(string)substr($url->getPath(),strlen($basePath));}else{$path=$url->getPath();}if($path!==''){$path=rtrim($path,'/').'/';}if(!$matches=Strings::match($path,$this->re)){return
  1388. NULL;}$params=array();foreach($matches
  1389. as$k=>$v){if(is_string($k)&&$v!==''){$params[str_replace('___','-',$k)]=$v;}}foreach($this->metadata
  1390. 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
  1391. 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_TABLE])&&!empty($meta[self::FILTER_STRICT])){return
  1392. NULL;}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
  1393. NULL;}}}elseif(isset($meta['fixity'])){$params[$name]=$meta[self::VALUE];}}if(!isset($params[self::PRESENTER_KEY])){throw
  1394. new
  1395. Nette\InvalidStateException('Missing presenter in route definition.');}if(isset($this->metadata[self::MODULE_KEY])){if(!isset($params[self::MODULE_KEY])){throw
  1396. new
  1397. Nette\InvalidStateException('Missing module in route definition.');}$presenter=$params[self::MODULE_KEY].':'.$params[self::PRESENTER_KEY];unset($params[self::MODULE_KEY],$params[self::PRESENTER_KEY]);}else{$presenter=$params[self::PRESENTER_KEY];unset($params[self::PRESENTER_KEY]);}return
  1398. new
  1399. Application\Request($presenter,$httpRequest->getMethod(),$params,$httpRequest->getPost(),$httpRequest->getFiles(),array(Application\Request::SECURED=>$httpRequest->isSecured()));}function
  1400. constructUrl(Application\Request$appRequest,Nette\Http\Url$refUrl){if($this->flags&self::ONE_WAY){return
  1401. NULL;}$params=$appRequest->getParameters();$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
  1402. as$name=>$meta){if(!isset($params[$name])){continue;}if(isset($meta['fixity'])){if($params[$name]===FALSE){$params[$name]='0';}if(is_scalar($params[$name])?strcasecmp($params[$name],$meta[self::VALUE])===0:$params[$name]===$meta[self::VALUE]){unset($params[$name]);continue;}elseif($meta['fixity']===self::CONSTANT){return
  1403. NULL;}}if(!is_scalar($params[$name])){}elseif(isset($meta['filterTable2'][$params[$name]])){$params[$name]=$meta['filterTable2'][$params[$name]];}elseif(isset($meta['filterTable2'])&&!empty($meta[self::FILTER_STRICT])){return
  1404. NULL;}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
  1405. NULL;}}$sequence=$this->sequence;$brackets=array();$required=NULL;$url='';$i=count($sequence)-1;do{$url=$sequence[$i].$url;if($i===0){break;}$i--;$name=$sequence[$i];$i--;if($name===']'){$brackets[]=$url;}elseif($name[0]==='['){$tmp=array_pop($brackets);if($required<count($brackets)+1){if($name!=='[!'){$url=$tmp;}}else{$required=count($brackets);}}elseif($name[0]==='?'){continue;}elseif(isset($params[$name])&&$params[$name]!=''){$required=count($brackets);$url=$params[$name].$url;unset($params[$name]);}elseif(isset($metadata[$name]['fixity'])){if($required===NULL&&!$brackets){$url='';}else{$url=$metadata[$name]['defOut'].$url;}}else{return
  1406. 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!=''){$url.='?'.$query;}if($this->type===self::RELATIVE){$url='//'.$refUrl->getAuthority().$refUrl->getBasePath().$url;}elseif($this->type===self::PATH){$url='//'.$refUrl->getAuthority().$url;}if(strpos($url,'//',2)!==FALSE){return
  1407. NULL;}$url=($this->flags&self::SECURED?'https:':'http:').$url;return$url;}private
  1408. function
  1409. 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
  1410. 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=Strings::split($mask,'/<([^>#= ]+)(=[^># ]*)? *([^>#]*)(#?[^>\[\]]*)>|(\[!?|\]|\s*\?.*)/');$this->xlat=array();$i=count($parts)-1;if(isset($parts[$i-1])&&substr(ltrim($parts[$i-1]),0,1)==='?'){$matches=Strings::matchAll($parts[$i-1],'/(?:([a-zA-Z0-9_.-]+)=)?<([^># ]+) *([^>#]*)(#?[^>]*)>/');foreach($matches
  1411. as$match){list(,$param,$name,$pattern,$class)=$match;if($class!==''){if(!isset(static::$styles[$class])){throw
  1412. new
  1413. Nette\InvalidStateException("Parameter '$name' has '$class' flag, but Route::\$styles['$class'] is not set.");}$meta=static::$styles[$class];}elseif(isset(static::$styles['?'.$name])){$meta=static::$styles['?'.$name];}else{$meta=static::$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-=6;}$brackets=0;$re='';$sequence=array();$autoOptional=TRUE;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
  1414. new
  1415. Nette\InvalidArgumentException("Unexpected '$part' in mask '$mask'.");}array_unshift($sequence,$part);$re=($part[0]==='['?'(?:':')?').$re;$i-=5;continue;}$class=$parts[$i];$i--;$pattern=trim($parts[$i]);$i--;$default=$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
  1416. new
  1417. Nette\InvalidArgumentException("Parameter name must be alphanumeric string due to limitations of PCRE, '$name' given.");}if($class!==''){if(!isset(static::$styles[$class])){throw
  1418. new
  1419. Nette\InvalidStateException("Parameter '$name' has '$class' flag, but Route::\$styles['$class'] is not set.");}$meta=static::$styles[$class];}elseif(isset(static::$styles[$name])){$meta=static::$styles[$name];}else{$meta=static::$styles['#'];}if(isset($metadata[$name])){$meta=$metadata[$name]+$meta;}if($pattern==''&&isset($meta[self::PATTERN])){$pattern=$meta[self::PATTERN];}if($default!==''){$meta[self::VALUE]=(string)substr($default,1);$meta['fixity']=self::PATH_OPTIONAL;}$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)\\z#A".($this->flags&self::CASE_SENSITIVE?'':'iu');$re='(?P<'.str_replace('-','___',$name).'>(?U)'.$pattern.')'.$re;if($brackets){if(!isset($meta[self::VALUE])){$meta[self::VALUE]=$meta['defOut']=NULL;}$meta['fixity']=self::PATH_OPTIONAL;}elseif(!$autoOptional){unset($meta['fixity']);}elseif(isset($meta['fixity'])){$re='(?:'.$re.')?';$meta['fixity']=self::PATH_OPTIONAL;}else{$autoOptional=FALSE;}$metadata[$name]=$meta;}while(TRUE);if($brackets){throw
  1420. new
  1421. Nette\InvalidArgumentException("Missing closing ']' in mask '$mask'.");}$this->re='#'.$re.'/?\z#A'.($this->flags&self::CASE_SENSITIVE?'':'iu');$this->metadata=$metadata;$this->sequence=$sequence;}function
  1422. getMask(){return$this->mask;}function
  1423. getDefaults(){$defaults=array();foreach($this->metadata
  1424. as$name=>$meta){if(isset($meta['fixity'])){$defaults[$name]=$meta[self::VALUE];}}return$defaults;}function
  1425. getFlags(){return$this->flags;}function
  1426. getTargetPresenter(){if($this->flags&self::ONE_WAY){return
  1427. 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
  1428. NULL;}}if(isset($m[self::PRESENTER_KEY]['fixity'])&&$m[self::PRESENTER_KEY]['fixity']===self::CONSTANT){return$module.$m[self::PRESENTER_KEY][self::VALUE];}return
  1429. NULL;}private
  1430. static
  1431. function
  1432. renameKeys($arr,$xlat){if(empty($xlat)){return$arr;}$res=array();$occupied=array_flip($xlat);foreach($arr
  1433. as$k=>$v){if(isset($xlat[$k])){$res[$xlat[$k]]=$v;}elseif(!isset($occupied[$k])){$res[$k]=$v;}}return$res;}private
  1434. static
  1435. function
  1436. action2path($s){$s=preg_replace('#(.)(?=[A-Z])#','$1-',$s);$s=strtolower($s);$s=rawurlencode($s);return$s;}private
  1437. static
  1438. function
  1439. path2action($s){$s=strtolower($s);$s=preg_replace('#-(?=[a-z])#',' ',$s);$s=substr(ucwords('x'.$s),1);$s=str_replace(' ','',$s);return$s;}private
  1440. static
  1441. function
  1442. presenter2path($s){$s=strtr($s,':','.');$s=preg_replace('#([^.])(?=[A-Z])#','$1-',$s);$s=strtolower($s);$s=rawurlencode($s);return$s;}private
  1443. static
  1444. function
  1445. 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;}private
  1446. static
  1447. function
  1448. param2path($s){return
  1449. str_replace('%2F','/',rawurlencode($s));}static
  1450. function
  1451. addStyle($style,$parent='#'){if(isset(static::$styles[$style])){throw
  1452. new
  1453. Nette\InvalidArgumentException("Style '$style' already exists.");}if($parent!==NULL){if(!isset(static::$styles[$parent])){throw
  1454. new
  1455. Nette\InvalidArgumentException("Parent style '$parent' doesn't exist.");}static::$styles[$style]=static::$styles[$parent];}else{static::$styles[$style]=array();}}static
  1456. function
  1457. setStyleProperty($style,$key,$value){if(!isset(static::$styles[$style])){throw
  1458. new
  1459. Nette\InvalidArgumentException("Style '$style' doesn't exist.");}static::$styles[$style][$key]=$value;}}}namespace Nette{use
  1460. Nette;class
  1461. ArrayList
  1462. extends
  1463. Object
  1464. implements\ArrayAccess,\Countable,\IteratorAggregate{private$list=array();function
  1465. getIterator(){return
  1466. new\ArrayIterator($this->list);}function
  1467. count(){return
  1468. count($this->list);}function
  1469. offsetSet($index,$value){if($index===NULL){$this->list[]=$value;}elseif($index<0||$index>=count($this->list)){throw
  1470. new
  1471. OutOfRangeException("Offset invalid or out of range");}else{$this->list[(int)$index]=$value;}}function
  1472. offsetGet($index){if($index<0||$index>=count($this->list)){throw
  1473. new
  1474. OutOfRangeException("Offset invalid or out of range");}return$this->list[(int)$index];}function
  1475. offsetExists($index){return$index>=0&&$index<count($this->list);}function
  1476. offsetUnset($index){if($index<0||$index>=count($this->list)){throw
  1477. new
  1478. OutOfRangeException("Offset invalid or out of range");}array_splice($this->list,(int)$index,1);}}}namespace Nette\Application\Routers{use
  1479. Nette;class
  1480. RouteList
  1481. extends
  1482. Nette\ArrayList
  1483. implements
  1484. Nette\Application\IRouter{private$cachedRoutes;private$module;function
  1485. __construct($module=NULL){$this->module=$module?$module.':':'';}function
  1486. match(Nette\Http\IRequest$httpRequest){foreach($this
  1487. as$route){$appRequest=$route->match($httpRequest);if($appRequest!==NULL){$appRequest->setPresenterName($this->module.$appRequest->getPresenterName());return$appRequest;}}return
  1488. NULL;}function
  1489. constructUrl(Nette\Application\Request$appRequest,Nette\Http\Url$refUrl){if($this->cachedRoutes===NULL){$routes=array();$routes['*']=array();foreach($this
  1490. as$route){$presenter=$route
  1491. instanceof
  1492. 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
  1493. as$id=>$foo){$routes[$id][]=$route;}}}$this->cachedRoutes=$routes;}if($this->module){if(strncasecmp($tmp=$appRequest->getPresenterName(),$this->module,strlen($this->module))===0){$appRequest=clone$appRequest;$appRequest->setPresenterName(substr($tmp,strlen($this->module)));}else{return
  1494. NULL;}}$presenter=strtolower($appRequest->getPresenterName());if(!isset($this->cachedRoutes[$presenter])){$presenter='*';}foreach($this->cachedRoutes[$presenter]as$route){$url=$route->constructUrl($appRequest,$refUrl);if($url!==NULL){return$url;}}return
  1495. NULL;}function
  1496. offsetSet($index,$route){if(!$route
  1497. instanceof
  1498. Nette\Application\IRouter){throw
  1499. new
  1500. Nette\InvalidArgumentException("Argument must be IRouter descendant.");}parent::offsetSet($index,$route);}function
  1501. getModule(){return$this->module;}}use
  1502. Nette\Application;class
  1503. SimpleRouter
  1504. extends
  1505. Nette\Object
  1506. implements
  1507. Application\IRouter{const
  1508. PRESENTER_KEY='presenter';const
  1509. MODULE_KEY='module';private$module='';private$defaults;private$flags;function
  1510. __construct($defaults=array(),$flags=0){if(is_string($defaults)){$a=strrpos($defaults,':');if(!$a){throw
  1511. new
  1512. Nette\InvalidArgumentException("Argument must be array or string in format Presenter:action, '$defaults' given.");}$defaults=array(self::PRESENTER_KEY=>substr($defaults,0,$a),'action'=>$a===strlen($defaults)-1?Application\UI\Presenter::DEFAULT_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
  1513. match(Nette\Http\IRequest$httpRequest){if($httpRequest->getUrl()->getPathInfo()!==''){return
  1514. NULL;}$params=$httpRequest->getQuery();$params+=$this->defaults;if(!isset($params[self::PRESENTER_KEY])){throw
  1515. new
  1516. Nette\InvalidStateException('Missing presenter.');}$presenter=$this->module.$params[self::PRESENTER_KEY];unset($params[self::PRESENTER_KEY]);return
  1517. new
  1518. Application\Request($presenter,$httpRequest->getMethod(),$params,$httpRequest->getPost(),$httpRequest->getFiles(),array(Application\Request::SECURED=>$httpRequest->isSecured()));}function
  1519. constructUrl(Application\Request$appRequest,Nette\Http\Url$refUrl){if($this->flags&self::ONE_WAY){return
  1520. NULL;}$params=$appRequest->getParameters();$presenter=$appRequest->getPresenterName();if(strncasecmp($presenter,$this->module,strlen($this->module))===0){$params[self::PRESENTER_KEY]=substr($presenter,strlen($this->module));}else{return
  1521. NULL;}foreach($this->defaults
  1522. as$key=>$value){if(isset($params[$key])&&$params[$key]==$value){unset($params[$key]);}}$url=($this->flags&self::SECURED?'https://':'http://').$refUrl->getAuthority().$refUrl->getPath();$sep=ini_get('arg_separator.input');$query=http_build_query($params,'',$sep?$sep[0]:'&');if($query!=''){$url.='?'.$query;}return$url;}function
  1523. getDefaults(){return$this->defaults;}function
  1524. getFlags(){return$this->flags;}}}namespace Nette\Application\UI{use
  1525. Nette;class
  1526. BadSignalException
  1527. extends
  1528. Nette\Application\BadRequestException{protected$defaultCode=403;}}namespace Nette\ComponentModel{use
  1529. Nette;abstract
  1530. class
  1531. Component
  1532. extends
  1533. Nette\Object
  1534. implements
  1535. IComponent{private$parent;private$name;private$monitors=array();function
  1536. __construct(IContainer$parent=NULL,$name=NULL){if($parent!==NULL){$parent->addComponent($this,$name);}elseif(is_string($name)){$this->name=$name;}}function
  1537. 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
  1538. 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
  1539. new
  1540. Nette\InvalidStateException("Component '$this->name' is not attached to '$type'.");}return$this->monitors[$type][0];}function
  1541. lookupPath($type,$need=TRUE){$this->lookup($type,$need);return$this->monitors[$type][2];}function
  1542. monitor($type){if(empty($this->monitors[$type][3])){if($obj=$this->lookup($type,FALSE)){$this->attached($obj);}$this->monitors[$type][3]=TRUE;}}function
  1543. unmonitor($type){unset($this->monitors[$type]);}protected
  1544. function
  1545. attached($obj){}protected
  1546. function
  1547. detached($obj){}final
  1548. function
  1549. getName(){return$this->name;}final
  1550. function
  1551. getParent(){return$this->parent;}function
  1552. setParent(IContainer$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
  1553. new
  1554. Nette\InvalidStateException("Component '$this->name' already has a parent.");}if($parent===NULL){$this->refreshMonitors(0);$this->parent=NULL;}else{$this->validateParent($parent);$this->parent=$parent;if($name!==NULL){$this->name=$name;}$tmp=array();$this->refreshMonitors(0,$tmp);}return$this;}protected
  1555. function
  1556. validateParent(IContainer$parent){}private
  1557. function
  1558. refreshMonitors($depth,&$missing=NULL,&$listeners=array()){if($this
  1559. instanceof
  1560. IContainer){foreach($this->getComponents()as$component){if($component
  1561. instanceof
  1562. Component){$component->refreshMonitors($depth+1,$missing,$listeners);}}}if($missing===NULL){foreach($this->monitors
  1563. 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
  1564. 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
  1565. as$item){$item[0]->$method($item[1]);}}}function
  1566. __clone(){if($this->parent===NULL){return;}elseif($this->parent
  1567. instanceof
  1568. Container){$this->parent=$this->parent->_isCloning();if($this->parent===NULL){$this->refreshMonitors(0);}}else{$this->parent=NULL;$this->refreshMonitors(0);}}final
  1569. function
  1570. __sleep(){throw
  1571. new
  1572. Nette\NotImplementedException('Object serialization is not supported by class '.get_class($this));}final
  1573. function
  1574. __wakeup(){throw
  1575. new
  1576. Nette\NotImplementedException('Object unserialization is not supported by class '.get_class($this));}}class
  1577. Container
  1578. extends
  1579. Component
  1580. implements
  1581. IContainer{private$components=array();private$cloning;function
  1582. addComponent(IComponent$component,$name,$insertBefore=NULL){if($name===NULL){$name=$component->getName();}if(is_int($name)){$name=(string)$name;}elseif(!is_string($name)){throw
  1583. new
  1584. Nette\InvalidArgumentException("Component name must be integer or string, ".gettype($name)." given.");}elseif(!preg_match('#^[a-zA-Z0-9_]+\z#',$name)){throw
  1585. new
  1586. Nette\InvalidArgumentException("Component name must be non-empty alphanumeric string, '$name' given.");}if(isset($this->components[$name])){throw
  1587. new
  1588. Nette\InvalidStateException("Component with name '$name' already exists.");}$obj=$this;do{if($obj===$component){throw
  1589. new
  1590. Nette\InvalidStateException("Circular reference detected while adding component '$name'.");}$obj=$obj->getParent();}while($obj!==NULL);$this->validateChildComponent($component);try{if(isset($this->components[$insertBefore])){$tmp=array();foreach($this->components
  1591. 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;}return$this;}function
  1592. removeComponent(IComponent$component){$name=$component->getName();if(!isset($this->components[$name])||$this->components[$name]!==$component){throw
  1593. new
  1594. Nette\InvalidArgumentException("Component named '$name' is not located in this container.");}unset($this->components[$name]);$component->setParent(NULL);}final
  1595. function
  1596. getComponent($name,$need=TRUE){if(is_int($name)){$name=(string)$name;}elseif(!is_string($name)){throw
  1597. new
  1598. Nette\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
  1599. new
  1600. Nette\InvalidArgumentException("Component or subcomponent name must not be empty string.");}}if(!isset($this->components[$name])){$component=$this->createComponent($name);if($component
  1601. instanceof
  1602. 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
  1603. IContainer){return$this->components[$name]->getComponent($ext,$need);}elseif($need){throw
  1604. new
  1605. Nette\InvalidArgumentException("Component with name '$name' is not container and cannot have '$ext' component.");}}elseif($need){throw
  1606. new
  1607. Nette\InvalidArgumentException("Component with name '$name' does not exist.");}}protected
  1608. function
  1609. createComponent($name){$ucname=ucfirst($name);$method='createComponent'.$ucname;if($ucname!==$name&&method_exists($this,$method)&&$this->getReflection()->getMethod($method)->getName()===$method){$component=$this->$method($name);if(!$component
  1610. instanceof
  1611. IComponent&&!isset($this->components[$name])){$class=get_class($this);throw
  1612. new
  1613. Nette\UnexpectedValueException("Method $class::$method() did not return or create the desired component.");}return$component;}}final
  1614. function
  1615. getComponents($deep=FALSE,$filterType=NULL){$iterator=new
  1616. RecursiveComponentIterator($this->components);if($deep){$deep=$deep>0?\RecursiveIteratorIterator::SELF_FIRST:\RecursiveIteratorIterator::CHILD_FIRST;$iterator=new\RecursiveIteratorIterator($iterator,$deep);}if($filterType){$iterator=new
  1617. Nette\Iterators\InstanceFilter($iterator,$filterType);}return$iterator;}protected
  1618. function
  1619. validateChildComponent(IComponent$child){}function
  1620. __clone(){if($this->components){$oldMyself=reset($this->components)->getParent();$oldMyself->cloning=$this;foreach($this->components
  1621. as$name=>$component){$this->components[$name]=clone$component;}$oldMyself->cloning=NULL;}parent::__clone();}function
  1622. _isCloning(){return$this->cloning;}}}namespace Nette\Application\UI{use
  1623. Nette;abstract
  1624. class
  1625. PresenterComponent
  1626. extends
  1627. Nette\ComponentModel\Container
  1628. implements
  1629. ISignalReceiver,IStatePersistent,\ArrayAccess{protected$params=array();function
  1630. getPresenter($need=TRUE){return$this->lookup('Nette\Application\UI\Presenter',$need);}function
  1631. getUniqueId(){return$this->lookupPath('Nette\Application\UI\Presenter',TRUE);}protected
  1632. function
  1633. attached($presenter){if($presenter
  1634. instanceof
  1635. Presenter){$this->loadState($presenter->popGlobalParameters($this->getUniqueId()));}}protected
  1636. function
  1637. validateParent(Nette\ComponentModel\IContainer$parent){parent::validateParent($parent);$this->monitor('Nette\Application\UI\Presenter');}protected
  1638. function
  1639. tryCall($method,array$params){$rc=$this->getReflection();if($rc->hasMethod($method)){$rm=$rc->getMethod($method);if($rm->isPublic()&&!$rm->isAbstract()&&!$rm->isStatic()){$this->checkRequirements($rm);$rm->invokeArgs($this,$rc->combineArgs($rm,$params));return
  1640. TRUE;}}return
  1641. FALSE;}function
  1642. checkRequirements($element){}static
  1643. function
  1644. getReflection(){return
  1645. new
  1646. PresenterComponentReflection(get_called_class());}function
  1647. loadState(array$params){$reflection=$this->getReflection();foreach($reflection->getPersistentParams()as$name=>$meta){if(isset($params[$name])){$type=gettype($meta['def']===NULL?$params[$name]:$meta['def']);if(!$reflection->convertType($params[$name],$type)){throw
  1648. new
  1649. Nette\Application\BadRequestException("Invalid value for persistent parameter '$name' in '{$this->getName()}', expected ".($type==='NULL'?'scalar':$type).".");}$this->$name=&$params[$name];}else{$params[$name]=&$this->$name;}}$this->params=$params;}function
  1650. saveState(array&$params,$reflection=NULL){$reflection=$reflection===NULL?$this->getReflection():$reflection;foreach($reflection->getPersistentParams()as$name=>$meta){if(isset($params[$name])){}elseif(array_key_exists($name,$params)){continue;}elseif(!isset($meta['since'])||$this
  1651. instanceof$meta['since']){$params[$name]=$this->$name;}else{continue;}$type=gettype($meta['def']===NULL?$params[$name]:$meta['def']);if(!PresenterComponentReflection::convertType($params[$name],$type)){throw
  1652. new
  1653. InvalidLinkException("Invalid value for persistent parameter '$name' in '{$this->getName()}', expected ".($type==='NULL'?'scalar':$type).".");}if($params[$name]===$meta['def']||($meta['def']===NULL&&is_scalar($params[$name])&&(string)$params[$name]==='')){$params[$name]=NULL;}}}final
  1654. function
  1655. getParameter($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
  1656. function
  1657. getParameterId($name){$uid=$this->getUniqueId();return$uid===''?$name:$uid.self::NAME_SEPARATOR.$name;}function
  1658. getParam($name=NULL,$default=NULL){return
  1659. func_num_args()?$this->getParameter($name,$default):$this->getParameter();}function
  1660. getParamId($name){trigger_error(__METHOD__.'() is deprecated; use getParameterId() instead.',E_USER_WARNING);return$this->getParameterId($name);}static
  1661. function
  1662. getPersistentParams(){$rc=new
  1663. Nette\Reflection\ClassType(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
  1664. signalReceived($signal){if(!$this->tryCall($this->formatSignalMethod($signal),$this->params)){$class=get_class($this);throw
  1665. new
  1666. BadSignalException("There is no handler for signal '$signal' in class $class.");}}function
  1667. formatSignalMethod($signal){return$signal==NULL?NULL:'handle'.$signal;}function
  1668. 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
  1669. lazyLink($destination,$args=array()){if(!is_array($args)){$args=func_get_args();array_shift($args);}return
  1670. new
  1671. Link($this,$destination,$args);}function
  1672. isLinkCurrent($destination=NULL,$args=array()){if($destination!==NULL){if(!is_array($args)){$args=func_get_args();array_shift($args);}$this->getPresenter()->createRequest($this,$destination,$args,'test');}return$this->getPresenter()->getLastCreatedRequestFlag('current');}function
  1673. 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->redirectUrl($presenter->createRequest($this,$destination,$args,'redirect'),$code);}final
  1674. function
  1675. offsetSet($name,$component){$this->addComponent($component,$name);}final
  1676. function
  1677. offsetGet($name){return$this->getComponent($name,TRUE);}final
  1678. function
  1679. offsetExists($name){return$this->getComponent($name,FALSE)!==NULL;}final
  1680. function
  1681. offsetUnset($name){$component=$this->getComponent($name,FALSE);if($component!==NULL){$this->removeComponent($component);}}}abstract
  1682. class
  1683. Control
  1684. extends
  1685. PresenterComponent
  1686. implements
  1687. IRenderable{private$template;private$invalidSnippets=array();public$snippetMode;final
  1688. function
  1689. getTemplate(){if($this->template===NULL){$value=$this->createTemplate();if(!$value
  1690. instanceof
  1691. Nette\Templating\ITemplate&&$value!==NULL){$class2=get_class($value);$class=get_class($this);throw
  1692. new
  1693. Nette\UnexpectedValueException("Object returned by $class::createTemplate() must be instance of Nette\\Templating\\ITemplate, '$class2' given.");}$this->template=$value;}return$this->template;}protected
  1694. function
  1695. createTemplate($class=NULL){$template=$class?new$class:new
  1696. Nette\Templating\FileTemplate;$presenter=$this->getPresenter(FALSE);$template->onPrepareFilters[]=$this->templatePrepareFilters;$template->registerHelperLoader('Nette\Templating\Helpers::loader');$template->control=$template->_control=$this;$template->presenter=$template->_presenter=$presenter;if($presenter
  1697. instanceof
  1698. Presenter){$template->setCacheStorage($presenter->getContext()->nette->templateCacheStorage);$template->user=$presenter->getUser();$template->netteHttpResponse=$presenter->getHttpResponse();$template->netteCacheStorage=$presenter->getContext()->getByType('Nette\Caching\IStorage');$template->baseUri=$template->baseUrl=rtrim($presenter->getHttpRequest()->getUrl()->getBaseUrl(),'/');$template->basePath=preg_replace('#https?://[^/]+#A','',$template->baseUrl);if($presenter->hasFlashSession()){$id=$this->getParameterId('flash');$template->flashes=$presenter->getFlashSession()->$id;}}if(!isset($template->flashes)||!is_array($template->flashes)){$template->flashes=array();}return$template;}function
  1699. templatePrepareFilters($template){$template->registerFilter($this->getPresenter()->getContext()->nette->createLatte());}function
  1700. getWidget($name){trigger_error(__METHOD__.'() is deprecated, use getComponent() instead.',E_USER_WARNING);return$this->getComponent($name);}function
  1701. flashMessage($message,$type='info'){$id=$this->getParameterId('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
  1702. invalidateControl($snippet=NULL){$this->invalidSnippets[$snippet]=TRUE;}function
  1703. validateControl($snippet=NULL){if($snippet===NULL){$this->invalidSnippets=array();}else{unset($this->invalidSnippets[$snippet]);}}function
  1704. isControlInvalid($snippet=NULL){if($snippet===NULL){if(count($this->invalidSnippets)>0){return
  1705. TRUE;}else{$queue=array($this);do{foreach(array_shift($queue)->getComponents()as$component){if($component
  1706. instanceof
  1707. IRenderable){if($component->isControlInvalid()){return
  1708. TRUE;}}elseif($component
  1709. instanceof
  1710. Nette\ComponentModel\IContainer){$queue[]=$component;}}}while($queue);return
  1711. FALSE;}}else{return
  1712. isset($this->invalidSnippets[NULL])||isset($this->invalidSnippets[$snippet]);}}function
  1713. getSnippetId($name=NULL){return'snippet-'.$this->getUniqueId().'-'.$name;}}}namespace Nette\Forms{use
  1714. Nette;class
  1715. Container
  1716. extends
  1717. Nette\ComponentModel\Container
  1718. implements\ArrayAccess{public$onValidate;protected$currentGroup;protected$valid;function
  1719. setDefaults($values,$erase=FALSE){$form=$this->getForm(FALSE);if(!$form||!$form->isAnchored()||!$form->isSubmitted()){$this->setValues($values,$erase);}return$this;}function
  1720. setValues($values,$erase=FALSE){if($values
  1721. instanceof\Traversable){$values=iterator_to_array($values);}elseif(!is_array($values)){throw
  1722. new
  1723. Nette\InvalidArgumentException("First parameter must be an array, ".gettype($values)." given.");}foreach($this->getComponents()as$name=>$control){if($control
  1724. instanceof
  1725. IControl){if(array_key_exists($name,$values)){$control->setValue($values[$name]);}elseif($erase){$control->setValue(NULL);}}elseif($control
  1726. instanceof
  1727. Container){if(array_key_exists($name,$values)){$control->setValues($values[$name],$erase);}elseif($erase){$control->setValues(array(),$erase);}}}return$this;}function
  1728. getValues($asArray=FALSE){$values=$asArray?array():new
  1729. Nette\ArrayHash;foreach($this->getComponents()as$name=>$control){if($control
  1730. instanceof
  1731. IControl&&!$control->isDisabled()&&!$control
  1732. instanceof
  1733. ISubmitterControl){$values[$name]=$control->getValue();}elseif($control
  1734. instanceof
  1735. Container){$values[$name]=$control->getValues($asArray);}}return$values;}function
  1736. isValid(){if($this->valid===NULL){$this->validate();}return$this->valid;}function
  1737. validate(){$this->valid=TRUE;foreach($this->getControls()as$control){if(!$control->getRules()->validate()){$this->valid=FALSE;}}$this->onValidate($this);}function
  1738. setCurrentGroup(ControlGroup$group=NULL){$this->currentGroup=$group;return$this;}function
  1739. getCurrentGroup(){return$this->currentGroup;}function
  1740. addComponent(Nette\ComponentModel\IComponent$component,$name,$insertBefore=NULL){parent::addComponent($component,$name,$insertBefore);if($this->currentGroup!==NULL&&$component
  1741. instanceof
  1742. IControl){$this->currentGroup->add($component);}return$this;}function
  1743. getControls(){return$this->getComponents(TRUE,'Nette\Forms\IControl');}function
  1744. getForm($need=TRUE){return$this->lookup('Nette\Forms\Form',$need);}function
  1745. addText($name,$label=NULL,$cols=NULL,$maxLength=NULL){return$this[$name]=new
  1746. Controls\TextInput($label,$cols,$maxLength);}function
  1747. addPassword($name,$label=NULL,$cols=NULL,$maxLength=NULL){$control=new
  1748. Controls\TextInput($label,$cols,$maxLength);$control->setType('password');return$this[$name]=$control;}function
  1749. addTextArea($name,$label=NULL,$cols=40,$rows=10){return$this[$name]=new
  1750. Controls\TextArea($label,$cols,$rows);}function
  1751. addUpload($name,$label=NULL){return$this[$name]=new
  1752. Controls\UploadControl($label);}function
  1753. addHidden($name,$default=NULL){$control=new
  1754. Controls\HiddenField;$control->setDefaultValue($default);return$this[$name]=$control;}function
  1755. addCheckbox($name,$caption=NULL){return$this[$name]=new
  1756. Controls\Checkbox($caption);}function
  1757. addRadioList($name,$label=NULL,array$items=NULL){return$this[$name]=new
  1758. Controls\RadioList($label,$items);}function
  1759. addSelect($name,$label=NULL,array$items=NULL,$size=NULL){return$this[$name]=new
  1760. Controls\SelectBox($label,$items,$size);}function
  1761. addMultiSelect($name,$label=NULL,array$items=NULL,$size=NULL){return$this[$name]=new
  1762. Controls\MultiSelectBox($label,$items,$size);}function
  1763. addSubmit($name,$caption=NULL){return$this[$name]=new
  1764. Controls\SubmitButton($caption);}function
  1765. addButton($name,$caption){return$this[$name]=new
  1766. Controls\Button($caption);}function
  1767. addImage($name,$src=NULL,$alt=NULL){return$this[$name]=new
  1768. Controls\ImageButton($src,$alt);}function
  1769. addContainer($name){$control=new
  1770. Container;$control->currentGroup=$this->currentGroup;return$this[$name]=$control;}final
  1771. function
  1772. offsetSet($name,$component){$this->addComponent($component,$name);}final
  1773. function
  1774. offsetGet($name){return$this->getComponent($name,TRUE);}final
  1775. function
  1776. offsetExists($name){return$this->getComponent($name,FALSE)!==NULL;}final
  1777. function
  1778. offsetUnset($name){$component=$this->getComponent($name,FALSE);if($component!==NULL){$this->removeComponent($component);}}final
  1779. function
  1780. __clone(){throw
  1781. new
  1782. Nette\NotImplementedException('Form cloning is not supported yet.');}function
  1783. addFile($name,$label=NULL){trigger_error(__METHOD__.'() is deprecated; use addUpload() instead.',E_USER_WARNING);return$this->addUpload($name,$label);}}class
  1784. Form
  1785. extends
  1786. Container{const
  1787. EQUAL=':equal',IS_IN=':equal',FILLED=':filled',VALID=':valid';const
  1788. PROTECTION='Nette\Forms\Controls\HiddenField::validateEqual';const
  1789. SUBMITTED=':submitted';const
  1790. MIN_LENGTH=':minLength',MAX_LENGTH=':maxLength',LENGTH=':length',EMAIL=':email',URL=':url',REGEXP=':regexp',PATTERN=':pattern',INTEGER=':integer',NUMERIC=':integer',FLOAT=':float',RANGE=':range';const
  1791. COUNT=':length';const
  1792. MAX_FILE_SIZE=':fileSize',MIME_TYPE=':mimeType',IMAGE=':image';const
  1793. GET='get',POST='post';const
  1794. TRACKER_ID='_form_';const
  1795. PROTECTOR_ID='_token_';public$onSuccess;public$onError;public$onSubmit;public$onInvalidSubmit;private$submittedBy;private$httpData;private$element;private$renderer;private$translator;private$groups=array();private$errors=array();function
  1796. __construct($name=NULL){$this->element=Nette\Utils\Html::el('form');$this->element->action='';$this->element->method=self::POST;$this->element->id=$name===NULL?NULL:'frm-'.$name;$this->monitor(__CLASS__);if($name!==NULL){$tracker=new
  1797. Controls\HiddenField($name);$tracker->unmonitor(__CLASS__);$this[self::TRACKER_ID]=$tracker;}parent::__construct(NULL,$name);}protected
  1798. function
  1799. attached($obj){if($obj
  1800. instanceof
  1801. self){throw
  1802. new
  1803. Nette\InvalidStateException('Nested forms are forbidden.');}}final
  1804. function
  1805. getForm($need=TRUE){return$this;}function
  1806. setAction($url){$this->element->action=$url;return$this;}function
  1807. getAction(){return$this->element->action;}function
  1808. setMethod($method){if($this->httpData!==NULL){throw
  1809. new
  1810. Nette\InvalidStateException(__METHOD__.'() must be called until the form is empty.');}$this->element->method=strtolower($method);return$this;}function
  1811. getMethod(){return$this->element->method;}function
  1812. addProtection($message=NULL,$timeout=NULL){$session=$this->getSession()->getSection('Nette.Forms.Form/CSRF');$key="key$timeout";if(isset($session->$key)){$token=$session->$key;}else{$session->$key=$token=Nette\Utils\Strings::random();}$session->setExpiration($timeout,$key);$this[self::PROTECTOR_ID]=new
  1813. Controls\HiddenField($token);$this[self::PROTECTOR_ID]->addRule(self::PROTECTION,$message,$token);}function
  1814. addGroup($caption=NULL,$setAsCurrent=TRUE){$group=new
  1815. ControlGroup;$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
  1816. removeGroup($name){if(is_string($name)&&isset($this->groups[$name])){$group=$this->groups[$name];}elseif($name
  1817. instanceof
  1818. ControlGroup&&in_array($name,$this->groups,TRUE)){$group=$name;$name=array_search($group,$this->groups,TRUE);}else{throw
  1819. new
  1820. Nette\InvalidArgumentException("Group not found in form '$this->name'");}foreach($group->getControls()as$control){$control->getParent()->removeComponent($control);}unset($this->groups[$name]);}function
  1821. getGroups(){return$this->groups;}function
  1822. getGroup($name){return
  1823. isset($this->groups[$name])?$this->groups[$name]:NULL;}function
  1824. setTranslator(Nette\Localization\ITranslator$translator=NULL){$this->translator=$translator;return$this;}final
  1825. function
  1826. getTranslator(){return$this->translator;}function
  1827. isAnchored(){return
  1828. TRUE;}final
  1829. function
  1830. isSubmitted(){if($this->submittedBy===NULL&&count($this->getControls())){$this->submittedBy=(bool)$this->getHttpData();}return$this->submittedBy;}final
  1831. function
  1832. isSuccess(){return$this->isSubmitted()&&$this->isValid();}function
  1833. setSubmittedBy(ISubmitterControl$by=NULL){$this->submittedBy=$by===NULL?FALSE:$by;return$this;}final
  1834. function
  1835. getHttpData(){if($this->httpData===NULL){if(!$this->isAnchored()){throw
  1836. new
  1837. Nette\InvalidStateException('Form is not anchored and therefore can not determine whether it was submitted.');}$this->httpData=$this->receiveHttpData();}return$this->httpData;}function
  1838. fireEvents(){if(!$this->isSubmitted()){return;}elseif($this->submittedBy
  1839. instanceof
  1840. ISubmitterControl){if(!$this->submittedBy->getValidationScope()||$this->isValid()){$this->submittedBy->click();$valid=TRUE;}else{$this->submittedBy->onInvalidClick($this->submittedBy);}}if(isset($valid)||$this->isValid()){$this->onSuccess($this);}else{$this->onError($this);if($this->onInvalidSubmit){trigger_error(__CLASS__.'->onInvalidSubmit is deprecated; use onError instead.',E_USER_WARNING);$this->onInvalidSubmit($this);}}if($this->onSuccess){$this->onSubmit($this);}elseif($this->onSubmit){trigger_error(__CLASS__.'->onSubmit changed its behavior; use onSuccess instead.',E_USER_WARNING);if(isset($valid)||$this->isValid()){$this->onSubmit($this);}}}protected
  1841. function
  1842. receiveHttpData(){$httpRequest=$this->getHttpRequest();if(strcasecmp($this->getMethod(),$httpRequest->getMethod())){return
  1843. array();}if($httpRequest->isMethod('post')){$data=Nette\Utils\Arrays::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
  1844. array();}}return$data;}function
  1845. getValues($asArray=FALSE){$values=parent::getValues($asArray);unset($values[self::TRACKER_ID],$values[self::PROTECTOR_ID]);return$values;}function
  1846. addError($message){$this->valid=FALSE;if($message!==NULL&&!in_array($message,$this->errors,TRUE)){$this->errors[]=$message;}}function
  1847. getErrors(){return$this->errors;}function
  1848. hasErrors(){return(bool)$this->getErrors();}function
  1849. cleanErrors(){$this->errors=array();$this->valid=NULL;}function
  1850. getElementPrototype(){return$this->element;}function
  1851. setRenderer(IFormRenderer$renderer){$this->renderer=$renderer;return$this;}final
  1852. function
  1853. getRenderer(){if($this->renderer===NULL){$this->renderer=new
  1854. Rendering\DefaultFormRenderer;}return$this->renderer;}function
  1855. render(){$args=func_get_args();array_unshift($args,$this);echo
  1856. call_user_func_array(array($this->getRenderer(),'render'),$args);}function
  1857. __toString(){try{return$this->getRenderer()->render($this);}catch(\Exception$e){if(func_get_args()&&func_get_arg(0)){throw$e;}else{trigger_error("Exception in ".__METHOD__."(): {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}",E_USER_ERROR);}}}protected
  1858. function
  1859. getHttpRequest(){return
  1860. Nette\Environment::getHttpRequest();}protected
  1861. function
  1862. getSession(){return
  1863. Nette\Environment::getSession();}}}namespace Nette\Application\UI{use
  1864. Nette;class
  1865. Form
  1866. extends
  1867. Nette\Forms\Form
  1868. implements
  1869. ISignalReceiver{function
  1870. __construct(Nette\ComponentModel\IContainer$parent=NULL,$name=NULL){parent::__construct();$this->monitor('Nette\Application\UI\Presenter');if($parent!==NULL){$parent->addComponent($this,$name);}}function
  1871. getPresenter($need=TRUE){return$this->lookup('Nette\Application\UI\Presenter',$need);}protected
  1872. function
  1873. attached($presenter){if($presenter
  1874. instanceof
  1875. Presenter){$name=$this->lookupPath('Nette\Application\UI\Presenter');if(!isset($this->getElementPrototype()->id)){$this->getElementPrototype()->id='frm-'.$name;}$this->setAction(new
  1876. Link($presenter,$name.self::NAME_SEPARATOR.'submit!',array()));if($this->isSubmitted()){foreach($this->getControls()as$control){if(!$control->isDisabled()){$control->loadHttpData();}}}}parent::attached($presenter);}function
  1877. isAnchored(){return(bool)$this->getPresenter(FALSE);}protected
  1878. function
  1879. 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
  1880. Nette\Utils\Arrays::mergeTree($request->getPost(),$request->getFiles());}else{return$request->getParameters();}}function
  1881. signalReceived($signal){if($signal==='submit'){if(!$this->getPresenter()->getRequest()->hasFlag(Nette\Application\Request::RESTORED)){$this->fireEvents();}}else{$class=get_class($this);throw
  1882. new
  1883. BadSignalException("Missing handler for signal '$signal' in $class.");}}}class
  1884. InvalidLinkException
  1885. extends\Exception{}class
  1886. Link
  1887. extends
  1888. Nette\Object{private$component;private$destination;private$params;function
  1889. __construct(PresenterComponent$component,$destination,array$params){$this->component=$component;$this->destination=$destination;$this->params=$params;}function
  1890. getDestination(){return$this->destination;}function
  1891. setParameter($key,$value){$this->params[$key]=$value;return$this;}function
  1892. getParameter($key){return
  1893. isset($this->params[$key])?$this->params[$key]:NULL;}function
  1894. getParameters(){return$this->params;}function
  1895. __toString(){try{return(string)$this->component->link($this->destination,$this->params);}catch(\Exception$e){trigger_error("Exception in ".__METHOD__."(): {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}",E_USER_ERROR);}}}class
  1896. Multiplier
  1897. extends
  1898. PresenterComponent{private$factory;function
  1899. __construct($factory){parent::__construct();$this->factory=new
  1900. Nette\Callback($factory);}protected
  1901. function
  1902. createComponent($name){return$this->factory->invoke($name,$this);}}use
  1903. Nette\Application;use
  1904. Nette\Application\Responses;use
  1905. Nette\Http;use
  1906. Nette\Reflection;abstract
  1907. class
  1908. Presenter
  1909. extends
  1910. Control
  1911. implements
  1912. Application\IPresenter{const
  1913. INVALID_LINK_SILENT=1,INVALID_LINK_WARNING=2,INVALID_LINK_EXCEPTION=3;const
  1914. SIGNAL_KEY='do',ACTION_KEY='action',FLASH_KEY='_fid',DEFAULT_ACTION='default';public$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;private$context;function
  1915. __construct(Nette\DI\Container$context=NULL){$this->context=$context;if($context&&$this->invalidLinkMode===NULL){$this->invalidLinkMode=$context->parameters['productionMode']?self::INVALID_LINK_SILENT:self::INVALID_LINK_WARNING;}}final
  1916. function
  1917. getRequest(){return$this->request;}final
  1918. function
  1919. getPresenter($need=TRUE){return$this;}final
  1920. function
  1921. getUniqueId(){return'';}function
  1922. run(Application\Request$request){try{$this->request=$request;$this->payload=new\stdClass;$this->setParent($this->getParent(),$request->getPresenterName());$this->initGlobalParameters();$this->checkRequirements($this->getReflection());$this->startup();if(!$this->startupCheck){$class=$this->getReflection()->getMethod('startup')->getDeclaringClass()->getName();throw
  1923. new
  1924. Nette\InvalidStateException("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(Application\AbortException$e){if($this->isAjax())try{$hasPayload=(array)$this->payload;unset($hasPayload['state']);if($this->response
  1925. instanceof
  1926. Responses\TextResponse&&$this->isControlInvalid()){$this->snippetMode=TRUE;$this->response->send($this->getHttpRequest(),$this->getHttpResponse());$this->sendPayload();}elseif(!$this->response&&$hasPayload){$this->sendPayload();}}catch(Application\AbortException$e){}if($this->hasFlashSession()){$this->getFlashSession()->setExpiration($this->response
  1927. instanceof
  1928. Responses\RedirectResponse?'+ 30 seconds':'+ 3 seconds');}$this->onShutdown($this,$this->response);$this->shutdown($this->response);return$this->response;}}protected
  1929. function
  1930. startup(){$this->startupCheck=TRUE;}protected
  1931. function
  1932. beforeRender(){}protected
  1933. function
  1934. afterRender(){}protected
  1935. function
  1936. shutdown($response){}function
  1937. checkRequirements($element){$user=(array)$element->getAnnotation('User');if(in_array('loggedIn',$user)&&!$this->getUser()->isLoggedIn()){throw
  1938. new
  1939. Application\ForbiddenRequestException;}}function
  1940. processSignal(){if($this->signal===NULL){return;}try{$component=$this->signalReceiver===''?$this:$this->getComponent($this->signalReceiver,FALSE);}catch(Nette\InvalidArgumentException$e){}if(isset($e)||$component===NULL){throw
  1941. new
  1942. BadSignalException("The signal receiver component '$this->signalReceiver' is not found.",NULL,isset($e)?$e:NULL);}elseif(!$component
  1943. instanceof
  1944. ISignalReceiver){throw
  1945. new
  1946. BadSignalException("The signal receiver component '$this->signalReceiver' is not ISignalReceiver implementor.");}$component->signalReceived($this->signal);$this->signal=NULL;}final
  1947. function
  1948. getSignal(){return$this->signal===NULL?NULL:array($this->signalReceiver,$this->signal);}final
  1949. function
  1950. isSignalReceiver($component,$signal=NULL){if($component
  1951. instanceof
  1952. Nette\ComponentModel\Component){$component=$component===$this?'':$component->lookupPath(__CLASS__,TRUE);}if($this->signal===NULL){return
  1953. 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
  1954. function
  1955. getAction($fullyQualified=FALSE){return$fullyQualified?':'.$this->getName().':'.$this->action:$this->action;}function
  1956. changeAction($action){if(is_string($action)&&Nette\Utils\Strings::match($action,'#^[a-zA-Z0-9][a-zA-Z0-9_\x7f-\xff]*\z#')){$this->action=$action;$this->view=$action;}else{$this->error('Action name is not alphanumeric string.');}}final
  1957. function
  1958. getView(){return$this->view;}function
  1959. setView($view){$this->view=(string)$view;return$this;}final
  1960. function
  1961. getLayout(){return$this->layout;}function
  1962. setLayout($layout){$this->layout=$layout===FALSE?FALSE:(string)$layout;return$this;}function
  1963. sendTemplate(){$template=$this->getTemplate();if(!$template){return;}if($template
  1964. instanceof
  1965. Nette\Templating\IFileTemplate&&!$template->getFile()){$files=$this->formatTemplateFiles();foreach($files
  1966. as$file){if(is_file($file)){$template->setFile($file);break;}}if(!$template->getFile()){$file=preg_replace('#^.*([/\\\\].{1,70})\z#U',"\xE2\x80\xA6\$1",reset($files));$file=strtr($file,'/',DIRECTORY_SEPARATOR);$this->error("Page not found. Missing template '$file'.");}}$this->sendResponse(new
  1967. Responses\TextResponse($template));}function
  1968. findLayoutTemplateFile(){if($this->layout===FALSE){return;}$files=$this->formatLayoutTemplateFiles();foreach($files
  1969. as$file){if(is_file($file)){return$file;}}if($this->layout){$file=preg_replace('#^.*([/\\\\].{1,70})\z#U',"\xE2\x80\xA6\$1",reset($files));$file=strtr($file,'/',DIRECTORY_SEPARATOR);throw
  1970. new
  1971. Nette\FileNotFoundException("Layout not found. Missing template '$file'.");}}function
  1972. formatLayoutTemplateFiles(){$name=$this->getName();$presenter=substr($name,strrpos(':'.$name,':'));$layout=$this->layout?$this->layout:'layout';$dir=dirname($this->getReflection()->getFileName());$dir=is_dir("$dir/templates")?$dir:dirname($dir);$list=array("$dir/templates/$presenter/@$layout.latte","$dir/templates/$presenter.@$layout.latte","$dir/templates/$presenter/@$layout.phtml","$dir/templates/$presenter.@$layout.phtml");do{$list[]="$dir/templates/@$layout.latte";$list[]="$dir/templates/@$layout.phtml";$dir=dirname($dir);}while($dir&&($name=substr($name,0,strrpos($name,':'))));return$list;}function
  1973. formatTemplateFiles(){$name=$this->getName();$presenter=substr($name,strrpos(':'.$name,':'));$dir=dirname($this->getReflection()->getFileName());$dir=is_dir("$dir/templates")?$dir:dirname($dir);return
  1974. array("$dir/templates/$presenter/$this->view.latte","$dir/templates/$presenter.$this->view.latte","$dir/templates/$presenter/$this->view.phtml","$dir/templates/$presenter.$this->view.phtml");}protected
  1975. static
  1976. function
  1977. formatActionMethod($action){return'action'.$action;}protected
  1978. static
  1979. function
  1980. formatRenderMethod($view){return'render'.$view;}function
  1981. getPayload(){return$this->payload;}function
  1982. isAjax(){if($this->ajaxMode===NULL){$this->ajaxMode=$this->getHttpRequest()->isAjax();}return$this->ajaxMode;}function
  1983. sendPayload(){$this->sendResponse(new
  1984. Responses\JsonResponse($this->payload));}function
  1985. sendResponse(Application\IResponse$response){$this->response=$response;$this->terminate();}function
  1986. terminate(){if(func_num_args()!==0){trigger_error(__METHOD__.' is not intended to send a Application\Response; use sendResponse() instead.',E_USER_WARNING);$this->sendResponse(func_get_arg(0));}throw
  1987. new
  1988. Application\AbortException();}function
  1989. forward($destination,$args=array()){if($destination
  1990. instanceof
  1991. Application\Request){$this->sendResponse(new
  1992. Responses\ForwardResponse($destination));}elseif(!is_array($args)){$args=func_get_args();array_shift($args);}$this->createRequest($this,$destination,$args,'forward');$this->sendResponse(new
  1993. Responses\ForwardResponse($this->lastCreatedRequest));}function
  1994. redirectUrl($url,$code=NULL){if($this->isAjax()){$this->payload->redirect=(string)$url;$this->sendPayload();}elseif(!$code){$code=$this->getHttpRequest()->isMethod('post')?Http\IResponse::S303_POST_GET:Http\IResponse::S302_FOUND;}$this->sendResponse(new
  1995. Responses\RedirectResponse($url,$code));}function
  1996. redirectUri($url,$code=NULL){trigger_error(__METHOD__.'() is deprecated; use '.__CLASS__.'::redirectUrl() instead.',E_USER_WARNING);$this->redirectUrl($url,$code);}function
  1997. error($message=NULL,$code=Http\IResponse::S404_NOT_FOUND){throw
  1998. new
  1999. Application\BadRequestException($message,$code);}function
  2000. backlink(){return$this->getAction(TRUE);}function
  2001. getLastCreatedRequest(){return$this->lastCreatedRequest;}function
  2002. getLastCreatedRequestFlag($flag){return!empty($this->lastCreatedRequestFlag[$flag]);}function
  2003. canonicalize(){if(!$this->isAjax()&&($this->request->isMethod('get')||$this->request->isMethod('head'))){try{$url=$this->createRequest($this,$this->action,$this->getGlobalState()+$this->request->getParameters(),'redirectX');}catch(InvalidLinkException$e){}if(isset($url)&&!$this->getHttpRequest()->getUrl()->isEqual($url)){$this->sendResponse(new
  2004. Responses\RedirectResponse($url,Http\IResponse::S301_MOVED_PERMANENTLY));}}}function
  2005. lastModified($lastModified,$etag=NULL,$expire=NULL){if($expire!==NULL){$this->getHttpResponse()->setExpiration($expire);}if(!$this->getHttpContext()->isModified($lastModified,$etag)){$this->terminate();}}final
  2006. protected
  2007. function
  2008. createRequest($component,$destination,array$args,$mode){static$presenterFactory,$router,$refUrl;if($presenterFactory===NULL){$presenterFactory=$this->getApplication()->getPresenterFactory();$router=$this->getApplication()->getRouter();$refUrl=new
  2009. Http\Url($this->getHttpRequest()->getUrl());$refUrl->setPath($this->getHttpRequest()->getUrl()->getScriptPath());}$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
  2010. instanceof
  2011. 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
  2012. new
  2013. InvalidLinkException("Signal must be non-empty string.");}$destination='this';}if($destination==NULL){throw
  2014. new
  2015. 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
  2016. new
  2017. 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);}}try{$presenterClass=$presenterFactory->getPresenterClass($presenter);}catch(Application\InvalidPresenterException$e){throw
  2018. new
  2019. InvalidLinkException($e->getMessage(),NULL,$e);}}if(isset($signal)){$reflection=new
  2020. PresenterComponentReflection(get_class($component));if($signal==='this'){$signal='';if(array_key_exists(0,$args)){throw
  2021. new
  2022. InvalidLinkException("Unable to pass parameters to 'this!' signal.");}}elseif(strpos($signal,self::NAME_SEPARATOR)===FALSE){$method=$component->formatSignalMethod($signal);if(!$reflection->hasCallableMethod($method)){throw
  2023. new
  2024. 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
  2025. as$key=>$val){unset($args[$key]);$args[$prefix.$key]=$val;}}}if(is_subclass_of($presenterClass,__CLASS__)){if($action===''){$action=self::DEFAULT_ACTION;}$current=($action==='*'||strcasecmp($action,$this->action)===0)&&$presenterClass===get_class($this);$reflection=new
  2026. 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
  2027. new
  2028. 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);}if($mode==='redirect'){$this->saveGlobalState();}$globalState=$this->getGlobalState($destination==='this'?NULL:$presenterClass);if($current&&$args){$tmp=$globalState+$this->params;foreach($args
  2029. as$key=>$val){if(http_build_query(array($val))!==(isset($tmp[$key])?http_build_query(array($tmp[$key])):'')){$current=FALSE;break;}}}$args+=$globalState;}$args[self::ACTION_KEY]=$action;if(!empty($signal)){$args[self::SIGNAL_KEY]=$component->getParameterId($signal);$current=$current&&$args[self::SIGNAL_KEY]===$this->getParameter(self::SIGNAL_KEY);}if(($mode==='redirect'||$mode==='forward')&&$this->hasFlashSession()){$args[self::FLASH_KEY]=$this->getParameter(self::FLASH_KEY);}$this->lastCreatedRequest=new
  2030. Application\Request($presenter,Application\Request::FORWARD,$args,array(),array());$this->lastCreatedRequestFlag=array('current'=>$current);if($mode==='forward'||$mode==='test'){return;}$url=$router->constructUrl($this->lastCreatedRequest,$refUrl);if($url===NULL){unset($args[self::ACTION_KEY]);$params=urldecode(http_build_query($args,NULL,', '));throw
  2031. new
  2032. InvalidLinkException("No route for $presenter:$action($params)");}if($mode==='link'&&$scheme===FALSE&&!$this->absoluteUrls){$hostUrl=$refUrl->getHostUrl();if(strncmp($url,$hostUrl,strlen($hostUrl))===0){$url=substr($url,strlen($hostUrl));}}return$url.$fragment;}private
  2033. static
  2034. function
  2035. argsToParams($class,$method,&$args,$supplemental=array()){$i=0;$rm=new\ReflectionMethod($class,$method);foreach($rm->getParameters()as$param){$name=$param->getName();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($args[$name]===NULL){continue;}$def=$param->isDefaultValueAvailable()&&$param->isOptional()?$param->getDefaultValue():NULL;$type=$param->isArray()?'array':gettype($def);if(!PresenterComponentReflection::convertType($args[$name],$type)){throw
  2036. new
  2037. InvalidLinkException("Invalid value for parameter '$name' in method $class::$method(), expected ".($type==='NULL'?'scalar':$type).".");}if($args[$name]===$def||($def===NULL&&is_scalar($args[$name])&&(string)$args[$name]==='')){$args[$name]=NULL;}}if(array_key_exists($i,$args)){$method=$rm->getName();throw
  2038. new
  2039. InvalidLinkException("Passed more parameters than method $class::$method() expects.");}}protected
  2040. function
  2041. handleInvalidLink(InvalidLinkException$e){if($this->invalidLinkMode===self::INVALID_LINK_SILENT){return'#';}elseif($this->invalidLinkMode===self::INVALID_LINK_WARNING){return'error: '.$e->getMessage();}else{throw$e;}}function
  2042. storeRequest($expiration='+ 10 minutes'){$session=$this->getSession('Nette.Application/requests');do{$key=Nette\Utils\Strings::random(5);}while(isset($session[$key]));$session[$key]=array($this->getUser()->getId(),$this->request);$session->setExpiration($expiration,$key);return$key;}function
  2043. restoreRequest($key){$session=$this->getSession('Nette.Application/requests');if(!isset($session[$key])||($session[$key][0]!==NULL&&$session[$key][0]!==$this->getUser()->getId())){return;}$request=clone$session[$key][1];unset($session[$key]);$request->setFlag(Application\Request::RESTORED,TRUE);$params=$request->getParameters();$params[self::FLASH_KEY]=$this->getParameter(self::FLASH_KEY);$request->setParameters($params);$this->sendResponse(new
  2044. Responses\ForwardResponse($request));}static
  2045. function
  2046. getPersistentComponents(){return(array)Reflection\ClassType::from(get_called_class())->getAnnotation('persistent');}private
  2047. function
  2048. getGlobalState($forClass=NULL){$sinces=&$this->globalStateSinces;if($this->globalState===NULL){$state=array();foreach($this->globalParams
  2049. as$id=>$params){$prefix=$id.self::NAME_SEPARATOR;foreach($params
  2050. as$key=>$val){$state[$prefix.$key]=$val;}}$this->saveState($state,$forClass?new
  2051. PresenterComponentReflection($forClass):NULL);if($sinces===NULL){$sinces=array();foreach($this->getReflection()->getPersistentParams()as$name=>$meta){$sinces[$name]=$meta['since'];}}$components=$this->getReflection()->getPersistentComponents();$iterator=$this->getComponents(TRUE,'Nette\Application\UI\IStatePersistent');foreach($iterator
  2052. 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
  2053. as$key=>$val){$state[$prefix.$key]=$val;$sinces[$prefix.$key]=$since;}}}else{$state=$this->globalState;}if($forClass!==NULL){$since=NULL;foreach($state
  2054. 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
  2055. function
  2056. saveGlobalState(){foreach($this->globalParams
  2057. as$id=>$foo){$this->getComponent($id,FALSE);}$this->globalParams=array();$this->globalState=$this->getGlobalState();}private
  2058. function
  2059. initGlobalParameters(){$this->globalParams=array();$selfParams=array();$params=$this->request->getParameters();if($this->isAjax()){$params+=$this->request->getPost();}foreach($params
  2060. as$key=>$value){if(!preg_match('#^((?:[a-z0-9_]+-)*)((?!\d+\z)[a-z0-9_]+)\z#i',$key,$matches)){continue;}elseif(!$matches[1]){$selfParams[$key]=$value;}else{$this->globalParams[substr($matches[1],0,-1)][$matches[2]]=$value;}}$this->changeAction(isset($selfParams[self::ACTION_KEY])?$selfParams[self::ACTION_KEY]:self::DEFAULT_ACTION);$this->signalReceiver=$this->getUniqueId();if(isset($selfParams[self::SIGNAL_KEY])){$param=$selfParams[self::SIGNAL_KEY];if(!is_string($param)){$this->error('Signal name is not string.');}$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
  2061. function
  2062. popGlobalParameters($id){if(isset($this->globalParams[$id])){$res=$this->globalParams[$id];unset($this->globalParams[$id]);return$res;}else{return
  2063. array();}}function
  2064. hasFlashSession(){return!empty($this->params[self::FLASH_KEY])&&$this->getSession()->hasSection('Nette.Application.Flash/'.$this->params[self::FLASH_KEY]);}function
  2065. getFlashSession(){if(empty($this->params[self::FLASH_KEY])){$this->params[self::FLASH_KEY]=Nette\Utils\Strings::random(4);}return$this->getSession('Nette.Application.Flash/'.$this->params[self::FLASH_KEY]);}final
  2066. function
  2067. injectPrimary(Nette\DI\Container$context){$this->context=$context;}final
  2068. function
  2069. getContext(){return$this->context;}final
  2070. function
  2071. getService($name){return$this->context->getService($name);}protected
  2072. function
  2073. getHttpRequest(){return$this->context->getByType('Nette\Http\IRequest');}protected
  2074. function
  2075. getHttpResponse(){return$this->context->getByType('Nette\Http\IResponse');}protected
  2076. function
  2077. getHttpContext(){return$this->context->getByType('Nette\Http\Context');}function
  2078. getApplication(){return$this->context->getByType('Nette\Application\Application');}function
  2079. getSession($namespace=NULL){$handler=$this->context->getByType('Nette\Http\Session');return$namespace===NULL?$handler:$handler->getSection($namespace);}function
  2080. getUser(){return$this->context->getByType('Nette\Security\User');}}}namespace Nette\Reflection{use
  2081. Nette;use
  2082. Nette\ObjectMixin;class
  2083. ClassType
  2084. extends\ReflectionClass{private
  2085. static$extMethods;static
  2086. function
  2087. from($class){return
  2088. new
  2089. static($class);}function
  2090. __toString(){return'Class '.$this->getName();}function
  2091. hasEventProperty($name){if(preg_match('#^on[A-Z]#',$name)&&$this->hasProperty($name)){$rp=$this->getProperty($name);return$rp->isPublic()&&!$rp->isStatic();}return
  2092. FALSE;}function
  2093. setExtensionMethod($name,$callback){$l=&self::$extMethods[strtolower($name)];$l[strtolower($this->getName())]=new
  2094. Nette\Callback($callback);$l['']=NULL;return$this;}function
  2095. getExtensionMethod($name){$class=strtolower($this->getName());$l=&self::$extMethods[strtolower($name)];if(empty($l)){return
  2096. 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
  2097. is($type){return$this->isSubclassOf($type)||strcasecmp($this->getName(),ltrim($type,'\\'))===0;}function
  2098. getConstructor(){return($ref=parent::getConstructor())?Method::from($this->getName(),$ref->getName()):NULL;}function
  2099. getExtension(){return($name=$this->getExtensionName())?new
  2100. Extension($name):NULL;}function
  2101. getInterfaces(){$res=array();foreach(parent::getInterfaceNames()as$val){$res[$val]=new
  2102. static($val);}return$res;}function
  2103. getMethod($name){return
  2104. new
  2105. Method($this->getName(),$name);}function
  2106. getMethods($filter=-1){foreach($res=parent::getMethods($filter)as$key=>$val){$res[$key]=new
  2107. Method($this->getName(),$val->getName());}return$res;}function
  2108. getParentClass(){return($ref=parent::getParentClass())?new
  2109. static($ref->getName()):NULL;}function
  2110. getProperties($filter=-1){foreach($res=parent::getProperties($filter)as$key=>$val){$res[$key]=new
  2111. Property($this->getName(),$val->getName());}return$res;}function
  2112. getProperty($name){return
  2113. new
  2114. Property($this->getName(),$name);}function
  2115. hasAnnotation($name){$res=AnnotationsParser::getAll($this);return!empty($res[$name]);}function
  2116. getAnnotation($name){$res=AnnotationsParser::getAll($this);return
  2117. isset($res[$name])?end($res[$name]):NULL;}function
  2118. getAnnotations(){return
  2119. AnnotationsParser::getAll($this);}function
  2120. getDescription(){return$this->getAnnotation('description');}static
  2121. function
  2122. getReflection(){return
  2123. new
  2124. ClassType(get_called_class());}function
  2125. __call($name,$args){return
  2126. ObjectMixin::call($this,$name,$args);}function&__get($name){return
  2127. ObjectMixin::get($this,$name);}function
  2128. __set($name,$value){return
  2129. ObjectMixin::set($this,$name,$value);}function
  2130. __isset($name){return
  2131. ObjectMixin::has($this,$name);}function
  2132. __unset($name){ObjectMixin::remove($this,$name);}}}namespace Nette\Application\UI{use
  2133. Nette;use
  2134. Nette\Application\BadRequestException;class
  2135. PresenterComponentReflection
  2136. extends
  2137. Nette\Reflection\ClassType{private
  2138. static$ppCache=array();private
  2139. static$pcCache=array();private
  2140. static$mcCache=array();function
  2141. 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,'Nette\Application\UI\PresenterComponent')){$defaults=get_class_vars($class);foreach($class::getPersistentParams()as$name=>$meta){if(is_string($meta)){$name=$meta;}$params[$name]=array('def'=>$defaults[$name],'since'=>$class);}foreach($this->getPersistentParams(get_parent_class($class))as$name=>$param){if(isset($params[$name])){$params[$name]['since']=$param['since'];continue;}$params[$name]=$param;}}return$params;}function
  2142. getPersistentComponents($class=NULL){$class=$class===NULL?$this->getName():$class;$components=&self::$pcCache[$class];if($components!==NULL){return$components;}$components=array();if(is_subclass_of($class,'Nette\Application\UI\Presenter')){foreach($class::getPersistentComponents()as$name=>$meta){if(is_string($meta)){$name=$meta;}$components[$name]=array('since'=>$class);}$components=$this->getPersistentComponents(get_parent_class($class))+$components;}return$components;}function
  2143. hasCallableMethod($method){$class=$this->getName();$cache=&self::$mcCache[strtolower($class.':'.$method)];if($cache===NULL)try{$cache=FALSE;$rm=Nette\Reflection\Method::from($class,$method);$cache=$this->isInstantiable()&&$rm->isPublic()&&!$rm->isAbstract()&&!$rm->isStatic();}catch(\ReflectionException$e){}return$cache;}static
  2144. function
  2145. combineArgs(\ReflectionFunctionAbstract$method,$args){$res=array();$i=0;foreach($method->getParameters()as$param){$name=$param->getName();if(isset($args[$name])){$res[$i++]=$args[$name];$type=$param->isArray()?'array':($param->isDefaultValueAvailable()&&$param->isOptional()?gettype($param->getDefaultValue()):'NULL');if(!self::convertType($res[$i-1],$type)){$mName=$method
  2146. instanceof\ReflectionMethod?$method->getDeclaringClass()->getName().'::'.$method->getName():$method->getName();throw
  2147. new
  2148. BadRequestException("Invalid value for parameter '$name' in method $mName(), expected ".($type==='NULL'?'scalar':$type).".");}}else{$res[$i++]=$param->isDefaultValueAvailable()&&$param->isOptional()?$param->getDefaultValue():($param->isArray()?array():NULL);}}return$res;}static
  2149. function
  2150. convertType(&$val,$type){if($val===NULL||is_object($val)){}elseif($type==='array'){if(!is_array($val)){return
  2151. FALSE;}}elseif(!is_scalar($val)){return
  2152. FALSE;}elseif($type!=='NULL'){$old=$val=($val===FALSE?'0':(string)$val);settype($val,$type);if($old!==($val===FALSE?'0':(string)$val)){return
  2153. FALSE;}}return
  2154. TRUE;}}}namespace Nette\Caching{use
  2155. Nette;class
  2156. Cache
  2157. extends
  2158. Nette\Object
  2159. implements\ArrayAccess{const
  2160. PRIORITY='priority',EXPIRATION='expire',EXPIRE='expire',SLIDING='sliding',TAGS='tags',FILES='files',ITEMS='items',CONSTS='consts',CALLBACKS='callbacks',ALL='all';const
  2161. NAMESPACE_SEPARATOR="\x00";private$storage;private$namespace;private$key;private$data;function
  2162. __construct(IStorage$storage,$namespace=NULL){$this->storage=$storage;$this->namespace=$namespace.self::NAMESPACE_SEPARATOR;}function
  2163. getStorage(){return$this->storage;}function
  2164. getNamespace(){return(string)substr($this->namespace,0,-1);}function
  2165. derive($namespace){$derived=new
  2166. static($this->storage,$this->namespace.$namespace);return$derived;}function
  2167. load($key,$fallback=NULL){$data=$this->storage->read($this->generateKey($key));if($data===NULL&&$fallback){return$this->save($key,new
  2168. Nette\Callback($fallback));}return$data;}function
  2169. save($key,$data,array$dependencies=NULL){$this->release();$key=$this->generateKey($key);if($data
  2170. instanceof
  2171. Nette\Callback||$data
  2172. instanceof\Closure){$this->storage->lock($key);$data=Nette\Callback::create($data)->invokeArgs(array(&$dependencies));}if($data===NULL){$this->storage->remove($key);}else{$this->storage->write($key,$data,$this->completeDependencies($dependencies,$data));return$data;}}private
  2173. function
  2174. completeDependencies($dp,$data){if(is_object($data)){$dp[self::CALLBACKS][]=array(array(__CLASS__,'checkSerializationVersion'),get_class($data),Nette\Reflection\ClassType::from($data)->getAnnotation('serializationVersion'));}if(isset($dp[Cache::EXPIRATION])){$dp[Cache::EXPIRATION]=Nette\DateTime::from($dp[Cache::EXPIRATION])->format('U')-time();}if(isset($dp[self::FILES])){foreach(array_unique((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_unique(array_map(array($this,'generateKey'),(array)$dp[self::ITEMS]));}if(isset($dp[self::CONSTS])){foreach(array_unique((array)$dp[self::CONSTS])as$item){$dp[self::CALLBACKS][]=array(array(__CLASS__,'checkConst'),$item,constant($item));}unset($dp[self::CONSTS]);}if(!is_array($dp)){$dp=array();}return$dp;}function
  2175. remove($key){$this->save($key,NULL);}function
  2176. clean(array$conditions=NULL){$this->release();$this->storage->clean((array)$conditions);}function
  2177. call($function){$key=func_get_args();return$this->load($key,function()use($function,$key){array_shift($key);return
  2178. Nette\Callback::create($function)->invokeArgs($key);});}function
  2179. wrap($function,array$dependencies=NULL){$cache=$this;return
  2180. function()use($cache,$function,$dependencies){$key=array($function,func_get_args());$data=$cache->load($key);if($data===NULL){$data=$cache->save($key,Nette\Callback::create($function)->invokeArgs($key[1]),$dependencies);}return$data;};}function
  2181. start($key){$data=$this->load($key);if($data===NULL){return
  2182. new
  2183. OutputHelper($this,$key);}echo$data;}protected
  2184. function
  2185. generateKey($key){return$this->namespace.md5(is_scalar($key)?$key:serialize($key));}function
  2186. offsetSet($key,$data){$this->save($key,$data);}function
  2187. offsetGet($key){$key=is_scalar($key)?(string)$key:serialize($key);if($this->key!==$key){$this->key=$key;$this->data=$this->load($key);}return$this->data;}function
  2188. offsetExists($key){$this->release();return$this->offsetGet($key)!==NULL;}function
  2189. offsetUnset($key){$this->save($key,NULL);}function
  2190. release(){$this->key=$this->data=NULL;}static
  2191. function
  2192. checkCallbacks($callbacks){foreach($callbacks
  2193. as$callback){$func=array_shift($callback);if(!call_user_func_array($func,$callback)){return
  2194. FALSE;}}return
  2195. TRUE;}private
  2196. static
  2197. function
  2198. checkConst($const,$value){return
  2199. defined($const)&&constant($const)===$value;}private
  2200. static
  2201. function
  2202. checkFile($file,$time){return@filemtime($file)==$time;}private
  2203. static
  2204. function
  2205. checkSerializationVersion($class,$value){return
  2206. Nette\Reflection\ClassType::from($class)->getAnnotation('serializationVersion')===$value;}}class
  2207. OutputHelper
  2208. extends
  2209. Nette\Object{public$dependencies;private$cache;private$key;function
  2210. __construct(Cache$cache,$key){$this->cache=$cache;$this->key=$key;ob_start();}function
  2211. end(array$dependencies=NULL){if($this->cache===NULL){throw
  2212. new
  2213. Nette\InvalidStateException('Output cache has already been saved.');}$this->cache->save($this->key,ob_get_flush(),(array)$dependencies+(array)$this->dependencies);$this->cache=NULL;}}}namespace Nette\Caching\Storages{use
  2214. Nette;class
  2215. DevNullStorage
  2216. extends
  2217. Nette\Object
  2218. implements
  2219. Nette\Caching\IStorage{function
  2220. read($key){}function
  2221. lock($key){}function
  2222. write($key,$data,array$dependencies){}function
  2223. remove($key){}function
  2224. clean(array$conditions){}}use
  2225. Nette\Caching\Cache;class
  2226. FileJournal
  2227. extends
  2228. Nette\Object
  2229. implements
  2230. IJournal{const
  2231. FILE='btfj.dat';const
  2232. FILE_MAGIC=0x6274666A;const
  2233. INDEX_MAGIC=0x696E6465;const
  2234. DATA_MAGIC=0x64617461;const
  2235. NODE_SIZE=4096;const
  2236. BITROT=12;const
  2237. HEADER_SIZE=4096;const
  2238. INT32_SIZE=4;const
  2239. INFO='i',TYPE='t',IS_LEAF='il',PREV_NODE='p',END='e',MAX='m',INDEX_DATA='id',LAST_INDEX='l';const
  2240. TAGS='t',PRIORITY='p',ENTRIES='e';const
  2241. DATA='d',KEY='k',DELETED='d';public
  2242. static$debug=FALSE;private$file;private$handle;private$lastNode=2;private$processIdentifier;private$nodeCache=array();private$nodeChanged=array();private$toCommit=array();private$deletedLinks=array();private$dataNodeFreeSpace=array();private
  2243. static$startNode=array(self::TAGS=>0,self::PRIORITY=>1,self::ENTRIES=>2,self::DATA=>3);function
  2244. __construct($dir){$this->file=$dir.'/'.self::FILE;}function
  2245. __destruct(){if($this->handle){$this->headerCommit();flock($this->handle,LOCK_UN);fclose($this->handle);$this->handle=FALSE;}}function
  2246. write($key,array$dependencies){$this->lock();$priority=!isset($dependencies[Cache::PRIORITY])?FALSE:(int)$dependencies[Cache::PRIORITY];$tags=empty($dependencies[Cache::TAGS])?FALSE:(array)$dependencies[Cache::TAGS];$exists=FALSE;$keyHash=crc32($key);list($entriesNodeId,$entriesNode)=$this->findIndexNode(self::ENTRIES,$keyHash);if(isset($entriesNode[$keyHash])){$entries=$this->mergeIndexData($entriesNode[$keyHash]);foreach($entries
  2247. as$link=>$foo){$dataNode=$this->getNode($link>>self::BITROT);if($dataNode[$link][self::KEY]===$key){if($dataNode[$link][self::TAGS]==$tags&&$dataNode[$link][self::PRIORITY]===$priority){if($dataNode[$link][self::DELETED]){$dataNode[$link][self::DELETED]=FALSE;$this->saveNode($link>>self::BITROT,$dataNode);}$exists=TRUE;}else{$toDelete=array();foreach($dataNode[$link][self::TAGS]as$tag){$toDelete[self::TAGS][$tag][$link]=TRUE;}if($dataNode[$link][self::PRIORITY]!==FALSE){$toDelete[self::PRIORITY][$dataNode[$link][self::PRIORITY]][$link]=TRUE;}$toDelete[self::ENTRIES][$keyHash][$link]=TRUE;$this->cleanFromIndex($toDelete);unset($dataNode[$link]);$this->saveNode($link>>self::BITROT,$dataNode);list($entriesNodeId,$entriesNode)=$this->findIndexNode(self::ENTRIES,$keyHash);}break;}}}if($exists===FALSE){$requiredSize=strlen($key)+75;if($tags){foreach($tags
  2248. as$tag){$requiredSize+=strlen($tag)+13;}}$requiredSize+=$priority?10:1;$freeDataNode=$this->findFreeDataNode($requiredSize);$data=$this->getNode($freeDataNode);if($data===FALSE){$data=array(self::INFO=>array(self::LAST_INDEX=>($freeDataNode<<self::BITROT),self::TYPE=>self::DATA));}$dataNodeKey=$this->findNextFreeKey($freeDataNode,$data);$data[$dataNodeKey]=array(self::KEY=>$key,self::TAGS=>$tags?$tags:array(),self::PRIORITY=>$priority,self::DELETED=>FALSE);$this->saveNode($freeDataNode,$data);$entriesNode[$keyHash][$dataNodeKey]=1;$this->saveNode($entriesNodeId,$entriesNode);if($tags){foreach($tags
  2249. as$tag){list($nodeId,$node)=$this->findIndexNode(self::TAGS,$tag);$node[$tag][$dataNodeKey]=1;$this->saveNode($nodeId,$node);}}if($priority!==FALSE){list($nodeId,$node)=$this->findIndexNode(self::PRIORITY,$priority);$node[$priority][$dataNodeKey]=1;$this->saveNode($nodeId,$node);}}$this->commit();$this->unlock();}function
  2250. clean(array$conditions){$this->lock();if(!empty($conditions[Cache::ALL])){$this->nodeCache=$this->nodeChanged=$this->dataNodeFreeSpace=array();$this->deleteAll();$this->unlock();return
  2251. NULL;}$toDelete=array(self::TAGS=>array(),self::PRIORITY=>array(),self::ENTRIES=>array());$entries=array();if(!empty($conditions[Cache::TAGS])){$entries=$this->cleanTags((array)$conditions[Cache::TAGS],$toDelete);}if(isset($conditions[Cache::PRIORITY])){$this->arrayAppend($entries,$this->cleanPriority((int)$conditions[Cache::PRIORITY],$toDelete));}$this->deletedLinks=array();$this->cleanFromIndex($toDelete);$this->commit();$this->unlock();return$entries;}private
  2252. function
  2253. cleanTags(array$tags,array&$toDelete){$entries=array();foreach($tags
  2254. as$tag){list($nodeId,$node)=$this->findIndexNode(self::TAGS,$tag);if(isset($node[$tag])){$ent=$this->cleanLinks($this->mergeIndexData($node[$tag]),$toDelete);$this->arrayAppend($entries,$ent);}}return$entries;}private
  2255. function
  2256. cleanPriority($priority,array&$toDelete){list($nodeId,$node)=$this->findIndexNode(self::PRIORITY,$priority);ksort($node);$allData=array();foreach($node
  2257. as$prior=>$data){if($prior===self::INFO){continue;}elseif($prior>$priority){break;}$this->arrayAppendKeys($allData,$this->mergeIndexData($data));}$nodeInfo=$node[self::INFO];while($nodeInfo[self::PREV_NODE]!==-1){$nodeId=$nodeInfo[self::PREV_NODE];$node=$this->getNode($nodeId);if($node===FALSE){if(self::$debug){throw
  2258. new
  2259. Nette\InvalidStateException("Cannot load node number $nodeId.");}break;}$nodeInfo=$node[self::INFO];unset($node[self::INFO]);foreach($node
  2260. as$prior=>$data){$this->arrayAppendKeys($allData,$this->mergeIndexData($data));}}return$this->cleanLinks($allData,$toDelete);}private
  2261. function
  2262. cleanLinks(array$data,array&$toDelete){$return=array();$data=array_keys($data);sort($data);$max=count($data);$data[]=0;$i=0;while($i<$max){$searchLink=$data[$i];if(isset($this->deletedLinks[$searchLink])){++$i;continue;}$nodeId=$searchLink>>self::BITROT;$node=$this->getNode($nodeId);if($node===FALSE){if(self::$debug){throw
  2263. new
  2264. Nette\InvalidStateException("Cannot load node number $nodeId.");}++$i;continue;}do{$link=$data[$i];if(!isset($node[$link])){if(self::$debug){throw
  2265. new
  2266. Nette\InvalidStateException("Link with ID $searchLink is not in node $nodeId.");}continue;}elseif(isset($this->deletedLinks[$link])){continue;}$nodeLink=&$node[$link];if(!$nodeLink[self::DELETED]){$nodeLink[self::DELETED]=TRUE;$return[]=$nodeLink[self::KEY];}else{foreach($nodeLink[self::TAGS]as$tag){$toDelete[self::TAGS][$tag][$link]=TRUE;}if($nodeLink[self::PRIORITY]!==FALSE){$toDelete[self::PRIORITY][$nodeLink[self::PRIORITY]][$link]=TRUE;}$toDelete[self::ENTRIES][crc32($nodeLink[self::KEY])][$link]=TRUE;unset($node[$link]);$this->deletedLinks[$link]=TRUE;}}while(($data[++$i]>>self::BITROT)===$nodeId);$this->saveNode($nodeId,$node);}return$return;}private
  2267. function
  2268. cleanFromIndex(array$toDeleteFromIndex){foreach($toDeleteFromIndex
  2269. as$type=>$toDelete){ksort($toDelete);while(!empty($toDelete)){reset($toDelete);$searchKey=key($toDelete);list($masterNodeId,$masterNode)=$this->findIndexNode($type,$searchKey);if(!isset($masterNode[$searchKey])){if(self::$debug){throw
  2270. new
  2271. Nette\InvalidStateException('Bad index.');}unset($toDelete[$searchKey]);continue;}foreach($toDelete
  2272. as$key=>$links){if(isset($masterNode[$key])){foreach($links
  2273. as$link=>$foo){if(isset($masterNode[$key][$link])){unset($masterNode[$key][$link],$links[$link]);}}if(!empty($links)&&isset($masterNode[$key][self::INDEX_DATA])){$this->cleanIndexData($masterNode[$key][self::INDEX_DATA],$links,$masterNode[$key]);}if(empty($masterNode[$key])){unset($masterNode[$key]);}unset($toDelete[$key]);}else{break;}}$this->saveNode($masterNodeId,$masterNode);}}}private
  2274. function
  2275. mergeIndexData(array$data){while(isset($data[self::INDEX_DATA])){$id=$data[self::INDEX_DATA];unset($data[self::INDEX_DATA]);$childNode=$this->getNode($id);if($childNode===FALSE){if(self::$debug){throw
  2276. new
  2277. Nette\InvalidStateException("Cannot load node number $id.");}break;}$this->arrayAppendKeys($data,$childNode[self::INDEX_DATA]);}return$data;}private
  2278. function
  2279. cleanIndexData($nextNodeId,array$links,&$masterNodeLink){$prev=-1;while($nextNodeId&&!empty($links)){$nodeId=$nextNodeId;$node=$this->getNode($nodeId);if($node===FALSE){if(self::$debug){throw
  2280. new
  2281. Nette\InvalidStateException("Cannot load node number $nodeId.");}break;}foreach($links
  2282. as$link=>$foo){if(isset($node[self::INDEX_DATA][$link])){unset($node[self::INDEX_DATA][$link],$links[$link]);}}if(isset($node[self::INDEX_DATA][self::INDEX_DATA])){$nextNodeId=$node[self::INDEX_DATA][self::INDEX_DATA];}else{$nextNodeId=FALSE;}if(empty($node[self::INDEX_DATA])||(count($node[self::INDEX_DATA])===1&&$nextNodeId)){if($prev===-1){if($nextNodeId===FALSE){unset($masterNodeLink[self::INDEX_DATA]);}else{$masterNodeLink[self::INDEX_DATA]=$nextNodeId;}}else{$prevNode=$this->getNode($prev);if($prevNode===FALSE){if(self::$debug){throw
  2283. new
  2284. Nette\InvalidStateException("Cannot load node number $prev.");}}else{if($nextNodeId===FALSE){unset($prevNode[self::INDEX_DATA][self::INDEX_DATA]);if(empty($prevNode[self::INDEX_DATA])){unset($prevNode[self::INDEX_DATA]);}}else{$prevNode[self::INDEX_DATA][self::INDEX_DATA]=$nextNodeId;}$this->saveNode($prev,$prevNode);}}unset($node[self::INDEX_DATA]);}else{$prev=$nodeId;}$this->saveNode($nodeId,$node);}}private
  2285. function
  2286. getNode($id){if(isset($this->nodeCache[$id])){return$this->nodeCache[$id];}$binary=stream_get_contents($this->handle,self::NODE_SIZE,self::HEADER_SIZE+self::NODE_SIZE*$id);if(empty($binary)){return
  2287. FALSE;}list(,$magic,$length)=unpack('N2',$binary);if($magic!==self::INDEX_MAGIC&&$magic!==self::DATA_MAGIC){if(!empty($magic)){if(self::$debug){throw
  2288. new
  2289. Nette\InvalidStateException("Node $id has malformed header.");}$this->deleteNode($id);}return
  2290. FALSE;}$data=substr($binary,2*self::INT32_SIZE,$length-2*self::INT32_SIZE);$node=@unserialize($data);if($node===FALSE){$this->deleteNode($id);if(self::$debug){throw
  2291. new
  2292. Nette\InvalidStateException("Cannot unserialize node number $id.");}return
  2293. FALSE;}return$this->nodeCache[$id]=$node;}private
  2294. function
  2295. saveNode($id,array$node){if(count($node)===1){$nodeInfo=$node[self::INFO];if($nodeInfo[self::TYPE]!==self::DATA){if($nodeInfo[self::END]!==-1){$this->nodeCache[$id]=$node;$this->nodeChanged[$id]=TRUE;return;}if($nodeInfo[self::MAX]===-1){$max=PHP_INT_MAX;}else{$max=$nodeInfo[self::MAX];}list(,,$parentId)=$this->findIndexNode($nodeInfo[self::TYPE],$max,$id);if($parentId!==-1&&$parentId!==$id){$parentNode=$this->getNode($parentId);if($parentNode===FALSE){if(self::$debug){throw
  2296. new
  2297. Nette\InvalidStateException("Cannot load node number $parentId.");}}else{if($parentNode[self::INFO][self::END]===$id){if(count($parentNode)===1){$parentNode[self::INFO][self::END]=-1;}else{end($parentNode);$lastKey=key($parentNode);$parentNode[self::INFO][self::END]=$parentNode[$lastKey];unset($parentNode[$lastKey]);}}else{unset($parentNode[$nodeInfo[self::MAX]]);}$this->saveNode($parentId,$parentNode);}}if($nodeInfo[self::TYPE]===self::PRIORITY){if($nodeInfo[self::MAX]===-1){if($nodeInfo[self::PREV_NODE]!==-1){$prevNode=$this->getNode($nodeInfo[self::PREV_NODE]);if($prevNode===FALSE){if(self::$debug){throw
  2298. new
  2299. Nette\InvalidStateException("Cannot load node number {$nodeInfo[self::PREV_NODE]}.");}}else{$prevNode[self::INFO][self::MAX]=-1;$this->saveNode($nodeInfo[self::PREV_NODE],$prevNode);}}}else{list($nextId,$nextNode)=$this->findIndexNode($nodeInfo[self::TYPE],$nodeInfo[self::MAX]+1,NULL,$id);if($nextId!==-1&&$nextId!==$id){$nextNode[self::INFO][self::PREV_NODE]=$nodeInfo[self::PREV_NODE];$this->saveNode($nextId,$nextNode);}}}}$this->nodeCache[$id]=FALSE;}else{$this->nodeCache[$id]=$node;}$this->nodeChanged[$id]=TRUE;}private
  2300. function
  2301. commit(){do{foreach($this->nodeChanged
  2302. as$id=>$foo){if($this->prepareNode($id,$this->nodeCache[$id])){unset($this->nodeChanged[$id]);}}}while(!empty($this->nodeChanged));foreach($this->toCommit
  2303. as$node=>$str){$this->commitNode($node,$str);}$this->toCommit=array();}private
  2304. function
  2305. prepareNode($id,$node){if($node===FALSE){if($id<$this->lastNode){$this->lastNode=$id;}unset($this->nodeCache[$id]);unset($this->dataNodeFreeSpace[$id]);$this->deleteNode($id);return
  2306. TRUE;}$data=serialize($node);$dataSize=strlen($data)+2*self::INT32_SIZE;$isData=$node[self::INFO][self::TYPE]===self::DATA;if($dataSize>self::NODE_SIZE){if($isData){throw
  2307. new
  2308. Nette\InvalidStateException('Saving node is bigger than maximum node size.');}else{$this->bisectNode($id,$node);return
  2309. FALSE;}}$this->toCommit[$id]=pack('N2',$isData?self::DATA_MAGIC:self::INDEX_MAGIC,$dataSize).$data;if($this->lastNode<$id){$this->lastNode=$id;}if($isData){$this->dataNodeFreeSpace[$id]=self::NODE_SIZE-$dataSize;}return
  2310. TRUE;}private
  2311. function
  2312. commitNode($id,$str){fseek($this->handle,self::HEADER_SIZE+self::NODE_SIZE*$id);$written=fwrite($this->handle,$str);if($written===FALSE){throw
  2313. new
  2314. Nette\InvalidStateException("Cannot write node number $id to journal.");}}private
  2315. function
  2316. findIndexNode($type,$search,$childId=NULL,$prevId=NULL){$nodeId=self::$startNode[$type];$parentId=-1;while(TRUE){$node=$this->getNode($nodeId);if($node===FALSE){return
  2317. array($nodeId,array(self::INFO=>array(self::TYPE=>$type,self::IS_LEAF=>TRUE,self::PREV_NODE=>-1,self::END=>-1,self::MAX=>-1)),$parentId);}if($node[self::INFO][self::IS_LEAF]||$nodeId===$childId||$node[self::INFO][self::PREV_NODE]===$prevId){return
  2318. array($nodeId,$node,$parentId);}$parentId=$nodeId;if(isset($node[$search])){$nodeId=$node[$search];}else{foreach($node
  2319. as$key=>$childNode){if($key>$search
  2320. and$key!==self::INFO){$nodeId=$childNode;continue
  2321. 2;}}$nodeId=$node[self::INFO][self::END];}}}private
  2322. function
  2323. findFreeNode($count=1){$id=$this->lastNode;$nodesId=array();do{if(isset($this->nodeCache[$id])){++$id;continue;}$offset=self::HEADER_SIZE+self::NODE_SIZE*$id;$binary=stream_get_contents($this->handle,self::INT32_SIZE,$offset);if(empty($binary)){$nodesId[]=$id;}else{list(,$magic)=unpack('N',$binary);if($magic!==self::INDEX_MAGIC&&$magic!==self::DATA_MAGIC){$nodesId[]=$id;}}++$id;}while(count($nodesId)!==$count);if($count===1){return$nodesId[0];}else{return$nodesId;}}private
  2324. function
  2325. findFreeDataNode($size){foreach($this->dataNodeFreeSpace
  2326. as$id=>$freeSpace){if($freeSpace>$size){return$id;}}$id=self::$startNode[self::DATA];while(TRUE){if(isset($this->dataNodeFreeSpace[$id])||isset($this->nodeCache[$id])){++$id;continue;}$offset=self::HEADER_SIZE+self::NODE_SIZE*$id;$binary=stream_get_contents($this->handle,2*self::INT32_SIZE,$offset);if(empty($binary)){$this->dataNodeFreeSpace[$id]=self::NODE_SIZE;return$id;}list(,$magic,$nodeSize)=unpack('N2',$binary);if(empty($magic)){$this->dataNodeFreeSpace[$id]=self::NODE_SIZE;return$id;}elseif($magic===self::DATA_MAGIC){$freeSpace=self::NODE_SIZE-$nodeSize;$this->dataNodeFreeSpace[$id]=$freeSpace;if($freeSpace>$size){return$id;}}++$id;}}private
  2327. function
  2328. bisectNode($id,array$node){$nodeInfo=$node[self::INFO];unset($node[self::INFO]);if(count($node)===1){$key=key($node);$dataId=$this->findFreeDataNode(self::NODE_SIZE);$this->saveNode($dataId,array(self::INDEX_DATA=>$node[$key],self::INFO=>array(self::TYPE=>self::DATA,self::LAST_INDEX=>($dataId<<self::BITROT))));unset($node[$key]);$node[$key][self::INDEX_DATA]=$dataId;$node[self::INFO]=$nodeInfo;$this->saveNode($id,$node);return;}ksort($node);$halfCount=ceil(count($node)/2);list($first,$second)=array_chunk($node,$halfCount,TRUE);end($first);$halfKey=key($first);if($id<=2){list($firstId,$secondId)=$this->findFreeNode(2);$first[self::INFO]=array(self::TYPE=>$nodeInfo[self::TYPE],self::IS_LEAF=>$nodeInfo[self::IS_LEAF],self::PREV_NODE=>-1,self::END=>-1,self::MAX=>$halfKey);$this->saveNode($firstId,$first);$second[self::INFO]=array(self::TYPE=>$nodeInfo[self::TYPE],self::IS_LEAF=>$nodeInfo[self::IS_LEAF],self::PREV_NODE=>$firstId,self::END=>$nodeInfo[self::END],self::MAX=>-1);$this->saveNode($secondId,$second);$parentNode=array(self::INFO=>array(self::TYPE=>$nodeInfo[self::TYPE],self::IS_LEAF=>FALSE,self::PREV_NODE=>-1,self::END=>$secondId,self::MAX=>-1),$halfKey=>$firstId);$this->saveNode($id,$parentNode);}else{$firstId=$this->findFreeNode();$first[self::INFO]=array(self::TYPE=>$nodeInfo[self::TYPE],self::IS_LEAF=>$nodeInfo[self::IS_LEAF],self::PREV_NODE=>$nodeInfo[self::PREV_NODE],self::END=>-1,self::MAX=>$halfKey);$this->saveNode($firstId,$first);$second[self::INFO]=array(self::TYPE=>$nodeInfo[self::TYPE],self::IS_LEAF=>$nodeInfo[self::IS_LEAF],self::PREV_NODE=>$firstId,self::END=>$nodeInfo[self::END],self::MAX=>$nodeInfo[self::MAX]);$this->saveNode($id,$second);list(,,$parent)=$this->findIndexNode($nodeInfo[self::TYPE],$halfKey);$parentNode=$this->getNode($parent);if($parentNode===FALSE){if(self::$debug){throw
  2329. new
  2330. Nette\InvalidStateException("Cannot load node number $parent.");}}else{$parentNode[$halfKey]=$firstId;ksort($parentNode);$this->saveNode($parent,$parentNode);}}}private
  2331. function
  2332. headerCommit(){fseek($this->handle,self::INT32_SIZE);@fwrite($this->handle,pack('N',$this->lastNode));}private
  2333. function
  2334. deleteNode($id){fseek($this->handle,0,SEEK_END);$end=ftell($this->handle);if($end<=(self::HEADER_SIZE+self::NODE_SIZE*($id+1))){$packedNull=pack('N',0);do{$binary=stream_get_contents($this->handle,self::INT32_SIZE,(self::HEADER_SIZE+self::NODE_SIZE*--$id));}while(empty($binary)||$binary===$packedNull);if(!ftruncate($this->handle,self::HEADER_SIZE+self::NODE_SIZE*($id+1))){throw
  2335. new
  2336. Nette\InvalidStateException('Cannot truncate journal file.');}}else{fseek($this->handle,self::HEADER_SIZE+self::NODE_SIZE*$id);$written=fwrite($this->handle,pack('N',0));if($written!==self::INT32_SIZE){throw
  2337. new
  2338. Nette\InvalidStateException("Cannot delete node number $id from journal.");}}}private
  2339. function
  2340. deleteAll(){if(!ftruncate($this->handle,self::HEADER_SIZE)){throw
  2341. new
  2342. Nette\InvalidStateException('Cannot truncate journal file.');}}private
  2343. function
  2344. lock(){if(!$this->handle){$this->prepare();}if(!flock($this->handle,LOCK_EX)){throw
  2345. new
  2346. Nette\InvalidStateException("Cannot acquire exclusive lock on journal file '$this->file'.");}$lastProcessIdentifier=stream_get_contents($this->handle,self::INT32_SIZE,self::INT32_SIZE*2);if($lastProcessIdentifier!==$this->processIdentifier){$this->nodeCache=$this->dataNodeFreeSpace=array();fseek($this->handle,self::INT32_SIZE*2);fwrite($this->handle,$this->processIdentifier);}}private
  2347. function
  2348. prepare(){if(!file_exists($this->file)){$init=@fopen($this->file,'xb');if(!$init){clearstatcache();if(!file_exists($this->file)){throw
  2349. new
  2350. Nette\InvalidStateException("Cannot create journal file '$this->file'.");}}else{$written=fwrite($init,pack('N2',self::FILE_MAGIC,$this->lastNode));fclose($init);if($written!==self::INT32_SIZE*2){throw
  2351. new
  2352. Nette\InvalidStateException("Cannot write journal header.");}}}$this->handle=fopen($this->file,'r+b');if(!$this->handle){throw
  2353. new
  2354. Nette\InvalidStateException("Cannot open journal file '$this->file'.");}if(!flock($this->handle,LOCK_SH)){throw
  2355. new
  2356. Nette\InvalidStateException('Cannot acquire shared lock on journal.');}$header=stream_get_contents($this->handle,2*self::INT32_SIZE,0);flock($this->handle,LOCK_UN);list(,$fileMagic,$this->lastNode)=unpack('N2',$header);if($fileMagic!==self::FILE_MAGIC){fclose($this->handle);$this->handle=FALSE;throw
  2357. new
  2358. Nette\InvalidStateException("Malformed journal file '$this->file'.");}$this->processIdentifier=pack('N',mt_rand());}private
  2359. function
  2360. unlock(){if($this->handle){fflush($this->handle);flock($this->handle,LOCK_UN);}}private
  2361. function
  2362. findNextFreeKey($nodeId,array&$nodeData){$newKey=$nodeData[self::INFO][self::LAST_INDEX]+1;$maxKey=($nodeId+1)<<self::BITROT;if($newKey>=$maxKey){$start=$nodeId<<self::BITROT;for($i=$start;$i<$maxKey;$i++){if(!isset($nodeData[$i])){return$i;}}throw
  2363. new
  2364. Nette\InvalidStateException("Node $nodeId is full.");}else{return++$nodeData[self::INFO][self::LAST_INDEX];}}private
  2365. function
  2366. arrayAppend(array&$array,array$append){foreach($append
  2367. as$value){$array[]=$value;}}private
  2368. function
  2369. arrayAppendKeys(array&$array,array$append){foreach($append
  2370. as$key=>$value){$array[$key]=$value;}}}class
  2371. FileStorage
  2372. extends
  2373. Nette\Object
  2374. implements
  2375. Nette\Caching\IStorage{const
  2376. META_HEADER_LEN=28,META_TIME='time',META_SERIALIZED='serialized',META_EXPIRE='expire',META_DELTA='delta',META_ITEMS='di',META_CALLBACKS='callbacks';const
  2377. FILE='file',HANDLE='handle';public
  2378. static$gcProbability=0.001;public
  2379. static$useDirectories=TRUE;private$dir;private$useDirs;private$journal;private$locks;function
  2380. __construct($dir,IJournal$journal=NULL){$this->dir=realpath($dir);if($this->dir===FALSE){throw
  2381. new
  2382. Nette\DirectoryNotFoundException("Directory '$dir' not found.");}$this->useDirs=(bool)static::$useDirectories;$this->journal=$journal;if(mt_rand()/mt_getrandmax()<static::$gcProbability){$this->clean(array());}}function
  2383. read($key){$meta=$this->readMetaAndLock($this->getCacheFile($key),LOCK_SH);if($meta&&$this->verify($meta)){return$this->readData($meta);}else{return
  2384. NULL;}}private
  2385. function
  2386. 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->readMetaAndLock($depFile,LOCK_SH);if($m[self::META_TIME]!==$time||($m&&!$this->verify($m))){break
  2387. 2;}}}return
  2388. TRUE;}while(FALSE);$this->delete($meta[self::FILE],$meta[self::HANDLE]);return
  2389. FALSE;}function
  2390. lock($key){$cacheFile=$this->getCacheFile($key);if($this->useDirs&&!is_dir($dir=dirname($cacheFile))){@mkdir($dir);}$handle=@fopen($cacheFile,'r+b');if(!$handle){$handle=fopen($cacheFile,'wb');if(!$handle){return;}}$this->locks[$key]=$handle;flock($handle,LOCK_EX);}function
  2391. 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->readMetaAndLock($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];}if(!isset($this->locks[$key])){$this->lock($key);if(!isset($this->locks[$key])){return;}}$handle=$this->locks[$key];unset($this->locks[$key]);$cacheFile=$this->getCacheFile($key);if(isset($dp[Cache::TAGS])||isset($dp[Cache::PRIORITY])){if(!$this->journal){throw
  2392. new
  2393. Nette\InvalidStateException('CacheJournal has not been provided.');}$this->journal->write($cacheFile,$dp);}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;}flock($handle,LOCK_UN);fclose($handle);return;}while(FALSE);$this->delete($cacheFile,$handle);}function
  2394. remove($key){unset($this->locks[$key]);$this->delete($this->getCacheFile($key));}function
  2395. clean(array$conditions){$all=!empty($conditions[Cache::ALL]);$collector=empty($conditions);if($all||$collector){$now=time();foreach(Nette\Utils\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->readMetaAndLock($path,LOCK_SH);if(!$meta){continue;}if((!empty($meta[self::META_DELTA])&&filemtime($meta[self::FILE])+$meta[self::META_DELTA]<$now)||(!empty($meta[self::META_EXPIRE])&&$meta[self::META_EXPIRE]<$now)){$this->delete($path,$meta[self::HANDLE]);continue;}flock($meta[self::HANDLE],LOCK_UN);fclose($meta[self::HANDLE]);}}if($this->journal){$this->journal->clean($conditions);}return;}if($this->journal){foreach($this->journal->clean($conditions)as$file){$this->delete($file);}}}protected
  2396. function
  2397. readMetaAndLock($file,$lock){$handle=@fopen($file,'r+b');if(!$handle){return
  2398. 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;}}flock($handle,LOCK_UN);fclose($handle);return
  2399. NULL;}protected
  2400. function
  2401. readData($meta){$data=stream_get_contents($meta[self::HANDLE]);flock($meta[self::HANDLE],LOCK_UN);fclose($meta[self::HANDLE]);if(empty($meta[self::META_SERIALIZED])){return$data;}else{return@unserialize($data);}}protected
  2402. function
  2403. getCacheFile($key){$file=urlencode($key);if($this->useDirs&&$a=strrpos($file,'%00')){$file=substr_replace($file,'/_',$a,3);}return$this->dir.'/_'.$file;}private
  2404. static
  2405. function
  2406. delete($file,$handle=NULL){if(@unlink($file)){if($handle){flock($handle,LOCK_UN);fclose($handle);}return;}if(!$handle){$handle=@fopen($file,'r+');}if($handle){flock($handle,LOCK_EX);ftruncate($handle,0);flock($handle,LOCK_UN);fclose($handle);@unlink($file);}}}class
  2407. MemcachedStorage
  2408. extends
  2409. Nette\Object
  2410. implements
  2411. Nette\Caching\IStorage{const
  2412. META_CALLBACKS='callbacks',META_DATA='data',META_DELTA='delta';private$memcache;private$prefix;private$journal;static
  2413. function
  2414. isAvailable(){return
  2415. extension_loaded('memcache');}function
  2416. __construct($host='localhost',$port=11211,$prefix='',IJournal$journal=NULL){if(!static::isAvailable()){throw
  2417. new
  2418. Nette\NotSupportedException("PHP extension 'memcache' is not loaded.");}$this->prefix=$prefix;$this->journal=$journal;$this->memcache=new\Memcache;if($host){$this->addServer($host,$port);}}function
  2419. addServer($host='localhost',$port=11211,$timeout=1){if($this->memcache->addServer($host,$port,TRUE,1,$timeout)===FALSE){$error=error_get_last();throw
  2420. new
  2421. Nette\InvalidStateException("Memcache::addServer(): $error[message].");}}function
  2422. getConnection(){return$this->memcache;}function
  2423. read($key){$key=$this->prefix.$key;$meta=$this->memcache->get($key);if(!$meta){return
  2424. NULL;}if(!empty($meta[self::META_CALLBACKS])&&!Cache::checkCallbacks($meta[self::META_CALLBACKS])){$this->memcache->delete($key,0);return
  2425. NULL;}if(!empty($meta[self::META_DELTA])){$this->memcache->replace($key,$meta,0,$meta[self::META_DELTA]+time());}return$meta[self::META_DATA];}function
  2426. lock($key){}function
  2427. write($key,$data,array$dp){if(isset($dp[Cache::ITEMS])){throw
  2428. new
  2429. Nette\NotSupportedException('Dependent items are not supported by MemcachedStorage.');}$key=$this->prefix.$key;$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->journal){throw
  2430. new
  2431. Nette\InvalidStateException('CacheJournal has not been provided.');}$this->journal->write($key,$dp);}$this->memcache->set($key,$meta,0,$expire);}function
  2432. remove($key){$this->memcache->delete($this->prefix.$key,0);}function
  2433. clean(array$conditions){if(!empty($conditions[Cache::ALL])){$this->memcache->flush();}elseif($this->journal){foreach($this->journal->clean($conditions)as$entry){$this->memcache->delete($entry,0);}}}}class
  2434. MemoryStorage
  2435. extends
  2436. Nette\Object
  2437. implements
  2438. Nette\Caching\IStorage{private$data=array();function
  2439. read($key){return
  2440. isset($this->data[$key])?$this->data[$key]:NULL;}function
  2441. lock($key){}function
  2442. write($key,$data,array$dependencies){$this->data[$key]=$data;}function
  2443. remove($key){unset($this->data[$key]);}function
  2444. clean(array$conditions){if(!empty($conditions[Nette\Caching\Cache::ALL])){$this->data=array();}}}class
  2445. PhpFileStorage
  2446. extends
  2447. FileStorage{public$hint;protected
  2448. function
  2449. readData($meta){return
  2450. array('file'=>$meta[self::FILE],'handle'=>$meta[self::HANDLE]);}protected
  2451. function
  2452. getCacheFile($key){return
  2453. parent::getCacheFile(substr_replace($key,trim(strtr($this->hint,'\\/@','.._'),'.').'-',strpos($key,Nette\Caching\Cache::NAMESPACE_SEPARATOR)+1,0)).'.php';}}}namespace Nette{use
  2454. Nette;class
  2455. ArrayHash
  2456. extends\stdClass
  2457. implements\ArrayAccess,\Countable,\IteratorAggregate{static
  2458. function
  2459. from($arr,$recursive=TRUE){$obj=new
  2460. static;foreach($arr
  2461. as$key=>$value){if($recursive&&is_array($value)){$obj->$key=static::from($value,TRUE);}else{$obj->$key=$value;}}return$obj;}function
  2462. getIterator(){return
  2463. new\RecursiveArrayIterator($this);}function
  2464. count(){return
  2465. count((array)$this);}function
  2466. offsetSet($key,$value){if(!is_scalar($key)){throw
  2467. new
  2468. InvalidArgumentException("Key must be either a string or an integer, ".gettype($key)." given.");}$this->$key=$value;}function
  2469. offsetGet($key){return$this->$key;}function
  2470. offsetExists($key){return
  2471. isset($this->$key);}function
  2472. offsetUnset($key){unset($this->$key);}}final
  2473. class
  2474. Callback
  2475. extends
  2476. Object{private$cb;static
  2477. function
  2478. create($callback,$m=NULL){return
  2479. new
  2480. self($callback,$m);}function
  2481. __construct($cb,$m=NULL){if($m!==NULL){$cb=array($cb,$m);}elseif($cb
  2482. instanceof
  2483. self){$this->cb=$cb->cb;return;}if(!is_callable($cb,TRUE)){throw
  2484. new
  2485. InvalidArgumentException("Invalid callback.");}$this->cb=$cb;}function
  2486. __invoke(){if(!is_callable($this->cb)){throw
  2487. new
  2488. InvalidStateException("Callback '$this' is not callable.");}$args=func_get_args();return
  2489. call_user_func_array($this->cb,$args);}function
  2490. invoke(){if(!is_callable($this->cb)){throw
  2491. new
  2492. InvalidStateException("Callback '$this' is not callable.");}$args=func_get_args();return
  2493. call_user_func_array($this->cb,$args);}function
  2494. invokeArgs(array$args){if(!is_callable($this->cb)){throw
  2495. new
  2496. InvalidStateException("Callback '$this' is not callable.");}return
  2497. call_user_func_array($this->cb,$args);}function
  2498. isCallable(){return
  2499. is_callable($this->cb);}function
  2500. getNative(){return$this->cb;}function
  2501. toReflection(){if(is_string($this->cb)&&strpos($this->cb,'::')){return
  2502. new
  2503. Nette\Reflection\Method($this->cb);}elseif(is_array($this->cb)){return
  2504. new
  2505. Nette\Reflection\Method($this->cb[0],$this->cb[1]);}elseif(is_object($this->cb)&&!$this->cb
  2506. instanceof\Closure){return
  2507. new
  2508. Nette\Reflection\Method($this->cb,'__invoke');}else{return
  2509. new
  2510. Nette\Reflection\GlobalFunction($this->cb);}}function
  2511. isStatic(){return
  2512. is_array($this->cb)?is_string($this->cb[0]):is_string($this->cb);}function
  2513. __toString(){if($this->cb
  2514. instanceof\Closure){return'{closure}';}elseif(is_string($this->cb)&&$this->cb[0]==="\0"){return'{lambda}';}else{is_callable($this->cb,TRUE,$textual);return$textual;}}}class
  2515. DateTime
  2516. extends\DateTime{const
  2517. MINUTE=60;const
  2518. HOUR=3600;const
  2519. DAY=86400;const
  2520. WEEK=604800;const
  2521. MONTH=2629800;const
  2522. YEAR=31557600;static
  2523. function
  2524. from($time){if($time
  2525. instanceof\DateTime){return
  2526. new
  2527. self($time->format('Y-m-d H:i:s'),$time->getTimezone());}elseif(is_numeric($time)){if($time<=self::YEAR){$time+=time();}return
  2528. new
  2529. static(date('Y-m-d H:i:s',$time));}else{return
  2530. new
  2531. static($time);}}function
  2532. __toString(){return$this->format('Y-m-d H:i:s');}function
  2533. modifyClone($modify=''){$dolly=clone$this;return$modify?$dolly->modify($modify):$dolly;}}final
  2534. class
  2535. Environment{const
  2536. DEVELOPMENT='development',PRODUCTION='production',CONSOLE='console';private
  2537. static$productionMode;private
  2538. static$createdAt;private
  2539. static$context;final
  2540. function
  2541. __construct(){throw
  2542. new
  2543. StaticClassException;}static
  2544. function
  2545. isConsole(){return
  2546. PHP_SAPI==='cli';}static
  2547. function
  2548. isProduction(){if(self::$productionMode===NULL){self::$productionMode=!Nette\Config\Configurator::detectDebugMode();}return
  2549. self::$productionMode;}static
  2550. function
  2551. setProductionMode($value=TRUE){self::$productionMode=(bool)$value;}static
  2552. function
  2553. setVariable($name,$value,$expand=TRUE){if($expand&&is_string($value)){$value=self::getContext()->expand($value);}self::getContext()->parameters[$name]=$value;}static
  2554. function
  2555. getVariable($name,$default=NULL){if(isset(self::getContext()->parameters[$name])){return
  2556. self::getContext()->parameters[$name];}elseif(func_num_args()>1){return$default;}else{throw
  2557. new
  2558. InvalidStateException("Unknown environment variable '$name'.");}}static
  2559. function
  2560. getVariables(){return
  2561. self::getContext()->parameters;}static
  2562. function
  2563. expand($s){return
  2564. self::getContext()->expand($s);}static
  2565. function
  2566. setContext(DI\Container$context){if(self::$createdAt){throw
  2567. new
  2568. Nette\InvalidStateException('Configurator & SystemContainer has already been created automatically by Nette\Environment at '.self::$createdAt);}self::$context=$context;}static
  2569. function
  2570. getContext(){if(self::$context===NULL){self::loadConfig();}return
  2571. self::$context;}static
  2572. function
  2573. getService($name){return
  2574. self::getContext()->getService($name);}static
  2575. function
  2576. __callStatic($name,$args){if(!$args&&strncasecmp($name,'get',3)===0){return
  2577. self::getContext()->getService(lcfirst(substr($name,3)));}else{throw
  2578. new
  2579. MemberAccessException("Call to undefined static method Nette\\Environment::$name().");}}static
  2580. function
  2581. getHttpRequest(){return
  2582. self::getContext()->getByType('Nette\Http\IRequest');}static
  2583. function
  2584. getHttpContext(){return
  2585. self::getContext()->getByType('Nette\Http\Context');}static
  2586. function
  2587. getHttpResponse(){return
  2588. self::getContext()->getByType('Nette\Http\IResponse');}static
  2589. function
  2590. getApplication(){return
  2591. self::getContext()->getByType('Nette\Application\Application');}static
  2592. function
  2593. getUser(){return
  2594. self::getContext()->getByType('Nette\Security\User');}static
  2595. function
  2596. getRobotLoader(){return
  2597. self::getContext()->getByType('Nette\Loaders\RobotLoader');}static
  2598. function
  2599. getCache($namespace=''){return
  2600. new
  2601. Caching\Cache(self::getContext()->cacheStorage,$namespace);}static
  2602. function
  2603. getSession($namespace=NULL){return$namespace===NULL?self::getContext()->session:self::getContext()->session->getSection($namespace);}static
  2604. function
  2605. loadConfig($file=NULL,$section=NULL){if(self::$createdAt){throw
  2606. new
  2607. Nette\InvalidStateException('Nette\Config\Configurator has already been created automatically by Nette\Environment at '.self::$createdAt);}$configurator=new
  2608. Nette\Config\Configurator;$configurator->setDebugMode(!self::isProduction())->setTempDirectory(defined('TEMP_DIR')?TEMP_DIR:'');if($file){$configurator->addConfig($file,$section);}self::$context=$configurator->createContainer();self::$createdAt='?';foreach(debug_backtrace(FALSE)as$row){if(isset($row['file'])&&is_file($row['file'])&&strpos($row['file'],NETTE_DIR.DIRECTORY_SEPARATOR)!==0){self::$createdAt="$row[file]:$row[line]";break;}}return
  2609. self::getConfig();}static
  2610. function
  2611. getConfig($key=NULL,$default=NULL){$params=Nette\ArrayHash::from(self::getContext()->parameters);if(func_num_args()){return
  2612. isset($params[$key])?$params[$key]:$default;}else{return$params;}}}final
  2613. class
  2614. Framework{const
  2615. NAME='Nette Framework',VERSION='2.0.10',REVISION='c0332ac released on 2013-03-08';public
  2616. static$iAmUsingBadHost=FALSE;final
  2617. function
  2618. __construct(){throw
  2619. new
  2620. StaticClassException;}}class
  2621. Image
  2622. extends
  2623. Object{const
  2624. SHRINK_ONLY=1;const
  2625. STRETCH=2;const
  2626. FIT=0;const
  2627. FILL=4;const
  2628. EXACT=8;const
  2629. JPEG=IMAGETYPE_JPEG,PNG=IMAGETYPE_PNG,GIF=IMAGETYPE_GIF;const
  2630. 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;";const
  2631. ENLARGE=0;private$image;static
  2632. function
  2633. rgb($red,$green,$blue,$transparency=0){return
  2634. 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
  2635. function
  2636. fromFile($file,&$format=NULL){if(!extension_loaded('gd')){throw
  2637. new
  2638. NotSupportedException("PHP extension GD is not loaded.");}$info=@getimagesize($file);switch($format=$info[2]){case
  2639. self::JPEG:return
  2640. new
  2641. static(imagecreatefromjpeg($file));case
  2642. self::PNG:return
  2643. new
  2644. static(imagecreatefrompng($file));case
  2645. self::GIF:return
  2646. new
  2647. static(imagecreatefromgif($file));default:throw
  2648. new
  2649. UnknownImageFileException("Unknown image type or file '$file' not found.");}}static
  2650. function
  2651. getFormatFromString($s){$types=array('image/jpeg'=>self::JPEG,'image/gif'=>self::GIF,'image/png'=>self::PNG);$type=Utils\MimeTypeDetector::fromString($s);return
  2652. isset($types[$type])?$types[$type]:NULL;}static
  2653. function
  2654. fromString($s,&$format=NULL){if(!extension_loaded('gd')){throw
  2655. new
  2656. NotSupportedException("PHP extension GD is not loaded.");}$format=static::getFormatFromString($s);return
  2657. new
  2658. static(imagecreatefromstring($s));}static
  2659. function
  2660. fromBlank($width,$height,$color=NULL){if(!extension_loaded('gd')){throw
  2661. new
  2662. NotSupportedException("PHP extension GD is not loaded.");}$width=(int)$width;$height=(int)$height;if($width<1||$height<1){throw
  2663. new
  2664. 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
  2665. new
  2666. static($image);}function
  2667. __construct($image){$this->setImageResource($image);imagesavealpha($image,TRUE);}function
  2668. getWidth(){return
  2669. imagesx($this->image);}function
  2670. getHeight(){return
  2671. imagesy($this->image);}protected
  2672. function
  2673. setImageResource($image){if(!is_resource($image)||get_resource_type($image)!=='gd'){throw
  2674. new
  2675. InvalidArgumentException('Image is not valid.');}$this->image=$image;return$this;}function
  2676. getImageResource(){return$this->image;}function
  2677. resize($width,$height,$flags=self::FIT){if($flags&self::EXACT){return$this->resize($width,$height,self::FILL)->crop('50%','50%',$width,$height);}list($newWidth,$newHeight)=static::calculateSize($this->getWidth(),$this->getHeight(),$width,$height,$flags);if($newWidth!==$this->getWidth()||$newHeight!==$this->getHeight()){$newImage=static::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=static::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
  2678. function
  2679. calculateSize($srcWidth,$srcHeight,$newWidth,$newHeight,$flags=self::FIT){if(substr($newWidth,-1)==='%'){$newWidth=round($srcWidth/100*abs($newWidth));$percents=TRUE;}else{$newWidth=(int)abs($newWidth);}if(substr($newHeight,-1)==='%'){$newHeight=round($srcHeight/100*abs($newHeight));$flags|=empty($percents)?0:self::STRETCH;}else{$newHeight=(int)abs($newHeight);}if($flags&self::STRETCH){if(empty($newWidth)||empty($newHeight)){throw
  2680. new
  2681. InvalidArgumentException('For stretching must be both width and height specified.');}if($flags&self::SHRINK_ONLY){$newWidth=round($srcWidth*min(1,$newWidth/$srcWidth));$newHeight=round($srcHeight*min(1,$newHeight/$srcHeight));}}else{if(empty($newWidth)&&empty($newHeight)){throw
  2682. new
  2683. 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::SHRINK_ONLY){$scale[]=1;}$scale=min($scale);$newWidth=round($srcWidth*$scale);$newHeight=round($srcHeight*$scale);}return
  2684. array(max((int)$newWidth,1),max((int)$newHeight,1));}function
  2685. crop($left,$top,$width,$height){list($left,$top,$width,$height)=static::calculateCutout($this->getWidth(),$this->getHeight(),$left,$top,$width,$height);$newImage=static::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
  2686. function
  2687. 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
  2688. array($left,$top,$newWidth,$newHeight);}function
  2689. sharpen(){imageconvolution($this->getImageResource(),array(array(-1,-1,-1),array(-1,24,-1),array(-1,-1,-1)),16,0);return$this;}function
  2690. 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
  2691. 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
  2692. self::JPEG:$quality=$quality===NULL?85:max(0,min(100,(int)$quality));return
  2693. imagejpeg($this->getImageResource(),$file,$quality);case
  2694. self::PNG:$quality=$quality===NULL?9:max(0,min(9,(int)$quality));return
  2695. imagepng($this->getImageResource(),$file,$quality);case
  2696. self::GIF:return$file===NULL?imagegif($this->getImageResource()):imagegif($this->getImageResource(),$file);default:throw
  2697. new
  2698. InvalidArgumentException("Unsupported image type.");}}function
  2699. toString($type=self::JPEG,$quality=NULL){ob_start();$this->save(NULL,$quality,$type);return
  2700. ob_get_clean();}function
  2701. __toString(){try{return$this->toString();}catch(\Exception$e){trigger_error("Exception in ".__METHOD__."(): {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}",E_USER_ERROR);}}function
  2702. send($type=self::JPEG,$quality=NULL){if($type!==self::GIF&&$type!==self::PNG&&$type!==self::JPEG){throw
  2703. new
  2704. InvalidArgumentException("Unsupported image type.");}header('Content-Type: '.image_type_to_mime_type($type));return$this->save(NULL,$quality,$type);}function
  2705. __call($name,$args){$function='image'.$name;if(function_exists($function)){foreach($args
  2706. as$key=>$value){if($value
  2707. instanceof
  2708. 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
  2709. is_resource($res)&&get_resource_type($res)==='gd'?$this->setImageResource($res):$res;}return
  2710. parent::__call($name,$args);}}class
  2711. UnknownImageFileException
  2712. extends\Exception{}final
  2713. class
  2714. ObjectMixin{private
  2715. static$methods;private
  2716. static$props;final
  2717. function
  2718. __construct(){throw
  2719. new
  2720. StaticClassException;}static
  2721. function
  2722. call($_this,$name,$args){$class=get_class($_this);$isProp=self::hasProperty($class,$name);if($name===''){throw
  2723. new
  2724. MemberAccessException("Call to class '$class' method without name.");}elseif($isProp==='event'){if(is_array($_this->$name)||$_this->$name
  2725. instanceof\Traversable){foreach($_this->$name
  2726. as$handler){Nette\Callback::create($handler)->invokeArgs($args);}}elseif($_this->$name!==NULL){throw
  2727. new
  2728. UnexpectedValueException("Property $class::$$name must be array or NULL, ".gettype($_this->$name)." given.");}}elseif($cb=Reflection\ClassType::from($_this)->getExtensionMethod($name)){array_unshift($args,$_this);return$cb->invokeArgs($args);}else{throw
  2729. new
  2730. MemberAccessException("Call to undefined method $class::$name().");}}static
  2731. function
  2732. callProperty($_this,$name,$args){if(strlen($name)>3){$op=substr($name,0,3);$prop=strtolower($name[3]).substr($name,4);if($op==='add'&&self::hasProperty(get_class($_this),$prop.'s')){$_this->{$prop.'s'}[]=$args[0];return$_this;}elseif($op==='set'&&self::hasProperty(get_class($_this),$prop)){$_this->$prop=$args[0];return$_this;}elseif($op==='get'&&self::hasProperty(get_class($_this),$prop)){return$_this->$prop;}}return
  2733. self::call($_this,$name,$args);}static
  2734. function
  2735. callStatic($class,$method,$args){throw
  2736. new
  2737. MemberAccessException("Call to undefined static method $class::$method().");}static
  2738. function&get($_this,$name){$class=get_class($_this);$uname=ucfirst($name);if(!isset(self::$methods[$class])){self::$methods[$class]=array_flip(get_class_methods($class));}if($name===''){throw
  2739. new
  2740. MemberAccessException("Cannot read a class '$class' property without name.");}elseif(isset(self::$methods[$class][$m='get'.$uname])||isset(self::$methods[$class][$m='is'.$uname])){$val=$_this->$m();return$val;}elseif(isset(self::$methods[$class][$name])){$val=Callback::create($_this,$name);return$val;}else{$type=isset(self::$methods[$class]['set'.$uname])?'a write-only':'an undeclared';throw
  2741. new
  2742. MemberAccessException("Cannot read $type property $class::\$$name.");}}static
  2743. function
  2744. set($_this,$name,$value){$class=get_class($_this);$uname=ucfirst($name);if(!isset(self::$methods[$class])){self::$methods[$class]=array_flip(get_class_methods($class));}if($name===''){throw
  2745. new
  2746. MemberAccessException("Cannot write to a class '$class' property without name.");}elseif(self::hasProperty($class,$name)){$_this->$name=$value;}elseif(isset(self::$methods[$class][$m='set'.$uname])){$_this->$m($value);}else{$type=isset(self::$methods[$class]['get'.$uname])||isset(self::$methods[$class]['is'.$uname])?'a read-only':'an undeclared';throw
  2747. new
  2748. MemberAccessException("Cannot write to $type property $class::\$$name.");}}static
  2749. function
  2750. remove($_this,$name){$class=get_class($_this);if(!self::hasProperty($class,$name)){throw
  2751. new
  2752. MemberAccessException("Cannot unset the property $class::\$$name.");}}static
  2753. function
  2754. has($_this,$name){$class=get_class($_this);$name=ucfirst($name);if(!isset(self::$methods[$class])){self::$methods[$class]=array_flip(get_class_methods($class));}return$name!==''&&(isset(self::$methods[$class]['get'.$name])||isset(self::$methods[$class]['is'.$name]));}private
  2755. static
  2756. function
  2757. hasProperty($class,$name){$prop=&self::$props[$class][$name];if($prop===NULL){$prop=FALSE;try{$rp=new\ReflectionProperty($class,$name);if($name===$rp->getName()&&$rp->isPublic()&&!$rp->isStatic()){$prop=preg_match('#^on[A-Z]#',$name)?'event':TRUE;}}catch(\ReflectionException$e){}}return$prop;}}}namespace Nette\ComponentModel{use
  2758. Nette;class
  2759. RecursiveComponentIterator
  2760. extends\RecursiveArrayIterator
  2761. implements\Countable{function
  2762. hasChildren(){return$this->current()instanceof
  2763. IContainer;}function
  2764. getChildren(){return$this->current()->getComponents();}function
  2765. count(){return
  2766. iterator_count($this);}}}namespace Nette\Config\Adapters{use
  2767. Nette;use
  2768. Nette\Config\Helpers;class
  2769. IniAdapter
  2770. extends
  2771. Nette\Object
  2772. implements
  2773. Nette\Config\IAdapter{const
  2774. INHERITING_SEPARATOR='<',KEY_SEPARATOR='.',ESCAPED_KEY_SEPARATOR='..',RAW_SECTION='!';function
  2775. load($file){set_error_handler(function($severity,$message){restore_error_handler();throw
  2776. new
  2777. Nette\InvalidStateException("parse_ini_file(): $message");});$ini=parse_ini_file($file,TRUE);restore_error_handler();$data=array();foreach($ini
  2778. as$secName=>$secData){if(is_array($secData)){if(substr($secName,-1)===self::RAW_SECTION){$secName=substr($secName,0,-1);}else{$tmp=array();foreach($secData
  2779. as$key=>$val){$cursor=&$tmp;$key=str_replace(self::ESCAPED_KEY_SEPARATOR,"\xFF",$key);foreach(explode(self::KEY_SEPARATOR,$key)as$part){$part=str_replace("\xFF",self::KEY_SEPARATOR,$part);if(!isset($cursor[$part])||is_array($cursor[$part])){$cursor=&$cursor[$part];}else{throw
  2780. new
  2781. Nette\InvalidStateException("Invalid key '$key' in section [$secName] in file '$file'.");}}$cursor=$val;}$secData=$tmp;}$parts=explode(self::INHERITING_SEPARATOR,$secName);if(count($parts)>1){$secName=trim($parts[0]);$secData[Helpers::EXTENDS_KEY]=trim($parts[1]);}}$cursor=&$data;foreach(explode(self::KEY_SEPARATOR,$secName)as$part){if(!isset($cursor[$part])||is_array($cursor[$part])){$cursor=&$cursor[$part];}else{throw
  2782. new
  2783. Nette\InvalidStateException("Invalid section [$secName] in file '$file'.");}}if(is_array($secData)&&is_array($cursor)){$secData=Helpers::merge($secData,$cursor);}$cursor=$secData;}return$data;}function
  2784. dump(array$data){$output=array();foreach($data
  2785. as$name=>$secData){if(!is_array($secData)){$output=array();self::build($data,$output,'');break;}if($parent=Helpers::takeParent($secData)){$output[]="[$name ".self::INHERITING_SEPARATOR." $parent]";}else{$output[]="[$name]";}self::build($secData,$output,'');$output[]='';}return"; generated by Nette\n\n".implode(PHP_EOL,$output);}private
  2786. static
  2787. function
  2788. build($input,&$output,$prefix){foreach($input
  2789. as$key=>$val){$key=str_replace(self::KEY_SEPARATOR,self::ESCAPED_KEY_SEPARATOR,$key);if(is_array($val)){self::build($val,$output,$prefix.$key.self::KEY_SEPARATOR);}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
  2790. new
  2791. Nette\InvalidArgumentException("The '$prefix$key' item must be scalar or array, ".gettype($val)." given.");}}}}use
  2792. Nette\Utils\Neon;class
  2793. NeonAdapter
  2794. extends
  2795. Nette\Object
  2796. implements
  2797. Nette\Config\IAdapter{const
  2798. INHERITING_SEPARATOR='<',PREVENT_MERGING='!';function
  2799. load($file){return$this->process((array)Neon::decode(file_get_contents($file)));}private
  2800. function
  2801. process(array$arr){$res=array();foreach($arr
  2802. as$key=>$val){if(substr($key,-1)===self::PREVENT_MERGING){if(!is_array($val)&&$val!==NULL){throw
  2803. new
  2804. Nette\InvalidStateException("Replacing operator is available only for arrays, item '$key' is not array.");}$key=substr($key,0,-1);$val[Helpers::EXTENDS_KEY]=Helpers::OVERWRITE;}elseif(preg_match('#^(\S+)\s+'.self::INHERITING_SEPARATOR.'\s+(\S+)\z#',$key,$matches)){if(!is_array($val)&&$val!==NULL){throw
  2805. new
  2806. Nette\InvalidStateException("Inheritance operator is available only for arrays, item '$key' is not array.");}list(,$key,$val[Helpers::EXTENDS_KEY])=$matches;if(isset($res[$key])){throw
  2807. new
  2808. Nette\InvalidStateException("Duplicated key '$key'.");}}if(is_array($val)){$val=$this->process($val);}elseif($val
  2809. instanceof
  2810. Nette\Utils\NeonEntity){$val=(object)array('value'=>$val->value,'attributes'=>$this->process($val->attributes));}$res[$key]=$val;}return$res;}function
  2811. dump(array$data){$tmp=array();foreach($data
  2812. as$name=>$secData){if($parent=Helpers::takeParent($secData)){$name.=' '.self::INHERITING_SEPARATOR.' '.$parent;}$tmp[$name]=$secData;}return"# generated by Nette\n\n".Neon::encode($tmp,Neon::BLOCK);}}class
  2813. PhpAdapter
  2814. extends
  2815. Nette\Object
  2816. implements
  2817. Nette\Config\IAdapter{function
  2818. load($file){return
  2819. Nette\Utils\LimitedScope::load($file);}function
  2820. dump(array$data){return"<?php // generated by Nette \nreturn ".Nette\Utils\PhpGenerator\Helpers::dump($data).';';}}}namespace Nette\Config{use
  2821. Nette;use
  2822. Nette\Utils\Validators;class
  2823. Compiler
  2824. extends
  2825. Nette\Object{private$extensions=array();private$container;private$config;private
  2826. static$reserved=array('services'=>1,'factories'=>1,'parameters'=>1);function
  2827. addExtension($name,CompilerExtension$extension){if(isset(self::$reserved[$name])){throw
  2828. new
  2829. Nette\InvalidArgumentException("Name '$name' is reserved.");}$this->extensions[$name]=$extension->setCompiler($this,$name);return$this;}function
  2830. getExtensions(){return$this->extensions;}function
  2831. getContainerBuilder(){return$this->container;}function
  2832. getConfig(){return$this->config;}function
  2833. compile(array$config,$className,$parentName){$this->config=$config;$this->container=new
  2834. Nette\DI\ContainerBuilder;$this->processParameters();$this->processExtensions();$this->processServices();return$this->generateCode($className,$parentName);}function
  2835. processParameters(){if(isset($this->config['parameters'])){$this->container->parameters=$this->config['parameters'];}}function
  2836. processExtensions(){for($i=0;$slice=array_slice($this->extensions,$i,1);$i++){reset($slice)->loadConfiguration();}if($extra=array_diff_key($this->config,self::$reserved,$this->extensions)){$extra=implode("', '",array_keys($extra));throw
  2837. new
  2838. Nette\InvalidStateException("Found sections '$extra' in configuration, but corresponding extensions are missing.");}}function
  2839. processServices(){$this->parseServices($this->container,$this->config);foreach($this->extensions
  2840. as$name=>$extension){$this->container->addDefinition($name)->setClass('Nette\DI\NestedAccessor',array('@container',$name))->setAutowired(FALSE);if(isset($this->config[$name])){$this->parseServices($this->container,$this->config[$name],$name);}}foreach($this->container->getDefinitions()as$name=>$def){$factory=$name.'Factory';if(!$def->shared&&!$def->internal&&!$this->container->hasDefinition($factory)){$this->container->addDefinition($factory)->setClass('Nette\Callback',array('@container',Nette\DI\Container::getMethodName($name,FALSE)))->setAutowired(FALSE)->tags=$def->tags;}}}function
  2841. generateCode($className,$parentName){foreach($this->extensions
  2842. as$extension){$extension->beforeCompile();$this->container->addDependency(Nette\Reflection\ClassType::from($extension)->getFileName());}$classes[]=$class=$this->container->generateClass($parentName);$class->setName($className)->addMethod('initialize');foreach($this->extensions
  2843. as$extension){$extension->afterCompile($class);}$defs=$this->container->getDefinitions();ksort($defs);$list=array_keys($defs);foreach(array_reverse($defs,TRUE)as$name=>$def){if($def->class==='Nette\DI\NestedAccessor'&&($found=preg_grep('#^'.$name.'\.#i',$list))){$list=array_diff($list,$found);$def->class=$className.'_'.preg_replace('#\W+#','_',$name);$class->documents=preg_replace("#\\S+(?= \\$$name\\z)#",$def->class,$class->documents);$classes[]=$accessor=new
  2844. Nette\Utils\PhpGenerator\ClassType($def->class);foreach($found
  2845. as$item){if($defs[$item]->internal){continue;}$short=substr($item,strlen($name)+1);$accessor->addDocument($defs[$item]->shared?"@property {$defs[$item]->class} \$$short":"@method {$defs[$item]->class} create".ucfirst("$short()"));}}}return
  2846. implode("\n\n\n",$classes);}static
  2847. function
  2848. parseServices(Nette\DI\ContainerBuilder$container,array$config,$namespace=NULL){$services=isset($config['services'])?$config['services']:array();$factories=isset($config['factories'])?$config['factories']:array();$all=array_merge($services,$factories);uasort($all,function($a,$b){return
  2849. strcmp(Helpers::isInheriting($a),Helpers::isInheriting($b));});foreach($all
  2850. as$origName=>$def){$shared=array_key_exists($origName,$services);if((string)(int)$origName===(string)$origName){$name=(string)(count($container->getDefinitions())+1);}elseif($shared&&array_key_exists($origName,$factories)){throw
  2851. new
  2852. Nette\DI\ServiceCreationException("It is not allowed to use services and factories with the same name: '$origName'.");}else{$name=($namespace?$namespace.'.':'').strtr($origName,'\\','_');}if(($parent=Helpers::takeParent($def))&&$parent!==$name){$container->removeDefinition($name);$definition=$container->addDefinition($name);if($parent!==Helpers::OVERWRITE){foreach($container->getDefinition($parent)as$k=>$v){$definition->$k=unserialize(serialize($v));}}}elseif($container->hasDefinition($name)){$definition=$container->getDefinition($name);if($definition->shared!==$shared){throw
  2853. new
  2854. Nette\DI\ServiceCreationException("It is not allowed to use service and factory with the same name '$name'.");}}else{$definition=$container->addDefinition($name);}try{static::parseService($definition,$def,$shared);}catch(\Exception$e){throw
  2855. new
  2856. Nette\DI\ServiceCreationException("Service '$name': ".$e->getMessage(),NULL,$e);}}}static
  2857. function
  2858. parseService(Nette\DI\ServiceDefinition$definition,$config,$shared=TRUE){if($config===NULL){return;}elseif(!is_array($config)){$config=array('class'=>NULL,'factory'=>$config);}$known=$shared?array('class','factory','arguments','setup','autowired','run','tags'):array('class','factory','arguments','setup','autowired','tags','internal','parameters');if($error=array_diff(array_keys($config),$known)){throw
  2859. new
  2860. Nette\InvalidStateException("Unknown key '".implode("', '",$error)."' in definition of service.");}$arguments=array();if(array_key_exists('arguments',$config)){Validators::assertField($config,'arguments','array');$arguments=self::filterArguments($config['arguments']);$definition->setArguments($arguments);}if(array_key_exists('class',$config)||array_key_exists('factory',$config)){$definition->class=NULL;$definition->factory=NULL;}if(array_key_exists('class',$config)){Validators::assertField($config,'class','string|stdClass|null');if($config['class']instanceof\stdClass){$definition->setClass($config['class']->value,self::filterArguments($config['class']->attributes));}else{$definition->setClass($config['class'],$arguments);}}if(array_key_exists('factory',$config)){Validators::assertField($config,'factory','callable|stdClass|null');if($config['factory']instanceof\stdClass){$definition->setFactory($config['factory']->value,self::filterArguments($config['factory']->attributes));}else{$definition->setFactory($config['factory'],$arguments);}}if(isset($config['setup'])){if(Helpers::takeParent($config['setup'])){$definition->setup=array();}Validators::assertField($config,'setup','list');foreach($config['setup']as$id=>$setup){Validators::assert($setup,'callable|stdClass',"setup item #$id");if($setup
  2861. instanceof\stdClass){Validators::assert($setup->value,'callable',"setup item #$id");$definition->addSetup($setup->value,self::filterArguments($setup->attributes));}else{$definition->addSetup($setup);}}}$definition->setShared($shared);if(isset($config['parameters'])){Validators::assertField($config,'parameters','array');$definition->setParameters($config['parameters']);}if(isset($config['autowired'])){Validators::assertField($config,'autowired','bool');$definition->setAutowired($config['autowired']);}if(isset($config['internal'])){Validators::assertField($config,'internal','bool');$definition->setInternal($config['internal']);}if(isset($config['run'])){$config['tags']['run']=(bool)$config['run'];}if(isset($config['tags'])){Validators::assertField($config,'tags','array');if(Helpers::takeParent($config['tags'])){$definition->tags=array();}foreach($config['tags']as$tag=>$attrs){if(is_int($tag)&&is_string($attrs)){$definition->addTag($attrs);}else{$definition->addTag($tag,$attrs);}}}}static
  2862. function
  2863. filterArguments(array$args){foreach($args
  2864. as$k=>$v){if($v==='...'){unset($args[$k]);}elseif($v
  2865. instanceof\stdClass&&isset($v->value,$v->attributes)){$args[$k]=new
  2866. Nette\DI\Statement($v->value,self::filterArguments($v->attributes));}}return$args;}}use
  2867. Nette\DI\ContainerBuilder;abstract
  2868. class
  2869. CompilerExtension
  2870. extends
  2871. Nette\Object{protected$compiler;protected$name;function
  2872. setCompiler(Compiler$compiler,$name){$this->compiler=$compiler;$this->name=$name;return$this;}function
  2873. getConfig(array$defaults=NULL,$expand=TRUE){$config=$this->compiler->getConfig();$config=isset($config[$this->name])?$config[$this->name]:array();unset($config['services'],$config['factories']);$config=Helpers::merge($config,$defaults);return$expand?$this->compiler->getContainerBuilder()->expand($config):$config;}function
  2874. getContainerBuilder(){return$this->compiler->getContainerBuilder();}function
  2875. loadFromFile($file){$loader=new
  2876. Loader;$res=$loader->load($file);$container=$this->compiler->getContainerBuilder();foreach($loader->getDependencies()as$file){$container->addDependency($file);}return$res;}function
  2877. prefix($id){return
  2878. substr_replace($id,$this->name.'.',substr($id,0,1)==='@'?1:0,0);}function
  2879. loadConfiguration(){}function
  2880. beforeCompile(){}function
  2881. afterCompile(Nette\Utils\PhpGenerator\ClassType$class){}}use
  2882. Nette\Caching\Cache;class
  2883. Configurator
  2884. extends
  2885. Nette\Object{const
  2886. AUTO=NULL,NONE=FALSE;const
  2887. DEVELOPMENT='development',PRODUCTION='production';public$onCompile;protected$parameters;protected$files=array();function
  2888. __construct(){$this->parameters=$this->getDefaultParameters();}function
  2889. setDebugMode($value=TRUE){$this->parameters['debugMode']=is_bool($value)?$value:static::detectDebugMode($value);$this->parameters['productionMode']=!$this->parameters['debugMode'];return$this;}function
  2890. isDebugMode(){return!$this->parameters['productionMode'];}function
  2891. setTempDirectory($path){$this->parameters['tempDir']=$path;if(($cacheDir=$this->getCacheDirectory())&&!is_dir($cacheDir)){mkdir($cacheDir);}return$this;}function
  2892. addParameters(array$params){$this->parameters=Helpers::merge($params,$this->parameters);return$this;}protected
  2893. function
  2894. getDefaultParameters(){$trace=debug_backtrace(FALSE);$debugMode=static::detectDebugMode();return
  2895. array('appDir'=>isset($trace[1]['file'])?dirname($trace[1]['file']):NULL,'wwwDir'=>isset($_SERVER['SCRIPT_FILENAME'])?dirname($_SERVER['SCRIPT_FILENAME']):NULL,'debugMode'=>$debugMode,'productionMode'=>!$debugMode,'environment'=>$debugMode?'development':'production','consoleMode'=>PHP_SAPI==='cli','container'=>array('class'=>'SystemContainer','parent'=>'Nette\DI\Container'));}function
  2896. enableDebugger($logDirectory=NULL,$email=NULL){Nette\Diagnostics\Debugger::$strictMode=TRUE;Nette\Diagnostics\Debugger::enable($this->parameters['productionMode'],$logDirectory,$email);}function
  2897. createRobotLoader(){if(!($cacheDir=$this->getCacheDirectory())){throw
  2898. new
  2899. Nette\InvalidStateException("Set path to temporary directory using setTempDirectory().");}$loader=new
  2900. Nette\Loaders\RobotLoader;$loader->setCacheStorage(new
  2901. Nette\Caching\Storages\FileStorage($cacheDir));$loader->autoRebuild=!$this->parameters['productionMode'];return$loader;}function
  2902. addConfig($file,$section=NULL){$this->files[]=array($file,$section===NULL?$this->parameters['environment']:$section);return$this;}function
  2903. loadConfig($file,$section=NULL){trigger_error(__METHOD__.'() is deprecated; use addConfig(file, [section])->createContainer() instead.',E_USER_WARNING);return$this->addConfig($file,$section)->createContainer();}function
  2904. createContainer(){if($cacheDir=$this->getCacheDirectory()){$cache=new
  2905. Cache(new
  2906. Nette\Caching\Storages\PhpFileStorage($cacheDir),'Nette.Configurator');$cacheKey=array($this->parameters,$this->files);$cached=$cache->load($cacheKey);if(!$cached){$code=$this->buildContainer($dependencies);$cache->save($cacheKey,$code,array(Cache::FILES=>$dependencies));$cached=$cache->load($cacheKey);}Nette\Utils\LimitedScope::load($cached['file'],TRUE);}elseif($this->files){throw
  2907. new
  2908. Nette\InvalidStateException("Set path to temporary directory using setTempDirectory().");}else{Nette\Utils\LimitedScope::evaluate($this->buildContainer());}$container=new$this->parameters['container']['class'];$container->initialize();Nette\Environment::setContext($container);return$container;}protected
  2909. function
  2910. buildContainer(&$dependencies=NULL){$loader=$this->createLoader();$config=array();$code="<?php\n";foreach($this->files
  2911. as$tmp){list($file,$section)=$tmp;$config=Helpers::merge($loader->load($file,$section),$config);$code.="// source: $file $section\n";}$code.="\n";$this->checkCompatibility($config);if(!isset($config['parameters'])){$config['parameters']=array();}$config['parameters']=Helpers::merge($config['parameters'],$this->parameters);$compiler=$this->createCompiler();$this->onCompile($this,$compiler);$code.=$compiler->compile($config,$this->parameters['container']['class'],$config['parameters']['container']['parent']);$dependencies=array_merge($loader->getDependencies(),$this->isDebugMode()?$compiler->getContainerBuilder()->getDependencies():array());return$code;}protected
  2912. function
  2913. checkCompatibility(array$config){foreach(array('service'=>'services','variable'=>'parameters','variables'=>'parameters','mode'=>'parameters','const'=>'constants')as$old=>$new){if(isset($config[$old])){throw
  2914. new
  2915. Nette\DeprecatedException("Section '$old' in configuration file is deprecated; use '$new' instead.");}}if(isset($config['services'])){foreach($config['services']as$key=>$def){foreach(array('option'=>'arguments','methods'=>'setup')as$old=>$new){if(is_array($def)&&isset($def[$old])){throw
  2916. new
  2917. Nette\DeprecatedException("Section '$old' in service definition is deprecated; refactor it into '$new'.");}}}}}protected
  2918. function
  2919. createCompiler(){$compiler=new
  2920. Compiler;$compiler->addExtension('php',new
  2921. Extensions\PhpExtension)->addExtension('constants',new
  2922. Extensions\ConstantsExtension)->addExtension('nette',new
  2923. Extensions\NetteExtension);return$compiler;}protected
  2924. function
  2925. createLoader(){return
  2926. new
  2927. Loader;}protected
  2928. function
  2929. getCacheDirectory(){return
  2930. empty($this->parameters['tempDir'])?NULL:$this->parameters['tempDir'].'/cache';}static
  2931. function
  2932. detectDebugMode($list=NULL){$list=is_string($list)?preg_split('#[,\s]+#',$list):(array)$list;if(!isset($_SERVER['HTTP_X_FORWARDED_FOR'])){$list[]='127.0.0.1';$list[]='::1';}return
  2933. in_array(isset($_SERVER['REMOTE_ADDR'])?$_SERVER['REMOTE_ADDR']:php_uname('n'),$list,TRUE);}function
  2934. setProductionMode($value=TRUE){return$this->setDebugMode(is_bool($value)?!$value:$value);}function
  2935. isProductionMode(){return!$this->isDebugMode();}static
  2936. function
  2937. detectProductionMode($list=NULL){return!static::detectDebugMode($list);}}}namespace Nette\Config\Extensions{use
  2938. Nette;use
  2939. Nette\DI\ContainerBuilder;class
  2940. ConstantsExtension
  2941. extends
  2942. Nette\Config\CompilerExtension{function
  2943. afterCompile(Nette\Utils\PhpGenerator\ClassType$class){foreach($this->getConfig()as$name=>$value){$class->methods['initialize']->addBody('define(?, ?);',array($name,$value));}}}use
  2944. Nette\Utils\Validators;class
  2945. NetteExtension
  2946. extends
  2947. Nette\Config\CompilerExtension{public$defaults=array('xhtml'=>TRUE,'session'=>array('iAmUsingBadHost'=>NULL,'autoStart'=>'smart','expiration'=>NULL),'application'=>array('debugger'=>TRUE,'errorPresenter'=>NULL,'catchExceptions'=>'%productionMode%'),'routing'=>array('debugger'=>TRUE,'routes'=>array()),'security'=>array('debugger'=>TRUE,'frames'=>'SAMEORIGIN','users'=>array(),'roles'=>array(),'resources'=>array()),'mailer'=>array('smtp'=>FALSE),'database'=>array(),'forms'=>array('messages'=>array()),'container'=>array('debugger'=>FALSE),'debugger'=>array('email'=>NULL,'editor'=>NULL,'browser'=>NULL,'strictMode'=>NULL,'bar'=>array(),'blueScreen'=>array()));public$databaseDefaults=array('dsn'=>NULL,'user'=>NULL,'password'=>NULL,'options'=>NULL,'debugger'=>TRUE,'explain'=>TRUE,'reflection'=>'Nette\Database\Reflection\DiscoveredReflection');function
  2948. loadConfiguration(){$container=$this->getContainerBuilder();$config=$this->getConfig($this->defaults);$container->addDefinition($this->prefix('cacheJournal'))->setClass('Nette\Caching\Storages\FileJournal',array('%tempDir%'));$container->addDefinition('cacheStorage')->setClass('Nette\Caching\Storages\FileStorage',array('%tempDir%/cache'));$container->addDefinition($this->prefix('templateCacheStorage'))->setClass('Nette\Caching\Storages\PhpFileStorage',array('%tempDir%/cache'))->setAutowired(FALSE);$container->addDefinition($this->prefix('cache'))->setClass('Nette\Caching\Cache',array(1=>'%namespace%'))->setParameters(array('namespace'=>NULL));$container->addDefinition($this->prefix('httpRequestFactory'))->setClass('Nette\Http\RequestFactory')->addSetup('setEncoding',array('UTF-8'))->setInternal(TRUE);$container->addDefinition('httpRequest')->setClass('Nette\Http\Request')->setFactory('@Nette\Http\RequestFactory::createHttpRequest');$container->addDefinition('httpResponse')->setClass('Nette\Http\Response');$container->addDefinition($this->prefix('httpContext'))->setClass('Nette\Http\Context');$session=$container->addDefinition('session')->setClass('Nette\Http\Session');if(isset($config['session']['expiration'])){$session->addSetup('setExpiration',array($config['session']['expiration']));}if(isset($config['session']['iAmUsingBadHost'])){$session->addSetup('Nette\Framework::$iAmUsingBadHost = ?;',array((bool)$config['session']['iAmUsingBadHost']));}unset($config['session']['expiration'],$config['session']['autoStart'],$config['session']['iAmUsingBadHost']);if(!empty($config['session'])){$session->addSetup('setOptions',array($config['session']));}$container->addDefinition($this->prefix('userStorage'))->setClass('Nette\Http\UserStorage');$user=$container->addDefinition('user')->setClass('Nette\Security\User');if(!$container->parameters['productionMode']&&$config['security']['debugger']){$user->addSetup('Nette\Diagnostics\Debugger::$bar->addPanel(?)',array(new
  2949. Nette\DI\Statement('Nette\Security\Diagnostics\UserPanel')));}if($config['security']['users']){$container->addDefinition($this->prefix('authenticator'))->setClass('Nette\Security\SimpleAuthenticator',array($config['security']['users']));}if($config['security']['roles']||$config['security']['resources']){$authorizator=$container->addDefinition($this->prefix('authorizator'))->setClass('Nette\Security\Permission');foreach($config['security']['roles']as$role=>$parents){$authorizator->addSetup('addRole',array($role,$parents));}foreach($config['security']['resources']as$resource=>$parents){$authorizator->addSetup('addResource',array($resource,$parents));}}$application=$container->addDefinition('application')->setClass('Nette\Application\Application')->addSetup('$catchExceptions',$config['application']['catchExceptions'])->addSetup('$errorPresenter',$config['application']['errorPresenter']);if($config['application']['debugger']){$application->addSetup('Nette\Application\Diagnostics\RoutingPanel::initializePanel');}$container->addDefinition($this->prefix('presenterFactory'))->setClass('Nette\Application\PresenterFactory',array(isset($container->parameters['appDir'])?$container->parameters['appDir']:NULL));$router=$container->addDefinition('router')->setClass('Nette\Application\Routers\RouteList');foreach($config['routing']['routes']as$mask=>$action){$router->addSetup('$service[] = new Nette\Application\Routers\Route(?, ?);',array($mask,$action));}if(!$container->parameters['productionMode']&&$config['routing']['debugger']){$application->addSetup('Nette\Diagnostics\Debugger::$bar->addPanel(?)',array(new
  2950. Nette\DI\Statement('Nette\Application\Diagnostics\RoutingPanel')));}if(empty($config['mailer']['smtp'])){$container->addDefinition($this->prefix('mailer'))->setClass('Nette\Mail\SendmailMailer');}else{$container->addDefinition($this->prefix('mailer'))->setClass('Nette\Mail\SmtpMailer',array($config['mailer']));}$container->addDefinition($this->prefix('mail'))->setClass('Nette\Mail\Message')->addSetup('setMailer')->setShared(FALSE);$container->addDefinition($this->prefix('basicForm'))->setClass('Nette\Forms\Form')->setShared(FALSE);$latte=$container->addDefinition($this->prefix('latte'))->setClass('Nette\Latte\Engine')->setShared(FALSE);if(empty($config['xhtml'])){$latte->addSetup('$service->getCompiler()->defaultContentType = ?',Nette\Latte\Compiler::CONTENT_HTML);}$container->addDefinition($this->prefix('template'))->setClass('Nette\Templating\FileTemplate')->addSetup('registerFilter',array($latte))->addSetup('registerHelperLoader',array('Nette\Templating\Helpers::loader'))->setShared(FALSE);$container->addDefinition($this->prefix('database'))->setClass('Nette\DI\NestedAccessor',array('@container',$this->prefix('database')));if(isset($config['database']['dsn'])){$config['database']=array('default'=>$config['database']);}$autowired=TRUE;foreach((array)$config['database']as$name=>$info){if(!is_array($info)){continue;}$info+=$this->databaseDefaults+array('autowired'=>$autowired);$autowired=FALSE;foreach((array)$info['options']as$key=>$value){unset($info['options'][$key]);$info['options'][constant($key)]=$value;}$connection=$container->addDefinition($this->prefix("database.$name"))->setClass('Nette\Database\Connection',array($info['dsn'],$info['user'],$info['password'],$info['options']))->setAutowired($info['autowired'])->addSetup('setCacheStorage')->addSetup('Nette\Diagnostics\Debugger::$blueScreen->addPanel(?)',array('Nette\Database\Diagnostics\ConnectionPanel::renderException'));if($info['reflection']){$connection->addSetup('setDatabaseReflection',is_string($info['reflection'])?array(new
  2951. Nette\DI\Statement(preg_match('#^[a-z]+\z#',$info['reflection'])?'Nette\Database\Reflection\\'.ucfirst($info['reflection']).'Reflection':$info['reflection'])):Nette\Config\Compiler::filterArguments(array($info['reflection'])));}if(!$container->parameters['productionMode']&&$info['debugger']){$panel=$container->addDefinition($this->prefix("database.{$name}ConnectionPanel"))->setClass('Nette\Database\Diagnostics\ConnectionPanel')->setAutowired(FALSE)->addSetup('$explain',!empty($info['explain']))->addSetup('Nette\Diagnostics\Debugger::$bar->addPanel(?)',array('@self'));$connection->addSetup('$service->onQuery[] = ?',array(array($panel,'logQuery')));}}}function
  2952. afterCompile(Nette\Utils\PhpGenerator\ClassType$class){$initialize=$class->methods['initialize'];$container=$this->getContainerBuilder();$config=$this->getConfig($this->defaults);foreach(array('email','editor','browser','strictMode','maxLen','maxDepth')as$key){if(isset($config['debugger'][$key])){$initialize->addBody('Nette\Diagnostics\Debugger::$? = ?;',array($key,$config['debugger'][$key]));}}if(!$container->parameters['productionMode']){if($config['container']['debugger']){$config['debugger']['bar'][]='Nette\DI\Diagnostics\ContainerPanel';}foreach((array)$config['debugger']['bar']as$item){$initialize->addBody($container->formatPhp('Nette\Diagnostics\Debugger::$bar->addPanel(?);',Nette\Config\Compiler::filterArguments(array(is_string($item)?new
  2953. Nette\DI\Statement($item):$item))));}foreach((array)$config['debugger']['blueScreen']as$item){$initialize->addBody($container->formatPhp('Nette\Diagnostics\Debugger::$blueScreen->addPanel(?);',Nette\Config\Compiler::filterArguments(array($item))));}}if(!empty($container->parameters['tempDir'])){$initialize->addBody($this->checkTempDir($container->expand('%tempDir%/cache')));}foreach((array)$config['forms']['messages']as$name=>$text){$initialize->addBody('Nette\Forms\Rules::$defaultMessages[Nette\Forms\Form::?] = ?;',array($name,$text));}if($config['session']['autoStart']==='smart'){$initialize->addBody('$this->session->exists() && $this->session->start();');}elseif($config['session']['autoStart']){$initialize->addBody('$this->session->start();');}if(empty($config['xhtml'])){$initialize->addBody('Nette\Utils\Html::$xhtml = ?;',array((bool)$config['xhtml']));}if(isset($config['security']['frames'])&&$config['security']['frames']!==TRUE){$frames=$config['security']['frames'];if($frames===FALSE){$frames='DENY';}elseif(preg_match('#^https?:#',$frames)){$frames="ALLOW-FROM $frames";}$initialize->addBody('header(?);',array("X-Frame-Options: $frames"));}foreach($container->findByTag('run')as$name=>$on){if($on){$initialize->addBody('$this->getService(?);',array($name));}}}private
  2954. function
  2955. checkTempDir($dir){$uniq=uniqid('_',TRUE);if(!@mkdir("$dir/$uniq",0777)){throw
  2956. new
  2957. Nette\InvalidStateException("Unable to write to directory '$dir'. Make this directory writable.");}$useDirs=@file_put_contents("$dir/$uniq/_",'')!==FALSE;@unlink("$dir/$uniq/_");@rmdir("$dir/$uniq");return'Nette\Caching\Storages\FileStorage::$useDirectories = '.($useDirs?'TRUE':'FALSE').";\n";}}class
  2958. PhpExtension
  2959. extends
  2960. Nette\Config\CompilerExtension{function
  2961. afterCompile(Nette\Utils\PhpGenerator\ClassType$class){$initialize=$class->methods['initialize'];foreach($this->getConfig()as$name=>$value){if(!is_scalar($value)){throw
  2962. new
  2963. Nette\InvalidStateException("Configuration value for directive '$name' is not scalar.");}elseif($name==='include_path'){$initialize->addBody('set_include_path(?);',array(str_replace(';',PATH_SEPARATOR,$value)));}elseif($name==='ignore_user_abort'){$initialize->addBody('ignore_user_abort(?);',array($value));}elseif($name==='max_execution_time'){$initialize->addBody('set_time_limit(?);',array($value));}elseif($name==='date.timezone'){$initialize->addBody('date_default_timezone_set(?);',array($value));}elseif(function_exists('ini_set')){$initialize->addBody('ini_set(?, ?);',array($name,$value));}elseif(ini_get($name)!=$value){throw
  2964. new
  2965. Nette\NotSupportedException('Required function ini_set() is disabled.');}}}}}namespace Nette\Config{use
  2966. Nette;class
  2967. Helpers{const
  2968. EXTENDS_KEY='_extends',OVERWRITE=TRUE;static
  2969. function
  2970. merge($left,$right){if(is_array($left)&&is_array($right)){foreach($left
  2971. as$key=>$val){if(is_int($key)){$right[]=$val;}else{if(is_array($val)&&isset($val[self::EXTENDS_KEY])){if($val[self::EXTENDS_KEY]===self::OVERWRITE){unset($val[self::EXTENDS_KEY]);}}elseif(isset($right[$key])){$val=static::merge($val,$right[$key]);}$right[$key]=$val;}}return$right;}elseif($left===NULL&&is_array($right)){return$right;}else{return$left;}}static
  2972. function
  2973. takeParent(&$data){if(is_array($data)&&isset($data[self::EXTENDS_KEY])){$parent=$data[self::EXTENDS_KEY];unset($data[self::EXTENDS_KEY]);return$parent;}}static
  2974. function
  2975. isOverwriting(&$data){return
  2976. is_array($data)&&isset($data[self::EXTENDS_KEY])&&$data[self::EXTENDS_KEY]===self::OVERWRITE;}static
  2977. function
  2978. isInheriting(&$data){return
  2979. is_array($data)&&isset($data[self::EXTENDS_KEY])&&$data[self::EXTENDS_KEY]!==self::OVERWRITE;}}use
  2980. Nette\Utils\Validators;class
  2981. Loader
  2982. extends
  2983. Nette\Object{const
  2984. INCLUDES_KEY='includes';private$adapters=array('php'=>'Nette\Config\Adapters\PhpAdapter','ini'=>'Nette\Config\Adapters\IniAdapter','neon'=>'Nette\Config\Adapters\NeonAdapter');private$dependencies=array();function
  2985. load($file,$section=NULL){if(!is_file($file)||!is_readable($file)){throw
  2986. new
  2987. Nette\FileNotFoundException("File '$file' is missing or is not readable.");}$this->dependencies[]=$file=realpath($file);$data=$this->getAdapter($file)->load($file);if($section){if(isset($data[self::INCLUDES_KEY])){throw
  2988. new
  2989. Nette\InvalidStateException("Section 'includes' must be placed under some top section in file '$file'.");}$data=$this->getSection($data,$section,$file);}$merged=array();if(isset($data[self::INCLUDES_KEY])){Validators::assert($data[self::INCLUDES_KEY],'list',"section 'includes' in file '$file'");foreach($data[self::INCLUDES_KEY]as$include){$merged=Helpers::merge($this->load(dirname($file).'/'.$include),$merged);}}unset($data[self::INCLUDES_KEY]);return
  2990. Helpers::merge($data,$merged);}function
  2991. save($data,$file){if(file_put_contents($file,$this->getAdapter($file)->dump($data))===FALSE){throw
  2992. new
  2993. Nette\IOException("Cannot write file '$file'.");}}function
  2994. getDependencies(){return
  2995. array_unique($this->dependencies);}function
  2996. addAdapter($extension,$adapter){$this->adapters[strtolower($extension)]=$adapter;return$this;}private
  2997. function
  2998. getAdapter($file){$extension=strtolower(pathinfo($file,PATHINFO_EXTENSION));if(!isset($this->adapters[$extension])){throw
  2999. new
  3000. Nette\InvalidArgumentException("Unknown file extension '$file'.");}return
  3001. is_object($this->adapters[$extension])?$this->adapters[$extension]:new$this->adapters[$extension];}private
  3002. function
  3003. getSection(array$data,$key,$file){Validators::assertField($data,$key,'array|null',"section '%' in file '$file'");$item=$data[$key];if($parent=Helpers::takeParent($item)){$item=Helpers::merge($item,$this->getSection($data,$parent,$file));}return$item;}}}namespace Nette\Database{use
  3004. Nette;use
  3005. Nette\ObjectMixin;use
  3006. PDO;if(class_exists('PDO')){class
  3007. Connection
  3008. extends
  3009. PDO{private$dsn;private$driver;private$preprocessor;private$databaseReflection;private$cache;public$onQuery;function
  3010. __construct($dsn,$username=NULL,$password=NULL,array$options=NULL,$driverClass=NULL){parent::__construct($this->dsn=$dsn,$username,$password,$options);$this->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);$this->setAttribute(PDO::ATTR_STATEMENT_CLASS,array('Nette\Database\Statement',array($this)));$driverClass=$driverClass?:'Nette\Database\Drivers\\'.ucfirst(str_replace('sql','Sql',$this->getAttribute(PDO::ATTR_DRIVER_NAME))).'Driver';$this->driver=new$driverClass($this,(array)$options);$this->preprocessor=new
  3011. SqlPreprocessor($this);}function
  3012. getDsn(){return$this->dsn;}function
  3013. getSupplementalDriver(){return$this->driver;}function
  3014. setDatabaseReflection(IReflection$databaseReflection){$databaseReflection->setConnection($this);$this->databaseReflection=$databaseReflection;return$this;}function
  3015. getDatabaseReflection(){if(!$this->databaseReflection){$this->setDatabaseReflection(new
  3016. Reflection\ConventionalReflection);}return$this->databaseReflection;}function
  3017. setCacheStorage(Nette\Caching\IStorage$storage=NULL){$this->cache=$storage?new
  3018. Nette\Caching\Cache($storage,'Nette.Database.'.md5($this->dsn)):NULL;return$this;}function
  3019. getCache(){return$this->cache;}function
  3020. query($statement){$args=func_get_args();return$this->queryArgs(array_shift($args),$args);}function
  3021. exec($statement){$args=func_get_args();return$this->queryArgs(array_shift($args),$args)->rowCount();}function
  3022. queryArgs($statement,$params){foreach($params
  3023. as$value){if(is_array($value)||is_object($value)){$need=TRUE;break;}}if(isset($need)&&$this->preprocessor!==NULL){list($statement,$params)=$this->preprocessor->process($statement,$params);}return$this->prepare($statement)->execute($params);}function
  3024. fetch($args){$args=func_get_args();return$this->queryArgs(array_shift($args),$args)->fetch();}function
  3025. fetchColumn($args){$args=func_get_args();return$this->queryArgs(array_shift($args),$args)->fetchColumn();}function
  3026. fetchPairs($args){$args=func_get_args();return$this->queryArgs(array_shift($args),$args)->fetchPairs();}function
  3027. fetchAll($args){$args=func_get_args();return$this->queryArgs(array_shift($args),$args)->fetchAll();}function
  3028. table($table){return
  3029. new
  3030. Table\Selection($table,$this);}static
  3031. function
  3032. getReflection(){return
  3033. new
  3034. Nette\Reflection\ClassType(get_called_class());}function
  3035. __call($name,$args){return
  3036. ObjectMixin::call($this,$name,$args);}function&__get($name){return
  3037. ObjectMixin::get($this,$name);}function
  3038. __set($name,$value){return
  3039. ObjectMixin::set($this,$name,$value);}function
  3040. __isset($name){return
  3041. ObjectMixin::has($this,$name);}function
  3042. __unset($name){ObjectMixin::remove($this,$name);}}}}namespace Nette\Database\Diagnostics{use
  3043. Nette;use
  3044. Nette\Database\Helpers;use
  3045. Nette\Diagnostics\Debugger;class
  3046. ConnectionPanel
  3047. extends
  3048. Nette\Object
  3049. implements
  3050. Nette\Diagnostics\IBarPanel{static
  3051. public$maxLength=1000;private$totalTime=0;private$queries=array();public$name;public$explain=TRUE;public$disabled=FALSE;function
  3052. logQuery(Nette\Database\Statement$result,array$params=NULL){if($this->disabled){return;}$source=NULL;foreach(debug_backtrace(FALSE)as$row){if(isset($row['file'])&&is_file($row['file'])&&strpos($row['file'],NETTE_DIR.DIRECTORY_SEPARATOR)!==0){if(isset($row['function'])&&strpos($row['function'],'call_user_func')===0)continue;if(isset($row['class'])&&is_subclass_of($row['class'],'\\Nette\\Database\\Connection'))continue;$source=array($row['file'],(int)$row['line']);break;}}$this->totalTime+=$result->getTime();$this->queries[]=array($result->queryString,$params,$result->getTime(),$result->rowCount(),$result->getConnection(),$source);}static
  3053. function
  3054. renderException($e){if(!$e
  3055. instanceof\PDOException){return;}if(isset($e->queryString)){$sql=$e->queryString;}elseif($item=Nette\Diagnostics\Helpers::findTrace($e->getTrace(),'PDO::prepare')){$sql=$item['args'][0];}return
  3056. isset($sql)?array('tab'=>'SQL','panel'=>Helpers::dumpSql($sql)):NULL;}function
  3057. getTab(){return'<span title="Nette\\Database '.htmlSpecialChars($this->name).'">'.'<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAEYSURBVBgZBcHPio5hGAfg6/2+R980k6wmJgsJ5U/ZOAqbSc2GnXOwUg7BESgLUeIQ1GSjLFnMwsKGGg1qxJRmPM97/1zXFAAAAEADdlfZzr26miup2svnelq7d2aYgt3rebl585wN6+K3I1/9fJe7O/uIePP2SypJkiRJ0vMhr55FLCA3zgIAOK9uQ4MS361ZOSX+OrTvkgINSjS/HIvhjxNNFGgQsbSmabohKDNoUGLohsls6BaiQIMSs2FYmnXdUsygQYmumy3Nhi6igwalDEOJEjPKP7CA2aFNK8Bkyy3fdNCg7r9/fW3jgpVJbDmy5+PB2IYp4MXFelQ7izPrhkPHB+P5/PjhD5gCgCenx+VR/dODEwD+A3T7nqbxwf1HAAAAAElFTkSuQmCC" />'.count($this->queries).' '.(count($this->queries)===1?'query':'queries').($this->totalTime?' / '.sprintf('%0.1f',$this->totalTime*1000).'ms':'').'</span>';}function
  3058. getPanel(){$this->disabled=TRUE;$s='';$h='htmlSpecialChars';foreach($this->queries
  3059. as$i=>$query){list($sql,$params,$time,$rows,$connection,$source)=$query;$explain=NULL;if($this->explain&&preg_match('#\s*\(?\s*SELECT\s#iA',$sql)){try{$cmd=is_string($this->explain)?$this->explain:'EXPLAIN';$explain=$connection->queryArgs("$cmd $sql",$params)->fetchAll();}catch(\PDOException$e){}}$s.='<tr><td>'.sprintf('%0.3f',$time*1000);if($explain){static$counter;$counter++;$s.="<br /><a href='#' class='nette-toggler' rel='#nette-DbConnectionPanel-row-$counter'>explain&nbsp;&#x25ba;</a>";}$s.='</td><td class="nette-DbConnectionPanel-sql">'.Helpers::dumpSql(self::$maxLength?Nette\Utils\Strings::truncate($sql,self::$maxLength):$sql);if($explain){$s.="<table id='nette-DbConnectionPanel-row-$counter' class='nette-collapsed'><tr>";foreach($explain[0]as$col=>$foo){$s.="<th>{$h($col)}</th>";}$s.="</tr>";foreach($explain
  3060. as$row){$s.="<tr>";foreach($row
  3061. as$col){$s.="<td>{$h($col)}</td>";}$s.="</tr>";}$s.="</table>";}if($source){$s.=Nette\Diagnostics\Helpers::editorLink($source[0],$source[1])->class('nette-DbConnectionPanel-source');}$s.='</td><td>';foreach($params
  3062. as$param){$s.=Debugger::dump($param,TRUE);}$s.='</td><td>'.$rows.'</td></tr>';}return
  3063. empty($this->queries)?'':'<style> #nette-debug td.nette-DbConnectionPanel-sql { background: white !important }
  3064. #nette-debug .nette-DbConnectionPanel-source { color: #BBB !important } </style>
  3065. <h1>Queries: '.count($this->queries).($this->totalTime?', time: '.sprintf('%0.3f',$this->totalTime*1000).' ms':'').'</h1>
  3066. <div class="nette-inner nette-DbConnectionPanel">
  3067. <table>
  3068. <tr><th>Time&nbsp;ms</th><th>SQL Statement</th><th>Params</th><th>Rows</th></tr>'.$s.'
  3069. </table>
  3070. </div>';}}}namespace Nette\Database\Drivers{use
  3071. Nette;class
  3072. MsSqlDriver
  3073. extends
  3074. Nette\Object
  3075. implements
  3076. Nette\Database\ISupplementalDriver{private$connection;function
  3077. __construct(Nette\Database\Connection$connection,array$options){$this->connection=$connection;}function
  3078. delimite($name){return'['.str_replace(array('[',']'),array('[[',']]'),$name).']';}function
  3079. formatBool($value){return$value?'1':'0';}function
  3080. formatDateTime(\DateTime$value){return$value->format("'Y-m-d H:i:s'");}function
  3081. formatLike($value,$pos){$value=strtr($value,array("'"=>"''",'%'=>'[%]','_'=>'[_]','['=>'[[]'));return($pos<=0?"'%":"'").$value.($pos>=0?"%'":"'");}function
  3082. applyLimit(&$sql,$limit,$offset){if($limit>=0){$sql='SELECT TOP '.(int)$limit.' * FROM ('.$sql.') t';}if($offset){throw
  3083. new
  3084. Nette\NotImplementedException('Offset is not implemented.');}}function
  3085. normalizeRow($row,$statement){return$row;}function
  3086. getTables(){throw
  3087. new
  3088. Nette\NotImplementedException;}function
  3089. getColumns($table){throw
  3090. new
  3091. Nette\NotImplementedException;}function
  3092. getIndexes($table){throw
  3093. new
  3094. Nette\NotImplementedException;}function
  3095. getForeignKeys($table){throw
  3096. new
  3097. Nette\NotImplementedException;}function
  3098. isSupported($item){return$item===self::SUPPORT_COLUMNS_META;}}class
  3099. MySqlDriver
  3100. extends
  3101. Nette\Object
  3102. implements
  3103. Nette\Database\ISupplementalDriver{const
  3104. ERROR_ACCESS_DENIED=1045;const
  3105. ERROR_DUPLICATE_ENTRY=1062;const
  3106. ERROR_DATA_TRUNCATED=1265;private$connection;function
  3107. __construct(Nette\Database\Connection$connection,array$options){$this->connection=$connection;$charset=isset($options['charset'])?$options['charset']:'utf8';if($charset){$connection->exec("SET NAMES '$charset'");}if(isset($options['sqlmode'])){$connection->exec("SET sql_mode='$options[sqlmode]'");}$connection->exec("SET time_zone='".date('P')."'");}function
  3108. delimite($name){return'`'.str_replace('`','``',$name).'`';}function
  3109. formatBool($value){return$value?'1':'0';}function
  3110. formatDateTime(\DateTime$value){return$value->format("'Y-m-d H:i:s'");}function
  3111. formatLike($value,$pos){$value=addcslashes(str_replace('\\','\\\\',$value),"\x00\n\r\\'%_");return($pos<=0?"'%":"'").$value.($pos>=0?"%'":"'");}function
  3112. applyLimit(&$sql,$limit,$offset){if($limit>=0||$offset>0){$sql.=' LIMIT '.($limit<0?'18446744073709551615':(int)$limit).($offset>0?' OFFSET '.(int)$offset:'');}}function
  3113. normalizeRow($row,$statement){return$row;}function
  3114. getTables(){$tables=array();foreach($this->connection->query('SHOW FULL TABLES')as$row){$tables[]=array('name'=>$row[0],'view'=>isset($row[1])&&$row[1]==='VIEW');}return$tables;}function
  3115. getColumns($table){$columns=array();foreach($this->connection->query('SHOW FULL COLUMNS FROM '.$this->delimite($table))as$row){$type=explode('(',$row['Type']);$columns[]=array('name'=>$row['Field'],'table'=>$table,'nativetype'=>strtoupper($type[0]),'size'=>isset($type[1])?(int)$type[1]:NULL,'unsigned'=>(bool)strstr($row['Type'],'unsigned'),'nullable'=>$row['Null']==='YES','default'=>$row['Default'],'autoincrement'=>$row['Extra']==='auto_increment','primary'=>$row['Key']==='PRI','vendor'=>(array)$row);}return$columns;}function
  3116. getIndexes($table){$indexes=array();foreach($this->connection->query('SHOW INDEX FROM '.$this->delimite($table))as$row){$indexes[$row['Key_name']]['name']=$row['Key_name'];$indexes[$row['Key_name']]['unique']=!$row['Non_unique'];$indexes[$row['Key_name']]['primary']=$row['Key_name']==='PRIMARY';$indexes[$row['Key_name']]['columns'][$row['Seq_in_index']-1]=$row['Column_name'];}return
  3117. array_values($indexes);}function
  3118. getForeignKeys($table){$keys=array();$query='SELECT CONSTRAINT_NAME, COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME FROM information_schema.KEY_COLUMN_USAGE '.'WHERE TABLE_SCHEMA = DATABASE() AND REFERENCED_TABLE_NAME IS NOT NULL AND TABLE_NAME = '.$this->connection->quote($table);foreach($this->connection->query($query)as$id=>$row){$keys[$id]['name']=$row['CONSTRAINT_NAME'];$keys[$id]['local']=$row['COLUMN_NAME'];$keys[$id]['table']=$row['REFERENCED_TABLE_NAME'];$keys[$id]['foreign']=$row['REFERENCED_COLUMN_NAME'];}return
  3119. array_values($keys);}function
  3120. isSupported($item){return$item===self::SUPPORT_COLUMNS_META||$item===self::SUPPORT_SELECT_UNGROUPED_COLUMNS;}}class
  3121. OciDriver
  3122. extends
  3123. Nette\Object
  3124. implements
  3125. Nette\Database\ISupplementalDriver{private$connection;private$fmtDateTime;function
  3126. __construct(Nette\Database\Connection$connection,array$options){$this->connection=$connection;$this->fmtDateTime=isset($options['formatDateTime'])?$options['formatDateTime']:'U';}function
  3127. delimite($name){return'"'.str_replace('"','""',$name).'"';}function
  3128. formatBool($value){return$value?'1':'0';}function
  3129. formatDateTime(\DateTime$value){return$value->format($this->fmtDateTime);}function
  3130. formatLike($value,$pos){throw
  3131. new
  3132. Nette\NotImplementedException;}function
  3133. applyLimit(&$sql,$limit,$offset){if($offset>0){$sql='SELECT * FROM (SELECT t.*, ROWNUM AS "__rnum" FROM ('.$sql.') t '.($limit>=0?'WHERE ROWNUM <= '.((int)$offset+(int)$limit):'').') WHERE "__rnum" > '.(int)$offset;}elseif($limit>=0){$sql='SELECT * FROM ('.$sql.') WHERE ROWNUM <= '.(int)$limit;}}function
  3134. normalizeRow($row,$statement){return$row;}function
  3135. getTables(){$tables=array();foreach($this->connection->query('SELECT * FROM cat')as$row){if($row[1]==='TABLE'||$row[1]==='VIEW'){$tables[]=array('name'=>$row[0],'view'=>$row[1]==='VIEW');}}return$tables;}function
  3136. getColumns($table){throw
  3137. new
  3138. Nette\NotImplementedException;}function
  3139. getIndexes($table){throw
  3140. new
  3141. Nette\NotImplementedException;}function
  3142. getForeignKeys($table){throw
  3143. new
  3144. Nette\NotImplementedException;}function
  3145. isSupported($item){return$item===self::SUPPORT_COLUMNS_META||$item===self::SUPPORT_SEQUENCE;}}class
  3146. OdbcDriver
  3147. extends
  3148. Nette\Object
  3149. implements
  3150. Nette\Database\ISupplementalDriver{private$connection;function
  3151. __construct(Nette\Database\Connection$connection,array$options){$this->connection=$connection;}function
  3152. delimite($name){return'['.str_replace(array('[',']'),array('[[',']]'),$name).']';}function
  3153. formatBool($value){return$value?'1':'0';}function
  3154. formatDateTime(\DateTime$value){return$value->format("#m/d/Y H:i:s#");}function
  3155. formatLike($value,$pos){$value=strtr($value,array("'"=>"''",'%'=>'[%]','_'=>'[_]','['=>'[[]'));return($pos<=0?"'%":"'").$value.($pos>=0?"%'":"'");}function
  3156. applyLimit(&$sql,$limit,$offset){if($limit>=0){$sql='SELECT TOP '.(int)$limit.' * FROM ('.$sql.')';}if($offset){throw
  3157. new
  3158. Nette\InvalidArgumentException('Offset is not implemented in driver odbc.');}}function
  3159. normalizeRow($row,$statement){return$row;}function
  3160. getTables(){throw
  3161. new
  3162. Nette\NotImplementedException;}function
  3163. getColumns($table){throw
  3164. new
  3165. Nette\NotImplementedException;}function
  3166. getIndexes($table){throw
  3167. new
  3168. Nette\NotImplementedException;}function
  3169. getForeignKeys($table){throw
  3170. new
  3171. Nette\NotImplementedException;}function
  3172. isSupported($item){return$item===self::SUPPORT_COLUMNS_META;}}class
  3173. PgSqlDriver
  3174. extends
  3175. Nette\Object
  3176. implements
  3177. Nette\Database\ISupplementalDriver{private$connection;function
  3178. __construct(Nette\Database\Connection$connection,array$options){$this->connection=$connection;}function
  3179. delimite($name){return'"'.str_replace('"','""',$name).'"';}function
  3180. formatBool($value){return$value?'TRUE':'FALSE';}function
  3181. formatDateTime(\DateTime$value){return$value->format("'Y-m-d H:i:s'");}function
  3182. formatLike($value,$pos){$value=strtr($value,array("'"=>"''",'\\'=>'\\\\','%'=>'\\\\%','_'=>'\\\\_'));return($pos<=0?"'%":"'").$value.($pos>=0?"%'":"'");}function
  3183. applyLimit(&$sql,$limit,$offset){if($limit>=0){$sql.=' LIMIT '.(int)$limit;}if($offset>0){$sql.=' OFFSET '.(int)$offset;}}function
  3184. normalizeRow($row,$statement){return$row;}function
  3185. getTables(){$tables=array();foreach($this->connection->query("
  3186. SELECT
  3187. c.relname::varchar AS name,
  3188. c.relkind = 'v' AS view
  3189. FROM
  3190. pg_catalog.pg_class AS c
  3191. JOIN pg_catalog.pg_namespace AS n ON n.oid = c.relnamespace
  3192. WHERE
  3193. c.relkind IN ('r', 'v')
  3194. AND n.nspname = current_schema()
  3195. ORDER BY
  3196. c.relname
  3197. ")as$row){$tables[]=(array)$row;}return$tables;}function
  3198. getColumns($table){$columns=array();foreach($this->connection->query("
  3199. SELECT
  3200. a.attname::varchar AS name,
  3201. c.relname::varchar AS table,
  3202. upper(t.typname) AS nativetype,
  3203. NULL AS size,
  3204. FALSE AS unsigned,
  3205. NOT (a.attnotnull OR t.typtype = 'd' AND t.typnotnull) AS nullable,
  3206. ad.adsrc::varchar AS default,
  3207. coalesce(co.contype = 'p' AND strpos(ad.adsrc, 'nextval') = 1, FALSE) AS autoincrement,
  3208. coalesce(co.contype = 'p', FALSE) AS primary,
  3209. substring(ad.adsrc from 'nextval[(]''\"?([^''\"]+)') AS sequence
  3210. FROM
  3211. pg_catalog.pg_attribute AS a
  3212. JOIN pg_catalog.pg_class AS c ON a.attrelid = c.oid
  3213. JOIN pg_catalog.pg_namespace AS n ON n.oid = c.relnamespace
  3214. JOIN pg_catalog.pg_type AS t ON a.atttypid = t.oid
  3215. LEFT JOIN pg_catalog.pg_attrdef AS ad ON ad.adrelid = c.oid AND ad.adnum = a.attnum
  3216. LEFT JOIN pg_catalog.pg_constraint AS co ON co.connamespace = n.oid AND contype = 'p' AND co.conrelid = c.oid AND a.attnum = ANY(co.conkey)
  3217. WHERE
  3218. c.relkind IN ('r', 'v')
  3219. AND c.relname::varchar = {$this->connection->quote($table)}
  3220. AND n.nspname = current_schema()
  3221. AND a.attnum > 0
  3222. AND NOT a.attisdropped
  3223. ORDER BY
  3224. a.attnum
  3225. ")as$row){$column=(array)$row;$column['vendor']=$column;unset($column['sequence']);$columns[]=$column;}return$columns;}function
  3226. getIndexes($table){$indexes=array();foreach($this->connection->query("
  3227. SELECT
  3228. c2.relname::varchar AS name,
  3229. i.indisunique AS unique,
  3230. i.indisprimary AS primary,
  3231. a.attname::varchar AS column
  3232. FROM
  3233. pg_catalog.pg_class AS c1
  3234. JOIN pg_catalog.pg_namespace AS n ON c1.relnamespace = n.oid
  3235. JOIN pg_catalog.pg_index AS i ON c1.oid = i.indrelid
  3236. JOIN pg_catalog.pg_class AS c2 ON i.indexrelid = c2.oid
  3237. LEFT JOIN pg_catalog.pg_attribute AS a ON c1.oid = a.attrelid AND a.attnum = ANY(i.indkey)
  3238. WHERE
  3239. n.nspname = current_schema()
  3240. AND c1.relkind = 'r'
  3241. AND c1.relname = {$this->connection->quote($table)}
  3242. ")as$row){$indexes[$row['name']]['name']=$row['name'];$indexes[$row['name']]['unique']=$row['unique'];$indexes[$row['name']]['primary']=$row['primary'];$indexes[$row['name']]['columns'][]=$row['column'];}return
  3243. array_values($indexes);}function
  3244. getForeignKeys($table){return$this->connection->query("
  3245. SELECT
  3246. co.conname::varchar AS name,
  3247. al.attname::varchar AS local,
  3248. cf.relname::varchar AS table,
  3249. af.attname::varchar AS foreign
  3250. FROM
  3251. pg_catalog.pg_constraint AS co
  3252. JOIN pg_catalog.pg_namespace AS n ON co.connamespace = n.oid
  3253. JOIN pg_catalog.pg_class AS cl ON co.conrelid = cl.oid
  3254. JOIN pg_catalog.pg_class AS cf ON co.confrelid = cf.oid
  3255. JOIN pg_catalog.pg_attribute AS al ON al.attrelid = cl.oid AND al.attnum = co.conkey[1]
  3256. JOIN pg_catalog.pg_attribute AS af ON af.attrelid = cf.oid AND af.attnum = co.confkey[1]
  3257. WHERE
  3258. n.nspname = current_schema()
  3259. AND co.contype = 'f'
  3260. AND cl.relname = {$this->connection->quote($table)}
  3261. ")->fetchAll();}function
  3262. isSupported($item){return$item===self::SUPPORT_COLUMNS_META||$item===self::SUPPORT_SEQUENCE;}}class
  3263. SqliteDriver
  3264. extends
  3265. Nette\Object
  3266. implements
  3267. Nette\Database\ISupplementalDriver{private$connection;private$fmtDateTime;function
  3268. __construct(Nette\Database\Connection$connection,array$options){$this->connection=$connection;$this->fmtDateTime=isset($options['formatDateTime'])?$options['formatDateTime']:'U';}function
  3269. delimite($name){return'['.strtr($name,'[]',' ').']';}function
  3270. formatBool($value){return$value?'1':'0';}function
  3271. formatDateTime(\DateTime$value){return$value->format($this->fmtDateTime);}function
  3272. formatLike($value,$pos){$value=addcslashes(substr($this->connection->quote($value),1,-1),'%_\\');return($pos<=0?"'%":"'").$value.($pos>=0?"%'":"'")." ESCAPE '\\'";}function
  3273. applyLimit(&$sql,$limit,$offset){if($limit>=0||$offset>0){$sql.=' LIMIT '.$limit.($offset>0?' OFFSET '.(int)$offset:'');}}function
  3274. normalizeRow($row,$statement){return$row;}function
  3275. getTables(){return$this->connection->query("
  3276. SELECT name, type = 'view' as view FROM sqlite_master WHERE type IN ('table', 'view')
  3277. UNION ALL
  3278. SELECT name, type = 'view' as view FROM sqlite_temp_master WHERE type IN ('table', 'view')
  3279. ORDER BY name
  3280. ")->fetchAll();}function
  3281. getColumns($table){$meta=$this->connection->query("
  3282. SELECT sql FROM sqlite_master WHERE type = 'table' AND name = {$this->connection->quote($table)}
  3283. UNION ALL
  3284. SELECT sql FROM sqlite_temp_master WHERE type = 'table' AND name = {$this->connection->quote($table)}
  3285. ")->fetch();$columns=array();foreach($this->connection->query("PRAGMA table_info({$this->delimite($table)})")as$row){$column=$row['name'];$pattern="/(\"$column\"|\[$column\]|$column)\\s+[^,]+\\s+PRIMARY\\s+KEY\\s+AUTOINCREMENT/Ui";$type=explode('(',$row['type']);$columns[]=array('name'=>$column,'table'=>$table,'fullname'=>"$table.$column",'nativetype'=>strtoupper($type[0]),'size'=>isset($type[1])?(int)$type[1]:NULL,'nullable'=>$row['notnull']=='0','default'=>$row['dflt_value'],'autoincrement'=>(bool)preg_match($pattern,$meta['sql']),'primary'=>$row['pk']=='1','vendor'=>(array)$row);}return$columns;}function
  3286. getIndexes($table){$indexes=array();foreach($this->connection->query("PRAGMA index_list({$this->delimite($table)})")as$row){$indexes[$row['name']]['name']=$row['name'];$indexes[$row['name']]['unique']=(bool)$row['unique'];}foreach($indexes
  3287. as$index=>$values){$res=$this->connection->query("PRAGMA index_info({$this->delimite($index)})");while($row=$res->fetch(TRUE)){$indexes[$index]['columns'][$row['seqno']]=$row['name'];}}$columns=$this->getColumns($table);foreach($indexes
  3288. as$index=>$values){$column=$indexes[$index]['columns'][0];$primary=FALSE;foreach($columns
  3289. as$info){if($column==$info['name']){$primary=$info['primary'];break;}}$indexes[$index]['primary']=(bool)$primary;}if(!$indexes){foreach($columns
  3290. as$column){if($column['vendor']['pk']){$indexes[]=array('name'=>'ROWID','unique'=>TRUE,'primary'=>TRUE,'columns'=>array($column['name']));break;}}}return
  3291. array_values($indexes);}function
  3292. getForeignKeys($table){$keys=array();foreach($this->connection->query("PRAGMA foreign_key_list({$this->delimite($table)})")as$row){$keys[$row['id']]['name']=$row['id'];$keys[$row['id']]['local']=$row['from'];$keys[$row['id']]['table']=$row['table'];$keys[$row['id']]['foreign']=$row['to'];$keys[$row['id']]['onDelete']=$row['on_delete'];$keys[$row['id']]['onUpdate']=$row['on_update'];if($keys[$row['id']]['foreign'][0]==NULL){$keys[$row['id']]['foreign']=NULL;}}return
  3293. array_values($keys);}function
  3294. isSupported($item){return
  3295. FALSE;}}class
  3296. Sqlite2Driver
  3297. extends
  3298. SqliteDriver{function
  3299. formatLike($value,$pos){throw
  3300. new
  3301. Nette\NotSupportedException;}function
  3302. normalizeRow($row,$statement){if(!is_object($row)){$iterator=$row;}elseif($row
  3303. instanceof\Traversable){$iterator=iterator_to_array($row);}else{$iterator=(array)$row;}foreach($iterator
  3304. as$key=>$value){unset($row[$key]);if($key[0]==='['||$key[0]==='"'){$key=substr($key,1,-1);}$row[$key]=$value;}return$row;}function
  3305. getForeignKeys($table){throw
  3306. new
  3307. NotSupportedException;}}}namespace Nette\Database{use
  3308. Nette;class
  3309. Helpers{public
  3310. static$typePatterns=array('^_'=>IReflection::FIELD_TEXT,'BYTEA|BLOB|BIN'=>IReflection::FIELD_BINARY,'TEXT|CHAR|POINT|INTERVAL'=>IReflection::FIELD_TEXT,'YEAR|BYTE|COUNTER|SERIAL|INT|LONG|SHORT'=>IReflection::FIELD_INTEGER,'CURRENCY|REAL|MONEY|FLOAT|DOUBLE|DECIMAL|NUMERIC|NUMBER'=>IReflection::FIELD_FLOAT,'^TIME$'=>IReflection::FIELD_TIME,'TIME'=>IReflection::FIELD_DATETIME,'DATE'=>IReflection::FIELD_DATE,'BOOL'=>IReflection::FIELD_BOOL);static
  3311. function
  3312. dumpResult(Statement$statement){echo"\n<table class=\"dump\">\n<caption>".htmlSpecialChars($statement->queryString)."</caption>\n";if(!$statement->columnCount()){echo"\t<tr>\n\t\t<th>Affected rows:</th>\n\t\t<td>",$statement->rowCount(),"</td>\n\t</tr>\n</table>\n";return;}$i=0;foreach($statement
  3313. as$row){if($i===0){echo"<thead>\n\t<tr>\n\t\t<th>#row</th>\n";foreach($row
  3314. as$col=>$foo){echo"\t\t<th>".htmlSpecialChars($col)."</th>\n";}echo"\t</tr>\n</thead>\n<tbody>\n";}echo"\t<tr>\n\t\t<th>",$i,"</th>\n";foreach($row
  3315. as$col){echo"\t\t<td>",htmlSpecialChars($col),"</td>\n";}echo"\t</tr>\n";$i++;}if($i===0){echo"\t<tr>\n\t\t<td><em>empty result set</em></td>\n\t</tr>\n</table>\n";}else{echo"</tbody>\n</table>\n";}}static
  3316. function
  3317. dumpSql($sql){static$keywords1='SELECT|(?:ON\s+DUPLICATE\s+KEY)?UPDATE|INSERT(?:\s+INTO)?|REPLACE(?:\s+INTO)?|DELETE|CALL|UNION|FROM|WHERE|HAVING|GROUP\s+BY|ORDER\s+BY|LIMIT|OFFSET|SET|VALUES|LEFT\s+JOIN|INNER\s+JOIN|TRUNCATE';static$keywords2='ALL|DISTINCT|DISTINCTROW|IGNORE|AS|USING|ON|AND|OR|IN|IS|NOT|NULL|LIKE|RLIKE|REGEXP|TRUE|FALSE';$sql=" $sql ";$sql=preg_replace("#(?<=[\\s,(])($keywords1)(?=[\\s,)])#i","\n\$1",$sql);$sql=preg_replace('#[ \t]{2,}#'," ",$sql);$sql=wordwrap($sql,100);$sql=preg_replace('#([ \t]*\r?\n){2,}#',"\n",$sql);$sql=htmlSpecialChars($sql);$sql=preg_replace_callback("#(/\\*.+?\\*/)|(\\*\\*.+?\\*\\*)|(?<=[\\s,(])($keywords1)(?=[\\s,)])|(?<=[\\s,(=])($keywords2)(?=[\\s,)=])#is",function($matches){if(!empty($matches[1])){return'<em style="color:gray">'.$matches[1].'</em>';}elseif(!empty($matches[2])){return'<strong style="color:red">'.$matches[2].'</strong>';}elseif(!empty($matches[3])){return'<strong style="color:blue">'.$matches[3].'</strong>';}elseif(!empty($matches[4])){return'<strong style="color:green">'.$matches[4].'</strong>';}},$sql);return'<pre class="dump">'.trim($sql)."</pre>\n";}static
  3318. function
  3319. detectType($type){static$cache;if(!isset($cache[$type])){$cache[$type]='string';foreach(self::$typePatterns
  3320. as$s=>$val){if(preg_match("#$s#i",$type)){return$cache[$type]=$val;}}}return$cache[$type];}static
  3321. function
  3322. loadFromFile(Connection$connection,$file){@set_time_limit(0);$handle=@fopen($file,'r');if(!$handle){throw
  3323. new
  3324. Nette\FileNotFoundException("Cannot open file '$file'.");}$count=0;$sql='';while(!feof($handle)){$s=fgets($handle);$sql.=$s;if(substr(rtrim($s),-1)===';'){$connection->exec($sql);$sql='';$count++;}}if(trim($sql)!==''){$connection->exec($sql);$count++;}fclose($handle);return$count;}}}namespace Nette\Database\Reflection{use
  3325. Nette;class
  3326. ConventionalReflection
  3327. extends
  3328. Nette\Object
  3329. implements
  3330. Nette\Database\IReflection{protected$primary;protected$foreign;protected$table;function
  3331. __construct($primary='id',$foreign='%s_id',$table='%s'){$this->primary=$primary;$this->foreign=$foreign;$this->table=$table;}function
  3332. getPrimary($table){return
  3333. sprintf($this->primary,$this->getColumnFromTable($table));}function
  3334. getHasManyReference($table,$key){$table=$this->getColumnFromTable($table);return
  3335. array(sprintf($this->table,$key,$table),sprintf($this->foreign,$table,$key));}function
  3336. getBelongsToReference($table,$key){$table=$this->getColumnFromTable($table);return
  3337. array(sprintf($this->table,$key,$table),sprintf($this->foreign,$key,$table));}function
  3338. setConnection(Nette\Database\Connection$connection){}protected
  3339. function
  3340. getColumnFromTable($name){if($this->table!=='%s'&&preg_match('(^'.str_replace('%s','(.*)',preg_quote($this->table)).'\z)',$name,$match)){return$match[1];}return$name;}}class
  3341. DiscoveredReflection
  3342. extends
  3343. Nette\Object
  3344. implements
  3345. Nette\Database\IReflection{protected$cache;protected$cacheStorage;protected$connection;protected$structure=array();protected$loadedStructure;function
  3346. __construct(Nette\Caching\IStorage$storage=NULL){$this->cacheStorage=$storage;}function
  3347. setConnection(Nette\Database\Connection$connection){$this->connection=$connection;if($this->cacheStorage){$this->cache=new
  3348. Nette\Caching\Cache($this->cacheStorage,'Nette.Database.'.md5($connection->getDsn()));$this->structure=$this->loadedStructure=$this->cache->load('structure')?:$this->structure;}}function
  3349. __destruct(){if($this->cache&&$this->structure!==$this->loadedStructure){$this->cache->save('structure',$this->structure);}}function
  3350. getPrimary($table){$primary=&$this->structure['primary'][strtolower($table)];if(isset($primary)){return
  3351. empty($primary)?NULL:$primary;}$columns=$this->connection->getSupplementalDriver()->getColumns($table);$primary=array();foreach($columns
  3352. as$column){if($column['primary']){$primary[]=$column['name'];}}if(count($primary)===0){return
  3353. NULL;}elseif(count($primary)===1){$primary=reset($primary);}return$primary;}function
  3354. getHasManyReference($table,$key,$refresh=TRUE){if(isset($this->structure['hasMany'][strtolower($table)])){$candidates=$columnCandidates=array();foreach($this->structure['hasMany'][strtolower($table)]as$targetPair){list($targetColumn,$targetTable)=$targetPair;if(stripos($targetTable,$key)===FALSE){continue;}$candidates[]=array($targetTable,$targetColumn);if(stripos($targetColumn,$table)!==FALSE){$columnCandidates[]=$candidate=array($targetTable,$targetColumn);if(strtolower($targetTable)===strtolower($key)){return$candidate;}}}if(count($columnCandidates)===1){return
  3355. reset($columnCandidates);}elseif(count($candidates)===1){return
  3356. reset($candidates);}foreach($candidates
  3357. as$candidate){list($targetTable,$targetColumn)=$candidate;if(strtolower($targetTable)===strtolower($key)){return$candidate;}}}if($refresh){$this->reloadAllForeignKeys();return$this->getHasManyReference($table,$key,FALSE);}if(empty($candidates)){throw
  3358. new
  3359. MissingReferenceException("No reference found for \${$table}->related({$key}).");}else{throw
  3360. new
  3361. AmbiguousReferenceKeyException('Ambiguous joining column in related call.');}}function
  3362. getBelongsToReference($table,$key,$refresh=TRUE){if(isset($this->structure['belongsTo'][strtolower($table)])){foreach($this->structure['belongsTo'][strtolower($table)]as$column=>$targetTable){if(stripos($column,$key)!==FALSE){return
  3363. array($targetTable,$column);}}}if($refresh){$this->reloadForeignKeys($table);return$this->getBelongsToReference($table,$key,FALSE);}throw
  3364. new
  3365. MissingReferenceException("No reference found for \${$table}->{$key}.");}protected
  3366. function
  3367. reloadAllForeignKeys(){foreach($this->connection->getSupplementalDriver()->getTables()as$table){if($table['view']==FALSE){$this->reloadForeignKeys($table['name']);}}foreach($this->structure['hasMany']as&$table){uksort($table,function($a,$b){return
  3368. strlen($a)-strlen($b);});}}protected
  3369. function
  3370. reloadForeignKeys($table){foreach($this->connection->getSupplementalDriver()->getForeignKeys($table)as$row){$this->structure['belongsTo'][strtolower($table)][$row['local']]=$row['table'];$this->structure['hasMany'][strtolower($row['table'])][$row['local'].$table]=array($row['local'],$table);}if(isset($this->structure['belongsTo'][$table])){uksort($this->structure['belongsTo'][$table],function($a,$b){return
  3371. strlen($a)-strlen($b);});}}}use
  3372. PDOException;if(class_exists('PDO')){class
  3373. MissingReferenceException
  3374. extends
  3375. PDOException{}class
  3376. AmbiguousReferenceKeyException
  3377. extends
  3378. PDOException{}}}namespace Nette\Database{use
  3379. Nette;class
  3380. Row
  3381. extends
  3382. Nette\ArrayHash{function
  3383. __construct(Statement$statement){$statement->normalizeRow($this);}function
  3384. offsetGet($key){if(is_int($key)){$arr=array_values((array)$this);return$arr[$key];}return$this->$key;}function
  3385. offsetExists($key){if(is_int($key)){$arr=array_values((array)$this);return
  3386. isset($arr[$key]);}return
  3387. parent::offsetExists($key);}}class
  3388. SqlLiteral
  3389. extends
  3390. Nette\Object{private$value='';function
  3391. __construct($value){$this->value=(string)$value;}function
  3392. __toString(){return$this->value;}}class
  3393. SqlPreprocessor
  3394. extends
  3395. Nette\Object{private$connection;private$driver;private$params;private$remaining;private$counter;private$arrayMode;function
  3396. __construct(Connection$connection){$this->connection=$connection;$this->driver=$connection->getSupplementalDriver();}function
  3397. process($sql,$params){$this->params=$params;$this->counter=0;$this->remaining=array();$this->arrayMode='assoc';$sql=Nette\Utils\Strings::replace($sql,'~\'.*?\'|".*?"|\?|\b(?:INSERT|REPLACE|UPDATE)\b~si',array($this,'callback'));while($this->counter<count($params)){$sql.=' '.$this->formatValue($params[$this->counter++]);}return
  3398. array($sql,$this->remaining);}function
  3399. callback($m){$m=$m[0];if($m[0]==="'"||$m[0]==='"'){return$m;}elseif($m==='?'){return$this->formatValue($this->params[$this->counter++]);}else{$this->arrayMode=strtoupper($m)==='UPDATE'?'assoc':'values';return$m;}}private
  3400. function
  3401. formatValue($value){if(is_string($value)){if(strlen($value)>20){$this->remaining[]=$value;return'?';}else{return$this->connection->quote($value);}}elseif(is_int($value)){return(string)$value;}elseif(is_float($value)){return
  3402. rtrim(rtrim(number_format($value,10,'.',''),'0'),'.');}elseif(is_bool($value)){return$this->driver->formatBool($value);}elseif($value===NULL){return'NULL';}elseif($value
  3403. instanceof
  3404. Table\ActiveRow){return$value->getPrimary();}elseif(is_array($value)||$value
  3405. instanceof\Traversable){$vx=$kx=array();if(isset($value[0])){foreach($value
  3406. as$v){$vx[]=$this->formatValue($v);}return
  3407. implode(', ',$vx);}elseif($this->arrayMode==='values'){$this->arrayMode='multi';foreach($value
  3408. as$k=>$v){$kx[]=$this->driver->delimite($k);$vx[]=$this->formatValue($v);}return'('.implode(', ',$kx).') VALUES ('.implode(', ',$vx).')';}elseif($this->arrayMode==='assoc'){foreach($value
  3409. as$k=>$v){$vx[]=$this->driver->delimite($k).'='.$this->formatValue($v);}return
  3410. implode(', ',$vx);}elseif($this->arrayMode==='multi'){foreach($value
  3411. as$k=>$v){$vx[]=$this->formatValue($v);}return'('.implode(', ',$vx).')';}}elseif($value
  3412. instanceof\DateTime){return$this->driver->formatDateTime($value);}elseif($value
  3413. instanceof
  3414. SqlLiteral){return$value->__toString();}else{$this->remaining[]=$value;return'?';}}}use
  3415. PDO;use
  3416. Nette\ObjectMixin;if(class_exists('PDO')){class
  3417. Statement
  3418. extends\PDOStatement{private$connection;private$time;private$types;protected
  3419. function
  3420. __construct(Connection$connection){$this->connection=$connection;$this->setFetchMode(PDO::FETCH_CLASS,'Nette\Database\Row',array($this));}function
  3421. getConnection(){return$this->connection;}function
  3422. execute($params=array()){static$types=array('boolean'=>PDO::PARAM_BOOL,'integer'=>PDO::PARAM_INT,'resource'=>PDO::PARAM_LOB,'NULL'=>PDO::PARAM_NULL);foreach($params
  3423. as$key=>$value){$type=gettype($value);$this->bindValue(is_int($key)?$key+1:$key,$value,isset($types[$type])?$types[$type]:PDO::PARAM_STR);}$time=microtime(TRUE);try{parent::execute();}catch(\PDOException$e){$e->queryString=$this->queryString;throw$e;}$this->time=microtime(TRUE)-$time;$this->connection->__call('onQuery',array($this,$params));return$this;}function
  3424. fetchPairs(){return$this->fetchAll(PDO::FETCH_KEY_PAIR);}function
  3425. normalizeRow($row){foreach($this->detectColumnTypes()as$key=>$type){$value=$row[$key];if($value===NULL||$value===FALSE||$type===IReflection::FIELD_TEXT){}elseif($type===IReflection::FIELD_INTEGER){$row[$key]=is_float($tmp=$value*1)?$value:$tmp;}elseif($type===IReflection::FIELD_FLOAT){$value=strpos($value,'.')===FALSE?$value:rtrim(rtrim($value,'0'),'.');$float=(float)$value;$row[$key]=(string)$float===$value?$float:$value;}elseif($type===IReflection::FIELD_BOOL){$row[$key]=((bool)$value)&&$value!=='f'&&$value!=='F';}elseif($type===IReflection::FIELD_DATETIME||$type===IReflection::FIELD_DATE||$type===IReflection::FIELD_TIME){$row[$key]=new
  3426. Nette\DateTime($value);}}return$this->connection->getSupplementalDriver()->normalizeRow($row,$this);}private
  3427. function
  3428. detectColumnTypes(){if($this->types===NULL){$this->types=array();if($this->connection->getSupplementalDriver()->isSupported(ISupplementalDriver::SUPPORT_COLUMNS_META)){$col=0;while($meta=$this->getColumnMeta($col++)){if(isset($meta['native_type'])){$this->types[$meta['name']]=Helpers::detectType($meta['native_type']);}}}}return$this->types;}function
  3429. getTime(){return$this->time;}function
  3430. dump(){Helpers::dumpResult($this);}static
  3431. function
  3432. getReflection(){return
  3433. new
  3434. Nette\Reflection\ClassType(get_called_class());}function
  3435. __call($name,$args){return
  3436. ObjectMixin::call($this,$name,$args);}function&__get($name){return
  3437. ObjectMixin::get($this,$name);}function
  3438. __set($name,$value){return
  3439. ObjectMixin::set($this,$name,$value);}function
  3440. __isset($name){return
  3441. ObjectMixin::has($this,$name);}function
  3442. __unset($name){ObjectMixin::remove($this,$name);}}}}namespace Nette\Database\Table{use
  3443. Nette;use
  3444. Nette\Database\Reflection\MissingReferenceException;class
  3445. ActiveRow
  3446. extends
  3447. Nette\Object
  3448. implements\IteratorAggregate,\ArrayAccess{private$table;private$data;private$dataRefreshed=FALSE;private$modified=array();function
  3449. __construct(array$data,Selection$table){$this->data=$data;$this->table=$table;}function
  3450. setTable(Selection$table){$this->table=$table;}function
  3451. getTable(){return$this->table;}function
  3452. __toString(){try{return(string)$this->getPrimary();}catch(\Exception$e){trigger_error("Exception in ".__METHOD__."(): {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}",E_USER_ERROR);}}function
  3453. toArray(){$this->accessColumn(NULL);return$this->data;}function
  3454. getPrimary($need=TRUE){$primary=$this->table->getPrimary();if(!is_array($primary)){if(isset($this->data[$primary])){return$this->data[$primary];}elseif($need){throw
  3455. new
  3456. Nette\InvalidStateException("Row does not contain primary $primary column data.");}else{return
  3457. NULL;}}else{$primaryVal=array();foreach($primary
  3458. as$key){if(!isset($this->data[$key])){if($need){throw
  3459. new
  3460. Nette\InvalidStateException("Row does not contain primary $key column data.");}else{return
  3461. NULL;}}$primaryVal[$key]=$this->data[$key];}return$primaryVal;}}function
  3462. getSignature($need=TRUE){return
  3463. implode('|',(array)$this->getPrimary($need));}function
  3464. ref($key,$throughColumn=NULL){if(!$throughColumn){list($key,$throughColumn)=$this->table->getConnection()->getDatabaseReflection()->getBelongsToReference($this->table->getName(),$key);}return$this->getReference($key,$throughColumn);}function
  3465. related($key,$throughColumn=NULL){if(strpos($key,'.')!==FALSE){list($key,$throughColumn)=explode('.',$key);}elseif(!$throughColumn){list($key,$throughColumn)=$this->table->getConnection()->getDatabaseReflection()->getHasManyReference($this->table->getName(),$key);}return$this->table->getReferencingTable($key,$throughColumn,$this[$this->table->getPrimary()]);}function
  3466. update($data=NULL){if($data===NULL){$data=$this->modified;}return$this->table->getConnection()->table($this->table->getName())->wherePrimary($this->getPrimary())->update($data);}function
  3467. delete(){$res=$this->table->getConnection()->table($this->table->getName())->wherePrimary($this->getPrimary())->delete();if($res>0&&($signature=$this->getSignature(FALSE))){unset($this->table[$signature]);}return$res;}function
  3468. getIterator(){$this->accessColumn(NULL);return
  3469. new\ArrayIterator($this->data);}function
  3470. offsetSet($key,$value){$this->__set($key,$value);}function
  3471. offsetGet($key){return$this->__get($key);}function
  3472. offsetExists($key){return$this->__isset($key);}function
  3473. offsetUnset($key){$this->__unset($key);}function
  3474. __set($key,$value){$this->data[$key]=$value;$this->modified[$key]=$value;}function&__get($key){$this->accessColumn($key);if(array_key_exists($key,$this->data)){return$this->data[$key];}try{list($table,$column)=$this->table->getConnection()->getDatabaseReflection()->getBelongsToReference($this->table->getName(),$key);$referenced=$this->getReference($table,$column);if($referenced!==FALSE){$this->accessColumn($key,FALSE);return$referenced;}}catch(MissingReferenceException$e){}$this->removeAccessColumn($key);throw
  3475. new
  3476. Nette\MemberAccessException("Cannot read an undeclared column \"$key\".");}function
  3477. __isset($key){$this->accessColumn($key);if(array_key_exists($key,$this->data)){return
  3478. isset($this->data[$key]);}$this->removeAccessColumn($key);return
  3479. FALSE;}function
  3480. __unset($key){unset($this->data[$key]);unset($this->modified[$key]);}protected
  3481. function
  3482. accessColumn($key,$selectColumn=TRUE){if(isset($this->modified[$key])){return;}$this->table->accessColumn($key,$selectColumn);if($this->table->getDataRefreshed()&&!$this->dataRefreshed){$this->data=$this->table[$this->getSignature()]->data;$this->dataRefreshed=TRUE;}}protected
  3483. function
  3484. removeAccessColumn($key){$this->table->removeAccessColumn($key);}protected
  3485. function
  3486. getReference($table,$column){$this->accessColumn($column);if(array_key_exists($column,$this->data)){$value=$this->data[$column];$value=$value
  3487. instanceof
  3488. ActiveRow?$value->getPrimary():$value;$referenced=$this->table->getReferencedTable($table,$column,!empty($this->modified[$column]));$referenced=isset($referenced[$value])?$referenced[$value]:NULL;if(!empty($this->modified[$column])){$this->modified[$column]=0;}return$referenced;}return
  3489. FALSE;}}use
  3490. Nette\Database\ISupplementalDriver;use
  3491. PDO;class
  3492. Selection
  3493. extends
  3494. Nette\Object
  3495. implements\Iterator,\ArrayAccess,\Countable{protected$connection;protected$cache;protected$sqlBuilder;protected$name;protected$primary;protected$primarySequence=FALSE;protected$rows;protected$data;protected$dataRefreshed=FALSE;protected$referenced=array();protected$referencing=array();protected$referencingPrototype=array();protected$aggregation=array();protected$accessedColumns;protected$previousAccessedColumns;protected$observeCache=FALSE;protected$checkReferenced=FALSE;protected$keys=array();function
  3496. __construct($table,Nette\Database\Connection$connection){$this->name=$table;$this->connection=$connection;$reflection=$connection->getDatabaseReflection();$this->primary=$reflection->getPrimary($table);$this->sqlBuilder=new
  3497. SqlBuilder($table,$connection,$reflection);$this->cache=$connection->getCache();}function
  3498. __destruct(){$this->saveCacheState();}function
  3499. __clone(){$this->sqlBuilder=clone$this->sqlBuilder;}function
  3500. getConnection(){return$this->connection;}function
  3501. getName(){return$this->name;}function
  3502. getPrimary(){return$this->primary;}function
  3503. getPrimarySequence(){if($this->primarySequence===FALSE){$this->primarySequence=NULL;$driver=$this->connection->getSupplementalDriver();if($driver->isSupported(ISupplementalDriver::SUPPORT_SEQUENCE)){foreach($driver->getColumns($this->name)as$column){if($column['name']===$this->primary){$this->primarySequence=$column['vendor']['sequence'];break;}}}}return$this->primarySequence;}function
  3504. setPrimarySequence($sequence){$this->primarySequence=$sequence;return$this;}function
  3505. getSql(){return$this->sqlBuilder->buildSelectQuery($this->getPreviousAccessedColumns());}function
  3506. getPreviousAccessedColumns(){if($this->cache&&$this->previousAccessedColumns===NULL){$this->accessedColumns=$this->previousAccessedColumns=$this->cache->load(array(__CLASS__,$this->name,$this->sqlBuilder->getConditions()));}return
  3507. array_keys(array_filter((array)$this->previousAccessedColumns));}function
  3508. getSqlBuilder(){return$this->sqlBuilder;}function
  3509. get($key){$clone=clone$this;return$clone->wherePrimary($key)->fetch();}function
  3510. fetch(){$this->execute();$return=current($this->data);next($this->data);return$return;}function
  3511. fetchPairs($key,$value=NULL){$return=array();foreach($this
  3512. as$row){$return[is_object($row[$key])?(string)$row[$key]:$row[$key]]=($value?$row[$value]:$row);}return$return;}function
  3513. select($columns){$this->emptyResultSet();$this->sqlBuilder->addSelect($columns);return$this;}function
  3514. find($key){return$this->wherePrimary($key);}function
  3515. wherePrimary($key){if(is_array($this->primary)&&Nette\Utils\Validators::isList($key)){foreach($this->primary
  3516. as$i=>$primary){$this->where($primary,$key[$i]);}}elseif(is_array($key)){$this->where($key);}else{$this->where($this->primary,$key);}return$this;}function
  3517. where($condition,$parameters=array()){if(is_array($condition)){foreach($condition
  3518. as$key=>$val){if(is_int($key)){$this->where($val);}else{$this->where($key,$val);}}return$this;}$args=func_get_args();if(call_user_func_array(array($this->sqlBuilder,'addWhere'),$args)){$this->emptyResultSet();}return$this;}function
  3519. order($columns){$this->emptyResultSet();$this->sqlBuilder->addOrder($columns);return$this;}function
  3520. limit($limit,$offset=NULL){$this->emptyResultSet();$this->sqlBuilder->setLimit($limit,$offset);return$this;}function
  3521. page($page,$itemsPerPage){return$this->limit($itemsPerPage,($page-1)*$itemsPerPage);}function
  3522. group($columns,$having=NULL){$this->emptyResultSet();$this->sqlBuilder->setGroup($columns,$having);return$this;}function
  3523. aggregation($function){$selection=$this->createSelectionInstance();$selection->getSqlBuilder()->importConditions($this->getSqlBuilder());$selection->select($function);foreach($selection->fetch()as$val){return$val;}}function
  3524. count($column=NULL){if(!$column){$this->execute();return
  3525. count($this->data);}return$this->aggregation("COUNT($column)");}function
  3526. min($column){return$this->aggregation("MIN($column)");}function
  3527. max($column){return$this->aggregation("MAX($column)");}function
  3528. sum($column){return$this->aggregation("SUM($column)");}protected
  3529. function
  3530. execute(){if($this->rows!==NULL){return;}$this->observeCache=TRUE;try{$result=$this->query($this->getSql());}catch(\PDOException$exception){if(!$this->sqlBuilder->getSelect()&&$this->previousAccessedColumns){$this->previousAccessedColumns=FALSE;$this->accessedColumns=array();$result=$this->query($this->getSql());}else{throw$exception;}}$this->rows=array();$usedPrimary=TRUE;$result->setFetchMode(PDO::FETCH_ASSOC);foreach($result
  3531. as$key=>$row){$row=$this->createRow($result->normalizeRow($row));$primary=$row->getSignature(FALSE);$usedPrimary=$usedPrimary&&$primary;$this->rows[$primary?:$key]=$row;}$this->data=$this->rows;if($usedPrimary&&$this->accessedColumns!==FALSE){foreach((array)$this->primary
  3532. as$primary){$this->accessedColumns[$primary]=TRUE;}}}protected
  3533. function
  3534. createRow(array$row){return
  3535. new
  3536. ActiveRow($row,$this);}protected
  3537. function
  3538. createSelectionInstance($table=NULL){return
  3539. new
  3540. Selection($table?:$this->name,$this->connection);}protected
  3541. function
  3542. createGroupedSelectionInstance($table,$column){return
  3543. new
  3544. GroupedSelection($this,$table,$column);}protected
  3545. function
  3546. query($query){return$this->connection->queryArgs($query,$this->sqlBuilder->getParameters());}protected
  3547. function
  3548. emptyResultSet(){if($this->rows===NULL){return;}$this->rows=NULL;$this->saveCacheState();}protected
  3549. function
  3550. saveCacheState(){if($this->observeCache&&$this->cache&&!$this->sqlBuilder->getSelect()&&$this->accessedColumns!=$this->previousAccessedColumns){$this->cache->save(array(__CLASS__,$this->name,$this->sqlBuilder->getConditions()),$this->accessedColumns);}}protected
  3551. function
  3552. getRefTable(&$refPath){return$this;}function
  3553. accessColumn($key,$selectColumn=TRUE){if(!$this->cache){return;}if($key===NULL){$this->accessedColumns=FALSE;$currentKey=key($this->data);}elseif($this->accessedColumns!==FALSE){$this->accessedColumns[$key]=$selectColumn;}if($selectColumn&&!$this->sqlBuilder->getSelect()&&$this->previousAccessedColumns&&($key===NULL||!isset($this->previousAccessedColumns[$key]))){$this->previousAccessedColumns=FALSE;$this->emptyResultSet();$this->dataRefreshed=TRUE;if($key===NULL){$this->execute();while(key($this->data)!==$currentKey){next($this->data);}}}}function
  3554. removeAccessColumn($key){if($this->cache&&is_array($this->accessedColumns)){$this->accessedColumns[$key]=FALSE;}}function
  3555. getDataRefreshed(){return$this->dataRefreshed;}function
  3556. insert($data){if($data
  3557. instanceof
  3558. Selection){$data=$data->getSql();}elseif($data
  3559. instanceof\Traversable){$data=iterator_to_array($data);}$return=$this->connection->query($this->sqlBuilder->buildInsertQuery(),$data);$this->checkReferenced=TRUE;if(!is_array($data)){return$return->rowCount();}if(!is_array($this->primary)&&!isset($data[$this->primary])&&($id=$this->connection->lastInsertId($this->getPrimarySequence()))){$data[$this->primary]=$id;}$row=$this->createRow($data);if($signature=$row->getSignature(FALSE)){$this->rows[$signature]=$row;}return$row;}function
  3560. update($data){if($data
  3561. instanceof\Traversable){$data=iterator_to_array($data);}elseif(!is_array($data)){throw
  3562. new
  3563. Nette\InvalidArgumentException;}if(!$data){return
  3564. 0;}return$this->connection->queryArgs($this->sqlBuilder->buildUpdateQuery(),array_merge(array($data),$this->sqlBuilder->getParameters()))->rowCount();}function
  3565. delete(){return$this->query($this->sqlBuilder->buildDeleteQuery())->rowCount();}function
  3566. getReferencedTable($table,$column,$checkReferenced=FALSE){$referenced=&$this->getRefTable($refPath)->referenced[$refPath."$table.$column"];if($referenced===NULL||$checkReferenced||$this->checkReferenced){$this->execute();$this->checkReferenced=FALSE;$keys=array();foreach($this->rows
  3567. as$row){if($row[$column]===NULL){continue;}$key=$row[$column]instanceof
  3568. ActiveRow?$row[$column]->getPrimary():$row[$column];$keys[$key]=TRUE;}if($referenced!==NULL&&array_keys($keys)===array_keys($referenced->rows)){return$referenced;}if($keys){$referenced=$this->createSelectionInstance($table);$referenced->where($referenced->primary,array_keys($keys));}else{$referenced=array();}}return$referenced;}function
  3569. getReferencingTable($table,$column,$active=NULL){$prototype=&$this->getRefTable($refPath)->referencingPrototype[$refPath."$table.$column"];if(!$prototype){$prototype=$this->createGroupedSelectionInstance($table,$column);$prototype->where("$table.$column",array_keys((array)$this->rows));}$clone=clone$prototype;$clone->setActive($active);return$clone;}function
  3570. rewind(){$this->execute();$this->keys=array_keys($this->data);reset($this->keys);}function
  3571. current(){if(($key=current($this->keys))!==FALSE){return$this->data[$key];}else{return
  3572. FALSE;}}function
  3573. key(){return
  3574. current($this->keys);}function
  3575. next(){next($this->keys);}function
  3576. valid(){return
  3577. current($this->keys)!==FALSE;}function
  3578. offsetSet($key,$value){$this->execute();$this->rows[$key]=$value;}function
  3579. offsetGet($key){$this->execute();return$this->rows[$key];}function
  3580. offsetExists($key){$this->execute();return
  3581. isset($this->rows[$key]);}function
  3582. offsetUnset($key){$this->execute();unset($this->rows[$key],$this->data[$key]);}}class
  3583. GroupedSelection
  3584. extends
  3585. Selection{protected$refTable;protected$column;protected$active;function
  3586. __construct(Selection$refTable,$table,$column){parent::__construct($table,$refTable->connection);$this->refTable=$refTable;$this->column=$column;}function
  3587. setActive($active){$this->active=$active;return$this;}function
  3588. through($column){trigger_error(__METHOD__.'() is deprecated; use '.__CLASS__.'::related("'.$this->name.'", "'.$column.'") instead.',E_USER_WARNING);$this->column=$column;$this->delimitedColumn=$this->refTable->connection->getSupplementalDriver()->delimite($this->column);return$this;}function
  3589. select($columns){if(!$this->sqlBuilder->getSelect()){$this->sqlBuilder->addSelect("$this->name.$this->column");}return
  3590. parent::select($columns);}function
  3591. order($columns){if(!$this->sqlBuilder->getOrder()){$this->sqlBuilder->addOrder("$this->name.$this->column".(preg_match('~\bDESC\z~i',$columns)?' DESC':''));}return
  3592. parent::order($columns);}function
  3593. aggregation($function){$aggregation=&$this->getRefTable($refPath)->aggregation[$refPath.$function.$this->getSql().json_encode($this->sqlBuilder->getParameters())];if($aggregation===NULL){$aggregation=array();$selection=$this->createSelectionInstance();$selection->getSqlBuilder()->importConditions($this->getSqlBuilder());$selection->select($function);$selection->select("$this->name.$this->column");$selection->group("$this->name.$this->column");foreach($selection
  3594. as$row){$aggregation[$row[$this->column]]=$row;}}if(isset($aggregation[$this->active])){foreach($aggregation[$this->active]as$val){return$val;}}}function
  3595. count($column=NULL){$return=parent::count($column);return
  3596. isset($return)?$return:0;}protected
  3597. function
  3598. execute(){if($this->rows!==NULL){return;}$hash=md5($this->getSql().json_encode($this->sqlBuilder->getParameters()));$referencing=&$this->getRefTable($refPath)->referencing[$refPath.$hash];$this->rows=&$referencing['rows'];$this->referenced=&$referencing['refs'];$this->accessedColumns=&$referencing['accessed'];$refData=&$referencing['data'];if($refData===NULL){$limit=$this->sqlBuilder->getLimit();$rows=count($this->refTable->rows);if($limit&&$rows>1){$this->sqlBuilder->setLimit(NULL,NULL);}parent::execute();$this->sqlBuilder->setLimit($limit,NULL);$refData=array();$offset=array();$this->accessColumn($this->column);foreach((array)$this->rows
  3599. as$key=>$row){$ref=&$refData[$row[$this->column]];$skip=&$offset[$row[$this->column]];if($limit===NULL||$rows<=1||(count($ref)<$limit&&$skip>=$this->sqlBuilder->getOffset())){$ref[$key]=$row;}else{unset($this->rows[$key]);}$skip++;unset($ref,$skip);}}$this->data=&$refData[$this->active];if($this->data===NULL){$this->data=array();}else{foreach($this->data
  3600. as$row){$row->setTable($this);}reset($this->data);$this->checkReferenced=TRUE;}}protected
  3601. function
  3602. getRefTable(&$refPath){$refObj=$this->refTable;$refPath=$this->name.'.';while($refObj
  3603. instanceof
  3604. GroupedSelection){$refPath.=$refObj->name.'.';$refObj=$refObj->refTable;}return$refObj;}function
  3605. insert($data){if($data
  3606. instanceof\Traversable&&!$data
  3607. instanceof
  3608. Selection){$data=iterator_to_array($data);}if(Nette\Utils\Validators::isList($data)){foreach(array_keys($data)as$key){$data[$key][$this->column]=$this->active;}}else{$data[$this->column]=$this->active;}return
  3609. parent::insert($data);}function
  3610. update($data){$builder=$this->sqlBuilder;$this->sqlBuilder=clone$this->sqlBuilder;$this->where($this->column,$this->active);$return=parent::update($data);$this->sqlBuilder=$builder;return$return;}function
  3611. delete(){$builder=$this->sqlBuilder;$this->sqlBuilder=clone$this->sqlBuilder;$this->where($this->column,$this->active);$return=parent::delete();$this->sqlBuilder=$builder;return$return;}}use
  3612. Nette\Database\Connection;use
  3613. Nette\Database\IReflection;class
  3614. SqlBuilder
  3615. extends
  3616. Nette\Object{private$driver;private$driverName;protected$tableName;protected$databaseReflection;protected$delimitedTable;protected$select=array();protected$where=array();protected$conditions=array();protected$parameters=array();protected$order=array();protected$limit=NULL;protected$offset=NULL;protected$group='';protected$having='';function
  3617. __construct($tableName,Connection$connection,IReflection$reflection){$this->tableName=$tableName;$this->databaseReflection=$reflection;$this->driver=$connection->getSupplementalDriver();$this->driverName=$connection->getAttribute(\PDO::ATTR_DRIVER_NAME);$this->delimitedTable=$this->tryDelimite($tableName);}function
  3618. buildInsertQuery(){return"INSERT INTO {$this->delimitedTable}";}function
  3619. buildUpdateQuery(){return"UPDATE{$this->buildTopClause()} {$this->delimitedTable} SET ?".$this->buildConditions();}function
  3620. buildDeleteQuery(){return"DELETE{$this->buildTopClause()} FROM {$this->delimitedTable}".$this->buildConditions();}function
  3621. importConditions(SqlBuilder$builder){$this->where=$builder->where;$this->parameters=$builder->parameters;$this->conditions=$builder->conditions;}function
  3622. addSelect($columns){$this->select[]=$columns;}function
  3623. getSelect(){return$this->select;}function
  3624. addWhere($condition,$parameters=array()){$args=func_get_args();$hash=md5(json_encode($args));if(isset($this->conditions[$hash])){return
  3625. FALSE;}$this->conditions[$hash]=$condition;$condition=$this->removeExtraTables($condition);$condition=$this->tryDelimite($condition);if(count($args)!==2||strpbrk($condition,'?:')){if(count($args)!==2||!is_array($parameters)){$parameters=$args;array_shift($parameters);}$this->parameters=array_merge($this->parameters,$parameters);}elseif($parameters===NULL){$condition.=' IS NULL';}elseif($parameters
  3626. instanceof
  3627. Selection){$clone=clone$parameters;if(!$clone->getSqlBuilder()->select){$clone->select($clone->primary);}if($this->driverName!=='mysql'){$condition.=' IN ('.$clone->getSql().')';}else{$in=array();foreach($clone
  3628. as$row){$this->parameters[]=array_values(iterator_to_array($row));$in[]=(count($row)===1?'?':'(?)');}$condition.=' IN ('.($in?implode(', ',$in):'NULL').')';}}elseif(!is_array($parameters)){$condition.=' = ?';$this->parameters[]=$parameters;}else{if($parameters){$condition.=" IN (?)";$this->parameters[]=$parameters;}else{$condition.=" IN (NULL)";}}$this->where[]=$condition;return
  3629. TRUE;}function
  3630. getConditions(){return
  3631. array_values($this->conditions);}function
  3632. addOrder($columns){$this->order[]=$columns;}function
  3633. getOrder(){return$this->order;}function
  3634. setLimit($limit,$offset){$this->limit=$limit;$this->offset=$offset;}function
  3635. getLimit(){return$this->limit;}function
  3636. getOffset(){return$this->offset;}function
  3637. setGroup($columns,$having){$this->group=$columns;$this->having=$having;}function
  3638. getGroup(){return$this->group;}function
  3639. getHaving(){return$this->having;}function
  3640. buildSelectQuery($columns=NULL){$join=$this->buildJoins(implode(',',$this->conditions),TRUE);$join+=$this->buildJoins(implode(',',$this->select).",{$this->group},{$this->having},".implode(',',$this->order));$prefix=$join?"{$this->delimitedTable}.":'';if($this->select){$cols=$this->tryDelimite($this->removeExtraTables(implode(', ',$this->select)));}elseif($columns){$cols=array_map(array($this->driver,'delimite'),$columns);$cols=$prefix.implode(', '.$prefix,$cols);}elseif($this->group&&!$this->driver->isSupported(ISupplementalDriver::SUPPORT_SELECT_UNGROUPED_COLUMNS)){$cols=$this->tryDelimite($this->removeExtraTables($this->group));}else{$cols=$prefix.'*';}return"SELECT{$this->buildTopClause()} {$cols} FROM {$this->delimitedTable}".implode($join).$this->buildConditions();}function
  3641. getParameters(){return$this->parameters;}protected
  3642. function
  3643. buildJoins($val,$inner=FALSE){$joins=array();preg_match_all('~\\b([a-z][\\w.:]*[.:])([a-z]\\w*|\*)(\\s+IS\\b|\\s*<=>)?~i',$val,$matches);foreach($matches[1]as$names){$parent=$parentAlias=$this->tableName;if($names!=="$parent."){preg_match_all('~\\b([a-z][\\w]*|\*)([.:])~i',$names,$matches,PREG_SET_ORDER);foreach($matches
  3644. as$match){list(,$name,$delimiter)=$match;if($delimiter===':'){list($table,$primary)=$this->databaseReflection->getHasManyReference($parent,$name);$column=$this->databaseReflection->getPrimary($parent);}else{list($table,$column)=$this->databaseReflection->getBelongsToReference($parent,$name);$primary=$this->databaseReflection->getPrimary($table);}$joins[$name]=' '.(!isset($joins[$name])&&$inner&&!isset($match[3])?'INNER':'LEFT').' JOIN '.$this->driver->delimite($table).($table!==$name?' AS '.$this->driver->delimite($name):'').' ON '.$this->driver->delimite($parentAlias).'.'.$this->driver->delimite($column).' = '.$this->driver->delimite($name).'.'.$this->driver->delimite($primary);$parent=$table;$parentAlias=$name;}}}return$joins;}protected
  3645. function
  3646. buildConditions(){$return='';$where=$this->where;if($this->limit!==NULL&&$this->driverName==='oci'){$where[]=($this->offset?"rownum > $this->offset AND ":'').'rownum <= '.($this->limit+$this->offset);}if($where){$return.=' WHERE ('.implode(') AND (',$where).')';}if($this->group){$return.=' GROUP BY '.$this->tryDelimite($this->removeExtraTables($this->group));}if($this->having){$return.=' HAVING '.$this->tryDelimite($this->removeExtraTables($this->having));}if($this->order){$return.=' ORDER BY '.$this->tryDelimite($this->removeExtraTables(implode(', ',$this->order)));}if($this->limit!==NULL&&$this->driverName!=='oci'&&$this->driverName!=='dblib'){$return.=" LIMIT $this->limit";if($this->offset!==NULL){$return.=" OFFSET $this->offset";}}return$return;}protected
  3647. function
  3648. buildTopClause(){if($this->limit!==NULL&&$this->driverName==='dblib'){return" TOP ($this->limit)";}return'';}protected
  3649. function
  3650. tryDelimite($s){$driver=$this->driver;return
  3651. preg_replace_callback('#(?<=[^\w`"\[]|^)[a-z_][a-z0-9_]*(?=[^\w`"(\]]|\z)#i',function($m)use($driver){return
  3652. strtoupper($m[0])===$m[0]?$m[0]:$driver->delimite($m[0]);},$s);}protected
  3653. function
  3654. removeExtraTables($expression){return
  3655. preg_replace('~(?:\\b[a-z_][a-z0-9_.:]*[.:])?([a-z_][a-z0-9_]*)[.:]([a-z_*])~i','\\1.\\2',$expression);}}}namespace Nette\DI{use
  3656. Nette;class
  3657. Container
  3658. extends
  3659. Nette\FreezableObject
  3660. implements
  3661. IContainer{const
  3662. TAGS='tags';public$parameters=array();public$params=array();public$classes=array();private$registry=array();private$factories=array();public$meta=array();private$creating;function
  3663. __construct(array$params=array()){$this->parameters=$params+$this->parameters;$this->params=&$this->parameters;}function
  3664. getParameters(){return$this->parameters;}function
  3665. addService($name,$service,array$meta=NULL){$this->updating();if(!is_string($name)||!$name){throw
  3666. new
  3667. Nette\InvalidArgumentException("Service name must be a non-empty string, ".gettype($name)." given.");}if(isset($this->registry[$name])){throw
  3668. new
  3669. Nette\InvalidStateException("Service '$name' has already been registered.");}if(is_object($service)&&!$service
  3670. instanceof\Closure&&!$service
  3671. instanceof
  3672. Nette\Callback){$this->registry[$name]=$service;$this->meta[$name]=$meta;return$this;}elseif(!is_string($service)||strpos($service,':')!==FALSE){$service=new
  3673. Nette\Callback($service);}$this->factories[$name]=array($service);$this->registry[$name]=&$this->factories[$name][1];$this->meta[$name]=$meta;return$this;}function
  3674. removeService($name){$this->updating();unset($this->registry[$name],$this->factories[$name],$this->meta[$name]);}function
  3675. getService($name){if(isset($this->registry[$name])){return$this->registry[$name];}elseif(isset($this->creating[$name])){throw
  3676. new
  3677. Nette\InvalidStateException("Circular reference detected for services: ".implode(', ',array_keys($this->creating)).".");}if(isset($this->factories[$name])){list($factory)=$this->factories[$name];if(is_string($factory)){if(!class_exists($factory)){throw
  3678. new
  3679. Nette\InvalidStateException("Cannot instantiate service, class '$factory' not found.");}try{$this->creating[$name]=TRUE;$service=new$factory;}catch(\Exception$e){}}elseif(!$factory->isCallable()){throw
  3680. new
  3681. Nette\InvalidStateException("Unable to create service '$name', factory '$factory' is not callable.");}else{$this->creating[$name]=TRUE;try{$service=$factory($this);}catch(\Exception$e){}}}elseif(method_exists($this,$factory=Container::getMethodName($name))&&$this->getReflection()->getMethod($factory)->getName()===$factory){$this->creating[$name]=TRUE;try{$service=$this->$factory();}catch(\Exception$e){}}else{throw
  3682. new
  3683. MissingServiceException("Service '$name' not found.");}unset($this->creating[$name]);if(isset($e)){throw$e;}elseif(!is_object($service)){throw
  3684. new
  3685. Nette\UnexpectedValueException("Unable to create service '$name', value returned by factory '$factory' is not object.");}return$this->registry[$name]=$service;}function
  3686. hasService($name){return
  3687. isset($this->registry[$name])||isset($this->factories[$name])||method_exists($this,$method=Container::getMethodName($name))&&$this->getReflection()->getMethod($method)->getName()===$method;}function
  3688. isCreated($name){if(!$this->hasService($name)){throw
  3689. new
  3690. MissingServiceException("Service '$name' not found.");}return
  3691. isset($this->registry[$name]);}function
  3692. getByType($class,$need=TRUE){$lower=ltrim(strtolower($class),'\\');if(!isset($this->classes[$lower])){if($need){throw
  3693. new
  3694. MissingServiceException("Service of type $class not found.");}}elseif($this->classes[$lower]===FALSE){throw
  3695. new
  3696. MissingServiceException("Multiple services of type $class found.");}else{return$this->getService($this->classes[$lower]);}}function
  3697. findByTag($tag){$found=array();foreach($this->meta
  3698. as$name=>$meta){if(isset($meta[self::TAGS][$tag])){$found[$name]=$meta[self::TAGS][$tag];}}return$found;}function
  3699. createInstance($class,array$args=array()){$rc=Nette\Reflection\ClassType::from($class);if(!$rc->isInstantiable()){throw
  3700. new
  3701. ServiceCreationException("Class $class is not instantiable.");}elseif($constructor=$rc->getConstructor()){return$rc->newInstanceArgs(Helpers::autowireArguments($constructor,$args,$this));}elseif($args){throw
  3702. new
  3703. ServiceCreationException("Unable to pass arguments, class $class has no constructor.");}return
  3704. new$class;}function
  3705. callMethod($function,array$args=array()){$callback=new
  3706. Nette\Callback($function);return$callback->invokeArgs(Helpers::autowireArguments($callback->toReflection(),$args,$this));}function
  3707. expand($s){return
  3708. Helpers::expand($s,$this->parameters);}function&__get($name){if(!isset($this->registry[$name])){$this->getService($name);}return$this->registry[$name];}function
  3709. __set($name,$service){$this->updating();if(!is_string($name)||$name===''){throw
  3710. new
  3711. Nette\InvalidArgumentException("Service name must be a non-empty string, ".gettype($name)." given.");}elseif(isset($this->registry[$name])){throw
  3712. new
  3713. Nette\InvalidStateException("Service '$name' has already been registered.");}elseif(!is_object($service)){throw
  3714. new
  3715. Nette\InvalidArgumentException("Service must be a object, ".gettype($service)." given.");}$this->registry[$name]=$service;}function
  3716. __isset($name){return$this->hasService($name);}function
  3717. __unset($name){$this->removeService($name);}static
  3718. function
  3719. getMethodName($name,$isService=TRUE){$uname=ucfirst($name);return($isService?'createService':'create').((string)$name===$uname?'__':'').str_replace('.','__',$uname);}}use
  3720. Nette\Utils\Validators;use
  3721. Nette\Utils\Strings;use
  3722. Nette\Reflection;use
  3723. Nette\Utils\PhpGenerator\Helpers as PhpHelpers;use
  3724. Nette\Utils\PhpGenerator\PhpLiteral;class
  3725. ContainerBuilder
  3726. extends
  3727. Nette\Object{const
  3728. CREATED_SERVICE='self',THIS_CONTAINER='container';public$parameters=array();private$definitions=array();private$classes;private$dependencies=array();function
  3729. addDefinition($name){if(!is_string($name)||!$name){throw
  3730. new
  3731. Nette\InvalidArgumentException("Service name must be a non-empty string, ".gettype($name)." given.");}elseif(isset($this->definitions[$name])){throw
  3732. new
  3733. Nette\InvalidStateException("Service '$name' has already been added.");}return$this->definitions[$name]=new
  3734. ServiceDefinition;}function
  3735. removeDefinition($name){unset($this->definitions[$name]);}function
  3736. getDefinition($name){if(!isset($this->definitions[$name])){throw
  3737. new
  3738. MissingServiceException("Service '$name' not found.");}return$this->definitions[$name];}function
  3739. getDefinitions(){return$this->definitions;}function
  3740. hasDefinition($name){return
  3741. isset($this->definitions[$name]);}function
  3742. getByType($class){$lower=ltrim(strtolower($class),'\\');if(!isset($this->classes[$lower])){return;}elseif(count($this->classes[$lower])===1){return$this->classes[$lower][0];}else{throw
  3743. new
  3744. ServiceCreationException("Multiple services of type $class found: ".implode(', ',$this->classes[$lower]));}}function
  3745. findByTag($tag){$found=array();foreach($this->definitions
  3746. as$name=>$def){if(isset($def->tags[$tag])&&$def->shared){$found[$name]=$def->tags[$tag];}}return$found;}function
  3747. autowireArguments($class,$method,array$arguments){$rc=Reflection\ClassType::from($class);if(!$rc->hasMethod($method)){if(!Nette\Utils\Validators::isList($arguments)){throw
  3748. new
  3749. ServiceCreationException("Unable to pass specified arguments to $class::$method().");}return$arguments;}$rm=$rc->getMethod($method);if($rm->isAbstract()||!$rm->isPublic()){throw
  3750. new
  3751. ServiceCreationException("$rm is not callable.");}$this->addDependency($rm->getFileName());return
  3752. Helpers::autowireArguments($rm,$arguments,$this);}function
  3753. prepareClassList(){foreach($this->definitions
  3754. as$name=>$def){if($def->class===self::CREATED_SERVICE||($def->factory&&$def->factory->entity===self::CREATED_SERVICE)){$def->class=$name;$def->internal=TRUE;if($def->factory&&$def->factory->entity===self::CREATED_SERVICE){$def->factory->entity=$def->class;}unset($this->definitions[$name]);$this->definitions['_anonymous_'.str_replace('\\','_',strtolower(trim($name,'\\')))]=$def;}if($def->class){$def->class=$this->expand($def->class);if(!$def->factory){$def->factory=new
  3755. Statement($def->class);}}elseif(!$def->factory){throw
  3756. new
  3757. ServiceCreationException("Class and factory are missing in service '$name' definition.");}}foreach($this->definitions
  3758. as$name=>$def){$factory=$this->normalizeEntity($this->expand($def->factory->entity));if(is_string($factory)&&preg_match('#^[\w\\\\]+\z#',$factory)&&$factory!==self::CREATED_SERVICE){if(!class_exists($factory)||!Reflection\ClassType::from($factory)->isInstantiable()){throw
  3759. new
  3760. Nette\InvalidStateException("Class $factory used in service '$name' has not been found or is not instantiable.");}}}$this->classes=FALSE;foreach($this->definitions
  3761. as$name=>$def){$this->resolveClass($name);}$this->classes=array();foreach($this->definitions
  3762. as$name=>$def){if(!$def->class){continue;}if(!class_exists($def->class)&&!interface_exists($def->class)){throw
  3763. new
  3764. Nette\InvalidStateException("Class $def->class has not been found.");}$def->class=Reflection\ClassType::from($def->class)->getName();if($def->autowired){foreach(class_parents($def->class)+class_implements($def->class)+array($def->class)as$parent){$this->classes[strtolower($parent)][]=(string)$name;}}}foreach($this->classes
  3765. as$class=>$foo){$this->addDependency(Reflection\ClassType::from($class)->getFileName());}}private
  3766. function
  3767. resolveClass($name,$recursive=array()){if(isset($recursive[$name])){throw
  3768. new
  3769. Nette\InvalidArgumentException('Circular reference detected for services: '.implode(', ',array_keys($recursive)).'.');}$recursive[$name]=TRUE;$def=$this->definitions[$name];$factory=$this->normalizeEntity($this->expand($def->factory->entity));if($def->class){return$def->class;}elseif(is_array($factory)){if($service=$this->getServiceName($factory[0])){if(Strings::contains($service,'\\')){throw
  3770. new
  3771. ServiceCreationException("Unable resolve class name for service '$name'.");}$factory[0]=$this->resolveClass($service,$recursive);if(!$factory[0]){return;}}$factory=new
  3772. Nette\Callback($factory);if(!$factory->isCallable()){throw
  3773. new
  3774. Nette\InvalidStateException("Factory '$factory' is not callable.");}try{$reflection=$factory->toReflection();$def->class=preg_replace('#[|\s].*#','',$reflection->getAnnotation('return'));if($def->class&&!class_exists($def->class)&&$def->class[0]!=='\\'&&$reflection
  3775. instanceof\ReflectionMethod){$def->class=$reflection->getDeclaringClass()->getNamespaceName().'\\'.$def->class;}}catch(\ReflectionException$e){}}elseif($service=$this->getServiceName($factory)){if(Strings::contains($service,'\\')){$def->autowired=FALSE;return$def->class=$service;}if($this->definitions[$service]->shared){$def->autowired=FALSE;}return$def->class=$this->resolveClass($service,$recursive);}else{return$def->class=$factory;}}function
  3776. addDependency($file){$this->dependencies[$file]=TRUE;return$this;}function
  3777. getDependencies(){unset($this->dependencies[FALSE]);return
  3778. array_keys($this->dependencies);}function
  3779. generateClass($parentClass='Nette\DI\Container'){unset($this->definitions[self::THIS_CONTAINER]);$this->addDefinition(self::THIS_CONTAINER)->setClass($parentClass);$this->prepareClassList();$class=new
  3780. Nette\Utils\PhpGenerator\ClassType('Container');$class->addExtend($parentClass);$class->addMethod('__construct')->addBody('parent::__construct(?);',array($this->expand($this->parameters)));$classes=$class->addProperty('classes',array());foreach($this->classes
  3781. as$name=>$foo){try{$classes->value[$name]=$this->getByType($name);}catch(ServiceCreationException$e){$classes->value[$name]=new
  3782. PhpLiteral('FALSE, //'.strstr($e->getMessage(),':'));}}$definitions=$this->definitions;ksort($definitions);$meta=$class->addProperty('meta',array());foreach($definitions
  3783. as$name=>$def){if($def->shared){foreach($this->expand($def->tags)as$tag=>$value){$meta->value[$name][Container::TAGS][$tag]=$value;}}}foreach($definitions
  3784. as$name=>$def){try{$name=(string)$name;$type=$def->class?:'object';$methodName=Container::getMethodName($name,$def->shared);if(!PhpHelpers::isIdentifier($methodName)){throw
  3785. new
  3786. ServiceCreationException('Name contains invalid characters.');}if($def->shared&&!$def->internal&&PhpHelpers::isIdentifier($name)){$class->addDocument("@property $type \$$name");}$method=$class->addMethod($methodName)->addDocument("@return $type")->setVisibility($def->shared||$def->internal?'protected':'public')->setBody($name===self::THIS_CONTAINER?'return $this;':$this->generateService($name));foreach($this->expand($def->parameters)as$k=>$v){$tmp=explode(' ',is_int($k)?$v:$k);$param=is_int($k)?$method->addParameter(end($tmp)):$method->addParameter(end($tmp),$v);if(isset($tmp[1])){$param->setTypeHint($tmp[0]);}}}catch(\Exception$e){throw
  3787. new
  3788. ServiceCreationException("Service '$name': ".$e->getMessage(),NULL,$e);}}return$class;}private
  3789. function
  3790. generateService($name){$def=$this->definitions[$name];$parameters=$this->parameters;foreach($this->expand($def->parameters)as$k=>$v){$v=explode(' ',is_int($k)?$v:$k);$parameters[end($v)]=new
  3791. PhpLiteral('$'.end($v));}$code='$service = '.$this->formatStatement(Helpers::expand($def->factory,$parameters,TRUE)).";\n";$entity=$this->normalizeEntity($def->factory->entity);if($def->class&&$def->class!==$entity&&!$this->getServiceName($entity)){$code.=PhpHelpers::formatArgs("if (!\$service instanceof $def->class) {\n"."\tthrow new Nette\\UnexpectedValueException(?);\n}\n",array("Unable to create service '$name', value returned by factory is not $def->class type."));}foreach((array)$def->setup
  3792. as$setup){$setup=Helpers::expand($setup,$parameters,TRUE);if(is_string($setup->entity)&&strpbrk($setup->entity,':@?')===FALSE){$setup->entity=array("@$name",$setup->entity);}$code.=$this->formatStatement($setup,$name).";\n";}return$code.='return $service;';}function
  3793. formatStatement(Statement$statement,$self=NULL){$entity=$this->normalizeEntity($statement->entity);$arguments=$statement->arguments;if(is_string($entity)&&Strings::contains($entity,'?')){return$this->formatPhp($entity,$arguments,$self);}elseif($service=$this->getServiceName($entity)){if($this->definitions[$service]->shared){if($arguments){throw
  3794. new
  3795. ServiceCreationException("Unable to call service '$entity'.");}return$this->formatPhp('$this->getService(?)',array($service));}$params=array();foreach($this->definitions[$service]->parameters
  3796. as$k=>$v){$params[]=preg_replace('#\w+\z#','\$$0',(is_int($k)?$v:$k)).(is_int($k)?'':' = '.PhpHelpers::dump($v));}$rm=new
  3797. Reflection\GlobalFunction(create_function(implode(', ',$params),''));$arguments=Helpers::autowireArguments($rm,$arguments,$this);return$this->formatPhp('$this->?(?*)',array(Container::getMethodName($service,FALSE),$arguments),$self);}elseif($entity==='not'){return$this->formatPhp('!?',array($arguments[0]));}elseif(is_string($entity)){if($constructor=Reflection\ClassType::from($entity)->getConstructor()){$this->addDependency($constructor->getFileName());$arguments=Helpers::autowireArguments($constructor,$arguments,$this);}elseif($arguments){throw
  3798. new
  3799. ServiceCreationException("Unable to pass arguments, class $entity has no constructor.");}return$this->formatPhp("new $entity".($arguments?'(?*)':''),array($arguments),$self);}elseif(!Validators::isList($entity)||count($entity)!==2){throw
  3800. new
  3801. Nette\InvalidStateException("Expected class, method or property, ".PhpHelpers::dump($entity)." given.");}elseif($entity[0]===''){return$this->formatPhp("$entity[1](?*)",array($arguments),$self);}elseif(Strings::contains($entity[1],'$')){Validators::assert($arguments,'list:1',"setup arguments for '".Nette\Callback::create($entity)."'");if($this->getServiceName($entity[0],$self)){return$this->formatPhp('?->? = ?',array($entity[0],substr($entity[1],1),$arguments[0]),$self);}else{return$this->formatPhp($entity[0].'::$? = ?',array(substr($entity[1],1),$arguments[0]),$self);}}elseif($service=$this->getServiceName($entity[0],$self)){if($this->definitions[$service]->class){$arguments=$this->autowireArguments($this->definitions[$service]->class,$entity[1],$arguments);}return$this->formatPhp('?->?(?*)',array($entity[0],$entity[1],$arguments),$self);}else{$arguments=$this->autowireArguments($entity[0],$entity[1],$arguments);return$this->formatPhp("$entity[0]::$entity[1](?*)",array($arguments),$self);}}function
  3802. formatPhp($statement,$args,$self=NULL){$that=$this;array_walk_recursive($args,function(&$val)use($self,$that){list($val)=$that->normalizeEntity(array($val));if($val
  3803. instanceof
  3804. Statement){$val=new
  3805. PhpLiteral($that->formatStatement($val,$self));}elseif($val==='@'.ContainerBuilder::THIS_CONTAINER){$val=new
  3806. PhpLiteral('$this');}elseif($service=$that->getServiceName($val,$self)){$val=$service===$self?'$service':$that->formatStatement(new
  3807. Statement($val));$val=new
  3808. PhpLiteral($val);}});return
  3809. PhpHelpers::formatArgs($statement,$args);}function
  3810. expand($value){return
  3811. Helpers::expand($value,$this->parameters,TRUE);}function
  3812. normalizeEntity($entity){if(is_string($entity)&&Strings::contains($entity,'::')&&!Strings::contains($entity,'?')){$entity=explode('::',$entity);}if(is_array($entity)&&$entity[0]instanceof
  3813. ServiceDefinition){$tmp=array_keys($this->definitions,$entity[0],TRUE);$entity[0]="@$tmp[0]";}elseif($entity
  3814. instanceof
  3815. ServiceDefinition){$tmp=array_keys($this->definitions,$entity,TRUE);$entity="@$tmp[0]";}elseif(is_array($entity)&&$entity[0]===$this){$entity[0]='@'.ContainerBuilder::THIS_CONTAINER;}return$entity;}function
  3816. getServiceName($arg,$self=NULL){if(!is_string($arg)||!preg_match('#^@[\w\\\\.].*\z#',$arg)){return
  3817. FALSE;}$service=substr($arg,1);if($service===self::CREATED_SERVICE){$service=$self;}if(Strings::contains($service,'\\')){if($this->classes===FALSE){return$service;}$res=$this->getByType($service);if(!$res){throw
  3818. new
  3819. ServiceCreationException("Reference to missing service of type $service.");}return$res;}if(!isset($this->definitions[$service])){throw
  3820. new
  3821. ServiceCreationException("Reference to missing service '$service'.");}return$service;}}}namespace Nette\DI\Diagnostics{use
  3822. Nette;use
  3823. Nette\DI\Container;use
  3824. Nette\Diagnostics\Helpers;class
  3825. ContainerPanel
  3826. extends
  3827. Nette\Object
  3828. implements
  3829. Nette\Diagnostics\IBarPanel{private$container;function
  3830. __construct(Container$container){if(PHP_VERSION_ID<50300){throw
  3831. new
  3832. Nette\NotSupportedException(__CLASS__.' requires PHP 5.3 or newer.');}$this->container=$container;}function
  3833. getTab(){ob_start();?>
  3834. <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGSSURBVCjPVVFNSwJhEF78Ad79Cf6PvXQRsotUlzKICosuRYmR2RJR0KE6lBFFZVEbpFBSqKu2rum6llFS9HHI4iUhT153n6ZtIWMOM+/MM88z7wwH7s9Ub16SJcnbmrNcxVm2q7Z8/QPvEOtntpj92NkCqITLepEpjix7xQtiLOoQ2b6+E7YAN/5nfOEJ2WbKqOIOJ4bYVMEQx4LfBBQDsvFMhUcCVU1/CxVXmDBGA5ZETrhDCQVcYAPbyEJBhvrnBVPiSpNr6cYDNCQwo4zzU/ySckkgDYuNuVpI42T9k4gLKGMPs/xPzzovQiY2hQYe0jlJfyNNhTqiWDYBq/wBMcSRpnyPzu1oS7WtxjVBSthU1vgVksiQ3Dn6Gp5ah2YOKQo5GiuHPA6xT1EKpxQNCNYejgIR457KKio0S56YckjSa9jo//3mrj+BV0QQagqGTOo+Y7gZIf1puP3WHoLhEb2PjTlCTCWGXtbp8DCX3hZuOdaIc9A+aQvWk4ihq95p67a7nP+u+Ws+r0dql9z/zv0NCYhdCPKZ7oYAAAAASUVORK5CYII="
  3835. />&nbsp;
  3836. <?php
  3837. return
  3838. ob_get_clean();}function
  3839. getPanel(){$services=$this->getContainerProperty('factories');$factories=array();foreach(Nette\Reflection\ClassType::from($this->container)->getMethods()as$method){if(preg_match('#^create(Service)?(.+)\z#',$method->getName(),$m)){$name=str_replace('__','.',strtolower(substr($m[2],0,1)).substr($m[2],1));if($m[1]){$services[$name]=$method->getAnnotation('return');}elseif($method->isPublic()){$a=strrpos(".$name",'.');$factories[substr($name,0,$a).'create'.ucfirst(substr($name,$a))]=$method->getAnnotation('return');}}}ksort($services);ksort($factories);$container=$this->container;$registry=$this->getContainerProperty('registry');ob_start();?>
  3840. <style>#nette-debug .nette-ContainerPanel .nette-inner{width:700px}#nette-debug .nette-ContainerPanel table{width:100%;white-space:nowrap}#nette-debug .nette-ContainerPanel-parameters pre{background:#FDF5CE;padding:.4em .7em;border:1px dotted silver;overflow:auto}#nette-debug .nette-ContainerPanel .created{font-weight:bold}#nette-debug .nette-ContainerPanel .yes{color:green;font-weight:bold}</style>
  3841. <div class="nette-ContainerPanel">
  3842. <h1><?php echo
  3843. get_class($this->container)?></h1>
  3844. <div class="nette-inner">
  3845. <h2>Parameters</h2>
  3846. <div class="nette-ContainerPanel-parameters">
  3847. <?php echo
  3848. Helpers::clickableDump($this->container->parameters);?>
  3849. </div>
  3850. <h2>Services</h2>
  3851. <table>
  3852. <thead>
  3853. <tr>
  3854. <th>Name</th>
  3855. <th>Autowired</th>
  3856. <th>Service</th>
  3857. <th>Meta</th>
  3858. </tr>
  3859. </thead>
  3860. <tbody>
  3861. <?php foreach($services
  3862. as$name=>$class):?>
  3863. <?php $autowired=array_keys($container->classes,$name);?>
  3864. <tr>
  3865. <td class="<?php echo
  3866. isset($registry[$name])?'created':''?>"><?php echo
  3867. htmlSpecialChars(str_replace('.','->',$name))?></td>
  3868. <td title="<?php echo
  3869. htmlSpecialChars(implode(" \n",$autowired))?>" class="<?php echo$autowired?'yes':''?>"><?php echo$autowired?'yes':'no'?></td>
  3870. <td>
  3871. <?php if(isset($registry[$name])&&!$registry[$name]instanceof
  3872. Nette\DI\Container&&!$registry[$name]instanceof
  3873. Nette\DI\NestedAccessor):?>
  3874. <?php echo
  3875. Helpers::clickableDump($registry[$name],TRUE);?>
  3876. <?php elseif(isset($registry[$name])):?>
  3877. <code><?php echo
  3878. get_class($registry[$name])?></code>
  3879. <?php elseif(is_string($class)):?>
  3880. <code><?php echo
  3881. htmlSpecialChars($class)?></code>
  3882. <?php endif?>
  3883. </td>
  3884. <td><?php if(isset($container->meta[$name])){echo
  3885. Helpers::clickableDump($container->meta[$name],TRUE);}?></td>
  3886. </tr>
  3887. <?php endforeach?>
  3888. </tbody>
  3889. </table>
  3890. <h2>Factories</h2>
  3891. <table>
  3892. <thead>
  3893. <tr>
  3894. <th>Method</th>
  3895. <th>Returns</th>
  3896. </tr>
  3897. </thead>
  3898. <tbody>
  3899. <?php foreach($factories
  3900. as$name=>$class):?>
  3901. <tr>
  3902. <td><?php echo
  3903. htmlSpecialChars(str_replace('.','->',$name))?>()</td>
  3904. <td><code><?php echo
  3905. htmlSpecialChars($class)?><code></td>
  3906. </tr>
  3907. <?php endforeach?>
  3908. </tbody>
  3909. </table>
  3910. </div>
  3911. </div>
  3912. <?php
  3913. return
  3914. ob_get_clean();}private
  3915. function
  3916. getContainerProperty($name){$prop=Nette\Reflection\ClassType::from('Nette\DI\Container')->getProperty($name);$prop->setAccessible(TRUE);return$prop->getValue($this->container);}}}namespace Nette\DI{use
  3917. Nette;class
  3918. MissingServiceException
  3919. extends
  3920. Nette\InvalidStateException{}class
  3921. ServiceCreationException
  3922. extends
  3923. Nette\InvalidStateException{}final
  3924. class
  3925. Helpers{static
  3926. function
  3927. expand($var,array$params,$recursive=FALSE){if(is_array($var)){$res=array();foreach($var
  3928. as$key=>$val){$res[$key]=self::expand($val,$params,$recursive);}return$res;}elseif($var
  3929. instanceof
  3930. Statement){return
  3931. new
  3932. Statement(self::expand($var->entity,$params,$recursive),self::expand($var->arguments,$params,$recursive));}elseif(!is_string($var)){return$var;}$parts=preg_split('#%([\w.-]*)%#i',$var,-1,PREG_SPLIT_DELIM_CAPTURE);$res='';foreach($parts
  3933. as$n=>$part){if($n
  3934. %
  3935. 2===0){$res.=$part;}elseif($part===''){$res.='%';}elseif(isset($recursive[$part])){throw
  3936. new
  3937. Nette\InvalidArgumentException('Circular reference detected for variables: '.implode(', ',array_keys($recursive)).'.');}else{$val=Nette\Utils\Arrays::get($params,explode('.',$part));if($recursive){$val=self::expand($val,$params,(is_array($recursive)?$recursive:array())+array($part=>1));}if(strlen($part)+2===strlen($var)){return$val;}if(!is_scalar($val)){throw
  3938. new
  3939. Nette\InvalidArgumentException("Unable to concatenate non-scalar parameter '$part' into '$var'.");}$res.=$val;}}return$res;}static
  3940. function
  3941. escape($value){if(is_array($value)){array_walk_recursive($value,function(&$val){$val=is_string($val)?str_replace('%','%%',$val):$val;});}elseif(is_string($value)){$value=str_replace('%','%%',$value);}return$value;}static
  3942. function
  3943. autowireArguments(\ReflectionFunctionAbstract$method,array$arguments,$container){$optCount=0;$num=-1;$res=array();foreach($method->getParameters()as$num=>$parameter){if(array_key_exists($num,$arguments)){$res[$num]=$arguments[$num];unset($arguments[$num]);$optCount=0;}elseif(array_key_exists($parameter->getName(),$arguments)){$res[$num]=$arguments[$parameter->getName()];unset($arguments[$parameter->getName()]);$optCount=0;}elseif($class=$parameter->getClassName()){$res[$num]=$container->getByType($class,FALSE);if($res[$num]===NULL){if($parameter->allowsNull()){$optCount++;}else{throw
  3944. new
  3945. ServiceCreationException("No service of type {$class} found. Make sure the type hint in $method is written correctly and service of this type is registered.");}}else{if($container
  3946. instanceof
  3947. ContainerBuilder){$res[$num]='@'.$res[$num];}$optCount=0;}}elseif($parameter->isOptional()){$res[$num]=$parameter->isDefaultValueAvailable()?$parameter->getDefaultValue():NULL;$optCount++;}else{throw
  3948. new
  3949. ServiceCreationException("$parameter has no type hint, so its value must be specified.");}}while(array_key_exists(++$num,$arguments)){$res[$num]=$arguments[$num];unset($arguments[$num]);$optCount=0;}if($arguments){throw
  3950. new
  3951. ServiceCreationException("Unable to pass specified arguments to $method.");}return$optCount?array_slice($res,0,-$optCount):$res;}}class
  3952. NestedAccessor
  3953. extends
  3954. Nette\Object{public$parameters;private$container;private$namespace;function
  3955. __construct(Container$container,$namespace){$this->container=$container;$this->namespace=$namespace.'.';$this->parameters=&$container->parameters[$namespace];}function
  3956. __call($name,$args){if(substr($name,0,6)==='create'){return
  3957. call_user_func_array(array($this->container,Container::getMethodName($this->namespace.substr($name,6),FALSE)),$args);}throw
  3958. new
  3959. Nette\NotSupportedException;}function&__get($name){$service=$this->container->getService($this->namespace.$name);return$service;}function
  3960. __set($name,$service){throw
  3961. new
  3962. Nette\NotSupportedException;}function
  3963. __isset($name){return$this->container->hasService($this->namespace.$name);}function
  3964. __unset($name){throw
  3965. new
  3966. Nette\NotSupportedException;}}class
  3967. ServiceDefinition
  3968. extends
  3969. Nette\Object{public$class;public$factory;public$setup=array();public$parameters=array();public$tags=array();public$autowired=TRUE;public$shared=TRUE;public$internal=FALSE;function
  3970. setClass($class,array$args=array()){$this->class=$class;if($args){$this->setFactory($class,$args);}return$this;}function
  3971. setFactory($factory,array$args=array()){$this->factory=new
  3972. Statement($factory,$args);return$this;}function
  3973. setArguments(array$args=array()){if($this->factory){$this->factory->arguments=$args;}else{$this->setClass($this->class,$args);}return$this;}function
  3974. addSetup($target,$args=NULL){if(!is_array($args)){$args=func_get_args();array_shift($args);}$this->setup[]=new
  3975. Statement($target,$args);return$this;}function
  3976. setParameters(array$params){$this->shared=$this->autowired=FALSE;$this->parameters=$params;return$this;}function
  3977. addTag($tag,$attrs=TRUE){$this->tags[$tag]=$attrs;return$this;}function
  3978. setAutowired($on){$this->autowired=$on;return$this;}function
  3979. setShared($on){$this->shared=(bool)$on;$this->autowired=$this->shared?$this->autowired:FALSE;return$this;}function
  3980. setInternal($on){$this->internal=(bool)$on;return$this;}}class
  3981. Statement
  3982. extends
  3983. Nette\Object{public$entity;public$arguments;function
  3984. __construct($entity,array$arguments=array()){$this->entity=$entity;$this->arguments=$arguments;}}}namespace Nette\Forms{use
  3985. Nette;class
  3986. ControlGroup
  3987. extends
  3988. Nette\Object{protected$controls;private$options=array();function
  3989. __construct(){$this->controls=new\SplObjectStorage;}function
  3990. add(){foreach(func_get_args()as$num=>$item){if($item
  3991. instanceof
  3992. IControl){$this->controls->attach($item);}elseif($item
  3993. instanceof\Traversable||is_array($item)){foreach($item
  3994. as$control){$this->controls->attach($control);}}else{throw
  3995. new
  3996. Nette\InvalidArgumentException("Only IFormControl items are allowed, the #$num parameter is invalid.");}}return$this;}function
  3997. getControls(){return
  3998. iterator_to_array($this->controls);}function
  3999. setOption($key,$value){if($value===NULL){unset($this->options[$key]);}else{$this->options[$key]=$value;}return$this;}final
  4000. function
  4001. getOption($key,$default=NULL){return
  4002. isset($this->options[$key])?$this->options[$key]:$default;}final
  4003. function
  4004. getOptions(){return$this->options;}}}namespace Nette\Forms\Controls{use
  4005. Nette;use
  4006. Nette\Forms\IControl;use
  4007. Nette\Utils\Html;use
  4008. Nette\Forms\Form;use
  4009. Nette\Forms\Rule;abstract
  4010. class
  4011. BaseControl
  4012. extends
  4013. Nette\ComponentModel\Component
  4014. implements
  4015. IControl{public
  4016. 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
  4017. __construct($caption=NULL){$this->monitor('Nette\Forms\Form');parent::__construct();$this->control=Html::el('input');$this->label=Html::el('label');$this->caption=$caption;$this->rules=new
  4018. Nette\Forms\Rules($this);}protected
  4019. function
  4020. attached($form){if(!$this->disabled&&$form
  4021. instanceof
  4022. Form&&$form->isAnchored()&&$form->isSubmitted()){$this->htmlName=NULL;$this->loadHttpData();}}function
  4023. getForm($need=TRUE){return$this->lookup('Nette\Forms\Form',$need);}function
  4024. getHtmlName(){if($this->htmlName===NULL){$name=str_replace(self::NAME_SEPARATOR,'][',$this->lookupPath('Nette\Forms\Form'),$count);if($count){$name=substr_replace($name,'',strpos($name,']'),1).']';}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
  4025. setHtmlId($id){$this->htmlId=$id;return$this;}function
  4026. getHtmlId(){if($this->htmlId===FALSE){return
  4027. NULL;}elseif($this->htmlId===NULL){$this->htmlId=sprintf(self::$idMask,$this->getForm()->getName(),$this->lookupPath('Nette\Forms\Form'));}return$this->htmlId;}function
  4028. setAttribute($name,$value=TRUE){$this->control->$name=$value;return$this;}function
  4029. setOption($key,$value){if($value===NULL){unset($this->options[$key]);}else{$this->options[$key]=$value;}return$this;}final
  4030. function
  4031. getOption($key,$default=NULL){return
  4032. isset($this->options[$key])?$this->options[$key]:$default;}final
  4033. function
  4034. getOptions(){return$this->options;}function
  4035. setTranslator(Nette\Localization\ITranslator$translator=NULL){$this->translator=$translator;return$this;}final
  4036. function
  4037. getTranslator(){if($this->translator===TRUE){return$this->getForm(FALSE)?$this->getForm()->getTranslator():NULL;}return$this->translator;}function
  4038. translate($s,$count=NULL){$translator=$this->getTranslator();return$translator===NULL||$s==NULL?$s:$translator->translate($s,$count);}function
  4039. setValue($value){$this->value=$value;return$this;}function
  4040. getValue(){return$this->value;}function
  4041. isFilled(){return(string)$this->getValue()!=='';}function
  4042. setDefaultValue($value){$form=$this->getForm(FALSE);if(!$form||!$form->isAnchored()||!$form->isSubmitted()){$this->setValue($value);}return$this;}function
  4043. loadHttpData(){$path=explode('[',strtr(str_replace(array('[]',']'),'',$this->getHtmlName()),'.','_'));$this->setValue(Nette\Utils\Arrays::get($this->getForm()->getHttpData(),$path,NULL));}function
  4044. setDisabled($value=TRUE){$this->disabled=(bool)$value;return$this;}function
  4045. isDisabled(){return$this->disabled;}function
  4046. 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(PHP_VERSION_ID>=50400?json_encode($rules,JSON_UNESCAPED_UNICODE):json_encode($rules),1,-1);$rules=preg_replace('#"([a-z0-9_]+)":#i','$1:',$rules);$rules=preg_replace('#(?<!\\\\)"(?!:[^a-z])([^\\\\\',]*)"#i',"'$1'",$rules);$control->data('nette-rules',$rules?$rules:NULL);return$control;}function
  4047. getLabel($caption=NULL){$label=clone$this->label;$label->for=$this->getHtmlId();if($caption!==NULL){$label->setText($this->translate($caption));}elseif($this->caption
  4048. instanceof
  4049. Html){$label->add($this->caption);}else{$label->setText($this->translate($this->caption));}return$label;}final
  4050. function
  4051. getControlPrototype(){return$this->control;}final
  4052. function
  4053. getLabelPrototype(){return$this->label;}function
  4054. addRule($operation,$message=NULL,$arg=NULL){$this->rules->addRule($operation,$message,$arg);return$this;}function
  4055. addCondition($operation,$value=NULL){return$this->rules->addCondition($operation,$value);}function
  4056. addConditionOn(IControl$control,$operation,$value=NULL){return$this->rules->addConditionOn($control,$operation,$value);}final
  4057. function
  4058. getRules(){return$this->rules;}final
  4059. function
  4060. setRequired($message=NULL){return$this->addRule(Form::FILLED,$message);}final
  4061. function
  4062. isRequired(){foreach($this->rules
  4063. as$rule){if($rule->type===Rule::VALIDATOR&&!$rule->isNegative&&$rule->operation===Form::FILLED){return
  4064. TRUE;}}return
  4065. FALSE;}protected
  4066. static
  4067. function
  4068. exportRules($rules){$payload=array();foreach($rules
  4069. as$rule){if(!is_string($op=$rule->operation)){$op=new
  4070. Nette\Callback($op);if(!$op->isStatic()){continue;}}if($rule->type===Rule::VALIDATOR){$item=array('op'=>($rule->isNegative?'~':'').$op,'msg'=>$rules->formatMessage($rule,FALSE));}elseif($rule->type===Rule::CONDITION){$item=array('op'=>($rule->isNegative?'~':'').$op,'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
  4071. as$key=>$value){$item['arg'][$key]=$value
  4072. instanceof
  4073. IControl?(object)array('control'=>$value->getHtmlName()):$value;}}elseif($rule->arg!==NULL){$item['arg']=$rule->arg
  4074. instanceof
  4075. IControl?(object)array('control'=>$rule->arg->getHtmlName()):$rule->arg;}$payload[]=$item;}return$payload;}static
  4076. function
  4077. validateEqual(IControl$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
  4078. instanceof
  4079. IControl?$item->value:$item)){return
  4080. TRUE;}}}return
  4081. FALSE;}static
  4082. function
  4083. validateFilled(IControl$control){return$control->isFilled();}static
  4084. function
  4085. validateValid(IControl$control){return$control->rules->validate(TRUE);}function
  4086. addError($message){if(!in_array($message,$this->errors,TRUE)){$this->errors[]=$message;}$this->getForm()->addError($message);}function
  4087. getErrors(){return$this->errors;}function
  4088. hasErrors(){return(bool)$this->errors;}function
  4089. cleanErrors(){$this->errors=array();}}class
  4090. Button
  4091. extends
  4092. BaseControl{function
  4093. __construct($caption=NULL){parent::__construct($caption);$this->control->type='button';}function
  4094. getLabel($caption=NULL){return
  4095. NULL;}function
  4096. getControl($caption=NULL){$control=parent::getControl();$control->value=$this->translate($caption===NULL?$this->caption:$caption);return$control;}}class
  4097. Checkbox
  4098. extends
  4099. BaseControl{function
  4100. __construct($label=NULL){parent::__construct($label);$this->control->type='checkbox';$this->value=FALSE;}function
  4101. setValue($value){$this->value=is_scalar($value)?(bool)$value:FALSE;return$this;}function
  4102. getControl(){return
  4103. parent::getControl()->checked($this->value);}}class
  4104. HiddenField
  4105. extends
  4106. BaseControl{private$forcedValue;function
  4107. __construct($forcedValue=NULL){parent::__construct();$this->control->type='hidden';$this->value=(string)$forcedValue;$this->forcedValue=$forcedValue;}function
  4108. getLabel($caption=NULL){return
  4109. NULL;}function
  4110. setValue($value){$this->value=is_scalar($value)?(string)$value:'';return$this;}function
  4111. getControl(){return
  4112. parent::getControl()->value($this->forcedValue===NULL?$this->value:$this->forcedValue)->data('nette-rules',NULL);}}class
  4113. SubmitButton
  4114. extends
  4115. Button
  4116. implements
  4117. Nette\Forms\ISubmitterControl{public$onClick;public$onInvalidClick;private$validationScope=TRUE;function
  4118. __construct($caption=NULL){parent::__construct($caption);$this->control->type='submit';}function
  4119. setValue($value){if($this->value=$value!==NULL){$this->getForm()->setSubmittedBy($this);}return$this;}function
  4120. isSubmittedBy(){return$this->getForm()->isSubmitted()===$this;}function
  4121. setValidationScope($scope){$this->validationScope=(bool)$scope;$this->control->formnovalidate=!$this->validationScope;return$this;}final
  4122. function
  4123. getValidationScope(){return$this->validationScope;}function
  4124. click(){$this->onClick($this);}static
  4125. function
  4126. validateSubmitted(Nette\Forms\ISubmitterControl$control){return$control->isSubmittedBy();}}class
  4127. ImageButton
  4128. extends
  4129. SubmitButton{function
  4130. __construct($src=NULL,$alt=NULL){parent::__construct();$this->control->type='image';$this->control->src=$src;$this->control->alt=$alt;}function
  4131. getHtmlName(){$name=parent::getHtmlName();return
  4132. strpos($name,'[')===FALSE?$name:$name.'[]';}function
  4133. loadHttpData(){$path=$this->getHtmlName();$path=explode('[',strtr(str_replace(']','',strpos($path,'[')===FALSE?$path.'.x':substr($path,0,-2)),'.','_'));$this->setValue(Nette\Utils\Arrays::get($this->getForm()->getHttpData(),$path,NULL));}}class
  4134. SelectBox
  4135. extends
  4136. BaseControl{private$items=array();protected$allowed=array();private$prompt=FALSE;private$useKeys=TRUE;function
  4137. __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
  4138. getValue(){return
  4139. is_scalar($this->value)&&isset($this->allowed[$this->value])?$this->value:NULL;}function
  4140. getRawValue(){return
  4141. is_scalar($this->value)?$this->value:NULL;}function
  4142. isFilled(){$value=$this->getValue();return
  4143. is_array($value)?count($value)>0:$value!==NULL;}function
  4144. setPrompt($prompt){if($prompt===TRUE){$prompt=reset($this->items);unset($this->allowed[key($this->items)],$this->items[key($this->items)]);}$this->prompt=$prompt;return$this;}function
  4145. skipFirst($v=NULL){trigger_error(__METHOD__.'() is deprecated; use setPrompt() instead.',E_USER_WARNING);return$this->setPrompt($v);}final
  4146. function
  4147. getPrompt(){return$this->prompt;}final
  4148. function
  4149. areKeysUsed(){return$this->useKeys;}function
  4150. setItems(array$items,$useKeys=TRUE){$allowed=array();foreach($items
  4151. as$k=>$v){foreach((is_array($v)?$v:array($k=>$v))as$key=>$value){if(!$useKeys){if(!is_scalar($value)){throw
  4152. new
  4153. Nette\InvalidArgumentException("All items must be scalar.");}$key=$value;}if(isset($allowed[$key])){throw
  4154. new
  4155. Nette\InvalidArgumentException("Items contain duplication for key '$key'.");}$allowed[$key]=$value;}}$this->items=$items;$this->allowed=$allowed;$this->useKeys=(bool)$useKeys;return$this;}final
  4156. function
  4157. getItems(){return$this->items;}function
  4158. getSelectedItem(){$value=$this->getValue();return($this->useKeys&&$value!==NULL)?$this->allowed[$value]:$value;}function
  4159. getControl(){$selected=$this->getValue();$selected=is_array($selected)?array_flip($selected):array($selected=>TRUE);$control=parent::getControl();$option=Nette\Utils\Html::el('option');if($this->prompt!==FALSE){$control->add($this->prompt
  4160. instanceof
  4161. Nette\Utils\Html?$this->prompt->value(''):(string)$option->value('')->setText($this->translate((string)$this->prompt)));}foreach($this->items
  4162. as$key=>$value){if(!is_array($value)){$value=array($key=>$value);$dest=$control;}else{$dest=$control->create('optgroup')->label($this->translate($key));}foreach($value
  4163. as$key2=>$value2){if($value2
  4164. instanceof
  4165. Nette\Utils\Html){$dest->add((string)$value2->selected(isset($selected[$key2])));}else{$key2=$this->useKeys?$key2:$value2;$value2=$this->translate((string)$value2);$dest->add((string)$option->value($key2)->selected(isset($selected[$key2]))->setText($value2));}}}return$control;}}class
  4166. MultiSelectBox
  4167. extends
  4168. SelectBox{function
  4169. getValue(){return
  4170. array_intersect($this->getRawValue(),array_keys($this->allowed));}function
  4171. getRawValue(){if(is_scalar($this->value)){return
  4172. array($this->value);}else{$res=array();foreach((array)$this->value
  4173. as$val){if(is_scalar($val)){$res[]=$val;}}return$res;}}function
  4174. getSelectedItem(){return$this->areKeysUsed()?array_intersect_key($this->allowed,array_flip($this->getValue())):$this->getValue();}function
  4175. getHtmlName(){return
  4176. parent::getHtmlName().'[]';}function
  4177. getControl(){return
  4178. parent::getControl()->multiple(TRUE);}static
  4179. function
  4180. validateLength(MultiSelectBox$control,$range){if(!is_array($range)){$range=array($range,$range);}$count=count($control->getSelectedItem());return($range[0]===NULL||$count>=$range[0])&&($range[1]===NULL||$count<=$range[1]);}}class
  4181. RadioList
  4182. extends
  4183. BaseControl{protected$separator;protected$container;protected$items=array();function
  4184. __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
  4185. getValue($raw=FALSE){return
  4186. is_scalar($this->value)&&($raw||isset($this->items[$this->value]))?$this->value:NULL;}function
  4187. isFilled(){return$this->getValue()!==NULL;}function
  4188. setItems(array$items){$this->items=$items;return$this;}final
  4189. function
  4190. getItems(){return$this->items;}final
  4191. function
  4192. getSeparatorPrototype(){return$this->separator;}final
  4193. function
  4194. getContainerPrototype(){return$this->container;}function
  4195. getControl($key=NULL){if($key===NULL){$container=clone$this->container;$separator=(string)$this->separator;}elseif(!isset($this->items[$key])){return
  4196. NULL;}$control=parent::getControl();$id=$control->id;$counter=-1;$value=$this->value===NULL?NULL:(string)$this->getValue();$label=Html::el('label');foreach($this->items
  4197. as$k=>$val){$counter++;if($key!==NULL&&(string)$key!==(string)$k){continue;}$control->id=$label->for=$id.'-'.$counter;$control->checked=(string)$k===$value;$control->value=$k;if($val
  4198. instanceof
  4199. Html){$label->setHtml($val);}else{$label->setText($this->translate((string)$val));}if($key!==NULL){return
  4200. Html::el()->add($control)->add($label);}$container->add((string)$control.(string)$label.$separator);$control->data('nette-rules',NULL);}return$container;}function
  4201. getLabel($caption=NULL){$label=parent::getLabel($caption);$label->for=NULL;return$label;}}use
  4202. Nette\Utils\Strings;use
  4203. Nette\Utils\Validators;abstract
  4204. class
  4205. TextBase
  4206. extends
  4207. BaseControl{protected$emptyValue='';protected$filters=array();function
  4208. setValue($value){$this->value=is_array($value)?'':(string)$value;return$this;}function
  4209. getValue(){$value=$this->value;foreach($this->filters
  4210. as$filter){$value=(string)$filter($value);}return$value===$this->translate($this->emptyValue)?'':$value;}function
  4211. setEmptyValue($value){$this->emptyValue=(string)$value;return$this;}final
  4212. function
  4213. getEmptyValue(){return$this->emptyValue;}function
  4214. addFilter($filter){$this->filters[]=new
  4215. Nette\Callback($filter);return$this;}function
  4216. getControl(){$control=parent::getControl();foreach($this->getRules()as$rule){if($rule->type===Nette\Forms\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
  4217. addRule($operation,$message=NULL,$arg=NULL){if($operation===Form::FLOAT){$this->addFilter(array(__CLASS__,'filterFloat'));}return
  4218. parent::addRule($operation,$message,$arg);}static
  4219. function
  4220. validateMinLength(TextBase$control,$length){return
  4221. Strings::length($control->getValue())>=$length;}static
  4222. function
  4223. validateMaxLength(TextBase$control,$length){return
  4224. Strings::length($control->getValue())<=$length;}static
  4225. function
  4226. validateLength(TextBase$control,$range){if(!is_array($range)){$range=array($range,$range);}return
  4227. Validators::isInRange(Strings::length($control->getValue()),$range);}static
  4228. function
  4229. validateEmail(TextBase$control){return
  4230. Validators::isEmail($control->getValue());}static
  4231. function
  4232. validateUrl(TextBase$control){return
  4233. Validators::isUrl($control->getValue())||Validators::isUrl('http://'.$control->getValue());}static
  4234. function
  4235. validateRegexp(TextBase$control,$regexp){return(bool)Strings::match($control->getValue(),$regexp);}static
  4236. function
  4237. validatePattern(TextBase$control,$pattern){return(bool)Strings::match($control->getValue(),"\x01^($pattern)\\z\x01u");}static
  4238. function
  4239. validateInteger(TextBase$control){return
  4240. Validators::isNumericInt($control->getValue());}static
  4241. function
  4242. validateFloat(TextBase$control){return
  4243. Validators::isNumeric(static::filterFloat($control->getValue()));}static
  4244. function
  4245. validateRange(TextBase$control,$range){return
  4246. Validators::isInRange($control->getValue(),$range);}static
  4247. function
  4248. filterFloat($s){return
  4249. str_replace(array(' ',','),array('','.'),$s);}}class
  4250. TextArea
  4251. extends
  4252. TextBase{function
  4253. __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
  4254. getControl(){$control=parent::getControl();$control->setText($this->getValue()===''?$this->translate($this->emptyValue):$this->value);return$control;}}class
  4255. TextInput
  4256. extends
  4257. TextBase{function
  4258. __construct($label=NULL,$cols=NULL,$maxLength=NULL){parent::__construct($label);$this->control->type='text';$this->control->size=$cols;$this->control->maxlength=$maxLength;$this->addFilter($this->sanitize);$this->value='';}function
  4259. sanitize($value){if($this->control->maxlength&&Nette\Utils\Strings::length($value)>$this->control->maxlength){$value=Nette\Utils\Strings::substring($value,0,$this->control->maxlength);}return
  4260. Nette\Utils\Strings::trim(strtr($value,"\r\n",' '));}function
  4261. setType($type){$this->control->type=$type;return$this;}function
  4262. setPasswordMode($mode=TRUE){$this->control->type=$mode?'password':'text';return$this;}function
  4263. getControl(){$control=parent::getControl();foreach($this->getRules()as$rule){if($rule->isNegative||$rule->type!==Nette\Forms\Rule::VALIDATOR){}elseif($rule->operation===Nette\Forms\Form::RANGE&&$control->type!=='text'){list($control->min,$control->max)=$rule->arg;}elseif($rule->operation===Nette\Forms\Form::PATTERN){$control->pattern=$rule->arg;}}if($control->type!=='password'){$control->value=$this->getValue()===''?$this->translate($this->emptyValue):$this->value;}return$control;}}use
  4264. Nette\Http;class
  4265. UploadControl
  4266. extends
  4267. BaseControl{function
  4268. __construct($label=NULL){parent::__construct($label);$this->control->type='file';}protected
  4269. function
  4270. attached($form){if($form
  4271. instanceof
  4272. Nette\Forms\Form){if($form->getMethod()!==Nette\Forms\Form::POST){throw
  4273. new
  4274. Nette\InvalidStateException('File upload requires method POST.');}$form->getElementPrototype()->enctype='multipart/form-data';}parent::attached($form);}function
  4275. setValue($value){if(is_array($value)){$this->value=new
  4276. Http\FileUpload($value);}elseif($value
  4277. instanceof
  4278. Http\FileUpload){$this->value=$value;}else{$this->value=new
  4279. Http\FileUpload(NULL);}return$this;}function
  4280. isFilled(){return$this->value
  4281. instanceof
  4282. Http\FileUpload&&$this->value->isOK();}static
  4283. function
  4284. validateFileSize(UploadControl$control,$limit){$file=$control->getValue();return$file
  4285. instanceof
  4286. Http\FileUpload&&$file->getSize()<=$limit;}static
  4287. function
  4288. validateMimeType(UploadControl$control,$mimeType){$file=$control->getValue();if($file
  4289. instanceof
  4290. Http\FileUpload){$type=strtolower($file->getContentType());$mimeTypes=is_array($mimeType)?$mimeType:explode(',',$mimeType);if(in_array($type,$mimeTypes,TRUE)){return
  4291. TRUE;}if(in_array(preg_replace('#/.*#','/*',$type),$mimeTypes,TRUE)){return
  4292. TRUE;}}return
  4293. FALSE;}static
  4294. function
  4295. validateImage(UploadControl$control){$file=$control->getValue();return$file
  4296. instanceof
  4297. Http\FileUpload&&$file->isImage();}}}namespace Nette\Forms\Rendering{use
  4298. Nette;use
  4299. Nette\Utils\Html;class
  4300. DefaultFormRenderer
  4301. extends
  4302. Nette\Object
  4303. implements
  4304. Nette\Forms\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
  4305. render(Nette\Forms\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
  4306. setClientScript(){trigger_error(__METHOD__.'() is deprecated; use unobstructive JavaScript instead.',E_USER_WARNING);return$this;}protected
  4307. function
  4308. 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
  4309. 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();$url=explode('?',(string)$el->action,2);$el->action=$url[0];$s='';if(isset($url[1])){foreach(preg_split('#[;&]#',$url[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
  4310. renderEnd(){$s='';foreach($this->form->getControls()as$control){if($control
  4311. instanceof
  4312. Nette\Forms\Controls\HiddenField&&!$control->getOption('rendered')){$s.=(string)$control->getControl();}}if(iterator_count($this->form->getComponents(TRUE,'Nette\Forms\Controls\TextInput'))<2){$s.='<!--[if IE]><input type=IEbug disabled style="display:none"><![endif]-->';}if($s){$s=$this->getWrapper('hidden container')->setHtml($s)."\n";}return$s.$this->form->getElementPrototype()->endTag()."\n";}function
  4313. renderErrors(Nette\Forms\IControl$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
  4314. as$error){$item=clone$li;if($error
  4315. instanceof
  4316. Html){$item->add($error);}else{$item->setText($error);}$ul->add($item);}return"\n".$ul->render(0);}}function
  4317. 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
  4318. instanceof
  4319. Html?clone$container:Html::el($container);$s.="\n".$container->startTag();$text=$group->getOption('label');if($text
  4320. instanceof
  4321. 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
  4322. instanceof
  4323. 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
  4324. renderControls($parent){if(!($parent
  4325. instanceof
  4326. Nette\Forms\Container||$parent
  4327. instanceof
  4328. Nette\Forms\ControlGroup)){throw
  4329. new
  4330. Nette\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
  4331. instanceof
  4332. Nette\Forms\Controls\HiddenField||$control->getForm(FALSE)!==$this->form){}elseif($control
  4333. instanceof
  4334. Nette\Forms\Controls\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
  4335. renderPair(Nette\Forms\IControl$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
  4336. %
  4337. 2){$pair->class($this->getValue('pair .odd'),TRUE);}$pair->id=$control->getOption('id');return$pair->render(0);}function
  4338. renderPairMulti(array$controls){$s=array();foreach($controls
  4339. as$control){if(!$control
  4340. instanceof
  4341. Nette\Forms\IControl){throw
  4342. new
  4343. Nette\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
  4344. renderLabel(Nette\Forms\IControl$control){$head=$this->getWrapper('label container');if($control
  4345. instanceof
  4346. Nette\Forms\Controls\Checkbox||$control
  4347. instanceof
  4348. Nette\Forms\Controls\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
  4349. instanceof
  4350. Html){$label->setHtml($label->getHtml().$suffix);$suffix='';}return$head->setHtml((string)$label.$suffix);}}function
  4351. renderControl(Nette\Forms\IControl$control){$body=$this->getWrapper('control container');if($this->counter
  4352. %
  4353. 2){$body->class($this->getValue('control .odd'),TRUE);}$description=$control->getOption('description');if($description
  4354. instanceof
  4355. 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
  4356. instanceof
  4357. Nette\Forms\Controls\Checkbox||$control
  4358. instanceof
  4359. Nette\Forms\Controls\Button){return$body->setHtml((string)$control->getControl().(string)$control->getLabel().$description);}else{return$body->setHtml((string)$control->getControl().$description);}}protected
  4360. function
  4361. getWrapper($name){$data=$this->getValue($name);return$data
  4362. instanceof
  4363. Html?clone$data:Html::el($data);}protected
  4364. function
  4365. getValue($name){$name=explode(' ',$name);$data=&$this->wrappers[$name[0]][$name[1]];return$data;}}}namespace Nette\Forms{use
  4366. Nette;final
  4367. class
  4368. Rule
  4369. extends
  4370. Nette\Object{const
  4371. CONDITION=1;const
  4372. VALIDATOR=2;const
  4373. FILTER=3;public$control;public$operation;public$arg;public$type;public$isNegative=FALSE;public$message;public$subRules;}final
  4374. class
  4375. Rules
  4376. extends
  4377. Nette\Object
  4378. implements\IteratorAggregate{const
  4379. VALIDATE_PREFIX='validate';public
  4380. static$defaultMessages=array(Form::PROTECTION=>'Please submit this form again (security token has expired).',Form::EQUAL=>'Please enter %s.',Form::FILLED=>'Please complete mandatory field.',Form::MIN_LENGTH=>'Please enter a value of at least %d characters.',Form::MAX_LENGTH=>'Please enter a value no longer than %d characters.',Form::LENGTH=>'Please enter a value between %d and %d characters long.',Form::EMAIL=>'Please enter a valid email address.',Form::URL=>'Please enter a valid URL.',Form::INTEGER=>'Please enter a numeric value.',Form::FLOAT=>'Please enter a numeric value.',Form::RANGE=>'Please enter a value between %d and %d.',Form::MAX_FILE_SIZE=>'The size of the uploaded file can be up to %d bytes.',Form::IMAGE=>'The uploaded file must be image in format JPEG, GIF or PNG.');private$rules=array();private$parent;private$toggles=array();private$control;function
  4381. __construct(IControl$control){$this->control=$control;}function
  4382. addRule($operation,$message=NULL,$arg=NULL){$rule=new
  4383. 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(static::$defaultMessages[$rule->operation])){$rule->message=static::$defaultMessages[$rule->operation];}else{$rule->message=$message;}$this->rules[]=$rule;return$this;}function
  4384. addCondition($operation,$arg=NULL){return$this->addConditionOn($this->control,$operation,$arg);}function
  4385. addConditionOn(IControl$control,$operation,$arg=NULL){$rule=new
  4386. Rule;$rule->control=$control;$rule->operation=$operation;$this->adjustOperation($rule);$rule->arg=$arg;$rule->type=Rule::CONDITION;$rule->subRules=new
  4387. static($this->control);$rule->subRules->parent=$this;$this->rules[]=$rule;return$rule->subRules;}function
  4388. elseCondition(){$rule=clone
  4389. end($this->parent->rules);$rule->isNegative=!$rule->isNegative;$rule->subRules=new
  4390. static($this->parent->control);$rule->subRules->parent=$this->parent;$this->parent->rules[]=$rule;return$rule->subRules;}function
  4391. endCondition(){return$this->parent;}function
  4392. toggle($id,$hide=TRUE){$this->toggles[$id]=$hide;return$this;}function
  4393. validate($onlyCheck=FALSE){foreach($this->rules
  4394. as$rule){if($rule->control->isDisabled()){continue;}$success=($rule->isNegative
  4395. xor$this->getCallback($rule)->invoke($rule->control,$rule->arg));if($rule->type===Rule::CONDITION&&$success){if(!$rule->subRules->validate($onlyCheck)){return
  4396. FALSE;}}elseif($rule->type===Rule::VALIDATOR&&!$success){if(!$onlyCheck){$rule->control->addError(static::formatMessage($rule,TRUE));}return
  4397. FALSE;}}return
  4398. TRUE;}final
  4399. function
  4400. getIterator(){return
  4401. new\ArrayIterator($this->rules);}final
  4402. function
  4403. getToggles(){return$this->toggles;}private
  4404. function
  4405. 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
  4406. new
  4407. Nette\InvalidArgumentException("Unknown operation$operation for control '{$rule->control->name}'.");}}private
  4408. function
  4409. getCallback($rule){$op=$rule->operation;if(is_string($op)&&strncmp($op,':',1)===0){return
  4410. new
  4411. Nette\Callback(get_class($rule->control),self::VALIDATE_PREFIX.ltrim($op,':'));}else{return
  4412. new
  4413. Nette\Callback($op);}}static
  4414. function
  4415. formatMessage($rule,$withValue){$message=$rule->message;if($message
  4416. instanceof
  4417. Nette\Utils\Html){return$message;}if(!isset($message)){$message=static::$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 Nette\Http{use
  4418. Nette;class
  4419. Context
  4420. extends
  4421. Nette\Object{private$request;private$response;function
  4422. __construct(IRequest$request,IResponse$response){$this->request=$request;$this->response=$response;}function
  4423. isModified($lastModified=NULL,$etag=NULL){if($lastModified){$this->response->setHeader('Last-Modified',$this->response->date($lastModified));}if($etag){$this->response->setHeader('ETag','"'.addslashes($etag).'"');}$ifNoneMatch=$this->request->getHeader('If-None-Match');if($ifNoneMatch==='*'){$match=TRUE;}elseif($ifNoneMatch!==NULL){$etag=$this->response->getHeader('ETag');if($etag==NULL||strpos(' '.strtr($ifNoneMatch,",\t",' '),' '.$etag)===FALSE){return
  4424. TRUE;}else{$match=TRUE;}}$ifModifiedSince=$this->request->getHeader('If-Modified-Since');if($ifModifiedSince!==NULL){$lastModified=$this->response->getHeader('Last-Modified');if($lastModified!=NULL&&strtotime($lastModified)<=strtotime($ifModifiedSince)){$match=TRUE;}else{return
  4425. TRUE;}}if(empty($match)){return
  4426. TRUE;}$this->response->setCode(IResponse::S304_NOT_MODIFIED);return
  4427. FALSE;}function
  4428. getRequest(){return$this->request;}function
  4429. getResponse(){return$this->response;}}class
  4430. FileUpload
  4431. extends
  4432. Nette\Object{private$name;private$type;private$size;private$tmpName;private$error;function
  4433. __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
  4434. getName(){return$this->name;}function
  4435. getSanitizedName(){return
  4436. trim(Nette\Utils\Strings::webalize($this->name,'.',FALSE),'.-');}function
  4437. getContentType(){if($this->isOk()&&$this->type===NULL){$this->type=Nette\Utils\MimeTypeDetector::fromFile($this->tmpName);}return$this->type;}function
  4438. getSize(){return$this->size;}function
  4439. getTemporaryFile(){return$this->tmpName;}function
  4440. __toString(){return$this->tmpName;}function
  4441. getError(){return$this->error;}function
  4442. isOk(){return$this->error===UPLOAD_ERR_OK;}function
  4443. move($dest){@mkdir(dirname($dest),0777,TRUE);@unlink($dest);if(!call_user_func(is_uploaded_file($this->tmpName)?'move_uploaded_file':'rename',$this->tmpName,$dest)){throw
  4444. new
  4445. Nette\InvalidStateException("Unable to move uploaded file '$this->tmpName' to '$dest'.");}chmod($dest,0666);$this->tmpName=$dest;return$this;}function
  4446. isImage(){return
  4447. in_array($this->getContentType(),array('image/gif','image/png','image/jpeg'),TRUE);}function
  4448. toImage(){return
  4449. Nette\Image::fromFile($this->tmpName);}function
  4450. getImageSize(){return$this->isOk()?@getimagesize($this->tmpName):NULL;}function
  4451. getContents(){return$this->isOk()?file_get_contents($this->tmpName):NULL;}}class
  4452. Request
  4453. extends
  4454. Nette\Object
  4455. implements
  4456. IRequest{private$method;private$url;private$query;private$post;private$files;private$cookies;private$headers;private$remoteAddress;private$remoteHost;function
  4457. __construct(UrlScript$url,$query=NULL,$post=NULL,$files=NULL,$cookies=NULL,$headers=NULL,$method=NULL,$remoteAddress=NULL,$remoteHost=NULL){$this->url=$url;$this->url->freeze();if($query===NULL){parse_str($url->query,$this->query);}else{$this->query=(array)$query;}$this->post=(array)$post;$this->files=(array)$files;$this->cookies=(array)$cookies;$this->headers=(array)$headers;$this->method=$method;$this->remoteAddress=$remoteAddress;$this->remoteHost=$remoteHost;}final
  4458. function
  4459. getUrl(){return$this->url;}function
  4460. getUri(){trigger_error(__METHOD__.'() is deprecated; use '.__CLASS__.'::getUrl() instead.',E_USER_WARNING);return$this->getUrl();}final
  4461. function
  4462. getQuery($key=NULL,$default=NULL){if(func_num_args()===0){return$this->query;}elseif(isset($this->query[$key])){return$this->query[$key];}else{return$default;}}final
  4463. function
  4464. getPost($key=NULL,$default=NULL){if(func_num_args()===0){return$this->post;}elseif(isset($this->post[$key])){return$this->post[$key];}else{return$default;}}final
  4465. function
  4466. getFile($key){$args=func_get_args();return
  4467. Nette\Utils\Arrays::get($this->files,$args,NULL);}final
  4468. function
  4469. getFiles(){return$this->files;}final
  4470. function
  4471. getCookie($key,$default=NULL){if(func_num_args()===0){return$this->cookies;}elseif(isset($this->cookies[$key])){return$this->cookies[$key];}else{return$default;}}final
  4472. function
  4473. getCookies(){return$this->cookies;}function
  4474. getMethod(){return$this->method;}function
  4475. isMethod($method){return
  4476. strcasecmp($this->method,$method)===0;}function
  4477. isPost(){return$this->isMethod('POST');}final
  4478. function
  4479. getHeader($header,$default=NULL){$header=strtolower($header);if(isset($this->headers[$header])){return$this->headers[$header];}else{return$default;}}function
  4480. getHeaders(){return$this->headers;}final
  4481. function
  4482. getReferer(){return
  4483. isset($this->headers['referer'])?new
  4484. Url($this->headers['referer']):NULL;}function
  4485. isSecured(){return$this->url->scheme==='https';}function
  4486. isAjax(){return$this->getHeader('X-Requested-With')==='XMLHttpRequest';}function
  4487. getRemoteAddress(){return$this->remoteAddress;}function
  4488. getRemoteHost(){if(!$this->remoteHost){$this->remoteHost=$this->remoteAddress?getHostByAddr($this->remoteAddress):NULL;}return$this->remoteHost;}function
  4489. detectLanguage(array$langs){$header=$this->getHeader('Accept-Language');if(!$header){return
  4490. 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
  4491. 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;}}use
  4492. Nette\Utils\Strings;class
  4493. RequestFactory
  4494. extends
  4495. Nette\Object{const
  4496. NONCHARS='#[^\x09\x0A\x0D\x20-\x7E\xA0-\x{10FFFF}]#u';public$urlFilters=array('path'=>array('#/{2,}#'=>'/'),'url'=>array());private$encoding;function
  4497. setEncoding($encoding){$this->encoding=$encoding;return$this;}function
  4498. createHttpRequest(){$url=new
  4499. UrlScript;$url->scheme=!empty($_SERVER['HTTPS'])&&strcasecmp($_SERVER['HTTPS'],'off')?'https':'http';$url->user=isset($_SERVER['PHP_AUTH_USER'])?$_SERVER['PHP_AUTH_USER']:'';$url->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('');}$url->host=preg_match('#^[-._a-z0-9]+\z#',$pair[0])?$pair[0]:'';if(isset($pair[1])){$url->port=(int)$pair[1];}elseif(isset($_SERVER['SERVER_PORT'])){$url->port=(int)$_SERVER['SERVER_PORT'];}if(isset($_SERVER['REQUEST_URI'])){$requestUrl=$_SERVER['REQUEST_URI'];}elseif(isset($_SERVER['ORIG_PATH_INFO'])){$requestUrl=$_SERVER['ORIG_PATH_INFO'];if(isset($_SERVER['QUERY_STRING'])&&$_SERVER['QUERY_STRING']!=''){$requestUrl.='?'.$_SERVER['QUERY_STRING'];}}else{$requestUrl='';}$requestUrl=Strings::replace($requestUrl,$this->urlFilters['url']);$tmp=explode('?',$requestUrl,2);$url->path=Strings::replace($tmp[0],$this->urlFilters['path']);$url->query=isset($tmp[1])?$tmp[1]:'';$url->canonicalize();$url->path=Strings::fixEncoding($url->path);if(isset($_SERVER['SCRIPT_NAME'])){$script=$_SERVER['SCRIPT_NAME'];}elseif(isset($_SERVER['DOCUMENT_ROOT'],$_SERVER['SCRIPT_FILENAME'])&&strncmp($_SERVER['DOCUMENT_ROOT'],$_SERVER['SCRIPT_FILENAME'],strlen($_SERVER['DOCUMENT_ROOT']))===0){$script='/'.ltrim(strtr(substr($_SERVER['SCRIPT_FILENAME'],strlen($_SERVER['DOCUMENT_ROOT'])),'\\','/'),'/');}else{$script='/';}$path=strtolower($url->path).'/';$script=strtolower($script).'/';$max=min(strlen($path),strlen($script));for($i=0;$i<$max;$i++){if($path[$i]!==$script[$i]){break;}elseif($path[$i]==='/'){$url->scriptPath=substr($url->path,0,$i+1);}}$useFilter=(!in_array(ini_get('filter.default'),array('','unsafe_raw'))||ini_get('filter.default_flags'));parse_str($url->query,$query);if(!$query){$query=$useFilter?filter_input_array(INPUT_GET,FILTER_UNSAFE_RAW):(empty($_GET)?array():$_GET);}$post=$useFilter?filter_input_array(INPUT_POST,FILTER_UNSAFE_RAW):(empty($_POST)?array():$_POST);$cookies=$useFilter?filter_input_array(INPUT_COOKIE,FILTER_UNSAFE_RAW):(empty($_COOKIE)?array():$_COOKIE);$gpc=(bool)get_magic_quotes_gpc();$old=error_reporting(error_reporting()^E_NOTICE);if($gpc||$this->encoding){$utf=strcasecmp($this->encoding,'UTF-8')===0;$list=array(&$query,&$post,&$cookies);while(list($key,$val)=each($list)){foreach($val
  4500. as$k=>$v){unset($list[$key][$k]);if($gpc){$k=stripslashes($k);}if($this->encoding&&is_string($k)&&(preg_match(self::NONCHARS,$k)||preg_last_error())){}elseif(is_array($v)){$list[$key][$k]=$v;$list[]=&$list[$key][$k];}else{if($gpc&&!$useFilter){$v=stripSlashes($v);}if($this->encoding){if($utf){$v=Strings::fixEncoding($v);}else{if(!Strings::checkEncoding($v)){$v=iconv($this->encoding,'UTF-8//IGNORE',$v);}$v=html_entity_decode($v,ENT_QUOTES,'UTF-8');}$v=preg_replace(self::NONCHARS,'',$v);}$list[$key][$k]=$v;}}}unset($list,$key,$val,$k,$v);}$files=array();$list=array();if(!empty($_FILES)){foreach($_FILES
  4501. as$k=>$v){if($this->encoding&&is_string($k)&&(preg_match(self::NONCHARS,$k)||preg_last_error())){continue;}$v['@']=&$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($this->encoding){$v['name']=preg_replace(self::NONCHARS,'',Strings::fixEncoding($v['name']));}$v['@']=new
  4502. FileUpload($v);continue;}foreach($v['name']as$k=>$foo){if($this->encoding&&is_string($k)&&(preg_match(self::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);if(function_exists('apache_request_headers')){$headers=array_change_key_case(apache_request_headers(),CASE_LOWER);}else{$headers=array();foreach($_SERVER
  4503. as$k=>$v){if(strncmp($k,'HTTP_',5)==0){$k=substr($k,5);}elseif(strncmp($k,'CONTENT_',8)){continue;}$headers[strtr(strtolower($k),'_','-')]=$v;}}return
  4504. new
  4505. Request($url,$query,$post,$files,$cookies,$headers,isset($_SERVER['REQUEST_METHOD'])?$_SERVER['REQUEST_METHOD']:NULL,isset($_SERVER['REMOTE_ADDR'])?$_SERVER['REMOTE_ADDR']:NULL,isset($_SERVER['REMOTE_HOST'])?$_SERVER['REMOTE_HOST']:NULL);}}final
  4506. class
  4507. Response
  4508. extends
  4509. Nette\Object
  4510. implements
  4511. IResponse{private
  4512. static$fixIE=TRUE;public$cookieDomain='';public$cookiePath='/';public$cookieSecure=FALSE;public$cookieHttpOnly=TRUE;private$code=self::S200_OK;function
  4513. 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,405=>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
  4514. new
  4515. Nette\InvalidArgumentException("Bad HTTP response '$code'.");}elseif(headers_sent($file,$line)){throw
  4516. new
  4517. Nette\InvalidStateException("Cannot set HTTP code after HTTP headers have been sent".($file?" (output started at $file:$line).":"."));}else{$this->code=$code;$protocol=isset($_SERVER['SERVER_PROTOCOL'])?$_SERVER['SERVER_PROTOCOL']:'HTTP/1.1';header($protocol.' '.$code,TRUE,$code);}return$this;}function
  4518. getCode(){return$this->code;}function
  4519. setHeader($name,$value){if(headers_sent($file,$line)){throw
  4520. new
  4521. Nette\InvalidStateException("Cannot send header after HTTP headers have been sent".($file?" (output started at $file:$line).":"."));}if($value===NULL&&function_exists('header_remove')){header_remove($name);}elseif(strcasecmp($name,'Content-Length')===0&&ini_get('zlib.output_compression')){}else{header($name.': '.$value,TRUE,$this->code);}return$this;}function
  4522. addHeader($name,$value){if(headers_sent($file,$line)){throw
  4523. new
  4524. Nette\InvalidStateException("Cannot send header after HTTP headers have been sent".($file?" (output started at $file:$line).":"."));}header($name.': '.$value,FALSE,$this->code);return$this;}function
  4525. setContentType($type,$charset=NULL){$this->setHeader('Content-Type',$type.($charset?'; charset='.$charset:''));return$this;}function
  4526. 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
  4527. 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=Nette\DateTime::from($time);$this->setHeader('Cache-Control','max-age='.($time->format('U')-time()));$this->setHeader('Expires',self::date($time));return$this;}function
  4528. isSent(){return
  4529. headers_sent();}function
  4530. getHeader($header,$default=NULL){$header.=':';$len=strlen($header);foreach(headers_list()as$item){if(strncasecmp($item,$header,$len)===0){return
  4531. ltrim(substr($item,$len));}}return$default;}function
  4532. getHeaders(){$headers=array();foreach(headers_list()as$header){$a=strpos($header,':');$headers[substr($header,0,$a)]=(string)substr($header,$a+2);}return$headers;}static
  4533. function
  4534. date($time=NULL){$time=Nette\DateTime::from($time);$time->setTimezone(new\DateTimeZone('GMT'));return$time->format('D, d M Y H:i:s \G\M\T');}function
  4535. __destruct(){if(self::$fixIE&&isset($_SERVER['HTTP_USER_AGENT'])&&strpos($_SERVER['HTTP_USER_AGENT'],'MSIE ')!==FALSE&&in_array($this->code,array(400,403,404,405,406,408,409,410,500,501,505),TRUE)&&$this->getHeader('Content-Type','text/html')==='text/html'){echo
  4536. Nette\Utils\Strings::random(2e3," \t\r\n");self::$fixIE=FALSE;}}function
  4537. setCookie($name,$value,$time,$path=NULL,$domain=NULL,$secure=NULL,$httpOnly=NULL){if(headers_sent($file,$line)){throw
  4538. new
  4539. Nette\InvalidStateException("Cannot set cookie after HTTP headers have been sent".($file?" (output started at $file:$line).":"."));}setcookie($name,$value,$time?Nette\DateTime::from($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);$this->removeDuplicateCookies();return$this;}function
  4540. removeDuplicateCookies(){if(headers_sent($file,$line)||ini_get('suhosin.cookie.encrypt')){return;}$flatten=array();foreach(headers_list()as$header){if(preg_match('#^Set-Cookie: .+?=#',$header,$m)){$flatten[$m[0]]=$header;if(PHP_VERSION_ID<50300){header('Set-Cookie:');}else{header_remove('Set-Cookie');}}}foreach(array_values($flatten)as$key=>$header){header($header,$key===0);}}function
  4541. deleteCookie($name,$path=NULL,$domain=NULL,$secure=NULL){$this->setCookie($name,FALSE,0,$path,$domain,$secure);}}class
  4542. Session
  4543. extends
  4544. Nette\Object{const
  4545. DEFAULT_FILE_LIFETIME=10800;private$regenerated;private
  4546. 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);private$request;private$response;function
  4547. __construct(IRequest$request,IResponse$response){$this->request=$request;$this->response=$response;}function
  4548. start(){if(self::$started){return;}$this->configure($this->options);$id=&$_COOKIE[session_name()];if(!is_string($id)||!preg_match('#^[0-9a-zA-Z,-]{22,128}\z#i',$id)){unset($_COOKIE[session_name()]);}set_error_handler(function($severity,$message)use(&$error){if(($severity&error_reporting())===$severity){$error=$message;restore_error_handler();}});session_start();$this->response->removeDuplicateCookies();restore_error_handler();if($error&&!session_id()){@session_write_close();throw
  4549. new
  4550. Nette\InvalidStateException("session_start(): $error");}self::$started=TRUE;unset($_SESSION['__NT'],$_SESSION['__NS'],$_SESSION['__NM']);$nf=&$_SESSION['__NF'];@$nf['C']++;if(empty($nf['Time'])){$nf['Time']=time();$this->regenerated=TRUE;}$browserKey=$this->request->getCookie('nette-browser');if(!$browserKey){$browserKey=Nette\Utils\Strings::random();}$browserClosed=!isset($nf['B'])||$nf['B']!==$browserKey;$nf['B']=$browserKey;$this->sendCookie();if(isset($nf['META'])){$now=time();foreach($nf['META']as$section=>$metadata){if(is_array($metadata)){foreach($metadata
  4551. as$variable=>$value){if((!empty($value['B'])&&$browserClosed)||(!empty($value['T'])&&$now>$value['T'])||(isset($nf['DATA'][$section][$variable])&&is_object($nf['DATA'][$section][$variable])&&(isset($value['V'])?$value['V']:NULL)!=Nette\Reflection\ClassType::from($nf['DATA'][$section][$variable])->getAnnotation('serializationVersion'))){if($variable===''){unset($nf['META'][$section],$nf['DATA'][$section]);continue
  4552. 2;}unset($nf['META'][$section][$variable],$nf['DATA'][$section][$variable]);}}}}}if($this->regenerated){$this->regenerated=FALSE;$this->regenerateId();}register_shutdown_function(array($this,'clean'));}function
  4553. isStarted(){return(bool)self::$started;}function
  4554. close(){if(self::$started){$this->clean();session_write_close();self::$started=FALSE;}}function
  4555. destroy(){if(!self::$started){throw
  4556. new
  4557. Nette\InvalidStateException('Session is not started.');}session_destroy();$_SESSION=NULL;self::$started=FALSE;if(!$this->response->isSent()){$params=session_get_cookie_params();$this->response->deleteCookie(session_name(),$params['path'],$params['domain'],$params['secure']);}}function
  4558. exists(){return
  4559. self::$started||$this->request->getCookie($this->getName())!==NULL;}function
  4560. regenerateId(){if(self::$started&&!$this->regenerated){if(headers_sent($file,$line)){throw
  4561. new
  4562. Nette\InvalidStateException("Cannot regenerate session ID after HTTP headers have been sent".($file?" (output started at $file:$line).":"."));}session_regenerate_id(TRUE);session_write_close();$backup=$_SESSION;session_start();$_SESSION=$backup;$this->response->removeDuplicateCookies();}$this->regenerated=TRUE;}function
  4563. getId(){return
  4564. session_id();}function
  4565. setName($name){if(!is_string($name)||!preg_match('#[^0-9.][^.]*\z#A',$name)){throw
  4566. new
  4567. Nette\InvalidArgumentException('Session name must be a string and cannot contain dot.');}session_name($name);return$this->setOptions(array('name'=>$name));}function
  4568. getName(){return
  4569. isset($this->options['name'])?$this->options['name']:session_name();}function
  4570. getSection($section,$class='Nette\Http\SessionSection'){return
  4571. new$class($this,$section);}function
  4572. getNamespace($section){trigger_error(__METHOD__.'() is deprecated; use getSection() instead.',E_USER_WARNING);return$this->getSection($section);}function
  4573. hasSection($section){if($this->exists()&&!self::$started){$this->start();}return!empty($_SESSION['__NF']['DATA'][$section]);}function
  4574. getIterator(){if($this->exists()&&!self::$started){$this->start();}if(isset($_SESSION['__NF']['DATA'])){return
  4575. new\ArrayIterator(array_keys($_SESSION['__NF']['DATA']));}else{return
  4576. new\ArrayIterator;}}function
  4577. 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
  4578. setOptions(array$options){if(self::$started){$this->configure($options);}$this->options=$options+$this->options;if(!empty($options['auto_start'])){$this->start();}return$this;}function
  4579. getOptions(){return$this->options;}private
  4580. function
  4581. configure(array$config){$special=array('cache_expire'=>1,'cache_limiter'=>1,'save_path'=>1,'name'=>1);foreach($config
  4582. as$key=>$value){if(!strncmp($key,'session.',8)){$key=substr($key,8);}$key=strtolower(preg_replace('#(.)(?=[A-Z])#','$1_',$key));if($value===NULL||ini_get("session.$key")==$value){continue;}elseif(strncmp($key,'cookie_',7)===0){if(!isset($cookie)){$cookie=session_get_cookie_params();}$cookie[substr($key,7)]=$value;}else{if(defined('SID')){throw
  4583. new
  4584. Nette\InvalidStateException("Unable to set 'session.$key' to value '$value' when session has been started".($this->started?".":" by session.auto_start or session_start()."));}if(isset($special[$key])){$key="session_$key";$key($value);}elseif(function_exists('ini_set')){ini_set("session.$key",$value);}elseif(!Nette\Framework::$iAmUsingBadHost){throw
  4585. new
  4586. Nette\NotSupportedException('Required function ini_set() is disabled.');}}}if(isset($cookie)){session_set_cookie_params($cookie['lifetime'],$cookie['path'],$cookie['domain'],$cookie['secure'],$cookie['httponly']);if(self::$started){$this->sendCookie();}}}function
  4587. setExpiration($time){if(empty($time)){return$this->setOptions(array('gc_maxlifetime'=>self::DEFAULT_FILE_LIFETIME,'cookie_lifetime'=>0));}else{$time=Nette\DateTime::from($time)->format('U')-time();return$this->setOptions(array('gc_maxlifetime'=>$time,'cookie_lifetime'=>$time));}}function
  4588. setCookieParameters($path,$domain=NULL,$secure=NULL){return$this->setOptions(array('cookie_path'=>$path,'cookie_domain'=>$domain,'cookie_secure'=>$secure));}function
  4589. getCookieParameters(){return
  4590. session_get_cookie_params();}function
  4591. setCookieParams($path,$domain=NULL,$secure=NULL){trigger_error(__METHOD__.'() is deprecated; use setCookieParameters() instead.',E_USER_WARNING);return$this->setCookieParameters($path,$domain,$secure);}function
  4592. setSavePath($path){return$this->setOptions(array('save_path'=>$path));}function
  4593. setStorage(ISessionStorage$storage){if(self::$started){throw
  4594. new
  4595. Nette\InvalidStateException("Unable to set storage when session has been started.");}session_set_save_handler(array($storage,'open'),array($storage,'close'),array($storage,'read'),array($storage,'write'),array($storage,'remove'),array($storage,'clean'));}private
  4596. function
  4597. sendCookie(){$cookie=$this->getCookieParameters();$this->response->setCookie(session_name(),session_id(),$cookie['lifetime']?$cookie['lifetime']+time():0,$cookie['path'],$cookie['domain'],$cookie['secure'],$cookie['httponly'])->setCookie('nette-browser',$_SESSION['__NF']['B'],Response::BROWSER,$cookie['path'],$cookie['domain']);}}class
  4598. SessionSection
  4599. extends
  4600. Nette\Object
  4601. implements\IteratorAggregate,\ArrayAccess{private$session;private$name;private$data;private$meta=FALSE;public$warnOnUndefined=FALSE;function
  4602. __construct(Session$session,$name){if(!is_string($name)){throw
  4603. new
  4604. Nette\InvalidArgumentException("Session namespace must be a string, ".gettype($name)." given.");}$this->session=$session;$this->name=$name;}private
  4605. function
  4606. start(){if($this->meta===FALSE){$this->session->start();$this->data=&$_SESSION['__NF']['DATA'][$this->name];$this->meta=&$_SESSION['__NF']['META'][$this->name];}}function
  4607. getIterator(){$this->start();if(isset($this->data)){return
  4608. new\ArrayIterator($this->data);}else{return
  4609. new\ArrayIterator;}}function
  4610. __set($name,$value){$this->start();$this->data[$name]=$value;if(is_object($value)){$this->meta[$name]['V']=Nette\Reflection\ClassType::from($value)->getAnnotation('serializationVersion');}}function&__get($name){$this->start();if($this->warnOnUndefined&&!array_key_exists($name,$this->data)){trigger_error("The variable '$name' does not exist in session section",E_USER_NOTICE);}return$this->data[$name];}function
  4611. __isset($name){if($this->session->exists()){$this->start();}return
  4612. isset($this->data[$name]);}function
  4613. __unset($name){$this->start();unset($this->data[$name],$this->meta[$name]);}function
  4614. offsetSet($name,$value){$this->__set($name,$value);}function
  4615. offsetGet($name){return$this->__get($name);}function
  4616. offsetExists($name){return$this->__isset($name);}function
  4617. offsetUnset($name){$this->__unset($name);}function
  4618. setExpiration($time,$variables=NULL){$this->start();if(empty($time)){$time=NULL;$whenBrowserIsClosed=TRUE;}else{$time=Nette\DateTime::from($time)->format('U');$max=ini_get('session.gc_maxlifetime');if($time-time()>$max+3){trigger_error("The expiration time is greater than the session expiration $max seconds",E_USER_NOTICE);}$whenBrowserIsClosed=FALSE;}if($variables===NULL){$this->meta['']['T']=$time;$this->meta['']['B']=$whenBrowserIsClosed;}elseif(is_array($variables)){foreach($variables
  4619. 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
  4620. removeExpiration($variables=NULL){$this->start();if($variables===NULL){unset($this->meta['']['T'],$this->meta['']['B']);}elseif(is_array($variables)){foreach($variables
  4621. as$variable){unset($this->meta[$variable]['T'],$this->meta[$variable]['B']);}}else{unset($this->meta[$variables]['T'],$this->meta[$variable]['B']);}}function
  4622. remove(){$this->start();$this->data=NULL;$this->meta=NULL;}}class
  4623. Url
  4624. extends
  4625. Nette\FreezableObject{public
  4626. 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
  4627. __construct($url=NULL){if(is_string($url)){$parts=@parse_url($url);if($parts===FALSE){throw
  4628. new
  4629. Nette\InvalidArgumentException("Malformed or unsupported URI '$url'.");}foreach($parts
  4630. 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($url
  4631. instanceof
  4632. self){foreach($this
  4633. as$key=>$val){$this->$key=$url->$key;}}}function
  4634. setScheme($value){$this->updating();$this->scheme=(string)$value;return$this;}function
  4635. getScheme(){return$this->scheme;}function
  4636. setUser($value){$this->updating();$this->user=(string)$value;return$this;}function
  4637. getUser(){return$this->user;}function
  4638. setPassword($value){$this->updating();$this->pass=(string)$value;return$this;}function
  4639. getPassword(){return$this->pass;}function
  4640. setHost($value){$this->updating();$this->host=(string)$value;return$this;}function
  4641. getHost(){return$this->host;}function
  4642. setPort($value){$this->updating();$this->port=(int)$value;return$this;}function
  4643. getPort(){return$this->port;}function
  4644. setPath($value){$this->updating();$this->path=(string)$value;return$this;}function
  4645. getPath(){return$this->path;}function
  4646. setQuery($value){$this->updating();$this->query=(string)(is_array($value)?http_build_query($value,'','&'):$value);return$this;}function
  4647. appendQuery($value){$this->updating();$value=(string)(is_array($value)?http_build_query($value,'','&'):$value);$this->query.=($this->query===''||$value==='')?$value:'&'.$value;}function
  4648. getQuery(){return$this->query;}function
  4649. setFragment($value){$this->updating();$this->fragment=(string)$value;return$this;}function
  4650. getFragment(){return$this->fragment;}function
  4651. getAbsoluteUrl(){return$this->scheme.'://'.$this->getAuthority().$this->path.($this->query===''?'':'?'.$this->query).($this->fragment===''?'':'#'.$this->fragment);}function
  4652. 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
  4653. getHostUrl(){return$this->scheme.'://'.$this->getAuthority();}function
  4654. getBasePath(){$pos=strrpos($this->path,'/');return$pos===FALSE?'':substr($this->path,0,$pos+1);}function
  4655. getBaseUrl(){return$this->scheme.'://'.$this->getAuthority().$this->getBasePath();}function
  4656. getRelativeUrl(){return(string)substr($this->getAbsoluteUrl(),strlen($this->getBaseUrl()));}function
  4657. isEqual($url){$part=self::unescape(strtok($url,'?#'),'%/');if(strncmp($part,'//',2)===0){if($part!=='//'.$this->getAuthority().$this->path){return
  4658. FALSE;}}elseif(strncmp($part,'/',1)===0){if($part!==$this->path){return
  4659. FALSE;}}else{if($part!==$this->scheme.'://'.$this->getAuthority().$this->path){return
  4660. FALSE;}}$part=preg_split('#[&;]#',self::unescape(strtr((string)strtok('?#'),'+',' '),'%&;=+'));sort($part);$query=preg_split('#[&;]#',$this->query);sort($query);return$part===$query;}function
  4661. 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
  4662. __toString(){return$this->getAbsoluteUrl();}static
  4663. function
  4664. 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;}function
  4665. getRelativeUri(){trigger_error(__METHOD__.'() is deprecated; use '.__CLASS__.'::getRelativeUrl() instead.',E_USER_WARNING);return$this->getRelativeUrl();}function
  4666. getAbsoluteUri(){trigger_error(__METHOD__.'() is deprecated; use '.__CLASS__.'::getAbsoluteUrl() instead.',E_USER_WARNING);return$this->getAbsoluteUrl();}function
  4667. getHostUri(){trigger_error(__METHOD__.'() is deprecated; use '.__CLASS__.'::getHostUrl() instead.',E_USER_WARNING);return$this->getHostUrl();}function
  4668. getBaseUri(){trigger_error(__METHOD__.'() is deprecated; use '.__CLASS__.'::getBaseUrl() instead.',E_USER_WARNING);return$this->getBaseUrl();}}class
  4669. UrlScript
  4670. extends
  4671. Url{private$scriptPath='/';function
  4672. setScriptPath($value){$this->updating();$this->scriptPath=(string)$value;return$this;}function
  4673. getScriptPath(){return$this->scriptPath;}function
  4674. getBasePath(){$pos=strrpos($this->scriptPath,'/');return$pos===FALSE?'':substr($this->path,0,$pos+1);}function
  4675. getPathInfo(){return(string)substr($this->path,strlen($this->scriptPath));}}use
  4676. Nette\Security\IIdentity;class
  4677. UserStorage
  4678. extends
  4679. Nette\Object
  4680. implements
  4681. Nette\Security\IUserStorage{private$namespace='';private$sessionHandler;private$sessionSection;function
  4682. __construct(Session$sessionHandler){$this->sessionHandler=$sessionHandler;}function
  4683. setAuthenticated($state){$section=$this->getSessionSection(TRUE);$section->authenticated=(bool)$state;$this->sessionHandler->regenerateId();if($state){$section->reason=NULL;$section->authTime=time();}else{$section->reason=self::MANUAL;$section->authTime=NULL;}return$this;}function
  4684. isAuthenticated(){$session=$this->getSessionSection(FALSE);return$session&&$session->authenticated;}function
  4685. setIdentity(IIdentity$identity=NULL){$this->getSessionSection(TRUE)->identity=$identity;return$this;}function
  4686. getIdentity(){$session=$this->getSessionSection(FALSE);return$session?$session->identity:NULL;}function
  4687. setNamespace($namespace){if($this->namespace!==$namespace){$this->namespace=(string)$namespace;$this->sessionSection=NULL;}return$this;}function
  4688. getNamespace(){return$this->namespace;}function
  4689. setExpiration($time,$flags=0){$section=$this->getSessionSection(TRUE);if($time){$time=Nette\DateTime::from($time)->format('U');$section->expireTime=$time;$section->expireDelta=$time-time();}else{unset($section->expireTime,$section->expireDelta);}$section->expireIdentity=(bool)($flags&self::CLEAR_IDENTITY);$section->expireBrowser=(bool)($flags&self::BROWSER_CLOSED);$section->browserCheck=TRUE;$section->setExpiration(0,'browserCheck');$section->setExpiration($time,'foo');return$this;}function
  4690. getLogoutReason(){$session=$this->getSessionSection(FALSE);return$session?$session->reason:NULL;}protected
  4691. function
  4692. getSessionSection($need){if($this->sessionSection!==NULL){return$this->sessionSection;}if(!$need&&!$this->sessionHandler->exists()){return
  4693. NULL;}$this->sessionSection=$section=$this->sessionHandler->getSection('Nette.Http.UserStorage/'.$this->namespace);if(!$section->identity
  4694. instanceof
  4695. IIdentity||!is_bool($section->authenticated)){$section->remove();}if($section->authenticated&&$section->expireBrowser&&!$section->browserCheck){$section->reason=self::BROWSER_CLOSED;$section->authenticated=FALSE;if($section->expireIdentity){unset($section->identity);}}if($section->authenticated&&$section->expireDelta>0){if($section->expireTime<time()){$section->reason=self::INACTIVITY;$section->authenticated=FALSE;if($section->expireIdentity){unset($section->identity);}}$section->expireTime=time()+$section->expireDelta;}if(!$section->authenticated){unset($section->expireTime,$section->expireDelta,$section->expireIdentity,$section->expireBrowser,$section->browserCheck,$section->authTime);}return$this->sessionSection;}}}namespace Nette\Iterators{use
  4696. Nette;class
  4697. CachingIterator
  4698. extends\CachingIterator
  4699. implements\Countable{private$counter=0;function
  4700. __construct($iterator){if(is_array($iterator)||$iterator
  4701. instanceof\stdClass){$iterator=new\ArrayIterator($iterator);}elseif($iterator
  4702. instanceof\Traversable){if($iterator
  4703. instanceof\IteratorAggregate){$iterator=$iterator->getIterator();}elseif(!$iterator
  4704. instanceof\Iterator){$iterator=new\IteratorIterator($iterator);}}else{throw
  4705. new
  4706. Nette\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
  4707. isFirst($width=NULL){return$this->counter===1||($width&&$this->counter!==0&&(($this->counter-1)%$width)===0);}function
  4708. isLast($width=NULL){return!$this->hasNext()||($width&&($this->counter
  4709. %$width)===0);}function
  4710. isEmpty(){return$this->counter===0;}function
  4711. isOdd(){return$this->counter
  4712. %
  4713. 2===1;}function
  4714. isEven(){return$this->counter
  4715. %
  4716. 2===0;}function
  4717. getCounter(){return$this->counter;}function
  4718. count(){$inner=$this->getInnerIterator();if($inner
  4719. instanceof\Countable){return$inner->count();}else{throw
  4720. new
  4721. Nette\NotSupportedException('Iterator is not countable.');}}function
  4722. next(){parent::next();if(parent::valid()){$this->counter++;}}function
  4723. rewind(){parent::rewind();$this->counter=parent::valid()?1:0;}function
  4724. getNextKey(){return$this->getInnerIterator()->key();}function
  4725. getNextValue(){return$this->getInnerIterator()->current();}function
  4726. __call($name,$args){return
  4727. Nette\ObjectMixin::call($this,$name,$args);}function&__get($name){return
  4728. Nette\ObjectMixin::get($this,$name);}function
  4729. __set($name,$value){return
  4730. Nette\ObjectMixin::set($this,$name,$value);}function
  4731. __isset($name){return
  4732. Nette\ObjectMixin::has($this,$name);}function
  4733. __unset($name){Nette\ObjectMixin::remove($this,$name);}}class
  4734. Filter
  4735. extends\FilterIterator{private$callback;function
  4736. __construct(\Iterator$iterator,$callback){parent::__construct($iterator);$this->callback=new
  4737. Nette\Callback($callback);}function
  4738. accept(){return$this->callback->invoke($this);}}class
  4739. InstanceFilter
  4740. extends\FilterIterator
  4741. implements\Countable{private$type;function
  4742. __construct(\Iterator$iterator,$type){$this->type=$type;parent::__construct($iterator);}function
  4743. accept(){return$this->current()instanceof$this->type;}function
  4744. count(){return
  4745. iterator_count($this);}}class
  4746. Mapper
  4747. extends\IteratorIterator{private$callback;function
  4748. __construct(\Traversable$iterator,$callback){parent::__construct($iterator);$this->callback=new
  4749. Nette\Callback($callback);}function
  4750. current(){return$this->callback->invoke(parent::current(),parent::key());}}class
  4751. RecursiveFilter
  4752. extends\FilterIterator
  4753. implements\RecursiveIterator{private$callback;private$childrenCallback;function
  4754. __construct(\RecursiveIterator$iterator,$callback,$childrenCallback=NULL){parent::__construct($iterator);$this->callback=$callback===NULL?NULL:new
  4755. Nette\Callback($callback);$this->childrenCallback=$childrenCallback===NULL?NULL:new
  4756. Nette\Callback($childrenCallback);}function
  4757. accept(){return$this->callback===NULL||$this->callback->invoke($this);}function
  4758. hasChildren(){return$this->getInnerIterator()->hasChildren()&&($this->childrenCallback===NULL||$this->childrenCallback->invoke($this));}function
  4759. getChildren(){return
  4760. new
  4761. static($this->getInnerIterator()->getChildren(),$this->callback,$this->childrenCallback);}}class
  4762. Recursor
  4763. extends\IteratorIterator
  4764. implements\RecursiveIterator,\Countable{function
  4765. hasChildren(){$obj=$this->current();return($obj
  4766. instanceof\IteratorAggregate&&$obj->getIterator()instanceof\RecursiveIterator)||$obj
  4767. instanceof\RecursiveIterator;}function
  4768. getChildren(){$obj=$this->current();return$obj
  4769. instanceof\IteratorAggregate?$obj->getIterator():$obj;}function
  4770. count(){return
  4771. iterator_count($this);}}}namespace Nette\Latte{use
  4772. Nette;use
  4773. Nette\Utils\Strings;class
  4774. Compiler
  4775. extends
  4776. Nette\Object{public$defaultContentType=self::CONTENT_XHTML;private$tokens;private$output;private$position;private$macros;private$macroHandlers;private$htmlNodes=array();private$macroNodes=array();private$attrCodes=array();private$contentType;private$context;private$templateId;const
  4777. CONTENT_HTML='html',CONTENT_XHTML='xhtml',CONTENT_XML='xml',CONTENT_JS='js',CONTENT_CSS='css',CONTENT_ICAL='ical',CONTENT_TEXT='text';const
  4778. CONTEXT_COMMENT='comment',CONTEXT_SINGLE_QUOTED="'",CONTEXT_DOUBLE_QUOTED='"';function
  4779. __construct(){$this->macroHandlers=new\SplObjectStorage;}function
  4780. addMacro($name,IMacro$macro){$this->macros[$name][]=$macro;$this->macroHandlers->attach($macro);return$this;}function
  4781. compile(array$tokens){$this->templateId=Strings::random();$this->tokens=$tokens;$output='';$this->output=&$output;$this->htmlNodes=$this->macroNodes=array();$this->setContentType($this->defaultContentType);foreach($this->macroHandlers
  4782. as$handler){$handler->initialize($this);}try{foreach($tokens
  4783. as$this->position=>$token){if($token->type===Token::TEXT){$this->output.=$token->text;}elseif($token->type===Token::MACRO_TAG){$isRightmost=!isset($tokens[$this->position+1])||substr($tokens[$this->position+1]->text,0,1)==="\n";$this->writeMacro($token->name,$token->value,$token->modifiers,$isRightmost);}elseif($token->type===Token::HTML_TAG_BEGIN){$this->processHtmlTagBegin($token);}elseif($token->type===Token::HTML_TAG_END){$this->processHtmlTagEnd($token);}elseif($token->type===Token::HTML_ATTRIBUTE){$this->processHtmlAttribute($token);}elseif($token->type===Token::COMMENT){$this->processComment($token);}}}catch(CompileException$e){$e->sourceLine=$token->line;throw$e;}foreach($this->htmlNodes
  4784. as$htmlNode){if(!empty($htmlNode->macroAttrs)){throw
  4785. new
  4786. CompileException("Missing end tag </$htmlNode->name> for macro-attribute ".Parser::N_PREFIX.implode(' and '.Parser::N_PREFIX,array_keys($htmlNode->macroAttrs)).".",0,$token->line);}}$prologs=$epilogs='';foreach($this->macroHandlers
  4787. as$handler){$res=$handler->finalize();$handlerName=get_class($handler);$prologs.=empty($res[0])?'':"<?php\n// prolog $handlerName\n$res[0]\n?>";$epilogs=(empty($res[1])?'':"<?php\n// epilog $handlerName\n$res[1]\n?>").$epilogs;}$output=($prologs?$prologs."<?php\n//\n// main template\n//\n?>\n":'').$output.$epilogs;if($this->macroNodes){throw
  4788. new
  4789. CompileException("There are unclosed macros.",0,$token->line);}$output=$this->expandTokens($output);return$output;}function
  4790. setContentType($type){$this->contentType=$type;$this->context=NULL;return$this;}function
  4791. getContentType(){return$this->contentType;}function
  4792. setContext($context,$sub=NULL){$this->context=array($context,$sub);return$this;}function
  4793. getContext(){return$this->context;}function
  4794. getTemplateId(){return$this->templateId;}function
  4795. getLine(){return$this->tokens?$this->tokens[$this->position]->line:NULL;}function
  4796. expandTokens($s){return
  4797. strtr($s,$this->attrCodes);}private
  4798. function
  4799. processHtmlTagBegin(Token$token){if($token->closing){do{$htmlNode=array_pop($this->htmlNodes);if(!$htmlNode){$htmlNode=new
  4800. HtmlNode($token->name);}if(strcasecmp($htmlNode->name,$token->name)===0){break;}if($htmlNode->macroAttrs){throw
  4801. new
  4802. CompileException("Unexpected </$token->name>.",0,$token->line);}}while(TRUE);$this->htmlNodes[]=$htmlNode;$htmlNode->closing=TRUE;$htmlNode->offset=strlen($this->output);$this->setContext(NULL);}elseif($token->text==='<!--'){$this->setContext(self::CONTEXT_COMMENT);}else{$this->htmlNodes[]=$htmlNode=new
  4803. HtmlNode($token->name);$htmlNode->isEmpty=in_array($this->contentType,array(self::CONTENT_HTML,self::CONTENT_XHTML))&&isset(Nette\Utils\Html::$emptyElements[strtolower($token->name)]);$htmlNode->offset=strlen($this->output);$this->setContext(NULL);}$this->output.=$token->text;}private
  4804. function
  4805. processHtmlTagEnd(Token$token){if($token->text==='-->'){$this->output.=$token->text;$this->setContext(NULL);return;}$htmlNode=end($this->htmlNodes);$isEmpty=!$htmlNode->closing&&(Strings::contains($token->text,'/')||$htmlNode->isEmpty);if($isEmpty&&in_array($this->contentType,array(self::CONTENT_HTML,self::CONTENT_XHTML))){$token->text=preg_replace('#^.*>#',$this->contentType===self::CONTENT_XHTML?' />':'>',$token->text);}if(empty($htmlNode->macroAttrs)){$this->output.=$token->text;}else{$code=substr($this->output,$htmlNode->offset).$token->text;$this->output=substr($this->output,0,$htmlNode->offset);$this->writeAttrsMacro($code,$htmlNode);if($isEmpty){$htmlNode->closing=TRUE;$this->writeAttrsMacro('',$htmlNode);}}if($isEmpty){$htmlNode->closing=TRUE;}if(!$htmlNode->closing&&(strcasecmp($htmlNode->name,'script')===0||strcasecmp($htmlNode->name,'style')===0)){$this->setContext(strcasecmp($htmlNode->name,'style')?self::CONTENT_JS:self::CONTENT_CSS);}else{$this->setContext(NULL);if($htmlNode->closing){array_pop($this->htmlNodes);}}}private
  4806. function
  4807. processHtmlAttribute(Token$token){$htmlNode=end($this->htmlNodes);if(Strings::startsWith($token->name,Parser::N_PREFIX)){$name=substr($token->name,strlen(Parser::N_PREFIX));if(isset($htmlNode->macroAttrs[$name])){throw
  4808. new
  4809. CompileException("Found multiple macro-attributes $token->name.",0,$token->line);}$htmlNode->macroAttrs[$name]=$token->value;}else{$htmlNode->attrs[$token->name]=TRUE;$this->output.=$token->text;if($token->value){$context=NULL;if(strncasecmp($token->name,'on',2)===0){$context=self::CONTENT_JS;}elseif($token->name==='style'){$context=self::CONTENT_CSS;}$this->setContext($token->value,$context);}}}private
  4810. function
  4811. processComment(Token$token){$isLeftmost=trim(substr($this->output,strrpos("\n$this->output","\n")))==='';if(!$isLeftmost){$this->output.=substr($token->text,strlen(rtrim($token->text,"\n")));}}function
  4812. writeMacro($name,$args=NULL,$modifiers=NULL,$isRightmost=FALSE,HtmlNode$htmlNode=NULL,$prefix=NULL){if($name[0]==='/'){$node=end($this->macroNodes);if(!$node||("/$node->name"!==$name&&'/'!==$name)||$modifiers||($args&&$node->args&&!Strings::startsWith("$node->args ","$args "))){$name.=$args?' ':'';throw
  4813. new
  4814. CompileException("Unexpected macro {{$name}{$args}{$modifiers}}".($node?", expecting {/$node->name}".($args&&$node->args?" or eventually {/$node->name $node->args}":''):''));}array_pop($this->macroNodes);if(!$node->args){$node->setArgs($args);}$isLeftmost=$node->content?trim(substr($this->output,strrpos("\n$this->output","\n")))==='':FALSE;$node->closing=TRUE;$node->macro->nodeClosed($node);$this->output=&$node->saved[0];$this->writeCode($node->openingCode,$this->output,$node->saved[1]);$this->writeCode($node->closingCode,$node->content,$isRightmost,$isLeftmost);$this->output.=$node->content;}else{$node=$this->expandMacro($name,$args,$modifiers,$htmlNode,$prefix);if($node->isEmpty){$this->writeCode($node->openingCode,$this->output,$isRightmost);}else{$this->macroNodes[]=$node;$node->saved=array(&$this->output,$isRightmost);$this->output=&$node->content;}}return$node;}private
  4815. function
  4816. writeCode($code,&$output,$isRightmost,$isLeftmost=NULL){if($isRightmost){$leftOfs=strrpos("\n$output","\n");$isLeftmost=$isLeftmost===NULL?trim(substr($output,$leftOfs))==='':$isLeftmost;if($isLeftmost&&substr($code,0,11)!=='<?php echo '){$output=substr($output,0,$leftOfs);}elseif(substr($code,-2)==='?>'){$code.="\n";}}$output.=$code;}function
  4817. writeAttrsMacro($code,HtmlNode$htmlNode){$attrs=$htmlNode->macroAttrs;$left=$right=array();$attrCode='';foreach($this->macros
  4818. as$name=>$foo){$attrName=MacroNode::PREFIX_INNER."-$name";if(isset($attrs[$attrName])){if($htmlNode->closing){$left[]=array("/$name",'',MacroNode::PREFIX_INNER);}else{array_unshift($right,array($name,$attrs[$attrName],MacroNode::PREFIX_INNER));}unset($attrs[$attrName]);}}foreach(array_reverse($this->macros)as$name=>$foo){$attrName=MacroNode::PREFIX_TAG."-$name";if(isset($attrs[$attrName])){$left[]=array($name,$attrs[$attrName],MacroNode::PREFIX_TAG);array_unshift($right,array("/$name",'',MacroNode::PREFIX_TAG));unset($attrs[$attrName]);}}foreach($this->macros
  4819. as$name=>$foo){if(isset($attrs[$name])){if($htmlNode->closing){$right[]=array("/$name",'',NULL);}else{array_unshift($left,array($name,$attrs[$name],NULL));}unset($attrs[$name]);}}if($attrs){throw
  4820. new
  4821. CompileException("Unknown macro-attribute ".Parser::N_PREFIX.implode(' and '.Parser::N_PREFIX,array_keys($attrs)));}if(!$htmlNode->closing){$htmlNode->attrCode=&$this->attrCodes[$uniq=' n:'.Nette\Utils\Strings::random()];$code=substr_replace($code,$uniq,strrpos($code,'/>')?:strrpos($code,'>'),0);}foreach($left
  4822. as$item){$node=$this->writeMacro($item[0],$item[1],NULL,NULL,$htmlNode,$item[2]);if($node->closing||$node->isEmpty){$htmlNode->attrCode.=$node->attrCode;if($node->isEmpty){unset($htmlNode->macroAttrs[$node->name]);}}}$this->output.=$code;foreach($right
  4823. as$item){$node=$this->writeMacro($item[0],$item[1],NULL,NULL,$htmlNode);if($node->closing){$htmlNode->attrCode.=$node->attrCode;}}if($right&&substr($this->output,-2)==='?>'){$this->output.="\n";}}function
  4824. expandMacro($name,$args,$modifiers=NULL,HtmlNode$htmlNode=NULL,$prefix=NULL){if(empty($this->macros[$name])){$cdata=$this->htmlNodes&&in_array(strtolower(end($this->htmlNodes)->name),array('script','style'));throw
  4825. new
  4826. CompileException("Unknown macro {{$name}}".($cdata?" (in JavaScript or CSS, try to put a space after bracket.)":''));}foreach(array_reverse($this->macros[$name])as$macro){$node=new
  4827. MacroNode($macro,$name,$args,$modifiers,$this->macroNodes?end($this->macroNodes):NULL,$htmlNode,$prefix);if($macro->nodeOpened($node)!==FALSE){return$node;}}throw
  4828. new
  4829. CompileException("Unhandled macro {{$name}}");}}class
  4830. Engine
  4831. extends
  4832. Nette\Object{private$parser;private$compiler;function
  4833. __construct(){$this->parser=new
  4834. Parser;$this->compiler=new
  4835. Compiler;$this->compiler->defaultContentType=Compiler::CONTENT_XHTML;Macros\CoreMacros::install($this->compiler);$this->compiler->addMacro('cache',new
  4836. Macros\CacheMacro($this->compiler));Macros\UIMacros::install($this->compiler);Macros\FormMacros::install($this->compiler);}function
  4837. __invoke($s){return$this->compiler->compile($this->parser->parse($s));}function
  4838. getParser(){return$this->parser;}function
  4839. getCompiler(){return$this->compiler;}}}namespace Nette\Templating{use
  4840. Nette;class
  4841. FilterException
  4842. extends
  4843. Nette\InvalidStateException{public$sourceFile;public$sourceLine;function
  4844. __construct($message,$code=0,$sourceLine=0){$this->sourceLine=(int)$sourceLine;parent::__construct($message,$code);}function
  4845. setSourceFile($file){$this->sourceFile=(string)$file;$this->message=rtrim($this->message,'.')." in ".str_replace(dirname(dirname($file)),'...',$file).($this->sourceLine?":$this->sourceLine":'');}}}namespace Nette\Latte{use
  4846. Nette;class
  4847. CompileException
  4848. extends
  4849. Nette\Templating\FilterException{}class_alias('Nette\Latte\CompileException','Nette\Latte\ParseException');class
  4850. HtmlNode
  4851. extends
  4852. Nette\Object{public$name;public$isEmpty=FALSE;public$attrs=array();public$macroAttrs=array();public$closing=FALSE;public$attrCode;public$offset;function
  4853. __construct($name){$this->name=$name;}}class
  4854. MacroNode
  4855. extends
  4856. Nette\Object{const
  4857. PREFIX_INNER='inner',PREFIX_TAG='tag';public$macro;public$name;public$isEmpty=FALSE;public$args;public$modifiers;public$closing=FALSE;public$tokenizer;public$parentNode;public$openingCode;public$closingCode;public$attrCode;public$content;public$data;public$htmlNode;public$prefix;public$saved;function
  4858. __construct(IMacro$macro,$name,$args=NULL,$modifiers=NULL,MacroNode$parentNode=NULL,HtmlNode$htmlNode=NULL,$prefix=NULL){$this->macro=$macro;$this->name=(string)$name;$this->modifiers=(string)$modifiers;$this->parentNode=$parentNode;$this->htmlNode=$htmlNode;$this->prefix=$prefix;$this->tokenizer=new
  4859. MacroTokenizer($this->args);$this->data=new\stdClass;$this->setArgs($args);}function
  4860. setArgs($args){$this->args=(string)$args;$this->tokenizer->tokenize($this->args);}}}namespace Nette\Latte\Macros{use
  4861. Nette;use
  4862. Nette\Latte;class
  4863. CacheMacro
  4864. extends
  4865. Nette\Object
  4866. implements
  4867. Latte\IMacro{private$used;function
  4868. initialize(){$this->used=FALSE;}function
  4869. finalize(){if($this->used){return
  4870. array('Nette\Latte\Macros\CacheMacro::initRuntime($template, $_g);');}}function
  4871. nodeOpened(Latte\MacroNode$node){$this->used=TRUE;$node->isEmpty=FALSE;$node->openingCode=Latte\PhpWriter::using($node)->write('<?php if (Nette\Latte\Macros\CacheMacro::createCache($netteCacheStorage, %var, $_g->caches, %node.array?)) { ?>',Nette\Utils\Strings::random());}function
  4872. nodeClosed(Latte\MacroNode$node){$node->closingCode='<?php $_l->tmp = array_pop($_g->caches); if (!$_l->tmp instanceof stdClass) $_l->tmp->end(); } ?>';}static
  4873. function
  4874. initRuntime(Nette\Templating\FileTemplate$template,\stdClass$global){if(!empty($global->caches)){end($global->caches)->dependencies[Nette\Caching\Cache::FILES][]=$template->getFile();}}static
  4875. function
  4876. createCache(Nette\Caching\IStorage$cacheStorage,$key,&$parents,array$args=NULL){if($args){if(array_key_exists('if',$args)&&!$args['if']){return$parents[]=new\stdClass;}$key=array_merge(array($key),array_intersect_key($args,range(0,count($args))));}if($parents){end($parents)->dependencies[Nette\Caching\Cache::ITEMS][]=$key;}$cache=new
  4877. Nette\Caching\Cache($cacheStorage,'Nette.Templating.Cache');if($helper=$cache->start($key)){if(isset($args['expire'])){$args['expiration']=$args['expire'];}$helper->dependencies=array(Nette\Caching\Cache::TAGS=>isset($args['tags'])?$args['tags']:NULL,Nette\Caching\Cache::EXPIRATION=>isset($args['expiration'])?$args['expiration']:'+ 7 days');$parents[]=$helper;}return$helper;}}use
  4878. Nette\Latte\MacroNode;class
  4879. MacroSet
  4880. extends
  4881. Nette\Object
  4882. implements
  4883. Latte\IMacro{private$compiler;private$macros;function
  4884. __construct(Latte\Compiler$compiler){$this->compiler=$compiler;}function
  4885. addMacro($name,$begin,$end=NULL,$attr=NULL){$this->macros[$name]=array($begin,$end,$attr);$this->compiler->addMacro($name,$this);return$this;}static
  4886. function
  4887. install(Latte\Compiler$compiler){return
  4888. new
  4889. static($compiler);}function
  4890. initialize(){}function
  4891. finalize(){}function
  4892. nodeOpened(MacroNode$node){if($this->macros[$node->name][2]&&$node->htmlNode){$node->isEmpty=TRUE;$this->compiler->setContext(Latte\Compiler::CONTEXT_DOUBLE_QUOTED);$res=$this->compile($node,$this->macros[$node->name][2]);$this->compiler->setContext(NULL);if(!$node->attrCode){$node->attrCode="<?php $res ?>";}}else{$node->isEmpty=!isset($this->macros[$node->name][1]);$res=$this->compile($node,$this->macros[$node->name][0]);if(!$node->openingCode){$node->openingCode="<?php $res ?>";}}return$res!==FALSE;}function
  4893. nodeClosed(MacroNode$node){$res=$this->compile($node,$this->macros[$node->name][1]);if(!$node->closingCode){$node->closingCode="<?php $res ?>";}}private
  4894. function
  4895. compile(MacroNode$node,$def){$node->tokenizer->reset();$writer=Latte\PhpWriter::using($node,$this->compiler);if(is_string($def)){return$writer->write($def);}else{return
  4896. Nette\Callback::create($def)->invoke($node,$writer);}}function
  4897. getCompiler(){return$this->compiler;}}use
  4898. Nette\Latte\CompileException;use
  4899. Nette\Latte\PhpWriter;class
  4900. CoreMacros
  4901. extends
  4902. MacroSet{static
  4903. function
  4904. install(Latte\Compiler$compiler){$me=new
  4905. static($compiler);$me->addMacro('if',array($me,'macroIf'),array($me,'macroEndIf'));$me->addMacro('elseif','elseif (%node.args):');$me->addMacro('else',array($me,'macroElse'));$me->addMacro('ifset','if (isset(%node.args)):','endif');$me->addMacro('elseifset','elseif (isset(%node.args)):');$me->addMacro('foreach','',array($me,'macroEndForeach'));$me->addMacro('for','for (%node.args):','endfor');$me->addMacro('while','while (%node.args):','endwhile');$me->addMacro('continueIf','if (%node.args) continue');$me->addMacro('breakIf','if (%node.args) break');$me->addMacro('first','if ($iterator->isFirst(%node.args)):','endif');$me->addMacro('last','if ($iterator->isLast(%node.args)):','endif');$me->addMacro('sep','if (!$iterator->isLast(%node.args)):','endif');$me->addMacro('var',array($me,'macroVar'));$me->addMacro('assign',array($me,'macroVar'));$me->addMacro('default',array($me,'macroVar'));$me->addMacro('dump',array($me,'macroDump'));$me->addMacro('debugbreak',array($me,'macroDebugbreak'));$me->addMacro('l','?>{<?php');$me->addMacro('r','?>}<?php');$me->addMacro('_',array($me,'macroTranslate'),array($me,'macroTranslate'));$me->addMacro('=',array($me,'macroExpr'));$me->addMacro('?',array($me,'macroExpr'));$me->addMacro('capture',array($me,'macroCapture'),array($me,'macroCaptureEnd'));$me->addMacro('include',array($me,'macroInclude'));$me->addMacro('use',array($me,'macroUse'));$me->addMacro('class',NULL,NULL,array($me,'macroClass'));$me->addMacro('attr',array($me,'macroOldAttr'),'',array($me,'macroAttr'));$me->addMacro('href',NULL);}function
  4906. finalize(){return
  4907. array('list($_l, $_g) = Nette\Latte\Macros\CoreMacros::initRuntime($template, '.var_export($this->getCompiler()->getTemplateId(),TRUE).')');}function
  4908. macroIf(MacroNode$node,PhpWriter$writer){if($node->data->capture=($node->args==='')){return'ob_start()';}if($node->prefix===$node::PREFIX_TAG){return$writer->write($node->htmlNode->closing?'if (array_pop($_l->ifs)):':'if ($_l->ifs[] = (%node.args)):');}return$writer->write('if (%node.args):');}function
  4909. macroEndIf(MacroNode$node,PhpWriter$writer){if($node->data->capture){if($node->args===''){throw
  4910. new
  4911. CompileException('Missing condition in {if} macro.');}return$writer->write('if (%node.args) '.(isset($node->data->else)?'{ ob_end_clean(); ob_end_flush(); }':'ob_end_flush();').' else '.(isset($node->data->else)?'{ $_else = ob_get_contents(); ob_end_clean(); ob_end_clean(); echo $_else; }':'ob_end_clean();'));}return'endif';}function
  4912. macroElse(MacroNode$node,PhpWriter$writer){$ifNode=$node->parentNode;if($ifNode&&$ifNode->name==='if'&&$ifNode->data->capture){if(isset($ifNode->data->else)){throw
  4913. new
  4914. CompileException("Macro {if} supports only one {else}.");}$ifNode->data->else=TRUE;return'ob_start()';}return'else:';}function
  4915. macroTranslate(MacroNode$node,PhpWriter$writer){if($node->closing){return$writer->write('echo %modify($template->translate(ob_get_clean()))');}elseif($node->isEmpty=($node->args!=='')){return$writer->write('echo %modify($template->translate(%node.args))');}else{return'ob_start()';}}function
  4916. macroInclude(MacroNode$node,PhpWriter$writer){$code=$writer->write('Nette\Latte\Macros\CoreMacros::includeTemplate(%node.word, %node.array? + $template->getParameters(), $_l->templates[%var])',$this->getCompiler()->getTemplateId());if($node->modifiers){return$writer->write('echo %modify(%raw->__toString(TRUE))',$code);}else{return$code.'->render()';}}function
  4917. macroUse(MacroNode$node,PhpWriter$writer){Nette\Callback::create($node->tokenizer->fetchWord(),'install')->invoke($this->getCompiler())->initialize();}function
  4918. macroCapture(MacroNode$node,PhpWriter$writer){$variable=$node->tokenizer->fetchWord();if(substr($variable,0,1)!=='$'){throw
  4919. new
  4920. CompileException("Invalid capture block variable '$variable'");}$node->data->variable=$variable;return'ob_start()';}function
  4921. macroCaptureEnd(MacroNode$node,PhpWriter$writer){return$node->data->variable.$writer->write(" = %modify(ob_get_clean())");}function
  4922. macroEndForeach(MacroNode$node,PhpWriter$writer){if(preg_match('#\W(\$iterator|include|require|get_defined_vars)\W#',$this->getCompiler()->expandTokens($node->content))){$node->openingCode='<?php $iterations = 0; foreach ($iterator = $_l->its[] = new Nette\Iterators\CachingIterator('.preg_replace('#(.*)\s+as\s+#i','$1) as ',$writer->formatArgs(),1).'): ?>';$node->closingCode='<?php $iterations++; endforeach; array_pop($_l->its); $iterator = end($_l->its) ?>';}else{$node->openingCode='<?php $iterations = 0; foreach ('.$writer->formatArgs().'): ?>';$node->closingCode='<?php $iterations++; endforeach ?>';}}function
  4923. macroClass(MacroNode$node,PhpWriter$writer){return$writer->write('if ($_l->tmp = array_filter(%node.array)) echo \' class="\' . %escape(implode(" ", array_unique($_l->tmp))) . \'"\'');}function
  4924. macroAttr(MacroNode$node,PhpWriter$writer){return$writer->write('echo Nette\Utils\Html::el(NULL, %node.array)->attributes()');}function
  4925. macroOldAttr(MacroNode$node){return
  4926. Nette\Utils\Strings::replace($node->args.' ','#\)\s+#',')->');}function
  4927. macroDump(MacroNode$node,PhpWriter$writer){$args=$writer->formatArgs();return'Nette\Diagnostics\Debugger::barDump('.($node->args?"array(".$writer->write('%var',$args)." => $args)":'get_defined_vars()').', "Template " . str_replace(dirname(dirname($template->getFile())), "\xE2\x80\xA6", $template->getFile()))';}function
  4928. macroDebugbreak(MacroNode$node,PhpWriter$writer){return$writer->write(($node->args==NULL?'':'if (!(%node.args)); else').'if (function_exists("debugbreak")) debugbreak(); elseif (function_exists("xdebug_break")) xdebug_break()');}function
  4929. macroVar(MacroNode$node,PhpWriter$writer){$out='';$var=TRUE;$tokenizer=$writer->preprocess();while($token=$tokenizer->fetchToken()){if($var&&($token['type']===Latte\MacroTokenizer::T_SYMBOL||$token['type']===Latte\MacroTokenizer::T_VARIABLE)){if($node->name==='default'){$out.="'".ltrim($token['value'],"$")."'";}else{$out.='$'.ltrim($token['value'],"$");}$var=NULL;}elseif(($token['value']==='='||$token['value']==='=>')&&$token['depth']===0){$out.=$node->name==='default'?'=>':'=';$var=FALSE;}elseif($token['value']===','&&$token['depth']===0){$out.=$node->name==='default'?',':';';$var=TRUE;}elseif($var===NULL&&$node->name==='default'&&$token['type']!==Latte\MacroTokenizer::T_WHITESPACE){throw
  4930. new
  4931. CompileException("Unexpected '$token[value]' in {default $node->args}");}else{$out.=$writer->canQuote($tokenizer)?"'$token[value]'":$token['value'];}}return$node->name==='default'?"extract(array($out), EXTR_SKIP)":$out;}function
  4932. macroExpr(MacroNode$node,PhpWriter$writer){return$writer->write(($node->name==='?'?'':'echo ').'%modify(%node.args)');}static
  4933. function
  4934. includeTemplate($destination,array$params,Nette\Templating\ITemplate$template){if($destination
  4935. instanceof
  4936. Nette\Templating\ITemplate){$tpl=$destination;}elseif($destination==NULL){throw
  4937. new
  4938. Nette\InvalidArgumentException("Template file name was not specified.");}elseif($template
  4939. instanceof
  4940. Nette\Templating\IFileTemplate){if(substr($destination,0,1)!=='/'&&substr($destination,1,1)!==':'){$destination=dirname($template->getFile()).'/'.$destination;}$tpl=clone$template;$tpl->setFile($destination);}else{throw
  4941. new
  4942. Nette\NotSupportedException('Macro {include "filename"} is supported only with Nette\Templating\IFileTemplate.');}$tpl->setParameters($params);return$tpl;}static
  4943. function
  4944. initRuntime(Nette\Templating\ITemplate$template,$templateId){if(isset($template->_l)){$local=$template->_l;unset($template->_l);}else{$local=new\stdClass;}$local->templates[$templateId]=$template;if(!isset($template->_g)){$template->_g=new\stdClass;}return
  4945. array($local,$template->_g);}}use
  4946. Nette\Forms\Form;use
  4947. Nette\Utils\Strings;class
  4948. FormMacros
  4949. extends
  4950. MacroSet{static
  4951. function
  4952. install(Latte\Compiler$compiler){$me=new
  4953. static($compiler);$me->addMacro('form','Nette\Latte\Macros\FormMacros::renderFormBegin($form = $_form = (is_object(%node.word) ? %node.word : $_control[%node.word]), %node.array)','Nette\Latte\Macros\FormMacros::renderFormEnd($_form)');$me->addMacro('label',array($me,'macroLabel'),'?></label><?php');$me->addMacro('input','$_input = (is_object(%node.word) ? %node.word : $_form[%node.word]); echo $_input->getControl()->addAttributes(%node.array)',NULL,array($me,'macroAttrInput'));$me->addMacro('formContainer','$_formStack[] = $_form; $formContainer = $_form = (is_object(%node.word) ? %node.word : $_form[%node.word])','$_form = array_pop($_formStack)');}function
  4954. macroLabel(MacroNode$node,PhpWriter$writer){$cmd='$_input = is_object(%node.word) ? %node.word : $_form[%node.word]; if ($_label = $_input->getLabel()) echo $_label->addAttributes(%node.array)';if($node->isEmpty=(substr($node->args,-1)==='/')){$node->setArgs(substr($node->args,0,-1));return$writer->write($cmd);}else{return$writer->write($cmd.'->startTag()');}}function
  4955. macroAttrInput(MacroNode$node,PhpWriter$writer){if($node->htmlNode->attrs){$reset=array_fill_keys(array_keys($node->htmlNode->attrs),NULL);return$writer->write('$_input = (is_object(%node.word) ? %node.word : $_form[%node.word]); echo $_input->getControl()->addAttributes(%var)->attributes()',$reset);}return$writer->write('$_input = (is_object(%node.word) ? %node.word : $_form[%node.word]); echo $_input->getControl()->attributes()');}static
  4956. function
  4957. renderFormBegin(Form$form,array$attrs){$el=$form->getElementPrototype();$el->action=$action=(string)$el->action;$el=clone$el;if(strcasecmp($form->getMethod(),'get')===0){list($el->action)=explode('?',$action,2);if(($i=strpos($action,'#'))!==FALSE){$el->action.=substr($action,$i);}}echo$el->addAttributes($attrs)->startTag();}static
  4958. function
  4959. renderFormEnd(Form$form){$s='';if(strcasecmp($form->getMethod(),'get')===0){$url=explode('?',$form->getElementPrototype()->action,2);if(isset($url[1])){list($url[1])=explode('#',$url[1],2);foreach(preg_split('#[;&]#',$url[1])as$param){$parts=explode('=',$param,2);$name=urldecode($parts[0]);if(!isset($form[$name])){$s.=Nette\Utils\Html::el('input',array('type'=>'hidden','name'=>$name,'value'=>urldecode($parts[1])));}}}}foreach($form->getComponents(TRUE,'Nette\Forms\Controls\HiddenField')as$control){if(!$control->getOption('rendered')){$s.=$control->getControl();}}if(iterator_count($form->getComponents(TRUE,'Nette\Forms\Controls\TextInput'))<2){$s.='<!--[if IE]><input type=IEbug disabled style="display:none"><![endif]-->';}echo($s?"<div>$s</div>\n":'').$form->getElementPrototype()->endTag()."\n";}}class
  4960. UIMacros
  4961. extends
  4962. MacroSet{private$namedBlocks=array();private$extends;static
  4963. function
  4964. install(Latte\Compiler$compiler){$me=new
  4965. static($compiler);$me->addMacro('include',array($me,'macroInclude'));$me->addMacro('includeblock',array($me,'macroIncludeBlock'));$me->addMacro('extends',array($me,'macroExtends'));$me->addMacro('layout',array($me,'macroExtends'));$me->addMacro('block',array($me,'macroBlock'),array($me,'macroBlockEnd'));$me->addMacro('define',array($me,'macroBlock'),array($me,'macroBlockEnd'));$me->addMacro('snippet',array($me,'macroBlock'),array($me,'macroBlockEnd'));$me->addMacro('ifset',array($me,'macroIfset'),'endif');$me->addMacro('widget',array($me,'macroControl'));$me->addMacro('control',array($me,'macroControl'));$me->addMacro('href',NULL,NULL,function(MacroNode$node,PhpWriter$writer)use($me){return' ?> href="<?php '.$me->macroLink($node,$writer).' ?>"<?php ';});$me->addMacro('plink',array($me,'macroLink'));$me->addMacro('link',array($me,'macroLink'));$me->addMacro('ifCurrent',array($me,'macroIfCurrent'),'endif');$me->addMacro('contentType',array($me,'macroContentType'));$me->addMacro('status',array($me,'macroStatus'));}function
  4966. initialize(){$this->namedBlocks=array();$this->extends=NULL;}function
  4967. finalize(){try{$this->getCompiler()->writeMacro('/block');}catch(CompileException$e){}$epilog=$prolog=array();if($this->namedBlocks){foreach($this->namedBlocks
  4968. as$name=>$code){$func='_lb'.substr(md5($this->getCompiler()->getTemplateId().$name),0,10).'_'.preg_replace('#[^a-z0-9_]#i','_',$name);$snippet=$name[0]==='_';$prolog[]="//\n// block $name\n//\n"."if (!function_exists(\$_l->blocks[".var_export($name,TRUE)."][] = '$func')) { "."function $func(\$_l, \$_args) { ".(PHP_VERSION_ID>50208?'extract($_args)':'foreach ($_args as $__k => $__v) $$__k = $__v').($snippet?'; $_control->validateControl('.var_export(substr($name,1),TRUE).')':'')."\n?>$code<?php\n}}";}$prolog[]="//\n// end of blocks\n//";}if($this->namedBlocks||$this->extends){$prolog[]="// template extending and snippets support";$prolog[]='$_l->extends = '.($this->extends?$this->extends:'empty($template->_extended) && isset($_control) && $_control instanceof Nette\Application\UI\Presenter ? $_control->findLayoutTemplateFile() : NULL').'; $template->_extended = $_extended = TRUE;';$prolog[]='
  4969. if ($_l->extends) {
  4970. '.($this->namedBlocks?'ob_start();':'return Nette\Latte\Macros\CoreMacros::includeTemplate($_l->extends, get_defined_vars(), $template)->render();').'
  4971. } elseif (!empty($_control->snippetMode)) {
  4972. return Nette\Latte\Macros\UIMacros::renderSnippets($_control, $_l, get_defined_vars());
  4973. }';}else{$prolog[]='
  4974. // snippets support
  4975. if (!empty($_control->snippetMode)) {
  4976. return Nette\Latte\Macros\UIMacros::renderSnippets($_control, $_l, get_defined_vars());
  4977. }';}return
  4978. array(implode("\n\n",$prolog),implode("\n",$epilog));}function
  4979. macroInclude(MacroNode$node,PhpWriter$writer){$destination=$node->tokenizer->fetchWord();if(substr($destination,0,1)!=='#'){return
  4980. FALSE;}$destination=ltrim($destination,'#');$parent=$destination==='parent';if($destination==='parent'||$destination==='this'){for($item=$node->parentNode;$item&&$item->name!=='block'&&!isset($item->data->name);$item=$item->parentNode);if(!$item){throw
  4981. new
  4982. CompileException("Cannot include $destination block outside of any block.");}$destination=$item->data->name;}$name=Strings::contains($destination,'$')?$destination:var_export($destination,TRUE);if(isset($this->namedBlocks[$destination])&&!$parent){$cmd="call_user_func(reset(\$_l->blocks[$name]), \$_l, %node.array? + get_defined_vars())";}else{$cmd='Nette\Latte\Macros\UIMacros::callBlock'.($parent?'Parent':'')."(\$_l, $name, %node.array? + ".($parent?'get_defined_vars':'$template->getParameters').'())';}if($node->modifiers){return$writer->write("ob_start(); $cmd; echo %modify(ob_get_clean())");}else{return$writer->write($cmd);}}function
  4983. macroIncludeBlock(MacroNode$node,PhpWriter$writer){return$writer->write('Nette\Latte\Macros\CoreMacros::includeTemplate(%node.word, %node.array? + get_defined_vars(), $_l->templates[%var])->render()',$this->getCompiler()->getTemplateId());}function
  4984. macroExtends(MacroNode$node,PhpWriter$writer){if(!$node->args){throw
  4985. new
  4986. CompileException("Missing destination in {extends}");}if(!empty($node->parentNode)){throw
  4987. new
  4988. CompileException("{extends} must be placed outside any macro.");}if($this->extends!==NULL){throw
  4989. new
  4990. CompileException("Multiple {extends} declarations are not allowed.");}if($node->args==='none'){$this->extends='FALSE';}elseif($node->args==='auto'){$this->extends='$_presenter->findLayoutTemplateFile()';}else{$this->extends=$writer->write('%node.word%node.args');}return;}function
  4991. macroBlock(MacroNode$node,PhpWriter$writer){$name=$node->tokenizer->fetchWord();if($node->name==='block'&&$name===FALSE){return$node->modifiers===''?'':'ob_start()';}$node->data->name=$name=ltrim($name,'#');if($name==NULL){if($node->name!=='snippet'){throw
  4992. new
  4993. CompileException("Missing block name.");}}elseif(Strings::contains($name,'$')){if($node->name==='snippet'){for($parent=$node->parentNode;$parent&&$parent->name!=='snippet';$parent=$parent->parentNode);if(!$parent){throw
  4994. new
  4995. CompileException("Dynamic snippets are allowed only inside static snippet.");}$parent->data->dynamic=TRUE;$node->data->leave=TRUE;$node->closingCode="<?php \$_dynSnippets[\$_dynSnippetId] = ob_get_flush() ?>";if($node->htmlNode){$node->attrCode=$writer->write("<?php echo ' id=\"' . (\$_dynSnippetId = \$_control->getSnippetId({$writer->formatWord($name)})) . '\"' ?>");return$writer->write('ob_start()');}$tag=trim($node->tokenizer->fetchWord(),'<>');$tag=$tag?$tag:'div';$node->closingCode.="\n</$tag>";return$writer->write("?>\n<$tag id=\"<?php echo \$_dynSnippetId = \$_control->getSnippetId({$writer->formatWord($name)}) ?>\"><?php ob_start()");}else{$node->data->leave=TRUE;$fname=$writer->formatWord($name);$node->closingCode="<?php }} ".($node->name==='define'?'':"call_user_func(reset(\$_l->blocks[$fname]), \$_l, get_defined_vars())")." ?>";$func='_lb'.substr(md5($this->getCompiler()->getTemplateId().$name),0,10).'_'.preg_replace('#[^a-z0-9_]#i','_',$name);return"\n\n//\n// block $name\n//\n"."if (!function_exists(\$_l->blocks[$fname]['{$this->getCompiler()->getTemplateId()}'] = '$func')) { "."function $func(\$_l, \$_args) { ".(PHP_VERSION_ID>50208?'extract($_args)':'foreach ($_args as $__k => $__v) $$__k = $__v');}}if($node->name==='snippet'){$node->data->name=$name='_'.$name;}if(isset($this->namedBlocks[$name])){throw
  4996. new
  4997. CompileException("Cannot redeclare static block '$name'");}$prolog=$this->namedBlocks?'':"if (\$_l->extends) { ob_end_clean(); return Nette\\Latte\\Macros\\CoreMacros::includeTemplate(\$_l->extends, get_defined_vars(), \$template)->render(); }\n";$top=empty($node->parentNode);$this->namedBlocks[$name]=TRUE;$include='call_user_func(reset($_l->blocks[%var]), $_l, '.($node->name==='snippet'?'$template->getParameters()':'get_defined_vars()').')';if($node->modifiers){$include="ob_start(); $include; echo %modify(ob_get_clean())";}if($node->name==='snippet'){if($node->htmlNode){$node->attrCode=$writer->write('<?php echo \' id="\' . $_control->getSnippetId(%var) . \'"\' ?>',(string)substr($name,1));return$writer->write($prolog.$include,$name);}$tag=trim($node->tokenizer->fetchWord(),'<>');$tag=$tag?$tag:'div';return$writer->write("$prolog ?>\n<$tag id=\"<?php echo \$_control->getSnippetId(%var) ?>\"><?php $include ?>\n</$tag><?php ",(string)substr($name,1),$name);}elseif($node->name==='define'){return$prolog;}else{return$writer->write($prolog.$include,$name);}}function
  4998. macroBlockEnd(MacroNode$node,PhpWriter$writer){if(isset($node->data->name)){if($node->name==='snippet'&&$node->htmlNode&&!$node->prefix&&preg_match('#^.*? n:\w+>\n?#s',$node->content,$m1)&&preg_match('#[ \t]*<[^<]+\z#s',$node->content,$m2)){$node->openingCode=$m1[0].$node->openingCode;$node->content=substr($node->content,strlen($m1[0]),-strlen($m2[0]));$node->closingCode.=$m2[0];}if(empty($node->data->leave)){if(!empty($node->data->dynamic)){$node->content.='<?php if (isset($_dynSnippets)) return $_dynSnippets; ?>';}$this->namedBlocks[$node->data->name]=$tmp=rtrim(ltrim($node->content,"\n")," \t");$node->content=substr_replace($node->content,$node->openingCode."\n",strspn($node->content,"\n"),strlen($tmp));$node->openingCode="<?php ?>";}}elseif($node->modifiers){return$writer->write('echo %modify(ob_get_clean())');}}function
  4999. macroIfset(MacroNode$node,PhpWriter$writer){if(!Strings::contains($node->args,'#')){return
  5000. FALSE;}$list=array();while(($name=$node->tokenizer->fetchWord())!==FALSE){$list[]=$name[0]==='#'?'$_l->blocks["'.substr($name,1).'"]':$name;}return'if (isset('.implode(', ',$list).')):';}function
  5001. macroControl(MacroNode$node,PhpWriter$writer){$pair=$node->tokenizer->fetchWord();if($pair===FALSE){throw
  5002. new
  5003. CompileException("Missing control name in {control}");}$pair=explode(':',$pair,2);$name=$writer->formatWord($pair[0]);$method=isset($pair[1])?ucfirst($pair[1]):'';$method=Strings::match($method,'#^\w*\z#')?"render$method":"{\"render$method\"}";$param=$writer->formatArray();if(!Strings::contains($node->args,'=>')){$param=substr($param,6,-1);}return($name[0]==='$'?"if (is_object($name)) \$_ctrl = $name; else ":'').'$_ctrl = $_control->getComponent('.$name.'); '.'if ($_ctrl instanceof Nette\Application\UI\IRenderable) $_ctrl->validateControl(); '."\$_ctrl->$method($param)";}function
  5004. macroLink(MacroNode$node,PhpWriter$writer){return$writer->write('echo %escape(%modify('.($node->name==='plink'?'$_presenter':'$_control').'->link(%node.word, %node.array?)))');}function
  5005. macroIfCurrent(MacroNode$node,PhpWriter$writer){return$writer->write(($node->args?'try { $_presenter->link(%node.word, %node.array?); } catch (Nette\Application\UI\InvalidLinkException $e) {}':'').'; if ($_presenter->getLastCreatedRequestFlag("current")):');}function
  5006. macroContentType(MacroNode$node,PhpWriter$writer){if(Strings::contains($node->args,'xhtml')){$this->getCompiler()->setContentType(Latte\Compiler::CONTENT_XHTML);}elseif(Strings::contains($node->args,'html')){$this->getCompiler()->setContentType(Latte\Compiler::CONTENT_HTML);}elseif(Strings::contains($node->args,'xml')){$this->getCompiler()->setContentType(Latte\Compiler::CONTENT_XML);}elseif(Strings::contains($node->args,'javascript')){$this->getCompiler()->setContentType(Latte\Compiler::CONTENT_JS);}elseif(Strings::contains($node->args,'css')){$this->getCompiler()->setContentType(Latte\Compiler::CONTENT_CSS);}elseif(Strings::contains($node->args,'calendar')){$this->getCompiler()->setContentType(Latte\Compiler::CONTENT_ICAL);}else{$this->getCompiler()->setContentType(Latte\Compiler::CONTENT_TEXT);}if(Strings::contains($node->args,'/')){return$writer->write('$netteHttpResponse->setHeader("Content-Type", %var)',$node->args);}}function
  5007. macroStatus(MacroNode$node,PhpWriter$writer){return$writer->write((substr($node->args,-1)==='?'?'if (!$netteHttpResponse->isSent()) ':'').'$netteHttpResponse->setCode(%var)',(int)$node->args);}static
  5008. function
  5009. callBlock(\stdClass$context,$name,array$params){if(empty($context->blocks[$name])){throw
  5010. new
  5011. Nette\InvalidStateException("Cannot include undefined block '$name'.");}$block=reset($context->blocks[$name]);$block($context,$params);}static
  5012. function
  5013. callBlockParent(\stdClass$context,$name,array$params){if(empty($context->blocks[$name])||($block=next($context->blocks[$name]))===FALSE){throw
  5014. new
  5015. Nette\InvalidStateException("Cannot include undefined parent block '$name'.");}$block($context,$params);}static
  5016. function
  5017. renderSnippets(Nette\Application\UI\Control$control,\stdClass$local,array$params){$control->snippetMode=FALSE;$payload=$control->getPresenter()->getPayload();if(isset($local->blocks)){foreach($local->blocks
  5018. as$name=>$function){if($name[0]!=='_'||!$control->isControlInvalid(substr($name,1))){continue;}ob_start();$function=reset($function);$snippets=$function($local,$params);$payload->snippets[$id=$control->getSnippetId(substr($name,1))]=ob_get_clean();if($snippets){$payload->snippets+=$snippets;unset($payload->snippets[$id]);}}}$control->snippetMode=TRUE;if($control
  5019. instanceof
  5020. Nette\Application\UI\IRenderable){$queue=array($control);do{foreach(array_shift($queue)->getComponents()as$child){if($child
  5021. instanceof
  5022. Nette\Application\UI\IRenderable){if($child->isControlInvalid()){$child->snippetMode=TRUE;$child->render();$child->snippetMode=FALSE;}}elseif($child
  5023. instanceof
  5024. Nette\ComponentModel\IContainer){$queue[]=$child;}}}while($queue);}}}}namespace Nette\Utils{use
  5025. Nette;class
  5026. Tokenizer
  5027. extends
  5028. Nette\Object{public$tokens;public$position=0;public$ignored=array();private$input;private$re;private$types;public$current;function
  5029. __construct(array$patterns,$flags=''){$this->re='~('.implode(')|(',$patterns).')~A'.$flags;$keys=array_keys($patterns);$this->types=$keys===range(0,count($patterns)-1)?FALSE:$keys;}function
  5030. tokenize($input){$this->input=$input;if($this->types){$this->tokens=Strings::matchAll($input,$this->re);$len=0;$count=count($this->types);$line=1;foreach($this->tokens
  5031. as&$match){$type=NULL;for($i=1;$i<=$count;$i++){if(!isset($match[$i])){break;}elseif($match[$i]!=NULL){$type=$this->types[$i-1];break;}}$match=self::createToken($match[0],$type,$line);$len+=strlen($match['value']);$line+=substr_count($match['value'],"\n");}if($len!==strlen($input)){$errorOffset=$len;}}else{$this->tokens=Strings::split($input,$this->re,PREG_SPLIT_NO_EMPTY);if($this->tokens&&!Strings::match(end($this->tokens),$this->re)){$tmp=Strings::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
  5032. new
  5033. TokenizerException("Unexpected '$token' on line $line, column $col.");}return$this->tokens;}static
  5034. function
  5035. createToken($value,$type=NULL,$line=NULL){return
  5036. array('value'=>$value,'type'=>$type,'line'=>$line);}function
  5037. getOffset($i){$tokens=Strings::split($this->input,$this->re,PREG_SPLIT_NO_EMPTY|PREG_SPLIT_OFFSET_CAPTURE);$offset=isset($tokens[$i])?$tokens[$i][1]:strlen($this->input);return
  5038. array($offset,($offset?substr_count($this->input,"\n",0,$offset)+1:1),$offset-strrpos(substr($this->input,0,$offset),"\n"));}function
  5039. fetch(){$args=func_get_args();return$this->scan($args,TRUE);}function
  5040. fetchToken(){$args=func_get_args();return$this->scan($args,TRUE)===FALSE?FALSE:$this->current;}function
  5041. fetchAll(){$args=func_get_args();return$this->scan($args,FALSE);}function
  5042. fetchUntil($arg){$args=func_get_args();return$this->scan($args,FALSE,TRUE,TRUE);}function
  5043. isNext($arg){$args=func_get_args();return(bool)$this->scan($args,TRUE,FALSE);}function
  5044. isPrev($arg){$args=func_get_args();return(bool)$this->scan($args,TRUE,FALSE,FALSE,TRUE);}function
  5045. hasNext(){return
  5046. isset($this->tokens[$this->position]);}function
  5047. hasPrev(){return$this->position>1;}function
  5048. isCurrent($arg){$args=func_get_args();if(is_array($this->current)){return
  5049. in_array($this->current['value'],$args,TRUE)||in_array($this->current['type'],$args,TRUE);}else{return
  5050. in_array($this->current,$args,TRUE);}}function
  5051. reset(){$this->position=0;$this->current=NULL;}private
  5052. function
  5053. scan($wanted,$first,$advance=TRUE,$neg=FALSE,$prev=FALSE){$res=FALSE;$pos=$this->position+($prev?-2:0);while(isset($this->tokens[$pos])){$token=$this->tokens[$pos];$pos+=$prev?-1:1;$value=is_array($token)?$token['value']:$token;$type=is_array($token)?$token['type']:$token;if(!$wanted||(in_array($value,$wanted,TRUE)||in_array($type,$wanted,TRUE))^$neg){if($advance){$this->position=$pos;$this->current=$token;}$res.=$value;if($first){break;}}elseif($neg||!in_array($type,$this->ignored,TRUE)){break;}}return$res;}}class
  5054. TokenizerException
  5055. extends\Exception{}}namespace Nette\Latte{use
  5056. Nette;class
  5057. MacroTokenizer
  5058. extends
  5059. Nette\Utils\Tokenizer{const
  5060. T_WHITESPACE=1,T_COMMENT=2,T_SYMBOL=3,T_NUMBER=4,T_VARIABLE=5,T_STRING=6,T_CAST=7,T_KEYWORD=8,T_CHAR=9;function
  5061. __construct($input){parent::__construct(array(self::T_WHITESPACE=>'\s+',self::T_COMMENT=>'(?s)/\*.*?\*/',self::T_STRING=>Parser::RE_STRING,self::T_KEYWORD=>'(?:true|false|null|and|or|xor|clone|new|instanceof|return|continue|break|[A-Z_][A-Z0-9_]{2,})(?![\w\pL_])',self::T_CAST=>'\((?:expand|string|array|int|integer|float|bool|boolean|object)\)',self::T_VARIABLE=>'\$[\w\pL_]+',self::T_NUMBER=>'[+-]?[0-9]+(?:\.[0-9]+)?(?:e[0-9]+)?',self::T_SYMBOL=>'[\w\pL_]+(?:-[\w\pL_]+)*',self::T_CHAR=>'::|=>|[^"\']'),'u');$this->ignored=array(self::T_COMMENT,self::T_WHITESPACE);$this->tokenize($input);}function
  5062. fetchWord(){$word=$this->fetchUntil(self::T_WHITESPACE,',');$this->fetch(',');$this->fetchAll(self::T_WHITESPACE,self::T_COMMENT);return$word;}}use
  5063. Nette\Utils\Strings;class
  5064. Parser
  5065. extends
  5066. Nette\Object{const
  5067. RE_STRING='\'(?:\\\\.|[^\'\\\\])*\'|"(?:\\\\.|[^"\\\\])*"';const
  5068. N_PREFIX='n:';public$defaultSyntax='latte';public$syntaxes=array('latte'=>array('\\{(?![\\s\'"{}])','\\}'),'double'=>array('\\{\\{(?![\\s\'"{}])','\\}\\}'),'asp'=>array('<%\s*','\s*%>'),'python'=>array('\\{[{%]\s*','\s*[%}]\\}'),'off'=>array('[^\x00-\xFF]',''));private$macroRe;private$input;private$output;private$offset;private$context;private$lastHtmlTag;private$syntaxEndTag;private$xmlMode;const
  5069. CONTEXT_TEXT='text',CONTEXT_CDATA='cdata',CONTEXT_TAG='tag',CONTEXT_ATTRIBUTE='attribute',CONTEXT_NONE='none',CONTEXT_COMMENT='comment';function
  5070. parse($input){if(substr($input,0,3)==="\xEF\xBB\xBF"){$input=substr($input,3);}if(!Strings::checkEncoding($input)){throw
  5071. new
  5072. Nette\InvalidArgumentException('Template is not valid UTF-8 stream.');}$input=str_replace("\r\n","\n",$input);$this->input=$input;$this->output=array();$this->offset=0;$this->setSyntax($this->defaultSyntax);$this->setContext(self::CONTEXT_TEXT);$this->lastHtmlTag=$this->syntaxEndTag=NULL;while($this->offset<strlen($input)){$matches=$this->{"context".$this->context[0]}();if(!$matches){break;}elseif(!empty($matches['comment'])){$this->addToken(Token::COMMENT,$matches[0]);}elseif(!empty($matches['macro'])){$token=$this->addToken(Token::MACRO_TAG,$matches[0]);list($token->name,$token->value,$token->modifiers)=$this->parseMacroTag($matches['macro']);}$this->filter();}if($this->offset<strlen($input)){$this->addToken(Token::TEXT,substr($this->input,$this->offset));}return$this->output;}private
  5073. function
  5074. contextText(){$matches=$this->match('~
  5075. (?:(?<=\n|^)[ \t]*)?<(?P<closing>/?)(?P<tag>[a-z0-9:]+)| ## begin of HTML tag <tag </tag - ignores <!DOCTYPE
  5076. <(?P<htmlcomment>!--)| ## begin of HTML comment <!--
  5077. '.$this->macroRe.' ## macro tag
  5078. ~xsi');if(!empty($matches['htmlcomment'])){$this->addToken(Token::HTML_TAG_BEGIN,$matches[0]);$this->setContext(self::CONTEXT_COMMENT);}elseif(!empty($matches['tag'])){$token=$this->addToken(Token::HTML_TAG_BEGIN,$matches[0]);$token->name=$matches['tag'];$token->closing=(bool)$matches['closing'];$this->lastHtmlTag=$matches['closing'].strtolower($matches['tag']);$this->setContext(self::CONTEXT_TAG);}return$matches;}private
  5079. function
  5080. contextCData(){$matches=$this->match('~
  5081. </(?P<tag>'.$this->lastHtmlTag.')(?![a-z0-9:])| ## end HTML tag </tag
  5082. '.$this->macroRe.' ## macro tag
  5083. ~xsi');if(!empty($matches['tag'])){$token=$this->addToken(Token::HTML_TAG_BEGIN,$matches[0]);$token->name=$this->lastHtmlTag;$token->closing=TRUE;$this->lastHtmlTag='/'.$this->lastHtmlTag;$this->setContext(self::CONTEXT_TAG);}return$matches;}private
  5084. function
  5085. contextTag(){$matches=$this->match('~
  5086. (?P<end>\ ?/?>)([ \t]*\n)?| ## end of HTML tag
  5087. '.$this->macroRe.'| ## macro tag
  5088. \s*(?P<attr>[^\s/>={]+)(?:\s*=\s*(?P<value>["\']|[^\s/>{]+))? ## begin of HTML attribute
  5089. ~xsi');if(!empty($matches['end'])){$this->addToken(Token::HTML_TAG_END,$matches[0]);$this->setContext(!$this->xmlMode&&in_array($this->lastHtmlTag,array('script','style'))?self::CONTEXT_CDATA:self::CONTEXT_TEXT);}elseif(isset($matches['attr'])&&$matches['attr']!==''){$token=$this->addToken(Token::HTML_ATTRIBUTE,$matches[0]);$token->name=$matches['attr'];$token->value=isset($matches['value'])?$matches['value']:'';if($token->value==='"'||$token->value==="'"){if(Strings::startsWith($token->name,self::N_PREFIX)){$token->value='';if($m=$this->match('~(.*?)'.$matches['value'].'~xsi')){$token->value=$m[1];$token->text.=$m[0];}}else{$this->setContext(self::CONTEXT_ATTRIBUTE,$matches['value']);}}}return$matches;}private
  5090. function
  5091. contextAttribute(){$matches=$this->match('~
  5092. (?P<quote>'.$this->context[1].')| ## end of HTML attribute
  5093. '.$this->macroRe.' ## macro tag
  5094. ~xsi');if(!empty($matches['quote'])){$this->addToken(Token::TEXT,$matches[0]);$this->setContext(self::CONTEXT_TAG);}return$matches;}private
  5095. function
  5096. contextComment(){$matches=$this->match('~
  5097. (?P<htmlcomment>--\s*>)| ## end of HTML comment
  5098. '.$this->macroRe.' ## macro tag
  5099. ~xsi');if(!empty($matches['htmlcomment'])){$this->addToken(Token::HTML_TAG_END,$matches[0]);$this->setContext(self::CONTEXT_TEXT);}return$matches;}private
  5100. function
  5101. contextNone(){$matches=$this->match('~
  5102. '.$this->macroRe.' ## macro tag
  5103. ~xsi');return$matches;}private
  5104. function
  5105. match($re){if($matches=Strings::match($this->input,$re,PREG_OFFSET_CAPTURE,$this->offset)){$value=substr($this->input,$this->offset,$matches[0][1]-$this->offset);if($value!==''){$this->addToken(Token::TEXT,$value);}$this->offset=$matches[0][1]+strlen($matches[0][0]);foreach($matches
  5106. as$k=>$v)$matches[$k]=$v[0];}return$matches;}function
  5107. setContext($context,$quote=NULL){$this->context=array($context,$quote);return$this;}function
  5108. setSyntax($type){$type=$type?:$this->defaultSyntax;if(isset($this->syntaxes[$type])){$this->setDelimiters($this->syntaxes[$type][0],$this->syntaxes[$type][1]);}else{throw
  5109. new
  5110. Nette\InvalidArgumentException("Unknown syntax '$type'");}return$this;}function
  5111. setDelimiters($left,$right){$this->macroRe='
  5112. (?P<comment>'.$left.'\\*.*?\\*'.$right.'\n{0,2})|
  5113. '.$left.'
  5114. (?P<macro>(?:'.self::RE_STRING.'|\{
  5115. (?P<inner>'.self::RE_STRING.'|\{(?P>inner)\}|[^\'"{}])*+
  5116. \}|[^\'"{}])+?)
  5117. '.$right.'
  5118. (?P<rmargin>[ \t]*(?=\n))?
  5119. ';return$this;}function
  5120. parseMacroTag($tag){$match=Strings::match($tag,'~^
  5121. (
  5122. (?P<name>\?|/?[a-z]\w*+(?:[.:]\w+)*+(?!::|\(|\\\\))| ## ?, name, /name, but not function( or class:: or namespace\
  5123. (?P<noescape>!?)(?P<shortname>/?[=\~#%^&_]?) ## !expression, !=expression, ...
  5124. )(?P<args>.*?)
  5125. (?P<modifiers>\|[a-z](?:'.Parser::RE_STRING.'|[^\'"])*)?
  5126. ()\z~isx');if(!$match){return
  5127. FALSE;}if($match['name']===''){$match['name']=$match['shortname']?:'=';if(!$match['noescape']&&substr($match['shortname'],0,1)!=='/'){$match['modifiers'].='|escape';}}return
  5128. array($match['name'],trim($match['args']),$match['modifiers']);}private
  5129. function
  5130. addToken($type,$text){$this->output[]=$token=new
  5131. Token;$token->type=$type;$token->text=$text;$token->line=substr_count($this->input,"\n",0,max(1,$this->offset-1))+1;return$token;}protected
  5132. function
  5133. filter(){$token=end($this->output);if($token->type===Token::MACRO_TAG&&$token->name==='/syntax'){$this->setSyntax($this->defaultSyntax);$token->type=Token::COMMENT;}elseif($token->type===Token::MACRO_TAG&&$token->name==='syntax'){$this->setSyntax($token->value);$token->type=Token::COMMENT;}elseif($token->type===Token::HTML_ATTRIBUTE&&$token->name==='n:syntax'){$this->setSyntax($token->value);$this->syntaxEndTag='/'.$this->lastHtmlTag;$token->type=Token::COMMENT;}elseif($token->type===Token::HTML_TAG_END&&$this->lastHtmlTag===$this->syntaxEndTag){$this->setSyntax($this->defaultSyntax);}elseif($token->type===Token::MACRO_TAG&&$token->name==='contentType'){if(preg_match('#html|xml#',$token->value,$m)){$this->xmlMode=$m[0]==='xml';$this->setContext(self::CONTEXT_TEXT);}else{$this->setContext(self::CONTEXT_NONE);}}}}class
  5134. PhpWriter
  5135. extends
  5136. Nette\Object{private$argsTokenizer;private$modifiers;private$compiler;static
  5137. function
  5138. using(MacroNode$node,Compiler$compiler=NULL){return
  5139. new
  5140. static($node->tokenizer,$node->modifiers,$compiler);}function
  5141. __construct(MacroTokenizer$argsTokenizer,$modifiers=NULL,Compiler$compiler=NULL){$this->argsTokenizer=$argsTokenizer;$this->modifiers=$modifiers;$this->compiler=$compiler;}function
  5142. write($mask){$args=func_get_args();array_shift($args);$word=strpos($mask,'%node.word')===FALSE?NULL:$this->argsTokenizer->fetchWord();$me=$this;$mask=Nette\Utils\Strings::replace($mask,'#%escape(\(([^()]*+|(?1))+\))#',function($m)use($me){return$me->escape(substr($m[1],1,-1));});$mask=Nette\Utils\Strings::replace($mask,'#%modify(\(([^()]*+|(?1))+\))#',function($m)use($me){return$me->formatModifiers(substr($m[1],1,-1));});return
  5143. Nette\Utils\Strings::replace($mask,'#([,+]\s*)?%(node\.word|node\.array|node\.args|var|raw)(\?)?(\s*\+\s*)?()#',function($m)use($me,$word,&$args){list(,$l,$macro,$cond,$r)=$m;switch($macro){case'node.word':$code=$me->formatWord($word);break;case'node.args':$code=$me->formatArgs();break;case'node.array':$code=$me->formatArray();$code=$cond&&$code==='array()'?'':$code;break;case'var':$code=var_export(array_shift($args),TRUE);break;case'raw':$code=(string)array_shift($args);break;}if($cond&&$code===''){return$r?$l:$r;}else{return$l.$code.$r;}});}function
  5144. formatModifiers($var){$modifiers=ltrim($this->modifiers,'|');if(!$modifiers){return$var;}$tokenizer=$this->preprocess(new
  5145. MacroTokenizer($modifiers));$inside=FALSE;while($token=$tokenizer->fetchToken()){if($token['type']===MacroTokenizer::T_WHITESPACE){$var=rtrim($var).' ';}elseif(!$inside){if($token['type']===MacroTokenizer::T_SYMBOL){if($this->compiler&&$token['value']==='escape'){$var=$this->escape($var);$tokenizer->fetch('|');}else{$var="\$template->".$token['value']."($var";$inside=TRUE;}}else{throw
  5146. new
  5147. CompileException("Modifier name must be alphanumeric string, '$token[value]' given.");}}else{if($token['value']===':'||$token['value']===','){$var=$var.', ';}elseif($token['value']==='|'){$var=$var.')';$inside=FALSE;}else{$var.=$this->canQuote($tokenizer)?"'$token[value]'":$token['value'];}}}return$inside?"$var)":$var;}function
  5148. formatArgs(){$out='';$tokenizer=$this->preprocess();while($token=$tokenizer->fetchToken()){$out.=$this->canQuote($tokenizer)?"'$token[value]'":$token['value'];}return$out;}function
  5149. formatArray(){$out='';$expand=NULL;$tokenizer=$this->preprocess();while($token=$tokenizer->fetchToken()){if($token['value']==='(expand)'&&$token['depth']===0){$expand=TRUE;$out.='),';}elseif($expand&&($token['value']===',')&&!$token['depth']){$expand=FALSE;$out.=', array(';}else{$out.=$this->canQuote($tokenizer)?"'$token[value]'":$token['value'];}}if($expand===NULL){return"array($out)";}else{return"array_merge(array($out".($expand?', array(':'')."))";}}function
  5150. formatWord($s){return(is_numeric($s)||preg_match('#^\$|[\'"]|^true\z|^false\z|^null\z#i',$s))?$s:'"'.$s.'"';}function
  5151. canQuote(MacroTokenizer$tokenizer){return$tokenizer->isCurrent(MacroTokenizer::T_SYMBOL)&&(!$tokenizer->hasPrev()||$tokenizer->isPrev(',','(','[','=','=>',':','?'))&&(!$tokenizer->hasNext()||$tokenizer->isNext(',',')',']','=','=>',':','|'));}function
  5152. preprocess(MacroTokenizer$tokenizer=NULL){$tokenizer=$tokenizer===NULL?$this->argsTokenizer:$tokenizer;$inTernary=$prev=NULL;$tokens=$arrays=array();while($token=$tokenizer->fetchToken()){$token['depth']=$depth=count($arrays);if($token['type']===MacroTokenizer::T_COMMENT){continue;}elseif($token['type']===MacroTokenizer::T_WHITESPACE){$tokens[]=$token;continue;}if($token['value']==='?'){$inTernary=$depth;}elseif($token['value']===':'){$inTernary=NULL;}elseif($inTernary===$depth&&($token['value']===','||$token['value']===')'||$token['value']===']')){$tokens[]=MacroTokenizer::createToken(':')+array('depth'=>$depth);$tokens[]=MacroTokenizer::createToken('null')+array('depth'=>$depth);$inTernary=NULL;}if($token['value']==='['){if($arrays[]=$prev['value']!==']'&&$prev['value']!==')'&&$prev['type']!==MacroTokenizer::T_SYMBOL&&$prev['type']!==MacroTokenizer::T_VARIABLE&&$prev['type']!==MacroTokenizer::T_KEYWORD){$tokens[]=MacroTokenizer::createToken('array')+array('depth'=>$depth);$token=MacroTokenizer::createToken('(');}}elseif($token['value']===']'){if(array_pop($arrays)===TRUE){$token=MacroTokenizer::createToken(')');}}elseif($token['value']==='('){$arrays[]='(';}elseif($token['value']===')'){array_pop($arrays);}$tokens[]=$prev=$token;}if($inTernary!==NULL){$tokens[]=MacroTokenizer::createToken(':')+array('depth'=>count($arrays));$tokens[]=MacroTokenizer::createToken('null')+array('depth'=>count($arrays));}$tokenizer=clone$tokenizer;$tokenizer->reset();$tokenizer->tokens=$tokens;return$tokenizer;}function
  5153. escape($s){switch($this->compiler->getContentType()){case
  5154. Compiler::CONTENT_XHTML:case
  5155. Compiler::CONTENT_HTML:$context=$this->compiler->getContext();switch($context[0]){case
  5156. Compiler::CONTEXT_SINGLE_QUOTED:case
  5157. Compiler::CONTEXT_DOUBLE_QUOTED:if($context[1]===Compiler::CONTENT_JS){$s="Nette\\Templating\\Helpers::escapeJs($s)";}elseif($context[1]===Compiler::CONTENT_CSS){$s="Nette\\Templating\\Helpers::escapeCss($s)";}$quote=$context[0]===Compiler::CONTEXT_DOUBLE_QUOTED?'':', ENT_QUOTES';return"htmlSpecialChars($s$quote)";case
  5158. Compiler::CONTEXT_COMMENT:return"Nette\\Templating\\Helpers::escapeHtmlComment($s)";case
  5159. Compiler::CONTENT_JS:case
  5160. Compiler::CONTENT_CSS:return'Nette\Templating\Helpers::escape'.ucfirst($context[0])."($s)";default:return"Nette\\Templating\\Helpers::escapeHtml($s, ENT_NOQUOTES)";}case
  5161. Compiler::CONTENT_XML:case
  5162. Compiler::CONTENT_JS:case
  5163. Compiler::CONTENT_CSS:case
  5164. Compiler::CONTENT_ICAL:return'Nette\Templating\Helpers::escape'.ucfirst($this->compiler->getContentType())."($s)";case
  5165. Compiler::CONTENT_TEXT:return$s;default:return"\$template->escape($s)";}}}class
  5166. Token
  5167. extends
  5168. Nette\Object{const
  5169. TEXT='text',MACRO_TAG='macroTag',HTML_TAG_BEGIN='htmlTagBegin',HTML_TAG_END='htmlTagEnd',HTML_ATTRIBUTE='htmlAttribute',COMMENT='comment';public$type;public$text;public$line;public$name;public$value;public$modifiers;public$closing;}}namespace Nette\Loaders{use
  5170. Nette;use
  5171. Nette\Caching\Cache;class
  5172. RobotLoader
  5173. extends
  5174. AutoLoader{const
  5175. RETRY_LIMIT=3;public$scanDirs=array();public$ignoreDirs='.*, *.old, *.bak, *.tmp, temp';public$acceptFiles='*.php, *.php5';public$autoRebuild=TRUE;private$classes=array();private$rebuilt=FALSE;private$missing=array();private$cacheStorage;function
  5176. __construct(){if(!extension_loaded('tokenizer')){throw
  5177. new
  5178. Nette\NotSupportedException("PHP extension Tokenizer is not loaded.");}}function
  5179. register(){$this->classes=$this->getCache()->load($this->getKey(),new
  5180. Nette\Callback($this,'_rebuildCallback'));parent::register();return$this;}function
  5181. tryLoad($type){$type=ltrim(strtolower($type),'\\');$info=&$this->classes[$type];if(isset($this->missing[$type])||(is_int($info)&&$info>=self::RETRY_LIMIT)){return;}if($this->autoRebuild){if(!is_array($info)||!is_file($info['file'])){$info=is_int($info)?$info+1:0;if($this->rebuilt){$this->getCache()->save($this->getKey(),$this->classes,array(Cache::CONSTS=>'Nette\Framework::REVISION'));}else{$this->rebuild();}}elseif(!$this->rebuilt&&filemtime($info['file'])!==$info['time']){$this->updateFile($info['file']);if(!isset($this->classes[$type])){$this->classes[$type]=0;}$this->getCache()->save($this->getKey(),$this->classes,array(Cache::CONSTS=>'Nette\Framework::REVISION'));}}if(isset($this->classes[$type]['file'])){Nette\Utils\LimitedScope::load($this->classes[$type]['file'],TRUE);self::$count++;}else{$this->missing[$type]=TRUE;}}function
  5182. addDirectory($path){foreach((array)$path
  5183. as$val){$real=realpath($val);if($real===FALSE){throw
  5184. new
  5185. Nette\DirectoryNotFoundException("Directory '$val' not found.");}$this->scanDirs[]=$real;}return$this;}function
  5186. getIndexedClasses(){$res=array();foreach($this->classes
  5187. as$class=>$info){if(is_array($info)){$res[$info['orig']]=$info['file'];}}return$res;}function
  5188. rebuild(){$this->rebuilt=TRUE;$this->getCache()->save($this->getKey(),new
  5189. Nette\Callback($this,'_rebuildCallback'));}function
  5190. _rebuildCallback(&$dp){$files=$missing=array();foreach($this->classes
  5191. as$class=>$info){if(is_array($info)){$files[$info['file']]['time']=$info['time'];$files[$info['file']]['classes'][]=$info['orig'];}else{$missing[$class]=$info;}}$this->classes=array();foreach(array_unique($this->scanDirs)as$dir){foreach($this->createFileIterator($dir)as$file){$file=$file->getPathname();if(isset($files[$file])&&$files[$file]['time']==filemtime($file)){$classes=$files[$file]['classes'];}else{$classes=$this->scanPhp(file_get_contents($file));}foreach($classes
  5192. as$class){$info=&$this->classes[strtolower($class)];if(isset($info['file'])){$e=new
  5193. Nette\InvalidStateException("Ambiguous class $class resolution; defined in {$info['file']} and in $file.");{throw$e;}}$info=array('file'=>$file,'time'=>filemtime($file),'orig'=>$class);}}}$dp=array(Cache::CONSTS=>'Nette\Framework::REVISION');$this->classes+=$missing;return$this->classes;}private
  5194. function
  5195. createFileIterator($dir){if(!is_dir($dir)){return
  5196. new\ArrayIterator(array(new\SplFileInfo($dir)));}$ignoreDirs=is_array($this->ignoreDirs)?$this->ignoreDirs:preg_split('#[,\s]+#',$this->ignoreDirs);$disallow=array();foreach($ignoreDirs
  5197. as$item){if($item=realpath($item)){$disallow[$item]=TRUE;}}$iterator=Nette\Utils\Finder::findFiles(is_array($this->acceptFiles)?$this->acceptFiles:preg_split('#[,\s]+#',$this->acceptFiles))->filter(function($file)use(&$disallow){return!isset($disallow[$file->getPathname()]);})->from($dir)->exclude($ignoreDirs)->filter($filter=function($dir)use(&$disallow){$path=$dir->getPathname();if(is_file("$path/netterobots.txt")){foreach(file("$path/netterobots.txt")as$s){if(preg_match('#^(?:disallow\\s*:)?\\s*(\\S+)#i',$s,$matches)){$disallow[$path.str_replace('/',DIRECTORY_SEPARATOR,rtrim('/'.ltrim($matches[1],'/'),'/'))]=TRUE;}}}return!isset($disallow[$path]);});$filter(new\SplFileInfo($dir));return$iterator;}private
  5198. function
  5199. updateFile($file){foreach($this->classes
  5200. as$class=>$info){if(isset($info['file'])&&$info['file']===$file){unset($this->classes[$class]);}}if(is_file($file)){foreach($this->scanPhp(file_get_contents($file))as$class){$info=&$this->classes[strtolower($class)];if(isset($info['file'])&&@filemtime($info['file'])!==$info['time']){$this->updateFile($info['file']);$info=&$this->classes[strtolower($class)];}if(isset($info['file'])){$e=new
  5201. Nette\InvalidStateException("Ambiguous class $class resolution; defined in {$info['file']} and in $file.");{throw$e;}}$info=array('file'=>$file,'time'=>filemtime($file),'orig'=>$class);}}}private
  5202. function
  5203. scanPhp($code){$T_NAMESPACE=PHP_VERSION_ID<50300?-1:T_NAMESPACE;$T_NS_SEPARATOR=PHP_VERSION_ID<50300?-1:T_NS_SEPARATOR;$T_TRAIT=PHP_VERSION_ID<50400?-1:T_TRAIT;$expected=FALSE;$namespace='';$level=$minLevel=0;$classes=array();if(preg_match('#//nette'.'loader=(\S*)#',$code,$matches)){foreach(explode(',',$matches[1])as$name){$classes[]=$name;}return$classes;}foreach(@token_get_all($code)as$token){if(is_array($token)){switch($token[0]){case
  5204. T_COMMENT:case
  5205. T_DOC_COMMENT:case
  5206. T_WHITESPACE:continue
  5207. 2;case$T_NS_SEPARATOR:case
  5208. T_STRING:if($expected){$name.=$token[1];}continue
  5209. 2;case$T_NAMESPACE:case
  5210. T_CLASS:case
  5211. T_INTERFACE:case$T_TRAIT:$expected=$token[0];$name='';continue
  5212. 2;case
  5213. T_CURLY_OPEN:case
  5214. T_DOLLAR_OPEN_CURLY_BRACES:$level++;}}if($expected){switch($expected){case
  5215. T_CLASS:case
  5216. T_INTERFACE:case$T_TRAIT:if($level===$minLevel){$classes[]=$namespace.$name;}break;case$T_NAMESPACE:$namespace=$name?$name.'\\':'';$minLevel=$token==='{'?1:0;}$expected=NULL;}if($token==='{'){$level++;}elseif($token==='}'){$level--;}}return$classes;}function
  5217. setCacheStorage(Nette\Caching\IStorage$storage){$this->cacheStorage=$storage;return$this;}function
  5218. getCacheStorage(){return$this->cacheStorage;}protected
  5219. function
  5220. getCache(){if(!$this->cacheStorage){trigger_error('Missing cache storage.',E_USER_WARNING);$this->cacheStorage=new
  5221. Nette\Caching\Storages\DevNullStorage;}return
  5222. new
  5223. Cache($this->cacheStorage,'Nette.RobotLoader');}protected
  5224. function
  5225. getKey(){return
  5226. array($this->ignoreDirs,$this->acceptFiles,$this->scanDirs);}}}namespace Nette\Mail{use
  5227. Nette;use
  5228. Nette\Utils\Strings;class
  5229. MimePart
  5230. extends
  5231. Nette\Object{const
  5232. ENCODING_BASE64='base64',ENCODING_7BIT='7bit',ENCODING_8BIT='8bit',ENCODING_QUOTED_PRINTABLE='quoted-printable';const
  5233. EOL="\r\n";const
  5234. LINE_LENGTH=76;private$headers=array();private$parts=array();private$body;function
  5235. setHeader($name,$value,$append=FALSE){if(!$name||preg_match('#[^a-z0-9-]#i',$name)){throw
  5236. new
  5237. Nette\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
  5238. as$email=>$recipient){if($recipient!==NULL&&!Strings::checkEncoding($recipient)){Nette\Utils\Validators::assert($recipient,'unicode',"header '$name'");}if(preg_match('#[\r\n]#',$recipient)){throw
  5239. new
  5240. Nette\InvalidArgumentException("Name must not contain line separator.");}Nette\Utils\Validators::assert($email,'email',"header '$name'");$tmp[$email]=$recipient;}}else{$value=(string)$value;if(!Strings::checkEncoding($value)){throw
  5241. new
  5242. Nette\InvalidArgumentException("Header is not valid UTF-8 string.");}$this->headers[$name]=preg_replace('#[\r\n]+#',' ',$value);}return$this;}function
  5243. getHeader($name){return
  5244. isset($this->headers[$name])?$this->headers[$name]:NULL;}function
  5245. clearHeader($name){unset($this->headers[$name]);return$this;}function
  5246. getEncodedHeader($name){$offset=strlen($name)+2;if(!isset($this->headers[$name])){return
  5247. 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
  5248. substr($s,0,-1);}elseif(preg_match('#^(\S+; (?:file)?name=)"(.*)"\z#',$this->headers[$name],$m)){$offset+=strlen($m[1]);return$m[1].'"'.self::encodeHeader($m[2],$offset).'"';}else{return
  5249. self::encodeHeader($this->headers[$name],$offset);}}function
  5250. getHeaders(){return$this->headers;}function
  5251. setContentType($contentType,$charset=NULL){$this->setHeader('Content-Type',$contentType.($charset?"; charset=$charset":''));return$this;}function
  5252. setEncoding($encoding){$this->setHeader('Content-Transfer-Encoding',$encoding);return$this;}function
  5253. getEncoding(){return$this->getHeader('Content-Transfer-Encoding');}function
  5254. addPart(MimePart$part=NULL){return$this->parts[]=$part===NULL?new
  5255. self:$part;}function
  5256. setBody($body){$this->body=$body;return$this;}function
  5257. getBody(){return$this->body;}function
  5258. generateMessage(){$output='';$boundary='--------'.Strings::random();foreach($this->headers
  5259. 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
  5260. self::ENCODING_QUOTED_PRINTABLE:$output.=function_exists('quoted_printable_encode')?quoted_printable_encode($body):self::encodeQuotedPrintable($body);break;case
  5261. self::ENCODING_BASE64:$output.=rtrim(chunk_split(base64_encode($body),self::LINE_LENGTH,self::EOL));break;case
  5262. self::ENCODING_7BIT:$body=preg_replace('#[\x80-\xFF]+#','',$body);case
  5263. self::ENCODING_8BIT:$body=str_replace(array("\x00","\r"),'',$body);$body=str_replace("\n",self::EOL,$body);$output.=$body;break;default:throw
  5264. new
  5265. Nette\InvalidStateException('Unknown encoding.');}}if($this->parts){if(substr($output,-strlen(self::EOL))!==self::EOL){$output.=self::EOL;}foreach($this->parts
  5266. as$part){$output.='--'.$boundary.self::EOL.$part->generateMessage().self::EOL;}$output.='--'.$boundary.'--';}return$output;}private
  5267. static
  5268. function
  5269. encodeHeader($s,&$offset=0){$o='';if($offset>=55){$o=self::EOL."\t";$offset=1;}if(strspn($s,"!\"#$%&\'()*+,-./0123456789:;<>@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^`abcdefghijklmnopqrstuvwxyz{|}=? _\r\n\t")===strlen($s)&&($offset+strlen($s)<=self::LINE_LENGTH)){$offset+=strlen($s);return$o.$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;}}class
  5270. Message
  5271. extends
  5272. MimePart{const
  5273. HIGH=1,NORMAL=3,LOW=5;public
  5274. static$defaultMailer='Nette\Mail\SendmailMailer';public
  5275. static$defaultHeaders=array('MIME-Version'=>'1.0','X-Mailer'=>'Nette Framework');private$mailer;private$attachments=array();private$inlines=array();private$html;private$basePath;function
  5276. __construct(){foreach(static::$defaultHeaders
  5277. as$name=>$value){$this->setHeader($name,$value);}$this->setHeader('Date',date('r'));}function
  5278. setFrom($email,$name=NULL){$this->setHeader('From',$this->formatEmail($email,$name));return$this;}function
  5279. getFrom(){return$this->getHeader('From');}function
  5280. addReplyTo($email,$name=NULL){$this->setHeader('Reply-To',$this->formatEmail($email,$name),TRUE);return$this;}function
  5281. setSubject($subject){$this->setHeader('Subject',$subject);return$this;}function
  5282. getSubject(){return$this->getHeader('Subject');}function
  5283. addTo($email,$name=NULL){$this->setHeader('To',$this->formatEmail($email,$name),TRUE);return$this;}function
  5284. addCc($email,$name=NULL){$this->setHeader('Cc',$this->formatEmail($email,$name),TRUE);return$this;}function
  5285. addBcc($email,$name=NULL){$this->setHeader('Bcc',$this->formatEmail($email,$name),TRUE);return$this;}private
  5286. function
  5287. formatEmail($email,$name){if(!$name&&preg_match('#^(.+) +<(.*)>\z#',$email,$matches)){return
  5288. array($matches[2]=>$matches[1]);}else{return
  5289. array($email=>$name);}}function
  5290. setReturnPath($email){$this->setHeader('Return-Path',$email);return$this;}function
  5291. getReturnPath(){return$this->getHeader('From');}function
  5292. setPriority($priority){$this->setHeader('X-Priority',(int)$priority);return$this;}function
  5293. getPriority(){return$this->getHeader('X-Priority');}function
  5294. setHtmlBody($html,$basePath=NULL){$this->html=$html;$this->basePath=$basePath;return$this;}function
  5295. getHtmlBody(){return$this->html;}function
  5296. addEmbeddedFile($file,$content=NULL,$contentType=NULL){return$this->inlines[$file]=$this->createAttachment($file,$content,$contentType,'inline')->setHeader('Content-ID',$this->getRandomId());}function
  5297. addAttachment($file,$content=NULL,$contentType=NULL){return$this->attachments[]=$this->createAttachment($file,$content,$contentType,'attachment');}private
  5298. function
  5299. createAttachment($file,$content,$contentType,$disposition){$part=new
  5300. MimePart;if($content===NULL){$content=@file_get_contents($file);if($content===FALSE){throw
  5301. new
  5302. Nette\FileNotFoundException("Unable to read file '$file'.");}}else{$content=(string)$content;}$part->setBody($content);$part->setContentType($contentType?$contentType:Nette\Utils\MimeTypeDetector::fromString($content));$part->setEncoding(preg_match('#(multipart|message)/#A',$contentType)?self::ENCODING_8BIT:self::ENCODING_BASE64);$part->setHeader('Content-Disposition',$disposition.'; filename="'.Strings::fixEncoding(basename($file)).'"');return$part;}function
  5303. send(){$this->getMailer()->send($this->build());}function
  5304. setMailer(IMailer$mailer){$this->mailer=$mailer;return$this;}function
  5305. getMailer(){if($this->mailer===NULL){$this->mailer=is_object(static::$defaultMailer)?static::$defaultMailer:new
  5306. static::$defaultMailer;}return$this->mailer;}function
  5307. generateMessage(){if($this->getHeader('Message-ID')){return
  5308. parent::generateMessage();}else{return$this->build()->generateMessage();}}protected
  5309. function
  5310. build(){$mail=clone$this;$mail->setHeader('Message-ID',$this->getRandomId());$mail->buildHtml();$mail->buildText();$cursor=$mail;if($mail->attachments){$tmp=$cursor->setContentType('multipart/mixed');$cursor=$cursor->addPart();foreach($mail->attachments
  5311. 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
  5312. as$name=>$value){$tmp->addPart($value);}}$alt->setContentType('text/html','UTF-8')->setEncoding(preg_match('#\S{990}#',$mail->html)?self::ENCODING_QUOTED_PRINTABLE:(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('#\S{990}#',$text)?self::ENCODING_QUOTED_PRINTABLE:(preg_match('#[\x80-\xFF]#',$text)?self::ENCODING_8BIT:self::ENCODING_7BIT))->setBody($text);return$mail;}protected
  5313. function
  5314. buildHtml(){if($this->html
  5315. instanceof
  5316. Nette\Templating\ITemplate){$this->html->mail=$this;if($this->basePath===NULL&&$this->html
  5317. instanceof
  5318. Nette\Templating\IFileTemplate){$this->basePath=dirname($this->html->getFile());}$this->html=$this->html->__toString(TRUE);}if($this->basePath!==FALSE){$cids=array();$matches=Strings::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];if(!isset($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:{$cids[$file]}{$m[2][0]}",$m[0][1],strlen($m[0][0]));}}if(!$this->getSubject()&&$matches=Strings::match($this->html,'#<title>(.+?)</title>#is')){$this->setSubject(html_entity_decode($matches[1],ENT_QUOTES,'UTF-8'));}}protected
  5319. function
  5320. buildText(){$text=$this->getBody();if($text
  5321. instanceof
  5322. Nette\Templating\ITemplate){$text->mail=$this;$this->setBody($text->__toString(TRUE));}elseif($text==NULL&&$this->html!=NULL){$text=Strings::replace($this->html,array('#<(style|script|head).*</\\1>#Uis'=>'','#<t[dh][ >]#i'=>" $0",'#[\r\n]+#'=>' ','#<(/?p|/?h\d|li|br|/tr)[ >/]#i'=>"\n$0"));$text=html_entity_decode(strip_tags($text),ENT_QUOTES,'UTF-8');$text=Strings::replace($text,'#[ \t]+#',' ');$this->setBody(trim($text));}}private
  5323. function
  5324. getRandomId(){return'<'.Strings::random().'@'.(isset($_SERVER['HTTP_HOST'])?$_SERVER['HTTP_HOST']:(isset($_SERVER['SERVER_NAME'])?$_SERVER['SERVER_NAME']:'localhost')).'>';}}class
  5325. SendmailMailer
  5326. extends
  5327. Nette\Object
  5328. implements
  5329. IMailer{public$commandArgs;function
  5330. send(Message$mail){$tmp=clone$mail;$tmp->setHeader('Subject',NULL);$tmp->setHeader('To',NULL);$parts=explode(Message::EOL.Message::EOL,$tmp->generateMessage(),2);$args=array(str_replace(Message::EOL,PHP_EOL,$mail->getEncodedHeader('To')),str_replace(Message::EOL,PHP_EOL,$mail->getEncodedHeader('Subject')),str_replace(Message::EOL,PHP_EOL,$parts[1]),str_replace(Message::EOL,PHP_EOL,$parts[0]));if($this->commandArgs){$args[]=(string)$this->commandArgs;}if(call_user_func_array('mail',$args)===FALSE){$error=error_get_last();throw
  5331. new
  5332. Nette\InvalidStateException("Unable to send email: $error[message].");}}}class
  5333. SmtpMailer
  5334. extends
  5335. Nette\Object
  5336. implements
  5337. IMailer{private$connection;private$host;private$port;private$username;private$password;private$secure;private$timeout;function
  5338. __construct(array$options=array()){if(isset($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
  5339. send(Message$mail){$mail=clone$mail;$this->connect();$from=$mail->getHeader('From');if($from){$from=array_keys($from);$this->write("MAIL FROM:<$from[0]>",250);}foreach(array_merge((array)$mail->getHeader('To'),(array)$mail->getHeader('Cc'),(array)$mail->getHeader('Bcc'))as$email=>$name){$this->write("RCPT TO:<$email>",array(250,251));}$mail->setHeader('Bcc',NULL);$data=$mail->generateMessage();$this->write('DATA',354);$data=preg_replace('#^\.#m','..',$data);$this->write($data);$this->write('.',250);$this->write('QUIT',221);$this->disconnect();}private
  5340. function
  5341. connect(){$this->connection=@fsockopen(($this->secure==='ssl'?'ssl://':'').$this->host,$this->port,$errno,$error,$this->timeout);if(!$this->connection){throw
  5342. new
  5343. 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
  5344. new
  5345. SmtpException('Unable to connect via TLS.');}$this->write("EHLO $self",250);}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
  5346. function
  5347. disconnect(){fclose($this->connection);$this->connection=NULL;}private
  5348. function
  5349. write($line,$expectedCode=NULL,$message=NULL){fwrite($this->connection,$line.Message::EOL);if($expectedCode&&!in_array((int)$this->read(),(array)$expectedCode)){throw
  5350. new
  5351. SmtpException('SMTP server did not accept '.($message?$message:$line));}}private
  5352. function
  5353. read(){$s='';while(($line=fgets($this->connection,1e3))!=NULL){$s.=$line;if(substr($line,3,1)===' '){break;}}return$s;}}class
  5354. SmtpException
  5355. extends\Exception{}}namespace Nette\Reflection{use
  5356. Nette;class
  5357. Annotation
  5358. extends
  5359. Nette\Object
  5360. implements
  5361. IAnnotation{function
  5362. __construct(array$values){foreach($values
  5363. as$k=>$v){$this->$k=$v;}}function
  5364. __toString(){return$this->value;}}use
  5365. Nette\Utils\Strings;/**
  5366. * Annotations support for PHP.
  5367. *
  5368. * @author David Grudl
  5369. * @Annotation
  5370. */final
  5371. class
  5372. AnnotationsParser{const
  5373. RE_STRING='\'(?:\\\\.|[^\'\\\\])*\'|"(?:\\\\.|[^"\\\\])*"';const
  5374. RE_IDENTIFIER='[_a-zA-Z\x7F-\xFF][_a-zA-Z0-9\x7F-\xFF-\\\]*';public
  5375. static$useReflection;public
  5376. static$inherited=array('description','param','return');private
  5377. static$cache;private
  5378. static$timestamps;private
  5379. static$cacheStorage;final
  5380. function
  5381. __construct(){throw
  5382. new
  5383. Nette\StaticClassException;}static
  5384. function
  5385. getAll(\Reflector$r){if($r
  5386. instanceof\ReflectionClass){$type=$r->getName();$member='';}elseif($r
  5387. instanceof\ReflectionMethod){$type=$r->getDeclaringClass()->getName();$member=$r->getName();}else{$type=$r->getDeclaringClass()->getName();$member='$'.$r->getName();}if(!self::$useReflection){$file=$r
  5388. 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
  5389. self::$cache[$type][$member];}if(self::$useReflection===NULL){self::$useReflection=(bool)ClassType::from(__CLASS__)->getDocComment();}if(self::$useReflection){$annotations=self::parseComment($r->getDocComment());}else{if(!self::$cacheStorage){self::$cacheStorage=new
  5390. Nette\Caching\Storages\DevNullStorage;}$outerCache=new
  5391. Nette\Caching\Cache(self::$cacheStorage,'Nette.Reflection.Annotations');if(self::$cache===NULL){self::$cache=(array)$outerCache->offsetGet('list');self::$timestamps=isset(self::$cache['*'])?self::$cache['*']:array();}if(!isset(self::$cache[$type])&&$file){self::$cache['*'][$file]=filemtime($file);self::parseScript($file);$outerCache->save('list',self::$cache);}if(isset(self::$cache[$type][$member])){$annotations=self::$cache[$type][$member];}else{$annotations=array();}}if($r
  5392. instanceof\ReflectionMethod&&!$r->isPrivate()&&(!$r->isConstructor()||!empty($annotations['inheritdoc'][0]))){try{$inherited=self::getAll(new\ReflectionMethod(get_parent_class($type),$member));}catch(\ReflectionException$e){try{$inherited=self::getAll($r->getPrototype());}catch(\ReflectionException$e){$inherited=array();}}$annotations+=array_intersect_key($inherited,array_flip(self::$inherited));}return
  5393. self::$cache[$type][$member]=$annotations;}private
  5394. static
  5395. function
  5396. parseComment($comment){static$tokens=array('true'=>TRUE,'false'=>FALSE,'null'=>NULL,''=>TRUE);$res=array();$comment=preg_replace('#^\s*\*\s?#ms','',trim($comment,'/*'));$parts=preg_split('#^\s*(?=@'.self::RE_IDENTIFIER.')#m',$comment,2);$description=trim($parts[0]);if($description!==''){$res['description']=array($description);}$matches=Strings::matchAll(isset($parts[1])?$parts[1]:'','~
  5397. (?<=\s|^)@('.self::RE_IDENTIFIER.')[ \t]* ## annotation
  5398. (
  5399. \((?>'.self::RE_STRING.'|[^\'")@]+)+\)| ## (value)
  5400. [^(@\r\n][^@\r\n]*|) ## value
  5401. ~xi');foreach($matches
  5402. as$match){list(,$name,$value)=$match;if(substr($value,0,1)==='('){$items=array();$key='';$val=TRUE;$value[0]=',';while($m=Strings::match($value,'#\s*,\s*(?>('.self::RE_IDENTIFIER.')\s*=\s*)?('.self::RE_STRING.'|[^\'"),\s][^\'"),]*)#A')){$value=substr($value,strlen($m[0]));list(,$key,$val)=$m;$val=rtrim($val);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
  5403. static
  5404. function
  5405. 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(Strings::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
  5406. T_DOC_COMMENT:$docComment=$token[1];case
  5407. T_WHITESPACE:case
  5408. T_COMMENT:continue
  5409. 2;case
  5410. T_STRING:case$T_NS_SEPARATOR:case
  5411. T_VARIABLE:if($expected){$name.=$token[1];}continue
  5412. 2;case
  5413. T_FUNCTION:case
  5414. T_VAR:case
  5415. T_PUBLIC:case
  5416. T_PROTECTED:case$T_NAMESPACE:case
  5417. T_CLASS:case
  5418. T_INTERFACE:$expected=$token[0];$name=NULL;continue
  5419. 2;case
  5420. T_STATIC:case
  5421. T_ABSTRACT:case
  5422. T_FINAL:continue
  5423. 2;case
  5424. T_CU