%IOApplication/Application.php jYX x=Application/ErrorPresenter.phpxjYXx{tApplication/exceptions.phpjYXyApplication/IPresenter.phppjYXp҅w!Application/IPresenterFactory.phpjYXTc6Application/IResponse.phpjYXضApplication/IRouter.phpjYXApplication/LinkGenerator.phpjYX%Application/MicroPresenter.php jYX >ö Application/PresenterFactory.phpz jYXz W%/EApplication/Request.phpjYXx\*Application/Responses/CallbackResponse.phpjYX5&Application/Responses/FileResponse.phpjYXZ )Application/Responses/ForwardResponse.phpjYXI&Application/Responses/JsonResponse.phpjYX&)*Application/Responses/RedirectResponse.php8jYX8>M&Application/Responses/TextResponse.phpjYX.!Application/Routers/CliRouter.phpjYXս$Application/Routers/Route.php7jYX7ж!Application/Routers/RouteList.phpZjYXZE,$Application/Routers/SimpleRouter.phpjYX<!Application/templates/error.phtmljYX{%Application/UI/BadSignalException.phpjYXJFApplication/UI/Control.phpQ jYXQ kNjApplication/UI/Form.php'jYX'`#{'Application/UI/InvalidLinkException.phpTjYXTK''Application/UI/IRenderable.phpjYX"Application/UI/ISignalReceiver.phpvjYXv/#Application/UI/IStatePersistent.phpjYX&Application/UI/ITemplate.phpjYX>#Application/UI/ITemplateFactory.phpjYXMOApplication/UI/Link.phpjYXCѨApplication/UI/Multiplier.php<jYX<zApplication/UI/Presenter.phpZjYXZPFVy%Application/UI/PresenterComponent.phpjYX/Application/UI/PresenterComponentReflection.phpjYXs# Bootstrap/Configurator.php1jYX1.Bridges/ApplicationDI/ApplicationExtension.phpjYX0(Bridges/ApplicationDI/LatteExtension.php jYX p&2Bridges/ApplicationDI/PresenterFactoryCallback.phpjYX*Bridges/ApplicationDI/RoutingExtension.php!jYX!:Q.*Bridges/ApplicationLatte/ILatteFactory.phpjYX@#Bridges/ApplicationLatte/Loader.phpjYXR%Bridges/ApplicationLatte/Template.php/ jYX/ 9۶,Bridges/ApplicationLatte/TemplateFactory.php jYX BN^%Bridges/ApplicationLatte/UIMacros.php jYX jfT&Bridges/ApplicationLatte/UIRuntime.phpZjYXZ[)Bridges/ApplicationTracy/RoutingPanel.php jYX a˶;Bridges/ApplicationTracy/templates/RoutingPanel.panel.phtml; jYX; 9Bridges/ApplicationTracy/templates/RoutingPanel.tab.phtmljYX !"Bridges/CacheDI/CacheExtension.php+jYX+!Bridges/CacheLatte/CacheMacro.phpEjYXES(Bridges/DatabaseDI/DatabaseExtension.php jYX 4!)Bridges/DatabaseTracy/ConnectionPanel.php# jYX# >Gw;Bridges/DatabaseTracy/templates/ConnectionPanel.panel.phtmljYXHto9Bridges/DatabaseTracy/templates/ConnectionPanel.tab.phtmlEjYXE븗8"Bridges/DITracy/ContainerPanel.php jYX 4Bridges/DITracy/templates/ContainerPanel.panel.phtmljYXf_2Bridges/DITracy/templates/ContainerPanel.tab.phtmljYX;"Bridges/FormsDI/FormsExtension.phpjYXk!Bridges/FormsLatte/FormMacros.phpjYXV2Bridges/FormsLatte/Runtime.phpfjYXfxT!Bridges/Framework/TracyBridge.phpjYXH Bridges/HttpDI/HttpExtension.phpjYX+P"#Bridges/HttpDI/SessionExtension.phpjYX^"Bridges/HttpTracy/SessionPanel.phpjYX-e4Bridges/HttpTracy/templates/SessionPanel.panel.phtmljYXeFfp2Bridges/HttpTracy/templates/SessionPanel.tab.phtmlJjYXJ{c>¶ Bridges/MailDI/MailExtension.phpjYX`V< Bridges/Nette/TracyExtension.phpjYX]Xt,Bridges/ReflectionDI/ReflectionExtension.phpjYXw?p(Bridges/SecurityDI/SecurityExtension.phpKjYXK5Bridges/SecurityTracy/templates/UserPanel.panel.phtmlMjYXMCLz3Bridges/SecurityTracy/templates/UserPanel.tab.phtmlLjYXLO9⊶#Bridges/SecurityTracy/UserPanel.phpFjYXFc{ֶCaching/Cache.phpjYXCaching/IStorage.php*jYX*lCaching/OutputHelper.phpjYX-#Caching/Storages/DevNullStorage.phpjYX ˶ Caching/Storages/FileJournal.phpMjYXMƶ Caching/Storages/FileStorage.phpjYXjCaching/Storages/IJournal.phpjYX'w_%Caching/Storages/MemcachedStorage.php jYX PK"Caching/Storages/MemoryStorage.phpajYXaAƶ(Caching/Storages/NewMemcachedStorage.php jYX vf"Caching/Storages/SQLiteStorage.phpjYXqComponentModel/Component.phpjYXҁt̶ComponentModel/Container.phpxjYXxMcComponentModel/IComponent.phpjYXR}ComponentModel/IContainer.phpbjYXbΓ-ComponentModel/RecursiveComponentIterator.phpjYXEkDatabase/Connection.php jYX tDatabase/Context.phpjYX.Database/Conventions/DiscoveredConventions.php!jYX!m1z#Database/Conventions/exceptions.phpkjYXk۟*Database/Conventions/StaticConventions.phpjYXR.Database/deprecated/ConventionalReflection.phpxjYXx9x,Database/deprecated/DiscoveredReflection.php jYX ɕ"Database/deprecated/exceptions.phpjYXGg#Database/deprecated/IReflection.php:jYX:xDatabase/DriverException.php)jYX)R.\ Database/Drivers/MsSqlDriver.phpjYXn Database/Drivers/MySqlDriver.phpsjYXsڞ;Database/Drivers/OciDriver.phpo jYXo fDatabase/Drivers/OdbcDriver.phpjYXx Database/Drivers/PgSqlDriver.phpjYX"M"Database/Drivers/Sqlite2Driver.php2jYX2i޶!Database/Drivers/SqliteDriver.phpjYXg!Database/Drivers/SqlsrvDriver.phpjYXDatabase/exceptions.phpjYXUDatabase/Helpers.phpjYX${Database/IConventions.phpjYXutDatabase/IRow.phpQjYXQmDatabase/IRowContainer.php$jYX$RȶDatabase/IStructure.phpjYX$D Database/ISupplementalDriver.phpjYXxADatabase/ResultSet.phpjYXLěZDatabase/Row.phpjYX&Database/SqlLiteral.phpjYXoDatabase/SqlPreprocessor.phpjYXtxDatabase/Structure.php'jYX'JDatabase/Table/ActiveRow.phpjYXp۶#Database/Table/GroupedSelection.phpjYXh>Database/Table/IRow.php)jYX)z Database/Table/IRowContainer.phpjYXG[Database/Table/Selection.phpf<jYXf<J7Database/Table/SqlBuilder.php_-jYX_-|%deprecated/Caching/PhpFileStorage.php jYX ldeprecated/Callback.phpjYXȨ#deprecated/Diagnostics/Debugger.phpjYXx^<"deprecated/Diagnostics/Helpers.phpljYXll$deprecated/Diagnostics/IBarPanel.phpZjYXZ&deprecated/Environment.phpjYX+deprecated/Latte/Engine.phpjYXlʶ&deprecated/Templating/FileTemplate.phpjYXA!!deprecated/Templating/Helpers.phpQjYXQ'deprecated/Templating/IFileTemplate.phpjYXIY#deprecated/Templating/ITemplate.php]jYX]>?"deprecated/Templating/Template.php*jYX* J$deprecated/Utils/FreezableObject.phpjYXӥdeprecated/Utils/IFreezable.php{jYX{΀˶!deprecated/Utils/LimitedScope.php{jYX{@$%deprecated/Utils/MimeTypeDetector.phpjYXcDI/Compiler.phpa(jYXa(DI/CompilerExtension.phpjYXQK!DI/Config/Adapters/IniAdapter.php jYX "N"DI/Config/Adapters/NeonAdapter.php` jYX` +!DI/Config/Adapters/PhpAdapter.phpWjYXW~DI/Config/Helpers.phpIjYXIZmVDI/Config/IAdapter.phpjYXp:DI/Config/Loader.phpzjYXz0DI/Container.phpjYXr堏DI/ContainerBuilder.php4SjYX4SɶDI/ContainerFactory.php/ jYX/ < ԶDI/ContainerLoader.phpGjYXG¾NDI/exceptions.phpjYX(篶$DI/Extensions/ConstantsExtension.php(jYX(<Ѷ$DI/Extensions/DecoratorExtension.phpjYXܶDI/Extensions/DIExtension.php,jYX,E%DI/Extensions/ExtensionsExtension.phpjYX ն!DI/Extensions/InjectExtension.php jYX _]DI/Extensions/PhpExtension.php jYX Ő(˶DI/Helpers.php jYX SjYX>4Finder/Finder.phpjYX7O*Finder/RecursiveCallbackFilterIterator.phpjYX1Forms/Container.phpjYX0FFForms/ControlGroup.phpFjYXF[ʬForms/Controls/BaseControl.phpIjYXI֔Forms/Controls/Button.phpjYX-daضForms/Controls/Checkbox.phpXjYXX(jForms/Controls/CheckboxList.phpjYX5d Forms/Controls/ChoiceControl.php~jYX~ !Forms/Controls/CsrfProtection.phpHjYXHΔfForms/Controls/HiddenField.php4jYX4˶Forms/Controls/ImageButton.phpjYX_%Forms/Controls/MultiChoiceControl.php jYX I!Forms/Controls/MultiSelectBox.phpvjYXvrCForms/Controls/RadioList.php jYX WForms/Controls/SelectBox.phpgjYXgn8Forms/Controls/SubmitButton.phpjYXForms/Controls/TextArea.php{jYX{MzxForms/Controls/TextBase.phpfjYXf5Forms/Controls/TextInput.phpYjYXY\ܶ Forms/Controls/UploadControl.phpjYX>_cForms/Form.php;!jYX;!Forms/Helpers.php1jYX171VForms/IControl.php<jYX<cjӶForms/IFormRenderer.phpgjYXgO޶Forms/ISubmitterControl.php~jYX~k]'Forms/Rendering/DefaultFormRenderer.php jYX 21Forms/Rule.phpjYX4SForms/Rules.phpjYXcForms/Validator.phpKjYXKs߶ Framework.phpjYXHttp/FileUpload.phpjYXdHttp/Helpers.phpjYX^Http/IRequest.phpjYX󯾶Http/IResponse.phpPjYXPYͥHttp/ISessionStorage.phpjYX䰝Http/Request.phpjYXKuHttp/RequestFactory.phpxjYXxar_lHttp/Response.phpjYX Http/Session.phpjYX2hHttp/SessionSection.php$ jYX$ 8 Http/Url.phppjYXpcTHttp/UrlScript.phpjYX͠Http/UserStorage.php jYX IpIterators/CachingIterator.php` jYX` ?`'Iterators/Filter.phpYjYXY!XMIterators/Mapper.phpYjYXYIterators/RecursiveFilter.phpjYX9"Latte/Compiler.php2jYX2ULatte/Engine.php?jYX?9%Latte/exceptions.phpjYXuILatte/Helpers.phpjYX#Latte/HtmlNode.php.jYX.h:Latte/ILoader.phpjYX[xLatte/IMacro.phpjYXųLatte/Loaders/FileLoader.phpjYXuOLatte/Loaders/StringLoader.php\jYX\gLatte/MacroNode.phpAjYXAC9:Latte/Macros/BlockMacros.php$jYX$єN#Latte/Macros/BlockMacrosRuntime.php5jYX5LLatte/Macros/CoreMacros.php*jYX*sLatte/Macros/MacroSet.php jYX N{HwLatte/MacroTokens.phpjjYXj4pLatte/Object.phpjYX/x Latte/Parser.phpC#jYXC#'Latte/PhpWriter.php\jYX\1ض!Latte/Runtime/CachingIterator.php\ jYX\ @Latte/Runtime/Filters.phpyjYXy}$,ضLatte/Runtime/Html.phpjYX mLatte/Runtime/IHtmlString.phpqjYXq±bLatte/Template.phpjYXmwLatte/Token.php-jYX-röLatte/TokenIterator.php jYX wMLatte/Tokenizer.phpjYX loader.php_jYX_-Loaders/NetteLoader.php!jYX!^Mail/exceptions.phpjYX\?Mail/IMailer.php_jYX_R Mail/Message.phpjYXbJMMail/MimePart.phpjYX l}Mail/SendmailMailer.phpjYXQh;Mail/SmtpMailer.php@ jYX@ dÊNeon/Decoder.phpzjYXz~蹶Neon/Encoder.phpjYXkNeon/Entity.phpjYX!:7Neon/Exception.php?jYX?_ Neon/Neon.phpMjYXMEPhpGenerator/ClassType.phpAjYXA/eCNPhpGenerator/Helpers.phpjYX+:uPhpGenerator/Method.phpTjYXTiPhpGenerator/Parameter.phpjYXlPhpGenerator/PhpFile.phpjYXBݶPhpGenerator/PhpLiteral.phpjYXfPhpGenerator/PhpNamespace.phpI jYXI APhpGenerator/Property.phpFjYXF%.Reflection/Annotation.phpjYX֚= Reflection/AnnotationsParser.phpCjYXC+5Reflection/ClassType.php5 jYX5 97Reflection/Extension.php jYX qReflection/GlobalFunction.php:jYX:Reflection/Helpers.php|jYX|wCݶReflection/IAnnotation.php\jYX\Reflection/Method.php[jYX[${Reflection/Parameter.php>jYX>GGKReflection/Property.phpjYXbRobotLoader/RobotLoader.php jYX &XSafeStream/SafeStream.phpjYX>3$Security/AuthenticationException.phpQjYXQ̎Security/IAuthenticator.phpjYXRSecurity/IAuthorizator.phpjYXyoSecurity/Identity.phpjYXPCZSecurity/IIdentity.phpjYX _Security/IResource.phpdjYXd&̶Security/IRole.php\jYX\Security/IUserStorage.phpjYXFuH,Security/Passwords.phpjYX6tsSecurity/Permission.php+jYX+z.\U Security/SimpleAuthenticator.phpjYXPSecurity/User.php jYX ws϶ shortcuts.phpjYX9VTokenizer/TokenIterator.php jYX ^ -Tokenizer/Tokenizer.phpjYXG, Tokenizer/TokenizerException.phpIjYXIFiTracy/assets/Bar/bar.css$jYX$=϶Tracy/assets/Bar/bar.jsv0jYXv0kTracy/assets/Bar/bar.phtmlJjYXJpӶ"Tracy/assets/Bar/dumps.panel.phtmljYXۭ"x Tracy/assets/Bar/dumps.tab.phtmljYXa9Ķ#Tracy/assets/Bar/errors.panel.phtmljYXvT!Tracy/assets/Bar/errors.tab.phtmljYXtNa!Tracy/assets/Bar/info.panel.phtmljYX0ܶTracy/assets/Bar/info.tab.phtmljYXp,&Tracy/assets/BlueScreen/bluescreen.cssfjYXfk8?u%Tracy/assets/BlueScreen/bluescreen.jssjYXs]L(Tracy/assets/BlueScreen/bluescreen.phtmlSjYXS3qvP%Tracy/assets/Debugger/error.500.phtml"jYX")!Tracy/assets/Dumper/dumper.cssjYX2Tracy/assets/Dumper/dumper.jsjYXD+_ Tracy/Bar.phpjYXFTracy/BlueScreen.php jYX 0Tracy/Debugger.phpp(jYXp(Tracy/DefaultBarPanel.phpjYX!϶Tracy/Dumper.php3jYX3 _Tracy/FireLogger.php jYX dSTracy/Helpers.phpjYXLTracy/IBarPanel.php~jYX~cլTracy/ILogger.phpjYXBTracy/Logger.phpjYXTracy/OutputDebugger.phpjYXUa~Utils/ArrayHash.phpjYXz;Utils/ArrayList.php=jYX=ѶUtils/Arrays.php jYX ,^Utils/Callback.phpojYXoTXAUtils/DateTime.phpjYXݹUtils/exceptions.phpjYXe{hUtils/FileSystem.php jYX Utils/Html.phpjYX$) Utils/IHtmlString.phpojYXo長Utils/Image.php"2jYX"2~آUtils/ITranslator.phpzjYXzzUtils/Json.phpujYXu.UUtils/Object.php[jYX[?Utils/ObjectMixin.php#jYX#W.ٶUtils/Paginator.php-jYX-OUtils/Random.phpjYXrm8˶Utils/Strings.php$jYX$LJ`Utils/Validators.phpjYXuhttpRequest=$httpRequest;$this->httpResponse=$httpResponse;$this->presenterFactory=$presenterFactory;$this->router=$router;}/** @return void **/public function run(){try{$this->onStartup($this);$this->processRequest($this->createInitialRequest());$this->onShutdown($this);}catch(\Exception$e){$this->onError($this,$e);if($this->catchExceptions&&$this->errorPresenter){try{$this->processException($e);$this->onShutdown($this,$e);return;}catch(\Exception$e){$this->onError($this,$e);}}$this->onShutdown($this,$e);throw$e;}}/** @return Request **/public function createInitialRequest(){$request=$this->router->match($this->httpRequest);if(!$request instanceof Request){throw new BadRequestException('No route for HTTP request.');}elseif(strcasecmp($request->getPresenterName(),$this->errorPresenter)===0){throw new BadRequestException('Invalid request. Presenter is not achievable.');}try{$name=$request->getPresenterName();$this->presenterFactory->getPresenterClass($name);}catch(InvalidPresenterException$e){throw new BadRequestException($e->getMessage(),0,$e);}return$request;}/** @return void **/public function processRequest(Request$request){if(count($this->requests)>self::$maxLoop){throw new ApplicationException('Too many loops detected in application life cycle.');}$this->requests[]=$request;$this->onRequest($this,$request);$this->presenter=$this->presenterFactory->createPresenter($request->getPresenterName());$this->onPresenter($this,$this->presenter);$response=$this->presenter->run($request);if($response instanceof Responses\ForwardResponse){$this->processRequest($response->getRequest());}elseif($response){$this->onResponse($this,$response);$response->send($this->httpRequest,$this->httpResponse);}}/** @return void **/public function processException(\Exception$e){if(!$e instanceof BadRequestException&&$this->httpResponse instanceof Nette\Http\Response){$this->httpResponse->warnOnBuffer=FALSE;}if(!$this->httpResponse->isSent()){$this->httpResponse->setCode($e instanceof BadRequestException?($e->getCode()?:404):500);}$args=array('exception'=>$e,'request'=>end($this->requests)?:NULL);if($this->presenter instanceof UI\Presenter){try{$this->presenter->forward(":$this->errorPresenter:",$args);}catch(AbortException$foo){$this->processRequest($this->presenter->getLastCreatedRequest());}}else{$this->processRequest(new Request($this->errorPresenter,Request::FORWARD,$args));}}/** @return Request[] **/public function getRequests(){return$this->requests;}/** @return IPresenter **/public function getPresenter(){return$this->presenter;}/** @return IRouter **/public function getRouter(){return$this->router;}/** @return IPresenterFactory **/public function getPresenterFactory(){return$this->presenterFactory;}}logger=$logger;}/** @return Application\IResponse **/public function run(Application\Request$request){$e=$request->getParameter('exception');if($e instanceof Application\BadRequestException){$code=$e->getCode();}else{$code=500;if($this->logger){$this->logger->log($e,ILogger::EXCEPTION);}}return new Application\Responses\CallbackResponse(function()use($code){require __DIR__.'/templates/error.phtml';});}}504?$this->code:$code,$previous);}}class ForbiddenRequestException extends BadRequestException{protected$code=403;}router=$router;$this->refUrl=$refUrl;$this->presenterFactory=$presenterFactory;}/** @return string **/public function link($dest,array$params=array()){if(!preg_match('~^([\w:]+):(\w*+)(#.*)?()\z~',$dest,$m)){throw new UI\InvalidLinkException("Invalid link destination '$dest'.");}list(,$presenter,$action,$frag)=$m;try{$class=$this->presenterFactory?$this->presenterFactory->getPresenterClass($presenter):NULL;}catch(InvalidPresenterException$e){throw new UI\InvalidLinkException($e->getMessage(),NULL,$e);}if(is_subclass_of($class,'Nette\Application\UI\Presenter')){if($action===''){$action=UI\Presenter::DEFAULT_ACTION;}if(method_exists($class,$method=$class::formatActionMethod($action))||method_exists($class,$method=$class::formatRenderMethod($action))){UI\Presenter::argsToParams($class,$method,$params);}}if($action!==''){$params[UI\Presenter::ACTION_KEY]=$action;}$url=$this->router->constructUrl(new Request($presenter,NULL,$params),$this->refUrl);if($url===NULL){unset($params[UI\Presenter::ACTION_KEY]);$params=urldecode(http_build_query($params,NULL,', '));throw new UI\InvalidLinkException("No route for $dest($params)");}return$url.$frag;}}context=$context;$this->httpRequest=$httpRequest;$this->router=$router;}/** @return Nette\DI\Container **/public function getContext(){return$this->context;}/** @return Nette\Application\IResponse **/public function run(Application\Request$request){$this->request=$request;if($this->httpRequest&&$this->router&&!$this->httpRequest->isAjax()&&($request->isMethod('get')||$request->isMethod('head'))){$refUrl=clone$this->httpRequest->getUrl();$url=$this->router->constructUrl($request,$refUrl->setPath($refUrl->getScriptPath()));if($url!==NULL&&!$this->httpRequest->getUrl()->isEqual($url)){return new Responses\RedirectResponse($url,Http\IResponse::S301_MOVED_PERMANENTLY);}}$params=$request->getParameters();if(!isset($params['callback'])){throw new Application\BadRequestException('Parameter callback is missing.');}$params['presenter']=$this;$callback=$params['callback'];$reflection=Nette\Utils\Callback::toReflection(Nette\Utils\Callback::check($callback));$params=Application\UI\PresenterComponentReflection::combineArgs($reflection,$params);if($this->context){foreach($reflection->getParameters()as$param){if($param->getClassName()){unset($params[$param->getPosition()]);}}$params=Nette\DI\Helpers::autowireArguments($reflection,$params,$this->context);$params['presenter']=$this;}$response=call_user_func_array($callback,$params);if(is_string($response)){$response=array($response,array());}if(is_array($response)){list($templateSource,$templateParams)=$response;$response=$this->createTemplate()->setParameters($templateParams);if(!$templateSource instanceof\SplFileInfo){$response->getLatte()->setLoader(new Latte\Loaders\StringLoader);}$response->setFile($templateSource);}if($response instanceof Application\UI\ITemplate){return new Responses\TextResponse($response);}else{return$response;}}/** @return Application\UI\ITemplate **/public function createTemplate($class=NULL,$latteFactory=NULL){$latte=$latteFactory?$latteFactory():$this->getContext()->getByType('Nette\Bridges\ApplicationLatte\ILatteFactory')->create();$template=$class?new$class:new Nette\Bridges\ApplicationLatte\Template($latte);$template->setParameters($this->request->getParameters());$template->presenter=$this;$template->context=$this->context;if($this->httpRequest){$url=$this->httpRequest->getUrl();$template->baseUrl=rtrim($url->getBaseUrl(),'/');$template->basePath=rtrim($url->getBasePath(),'/');}return$template;}/** @return Nette\Application\Responses\RedirectResponse **/public function redirectUrl($url,$code=Http\IResponse::S302_FOUND){return new Responses\RedirectResponse($url,$code);}/** @return void **/public function error($message=NULL,$code=Http\IResponse::S404_NOT_FOUND){throw new Application\BadRequestException($message,$code);}/** @return Nette\Application\Request **/public function getRequest(){return$this->request;}}array('','*Module\\','*Presenter'),'Nette'=>array('NetteModule\\','*\\','*Presenter'));private$cache=array();private$factory;public function __construct($factory=NULL){$this->factory=$factory?:function($class){return new$class;};}/** @return IPresenter **/public function createPresenter($name){return call_user_func($this->factory,$this->getPresenterClass($name));}/** @return string class name **/public function getPresenterClass(&$name){if(isset($this->cache[$name])){return$this->cache[$name];}if(!is_string($name)||!Nette\Utils\Strings::match($name,'#^[a-zA-Z\x7f-\xff][a-zA-Z0-9\x7f-\xff:]*\z#')){throw new InvalidPresenterException("Presenter name must be alphanumeric string, '$name' is invalid.");}$class=$this->formatPresenterClass($name);if(!class_exists($class)){throw new InvalidPresenterException("Cannot load presenter '$name', class '$class' was not found.");}$reflection=new\ReflectionClass($class);$class=$reflection->getName();if(!$reflection->implementsInterface('Nette\Application\IPresenter')){throw new InvalidPresenterException("Cannot load presenter '$name', class '$class' is not Nette\\Application\\IPresenter implementor.");}elseif($reflection->isAbstract()){throw new InvalidPresenterException("Cannot load presenter '$name', class '$class' is abstract.");}$this->cache[$name]=$class;if($name!==($realName=$this->unformatPresenterClass($class))){trigger_error("Case mismatch on presenter name '$name', correct name is '$realName'.",E_USER_WARNING);$name=$realName;}return$class;}/** @return self **/public function setMapping(array$mapping){foreach($mapping as$module=>$mask){if(is_string($mask)){if(!preg_match('#^\\\\?([\w\\\\]*\\\\)?(\w*\*\w*?\\\\)?([\w\\\\]*\*\w*)\z#',$mask,$m)){throw new Nette\InvalidStateException("Invalid mapping mask '$mask'.");}$this->mapping[$module]=array($m[1],$m[2]?:'*Module\\',$m[3]);}elseif(is_array($mask)&&count($mask)===3){$this->mapping[$module]=array($mask[0]?$mask[0].'\\':'',$mask[1].'\\',$mask[2]);}else{throw new Nette\InvalidStateException("Invalid mapping mask for module $module.");}}return$this;}/** @return string **/public function formatPresenterClass($presenter){$parts=explode(':',$presenter);$mapping=isset($parts[1],$this->mapping[$parts[0]])?$this->mapping[array_shift($parts)]:$this->mapping['*'];while($part=array_shift($parts)){$mapping[0].=str_replace('*',$part,$mapping[$parts?1:2]);}return$mapping[0];}/** @return string **/public function unformatPresenterClass($class){foreach($this->mapping as$module=>$mapping){$mapping=str_replace(array('\\','*'),array('\\\\','(\w+)'),$mapping);if(preg_match("#^\\\\?$mapping[0]((?:$mapping[1])*)$mapping[2]\\z#i",$class,$matches)){return($module==='*'?'':$module.':').preg_replace("#$mapping[1]#iA",'$1:',$matches[1]).$matches[3];}}}}name=$name;$this->method=$method;$this->params=$params;$this->post=$post;$this->files=$files;$this->flags=$flags;}/** @return self **/public function setPresenterName($name){$this->name=$name;return$this;}/** @return string **/public function getPresenterName(){return$this->name;}/** @return self **/public function setParameters(array$params){$this->params=$params;return$this;}/** @return array **/public function getParameters(){return$this->params;}/** @return mixed **/public function getParameter($key){return isset($this->params[$key])?$this->params[$key]:NULL;}/** @return self **/public function setPost(array$params){$this->post=$params;return$this;}/** @return mixed **/public function getPost($key=NULL){if(func_num_args()===0){return$this->post;}elseif(isset($this->post[$key])){return$this->post[$key];}else{return NULL;}}/** @return self **/public function setFiles(array$files){$this->files=$files;return$this;}/** @return array **/public function getFiles(){return$this->files;}/** @return self **/public function setMethod($method){$this->method=$method;return$this;}/** @return string|NULL **/public function getMethod(){return$this->method;}/** @return bool **/public function isMethod($method){return strcasecmp($this->method,$method)===0;}public function isPost(){trigger_error('Method isPost() is deprecated, use isMethod(\'POST\') instead.',E_USER_DEPRECATED);return strcasecmp($this->method,'post')===0;}/** @return self **/public function setFlag($flag,$value=TRUE){$this->flags[$flag]=(bool)$value;return$this;}/** @return bool **/public function hasFlag($flag){return!empty($this->flags[$flag]);}}callback=$callback;}/** @return void **/public function send(Nette\Http\IRequest$httpRequest,Nette\Http\IResponse$httpResponse){call_user_func($this->callback,$httpRequest,$httpResponse);}}file=$file;$this->name=$name?$name:basename($file);$this->contentType=$contentType?$contentType:'application/octet-stream';$this->forceDownload=$forceDownload;}/** @return string **/public function getFile(){return$this->file;}/** @return string **/public function getName(){return$this->name;}/** @return string **/public function getContentType(){return$this->contentType;}/** @return void **/public function send(Nette\Http\IRequest$httpRequest,Nette\Http\IResponse$httpResponse){$httpResponse->setContentType($this->contentType);$httpResponse->setHeader('Content-Disposition',($this->forceDownload?'attachment':'inline').'; filename="'.$this->name.'"'.'; filename*=utf-8\'\''.rawurlencode($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);}}request=$request;}/** @return Nette\Application\Request **/public function getRequest(){return$this->request;}/** @return void **/public function send(Nette\Http\IRequest$httpRequest,Nette\Http\IResponse$httpResponse){}}payload=$payload;$this->contentType=$contentType?$contentType:'application/json';}/** @return array|\stdClass **/public function getPayload(){return$this->payload;}/** @return string **/public function getContentType(){return$this->contentType;}/** @return void **/public function send(Nette\Http\IRequest$httpRequest,Nette\Http\IResponse$httpResponse){$httpResponse->setContentType($this->contentType,'utf-8');$httpResponse->setExpiration(FALSE);echo Nette\Utils\Json::encode($this->payload);}}url=(string)$url;$this->code=(int)$code;}/** @return string **/public function getUrl(){return$this->url;}/** @return int **/public function getCode(){return$this->code;}/** @return void **/public function send(Http\IRequest$httpRequest,Http\IResponse$httpResponse){$httpResponse->redirect($this->url,$this->code);}}source=$source;}/** @return mixed **/public function getSource(){return$this->source;}/** @return void **/public function send(Nette\Http\IRequest$httpRequest,Nette\Http\IResponse$httpResponse){if($this->source instanceof Nette\Application\UI\ITemplate){$this->source->render();}else{echo$this->source;}}}defaults=$defaults;}/** @return Nette\Application\Request|NULL **/public function match(Nette\Http\IRequest$httpRequest){if(empty($_SERVER['argv'])||!is_array($_SERVER['argv'])){return NULL;}$names=array(self::PRESENTER_KEY);$params=$this->defaults;$args=$_SERVER['argv'];array_shift($args);$args[]='--';foreach($args 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 new 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 new Application\Request($presenter,'CLI',$params);}/** @return NULL **/public function constructUrl(Application\Request$appRequest,Nette\Http\Url$refUrl){return NULL;}/** @return array **/public function getDefaults(){return$this->defaults;}}array(self::PATTERN=>'[^/]+',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$aliases;private$metadata=array();private$xlat;private$type;private$flags;private$lastRefUrl;private$lastBaseUrl;public function __construct($mask,$metadata=array(),$flags=0){if(is_string($metadata)){$a=strrpos($tmp=$metadata,':');if(!$a){throw new Nette\InvalidArgumentException("Second argument must be array or string in format Presenter:action, '$metadata' given.");}$metadata=array(self::PRESENTER_KEY=>substr($tmp,0,$a));if($a'Nette:Micro','callback'=>$metadata);}$this->flags=$flags|static::$defaultFlags;$this->setMask($mask,$metadata);}/** @return Nette\Application\Request|NULL **/public function match(Nette\Http\IRequest$httpRequest){$url=$httpRequest->getUrl();$re=$this->re;if($this->type===self::HOST){$host=$url->getHost();$path='//'.$host.$url->getPath();$parts=ip2long($host)?array($host):array_reverse(explode('.',$host));$re=strtr($re,array('/%basePath%/'=>preg_quote($url->getBasePath(),'#'),'%tld%'=>preg_quote($parts[0],'#'),'%domain%'=>preg_quote(isset($parts[1])?"$parts[1].$parts[0]":$parts[0],'#'),'%sld%'=>preg_quote(isset($parts[1])?$parts[1]:'','#'),'%host%'=>preg_quote($host,'#')));}elseif($this->type===self::RELATIVE){$basePath=$url->getBasePath();if(strncmp($url->getPath(),$basePath,strlen($basePath))!==0){return NULL;}$path=(string)substr($url->getPath(),strlen($basePath));}else{$path=$url->getPath();}if($path!==''){$path=rtrim(rawurldecode($path),'/').'/';}if(!$matches=Strings::match($path,$re)){return NULL;}$params=array();foreach($matches as$k=>$v){if(is_string($k)&&$v!==''){$params[$this->aliases[$k]]=$v;}}foreach($this->metadata as$name=>$meta){if(!isset($params[$name])&&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 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 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 NULL;}}}elseif(isset($meta['fixity'])){$params[$name]=$meta[self::VALUE];}}if(isset($this->metadata[NULL][self::FILTER_IN])){$params=call_user_func($this->metadata[NULL][self::FILTER_IN],$params);if($params===NULL){return NULL;}}if(!isset($params[self::PRESENTER_KEY])){throw new Nette\InvalidStateException('Missing presenter in route definition.');}elseif(!is_string($params[self::PRESENTER_KEY])){return NULL;}$presenter=$params[self::PRESENTER_KEY];unset($params[self::PRESENTER_KEY]);if(isset($this->metadata[self::MODULE_KEY])){$presenter=(isset($params[self::MODULE_KEY])?$params[self::MODULE_KEY].':':'').$presenter;unset($params[self::MODULE_KEY]);}return new Application\Request($presenter,$httpRequest->getMethod(),$params,$httpRequest->getPost(),$httpRequest->getFiles(),array(Application\Request::SECURED=>$httpRequest->isSecured()));}/** @return string|NULL **/public function constructUrl(Application\Request$appRequest,Nette\Http\Url$refUrl){if($this->flags&self::ONE_WAY){return NULL;}$params=$appRequest->getParameters();$metadata=$this->metadata;$presenter=$appRequest->getPresenterName();$params[self::PRESENTER_KEY]=$presenter;if(isset($metadata[NULL][self::FILTER_OUT])){$params=call_user_func($metadata[NULL][self::FILTER_OUT],$params);if($params===NULL){return NULL;}}if(isset($metadata[self::MODULE_KEY])){$module=$metadata[self::MODULE_KEY];if(isset($module['fixity'])&&strncmp($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]=isset($module[self::VALUE])?'':NULL;}else{$params[self::MODULE_KEY]=substr($presenter,0,$a);$params[self::PRESENTER_KEY]=substr($presenter,$a+1);}}foreach($metadata as$name=>$meta){if(!isset($params[$name])){continue;}if(isset($meta['fixity'])){if($params[$name]===FALSE){$params[$name]='0';}elseif(is_scalar($params[$name])){$params[$name]=(string)$params[$name];}if($params[$name]===$meta[self::VALUE]){unset($params[$name]);continue;}elseif($meta['fixity']===self::CONSTANT){return NULL;}}if(is_scalar($params[$name])&&isset($meta['filterTable2'][$params[$name]])){$params[$name]=$meta['filterTable2'][$params[$name]];}elseif(isset($meta['filterTable2'])&&!empty($meta[self::FILTER_STRICT])){return 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 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($requiredtype===self::HOST){$host=$refUrl->getHost();$parts=ip2long($host)?array($host):array_reverse(explode('.',$host));$url=strtr($url,array('/%basePath%/'=>$refUrl->getBasePath(),'%tld%'=>$parts[0],'%domain%'=>isset($parts[1])?"$parts[1].$parts[0]":$parts[0],'%sld%'=>isset($parts[1])?$parts[1]:'','%host%'=>$host));$url=($this->flags&self::SECURED?'https:':'http:').$url;}else{if($this->lastRefUrl!==$refUrl){$scheme=($this->flags&self::SECURED?'https://':'http://');$basePath=($this->type===self::RELATIVE?$refUrl->getBasePath():'');$this->lastBaseUrl=$scheme.$refUrl->getAuthority().$basePath;$this->lastRefUrl=$refUrl;}$url=$this->lastBaseUrl.$url;}if(strpos($url,'//',7)!==FALSE){return NULL;}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;}return$url;}/** @return void **/private function 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 as$name=>$meta){if(!is_array($meta)){$metadata[$name]=$meta=array(self::VALUE=>$meta);}if(array_key_exists(self::VALUE,$meta)){if(is_scalar($meta[self::VALUE])){$metadata[$name][self::VALUE]=(string)$meta[self::VALUE];}$metadata[$name]['fixity']=self::CONSTANT;}}if(strpbrk($mask,'?<[]')===FALSE){$this->re='#'.preg_quote($mask,'#').'/?\z#A';$this->sequence=array($mask);$this->metadata=$metadata;return;}$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 as$match){list(,$param,$name,$pattern,$class)=$match;if($class!==''){if(!isset(static::$styles[$class])){throw new 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;$aliases=array();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 new 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]==='?'){$name=substr($name,1);$re=$pattern?'(?:'.preg_quote($name,'#')."|$pattern)$re":preg_quote($name,'#').$re;$sequence[1]=$name.$sequence[1];continue;}if($class!==''){if(!isset(static::$styles[$class])){throw new 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";$aliases['p'.$i]=$name;$re='(?P(?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 new Nette\InvalidArgumentException("Missing '[' in mask '$mask'.");}$this->aliases=$aliases;$this->re='#'.$re.'/?\z#A';$this->metadata=$metadata;$this->sequence=$sequence;}/** @return string **/public function getMask(){return$this->mask;}/** @return array **/public function getDefaults(){$defaults=array();foreach($this->metadata as$name=>$meta){if(isset($meta['fixity'])){$defaults[$name]=$meta[self::VALUE];}}return$defaults;}/** @return int **/public function getFlags(){return$this->flags;}/** @return string[]|NULL **/public function getTargetPresenters(){if($this->flags&self::ONE_WAY){return array();}$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 NULL;}}if(isset($m[self::PRESENTER_KEY]['fixity'])&&$m[self::PRESENTER_KEY]['fixity']===self::CONSTANT){return array($module.$m[self::PRESENTER_KEY][self::VALUE]);}return NULL;}/** @return array **/private static function renameKeys($arr,$xlat){if(empty($xlat)){return$arr;}$res=array();$occupied=array_flip($xlat);foreach($arr as$k=>$v){if(isset($xlat[$k])){$res[$xlat[$k]]=$v;}elseif(!isset($occupied[$k])){$res[$k]=$v;}}return$res;}/** @return string **/private static function action2path($s){$s=preg_replace('#(.)(?=[A-Z])#','$1-',$s);$s=strtolower($s);$s=rawurlencode($s);return$s;}/** @return string **/private static function path2action($s){$s=preg_replace('#-(?=[a-z])#',' ',$s);$s=lcfirst(ucwords($s));$s=str_replace(' ','',$s);return$s;}/** @return string **/private static function presenter2path($s){$s=strtr($s,':','.');$s=preg_replace('#([^.])(?=[A-Z])#','$1-',$s);$s=strtolower($s);$s=rawurlencode($s);return$s;}/** @return string **/private static function path2presenter($s){$s=preg_replace('#([.-])(?=[a-z])#','$1 ',$s);$s=ucwords($s);$s=str_replace('. ',':',$s);$s=str_replace('- ','',$s);return$s;}/** @return string **/private static function param2path($s){return str_replace('%2F','/',rawurlencode($s));}public static function addStyle($style,$parent='#'){trigger_error(__METHOD__.'() is deprecated.',E_USER_DEPRECATED);if(isset(static::$styles[$style])){throw new Nette\InvalidArgumentException("Style '$style' already exists.");}if($parent!==NULL){if(!isset(static::$styles[$parent])){throw new Nette\InvalidArgumentException("Parent style '$parent' doesn't exist.");}static::$styles[$style]=static::$styles[$parent];}else{static::$styles[$style]=array();}}public static function setStyleProperty($style,$key,$value){trigger_error(__METHOD__.'() is deprecated.',E_USER_DEPRECATED);if(!isset(static::$styles[$style])){throw new Nette\InvalidArgumentException("Style '$style' doesn't exist.");}static::$styles[$style][$key]=$value;}}module=$module?$module.':':'';}/** @return Nette\Application\Request|NULL **/public function match(Nette\Http\IRequest$httpRequest){foreach($this as$route){$appRequest=$route->match($httpRequest);if($appRequest!==NULL){$name=$appRequest->getPresenterName();if(strncmp($name,'Nette:',6)){$appRequest->setPresenterName($this->module.$name);}return$appRequest;}}return NULL;}/** @return string|NULL **/public function constructUrl(Nette\Application\Request$appRequest,Nette\Http\Url$refUrl){if($this->cachedRoutes===NULL){$this->warmupCache();}if($this->module){if(strncmp($tmp=$appRequest->getPresenterName(),$this->module,strlen($this->module))===0){$appRequest=clone$appRequest;$appRequest->setPresenterName(substr($tmp,strlen($this->module)));}else{return NULL;}}$presenter=$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 NULL;}public function warmupCache(){$routes=array();$routes['*']=array();foreach($this as$route){$presenters=$route instanceof Route&&is_array($tmp=$route->getTargetPresenters())?$tmp:array_keys($routes);foreach($presenters as$presenter){if(!isset($routes[$presenter])){$routes[$presenter]=$routes['*'];}$routes[$presenter][]=$route;}}$this->cachedRoutes=$routes;}/** @return void **/public function offsetSet($index,$route){if(!$route instanceof Nette\Application\IRouter){throw new Nette\InvalidArgumentException('Argument must be IRouter descendant.');}parent::offsetSet($index,$route);}/** @return string **/public function getModule(){return$this->module;}}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;}/** @return Nette\Application\Request|NULL **/public function match(Nette\Http\IRequest$httpRequest){if($httpRequest->getUrl()->getPathInfo()!==''){return NULL;}$params=$httpRequest->getQuery();$params+=$this->defaults;if(!isset($params[self::PRESENTER_KEY])||!is_string($params[self::PRESENTER_KEY])){return NULL;}$presenter=$this->module.$params[self::PRESENTER_KEY];unset($params[self::PRESENTER_KEY]);return new Application\Request($presenter,$httpRequest->getMethod(),$params,$httpRequest->getPost(),$httpRequest->getFiles(),array(Application\Request::SECURED=>$httpRequest->isSecured()));}/** @return string|NULL **/public function constructUrl(Application\Request$appRequest,Nette\Http\Url$refUrl){if($this->flags&self::ONE_WAY){return NULL;}$params=$appRequest->getParameters();$presenter=$appRequest->getPresenterName();if(strncmp($presenter,$this->module,strlen($this->module))===0){$params[self::PRESENTER_KEY]=substr($presenter,strlen($this->module));}else{return NULL;}foreach($this->defaults 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;}/** @return array **/public function getDefaults(){return$this->defaults;}/** @return int **/public function getFlags(){return$this->flags;}}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];?> <?php echo$message[0]?>

error

templateFactory=$templateFactory;}/** @return ITemplate **/public function getTemplate(){if($this->template===NULL){$value=$this->createTemplate();if(!$value instanceof ITemplate&&$value!==NULL){$class2=get_class($value);$class=get_class($this);throw new Nette\UnexpectedValueException("Object returned by $class::createTemplate() must be instance of Nette\\Application\\UI\\ITemplate, '$class2' given.");}$this->template=$value;}return$this->template;}/** @return ITemplate **/protected function createTemplate(){$templateFactory=$this->templateFactory?:$this->getPresenter()->getTemplateFactory();return$templateFactory->createTemplate($this);}/** @return void **/public function templatePrepareFilters($template){}/** @return \stdClass **/public function 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;}/** @return void **/public function redrawControl($snippet=NULL,$redraw=TRUE){if($redraw){$this->invalidSnippets[$snippet===NULL?"\0":$snippet]=TRUE;}elseif($snippet===NULL){$this->invalidSnippets=array();}else{unset($this->invalidSnippets[$snippet]);}}function invalidateControl($snippet=NULL){$this->redrawControl($snippet);}function validateControl($snippet=NULL){$this->redrawControl($snippet,FALSE);}/** @return bool **/public function isControlInvalid($snippet=NULL){if($snippet===NULL){if(count($this->invalidSnippets)>0){return TRUE;}else{$queue=array($this);do{foreach(array_shift($queue)->getComponents()as$component){if($component instanceof IRenderable){if($component->isControlInvalid()){return TRUE;}}elseif($component instanceof Nette\ComponentModel\IContainer){$queue[]=$component;}}}while($queue);return FALSE;}}else{return isset($this->invalidSnippets["\0"])||isset($this->invalidSnippets[$snippet]);}}/** @return string **/public function getSnippetId($name=NULL){return'snippet-'.$this->getUniqueId().'-'.$name;}}addComponent($this,$name);}}/** @return void **/protected function validateParent(Nette\ComponentModel\IContainer$parent){parent::validateParent($parent);$this->monitor('Nette\Application\UI\Presenter');}/** @return Presenter|NULL **/public function getPresenter($need=TRUE){return$this->lookup('Nette\Application\UI\Presenter',$need);}/** @return void **/protected function attached($presenter){if($presenter instanceof Presenter){$name=$this->lookupPath('Nette\Application\UI\Presenter');if(!isset($this->getElementPrototype()->id)){$this->getElementPrototype()->id='frm-'.$name;}if(iterator_count($this->getControls())&&$this->isSubmitted()){foreach($this->getControls()as$control){if(!$control->isDisabled()){$control->loadHttpData();}}}if(!$this->getAction()){$this->setAction(new Link($presenter,'this',array()));$signal=new Nette\Forms\Controls\HiddenField($name.self::NAME_SEPARATOR.'submit');$signal->setOmitted()->setHtmlId(FALSE);$this[Presenter::SIGNAL_KEY]=$signal;}}parent::attached($presenter);}/** @return bool **/public function isAnchored(){return(bool)$this->getPresenter(FALSE);}/** @return array|NULL **/protected function 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 Nette\Utils\Arrays::mergeTree($request->getPost(),$request->getFiles());}else{return$request->getParameters();}}/** @return void **/public function signalReceived($signal){if($signal==='submit'){if(!$this->getPresenter()->getRequest()->hasFlag(Nette\Application\Request::RESTORED)){$this->fireEvents();}}else{$class=get_class($this);throw new BadSignalException("Missing handler for signal '$signal' in $class.");}}}component=$component;$this->destination=$destination;$this->params=$params;}/** @return string **/public function getDestination(){return$this->destination;}/** @return self **/public function setParameter($key,$value){$this->params[$key]=$value;return$this;}/** @return mixed **/public function getParameter($key){return isset($this->params[$key])?$this->params[$key]:NULL;}/** @return array **/public function getParameters(){return$this->params;}/** @return string **/public function __toString(){try{return(string)$this->component->link($this->destination,$this->params);}catch(\Throwable$e){}catch(\Exception$e){}if(isset($e)){if(func_num_args()){throw$e;}trigger_error("Exception in ".__METHOD__."(): {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}",E_USER_ERROR);}}}factory=Nette\Utils\Callback::check($factory);}protected function createComponent($name){return call_user_func($this->factory,$name,$this);}}payload=new\stdClass;}/** @return Nette\Application\Request **/public function getRequest(){return$this->request;}/** @return Presenter **/public function getPresenter($need=TRUE){return$this;}/** @return string **/public function getUniqueId(){return'';}/** @return Nette\Application\IResponse **/public function run(Application\Request$request){try{$this->request=$request;$this->payload=$this->payload?:new\stdClass;$this->setParent($this->getParent(),$request->getPresenterName());if(!$this->httpResponse->isSent()){$this->httpResponse->addHeader('Vary','X-Requested-With');}$this->initGlobalParameters();$this->checkRequirements($this->getReflection());$this->startup();if(!$this->startupCheck){$class=$this->getReflection()->getMethod('startup')->getDeclaringClass()->getName();throw new Nette\InvalidStateException("Method $class::startup() or its descendant doesn't call parent::startup().");}$this->tryCall($this->formatActionMethod($this->action),$this->params);foreach($this->globalParams as$id=>$foo){$this->getComponent($id,FALSE);}if($this->autoCanonicalize){$this->canonicalize();}if($this->httpRequest->isMethod('head')){$this->terminate();}$this->processSignal();$this->beforeRender();$this->tryCall($this->formatRenderMethod($this->view),$this->params);$this->afterRender();$this->saveGlobalState();if($this->isAjax()){$this->payload->state=$this->getGlobalState();}if($this->getTemplate()){$this->sendTemplate();}}catch(Application\AbortException$e){if($this->isAjax()){try{$hasPayload=(array)$this->payload;unset($hasPayload['state']);if($this->response instanceof Responses\TextResponse&&$this->isControlInvalid()){$this->snippetMode=TRUE;$this->response->send($this->httpRequest,$this->httpResponse);$this->sendPayload();}elseif(!$this->response&&$hasPayload){$this->sendPayload();}}catch(Application\AbortException$e){}}if($this->hasFlashSession()){$this->getFlashSession()->setExpiration($this->response instanceof Responses\RedirectResponse?'+ 30 seconds':'+ 3 seconds');}$this->onShutdown($this,$this->response);$this->shutdown($this->response);return$this->response;}}/** @return void **/protected function startup(){$this->startupCheck=TRUE;}/** @return void **/protected function beforeRender(){}/** @return void **/protected function afterRender(){}/** @return void **/protected function shutdown($response){}/** @return void **/public function checkRequirements($element){$user=(array)PresenterComponentReflection::parseAnnotation($element,'User');if(in_array('loggedIn',$user,TRUE)&&!$this->getUser()->isLoggedIn()){throw new Application\ForbiddenRequestException;}}/** @return void **/public function 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 new BadSignalException("The signal receiver component '$this->signalReceiver' is not found.",NULL,isset($e)?$e:NULL);}elseif(!$component instanceof ISignalReceiver){throw new BadSignalException("The signal receiver component '$this->signalReceiver' is not ISignalReceiver implementor.");}$component->signalReceived($this->signal);$this->signal=NULL;}/** @return array|NULL **/public function getSignal(){return$this->signal===NULL?NULL:array($this->signalReceiver,$this->signal);}/** @return bool **/public function isSignalReceiver($component,$signal=NULL){if($component instanceof Nette\ComponentModel\Component){$component=$component===$this?'':$component->lookupPath(__CLASS__,TRUE);}if($this->signal===NULL){return 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;}}/** @return string **/public function getAction($fullyQualified=FALSE){return$fullyQualified?':'.$this->getName().':'.$this->action:$this->action;}/** @return void **/public function 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.');}}/** @return string **/public function getView(){return$this->view;}/** @return self **/public function setView($view){$this->view=(string)$view;return$this;}/** @return string|FALSE **/public function getLayout(){return$this->layout;}/** @return self **/public function setLayout($layout){$this->layout=$layout===FALSE?FALSE:(string)$layout;return$this;}/** @return void **/public function sendTemplate(){$template=$this->getTemplate();if(!$template->getFile()){$files=$this->formatTemplateFiles();foreach($files 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 Responses\TextResponse($template));}/** @return string **/public function findLayoutTemplateFile(){if($this->layout===FALSE){return;}$files=$this->formatLayoutTemplateFiles();foreach($files 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 new Nette\FileNotFoundException("Layout not found. Missing template '$file'.");}}/** @return array **/public function 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");do{$list[]="$dir/templates/@$layout.latte";$dir=dirname($dir);}while($dir&&($name=substr($name,0,strrpos($name,':'))));return$list;}/** @return array **/public function formatTemplateFiles(){$name=$this->getName();$presenter=substr($name,strrpos(':'.$name,':'));$dir=dirname($this->getReflection()->getFileName());$dir=is_dir("$dir/templates")?$dir:dirname($dir);return array("$dir/templates/$presenter/$this->view.latte","$dir/templates/$presenter.$this->view.latte");}/** @return string **/public static function formatActionMethod($action){return'action'.$action;}/** @return string **/public static function formatRenderMethod($view){return'render'.$view;}/** @return ITemplate **/protected function createTemplate(){return$this->getTemplateFactory()->createTemplate($this);}/** @return \stdClass **/public function getPayload(){return$this->payload;}/** @return bool **/public function isAjax(){if($this->ajaxMode===NULL){$this->ajaxMode=$this->httpRequest->isAjax();}return$this->ajaxMode;}/** @return void **/public function sendPayload(){$this->sendResponse(new Responses\JsonResponse($this->payload));}/** @return void **/public function sendJson($data){$this->sendResponse(new Responses\JsonResponse($data));}/** @return void **/public function sendResponse(Application\IResponse$response){$this->response=$response;$this->terminate();}/** @return void **/public function terminate(){throw new Application\AbortException();}/** @return void **/public function forward($destination,$args=array()){if($destination instanceof Application\Request){$this->sendResponse(new Responses\ForwardResponse($destination));}$this->createRequest($this,$destination,is_array($args)?$args:array_slice(func_get_args(),1),'forward');$this->sendResponse(new Responses\ForwardResponse($this->lastCreatedRequest));}/** @return void **/public function redirectUrl($url,$code=NULL){if($this->isAjax()){$this->payload->redirect=(string)$url;$this->sendPayload();}elseif(!$code){$code=$this->httpRequest->isMethod('post')?Http\IResponse::S303_POST_GET:Http\IResponse::S302_FOUND;}$this->sendResponse(new Responses\RedirectResponse($url,$code));}/** @return void **/public function error($message=NULL,$code=Http\IResponse::S404_NOT_FOUND){throw new Application\BadRequestException($message,$code);}/** @return string **/public function backlink(){return$this->getAction(TRUE);}/** @return Nette\Application\Request **/public function getLastCreatedRequest(){return$this->lastCreatedRequest;}/** @return bool **/public function getLastCreatedRequestFlag($flag){return!empty($this->lastCreatedRequestFlag[$flag]);}/** @return void **/public function 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->httpRequest->getUrl()->isEqual($url)){$this->sendResponse(new Responses\RedirectResponse($url,Http\IResponse::S301_MOVED_PERMANENTLY));}}}/** @return void **/public function lastModified($lastModified,$etag=NULL,$expire=NULL){if($expire!==NULL){$this->httpResponse->setExpiration($expire);}$helper=new Http\Context($this->httpRequest,$this->httpResponse);if(!$helper->isModified($lastModified,$etag)){$this->terminate();}}/** @return string URL **/protected function createRequest($component,$destination,array$args,$mode){$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 instanceof self||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 new InvalidLinkException('Signal must be non-empty string.');}$destination='this';}if($destination==NULL){throw new 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 new 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);}}if(!$this->presenterFactory){throw new Nette\InvalidStateException('Unable to create link to other presenter, service PresenterFactory has not been set.');}try{$presenterClass=$this->presenterFactory->getPresenterClass($presenter);}catch(Application\InvalidPresenterException$e){throw new InvalidLinkException($e->getMessage(),NULL,$e);}}if(isset($signal)){$reflection=new PresenterComponentReflection(get_class($component));if($signal==='this'){$signal='';if(array_key_exists(0,$args)){throw new InvalidLinkException("Unable to pass parameters to 'this!' signal.");}}elseif(strpos($signal,self::NAME_SEPARATOR)===FALSE){$method=$component->formatSignalMethod($signal);if(!$reflection->hasCallableMethod($method)){throw new InvalidLinkException("Unknown signal '$signal', missing handler {$reflection->getName()}::$method()");}self::argsToParams(get_class($component),$method,$args,array(),$mode==='test');}if($args&&array_intersect_key($args,$reflection->getPersistentParams())){$component->saveState($args);}if($args&&$component!==$this){$prefix=$component->getUniqueId().self::NAME_SEPARATOR;foreach($args 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 PresenterComponentReflection($presenterClass);$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 new InvalidLinkException("Unable to pass parameters to action '$presenter:$action', missing corresponding method.");}}else{self::argsToParams($presenterClass,$method,$args,$destination==='this'?$this->params:array(),$mode==='test');}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 as$key=>$val){if(http_build_query(array($val))!==(isset($tmp[$key])?http_build_query(array($tmp[$key])):'')){$current=FALSE;break;}}}$args+=$globalState;}if($action){$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 Application\Request($presenter,Application\Request::FORWARD,$args,array(),array());$this->lastCreatedRequestFlag=array('current'=>$current);if($mode==='forward'||$mode==='test'){return;}static$refUrl;if($refUrl===NULL){$refUrl=new Http\Url($this->httpRequest->getUrl());$refUrl->setPath($this->httpRequest->getUrl()->getScriptPath());}if(!$this->router){throw new Nette\InvalidStateException('Unable to generate URL, service Router has not been set.');}$url=$this->router->constructUrl($this->lastCreatedRequest,$refUrl);if($url===NULL){unset($args[self::ACTION_KEY]);$params=urldecode(http_build_query($args,NULL,', '));throw new 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)-1);}}return$url.$fragment;}/** @return void **/public static function argsToParams($class,$method,&$args,$supplemental=array(),$ignoreMissing=FALSE){$i=0;$rm=new\ReflectionMethod($class,$method);foreach($rm->getParameters()as$param){list($type,$isClass)=PresenterComponentReflection::getParameterType($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];}if(!isset($args[$name])){if($param->isDefaultValueAvailable()||$type==='NULL'||$type==='array'||$isClass||$ignoreMissing){continue;}throw new InvalidLinkException("Missing parameter \$$name required by $class::{$rm->getName()}()");}if(!PresenterComponentReflection::convertType($args[$name],$type,$isClass)){throw new InvalidLinkException(sprintf('Argument $%s passed to %s() must be %s, %s given.',$name,$rm->getDeclaringClass()->getName().'::'.$rm->getName(),$type==='NULL'?'scalar':$type,is_object($args[$name])?get_class($args[$name]):gettype($args[$name])));}$def=$param->isDefaultValueAvailable()?$param->getDefaultValue():NULL;if($args[$name]===$def||($def===NULL&&is_scalar($args[$name])&&(string)$args[$name]==='')){$args[$name]=NULL;}}if(array_key_exists($i,$args)){throw new InvalidLinkException("Passed more parameters than method $class::{$rm->getName()}() expects.");}}/** @return string **/protected function handleInvalidLink(InvalidLinkException$e){if($this->invalidLinkMode&self::INVALID_LINK_EXCEPTION){throw$e;}elseif($this->invalidLinkMode&self::INVALID_LINK_WARNING){trigger_error('Invalid link: '.$e->getMessage(),E_USER_WARNING);}return$this->invalidLinkMode&self::INVALID_LINK_TEXTUAL?'#error: '.$e->getMessage():'#';}/** @return string key **/public function storeRequest($expiration='+ 10 minutes'){$session=$this->getSession('Nette.Application/requests');do{$key=Nette\Utils\Random::generate(5);}while(isset($session[$key]));$session[$key]=array($this->getUser()->getId(),$this->request);$session->setExpiration($expiration,$key);return$key;}/** @return void **/public function 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 Responses\ForwardResponse($request));}/** @return array **/public static function getPersistentComponents(){return(array)PresenterComponentReflection::parseAnnotation(new\ReflectionClass(get_called_class()),'persistent');}/** @return array **/protected function getGlobalState($forClass=NULL){$sinces=&$this->globalStateSinces;if($this->globalState===NULL){$state=array();foreach($this->globalParams as$id=>$params){$prefix=$id.self::NAME_SEPARATOR;foreach($params as$key=>$val){$state[$prefix.$key]=$val;}}$this->saveState($state,$forClass?new 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 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 as$key=>$val){$state[$prefix.$key]=$val;$sinces[$prefix.$key]=$since;}}}else{$state=$this->globalState;}if($forClass!==NULL){$since=NULL;foreach($state 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;}/** @return void **/protected function saveGlobalState(){$this->globalParams=array();$this->globalState=$this->getGlobalState();}/** @return void **/private function initGlobalParameters(){$this->globalParams=array();$selfParams=array();$params=$this->request->getParameters();if($this->isAjax()){$params+=$this->request->getPost();}if(($tmp=$this->request->getPost(self::SIGNAL_KEY))!==NULL){$params[self::SIGNAL_KEY]=$tmp;}foreach($params 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);}/** @return array **/public function popGlobalParameters($id){if(isset($this->globalParams[$id])){$res=$this->globalParams[$id];unset($this->globalParams[$id]);return$res;}else{return array();}}/** @return bool **/public function hasFlashSession(){return!empty($this->params[self::FLASH_KEY])&&$this->getSession()->hasSection('Nette.Application.Flash/'.$this->params[self::FLASH_KEY]);}/** @return Nette\Http\SessionSection **/public function getFlashSession(){if(empty($this->params[self::FLASH_KEY])){$this->params[self::FLASH_KEY]=Nette\Utils\Random::generate(4);}return$this->getSession('Nette.Application.Flash/'.$this->params[self::FLASH_KEY]);}public function injectPrimary(Nette\DI\Container$context=NULL,Application\IPresenterFactory$presenterFactory=NULL,Application\IRouter$router=NULL,Http\IRequest$httpRequest,Http\IResponse$httpResponse,Http\Session$session=NULL,Nette\Security\User$user=NULL,ITemplateFactory$templateFactory=NULL){if($this->presenterFactory!==NULL){throw new Nette\InvalidStateException('Method '.__METHOD__.' is intended for initialization and should not be called more than once.');}$this->context=$context;$this->presenterFactory=$presenterFactory;$this->router=$router;$this->httpRequest=$httpRequest;$this->httpResponse=$httpResponse;$this->session=$session;$this->user=$user;$this->templateFactory=$templateFactory;}/** @return Nette\DI\Container **/public function getContext(){if(!$this->context){throw new Nette\InvalidStateException('Context has not been set.');}return$this->context;}/** @return Nette\Http\IRequest **/protected function getHttpRequest(){return$this->httpRequest;}/** @return Nette\Http\IResponse **/protected function getHttpResponse(){return$this->httpResponse;}/** @return Nette\Http\Session|Nette\Http\SessionSection **/public function getSession($namespace=NULL){if(!$this->session){throw new Nette\InvalidStateException('Service Session has not been set.');}return$namespace===NULL?$this->session:$this->session->getSection($namespace);}/** @return Nette\Security\User **/public function getUser(){if(!$this->user){throw new Nette\InvalidStateException('Service User has not been set.');}return$this->user;}/** @return ITemplateFactory **/public function getTemplateFactory(){if(!$this->templateFactory){throw new Nette\InvalidStateException('Service TemplateFactory has not been set.');}return$this->templateFactory;}}lookup('Nette\Application\UI\Presenter',$need);}/** @return string **/public function getUniqueId(){return$this->lookupPath('Nette\Application\UI\Presenter',TRUE);}/** @return void **/protected function attached($presenter){if($presenter instanceof Presenter){$this->loadState($presenter->popGlobalParameters($this->getUniqueId()));}}/** @return void **/protected function validateParent(Nette\ComponentModel\IContainer$parent){parent::validateParent($parent);$this->monitor('Nette\Application\UI\Presenter');}/** @return bool does method exist? **/protected function 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 TRUE;}}return FALSE;}/** @return void **/public function checkRequirements($element){}/** @return PresenterComponentReflection **/public static function getReflection(){return new PresenterComponentReflection(get_called_class());}/** @return void **/public function loadState(array$params){$reflection=$this->getReflection();foreach($reflection->getPersistentParams()as$name=>$meta){if(isset($params[$name])){$type=gettype($meta['def']);if(!$reflection->convertType($params[$name],$type)){throw new Nette\Application\BadRequestException(sprintf("Value passed to persistent parameter '%s' in %s must be %s, %s given.",$name,$this instanceof Presenter?'presenter '.$this->getName():"component '{$this->getUniqueId()}'",$type==='NULL'?'scalar':$type,is_object($params[$name])?get_class($params[$name]):gettype($params[$name])));}$this->$name=$params[$name];}else{$params[$name]=$this->$name;}}$this->params=$params;}/** @return void **/public function 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 instanceof$meta['since'])&&isset($this->$name)){$params[$name]=$this->$name;}else{continue;}$type=gettype($meta['def']);if(!PresenterComponentReflection::convertType($params[$name],$type)){throw new InvalidLinkException(sprintf("Value passed to persistent parameter '%s' in %s must be %s, %s given.",$name,$this instanceof Presenter?'presenter '.$this->getName():"component '{$this->getUniqueId()}'",$type==='NULL'?'scalar':$type,is_object($params[$name])?get_class($params[$name]):gettype($params[$name])));}if($params[$name]===$meta['def']||($meta['def']===NULL&&is_scalar($params[$name])&&(string)$params[$name]==='')){$params[$name]=NULL;}}}/** @return mixed **/public function getParameter($name,$default=NULL){if(isset($this->params[$name])){return$this->params[$name];}else{return$default;}}/** @return array **/public function getParameters(){return$this->params;}/** @return string **/public function getParameterId($name){$uid=$this->getUniqueId();return$uid===''?$name:$uid.self::NAME_SEPARATOR.$name;}function getParam($name=NULL,$default=NULL){return func_num_args()?$this->getParameter($name,$default):$this->getParameters();}/** @return array **/public static function getPersistentParams(){$rc=new\ReflectionClass(get_called_class());$params=array();foreach($rc->getProperties(\ReflectionProperty::IS_PUBLIC)as$rp){if(!$rp->isStatic()&&PresenterComponentReflection::parseAnnotation($rp,'persistent')){$params[]=$rp->getName();}}return$params;}/** @return void **/public function signalReceived($signal){if(!$this->tryCall($this->formatSignalMethod($signal),$this->params)){$class=get_class($this);throw new BadSignalException("There is no handler for signal '$signal' in class $class.");}}/** @return string **/public static function formatSignalMethod($signal){return$signal==NULL?NULL:'handle'.$signal;}/** @return string **/public function link($destination,$args=array()){try{return$this->getPresenter()->createRequest($this,$destination,is_array($args)?$args:array_slice(func_get_args(),1),'link');}catch(InvalidLinkException$e){return$this->getPresenter()->handleInvalidLink($e);}}/** @return Link **/public function lazyLink($destination,$args=array()){return new Link($this,$destination,is_array($args)?$args:array_slice(func_get_args(),1));}/** @return bool **/public function isLinkCurrent($destination=NULL,$args=array()){if($destination!==NULL){$this->getPresenter()->createRequest($this,$destination,is_array($args)?$args:array_slice(func_get_args(),1),'test');}return$this->getPresenter()->getLastCreatedRequestFlag('current');}/** @return void **/public function redirect($code,$destination=NULL,$args=array()){if(!is_numeric($code)){$args=is_array($destination)?$destination:array_slice(func_get_args(),1);$destination=$code;$code=NULL;}elseif(!is_array($args)){$args=array_slice(func_get_args(),2);}$presenter=$this->getPresenter();$presenter->redirectUrl($presenter->createRequest($this,$destination,$args,'redirect'),$code);}/** @return void **/public function offsetSet($name,$component){$this->addComponent($component,$name);}/** @return Nette\ComponentModel\IComponent **/public function offsetGet($name){return$this->getComponent($name,TRUE);}/** @return bool **/public function offsetExists($name){return$this->getComponent($name,FALSE)!==NULL;}/** @return void **/public function offsetUnset($name){$component=$this->getComponent($name,FALSE);if($component!==NULL){$this->removeComponent($component);}}}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=>$default){if(is_int($name)){$name=$default;$default=$defaults[$name];}$params[$name]=array('def'=>$default,'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;}/** @return array of persistent components. **/public function 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;}/** @return bool **/public function hasCallableMethod($method){$class=$this->getName();$cache=&self::$mcCache[strtolower($class.':'.$method)];if($cache===NULL){try{$cache=FALSE;$rm=new\ReflectionMethod($class,$method);$cache=$this->isInstantiable()&&$rm->isPublic()&&!$rm->isAbstract()&&!$rm->isStatic();}catch(\ReflectionException$e){}}return$cache;}/** @return array **/public static function combineArgs(\ReflectionFunctionAbstract$method,$args){$res=array();foreach($method->getParameters()as$i=>$param){$name=$param->getName();list($type,$isClass)=self::getParameterType($param);if(isset($args[$name])){$res[$i]=$args[$name];if(!self::convertType($res[$i],$type,$isClass)){throw new BadRequestException(sprintf('Argument $%s passed to %s() must be %s, %s given.',$name,($method instanceof\ReflectionMethod?$method->getDeclaringClass()->getName().'::':'').$method->getName(),$type==='NULL'?'scalar':$type,is_object($args[$name])?get_class($args[$name]):gettype($args[$name])));}}elseif($param->isDefaultValueAvailable()){$res[$i]=$param->getDefaultValue();}elseif($type==='array'){$res[$i]=array();}elseif($type==='NULL'||$isClass){$res[$i]=NULL;}else{throw new BadRequestException(sprintf('Missing parameter $%s required by %s()',$name,($method instanceof\ReflectionMethod?$method->getDeclaringClass()->getName().'::':'').$method->getName()));}}return$res;}/** @return bool **/public static function convertType(&$val,$type,$isClass=FALSE){if($type==='callable'){return FALSE;}elseif($type==='NULL'||$isClass){return!is_array($val);}elseif(is_object($val)){}elseif($type==='array'){return is_array($val);}elseif(!is_scalar($val)){return FALSE;}else{$old=$tmp=($val===FALSE?'0':(string)$val);settype($tmp,$type);if($old!==($tmp===FALSE?'0':(string)$tmp)){return FALSE;}$val=$tmp;}return TRUE;}/** @return array|FALSE **/public static function parseAnnotation(\Reflector$ref,$name){if(!preg_match_all("#[\\s*]@$name(?:\(\\s*([^)]*)\\s*\))?#",$ref->getDocComment(),$m)){return FALSE;}$res=array();foreach($m[1]as$s){$arr=$s===''?array(TRUE):preg_split('#\s*,\s*#',$s,-1,PREG_SPLIT_NO_EMPTY);$res=array_merge($res,$arr);}return$res;}/** @return [string, bool] **/public static function getParameterType(\ReflectionParameter$param){$def=gettype($param->isDefaultValueAvailable()?$param->getDefaultValue():NULL);if(PHP_VERSION_ID>=70000){return array((string)$param->getType()?:$def,$param->hasType()&&!$param->getType()->isBuiltin());}elseif($param->isArray()){return array('array',FALSE);}elseif(PHP_VERSION_ID>=50400&&$param->isCallable()){return array('callable',FALSE);}else{try{return($ref=$param->getClass())?array($ref->getName(),TRUE):array($def,FALSE);}catch(\ReflectionException$e){if(preg_match('#Class (.+) does not exist#',$e->getMessage(),$m)){throw new\LogicException(sprintf("Class %s not found. Check type hint of parameter $%s in %s() or 'use' statements.",$m[1],$param->getName(),$param->getDeclaringFunction()->getDeclaringClass()->getName().'::'.$param->getDeclaringFunction()->getName()));}throw$e;}}}}'Nette\DI\Extensions\PhpExtension','constants'=>'Nette\DI\Extensions\ConstantsExtension','extensions'=>'Nette\DI\Extensions\ExtensionsExtension','application'=>array('Nette\Bridges\ApplicationDI\ApplicationExtension',array('%debugMode%',array('%appDir%'),'%tempDir%/cache')),'decorator'=>'Nette\DI\Extensions\DecoratorExtension','cache'=>array('Nette\Bridges\CacheDI\CacheExtension',array('%tempDir%')),'database'=>array('Nette\Bridges\DatabaseDI\DatabaseExtension',array('%debugMode%')),'di'=>array('Nette\DI\Extensions\DIExtension',array('%debugMode%')),'forms'=>'Nette\Bridges\FormsDI\FormsExtension','http'=>'Nette\Bridges\HttpDI\HttpExtension','latte'=>array('Nette\Bridges\ApplicationDI\LatteExtension',array('%tempDir%/cache/latte','%debugMode%')),'mail'=>'Nette\Bridges\MailDI\MailExtension','reflection'=>array('Nette\Bridges\ReflectionDI\ReflectionExtension',array('%debugMode%')),'routing'=>array('Nette\Bridges\ApplicationDI\RoutingExtension',array('%debugMode%')),'security'=>array('Nette\Bridges\SecurityDI\SecurityExtension',array('%debugMode%')),'session'=>array('Nette\Bridges\HttpDI\SessionExtension',array('%debugMode%')),'tracy'=>array('Tracy\Bridges\Nette\TracyExtension',array('%debugMode%')),'inject'=>'Nette\DI\Extensions\InjectExtension');public$autowireExcludedClasses=array('stdClass');protected$parameters;protected$services=array();protected$files=array();public function __construct(){$this->parameters=$this->getDefaultParameters();}/** @return self **/public function setDebugMode($value){if(is_string($value)||is_array($value)){$value=static::detectDebugMode($value);}elseif(!is_bool($value)){throw new Nette\InvalidArgumentException(sprintf('Value must be either a string, array, or boolean, %s given.',gettype($value)));}$this->parameters['debugMode']=$value;$this->parameters['productionMode']=!$this->parameters['debugMode'];$this->parameters['environment']=$this->parameters['debugMode']?'development':'production';return$this;}/** @return bool **/public function isDebugMode(){return$this->parameters['debugMode'];}/** @return self **/public function setTempDirectory($path){$this->parameters['tempDir']=$path;return$this;}/** @return self **/public function addParameters(array$params){$this->parameters=DI\Config\Helpers::merge($params,$this->parameters);return$this;}/** @return self **/public function addServices(array$services){$this->services=$services+$this->services;return$this;}/** @return array **/protected function getDefaultParameters(){$trace=debug_backtrace(PHP_VERSION_ID>=50306?DEBUG_BACKTRACE_IGNORE_ARGS:FALSE);$last=end($trace);$debugMode=static::detectDebugMode();return array('appDir'=>isset($trace[1]['file'])?dirname($trace[1]['file']):NULL,'wwwDir'=>isset($last['file'])?dirname($last['file']):NULL,'debugMode'=>$debugMode,'productionMode'=>!$debugMode,'environment'=>$debugMode?'development':'production','consoleMode'=>PHP_SAPI==='cli','container'=>array('class'=>NULL,'parent'=>NULL));}/** @return void **/public function enableDebugger($logDirectory=NULL,$email=NULL){Tracy\Debugger::$strictMode=TRUE;Tracy\Debugger::enable(!$this->parameters['debugMode'],$logDirectory,$email);Nette\Bridges\Framework\TracyBridge::initialize();}/** @return Nette\Loaders\RobotLoader **/public function createRobotLoader(){if(!class_exists('Nette\Loaders\RobotLoader')){throw new Nette\NotSupportedException('RobotLoader not found, do you have `nette/robot-loader` package installed?');}$loader=new Nette\Loaders\RobotLoader;$loader->setCacheStorage(new Nette\Caching\Storages\FileStorage($this->getCacheDirectory()));$loader->autoRebuild=$this->parameters['debugMode'];return$loader;}/** @return self **/public function addConfig($file,$section=NULL){if($section===NULL&&is_string($file)&&$this->parameters['debugMode']){try{$loader=new DI\Config\Loader;$loader->load($file,$this->parameters['environment']);trigger_error("Config file '$file' has sections, call addConfig() with second parameter Configurator::AUTO.",E_USER_WARNING);$section=$this->parameters['environment'];}catch(\Exception$e){}}$this->files[]=array($file,$section===self::AUTO?$this->parameters['environment']:$section);return$this;}/** @return DI\Container **/public function createContainer(){$loader=new DI\ContainerLoader($this->getCacheDirectory().'/Nette.Configurator',$this->parameters['debugMode']);$class=$loader->load(array($this->parameters,$this->files,PHP_VERSION_ID-PHP_RELEASE_VERSION),array($this,'generateContainer'));$container=new$class;foreach($this->services as$name=>$service){$container->addService($name,$service);}$container->initialize();if(class_exists('Nette\Environment')){Nette\Environment::setContext($container);}return$container;}/** @return string **/public function generateContainer(DI\Compiler$compiler){$loader=$this->createLoader();$compiler->addConfig(array('parameters'=>$this->parameters));$fileInfo=array();foreach($this->files as$info){if(is_scalar($info[0])){$fileInfo[]="// source: $info[0] $info[1]";$info[0]=$loader->load($info[0],$info[1]);}$compiler->addConfig($this->fixCompatibility($info[0]));}$compiler->addDependencies($loader->getDependencies());$builder=$compiler->getContainerBuilder();$builder->addExcludedClasses($this->autowireExcludedClasses);foreach($this->defaultExtensions as$name=>$extension){list($class,$args)=is_string($extension)?array($extension,array()):$extension;if(class_exists($class)){$rc=new\ReflectionClass($class);$args=DI\Helpers::expand($args,$this->parameters,TRUE);$compiler->addExtension($name,$args?$rc->newInstanceArgs($args):$rc->newInstance());}}$this->onCompile($this,$compiler);$classes=$compiler->compile();if(!empty($builder->parameters['container']['parent'])){$classes[0]->setExtends($builder->parameters['container']['parent']);}return implode("\n",$fileInfo)."\n\n".implode("\n\n\n",$classes).(($tmp=$builder->parameters['container']['class'])?"\nclass $tmp extends {$builder->getClassName()} {}\n":'');}/** @return DI\Config\Loader **/protected function createLoader(){return new DI\Config\Loader;}protected function getCacheDirectory(){if(empty($this->parameters['tempDir'])){throw new Nette\InvalidStateException('Set path to temporary directory using setTempDirectory().');}$dir=$this->parameters['tempDir'].'/cache';if(!is_dir($dir)){@mkdir($dir);}return$dir;}/** @return array **/protected function fixCompatibility($config){if(isset($config['nette']['security']['frames'])){$config['nette']['http']['frames']=$config['nette']['security']['frames'];unset($config['nette']['security']['frames']);}foreach(array('application','cache','database','di'=>'container','forms','http','latte','mail'=>'mailer','routing','security','session','tracy'=>'debugger')as$new=>$old){if(isset($config['nette'][$old])){$new=is_int($new)?$old:$new;if(isset($config[$new])){throw new Nette\DeprecatedException("You can use (deprecated) section 'nette.$old' or new section '$new', but not both of them.");}$config[$new]=$config['nette'][$old];unset($config['nette'][$old]);}}if(isset($config['nette']['xhtml'])){trigger_error("Configuration option 'nette.xhtml' is deprecated, use section 'latte.xhtml' instead.",E_USER_DEPRECATED);$config['latte']['xhtml']=$config['nette']['xhtml'];unset($config['nette']['xhtml']);}if(empty($config['nette'])){unset($config['nette']);}return$config;}/** @return bool **/public static function detectDebugMode($list=NULL){$addr=isset($_SERVER['REMOTE_ADDR'])?$_SERVER['REMOTE_ADDR']:php_uname('n');$secret=isset($_COOKIE[self::COOKIE_SECRET])&&is_string($_COOKIE[self::COOKIE_SECRET])?$_COOKIE[self::COOKIE_SECRET]: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 in_array($addr,$list,TRUE)||in_array("$secret@$addr",$list,TRUE);}}NULL,'errorPresenter'=>'Nette:Error','catchExceptions'=>NULL,'mapping'=>NULL,'scanDirs'=>array(),'scanComposer'=>NULL,'scanFilter'=>'Presenter','silentLinks'=>FALSE);private$debugMode;private$invalidLinkMode;private$tempFile;public function __construct($debugMode=FALSE,array$scanDirs=NULL,$tempDir=NULL){$this->defaults['debugger']=interface_exists('Tracy\IBarPanel');$this->defaults['scanDirs']=(array)$scanDirs;$this->defaults['scanComposer']=class_exists('Composer\Autoload\ClassLoader');$this->defaults['catchExceptions']=!$debugMode;$this->debugMode=$debugMode;$this->tempFile=$tempDir?$tempDir.'/'.urlencode(__CLASS__):NULL;}public function loadConfiguration(){$config=$this->validateConfig($this->defaults);$container=$this->getContainerBuilder();$container->addExcludedClasses(array('Nette\Application\UI\Control'));$this->invalidLinkMode=$this->debugMode?UI\Presenter::INVALID_LINK_TEXTUAL|($config['silentLinks']?0:UI\Presenter::INVALID_LINK_WARNING):UI\Presenter::INVALID_LINK_WARNING;$application=$container->addDefinition($this->prefix('application'))->setClass('Nette\Application\Application')->addSetup('$catchExceptions',array($config['catchExceptions']))->addSetup('$errorPresenter',array($config['errorPresenter']));if($config['debugger']){$application->addSetup('Nette\Bridges\ApplicationTracy\RoutingPanel::initializePanel');}$touch=$this->debugMode&&$config['scanDirs']?$this->tempFile:NULL;$presenterFactory=$container->addDefinition($this->prefix('presenterFactory'))->setClass('Nette\Application\IPresenterFactory')->setFactory('Nette\Application\PresenterFactory',array(new Nette\DI\Statement('Nette\Bridges\ApplicationDI\PresenterFactoryCallback',array(1=>$this->invalidLinkMode,$touch))));if($config['mapping']){$presenterFactory->addSetup('setMapping',array($config['mapping']));}$container->addDefinition($this->prefix('linkGenerator'))->setFactory('Nette\Application\LinkGenerator',array(1=>new Nette\DI\Statement('@Nette\Http\IRequest::getUrl')));if($this->name==='application'){$container->addAlias('application',$this->prefix('application'));$container->addAlias('nette.presenterFactory',$this->prefix('presenterFactory'));}}public function beforeCompile(){$container=$this->getContainerBuilder();$all=array();foreach($container->findByType('Nette\Application\IPresenter')as$def){$all[$def->getClass()]=$def;}$counter=0;foreach($this->findPresenters()as$class){if(empty($all[$class])){$all[$class]=$container->addDefinition($this->prefix(++$counter))->setClass($class);}}foreach($all as$def){$def->setInject(TRUE)->setAutowired(FALSE)->addTag('nette.presenter',$def->getClass());if(is_subclass_of($def->getClass(),'Nette\Application\UI\Presenter')){$def->addSetup('$invalidLinkMode',array($this->invalidLinkMode));}}}/** @return string[] **/private function findPresenters(){$config=$this->getConfig();$classes=array();if($config['scanDirs']){if(!class_exists('Nette\Loaders\RobotLoader')){throw new Nette\NotSupportedException("RobotLoader is required to find presenters, install package `nette/robot-loader` or disable option {$this->prefix('scanDirs')}: false");}$robot=new Nette\Loaders\RobotLoader;$robot->setCacheStorage(new Nette\Caching\Storages\DevNullStorage);$robot->addDirectory($config['scanDirs']);$robot->acceptFiles='*'.$config['scanFilter'].'*.php';$robot->rebuild();$classes=array_keys($robot->getIndexedClasses());$this->getContainerBuilder()->addDependency($this->tempFile);}if($config['scanComposer']){$rc=new\ReflectionClass('Composer\Autoload\ClassLoader');$classFile=dirname($rc->getFileName()).'/autoload_classmap.php';if(is_file($classFile)){$this->getContainerBuilder()->addDependency($classFile);$classes=array_merge($classes,array_keys(call_user_func(function($path){return require$path;},$classFile)));}}$presenters=array();foreach(array_unique($classes)as$class){if(strpos($class,$config['scanFilter'])!==FALSE&&class_exists($class)&&($rc=new\ReflectionClass($class))&&$rc->implementsInterface('Nette\Application\IPresenter')&&!$rc->isAbstract()){$presenters[]=$rc->getName();}}return$presenters;}}FALSE,'macros'=>array());private$debugMode;private$tempDir;public function __construct($tempDir,$debugMode=FALSE){$this->tempDir=$tempDir;$this->debugMode=$debugMode;}public function loadConfiguration(){if(!class_exists('Latte\Engine')){return;}$config=$this->validateConfig($this->defaults);$container=$this->getContainerBuilder();$latteFactory=$container->addDefinition($this->prefix('latteFactory'))->setClass('Latte\Engine')->addSetup('setTempDirectory',array($this->tempDir))->addSetup('setAutoRefresh',array($this->debugMode))->addSetup('setContentType',array($config['xhtml']?Latte\Compiler::CONTENT_XHTML:Latte\Compiler::CONTENT_HTML))->addSetup('Nette\Utils\Html::$xhtml = ?',array((bool)$config['xhtml']))->setImplement('Nette\Bridges\ApplicationLatte\ILatteFactory');$container->addDefinition($this->prefix('templateFactory'))->setClass('Nette\Application\UI\ITemplateFactory')->setFactory('Nette\Bridges\ApplicationLatte\TemplateFactory');$container->addDefinition('nette.latte')->setClass('Latte\Engine')->addSetup('::trigger_error',array('Service nette.latte is deprecated, implement Nette\Bridges\ApplicationLatte\ILatteFactory.',E_USER_DEPRECATED))->addSetup('setTempDirectory',array($this->tempDir))->addSetup('setAutoRefresh',array($this->debugMode))->addSetup('setContentType',array($config['xhtml']?Latte\Compiler::CONTENT_XHTML:Latte\Compiler::CONTENT_HTML))->addSetup('Nette\Utils\Html::$xhtml = ?',array((bool)$config['xhtml']))->setAutowired(FALSE);foreach($config['macros']as$macro){if(strpos($macro,'::')===FALSE&&class_exists($macro)){$macro.='::install';}$this->addMacro($macro);}if(class_exists('Nette\Templating\FileTemplate')){$container->addDefinition('nette.template')->setFactory('Nette\Templating\FileTemplate')->addSetup('::trigger_error',array('Service nette.template is deprecated.',E_USER_DEPRECATED))->addSetup('registerFilter',array(new Nette\DI\Statement(array($latteFactory,'create'))))->addSetup('registerHelperLoader',array('Nette\Templating\Helpers::loader'))->setAutowired(FALSE);}if($this->name==='latte'){$container->addAlias('nette.latteFactory',$this->prefix('latteFactory'));$container->addAlias('nette.templateFactory',$this->prefix('templateFactory'));}}/** @return void **/public function addMacro($macro){Nette\Utils\Validators::assert($macro,'callable');$container=$this->getContainerBuilder();$container->getDefinition('nette.latte')->addSetup('?->onCompile[] = function ($engine) { '.$macro.'($engine->getCompiler()); }',array('@self'));$container->getDefinition($this->prefix('latteFactory'))->addSetup('?->onCompile[] = function ($engine) { '.$macro.'($engine->getCompiler()); }',array('@self'));}}container=$container;$this->invalidLinkMode=$invalidLinkMode;$this->touchToRefresh=$touchToRefresh;}/** @return Nette\Application\IPresenter **/public function __invoke($class){$services=array_keys($this->container->findByTag('nette.presenter'),$class);if(count($services)>1){throw new Nette\Application\InvalidPresenterException("Multiple services of type $class found: ".implode(', ',$services).'.');}elseif(!$services){if($this->touchToRefresh){touch($this->touchToRefresh);}$presenter=$this->container->createInstance($class);$this->container->callInjects($presenter);if($presenter instanceof Nette\Application\UI\Presenter&&$presenter->invalidLinkMode===NULL){$presenter->invalidLinkMode=$this->invalidLinkMode;}return$presenter;}return$this->container->createService($services[0]);}}NULL,'routes'=>array(),'cache'=>FALSE);private$debugMode;public function __construct($debugMode=FALSE){$this->defaults['debugger']=interface_exists('Tracy\IBarPanel');$this->debugMode=$debugMode;}public function loadConfiguration(){$config=$this->validateConfig($this->defaults);$container=$this->getContainerBuilder();$router=$container->addDefinition($this->prefix('router'))->setClass('Nette\Application\IRouter')->setFactory('Nette\Application\Routers\RouteList');foreach($config['routes']as$mask=>$action){$router->addSetup('$service[] = new Nette\Application\Routers\Route(?, ?);',array($mask,$action));}if($this->name==='routing'){$container->addAlias('router',$this->prefix('router'));}}public function beforeCompile(){$container=$this->getContainerBuilder();if($this->debugMode&&$this->config['debugger']&&$application=$container->getByType('Nette\Application\Application')){$container->getDefinition($application)->addSetup('@Tracy\Bar::addPanel',array(new Nette\DI\Statement('Nette\Bridges\ApplicationTracy\RoutingPanel')));}}public function afterCompile(Nette\PhpGenerator\ClassType$class){if(!empty($this->config['cache'])){$method=$class->getMethod(Nette\DI\Container::getMethodName($this->prefix('router')));try{$router=eval($method->getBody());if($router instanceof Nette\Application\Routers\RouteList){$router->warmupCache();}$s=serialize($router);}catch(\Throwable$e){throw new Nette\DI\ServiceCreationException('Unable to cache router due to error: '.$e->getMessage(),0,$e);}catch(\Exception$e){throw new Nette\DI\ServiceCreationException('Unable to cache router due to error: '.$e->getMessage(),0,$e);}$method->setBody('return unserialize(?);',array($s));}}}presenter=$presenter;}}latte=$latte;}/** @return Latte\Engine **/public function getLatte(){return$this->latte;}/** @return void **/public function render($file=NULL,array$params=array()){$this->latte->render($file?:$this->file,$params+$this->params);}/** @return string **/public function __toString(){try{return$this->latte->renderToString($this->file,$this->params);}catch(\Throwable$e){}catch(\Exception$e){}if(isset($e)){if(func_num_args()){throw$e;}trigger_error("Exception in ".__METHOD__."(): {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}",E_USER_ERROR);}}/** @return self **/public function addFilter($name,$callback){return$this->latte->addFilter($name,$callback);}public function registerHelper($name,$callback){return$this->latte->addFilter($name,$callback);}public function registerHelperLoader($loader){trigger_error(__METHOD__.'() is deprecated, use dynamic getLatte()->addFilter().',E_USER_DEPRECATED);$latte=$this->latte;$this->latte->addFilter(NULL,function($name)use($loader,$latte){if($callback=call_user_func($loader,$name)){$latte->addFilter($name,$callback);}});return$this;}/** @return self **/public function setTranslator(Nette\Localization\ITranslator$translator=NULL){$this->latte->addFilter('translate',$translator===NULL?NULL:array($translator,'translate'));return$this;}public function registerFilter($callback){throw new Nette\DeprecatedException(__METHOD__.'() is deprecated.');}/** @return self **/public function setFile($file){$this->file=$file;return$this;}/** @return string **/public function getFile(){return$this->file;}/** @return self **/public function add($name,$value){if(array_key_exists($name,$this->params)){throw new Nette\InvalidStateException("The variable '$name' already exists.");}$this->params[$name]=$value;return$this;}/** @return self **/public function setParameters(array$params){$this->params=$params+$this->params;return$this;}/** @return array **/public function getParameters(){return$this->params;}public function __call($name,$args){trigger_error('Invoking filters on Template object is deprecated, use getLatte()->invokeFilter().',E_USER_DEPRECATED);return$this->latte->invokeFilter($name,$args);}/** @return void **/public function __set($name,$value){$this->params[$name]=$value;}/** @return mixed value **/public function&__get($name){if(!array_key_exists($name,$this->params)){trigger_error("The variable '$name' does not exist in template.",E_USER_NOTICE);}return$this->params[$name];}/** @return bool **/public function __isset($name){return isset($this->params[$name]);}/** @return void **/public function __unset($name){unset($this->params[$name]);}}latteFactory=$latteFactory;$this->httpRequest=$httpRequest;$this->httpResponse=$httpResponse;$this->user=$user;$this->cacheStorage=$cacheStorage;}/** @return Template **/public function createTemplate(UI\Control$control=NULL){$latte=$this->latteFactory->create();$template=new Template($latte);$presenter=$control?$control->getPresenter(FALSE):NULL;if($control instanceof UI\Presenter){$latte->setLoader(new Loader($control));}if($latte->onCompile instanceof\Traversable){$latte->onCompile=iterator_to_array($latte->onCompile);}array_unshift($latte->onCompile,function($latte)use($control,$template){$latte->getParser()->shortNoEscape=TRUE;$latte->getCompiler()->addMacro('cache',new Nette\Bridges\CacheLatte\CacheMacro($latte->getCompiler()));UIMacros::install($latte->getCompiler());if(class_exists('Nette\Bridges\FormsLatte\FormMacros')){Nette\Bridges\FormsLatte\FormMacros::install($latte->getCompiler());}if($control){$control->templatePrepareFilters($template);}});$latte->addFilter('url','rawurlencode');foreach(array('normalize','toAscii','webalize','padLeft','padRight','reverse')as$name){$latte->addFilter($name,'Nette\Utils\Strings::'.$name);}$latte->addFilter('null',function(){});$latte->addFilter('length',function($var){return is_string($var)?Nette\Utils\Strings::length($var):count($var);});$latte->addFilter('modifyDate',function($time,$delta,$unit=NULL){return$time==NULL?NULL:Nette\Utils\DateTime::from($time)->modify($delta.$unit);});if(!array_key_exists('translate',$latte->getFilters())){$latte->addFilter('translate',function(){throw new Nette\InvalidStateException('Translator has not been set. Set translator using $template->setTranslator().');});}$template->control=$template->_control=$control;$template->presenter=$template->_presenter=$presenter;$template->user=$this->user;$template->netteHttpResponse=$this->httpResponse;$template->netteCacheStorage=$this->cacheStorage;$template->baseUri=$template->baseUrl=$this->httpRequest?rtrim($this->httpRequest->getUrl()->getBaseUrl(),'/'):NULL;$template->basePath=preg_replace('#https?://[^/]+#A','',$template->baseUrl);$template->flashes=array();if($presenter instanceof UI\Presenter&&$presenter->hasFlashSession()){$id=$control->getParameterId('flash');$template->flashes=(array)$presenter->getFlashSession()->$id;}return$template;}}addMacro('control',array($me,'macroControl'));$me->addMacro('href',NULL,NULL,function(MacroNode$node,PhpWriter$writer)use($me){return' ?> href="macroLink($node,$writer).' ?>"addMacro('plink',array($me,'macroLink'));$me->addMacro('link',array($me,'macroLink'));$me->addMacro('ifCurrent',array($me,'macroIfCurrent'),'}');}/** @return array(prolog, epilog) **/public function finalize(){$prolog=' // snippets support if (empty($_l->extends) && !empty($_control->snippetMode)) { return Nette\Bridges\ApplicationLatte\UIRuntime::renderSnippets($_control, $_b, get_defined_vars()); }';return array($prolog,'');}public function macroControl(MacroNode$node,PhpWriter$writer){$words=$node->tokenizer->fetchWords();if(!$words){throw new CompileException('Missing control name in {control}');}$name=$writer->formatWord($words[0]);$method=isset($words[1])?ucfirst($words[1]):'';$method=Strings::match($method,'#^\w*\z#')?"render$method":"{\"render$method\"}";$param=$writer->formatArray();if(!Strings::contains($node->args,'=>')){$param=substr($param,$param[0]==='['?1:6,-1);}return($name[0]==='$'?"if (is_object($name)) \$_l->tmp = $name; else ":'').'$_l->tmp = $_control->getComponent('.$name.'); '.'if ($_l->tmp instanceof Nette\Application\UI\IRenderable) $_l->tmp->redrawControl(NULL, FALSE); '.($node->modifiers===''?"\$_l->tmp->$method($param)":$writer->write("ob_start(function () {}); \$_l->tmp->$method($param); echo %modify(ob_get_clean())"));}public function macroLink(MacroNode$node,PhpWriter$writer){$node->modifiers=preg_replace('#\|safeurl\s*(?=\||\z)#i','',$node->modifiers);return$writer->using($node,$this->getCompiler())->write('echo %escape(%modify('.($node->name==='plink'?'$_presenter':'$_control').'->link(%node.word, %node.array?)))');}public function macroIfCurrent(MacroNode$node,PhpWriter$writer){if($node->modifiers){trigger_error("Modifiers are not allowed in {{$node->name}}",E_USER_WARNING);}return$writer->write($node->args?'if ($_presenter->isLinkCurrent(%node.word, %node.array?)) {':'if ($_presenter->getLastCreatedRequestFlag("current")) {');}public static function renderSnippets(Nette\Application\UI\Control$control,\stdClass$local,array$params){UIRuntime::renderSnippets($control,$local,$params);}}snippetMode=FALSE;$payload=$control->getPresenter()->getPayload();if(isset($local->blocks)){foreach($local->blocks as$name=>$function){if($name[0]!=='_'||!$control->isControlInvalid((string)substr($name,1))){continue;}ob_start(function(){});$function=reset($function);$snippets=$function($local,$params+array('_snippetMode'=>TRUE));$payload->snippets[$id=$control->getSnippetId((string)substr($name,1))]=ob_get_clean();if($snippets!==NULL){if($snippets){$payload->snippets+=$snippets;}unset($payload->snippets[$id]);}}}$control->snippetMode=TRUE;if($control instanceof UI\IRenderable){$queue=array($control);do{foreach(array_shift($queue)->getComponents()as$child){if($child instanceof UI\IRenderable){if($child->isControlInvalid()){$child->snippetMode=TRUE;$child->render();$child->snippetMode=FALSE;}}elseif($child instanceof Nette\ComponentModel\IContainer){$queue[]=$child;}}}while($queue);}}}addPanel(function($e)use($application){return$e?NULL:array('tab'=>'Nette Application','panel'=>'

Requests

'.Dumper::toHtml($application->getRequests(),array(Dumper::LIVE=>TRUE)).'

Presenter

'.Dumper::toHtml($application->getPresenter(),array(Dumper::LIVE=>TRUE)));});}public function __construct(Nette\Application\IRouter$router,Nette\Http\IRequest$httpRequest,Nette\Application\IPresenterFactory$presenterFactory){$this->router=$router;$this->httpRequest=$httpRequest;$this->presenterFactory=$presenterFactory;}/** @return string **/public function getTab(){$this->analyse($this->router);ob_start(function(){});$request=$this->request;require __DIR__.'/templates/RoutingPanel.tab.phtml';return ob_get_clean();}/** @return string **/public function getPanel(){ob_start(function(){});$request=$this->request;$routers=$this->routers;$source=$this->source;$hasModule=(bool)array_filter($routers,function($rq){return$rq['module'];});$url=$this->httpRequest->getUrl();$method=$this->httpRequest->getMethod();require __DIR__.'/templates/RoutingPanel.panel.phtml';return ob_get_clean();}/** @return void **/private function analyse($router,$module=''){if($router instanceof Routers\RouteList){foreach($router 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;$this->findSource();$matched='yes';}}$this->routers[]=array('matched'=>$matched,'class'=>get_class($router),'defaults'=>$router instanceof Routers\Route||$router instanceof Routers\SimpleRouter?$router->getDefaults():array(),'mask'=>$router instanceof Routers\Route?$router->getMask():NULL,'request'=>$request,'module'=>rtrim($module,':'));}private function findSource(){$request=$this->request;$presenter=$request->getPresenterName();try{$class=$this->presenterFactory->getPresenterClass($presenter);}catch(Nette\Application\InvalidPresenterException$e){return;}$rc=new\ReflectionClass($class);if($rc->isSubclassOf('Nette\Application\UI\Presenter')){if($request->getParameter(Presenter::SIGNAL_KEY)){$method=$class::formatSignalMethod($request->getParameter(Presenter::SIGNAL_KEY));}elseif($request->getParameter(Presenter::ACTION_KEY)){$action=$request->getParameter(Presenter::ACTION_KEY);$method=$class::formatActionMethod($action);if(!$rc->hasMethod($method)){$method=$class::formatRenderMethod($action);}}}$this->source=isset($method)&&$rc->hasMethod($method)?$rc->getMethod($method):$rc;}}

no route getPresenterName().':'.(isset($request->parameters[Presenter::ACTION_KEY])?$request->parameters[Presenter::ACTION_KEY]:Presenter::DEFAULT_ACTION).(isset($request->parameters[Presenter::SIGNAL_KEY])?" {$request->parameters[Presenter::SIGNAL_KEY]}!":''),ENT_NOQUOTES,'UTF-8')?>

No routers defined.

Mask / Class Defaults Module Matched as
$value):?> ':Dumper::toHtml($value,array(Dumper::COLLAPSE=>TRUE,Dumper::LIVE=>TRUE))?> getParameters();?> getPresenterName().':'.(isset($params[Presenter::ACTION_KEY])?$params[Presenter::ACTION_KEY]:Presenter::DEFAULT_ACTION),ENT_NOQUOTES,'UTF-8')?>
$value):?> ':Dumper::toHtml($value,array(Dumper::COLLAPSE=>TRUE,Dumper::LIVE=>TRUE))?>

getBaseUrl(),ENT_IGNORE,'UTF-8')?>getRelativeUrl(),ENT_IGNORE,'UTF-8')?>

getName():$source->getDeclaringClass()->getName().'::'.$source->getName().'()'?>

no routegetPresenterName().':'.(isset($request->parameters[Presenter::ACTION_KEY])?$request->parameters[Presenter::ACTION_KEY]:Presenter::DEFAULT_ACTION).(isset($request->parameters[Presenter::SIGNAL_KEY])?" {$request->parameters[Presenter::SIGNAL_KEY]}!":''),ENT_NOQUOTES,'UTF-8');endif?> tempDir=$tempDir;}public function loadConfiguration(){$container=$this->getContainerBuilder();$container->addDefinition($this->prefix('journal'))->setClass('Nette\Caching\Storages\IJournal')->setFactory('Nette\Caching\Storages\FileJournal',array($this->tempDir));$container->addDefinition($this->prefix('storage'))->setClass('Nette\Caching\IStorage')->setFactory('Nette\Caching\Storages\FileStorage',array($this->tempDir.'/cache'));if($this->name==='cache'){$container->addAlias('nette.cacheJournal',$this->prefix('journal'));$container->addAlias('cacheStorage',$this->prefix('storage'));}}public function afterCompile(Nette\PhpGenerator\ClassType$class){if(!$this->checkTempDir($this->tempDir.'/cache')){$class->getMethod('initialize')->addBody('Nette\Caching\Storages\FileStorage::$useDirectories = FALSE;');}}private function checkTempDir($dir){@mkdir($dir);$uniq=uniqid('_',TRUE);if(!@mkdir("$dir/$uniq")){throw new Nette\InvalidStateException("Unable to write to directory '$dir'. Make this directory writable.");}$isWritable=@file_put_contents("$dir/$uniq/_",'')!==FALSE;if($isWritable){unlink("$dir/$uniq/_");}rmdir("$dir/$uniq");return$isWritable;}}used=FALSE;}/** @return array(prolog, epilog) **/public function finalize(){if($this->used){return array('Nette\Bridges\CacheLatte\CacheMacro::initRuntime($template, $_g);');}}/** @return bool **/public function nodeOpened(Latte\MacroNode$node){if($node->modifiers){trigger_error("Modifiers are not allowed in {{$node->name}}",E_USER_WARNING);}$this->used=TRUE;$node->isEmpty=FALSE;$node->openingCode=Latte\PhpWriter::using($node)->write('caches, %node.array?)) { ?>',Nette\Utils\Random::generate());}/** @return void **/public function nodeClosed(Latte\MacroNode$node){$node->closingCode='tmp = array_pop($_g->caches); if (!$_l->tmp instanceof stdClass) $_l->tmp->end(); } ?>';}/** @return void **/public static function initRuntime(Latte\Template$template,\stdClass$global){if(!empty($global->caches)&&$template->getEngine()->getLoader()instanceof Latte\Loaders\FileLoader){end($global->caches)->dependencies[Nette\Caching\Cache::FILES][]=$template->getName();}}/** @return Nette\Caching\OutputHelper **/public static function 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 Nette\Caching\Cache($cacheStorage,'Nette.Templating.Cache');if($helper=$cache->start($key)){if(isset($args['dependencies'])){$args+=call_user_func($args['dependencies']);}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;}}NULL,'user'=>NULL,'password'=>NULL,'options'=>NULL,'debugger'=>TRUE,'explain'=>TRUE,'reflection'=>NULL,'conventions'=>'discovered','autowired'=>NULL);private$debugMode;public function __construct($debugMode=FALSE){$this->debugMode=$debugMode;}public function loadConfiguration(){$configs=$this->getConfig();if(isset($configs['dsn'])){$configs=array('default'=>$configs);}$defaults=$this->databaseDefaults;$defaults['autowired']=TRUE;foreach((array)$configs as$name=>$config){if(!is_array($config)){continue;}$config=$this->validateConfig($defaults,$config,$this->prefix($name));$defaults['autowired']=FALSE;$this->setupDatabase($config,$name);}}private function setupDatabase($config,$name){$container=$this->getContainerBuilder();foreach((array)$config['options']as$key=>$value){if(preg_match('#^PDO::\w+\z#',$key)){unset($config['options'][$key]);$config['options'][constant($key)]=$value;}}$connection=$container->addDefinition($this->prefix("$name.connection"))->setClass('Nette\Database\Connection',array($config['dsn'],$config['user'],$config['password'],$config['options']))->setAutowired($config['autowired']);$structure=$container->addDefinition($this->prefix("$name.structure"))->setClass('Nette\Database\Structure')->setArguments(array($connection))->setAutowired($config['autowired']);if(!empty($config['reflection'])){$conventionsServiceName='reflection';$config['conventions']=$config['reflection'];if(strtolower($config['conventions'])==='conventional'){$config['conventions']='Static';}}else{$conventionsServiceName='conventions';}if(!$config['conventions']){$conventions=NULL;}elseif(is_string($config['conventions'])){$conventions=$container->addDefinition($this->prefix("$name.$conventionsServiceName"))->setClass(preg_match('#^[a-z]+\z#i',$config['conventions'])?'Nette\Database\Conventions\\'.ucfirst($config['conventions']).'Conventions':$config['conventions'])->setArguments(strtolower($config['conventions'])==='discovered'?array($structure):array())->setAutowired($config['autowired']);}else{$tmp=Nette\DI\Compiler::filterArguments(array($config['conventions']));$conventions=reset($tmp);}$container->addDefinition($this->prefix("$name.context"))->setClass('Nette\Database\Context',array($connection,$structure,$conventions))->setAutowired($config['autowired']);if($config['debugger']){$connection->addSetup('@Tracy\BlueScreen::addPanel',array('Nette\Bridges\DatabaseTracy\ConnectionPanel::renderException'));if($this->debugMode){$connection->addSetup('Nette\Database\Helpers::createDebugPanel',array($connection,!empty($config['explain']),$name));}}if($this->name==='database'){$container->addAlias($this->prefix($name),$this->prefix("$name.connection"));$container->addAlias("nette.database.$name",$this->prefix($name));$container->addAlias("nette.database.$name.context",$this->prefix("$name.context"));}}}onQuery[]=array($this,'logQuery');}public function logQuery(Nette\Database\Connection$connection,$result){if($this->disabled){return;}$this->count++;$source=NULL;$trace=$result instanceof\PDOException?$result->getTrace():debug_backtrace(PHP_VERSION_ID>=50306?DEBUG_BACKTRACE_IGNORE_ARGS:FALSE);foreach($trace as$row){if(isset($row['file'])&&is_file($row['file'])&&!Tracy\Debugger::getBluescreen()->isCollapsed($row['file'])){if((isset($row['function'])&&strpos($row['function'],'call_user_func')===0)||(isset($row['class'])&&is_subclass_of($row['class'],'\\Nette\\Database\\Connection'))){continue;}$source=array($row['file'],(int)$row['line']);break;}}if($result instanceof Nette\Database\ResultSet){$this->totalTime+=$result->getTime();if($this->count<$this->maxQueries){$this->queries[]=array($connection,$result->getQueryString(),$result->getParameters(),$source,$result->getTime(),$result->getRowCount(),NULL);}}elseif($result instanceof\PDOException&&$this->count<$this->maxQueries){$this->queries[]=array($connection,$result->queryString,NULL,$source,NULL,NULL,$result->getMessage());}}public static function renderException($e){if(!$e instanceof\PDOException){return;}if(isset($e->queryString)){$sql=$e->queryString;}elseif($item=Tracy\Helpers::findTrace($e->getTrace(),'PDO::prepare')){$sql=$item['args'][0];}return isset($sql)?array('tab'=>'SQL','panel'=>Helpers::dumpSql($sql)):NULL;}public function getTab(){$name=$this->name;$count=$this->count;$totalTime=$this->totalTime;ob_start(function(){});require __DIR__.'/templates/ConnectionPanel.tab.phtml';return ob_get_clean();}public function getPanel(){$this->disabled=TRUE;if(!$this->count){return;}$name=$this->name;$count=$this->count;$totalTime=$this->totalTime;$queries=array();foreach($this->queries as$query){list($connection,$sql,$params,$source,$time,$rows,$error)=$query;$explain=NULL;if(!$error&&$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){}}$query[]=$explain;$queries[]=$query;}ob_start(function(){});require __DIR__.'/templates/ConnectionPanel.panel.phtml';return ob_get_clean();}}

Queries:

Time msSQL QueryRows
ERROR
explain
$foo):?>

...and more

container=$container;$this->elapsedTime=self::$compilationTime?microtime(TRUE)-self::$compilationTime:NULL;}/** @return string **/public function getTab(){ob_start(function(){});$elapsedTime=$this->elapsedTime;require __DIR__.'/templates/ContainerPanel.tab.phtml';return ob_get_clean();}/** @return string **/public function getPanel(){$container=$this->container;$registry=$this->getContainerProperty('registry');$rc=new\ReflectionClass($container);$file=$rc->getFileName();$tags=array();$meta=$this->getContainerProperty('meta');$services=$meta[Container::SERVICES];ksort($services);if(isset($meta[Container::TAGS])){foreach($meta[Container::TAGS]as$tag=>$tmp){foreach($tmp as$service=>$val){$tags[$service][$tag]=$val;}}}ob_start(function(){});require __DIR__.'/templates/ContainerPanel.panel.phtml';return ob_get_clean();}private function getContainerProperty($name){$rc=new\ReflectionClass('Nette\DI\Container');$prop=$rc->getProperty($name);$prop->setAccessible(TRUE);return$prop->getValue($this->container);}}

Services

$class):?>
Name Autowired Service Tags
TRUE,Dumper::LIVE=>TRUE));?> TRUE));}?>

Parameters

parameters);?>

Source:

array());public function afterCompile(Nette\PhpGenerator\ClassType$class){$initialize=$class->getMethod('initialize');$config=$this->validateConfig($this->defaults);foreach((array)$config['messages']as$name=>$text){if(defined('Nette\Forms\Form::'.$name)){$initialize->addBody('Nette\Forms\Validator::$messages[Nette\Forms\Form::?] = ?;',array($name,$text));}elseif(defined($name)){$initialize->addBody('Nette\Forms\Validator::$messages['.$name.'] = ?;',array($text));}else{throw new Nette\InvalidArgumentException('Constant Nette\Forms\Form::'.$name.' or constant '.$name.' does not exist.');}}}}addMacro('form',array($me,'macroForm'),'echo Nette\Bridges\FormsLatte\Runtime::renderFormEnd($_form)');$me->addMacro('formContainer',array($me,'macroFormContainer'),'$formContainer = $_form = array_pop($_formStack)');$me->addMacro('label',array($me,'macroLabel'),array($me,'macroLabelEnd'));$me->addMacro('input',array($me,'macroInput'),NULL,array($me,'macroInputAttr'));$me->addMacro('name',array($me,'macroName'),array($me,'macroNameEnd'),array($me,'macroNameAttr'));$me->addMacro('inputError',array($me,'macroInputError'));}public function macroForm(MacroNode$node,PhpWriter$writer){if($node->modifiers){trigger_error("Modifiers are not allowed in {{$node->name}}",E_USER_WARNING);}if($node->prefix){throw new CompileException('Did you mean
?');}$name=$node->tokenizer->fetchWord();if($name===FALSE){throw new CompileException("Missing form name in {{$node->name}}.");}$node->tokenizer->reset();return$writer->write('echo Nette\Bridges\FormsLatte\Runtime::renderFormBegin($form = $_form = '.($name[0]==='$'?'is_object(%node.word) ? %node.word : ':'').'$_control[%node.word], %node.array)');}public function macroFormContainer(MacroNode$node,PhpWriter$writer){if($node->modifiers){trigger_error("Modifiers are not allowed in {{$node->name}}",E_USER_WARNING);}$name=$node->tokenizer->fetchWord();if($name===FALSE){throw new CompileException("Missing name in {{$node->name}}.");}$node->tokenizer->reset();return$writer->write('$_formStack[] = $_form; $formContainer = $_form = '.($name[0]==='$'?'is_object(%node.word) ? %node.word : ':'').'$_form[%node.word]');}public function macroLabel(MacroNode$node,PhpWriter$writer){if($node->modifiers){trigger_error("Modifiers are not allowed in {{$node->name}}",E_USER_WARNING);}$words=$node->tokenizer->fetchWords();if(!$words){throw new CompileException("Missing name in {{$node->name}}.");}$name=array_shift($words);return$writer->write(($name[0]==='$'?'$_input = is_object(%0.word) ? %0.word : $_form[%0.word]; if ($_label = $_input':'if ($_label = $_form[%0.word]').'->%1.raw) echo $_label'.($node->tokenizer->isNext()?'->addAttributes(%node.array)':''),$name,$words?('getLabelPart('.implode(', ',array_map(array($writer,'formatWord'),$words)).')'):'getLabel()');}public function macroLabelEnd(MacroNode$node,PhpWriter$writer){if($node->content!=NULL){$node->openingCode=rtrim($node->openingCode,'?> ').'->startTag() ?>';return$writer->write('if ($_label) echo $_label->endTag()');}}public function macroInput(MacroNode$node,PhpWriter$writer){if($node->modifiers){trigger_error("Modifiers are not allowed in {{$node->name}}",E_USER_WARNING);}$words=$node->tokenizer->fetchWords();if(!$words){throw new CompileException("Missing name in {{$node->name}}.");}$name=array_shift($words);return$writer->write(($name[0]==='$'?'$_input = is_object(%0.word) ? %0.word : $_form[%0.word]; echo $_input':'echo $_form[%0.word]').'->%1.raw'.($node->tokenizer->isNext()?'->addAttributes(%node.array)':''),$name,$words?'getControlPart('.implode(', ',array_map(array($writer,'formatWord'),$words)).')':'getControl()');}public function macroInputAttr(MacroNode$node,PhpWriter$writer){throw new CompileException('Use n:name instead of n:input.');}public function macroNameAttr(MacroNode$node,PhpWriter$writer){$words=$node->tokenizer->fetchWords();if(!$words){throw new CompileException("Missing name in n:{$node->name}.");}$name=array_shift($words);$tagName=strtolower($node->htmlNode->name);$node->isEmpty=$tagName==='input';if($tagName==='form'){return$writer->write('echo Nette\Bridges\FormsLatte\Runtime::renderFormBegin($form = $_form = '.($name[0]==='$'?'is_object(%0.word) ? %0.word : ':'').'$_control[%0.word], %1.var, FALSE)',$name,array_fill_keys(array_keys($node->htmlNode->attrs),NULL));}else{$method=$tagName==='label'?'getLabel':'getControl';return$writer->write('$_input = '.($name[0]==='$'?'is_object(%0.word) ? %0.word : ':'').'$_form[%0.word]; echo $_input->%1.raw'.($node->htmlNode->attrs?'->addAttributes(%2.var)':'').'->attributes()',$name,$words?$method.'Part('.implode(', ',array_map(array($writer,'formatWord'),$words)).')':"{method_exists(\$_input, '{$method}Part')?'{$method}Part':'{$method}'}()",array_fill_keys(array_keys($node->htmlNode->attrs),NULL));}}public function macroName(MacroNode$node,PhpWriter$writer){if(!$node->prefix){throw new CompileException("Unknown macro {{$node->name}}, use n:{$node->name} attribute.");}elseif($node->prefix!==MacroNode::PREFIX_NONE){throw new CompileException("Unknown attribute n:{$node->prefix}-{$node->name}, use n:{$node->name} attribute.");}}public function macroNameEnd(MacroNode$node,PhpWriter$writer){preg_match('#^(.*? n:\w+>)(.*)(<[^?].*)\z#s',$node->content,$parts);$tagName=strtolower($node->htmlNode->name);if($tagName==='form'){$node->content=$parts[1].$parts[2].''.$parts[3];}elseif($tagName==='label'){if($node->htmlNode->isEmpty){$node->content=$parts[1]."{method_exists(\$_input, 'getLabelPart')?'getLabelPart':'getLabel'}()->getHtml() ?>".$parts[3];}}elseif($tagName==='button'){if($node->htmlNode->isEmpty){$node->content=$parts[1].'caption) ?>'.$parts[3];}}else{$node->content=$parts[1].'getControl()->getHtml() ?>'.$parts[3];}}public function macroInputError(MacroNode$node,PhpWriter$writer){if($node->modifiers){trigger_error("Modifiers are not allowed in {{$node->name}}",E_USER_WARNING);}$name=$node->tokenizer->fetchWord();if(!$name){return$writer->write('echo %escape($_input->getError())');}elseif($name[0]==='$'){return$writer->write('$_input = is_object(%0.word) ? %0.word : $_form[%0.word]; echo %escape($_input->getError())',$name);}else{return$writer->write('echo %escape($_form[%0.word]->getError())',$name);}}public static function renderFormBegin(Form$form,array$attrs,$withTags=TRUE){echo Runtime::renderFormBegin($form,$attrs,$withTags);}public static function renderFormEnd(Form$form,$withTags=TRUE){echo Runtime::renderFormEnd($form,$withTags);}}getControls()as$control){$control->setOption('rendered',FALSE);}$el=$form->getElementPrototype();$el->action=(string)$el->action;$el=clone$el;if(strcasecmp($form->getMethod(),'get')===0){$el->action=preg_replace('~\?[^#]*~','',$el->action,1);}$el->addAttributes($attrs);return$withTags?$el->startTag():$el->attributes();}/** @return string **/public static function renderFormEnd(Form$form,$withTags=TRUE){$s='';if(strcasecmp($form->getMethod(),'get')===0){foreach(preg_split('#[;&]#',parse_url($form->getElementPrototype()->action,PHP_URL_QUERY),NULL,PREG_SPLIT_NO_EMPTY)as$param){$parts=explode('=',$param,2);$name=urldecode($parts[0]);if(!isset($form[$name])){$s.=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.="\n";}return$s.($withTags?$form->getElementPrototype()->endTag()."\n":'');}}getPanel('Tracy:info')->data['Nette Framework']=$version;$blueScreen->info[]="Nette Framework $version";}$blueScreen->addPanel(function($e){if($e instanceof Latte\CompileException){return array('tab'=>'Template','panel'=>(preg_match('#\n|\?#',$e->sourceName)?'':'

'.(@is_file($e->sourceName)?'File: '.Helpers::editorLink($e->sourceName,$e->sourceLine):''.htmlspecialchars($e->sourceName.($e->sourceLine?':'.$e->sourceLine:'')).'').'

').'
'.BlueScreen::highlightLine(htmlspecialchars($e->sourceCode,ENT_IGNORE,'UTF-8'),$e->sourceLine).'
');}});$blueScreen->addPanel(function($e){if($e instanceof Nette\Neon\Exception&&preg_match('#line (\d+)#',$e->getMessage(),$m)&&($trace=Helpers::findTrace($e->getTrace(),'Nette\Neon\Decoder::decode'))){return array('tab'=>'NEON','panel'=>($trace2=Helpers::findTrace($e->getTrace(),'Nette\DI\Config\Adapters\NeonAdapter::load'))?'

File: '.Helpers::editorLink($trace2['args'][0],$m[1]).'

'.BlueScreen::highlightFile($trace2['args'][0],$m[1]):BlueScreen::highlightPhp($trace['args'][0],$m[1]));}});}}array(),'headers'=>array('X-Powered-By'=>'Nette Framework','Content-Type'=>'text/html; charset=utf-8'),'frames'=>'SAMEORIGIN');public function loadConfiguration(){$container=$this->getContainerBuilder();$config=$this->validateConfig($this->defaults);$container->addDefinition($this->prefix('requestFactory'))->setClass('Nette\Http\RequestFactory')->addSetup('setProxy',array($config['proxy']));$container->addDefinition($this->prefix('request'))->setClass('Nette\Http\Request')->setFactory('@Nette\Http\RequestFactory::createHttpRequest');$container->addDefinition($this->prefix('response'))->setClass('Nette\Http\Response');$container->addDefinition($this->prefix('context'))->setClass('Nette\Http\Context');if($this->name==='http'){$container->addAlias('nette.httpRequestFactory',$this->prefix('requestFactory'));$container->addAlias('nette.httpContext',$this->prefix('context'));$container->addAlias('httpRequest',$this->prefix('request'));$container->addAlias('httpResponse',$this->prefix('response'));}}public function afterCompile(Nette\PhpGenerator\ClassType$class){if(PHP_SAPI==='cli'){return;}$initialize=$class->getMethod('initialize');$config=$this->getConfig();if(isset($config['frames'])&&$config['frames']!==TRUE){$frames=$config['frames'];if($frames===FALSE){$frames='DENY';}elseif(preg_match('#^https?:#',$frames)){$frames="ALLOW-FROM $frames";}$initialize->addBody('header(?);',array("X-Frame-Options: $frames"));}foreach($config['headers']as$key=>$value){if($value!=NULL){$initialize->addBody('header(?);',array("$key: $value"));}}}}FALSE,'autoStart'=>'smart','expiration'=>NULL);private$debugMode;public function __construct($debugMode=FALSE){$this->debugMode=$debugMode;}public function loadConfiguration(){$container=$this->getContainerBuilder();$config=$this->getConfig()+$this->defaults;$this->setConfig($config);$session=$container->addDefinition($this->prefix('session'))->setClass('Nette\Http\Session');if($config['expiration']){$session->addSetup('setExpiration',array($config['expiration']));}if($this->debugMode&&$config['debugger']){$session->addSetup('@Tracy\Bar::addPanel',array(new Nette\DI\Statement('Nette\Bridges\HttpTracy\SessionPanel')));}unset($config['expiration'],$config['autoStart'],$config['debugger']);if(!empty($config)){$session->addSetup('setOptions',array($config));}if($this->name==='session'){$container->addAlias('session',$this->prefix('session'));}}public function afterCompile(Nette\PhpGenerator\ClassType$class){if(PHP_SAPI==='cli'){return;}$initialize=$class->getMethod('initialize');$config=$this->getConfig();$name=$this->prefix('session');if($config['autoStart']==='smart'){$initialize->addBody('$this->getService(?)->exists() && $this->getService(?)->start();',array($name,$name));}elseif($config['autoStart']){$initialize->addBody('$this->getService(?)->start();',array($name));}}}

Session # (Lifetime: )

empty

$v){if($k==='__NF'){$k='Nette Session';$v=isset($v['DATA'])?$v['DATA']:NULL;}echo'\n";}?>
',htmlspecialchars($k,ENT_IGNORE,'UTF-8'),'',Dumper::toHtml($v,array(Dumper::LIVE=>TRUE)),"
FALSE,'host'=>NULL,'port'=>NULL,'username'=>NULL,'password'=>NULL,'secure'=>NULL,'timeout'=>NULL);public function loadConfiguration(){$container=$this->getContainerBuilder();$config=$this->validateConfig($this->defaults);$mailer=$container->addDefinition($this->prefix('mailer'))->setClass('Nette\Mail\IMailer');if(empty($config['smtp'])){$mailer->setFactory('Nette\Mail\SendmailMailer');}else{$mailer->setFactory('Nette\Mail\SmtpMailer',array($config));}if($this->name==='mail'){$container->addAlias('nette.mailer',$this->prefix('mailer'));}}}NULL,'fromEmail'=>NULL,'logSeverity'=>NULL,'editor'=>NULL,'browser'=>NULL,'errorTemplate'=>NULL,'strictMode'=>NULL,'showBar'=>NULL,'maxLen'=>NULL,'maxDepth'=>NULL,'showLocation'=>NULL,'scream'=>NULL,'bar'=>array(),'blueScreen'=>array());private$debugMode;public function __construct($debugMode=FALSE){$this->debugMode=$debugMode;}public function loadConfiguration(){$this->validateConfig($this->defaults);$container=$this->getContainerBuilder();$container->addDefinition($this->prefix('logger'))->setClass('Tracy\ILogger')->setFactory('Tracy\Debugger::getLogger');$container->addDefinition($this->prefix('blueScreen'))->setFactory('Tracy\Debugger::getBlueScreen');$container->addDefinition($this->prefix('bar'))->setFactory('Tracy\Debugger::getBar');}public function afterCompile(Nette\PhpGenerator\ClassType$class){$initialize=$class->getMethod('initialize');$container=$this->getContainerBuilder();$options=$this->config;unset($options['bar'],$options['blueScreen']);foreach($options as$key=>$value){if($value!==NULL){$key=($key==='fromEmail'?'getLogger()->':'$').$key;$initialize->addBody($container->formatPhp('Tracy\Debugger::'.$key.' = ?;',Nette\DI\Compiler::filterArguments(array($value))));}}if($this->debugMode){foreach((array)$this->config['bar']as$item){$initialize->addBody($container->formatPhp('$this->getService(?)->addPanel(?);',Nette\DI\Compiler::filterArguments(array($this->prefix('bar'),is_string($item)?new Nette\DI\Statement($item):$item))));}}foreach((array)$this->config['blueScreen']as$item){$initialize->addBody($container->formatPhp('$this->getService(?)->addPanel(?);',Nette\DI\Compiler::filterArguments(array($this->prefix('blueScreen'),$item))));}}}debugMode=$debugMode;}public function afterCompile(Nette\PhpGenerator\ClassType$class){$class->getMethod('initialize')->addBody('Nette\Reflection\AnnotationsParser::setCacheStorage($this->getByType("Nette\Caching\IStorage"));')->addBody('Nette\Reflection\AnnotationsParser::$autoRefresh = ?;',array($this->debugMode));}}TRUE,'users'=>array(),'roles'=>array(),'resources'=>array());private$debugMode;public function __construct($debugMode=FALSE){$this->debugMode=$debugMode;}public function loadConfiguration(){$config=$this->validateConfig($this->defaults);$container=$this->getContainerBuilder();$container->addDefinition($this->prefix('userStorage'))->setClass('Nette\Security\IUserStorage')->setFactory('Nette\Http\UserStorage');$user=$container->addDefinition($this->prefix('user'))->setClass('Nette\Security\User');if($this->debugMode&&$config['debugger']){$user->addSetup('@Tracy\Bar::addPanel',array(new Nette\DI\Statement('Nette\Bridges\SecurityTracy\UserPanel')));}if($config['users']){$usersList=$usersRoles=array();foreach($config['users']as$username=>$data){$data=is_array($data)?$data:array('password'=>$data);$this->validateConfig(array('password'=>NULL,'roles'=>NULL),$data,$this->prefix("security.users.$username"));$usersList[$username]=$data['password'];$usersRoles[$username]=isset($data['roles'])?$data['roles']:NULL;}$container->addDefinition($this->prefix('authenticator'))->setClass('Nette\Security\IAuthenticator')->setFactory('Nette\Security\SimpleAuthenticator',array($usersList,$usersRoles));if($this->name==='security'){$container->addAlias('nette.authenticator',$this->prefix('authenticator'));}}if($config['roles']||$config['resources']){$authorizator=$container->addDefinition($this->prefix('authorizator'))->setClass('Nette\Security\IAuthorizator')->setFactory('Nette\Security\Permission');foreach($config['roles']as$role=>$parents){$authorizator->addSetup('addRole',array($role,$parents));}foreach($config['resources']as$resource=>$parents){$authorizator->addSetup('addResource',array($resource,$parents));}if($this->name==='security'){$container->addAlias('nette.authorizator',$this->prefix('authorizator'));}}if($this->name==='security'){$container->addAlias('user',$this->prefix('user'));$container->addAlias('nette.userStorage',$this->prefix('userStorage'));}}}

isLoggedIn()):?>Logged inUnlogged

getIdentity()):echo Dumper::toHtml($user->getIdentity(),array(Dumper::LIVE=>TRUE));else:?>

no identity

user=$user;}/** @return string **/public function getTab(){if(headers_sent()&&!session_id()){return;}ob_start(function(){});$user=$this->user;require __DIR__.'/templates/UserPanel.tab.phtml';return ob_get_clean();}/** @return string **/public function getPanel(){ob_start(function(){});$user=$this->user;require __DIR__.'/templates/UserPanel.panel.phtml';return ob_get_clean();}}storage=$storage;$this->namespace=$namespace.self::NAMESPACE_SEPARATOR;}/** @return IStorage **/public function getStorage(){return$this->storage;}/** @return string **/public function getNamespace(){return(string)substr($this->namespace,0,-1);}/** @return self **/public function derive($namespace){$derived=new static($this->storage,$this->namespace.$namespace);return$derived;}/** @return mixed|NULL **/public function load($key,$fallback=NULL){$data=$this->storage->read($this->generateKey($key));if($data===NULL&&$fallback){return$this->save($key,function(&$dependencies)use($fallback){return call_user_func_array($fallback,array(&$dependencies));});}return$data;}/** @return mixed value itself **/public function save($key,$data,array$dependencies=NULL){$this->key=$this->data=NULL;$key=$this->generateKey($key);if($data instanceof Nette\Callback||$data instanceof\Closure){$this->storage->lock($key);try{$data=call_user_func_array($data,array(&$dependencies));}catch(\Throwable$e){$this->storage->remove($key);throw$e;}catch(\Exception$e){$this->storage->remove($key);throw$e;}}if($data===NULL){$this->storage->remove($key);}else{$this->storage->write($key,$data,$this->completeDependencies($dependencies,$data));return$data;}}private function completeDependencies($dp,$data){if(isset($dp[self::EXPIRATION])){$dp[self::EXPIRATION]=Nette\Utils\DateTime::from($dp[self::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;}/** @return void **/public function remove($key){$this->save($key,NULL);}/** @return void **/public function clean(array$conditions=NULL){$this->key=$this->data=NULL;$this->storage->clean((array)$conditions);}/** @return mixed **/public function call($function){$key=func_get_args();if(is_array($function)&&is_object($function[0])){$key[0][0]=get_class($function[0]);}return$this->load($key,function()use($function,$key){return Callback::invokeArgs($function,array_slice($key,1));});}/** @return \Closure **/public function wrap($function,array$dependencies=NULL){$cache=$this;return function()use($cache,$function,$dependencies){$key=array($function,func_get_args());if(is_array($function)&&is_object($function[0])){$key[0][0]=get_class($function[0]);}$data=$cache->load($key);if($data===NULL){$data=$cache->save($key,Callback::invokeArgs($function,$key[1]),$dependencies);}return$data;};}/** @return OutputHelper|NULL **/public function start($key){$data=$this->load($key);if($data===NULL){return new OutputHelper($this,$key);}echo$data;}/** @return string **/protected function generateKey($key){return$this->namespace.md5(is_scalar($key)?$key:serialize($key));}public function offsetSet($key,$data){trigger_error('Using [] is deprecated; use Cache::save(key, data) instead.',E_USER_DEPRECATED);$this->save($key,$data);}public function offsetGet($key){trigger_error('Using [] is deprecated; use Cache::load(key) instead.',E_USER_DEPRECATED);$key=is_scalar($key)?(string)$key:serialize($key);if($this->key!==$key){$this->key=$key;$this->data=$this->load($key);}return$this->data;}public function offsetExists($key){trigger_error('Using [] is deprecated; use Cache::load(key) !== NULL instead.',E_USER_DEPRECATED);$this->key=$this->data=NULL;return$this->offsetGet($key)!==NULL;}public function offsetUnset($key){trigger_error('Using [] is deprecated; use Cache::remove(key) instead.',E_USER_DEPRECATED);$this->save($key,NULL);}public function release(){trigger_error(__METHOD__.'() is deprecated.',E_USER_DEPRECATED);$this->key=$this->data=NULL;}/** @return bool **/public static function checkCallbacks($callbacks){foreach($callbacks as$callback){if(!call_user_func_array(array_shift($callback),$callback)){return FALSE;}}return TRUE;}/** @return bool **/private static function checkConst($const,$value){return defined($const)&&constant($const)===$value;}/** @return bool **/private static function checkFile($file,$time){return@filemtime($file)==$time;}}cache=$cache;$this->key=$key;ob_start();}/** @return void **/public function end(array$dependencies=NULL){if($this->cache===NULL){throw new Nette\InvalidStateException('Output cache has already been saved.');}$this->cache->save($this->key,ob_get_flush(),(array)$dependencies+(array)$this->dependencies);$this->cache=NULL;}}0,self::PRIORITY=>1,self::ENTRIES=>2,self::DATA=>3);public function __construct($dir){$this->file=$dir.'/'.self::FILE;}/** @return void **/public function __destruct(){if($this->handle){$this->headerCommit();flock($this->handle,LOCK_UN);fclose($this->handle);$this->handle=FALSE;}}/** @return void **/public function 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 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 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::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 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();}/** @return array of removed items or NULL when performing a full cleanup **/public function clean(array$conditions){$this->lock();if(!empty($conditions[Cache::ALL])){$this->nodeCache=$this->nodeChanged=$this->dataNodeFreeSpace=array();$this->deleteAll();$this->unlock();return 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;}/** @return array of removed items **/private function cleanTags(array$tags,array&$toDelete){$entries=array();foreach($tags as$tag){list(,$node)=$this->findIndexNode(self::TAGS,$tag);if(isset($node[$tag])){$ent=$this->cleanLinks($this->mergeIndexData($node[$tag]),$toDelete);$this->arrayAppend($entries,$ent);}}return$entries;}/** @return array of removed items **/private function cleanPriority($priority,array&$toDelete){list(,$node)=$this->findIndexNode(self::PRIORITY,$priority);ksort($node);$allData=array();foreach($node 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 new Nette\InvalidStateException("Cannot load node number $nodeId.");}break;}$nodeInfo=$node[self::INFO];unset($node[self::INFO]);foreach($node as$data){$this->arrayAppendKeys($allData,$this->mergeIndexData($data));}}return$this->cleanLinks($allData,$toDelete);}/** @return array of removed items **/private function 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 new Nette\InvalidStateException("Cannot load node number $nodeId.");}++$i;continue;}do{$link=$data[$i];if(isset($this->deletedLinks[$link])){continue;}elseif(!isset($node[$link])){if(self::$debug){throw new Nette\InvalidStateException("Link with ID $searchLink is not in node $nodeId.");}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 function cleanFromIndex(array$toDeleteFromIndex){foreach($toDeleteFromIndex 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 new Nette\InvalidStateException('Bad index.');}unset($toDelete[$searchKey]);continue;}foreach($toDelete as$key=>$links){if(isset($masterNode[$key])){foreach($links 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);}}}/** @return array of merged items **/private function 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 new Nette\InvalidStateException("Cannot load node number $id.");}break;}$this->arrayAppendKeys($data,$childNode[self::INDEX_DATA]);}return$data;}/** @return void **/private function cleanIndexData($nextNodeId,array$links,&$masterNodeLink){$prev=-1;while($nextNodeId&&!empty($links)){$nodeId=$nextNodeId;$node=$this->getNode($nodeId);if($node===FALSE){if(self::$debug){throw new Nette\InvalidStateException("Cannot load node number $nodeId.");}break;}foreach($links 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 new 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);}}/** @return array **/private function 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 FALSE;}list(,$magic,$length)=unpack('N2',$binary);if($magic!==self::INDEX_MAGIC&&$magic!==self::DATA_MAGIC){if(!empty($magic)){if(self::$debug){throw new Nette\InvalidStateException("Node $id has malformed header.");}$this->deleteNode($id);}return 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 new Nette\InvalidStateException("Cannot unserialize node number $id.");}return FALSE;}return$this->nodeCache[$id]=$node;}/** @return void **/private function 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 new 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 new 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;}/** @return void **/private function commit(){do{foreach($this->nodeChanged as$id=>$foo){if($this->prepareNode($id,$this->nodeCache[$id])){unset($this->nodeChanged[$id]);}}}while(!empty($this->nodeChanged));foreach($this->toCommit as$node=>$str){$this->commitNode($node,$str);}$this->toCommit=array();}/** @return bool Successfully committed **/private function 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 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 new Nette\InvalidStateException('Saving node is bigger than maximum node size.');}else{$this->bisectNode($id,$node);return 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 TRUE;}/** @return void **/private function commitNode($id,$str){fseek($this->handle,self::HEADER_SIZE+self::NODE_SIZE*$id);$written=fwrite($this->handle,$str);if($written===FALSE){throw new Nette\InvalidStateException("Cannot write node number $id to journal.");}}/** @return array Node **/private function findIndexNode($type,$search,$childId=NULL,$prevId=NULL){$nodeId=self::$startNode[$type];$parentId=-1;while(TRUE){$node=$this->getNode($nodeId);if($node===FALSE){return 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 array($nodeId,$node,$parentId);}$parentId=$nodeId;if(isset($node[$search])){$nodeId=$node[$search];}else{foreach($node as$key=>$childNode){if($key>$search&&$key!==self::INFO){$nodeId=$childNode;continue 2;}}$nodeId=$node[self::INFO][self::END];}}}/** @return array|int Node ID **/private function 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;}}/** @return int Node ID **/private function findFreeDataNode($size){foreach($this->dataNodeFreeSpace 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;}}/** @return void **/private function 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<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 new Nette\InvalidStateException("Cannot load node number $parent.");}}else{$parentNode[$halfKey]=$firstId;ksort($parentNode);$this->saveNode($parent,$parentNode);}}}/** @return void **/private function headerCommit(){fseek($this->handle,self::INT32_SIZE);@fwrite($this->handle,pack('N',$this->lastNode));}/** @return void **/private function 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 new 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 new Nette\InvalidStateException("Cannot delete node number $id from journal.");}}}private function deleteAll(){if(!ftruncate($this->handle,self::HEADER_SIZE)){throw new Nette\InvalidStateException('Cannot truncate journal file.');}}private function lock(){if(!$this->handle){$this->prepare();}if(!flock($this->handle,LOCK_EX)){throw new 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 function prepare(){if(!file_exists($this->file)){$init=@fopen($this->file,'xb');if(!$init){clearstatcache();if(!file_exists($this->file)){throw new 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 new Nette\InvalidStateException('Cannot write journal header.');}}}$this->handle=fopen($this->file,'r+b');if(!$this->handle){throw new Nette\InvalidStateException("Cannot open journal file '$this->file'.");}if(!flock($this->handle,LOCK_SH)){throw new 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 new Nette\InvalidStateException("Malformed journal file '$this->file'.");}$this->processIdentifier=pack('N',mt_rand());}/** @return void **/private function unlock(){if($this->handle){fflush($this->handle);flock($this->handle,LOCK_UN);}}/** @return int **/private function findNextFreeKey($nodeId,array&$nodeData){$newKey=$nodeData[self::INFO][self::LAST_INDEX]+1;$maxKey=($nodeId+1)<=$maxKey){$start=$nodeId<$value){$array[$key]=$value;}}}dir=$dir;$this->useDirs=(bool)static::$useDirectories;$this->journal=$journal;if(mt_rand()/mt_getrandmax()clean(array());}}/** @return mixed|NULL **/public function read($key){$meta=$this->readMetaAndLock($this->getCacheFile($key),LOCK_SH);if($meta&&$this->verify($meta)){return$this->readData($meta);}else{return NULL;}}/** @return bool **/private function verify($meta){do{if(!empty($meta[self::META_DELTA])){if(filemtime($meta[self::FILE])+$meta[self::META_DELTA]$time){$m=$this->readMetaAndLock($depFile,LOCK_SH);if($m[self::META_TIME]!==$time||($m&&!$this->verify($m))){break 2;}}}return TRUE;}while(FALSE);$this->delete($meta[self::FILE],$meta[self::HANDLE]);return FALSE;}/** @return void **/public function lock($key){$cacheFile=$this->getCacheFile($key);if($this->useDirs&&!is_dir($dir=dirname($cacheFile))){@mkdir($dir);}$handle=fopen($cacheFile,'c+b');if($handle){$this->locks[$key]=$handle;flock($handle,LOCK_EX);}}/** @return void **/public function 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 new 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='delete($cacheFile,$handle);}/** @return void **/public function remove($key){unset($this->locks[$key]);$this->delete($this->getCacheFile($key));}/** @return void **/public function 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);}}}/** @return array|NULL **/protected function readMetaAndLock($file,$lock){$handle=@fopen($file,'r+b');if(!$handle){return 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)){$meta[self::FILE]=$file;$meta[self::HANDLE]=$handle;return$meta;}}flock($handle,LOCK_UN);fclose($handle);return NULL;}/** @return mixed **/protected function 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);}}/** @return string **/protected function getCacheFile($key){$file=urlencode($key);if($this->useDirs&&$a=strrpos($file,'%00')){$file=substr_replace($file,'/_',$a,3);}return$this->dir.'/_'.$file;}/** @return void **/private static function 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);}}}prefix=$prefix;$this->journal=$journal;$this->memcache=new\Memcache;if($host){$this->addServer($host,$port);}}public function addServer($host='localhost',$port=11211,$timeout=1){if($this->memcache->addServer($host,$port,TRUE,1,$timeout)===FALSE){$error=error_get_last();throw new Nette\InvalidStateException("Memcache::addServer(): $error[message].");}}/** @return \Memcache **/public function getConnection(){return$this->memcache;}/** @return mixed|NULL **/public function read($key){$key=urlencode($this->prefix.$key);$meta=$this->memcache->get($key);if(!$meta){return NULL;}if(!empty($meta[self::META_CALLBACKS])&&!Cache::checkCallbacks($meta[self::META_CALLBACKS])){$this->memcache->delete($key,0);return NULL;}if(!empty($meta[self::META_DELTA])){$this->memcache->replace($key,$meta,0,$meta[self::META_DELTA]+time());}return$meta[self::META_DATA];}/** @return void **/public function lock($key){}/** @return void **/public function write($key,$data,array$dp){if(isset($dp[Cache::ITEMS])){throw new Nette\NotSupportedException('Dependent items are not supported by MemcachedStorage.');}$key=urlencode($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 new Nette\InvalidStateException('CacheJournal has not been provided.');}$this->journal->write($key,$dp);}$this->memcache->set($key,$meta,0,$expire);}/** @return void **/public function remove($key){$this->memcache->delete(urlencode($this->prefix.$key),0);}/** @return void **/public function 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);}}}}data[$key])?$this->data[$key]:NULL;}/** @return void **/public function lock($key){}/** @return void **/public function write($key,$data,array$dependencies){$this->data[$key]=$data;}/** @return void **/public function remove($key){unset($this->data[$key]);}/** @return void **/public function clean(array$conditions){if(!empty($conditions[Nette\Caching\Cache::ALL])){$this->data=array();}}}prefix=$prefix;$this->journal=$journal;$this->memcached=new\Memcached;if($host){$this->addServer($host,$port);}}public function addServer($host='localhost',$port=11211){if($this->memcached->addServer($host,$port,1)===FALSE){$error=error_get_last();throw new Nette\InvalidStateException("Memcached::addServer(): $error[message].");}}/** @return \Memcached **/public function getConnection(){return$this->memcached;}/** @return mixed|NULL **/public function read($key){$key=urlencode($this->prefix.$key);$meta=$this->memcached->get($key);if(!$meta){return NULL;}if(!empty($meta[self::META_CALLBACKS])&&!Cache::checkCallbacks($meta[self::META_CALLBACKS])){$this->memcached->delete($key,0);return NULL;}if(!empty($meta[self::META_DELTA])){$this->memcached->replace($key,$meta,$meta[self::META_DELTA]+time());}return$meta[self::META_DATA];}/** @return void **/public function lock($key){}/** @return void **/public function write($key,$data,array$dp){if(isset($dp[Cache::ITEMS])){throw new Nette\NotSupportedException('Dependent items are not supported by MemcachedStorage.');}$key=urlencode($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 new Nette\InvalidStateException('CacheJournal has not been provided.');}$this->journal->write($key,$dp);}$this->memcached->set($key,$meta,$expire);}/** @return void **/public function remove($key){$this->memcached->delete(urlencode($this->prefix.$key),0);}/** @return void **/public function clean(array$conditions){if(!empty($conditions[Cache::ALL])){$this->memcached->flush();}elseif($this->journal){foreach($this->journal->clean($conditions)as$entry){$this->memcached->delete($entry,0);}}}}pdo=new\PDO('sqlite:'.$path,NULL,NULL,array(\PDO::ATTR_PERSISTENT=>TRUE));$this->pdo->setAttribute(\PDO::ATTR_ERRMODE,\PDO::ERRMODE_EXCEPTION);$this->pdo->exec(' PRAGMA foreign_keys = ON; CREATE TABLE IF NOT EXISTS cache ( key BLOB NOT NULL PRIMARY KEY, data BLOB NOT NULL ); CREATE TABLE IF NOT EXISTS tags ( key BLOB NOT NULL REFERENCES cache ON DELETE CASCADE, tag BLOB NOT NULL ); CREATE INDEX IF NOT EXISTS tags_key ON tags(key); CREATE INDEX IF NOT EXISTS tags_tag ON tags(tag); ');}/** @return mixed|NULL **/public function read($key){$stmt=$this->pdo->prepare('SELECT data FROM cache WHERE key=?');$stmt->execute(array($key));if($res=$stmt->fetchColumn()){return unserialize($res);}}/** @return void **/public function lock($key){}/** @return void **/public function write($key,$data,array$dependencies){$this->pdo->exec('BEGIN TRANSACTION');$this->pdo->prepare('REPLACE INTO cache (key, data) VALUES (?, ?)')->execute(array($key,serialize($data)));if(!empty($dependencies[Cache::TAGS])){foreach((array)$dependencies[Cache::TAGS]as$tag){$arr[]=$key;$arr[]=$tag;}$this->pdo->prepare('INSERT INTO tags (key, tag) SELECT ?, ?'.str_repeat('UNION SELECT ?, ?',count($arr)/2-1))->execute($arr);}$this->pdo->exec('COMMIT');}/** @return void **/public function remove($key){$this->pdo->prepare('DELETE FROM cache WHERE key=?')->execute(array($key));}/** @return void **/public function clean(array$conditions){if(!empty($conditions[Cache::ALL])){$this->pdo->prepare('DELETE FROM cache')->execute();}elseif(!empty($conditions[Cache::TAGS])){$tags=(array)$conditions[Cache::TAGS];$this->pdo->prepare('DELETE FROM cache WHERE key IN (SELECT key FROM tags WHERE tag IN (?'.str_repeat(',?',count($tags)-1).'))')->execute($tags);}}}addComponent($this,$name);}elseif(is_string($name)){$this->name=$name;}}/** @return IComponent **/public function lookup($type,$need=TRUE){if(!isset($this->monitors[$type])){$obj=$this->parent;$path=self::NAME_SEPARATOR.$this->name;$depth=1;while($obj!==NULL){$parent=$obj->getParent();if($type?$obj instanceof$type:$parent===NULL){break;}$path=self::NAME_SEPARATOR.$obj->getName().$path;$depth++;$obj=$parent;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 new Nette\InvalidStateException("Component '$this->name' is not attached to '$type'.");}return$this->monitors[$type][0];}/** @return string **/public function lookupPath($type=NULL,$need=TRUE){$this->lookup($type,$need);return$this->monitors[$type][2];}/** @return void **/public function monitor($type){if(empty($this->monitors[$type][3])){if($obj=$this->lookup($type,FALSE)){$this->attached($obj);}$this->monitors[$type][3]=TRUE;}}/** @return void **/public function unmonitor($type){unset($this->monitors[$type]);}/** @return void **/protected function attached($obj){}/** @return void **/protected function detached($obj){}/** @return string **/public function getName(){return$this->name;}/** @return IContainer|NULL **/public function getParent(){return$this->parent;}/** @return static **/public function 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 new 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;}/** @return void **/protected function validateParent(IContainer$parent){}/** @return void **/private function refreshMonitors($depth,&$missing=NULL,&$listeners=array()){if($this instanceof IContainer){foreach($this->getComponents()as$component){if($component instanceof self){$component->refreshMonitors($depth+1,$missing,$listeners);}}}if($missing===NULL){foreach($this->monitors 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 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';$prev=array();foreach($listeners as$item){if(!in_array($item,$prev,TRUE)){$item[0]->$method($item[1]);$prev[]=$item;}}}}public function __clone(){if($this->parent===NULL){return;}elseif($this->parent instanceof Container){$this->parent=$this->parent->_isCloning();if($this->parent===NULL){$this->refreshMonitors(0);}}else{$this->parent=NULL;$this->refreshMonitors(0);}}public function __sleep(){throw new Nette\NotImplementedException('Object serialization is not supported by class '.get_class($this));}public function __wakeup(){throw new Nette\NotImplementedException('Object unserialization is not supported by class '.get_class($this));}}getName();}if(is_int($name)){$name=(string)$name;}elseif(!is_string($name)){throw new Nette\InvalidArgumentException(sprintf('Component name must be integer or string, %s given.',gettype($name)));}elseif(!preg_match('#^[a-zA-Z0-9_]+\z#',$name)){throw new Nette\InvalidArgumentException("Component name must be non-empty alphanumeric string, '$name' given.");}if(isset($this->components[$name])){throw new Nette\InvalidStateException("Component with name '$name' already exists.");}$obj=$this;do{if($obj===$component){throw new 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 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;}/** @return void **/public function removeComponent(IComponent$component){$name=$component->getName();if(!isset($this->components[$name])||$this->components[$name]!==$component){throw new Nette\InvalidArgumentException("Component named '$name' is not located in this container.");}unset($this->components[$name]);$component->setParent(NULL);}/** @return IComponent|NULL **/public function getComponent($name,$need=TRUE){if(isset($this->components[$name])){return$this->components[$name];}if(is_int($name)){$name=(string)$name;}elseif(!is_string($name)){throw new Nette\InvalidArgumentException(sprintf('Component name must be integer or string, %s given.',gettype($name)));}else{$a=strpos($name,self::NAME_SEPARATOR);if($a!==FALSE){$ext=(string)substr($name,$a+1);$name=substr($name,0,$a);}if($name===''){if($need){throw new Nette\InvalidArgumentException('Component or subcomponent name must not be empty string.');}return;}}if(!isset($this->components[$name])){$component=$this->createComponent($name);if($component){if(!$component instanceof IComponent){throw new Nette\UnexpectedValueException('Method createComponent() did not return Nette\ComponentModel\IComponent.');}elseif(!isset($this->components[$name])){$this->addComponent($component,$name);}}}if(isset($this->components[$name])){if(!isset($ext)){return$this->components[$name];}elseif($this->components[$name]instanceof IContainer){return$this->components[$name]->getComponent($ext,$need);}elseif($need){throw new Nette\InvalidArgumentException("Component with name '$name' is not container and cannot have '$ext' component.");}}elseif($need){$hint=Nette\Utils\ObjectMixin::getSuggestion(array_merge(array_keys($this->components),array_map('lcfirst',preg_filter('#^createComponent([A-Z0-9].*)#','$1',get_class_methods($this)))),$name);throw new Nette\InvalidArgumentException("Component with name '$name' does not exist".($hint?", did you mean '$hint'?":'.'));}}/** @return IComponent the created component (optionally) **/protected function 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 instanceof IComponent&&!isset($this->components[$name])){$class=get_class($this);throw new Nette\UnexpectedValueException("Method $class::$method() did not return or create the desired component.");}return$component;}}/** @return \ArrayIterator **/public function getComponents($deep=FALSE,$filterType=NULL){$iterator=new RecursiveComponentIterator($this->components);if($deep){$deep=$deep>0?\RecursiveIteratorIterator::SELF_FIRST:\RecursiveIteratorIterator::CHILD_FIRST;$iterator=new\RecursiveIteratorIterator($iterator,$deep);}if($filterType){$class=PHP_VERSION_ID<50400?'Nette\Iterators\Filter':'CallbackFilterIterator';$iterator=new$class($iterator,function($item)use($filterType){return$item instanceof$filterType;});}return$iterator;}/** @return void **/protected function validateChildComponent(IComponent$child){}public function __clone(){if($this->components){$oldMyself=reset($this->components)->getParent();$oldMyself->cloning=$this;foreach($this->components as$name=>$component){$this->components[$name]=clone$component;}$oldMyself->cloning=NULL;}parent::__clone();}/** @return NULL|IComponent **/public function _isCloning(){return$this->cloning;}}current()instanceof IContainer;}/** @return \RecursiveIterator **/public function getChildren(){return$this->current()->getComponents();}/** @return int **/public function count(){return iterator_count($this);}}4){$options['driverClass']=func_get_arg(4);}$this->params=array($dsn,$user,$password);$this->options=(array)$options;if(empty($options['lazy'])){$this->connect();}}/** @return void **/public function connect(){if($this->pdo){return;}try{$this->pdo=new PDO($this->params[0],$this->params[1],$this->params[2],$this->options);$this->pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);}catch(PDOException$e){throw ConnectionException::from($e);}$class=empty($this->options['driverClass'])?'Nette\Database\Drivers\\'.ucfirst(str_replace('sql','Sql',$this->pdo->getAttribute(PDO::ATTR_DRIVER_NAME))).'Driver':$this->options['driverClass'];$this->driver=new$class($this,$this->options);$this->preprocessor=new SqlPreprocessor($this);$this->onConnect($this);}/** @return void **/public function reconnect(){$this->disconnect();$this->connect();}/** @return void **/public function disconnect(){$this->pdo=NULL;}/** @return string **/public function getDsn(){return$this->params[0];}/** @return PDO **/public function getPdo(){$this->connect();return$this->pdo;}/** @return ISupplementalDriver **/public function getSupplementalDriver(){$this->connect();return$this->driver;}/** @return string **/public function getInsertId($name=NULL){try{return$this->getPdo()->lastInsertId($name);}catch(PDOException$e){throw$this->driver->convertException($e);}}/** @return string **/public function quote($string,$type=PDO::PARAM_STR){try{return$this->getPdo()->quote($string,$type);}catch(PDOException$e){throw DriverException::from($e);}}/** @return void **/function beginTransaction(){$this->query('::beginTransaction');}/** @return void **/function commit(){$this->query('::commit');}/** @return void **/public function rollBack(){$this->query('::rollBack');}/** @return ResultSet **/public function query($sql){$this->connect();$args=is_array($sql)?$sql:func_get_args();list($sql,$params)=count($args)>1?$this->preprocessor->process($args):array($args[0],array());try{$result=new ResultSet($this,$sql,$params);}catch(PDOException$e){$this->onQuery($this,$e);throw$e;}$this->onQuery($this,$result);return$result;}/** @return ResultSet **/public function queryArgs($sql,array$params){array_unshift($params,$sql);return$this->query($params);}/** @return [string, array] **/public function preprocess($sql){$this->connect();return func_num_args()>1?$this->preprocessor->process(func_get_args()):array($sql,array());}/** @return Row **/public function fetch($args){return$this->query(func_get_args())->fetch();}/** @return mixed **/public function fetchField($args){return$this->query(func_get_args())->fetchField();}/** @return array **/public function fetchPairs($args){return$this->query(func_get_args())->fetchPairs();}/** @return array **/public function fetchAll($args){return$this->query(func_get_args())->fetchAll();}/** @return SqlLiteral **/public static function literal($value){$args=func_get_args();return new SqlLiteral(array_shift($args),$args);}}connection=$connection;$this->structure=$structure;$this->conventions=$conventions?:new StaticConventions;$this->cacheStorage=$cacheStorage;}/** @return void **/public function beginTransaction(){$this->connection->beginTransaction();}/** @return void **/public function commit(){$this->connection->commit();}/** @return void **/public function rollBack(){$this->connection->rollBack();}/** @return string **/public function getInsertId($name=NULL){return$this->connection->getInsertId($name);}/** @return ResultSet **/public function query($sql){return$this->connection->query(func_get_args());}/** @return ResultSet **/public function queryArgs($sql,array$params){return$this->connection->queryArgs($sql,$params);}/** @return Table\Selection **/public function table($table){return new Table\Selection($this,$this->conventions,$table,$this->cacheStorage);}/** @return Connection **/public function getConnection(){return$this->connection;}/** @return IStructure **/public function getStructure(){return$this->structure;}/** @return IConventions **/public function getConventions(){return$this->conventions;}public function getDatabaseReflection(){trigger_error(__METHOD__.'() is deprecated; use getConventions() instead.',E_USER_DEPRECATED);return$this->conventions;}/** @return Row **/public function fetch($args){return$this->connection->query(func_get_args())->fetch();}/** @return mixed **/public function fetchField($args){return$this->connection->query(func_get_args())->fetchField();}/** @return array **/public function fetchPairs($args){return$this->connection->query(func_get_args())->fetchPairs();}/** @return array **/public function fetchAll($args){return$this->connection->query(func_get_args())->fetchAll();}/** @return SqlLiteral **/public static function literal($value){$args=func_get_args();return new SqlLiteral(array_shift($args),$args);}}structure=$structure;}public function getPrimary($table){return$this->structure->getPrimaryKey($table);}public function getHasManyReference($nsTable,$key){$candidates=$columnCandidates=array();$targets=$this->structure->getHasManyReference($nsTable);$table=preg_replace('#^(.*\.)?(.*)$#','$2',$nsTable);foreach($targets as$targetNsTable=>$targetColumns){$targetTable=preg_replace('#^(.*\.)?(.*)$#','$2',$targetNsTable);if(stripos($targetNsTable,$key)===FALSE){continue;}foreach($targetColumns as$targetColumn){if(stripos($targetColumn,$table)!==FALSE){$columnCandidates[]=$candidate=array($targetNsTable,$targetColumn);if(strcmp($targetTable,$key)===0||strcmp($targetNsTable,$key)===0){return$candidate;}}$candidates[]=array($targetTable,array($targetNsTable,$targetColumn));}}if(count($columnCandidates)===1){return$columnCandidates[0];}elseif(count($candidates)===1){return$candidates[0][1];}foreach($candidates as$candidate){if(strtolower($candidate[0])===strtolower($key)){return$candidate[1];}}if(!empty($candidates)){throw new AmbiguousReferenceKeyException('Ambiguous joining column in related call.');}if($this->structure->isRebuilt()){return NULL;}$this->structure->rebuild();return$this->getHasManyReference($nsTable,$key);}public function getBelongsToReference($table,$key){$tableColumns=$this->structure->getBelongsToReference($table);foreach($tableColumns as$column=>$targetTable){if(stripos($column,$key)!==FALSE){return array($targetTable,$column);}}if($this->structure->isRebuilt()){return NULL;}$this->structure->rebuild();return$this->getBelongsToReference($table,$key);}}primary=$primary;$this->foreign=$foreign;$this->table=$table;}public function getPrimary($table){return sprintf($this->primary,$this->getColumnFromTable($table));}public function getHasManyReference($table,$key){$table=$this->getColumnFromTable($table);return array(sprintf($this->table,$key,$table),sprintf($this->foreign,$table,$key));}public function getBelongsToReference($table,$key){$table=$this->getColumnFromTable($table);return array(sprintf($this->table,$key,$table),sprintf($this->foreign,$key,$table));}protected function getColumnFromTable($name){if($this->table!=='%s'&&preg_match('(^'.str_replace('%s','(.*)',preg_quote($this->table)).'\z)',$name,$match)){return$match[1];}return$name;}}connection=$connection;if($cacheStorage){$this->cache=new Nette\Caching\Cache($cacheStorage,'Nette.Database.'.md5($connection->getDsn()));$this->structure=$this->loadedStructure=$this->cache->load('structure')?:array();}}public function __destruct(){if($this->cache&&$this->structure!==$this->loadedStructure){$this->cache->save('structure',$this->structure);}}public function getPrimary($table){$primary=&$this->structure['primary'][strtolower($table)];if(isset($primary)){return empty($primary)?NULL:$primary;}$columns=$this->connection->getSupplementalDriver()->getColumns($table);$primary=array();foreach($columns as$column){if($column['primary']){$primary[]=$column['name'];}}if(count($primary)===0){return NULL;}elseif(count($primary)===1){$primary=reset($primary);}return$primary;}public function 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 reset($columnCandidates);}elseif(count($candidates)===1){return reset($candidates);}foreach($candidates as$candidate){if(strtolower($candidate[0])===strtolower($key)){return$candidate;}}}if($refresh){$this->reloadAllForeignKeys();return$this->getHasManyReference($table,$key,FALSE);}if(empty($candidates)){throw new MissingReferenceException("No reference found for \${$table}->related({$key}).");}else{throw new AmbiguousReferenceKeyException('Ambiguous joining column in related call.');}}public function 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 array($targetTable,$column);}}}if($refresh){$this->reloadForeignKeys($table);return$this->getBelongsToReference($table,$key,FALSE);}throw new MissingReferenceException("No reference found for \${$table}->{$key}.");}protected function reloadAllForeignKeys(){$this->structure['hasMany']=$this->structure['belongsTo']=array();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 strlen($a)-strlen($b);});}}protected function 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 strlen($a)-strlen($b);});}}}message,NULL,$src);if(!$src->errorInfo&&preg_match('#SQLSTATE\[(.*?)\] \[(.*?)\] (.*)#A',$src->message,$m)){$m[2]=(int)$m[2];$e->errorInfo=array_slice($m,1);$e->code=$m[1];}else{$e->errorInfo=$src->errorInfo;$e->code=$src->code;}return$e;}/** @return int|string|NULL Driver-specific error code **/public function getDriverCode(){return isset($this->errorInfo[1])?$this->errorInfo[1]:NULL;}/** @return string|NULL SQLSTATE error code **/public function getSqlState(){return isset($this->errorInfo[0])?$this->errorInfo[0]:NULL;}/** @return string|NULL SQL command **/public function getQueryString(){return$this->queryString;}}format("'Y-m-d H:i:s'");}public function formatDateInterval(\DateInterval$value){throw new Nette\NotSupportedException;}public function formatLike($value,$pos){$value=strtr($value,array("'"=>"''",'%'=>'[%]','_'=>'[_]','['=>'[[]'));return($pos<=0?"'%":"'").$value.($pos>=0?"%'":"'");}public function applyLimit(&$sql,$limit,$offset){if($offset){throw new Nette\NotSupportedException('Offset is not supported by this database.');}elseif($limit<0){throw new Nette\InvalidArgumentException('Negative offset or limit.');}elseif($limit!==NULL){$sql=preg_replace('#^\s*(SELECT(\s+DISTINCT|\s+ALL)?|UPDATE|DELETE)#i','$0 TOP '.(int)$limit,$sql,1,$count);if(!$count){throw new Nette\InvalidArgumentException('SQL query must begin with SELECT, UPDATE or DELETE command.');}}}public function normalizeRow($row){return$row;}public function getTables(){throw new Nette\NotImplementedException;}public function getColumns($table){throw new Nette\NotImplementedException;}public function getIndexes($table){throw new Nette\NotImplementedException;}public function getForeignKeys($table){throw new Nette\NotImplementedException;}public function getColumnTypes(\PDOStatement$statement){return Nette\Database\Helpers::detectTypes($statement);}/** @return bool **/public function isSupported($item){return$item===self::SUPPORT_SUBSELECT;}}connection=$connection;$charset=isset($options['charset'])?$options['charset']:(version_compare($connection->getPdo()->getAttribute(\PDO::ATTR_SERVER_VERSION),'5.5.3','>=')?'utf8mb4':'utf8');if($charset){$connection->query("SET NAMES '$charset'");}if(isset($options['sqlmode'])){$connection->query("SET sql_mode='$options[sqlmode]'");}}/** @return Nette\Database\DriverException **/public function convertException(\PDOException$e){$code=isset($e->errorInfo[1])?$e->errorInfo[1]:NULL;if(in_array($code,array(1216,1217,1451,1452,1701),TRUE)){return Nette\Database\ForeignKeyConstraintViolationException::from($e);}elseif(in_array($code,array(1062,1557,1569,1586),TRUE)){return Nette\Database\UniqueConstraintViolationException::from($e);}elseif($code>=2001&&$code<=2028){return Nette\Database\ConnectionException::from($e);}elseif(in_array($code,array(1048,1121,1138,1171,1252,1263,1566),TRUE)){return Nette\Database\NotNullConstraintViolationException::from($e);}else{return Nette\Database\DriverException::from($e);}}public function delimite($name){return'`'.str_replace('`','``',$name).'`';}public function formatBool($value){return$value?'1':'0';}public function formatDateTime($value){return$value->format("'Y-m-d H:i:s'");}public function formatDateInterval(\DateInterval$value){return$value->format("'%r%h:%I:%S'");}public function formatLike($value,$pos){$value=addcslashes(str_replace('\\','\\\\',$value),"\x00\n\r\\'%_");return($pos<=0?"'%":"'").$value.($pos>=0?"%'":"'");}public function applyLimit(&$sql,$limit,$offset){if($limit<0||$offset<0){throw new Nette\InvalidArgumentException('Negative offset or limit.');}elseif($limit!==NULL||$offset){$sql.=' LIMIT '.($limit===NULL?'18446744073709551615':(int)$limit).($offset?' OFFSET '.(int)$offset:'');}}public function normalizeRow($row){return$row;}public function 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;}public function 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;}public function 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 array_values($indexes);}public function 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 array_values($keys);}public function getColumnTypes(\PDOStatement$statement){$types=array();$count=$statement->columnCount();for($col=0;$col<$count;$col++){$meta=$statement->getColumnMeta($col);if(isset($meta['native_type'])){$types[$meta['name']]=$type=Nette\Database\Helpers::detectType($meta['native_type']);if($type===Nette\Database\IStructure::FIELD_TIME){$types[$meta['name']]=Nette\Database\IStructure::FIELD_TIME_INTERVAL;}}}return$types;}/** @return bool **/public function isSupported($item){return$item===self::SUPPORT_SELECT_UNGROUPED_COLUMNS||$item===self::SUPPORT_MULTI_COLUMN_AS_OR_COND;}}connection=$connection;$this->fmtDateTime=isset($options['formatDateTime'])?$options['formatDateTime']:'U';}public function convertException(\PDOException$e){$code=isset($e->errorInfo[1])?$e->errorInfo[1]:NULL;if(in_array($code,array(1,2299,38911),TRUE)){return Nette\Database\UniqueConstraintViolationException::from($e);}elseif(in_array($code,array(1400),TRUE)){return Nette\Database\NotNullConstraintViolationException::from($e);}elseif(in_array($code,array(2266,2291,2292),TRUE)){return Nette\Database\ForeignKeyConstraintViolationException::from($e);}else{return Nette\Database\DriverException::from($e);}}public function delimite($name){return'"'.str_replace('"','""',$name).'"';}public function formatBool($value){return$value?'1':'0';}public function formatDateTime($value){return$value->format($this->fmtDateTime);}public function formatDateInterval(\DateInterval$value){throw new Nette\NotSupportedException;}public function formatLike($value,$pos){throw new Nette\NotImplementedException;}public function applyLimit(&$sql,$limit,$offset){if($limit<0||$offset<0){throw new Nette\InvalidArgumentException('Negative offset or limit.');}elseif($offset){$sql='SELECT * FROM (SELECT t.*, ROWNUM AS "__rnum" FROM ('.$sql.') t '.($limit!==NULL?'WHERE ROWNUM <= '.((int)$offset+(int)$limit):'').') WHERE "__rnum" > '.(int)$offset;}elseif($limit!==NULL){$sql='SELECT * FROM ('.$sql.') WHERE ROWNUM <= '.(int)$limit;}}public function normalizeRow($row){return$row;}public function 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;}public function getColumns($table){throw new Nette\NotImplementedException;}public function getIndexes($table){throw new Nette\NotImplementedException;}public function getForeignKeys($table){throw new Nette\NotImplementedException;}public function getColumnTypes(\PDOStatement$statement){return Nette\Database\Helpers::detectTypes($statement);}/** @return bool **/public function isSupported($item){return$item===self::SUPPORT_SEQUENCE||$item===self::SUPPORT_SUBSELECT;}}format('#m/d/Y H:i:s#');}public function formatDateInterval(\DateInterval$value){throw new Nette\NotSupportedException;}public function formatLike($value,$pos){$value=strtr($value,array("'"=>"''",'%'=>'[%]','_'=>'[_]','['=>'[[]'));return($pos<=0?"'%":"'").$value.($pos>=0?"%'":"'");}public function applyLimit(&$sql,$limit,$offset){if($offset){throw new Nette\NotSupportedException('Offset is not supported by this database.');}elseif($limit<0){throw new Nette\InvalidArgumentException('Negative offset or limit.');}elseif($limit!==NULL){$sql=preg_replace('#^\s*(SELECT(\s+DISTINCT|\s+ALL)?|UPDATE|DELETE)#i','$0 TOP '.(int)$limit,$sql,1,$count);if(!$count){throw new Nette\InvalidArgumentException('SQL query must begin with SELECT, UPDATE or DELETE command.');}}}public function normalizeRow($row){return$row;}public function getTables(){throw new Nette\NotImplementedException;}public function getColumns($table){throw new Nette\NotImplementedException;}public function getIndexes($table){throw new Nette\NotImplementedException;}public function getForeignKeys($table){throw new Nette\NotImplementedException;}public function getColumnTypes(\PDOStatement$statement){return Nette\Database\Helpers::detectTypes($statement);}/** @return bool **/public function isSupported($item){return$item===self::SUPPORT_SUBSELECT;}}connection=$connection;}public function convertException(\PDOException$e){$code=isset($e->errorInfo[0])?$e->errorInfo[0]:NULL;if($code==='0A000'&&strpos($e->getMessage(),'truncate')!==FALSE){return Nette\Database\ForeignKeyConstraintViolationException::from($e);}elseif($code==='23502'){return Nette\Database\NotNullConstraintViolationException::from($e);}elseif($code==='23503'){return Nette\Database\ForeignKeyConstraintViolationException::from($e);}elseif($code==='23505'){return Nette\Database\UniqueConstraintViolationException::from($e);}elseif($code==='08006'){return Nette\Database\ConnectionException::from($e);}else{return Nette\Database\DriverException::from($e);}}public function delimite($name){return'"'.str_replace('"','""',$name).'"';}public function formatBool($value){return$value?'TRUE':'FALSE';}public function formatDateTime($value){return$value->format("'Y-m-d H:i:s'");}public function formatDateInterval(\DateInterval$value){throw new Nette\NotSupportedException;}public function formatLike($value,$pos){$bs=substr($this->connection->quote('\\',\PDO::PARAM_STR),1,-1);$value=substr($this->connection->quote($value,\PDO::PARAM_STR),1,-1);$value=strtr($value,array('%'=>$bs.'%','_'=>$bs.'_','\\'=>'\\\\'));return($pos<=0?"'%":"'").$value.($pos>=0?"%'":"'");}public function applyLimit(&$sql,$limit,$offset){if($limit<0||$offset<0){throw new Nette\InvalidArgumentException('Negative offset or limit.');}if($limit!==NULL){$sql.=' LIMIT '.(int)$limit;}if($offset){$sql.=' OFFSET '.(int)$offset;}}public function normalizeRow($row){return$row;}public function getTables(){$tables=array();foreach($this->connection->query(" SELECT DISTINCT ON (c.relname) c.relname::varchar AS name, c.relkind = 'v' AS view, n.nspname::varchar || '.' || c.relname::varchar AS \"fullName\" FROM pg_catalog.pg_class AS c JOIN pg_catalog.pg_namespace AS n ON n.oid = c.relnamespace WHERE c.relkind IN ('r', 'v') AND n.nspname = ANY (pg_catalog.current_schemas(FALSE)) ORDER BY c.relname ")as$row){$tables[]=(array)$row;}return$tables;}public function getColumns($table){$columns=array();foreach($this->connection->query(" SELECT a.attname::varchar AS name, c.relname::varchar AS table, upper(t.typname) AS nativetype, CASE WHEN a.atttypmod = -1 THEN NULL ELSE a.atttypmod -4 END AS size, FALSE AS unsigned, NOT (a.attnotnull OR t.typtype = 'd' AND t.typnotnull) AS nullable, pg_catalog.pg_get_expr(ad.adbin, 'pg_catalog.pg_attrdef'::regclass)::varchar AS default, coalesce(co.contype = 'p' AND strpos(ad.adsrc, 'nextval') = 1, FALSE) AS autoincrement, coalesce(co.contype = 'p', FALSE) AS primary, substring(pg_catalog.pg_get_expr(ad.adbin, 'pg_catalog.pg_attrdef'::regclass) from 'nextval[(]''\"?([^''\"]+)') AS sequence FROM pg_catalog.pg_attribute AS a JOIN pg_catalog.pg_class AS c ON a.attrelid = c.oid JOIN pg_catalog.pg_type AS t ON a.atttypid = t.oid LEFT JOIN pg_catalog.pg_attrdef AS ad ON ad.adrelid = c.oid AND ad.adnum = a.attnum LEFT JOIN pg_catalog.pg_constraint AS co ON co.connamespace = c.relnamespace AND contype = 'p' AND co.conrelid = c.oid AND a.attnum = ANY(co.conkey) WHERE c.relkind IN ('r', 'v') AND c.oid = {$this->connection->quote($this->delimiteFQN($table))}::regclass AND a.attnum > 0 AND NOT a.attisdropped ORDER BY a.attnum ")as$row){$column=(array)$row;$column['vendor']=$column;unset($column['sequence']);$columns[]=$column;}return$columns;}public function getIndexes($table){$indexes=array();foreach($this->connection->query(" SELECT c2.relname::varchar AS name, i.indisunique AS unique, i.indisprimary AS primary, a.attname::varchar AS column FROM pg_catalog.pg_class AS c1 JOIN pg_catalog.pg_index AS i ON c1.oid = i.indrelid JOIN pg_catalog.pg_class AS c2 ON i.indexrelid = c2.oid LEFT JOIN pg_catalog.pg_attribute AS a ON c1.oid = a.attrelid AND a.attnum = ANY(i.indkey) WHERE c1.relkind = 'r' AND c1.oid = {$this->connection->quote($this->delimiteFQN($table))}::regclass ")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 array_values($indexes);}public function getForeignKeys($table){return$this->connection->query(" SELECT co.conname::varchar AS name, al.attname::varchar AS local, nf.nspname || '.' || cf.relname::varchar AS table, af.attname::varchar AS foreign FROM pg_catalog.pg_constraint AS co JOIN pg_catalog.pg_class AS cl ON co.conrelid = cl.oid JOIN pg_catalog.pg_class AS cf ON co.confrelid = cf.oid JOIN pg_catalog.pg_namespace AS nf ON nf.oid = cf.relnamespace JOIN pg_catalog.pg_attribute AS al ON al.attrelid = cl.oid AND al.attnum = co.conkey[1] JOIN pg_catalog.pg_attribute AS af ON af.attrelid = cf.oid AND af.attnum = co.confkey[1] WHERE co.contype = 'f' AND cl.oid = {$this->connection->quote($this->delimiteFQN($table))}::regclass AND nf.nspname = ANY (pg_catalog.current_schemas(FALSE)) ")->fetchAll();}public function getColumnTypes(\PDOStatement$statement){return Nette\Database\Helpers::detectTypes($statement);}/** @return bool **/public function isSupported($item){return$item===self::SUPPORT_SEQUENCE||$item===self::SUPPORT_SUBSELECT||$item===self::SUPPORT_SCHEMA;}/** @return string **/private function delimiteFQN($name){return implode('.',array_map(array($this,'delimite'),explode('.',$name)));}}connection=$connection;$this->fmtDateTime=isset($options['formatDateTime'])?$options['formatDateTime']:'U';}public function convertException(\PDOException$e){$code=isset($e->errorInfo[1])?$e->errorInfo[1]:NULL;$msg=$e->getMessage();if($code!==19){return Nette\Database\DriverException::from($e);}elseif(strpos($msg,'must be unique')!==FALSE||strpos($msg,'is not unique')!==FALSE||strpos($msg,'UNIQUE constraint failed')!==FALSE){return Nette\Database\UniqueConstraintViolationException::from($e);}elseif(strpos($msg,'may not be NULL')!==FALSE||strpos($msg,'NOT NULL constraint failed')!==FALSE){return Nette\Database\NotNullConstraintViolationException::from($e);}elseif(strpos($msg,'foreign key constraint failed')!==FALSE||strpos($msg,'FOREIGN KEY constraint failed')!==FALSE){return Nette\Database\ForeignKeyConstraintViolationException::from($e);}else{return Nette\Database\ConstraintViolationException::from($e);}}public function delimite($name){return'['.strtr($name,'[]',' ').']';}public function formatBool($value){return$value?'1':'0';}public function formatDateTime($value){return$value->format($this->fmtDateTime);}public function formatDateInterval(\DateInterval$value){throw new Nette\NotSupportedException;}public function formatLike($value,$pos){$value=addcslashes(substr($this->connection->quote($value),1,-1),'%_\\');return($pos<=0?"'%":"'").$value.($pos>=0?"%'":"'")." ESCAPE '\\'";}public function applyLimit(&$sql,$limit,$offset){if($limit<0||$offset<0){throw new Nette\InvalidArgumentException('Negative offset or limit.');}elseif($limit!==NULL||$offset){$sql.=' LIMIT '.($limit===NULL?'-1':(int)$limit).($offset?' OFFSET '.(int)$offset:'');}}public function normalizeRow($row){foreach($row as$key=>$value){unset($row[$key]);if($key[0]==='['||$key[0]==='"'){$key=substr($key,1,-1);}$row[$key]=$value;}return$row;}public function getTables(){$tables=array();foreach($this->connection->query(" SELECT name, type = 'view' as view FROM sqlite_master WHERE type IN ('table', 'view') AND name NOT LIKE 'sqlite_%' UNION ALL SELECT name, type = 'view' as view FROM sqlite_temp_master WHERE type IN ('table', 'view') AND name NOT LIKE 'sqlite_%' ORDER BY name ")as$row){$tables[]=array('name'=>$row->name,'view'=>(bool)$row->view);}return$tables;}public function getColumns($table){$meta=$this->connection->query(" SELECT sql FROM sqlite_master WHERE type = 'table' AND name = {$this->connection->quote($table)} UNION ALL SELECT sql FROM sqlite_temp_master WHERE type = 'table' AND name = {$this->connection->quote($table)} ")->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,'nativetype'=>strtoupper($type[0]),'size'=>isset($type[1])?(int)$type[1]:NULL,'unsigned'=>FALSE,'nullable'=>$row['notnull']=='0','default'=>$row['dflt_value'],'autoincrement'=>(bool)preg_match($pattern,$meta['sql']),'primary'=>$row['pk']>0,'vendor'=>(array)$row);}return$columns;}public function 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'];$indexes[$row['name']]['primary']=FALSE;}foreach($indexes 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 as$index=>$values){$column=$indexes[$index]['columns'][0];foreach($columns as$info){if($column==$info['name']){$indexes[$index]['primary']=(bool)$info['primary'];break;}}}if(!$indexes){foreach($columns as$column){if($column['vendor']['pk']){$indexes[]=array('name'=>'ROWID','unique'=>TRUE,'primary'=>TRUE,'columns'=>array($column['name']));break;}}}return array_values($indexes);}public function 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 array_values($keys);}public function getColumnTypes(\PDOStatement$statement){$types=array();$count=$statement->columnCount();for($col=0;$col<$count;$col++){$meta=$statement->getColumnMeta($col);if(isset($meta['sqlite:decl_type'])){if($meta['sqlite:decl_type']==='DATE'){$types[$meta['name']]=Nette\Database\IStructure::FIELD_UNIX_TIMESTAMP;}else{$types[$meta['name']]=Nette\Database\Helpers::detectType($meta['sqlite:decl_type']);}}elseif(isset($meta['native_type'])){$types[$meta['name']]=Nette\Database\Helpers::detectType($meta['native_type']);}}return$types;}/** @return bool **/public function isSupported($item){return$item===self::SUPPORT_MULTI_INSERT_AS_SELECT||$item===self::SUPPORT_SUBSELECT||$item===self::SUPPORT_MULTI_COLUMN_AS_OR_COND;}}connection=$connection;$this->version=$connection->getPdo()->getAttribute(\PDO::ATTR_SERVER_VERSION);}public function convertException(\PDOException$e){return Nette\Database\DriverException::from($e);}public function delimite($name){return'['.str_replace(']',']]',$name).']';}public function formatBool($value){return$value?'1':'0';}public function formatDateTime($value){return$value->format("'Y-m-d H:i:s'");}public function formatDateInterval(\DateInterval$value){throw new Nette\NotSupportedException;}public function formatLike($value,$pos){$value=strtr($value,array("'"=>"''",'%'=>'[%]','_'=>'[_]','['=>'[[]'));return($pos<=0?"'%":"'").$value.($pos>=0?"%'":"'");}public function applyLimit(&$sql,$limit,$offset){if($limit<0||$offset<0){throw new Nette\InvalidArgumentException('Negative offset or limit.');}elseif(version_compare($this->version,11,'<')){if($offset){throw new Nette\NotSupportedException('Offset is not supported by this database.');}elseif($limit!==NULL){$sql=preg_replace('#^\s*(SELECT(\s+DISTINCT|\s+ALL)?|UPDATE|DELETE)#i','$0 TOP '.(int)$limit,$sql,1,$count);if(!$count){throw new Nette\InvalidArgumentException('SQL query must begin with SELECT, UPDATE or DELETE command.');}}}elseif($limit!==NULL||$offset){$sql.=' OFFSET '.(int)$offset.' ROWS '.'FETCH NEXT '.(int)$limit.' ROWS ONLY';}}public function normalizeRow($row){return$row;}public function getTables(){$tables=array();foreach($this->connection->query(" SELECT name, CASE type WHEN 'U' THEN 0 WHEN 'V' THEN 1 END AS [view] FROM sys.objects WHERE type IN ('U', 'V') ")as$row){$tables[]=array('name'=>$row->name,'view'=>(bool)$row->view);}return$tables;}public function getColumns($table){$columns=array();foreach($this->connection->query(" SELECT c.name AS name, o.name AS [table], UPPER(t.name) AS nativetype, NULL AS size, 0 AS unsigned, c.is_nullable AS nullable, OBJECT_DEFINITION(c.default_object_id) AS [default], c.is_identity AS autoincrement, CASE WHEN i.index_id IS NULL THEN 0 ELSE 1 END AS [primary] FROM sys.columns c JOIN sys.objects o ON c.object_id = o.object_id LEFT JOIN sys.types t ON c.user_type_id = t.user_type_id LEFT JOIN sys.key_constraints k ON o.object_id = k.parent_object_id AND k.type = 'PK' LEFT JOIN sys.index_columns i ON k.parent_object_id = i.object_id AND i.index_id = k.unique_index_id AND i.column_id = c.column_id WHERE o.type IN ('U', 'V') AND o.name = {$this->connection->quote($table)} ")as$row){$row=(array)$row;$row['vendor']=$row;$row['unsigned']=(bool)$row['unsigned'];$row['nullable']=(bool)$row['nullable'];$row['autoincrement']=(bool)$row['autoincrement'];$row['primary']=(bool)$row['primary'];$columns[]=$row;}return$columns;}public function getIndexes($table){$indexes=array();foreach($this->connection->query(" SELECT i.name AS name, CASE WHEN i.is_unique = 1 OR i.is_unique_constraint = 1 THEN 1 ELSE 0 END AS [unique], i.is_primary_key AS [primary], c.name AS [column] FROM sys.indexes i JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id JOIN sys.tables t ON i.object_id = t.object_id WHERE t.name = {$this->connection->quote($table)} ORDER BY i.index_id, ic.index_column_id ")as$row){$indexes[$row->name]['name']=$row->name;$indexes[$row->name]['unique']=(bool)$row->unique;$indexes[$row->name]['primary']=(bool)$row->primary;$indexes[$row->name]['columns'][]=$row->column;}return array_values($indexes);}public function getForeignKeys($table){$keys=array();foreach($this->connection->query(" SELECT fk.name AS name, cl.name AS local, tf.name AS [table], cf.name AS [column] FROM sys.foreign_keys fk JOIN sys.foreign_key_columns fkc ON fk.object_id = fkc.constraint_object_id JOIN sys.tables tl ON fkc.parent_object_id = tl.object_id JOIN sys.columns cl ON fkc.parent_object_id = cl.object_id AND fkc.parent_column_id = cl.column_id JOIN sys.tables tf ON fkc.referenced_object_id = tf.object_id JOIN sys.columns cf ON fkc.referenced_object_id = cf.object_id AND fkc.referenced_column_id = cf.column_id WHERE tl.name = {$this->connection->quote($table)} ")as$row){$keys[$row->name]=(array)$row;}return array_values($keys);}public function getColumnTypes(\PDOStatement$statement){$types=array();$count=$statement->columnCount();for($col=0;$col<$count;$col++){$meta=$statement->getColumnMeta($col);if(isset($meta['sqlsrv:decl_type'])&&$meta['sqlsrv:decl_type']!=='timestamp'){$types[$meta['name']]=Nette\Database\Helpers::detectType($meta['sqlsrv:decl_type']);}elseif(isset($meta['native_type'])){$types[$meta['name']]=Nette\Database\Helpers::detectType($meta['native_type']);}}return$types;}/** @return bool **/public function isSupported($item){return$item===self::SUPPORT_SUBSELECT;}}IStructure::FIELD_TEXT,'BYTEA|BLOB|BIN'=>IStructure::FIELD_BINARY,'TEXT|CHAR|POINT|INTERVAL'=>IStructure::FIELD_TEXT,'YEAR|BYTE|COUNTER|SERIAL|INT|LONG|SHORT|^TINY$'=>IStructure::FIELD_INTEGER,'CURRENCY|REAL|MONEY|FLOAT|DOUBLE|DECIMAL|NUMERIC|NUMBER'=>IStructure::FIELD_FLOAT,'^TIME$'=>IStructure::FIELD_TIME,'TIME'=>IStructure::FIELD_DATETIME,'DATE(?!RANGE)'=>IStructure::FIELD_DATE,'BOOL'=>IStructure::FIELD_BOOL);/** @return void **/public static function dumpResult(ResultSet$result){echo"\n\n\n";if(!$result->getColumnCount()){echo"\t\n\t\t\n\t\t\n\t\n
".htmlSpecialChars($result->getQueryString(),ENT_IGNORE,'UTF-8')."
Affected rows:",$result->getRowCount(),"
\n";return;}$i=0;foreach($result as$row){if($i===0){echo"\n\t\n\t\t#row\n";foreach($row as$col=>$foo){echo"\t\t".htmlSpecialChars($col,ENT_NOQUOTES,'UTF-8')."\n";}echo"\t\n\n\n";}echo"\t\n\t\t",$i,"\n";foreach($row as$col){echo"\t\t",htmlSpecialChars($col,ENT_NOQUOTES,'UTF-8'),"\n";}echo"\t\n";$i++;}if($i===0){echo"\t\n\t\tempty result set\n\t\n\n";}else{echo"\n\n";}}/** @return string **/public static function dumpSql($sql,array$params=NULL,Connection$connection=NULL){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|[RI]?LIKE|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,ENT_IGNORE,'UTF-8');$sql=preg_replace_callback("#(/\\*.+?\\*/)|(\\*\\*.+?\\*\\*)|(?<=[\\s,(])($keywords1)(?=[\\s,)])|(?<=[\\s,(=])($keywords2)(?=[\\s,)=])#is",function($matches){if(!empty($matches[1])){return''.$matches[1].'';}elseif(!empty($matches[2])){return''.$matches[2].'';}elseif(!empty($matches[3])){return''.$matches[3].'';}elseif(!empty($matches[4])){return''.$matches[4].'';}},$sql);$sql=preg_replace_callback('#\?#',function()use($params,$connection){static$i=0;if(!isset($params[$i])){return'?';}$param=$params[$i++];if(is_string($param)&&(preg_match('#[^\x09\x0A\x0D\x20-\x7E\xA0-\x{10FFFF}]#u',$param)||preg_last_error())){return'<binary>';}elseif(is_string($param)){$length=Nette\Utils\Strings::length($param);$truncated=Nette\Utils\Strings::truncate($param,Helpers::$maxLength);$text=htmlspecialchars($connection?$connection->quote($truncated):'\''.$truncated.'\'',ENT_NOQUOTES,'UTF-8');return''.$text.'';}elseif(is_resource($param)){$type=get_resource_type($param);if($type==='stream'){$info=stream_get_meta_data($param);}return'<'.htmlSpecialChars($type,ENT_NOQUOTES,'UTF-8').' resource> ';}else{return htmlspecialchars($param,ENT_NOQUOTES,'UTF-8');}},$sql);return'
'.trim($sql)."
\n";}/** @return array **/public static function detectTypes(\PDOStatement$statement){$types=array();$count=$statement->columnCount();for($col=0;$col<$count;$col++){$meta=$statement->getColumnMeta($col);if(isset($meta['native_type'])){$types[$meta['name']]=self::detectType($meta['native_type']);}}return$types;}/** @return string **/public static function detectType($type){static$cache;if(!isset($cache[$type])){$cache[$type]='string';foreach(self::$typePatterns as$s=>$val){if(preg_match("#$s#i",$type)){return$cache[$type]=$val;}}}return$cache[$type];}/** @return int count of commands **/public static function loadFromFile(Connection$connection,$file){@set_time_limit(0);$handle=@fopen($file,'r');if(!$handle){throw new Nette\FileNotFoundException("Cannot open file '$file'.");}$count=0;$delimiter=';';$sql='';$pdo=$connection->getPdo();while(!feof($handle)){$s=rtrim(fgets($handle));if(!strncasecmp($s,'DELIMITER ',10)){$delimiter=substr($s,10);}elseif(substr($s,-strlen($delimiter))===$delimiter){$sql.=substr($s,0,-strlen($delimiter));$pdo->exec($sql);$sql='';$count++;}else{$sql.=$s."\n";}}if(trim($sql)!==''){$pdo->exec($sql);$count++;}fclose($handle);return$count;}public static function createDebugPanel($connection,$explain=TRUE,$name=NULL){$panel=new Nette\Bridges\DatabaseTracy\ConnectionPanel($connection);$panel->explain=$explain;$panel->name=$name;Tracy\Debugger::getBar()->addPanel($panel);return$panel;}/** @return array **/public static function toPairs(array$rows,$key=NULL,$value=NULL){if(!$rows){return array();}$keys=array_keys((array)reset($rows));if(!count($keys)){throw new\LogicException('Result set does not contain any column.');}elseif($key===NULL&&$value===NULL){if(count($keys)===1){list($value)=$keys;}else{list($key,$value)=$keys;}}$return=array();if($key===NULL){foreach($rows as$row){$return[]=($value===NULL?$row:$row[$value]);}}else{foreach($rows as$row){$return[is_object($row[$key])?(string)$row[$key]:$row[$key]]=($value===NULL?$row:$row[$value]);}}return$return;}}connection=$connection;$this->supplementalDriver=$connection->getSupplementalDriver();$this->queryString=$queryString;$this->params=$params;try{if(substr($queryString,0,2)==='::'){$connection->getPdo()->{substr($queryString,2)}();}elseif($queryString!==NULL){static$types=array('boolean'=>PDO::PARAM_BOOL,'integer'=>PDO::PARAM_INT,'resource'=>PDO::PARAM_LOB,'NULL'=>PDO::PARAM_NULL);$this->pdoStatement=$connection->getPdo()->prepare($queryString);foreach($params as$key=>$value){$type=gettype($value);$this->pdoStatement->bindValue(is_int($key)?$key+1:$key,$value,isset($types[$type])?$types[$type]:PDO::PARAM_STR);}$this->pdoStatement->setFetchMode(PDO::FETCH_ASSOC);$this->pdoStatement->execute();}}catch(\PDOException$e){$e=$this->supplementalDriver->convertException($e);$e->queryString=$queryString;throw$e;}$this->time=microtime(TRUE)-$time;}/** @return Connection **/public function getConnection(){return$this->connection;}/** @return \PDOStatement **/public function getPdoStatement(){return$this->pdoStatement;}/** @return string **/public function getQueryString(){return$this->queryString;}/** @return array **/public function getParameters(){return$this->params;}/** @return int **/public function getColumnCount(){return$this->pdoStatement?$this->pdoStatement->columnCount():NULL;}/** @return int **/public function getRowCount(){return$this->pdoStatement?$this->pdoStatement->rowCount():NULL;}/** @return float **/public function getTime(){return$this->time;}/** @return array **/public function normalizeRow($row){if($this->types===NULL){$this->types=(array)$this->supplementalDriver->getColumnTypes($this->pdoStatement);}foreach($this->types as$key=>$type){$value=$row[$key];if($value===NULL||$value===FALSE||$type===IStructure::FIELD_TEXT){}elseif($type===IStructure::FIELD_INTEGER){$row[$key]=is_float($tmp=$value*1)?$value:$tmp;}elseif($type===IStructure::FIELD_FLOAT){if(($pos=strpos($value,'.'))!==FALSE){$value=rtrim(rtrim($pos===0?"0$value":$value,'0'),'.');}$float=(float)$value;$row[$key]=(string)$float===$value?$float:$value;}elseif($type===IStructure::FIELD_BOOL){$row[$key]=((bool)$value)&&$value!=='f'&&$value!=='F';}elseif($type===IStructure::FIELD_DATETIME||$type===IStructure::FIELD_DATE||$type===IStructure::FIELD_TIME){$row[$key]=new Nette\Utils\DateTime($value);}elseif($type===IStructure::FIELD_TIME_INTERVAL){preg_match('#^(-?)(\d+)\D(\d+)\D(\d+)\z#',$value,$m);$row[$key]=new\DateInterval("PT$m[2]H$m[3]M$m[4]S");$row[$key]->invert=(int)(bool)$m[1];}elseif($type===IStructure::FIELD_UNIX_TIMESTAMP){$row[$key]=Nette\Utils\DateTime::from($value);}}return$this->supplementalDriver->normalizeRow($row);}/** @return void **/public function dump(){Helpers::dumpResult($this);}public function rewind(){if($this->result===FALSE){throw new Nette\InvalidStateException('Nette\\Database\\ResultSet implements only one way iterator.');}}public function current(){return$this->result;}public function key(){return$this->resultKey;}public function next(){$this->result=FALSE;}public function valid(){if($this->result){return TRUE;}return$this->fetch()!==FALSE;}public function fetch(){$data=$this->pdoStatement?$this->pdoStatement->fetch():NULL;if(!$data){$this->pdoStatement->closeCursor();return FALSE;}$row=new Row;foreach($this->normalizeRow($data)as$key=>$value){if($key!==''){$row->$key=$value;}}if($this->result===NULL&&count($data)!==$this->pdoStatement->columnCount()){trigger_error('Found duplicate columns in database result set.',E_USER_NOTICE);}$this->resultKey++;return$this->result=$row;}/** @return mixed|FALSE **/public function fetchField($column=0){$row=$this->fetch();return$row?$row[$column]:FALSE;}public function fetchPairs($key=NULL,$value=NULL){return Helpers::toPairs($this->fetchAll(),$key,$value);}public function fetchAll(){if($this->results===NULL){$this->results=iterator_to_array($this);}return$this->results;}public function fetchAssoc($path){return Nette\Utils\Arrays::associate($this->fetchAll(),$path);}}$key;}/** @return bool **/public function offsetExists($key){if(is_int($key)){return(bool)current(array_slice((array)$this,$key,1));}return parent::offsetExists($key);}}value=(string)$value;$this->parameters=$parameters;}/** @return array **/public function getParameters(){return$this->parameters;}/** @return string **/public function __toString(){return$this->value;}}connection=$connection;$this->driver=$connection->getSupplementalDriver();}/** @return array of [sql, params] **/public function process($params){$this->params=$params;$this->counter=0;$prev=-1;$this->remaining=array();$this->arrayMode=NULL;$res=array();while($this->countercounter++];if(($this->counter===2&&count($params)===2)||!is_scalar($param)){$res[]=$this->formatValue($param,'auto');$this->arrayMode=NULL;}elseif(is_string($param)&&$this->counter>$prev+1){$prev=$this->counter;$this->arrayMode=NULL;$res[]=Nette\Utils\Strings::replace($param,'~\'[^\']*+\'|"[^"]*+"|\?[a-z]*|^\s*+(?:INSERT|REPLACE)\b|\b(?:SET|WHERE|HAVING|ORDER BY|GROUP BY|KEY UPDATE)(?=[\s?]*+\z)|/\*.*?\*/|--[^\n]*~si',array($this,'callback'));}else{throw new Nette\InvalidArgumentException('There are more parameters than placeholders.');}}return array(implode(' ',$res),$this->remaining);}public function callback($m){$m=$m[0];if($m[0]==='?'){if($this->counter>=count($this->params)){throw new Nette\InvalidArgumentException('There are more placeholders than passed parameters.');}return$this->formatValue($this->params[$this->counter++],substr($m,1)?:'auto');}elseif($m[0]==="'"||$m[0]==='"'||$m[0]==='/'||$m[0]==='-'){return$m;}else{static$modes=array('INSERT'=>'values','REPLACE'=>'values','KEY UPDATE'=>'set','SET'=>'set','WHERE'=>'and','HAVING'=>'and','ORDER BY'=>'order','GROUP BY'=>'order');$this->arrayMode=$modes[ltrim(strtoupper($m))];return$m;}}private function formatValue($value,$mode=NULL){if(!$mode||$mode==='auto'){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 rtrim(rtrim(number_format($value,10,'.',''),'0'),'.');}elseif(is_bool($value)){return$this->driver->formatBool($value);}elseif($value===NULL){return'NULL';}elseif($value instanceof Table\IRow){return$this->formatValue($value->getPrimary());}elseif($value instanceof SqlLiteral){$prep=clone$this;list($res,$params)=$prep->process(array_merge(array($value->__toString()),$value->getParameters()));$this->remaining=array_merge($this->remaining,$params);return$res;}elseif($value instanceof\DateTime||$value instanceof\DateTimeInterface){return$this->driver->formatDateTime($value);}elseif($value instanceof\DateInterval){return$this->driver->formatDateInterval($value);}elseif(is_object($value)&&method_exists($value,'__toString')){return$this->formatValue((string)$value);}elseif(is_resource($value)){$this->remaining[]=$value;return'?';}}elseif($mode==='name'){if(!is_string($value)){$type=gettype($value);throw new Nette\InvalidArgumentException("Placeholder ?$mode expects string, $type given.");}return$this->delimite($value);}if($value instanceof\Traversable&&!$value instanceof Table\IRow){$value=iterator_to_array($value);}if(is_array($value)){$vx=$kx=array();if($mode==='auto'){$mode=$this->arrayMode;}if($mode==='values'){if(array_key_exists(0,$value)){foreach($value[0]as$k=>$v){$kx[]=$this->delimite($k);}foreach($value as$val){$vx2=array();foreach($val as$v){$vx2[]=$this->formatValue($v);}$vx[]=implode(', ',$vx2);}$select=$this->driver->isSupported(ISupplementalDriver::SUPPORT_MULTI_INSERT_AS_SELECT);return'('.implode(', ',$kx).($select?') SELECT ':') VALUES (').implode($select?' UNION ALL SELECT ':'), (',$vx).($select?'':')');}foreach($value as$k=>$v){$kx[]=$this->delimite($k);$vx[]=$this->formatValue($v);}return'('.implode(', ',$kx).') VALUES ('.implode(', ',$vx).')';}elseif(!$mode||$mode==='set'){foreach($value as$k=>$v){if(is_int($k)){$vx[]=is_array($v)?'('.$this->formatValue($v).')':$this->formatValue($v);}elseif(substr($k,-1)==='='){$k2=$this->delimite(substr($k,0,-2));$vx[]=$k2.'='.$k2.' '.substr($k,-2,1).' '.$this->formatValue($v);}else{$vx[]=$this->delimite($k).'='.$this->formatValue($v);}}return implode(', ',$vx);}elseif($mode==='and'||$mode==='or'){foreach($value as$k=>$v){if(is_int($k)){$vx[]=$this->formatValue($v);continue;}list($k,$operator)=explode(' ',$k.' ');$k=$this->delimite($k);if(is_array($v)){if($v){$vx[]=$k.' '.($operator?$operator.' ':'').'IN ('.$this->formatValue(array_values($v)).')';}elseif($operator==='NOT'){}else{$vx[]='1=0';}}else{$v=$this->formatValue($v);$vx[]=$k.' '.($operator?:($v==='NULL'?'IS':'=')).' '.$v;}}return$value?'('.implode(') '.strtoupper($mode).' (',$vx).')':'1=1';}elseif($mode==='order'){foreach($value as$k=>$v){$vx[]=$this->delimite($k).($v>0?'':' DESC');}return implode(', ',$vx);}else{throw new Nette\InvalidArgumentException("Unknown placeholder ?$mode.");}}elseif(in_array($mode,array('and','or','set','values','order'),TRUE)){$type=gettype($value);throw new Nette\InvalidArgumentException("Placeholder ?$mode expects array or Traversable object, $type given.");}elseif($mode&&$mode!=='auto'){throw new Nette\InvalidArgumentException("Unknown placeholder ?$mode.");}else{throw new Nette\InvalidArgumentException('Unexpected type of parameter: '.(is_object($value)?get_class($value):gettype($value)));}}private function delimite($name){return implode('.',array_map(array($this->driver,'delimite'),explode('.',$name)));}}connection=$connection;$this->cache=new Nette\Caching\Cache($cacheStorage,'Nette.Database.Structure.'.md5($this->connection->getDsn()));}public function getTables(){$this->needStructure();return$this->structure['tables'];}public function getColumns($table){$this->needStructure();$table=$this->resolveFQTableName($table);return$this->structure['columns'][$table];}public function getPrimaryKey($table){$this->needStructure();$table=$this->resolveFQTableName($table);if(!isset($this->structure['primary'][$table])){return NULL;}return$this->structure['primary'][$table];}public function getPrimaryKeySequence($table){$this->needStructure();$table=$this->resolveFQTableName($table);if(!$this->connection->getSupplementalDriver()->isSupported(ISupplementalDriver::SUPPORT_SEQUENCE)){return NULL;}$primary=$this->getPrimaryKey($table);if(!$primary||is_array($primary)){return NULL;}foreach($this->structure['columns'][$table]as$columnMeta){if($columnMeta['name']===$primary){return isset($columnMeta['vendor']['sequence'])?$columnMeta['vendor']['sequence']:NULL;}}return NULL;}public function getHasManyReference($table,$targetTable=NULL){$this->needStructure();$table=$this->resolveFQTableName($table);if($targetTable){$targetTable=$this->resolveFQTableName($targetTable);foreach($this->structure['hasMany'][$table]as$key=>$value){if(strtolower($key)===$targetTable){return$this->structure['hasMany'][$table][$key];}}return NULL;}else{if(!isset($this->structure['hasMany'][$table])){return array();}return$this->structure['hasMany'][$table];}}public function getBelongsToReference($table,$column=NULL){$this->needStructure();$table=$this->resolveFQTableName($table);if($column){$column=strtolower($column);if(!isset($this->structure['belongsTo'][$table][$column])){return NULL;}return$this->structure['belongsTo'][$table][$column];}else{if(!isset($this->structure['belongsTo'][$table])){return array();}return$this->structure['belongsTo'][$table];}}public function rebuild(){$this->structure=$this->loadStructure();$this->cache->save('structure',$this->structure);}public function isRebuilt(){return$this->isRebuilt;}protected function needStructure(){if($this->structure!==NULL){return;}$this->structure=$this->cache->load('structure',array($this,'loadStructure'));}public function loadStructure(){$driver=$this->connection->getSupplementalDriver();$structure=array();$structure['tables']=$driver->getTables();foreach($structure['tables']as$tablePair){if(isset($tablePair['fullName'])){$table=$tablePair['fullName'];$structure['aliases'][strtolower($tablePair['name'])]=strtolower($table);}else{$table=$tablePair['name'];}$structure['columns'][strtolower($table)]=$columns=$driver->getColumns($table);if(!$tablePair['view']){$structure['primary'][strtolower($table)]=$this->analyzePrimaryKey($columns);$this->analyzeForeignKeys($structure,$table);}}if(isset($structure['hasMany'])){foreach($structure['hasMany']as&$table){uksort($table,function($a,$b){return strlen($a)-strlen($b);});}}$this->isRebuilt=TRUE;return$structure;}protected function analyzePrimaryKey(array$columns){$primary=array();foreach($columns as$column){if($column['primary']){$primary[]=$column['name'];}}if(count($primary)===0){return NULL;}elseif(count($primary)===1){return reset($primary);}else{return$primary;}}protected function analyzeForeignKeys(&$structure,$table){$lowerTable=strtolower($table);foreach($this->connection->getSupplementalDriver()->getForeignKeys($table)as$row){$structure['belongsTo'][$lowerTable][$row['local']]=$row['table'];$structure['hasMany'][strtolower($row['table'])][$table][]=$row['local'];}if(isset($structure['belongsTo'][$lowerTable])){uksort($structure['belongsTo'][$lowerTable],function($a,$b){return strlen($a)-strlen($b);});}}protected function resolveFQTableName($table){$name=strtolower($table);if(isset($this->structure['columns'][$name])){return$name;}if(isset($this->structure['aliases'][$name])){return$this->structure['aliases'][$name];}if(!$this->isRebuilt()){$this->rebuild();return$this->resolveFQTableName($table);}throw new Nette\InvalidArgumentException("Table '$name' does not exist.");}}data=$data;$this->table=$table;}public function setTable(Selection$table){$this->table=$table;}public function getTable(){return$this->table;}public function __toString(){try{return(string)$this->getPrimary();}catch(\Throwable$e){}catch(\Exception$e){}if(isset($e)){if(func_num_args()){throw$e;}trigger_error("Exception in ".__METHOD__."(): {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}",E_USER_ERROR);}}/** @return array **/public function toArray(){$this->accessColumn(NULL);return$this->data;}/** @return mixed possible int, string, array, object (Nette\Utils\DateTime) **/public function getPrimary($need=TRUE){$primary=$this->table->getPrimary($need);if($primary===NULL){return NULL;}elseif(!is_array($primary)){if(isset($this->data[$primary])){return$this->data[$primary];}elseif($need){throw new Nette\InvalidStateException("Row does not contain primary $primary column data.");}else{return NULL;}}else{$primaryVal=array();foreach($primary as$key){if(!isset($this->data[$key])){if($need){throw new Nette\InvalidStateException("Row does not contain primary $key column data.");}else{return NULL;}}$primaryVal[$key]=$this->data[$key];}return$primaryVal;}}/** @return string **/public function getSignature($need=TRUE){return implode('|',(array)$this->getPrimary($need));}/** @return IRow or NULL if the row does not exist **/public function ref($key,$throughColumn=NULL){$row=$this->table->getReferencedTable($this,$key,$throughColumn);if($row===FALSE){throw new Nette\MemberAccessException("No reference found for \${$this->table->name}->ref($key).");}return$row;}/** @return GroupedSelection **/public function related($key,$throughColumn=NULL){$groupedSelection=$this->table->getReferencingTable($key,$throughColumn,$this[$this->table->getPrimary()]);if(!$groupedSelection){throw new Nette\MemberAccessException("No reference found for \${$this->table->name}->related($key).");}return$groupedSelection;}/** @return bool **/public function update($data){if($data instanceof\Traversable){$data=iterator_to_array($data);}$primary=$this->getPrimary();if(!is_array($primary)){$primary=array($this->table->getPrimary()=>$primary);}$selection=$this->table->createSelectionInstance()->wherePrimary($primary);if($selection->update($data)){if($tmp=array_intersect_key($data,$primary)){$selection=$this->table->createSelectionInstance()->wherePrimary($tmp+$primary);}$selection->select('*');if(($row=$selection->fetch())===FALSE){throw new Nette\InvalidStateException('Database refetch failed; row does not exist!');}$this->data=$row->data;return TRUE;}else{return FALSE;}}/** @return int number of affected rows **/public function delete(){$res=$this->table->createSelectionInstance()->wherePrimary($this->getPrimary())->delete();if($res>0&&($signature=$this->getSignature(FALSE))){unset($this->table[$signature]);}return$res;}public function getIterator(){$this->accessColumn(NULL);return new\ArrayIterator($this->data);}/** @return void **/public function offsetSet($key,$value){$this->__set($key,$value);}/** @return string **/public function offsetGet($key){return$this->__get($key);}/** @return bool **/public function offsetExists($key){return$this->__isset($key);}/** @return void **/public function offsetUnset($key){$this->__unset($key);}public function __set($key,$value){throw new Nette\DeprecatedException('ActiveRow is read-only; use update() method instead.');}/** @return ActiveRow|mixed **/public function&__get($key){if($this->accessColumn($key)){return$this->data[$key];}$referenced=$this->table->getReferencedTable($this,$key);if($referenced!==FALSE){$this->accessColumn($key,FALSE);return$referenced;}$this->removeAccessColumn($key);$hint=Nette\Utils\ObjectMixin::getSuggestion(array_keys($this->data),$key);throw new Nette\MemberAccessException("Cannot read an undeclared column '$key'".($hint?", did you mean '$hint'?":'.'));}public function __isset($key){if($this->accessColumn($key)){return isset($this->data[$key]);}$this->removeAccessColumn($key);return FALSE;}public function __unset($key){throw new Nette\DeprecatedException('ActiveRow is read-only.');}public function accessColumn($key,$selectColumn=TRUE){if($this->table->accessColumn($key,$selectColumn)&&!$this->dataRefreshed){if(!isset($this->table[$this->getSignature()])){throw new Nette\InvalidStateException('Database refetch failed; row does not exist!');}$this->data=$this->table[$this->getSignature()]->data;$this->dataRefreshed=TRUE;}return isset($this->data[$key])||array_key_exists($key,$this->data);}protected function removeAccessColumn($key){$this->table->removeAccessColumn($key);}}refTable=$refTable;$this->column=$column;parent::__construct($context,$conventions,$tableName,$cacheStorage);}/** @return GroupedSelection **/public function setActive($active){$this->active=$active;return$this;}public function select($columns){if(!$this->sqlBuilder->getSelect()){$this->sqlBuilder->addSelect("$this->name.$this->column");}return call_user_func_array('parent::select',func_get_args());}public function order($columns){if(!$this->sqlBuilder->getOrder()){$this->sqlBuilder->addOrder("$this->name.$this->column".(preg_match('~\bDESC\z~i',$columns)?' DESC':''));}return call_user_func_array('parent::order',func_get_args());}public function 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 as$row){$aggregation[$row[$this->column]]=$row;}}if(isset($aggregation[$this->active])){foreach($aggregation[$this->active]as$val){return$val;}}}public function count($column=NULL){$return=parent::count($column);return isset($return)?$return:0;}protected function execute(){if($this->rows!==NULL){$this->observeCache=$this;return;}$accessedColumns=$this->accessedColumns;$this->loadRefCache();if(!isset($this->refCacheCurrent['data'])){$this->accessedColumns=$accessedColumns;$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);$data=array();$offset=array();$this->accessColumn($this->column);foreach((array)$this->rows as$key=>$row){$ref=&$data[$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->refCacheCurrent['data']=$data;$this->data=&$this->refCacheCurrent['data'][$this->active];}$this->observeCache=$this;if($this->data===NULL){$this->data=array();}else{foreach($this->data as$row){$row->setTable($this);}reset($this->data);}}protected function getRefTable(&$refPath){$refObj=$this->refTable;$refPath=$this->name.'.';while($refObj instanceof self){$refPath.=$refObj->name.'.';$refObj=$refObj->refTable;}return$refObj;}protected function loadRefCache(){$hash=$this->getSpecificCacheKey();$referencing=&$this->refCache['referencing'][$this->getGeneralCacheKey()];$this->observeCache=&$referencing['observeCache'];$this->refCacheCurrent=&$referencing[$hash];$this->accessedColumns=&$referencing[$hash]['accessed'];$this->specificCacheKey=&$referencing[$hash]['specificCacheKey'];$this->rows=&$referencing[$hash]['rows'];if(isset($referencing[$hash]['data'][$this->active])){$this->data=&$referencing[$hash]['data'][$this->active];}}protected function emptyResultSet($saveCache=TRUE,$deleteRererencedCache=TRUE){parent::emptyResultSet($saveCache,FALSE);}public function insert($data){if($data instanceof\Traversable&&!$data instanceof Selection){$data=iterator_to_array($data);}if(Nette\Utils\Arrays::isList($data)){foreach(array_keys($data)as$key){$data[$key][$this->column]=$this->active;}}else{$data[$this->column]=$this->active;}return parent::insert($data);}public function 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;}public function delete(){$builder=$this->sqlBuilder;$this->sqlBuilder=clone$this->sqlBuilder;$this->where($this->column,$this->active);$return=parent::delete();$this->sqlBuilder=$builder;return$return;}}context=$context;$this->conventions=$conventions;$this->name=$tableName;$this->cache=$cacheStorage?new Nette\Caching\Cache($cacheStorage,'Nette.Database.'.md5($context->getConnection()->getDsn())):NULL;$this->primary=$conventions->getPrimary($tableName);$this->sqlBuilder=new SqlBuilder($tableName,$context);$this->refCache=&$this->getRefTable($refPath)->globalRefCache[$refPath];}public function __destruct(){$this->saveCacheState();}public function __clone(){$this->sqlBuilder=clone$this->sqlBuilder;}public function getConnection(){trigger_error(__METHOD__.'() is deprecated; use DI container to autowire Nette\Database\Connection instead.',E_USER_DEPRECATED);return$this->context->getConnection();}public function getDatabaseReflection(){trigger_error(__METHOD__.'() is deprecated; use DI container to autowire Nette\Database\IConventions instead.',E_USER_DEPRECATED);return$this->conventions;}/** @return string **/public function getName(){return$this->name;}/** @return string|array|NULL **/public function getPrimary($need=TRUE){if($this->primary===NULL&&$need){throw new\LogicException("Table '{$this->name}' does not have a primary key.");}return$this->primary;}/** @return string **/public function getPrimarySequence(){if($this->primarySequence===FALSE){$this->primarySequence=$this->context->getStructure()->getPrimaryKeySequence($this->name);}return$this->primarySequence;}/** @return self **/public function setPrimarySequence($sequence){$this->primarySequence=$sequence;return$this;}/** @return string **/public function getSql(){return$this->sqlBuilder->buildSelectQuery($this->getPreviousAccessedColumns());}/** @return array|false **/public function getPreviousAccessedColumns(){if($this->cache&&$this->previousAccessedColumns===NULL){$this->accessedColumns=$this->previousAccessedColumns=$this->cache->load($this->getGeneralCacheKey());if($this->previousAccessedColumns===NULL){$this->previousAccessedColumns=array();}}return array_keys(array_filter((array)$this->previousAccessedColumns));}/** @return SqlBuilder **/public function getSqlBuilder(){return$this->sqlBuilder;}/** @return IRow or FALSE if there is no such row **/public function get($key){$clone=clone$this;return$clone->wherePrimary($key)->fetch();}public function fetch(){$this->execute();$return=current($this->data);next($this->data);return$return;}/** @return mixed|FALSE **/public function fetchField($column=NULL){if($column){$this->select($column);}$row=$this->fetch();if($row){return$column?$row[$column]:current($row->toArray());}return FALSE;}public function fetchPairs($key=NULL,$value=NULL){return Nette\Database\Helpers::toPairs($this->fetchAll(),$key,$value);}public function fetchAll(){return iterator_to_array($this);}public function fetchAssoc($path){$rows=array_map('iterator_to_array',$this->fetchAll());return Nette\Utils\Arrays::associate($rows,$path);}/** @return self **/public function select($columns){$this->emptyResultSet();call_user_func_array(array($this->sqlBuilder,'addSelect'),func_get_args());return$this;}/** @return self **/public function wherePrimary($key){if(is_array($this->primary)&&Nette\Utils\Arrays::isList($key)){if(isset($key[0])&&is_array($key[0])){$this->where($this->primary,$key);}else{foreach($this->primary as$i=>$primary){$this->where($this->name.'.'.$primary,$key[$i]);}}}elseif(is_array($key)&&!Nette\Utils\Arrays::isList($key)){$this->where($key);}else{$this->where($this->name.'.'.$this->getPrimary(),$key);}return$this;}/** @return self **/public function where($condition,$parameters=array()){if(is_array($condition)&&$parameters===array()){foreach($condition as$key=>$val){if(is_int($key)){$this->where($val);}else{$this->where($key,$val);}}return$this;}$this->emptyResultSet();call_user_func_array(array($this->sqlBuilder,'addWhere'),func_get_args());return$this;}/** @return self **/public function order($columns){$this->emptyResultSet();call_user_func_array(array($this->sqlBuilder,'addOrder'),func_get_args());return$this;}/** @return self **/public function limit($limit,$offset=NULL){$this->emptyResultSet();$this->sqlBuilder->setLimit($limit,$offset);return$this;}/** @return self **/public function page($page,$itemsPerPage,&$numOfPages=NULL){if(func_num_args()>2){$numOfPages=(int)ceil($this->count('*')/$itemsPerPage);}return$this->limit($itemsPerPage,($page-1)*$itemsPerPage);}/** @return self **/public function group($columns){$this->emptyResultSet();call_user_func_array(array($this->sqlBuilder,'setGroup'),func_get_args());return$this;}/** @return self **/public function having($having){$this->emptyResultSet();call_user_func_array(array($this->sqlBuilder,'setHaving'),func_get_args());return$this;}/** @return string **/public function aggregation($function){$selection=$this->createSelectionInstance();$selection->getSqlBuilder()->importConditions($this->getSqlBuilder());$selection->select($function);foreach($selection->fetch()as$val){return$val;}}/** @return int **/public function count($column=NULL){if(!$column){$this->execute();return count($this->data);}return$this->aggregation("COUNT($column)");}/** @return int **/public function min($column){return$this->aggregation("MIN($column)");}/** @return int **/public function max($column){return$this->aggregation("MAX($column)");}/** @return int **/public function sum($column){return$this->aggregation("SUM($column)");}protected function execute(){if($this->rows!==NULL){return;}$this->observeCache=$this;if($this->primary===NULL&&$this->sqlBuilder->getSelect()===NULL){throw new Nette\InvalidStateException('Table with no primary key requires an explicit select clause.');}try{$result=$this->query($this->getSql());}catch(Nette\Database\DriverException$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;foreach($result->getPdoStatement()as$key=>$row){$row=$this->createRow($result->normalizeRow($row));$primary=$row->getSignature(FALSE);$usedPrimary=$usedPrimary&&(string)$primary!=='';$this->rows[$usedPrimary?$primary:$key]=$row;}$this->data=$this->rows;if($usedPrimary&&$this->accessedColumns!==FALSE){foreach((array)$this->primary as$primary){$this->accessedColumns[$primary]=TRUE;}}}protected function createRow(array$row){return new ActiveRow($row,$this);}public function createSelectionInstance($table=NULL){return new self($this->context,$this->conventions,$table?:$this->name,$this->cache?$this->cache->getStorage():NULL);}protected function createGroupedSelectionInstance($table,$column){return new GroupedSelection($this->context,$this->conventions,$table,$column,$this,$this->cache?$this->cache->getStorage():NULL);}protected function query($query){return$this->context->queryArgs($query,$this->sqlBuilder->getParameters());}protected function emptyResultSet($saveCache=TRUE,$deleteRererencedCache=TRUE){if($this->rows!==NULL&&$saveCache){$this->saveCacheState();}if($saveCache){$this->generalCacheTraceKey=NULL;}$this->rows=NULL;$this->specificCacheKey=NULL;$this->generalCacheKey=NULL;$this->refCache['referencingPrototype']=array();if($deleteRererencedCache){$this->refCache['referenced']=array();}}protected function saveCacheState(){if($this->observeCache===$this&&$this->cache&&!$this->sqlBuilder->getSelect()&&$this->accessedColumns!==$this->previousAccessedColumns){$previousAccessed=$this->cache->load($this->getGeneralCacheKey());$accessed=$this->accessedColumns;$needSave=is_array($accessed)&&is_array($previousAccessed)?array_intersect_key($accessed,$previousAccessed)!==$accessed:$accessed!==$previousAccessed;if($needSave){$save=is_array($accessed)&&is_array($previousAccessed)?$previousAccessed+$accessed:$accessed;$this->cache->save($this->getGeneralCacheKey(),$save);$this->previousAccessedColumns=NULL;}}}/** @return Selection **/protected function getRefTable(&$refPath){return$this;}protected function loadRefCache(){}/** @return string **/protected function getGeneralCacheKey(){if($this->generalCacheKey){return$this->generalCacheKey;}$key=array(__CLASS__,$this->name,$this->sqlBuilder->getConditions());if(!$this->generalCacheTraceKey){$trace=array();foreach(debug_backtrace(PHP_VERSION_ID>=50306?DEBUG_BACKTRACE_IGNORE_ARGS:FALSE)as$item){$trace[]=isset($item['file'],$item['line'])?$item['file'].$item['line']:NULL;};$this->generalCacheTraceKey=$trace;}$key[]=$this->generalCacheTraceKey;return$this->generalCacheKey=md5(serialize($key));}/** @return string **/protected function getSpecificCacheKey(){if($this->specificCacheKey){return$this->specificCacheKey;}return$this->specificCacheKey=md5($this->getSql().json_encode($this->sqlBuilder->getParameters()));}/** @return bool if selection requeried for more columns. **/public function accessColumn($key,$selectColumn=TRUE){if(!$this->cache){return FALSE;}if($key===NULL){$this->accessedColumns=FALSE;$currentKey=key((array)$this->data);}elseif($this->accessedColumns!==FALSE){$this->accessedColumns[$key]=$selectColumn;}if($selectColumn&&$this->previousAccessedColumns&&($key===NULL||!isset($this->previousAccessedColumns[$key]))&&!$this->sqlBuilder->getSelect()){$this->previousAccessedColumns=array();if($this->sqlBuilder->getLimit()){$generalCacheKey=$this->generalCacheKey;$sqlBuilder=$this->sqlBuilder;$primaryValues=array();foreach((array)$this->rows as$row){$primary=$row->getPrimary();$primaryValues[]=is_array($primary)?array_values($primary):$primary;}$this->emptyResultSet(FALSE);$this->sqlBuilder=clone$this->sqlBuilder;$this->sqlBuilder->setLimit(NULL,NULL);$this->wherePrimary($primaryValues);$this->generalCacheKey=$generalCacheKey;$this->execute();$this->sqlBuilder=$sqlBuilder;}else{$this->emptyResultSet(FALSE);$this->execute();}$this->dataRefreshed=TRUE;if(isset($currentKey)){while(key($this->data)!==NULL&&key($this->data)!==$currentKey){next($this->data);}}}return$this->dataRefreshed;}public function removeAccessColumn($key){if($this->cache&&is_array($this->accessedColumns)){$this->accessedColumns[$key]=FALSE;}}/** @return bool **/public function getDataRefreshed(){return$this->dataRefreshed;}/** @return IRow|int|bool Returns IRow or number of affected rows for Selection or table without primary key **/public function insert($data){if($data instanceof self){$return=$this->context->queryArgs($this->sqlBuilder->buildInsertQuery().' '.$data->getSql(),$data->getSqlBuilder()->getParameters());}else{if($data instanceof\Traversable){$data=iterator_to_array($data);}$return=$this->context->query($this->sqlBuilder->buildInsertQuery().' ?values',$data);}$this->loadRefCache();if($data instanceof self||$this->primary===NULL){unset($this->refCache['referencing'][$this->getGeneralCacheKey()][$this->getSpecificCacheKey()]);return$return->getRowCount();}$primaryKey=$this->context->getInsertId(($tmp=$this->getPrimarySequence())?implode('.',array_map(array($this->context->getConnection()->getSupplementalDriver(),'delimite'),explode('.',$tmp))):NULL);if(!$primaryKey){unset($this->refCache['referencing'][$this->getGeneralCacheKey()][$this->getSpecificCacheKey()]);return$return->getRowCount();}if(is_array($this->getPrimary())){$primaryKey=array();foreach((array)$this->getPrimary()as$key){if(!isset($data[$key])){return$data;}$primaryKey[$key]=$data[$key];}if(count($primaryKey)===1){$primaryKey=reset($primaryKey);}}$row=$this->createSelectionInstance()->select('*')->wherePrimary($primaryKey)->fetch();if($this->rows!==NULL){if($signature=$row->getSignature(FALSE)){$this->rows[$signature]=$row;$this->data[$signature]=$row;}else{$this->rows[]=$row;$this->data[]=$row;}}return$row;}/** @return int number of affected rows **/public function update($data){if($data instanceof\Traversable){$data=iterator_to_array($data);}elseif(!is_array($data)){throw new Nette\InvalidArgumentException;}if(!$data){return 0;}return$this->context->queryArgs($this->sqlBuilder->buildUpdateQuery(),array_merge(array($data),$this->sqlBuilder->getParameters()))->getRowCount();}/** @return int number of affected rows **/public function delete(){return$this->query($this->sqlBuilder->buildDeleteQuery())->getRowCount();}/** @return ActiveRow|NULL|FALSE NULL if the row does not exist, FALSE if the relationship does not exist **/public function getReferencedTable(ActiveRow$row,$table,$column=NULL){if(!$column){$belongsTo=$this->conventions->getBelongsToReference($this->name,$table);if(!$belongsTo){return FALSE;}list($table,$column)=$belongsTo;}if(!$row->accessColumn($column)){return FALSE;}$checkPrimaryKey=$row[$column];$referenced=&$this->refCache['referenced'][$this->getSpecificCacheKey()]["$table.$column"];$selection=&$referenced['selection'];$cacheKeys=&$referenced['cacheKeys'];if($selection===NULL||($checkPrimaryKey!==NULL&&!isset($cacheKeys[$checkPrimaryKey]))){$this->execute();$cacheKeys=array();foreach($this->rows as$row){if($row[$column]===NULL){continue;}$key=$row[$column];$cacheKeys[$key]=TRUE;}if($cacheKeys){$selection=$this->createSelectionInstance($table);$selection->where($selection->getPrimary(),array_keys($cacheKeys));}else{$selection=array();}}return isset($selection[$checkPrimaryKey])?$selection[$checkPrimaryKey]:NULL;}/** @return GroupedSelection **/public function getReferencingTable($table,$column,$active=NULL){if(strpos($table,'.')!==FALSE){list($table,$column)=explode('.',$table);}elseif(!$column){$hasMany=$this->conventions->getHasManyReference($this->name,$table);if(!$hasMany){return FALSE;}list($table,$column)=$hasMany;}$prototype=&$this->refCache['referencingPrototype'][$this->getSpecificCacheKey()]["$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;}public function rewind(){$this->execute();$this->keys=array_keys($this->data);reset($this->keys);}/** @return IRow **/public function current(){if(($key=current($this->keys))!==FALSE){return$this->data[$key];}else{return FALSE;}}/** @return string row ID **/public function key(){return current($this->keys);}public function next(){next($this->keys);}public function valid(){return current($this->keys)!==FALSE;}/** @return NULL **/public function offsetSet($key,$value){$this->execute();$this->rows[$key]=$value;}/** @return IRow or NULL if there is no such row **/public function offsetGet($key){$this->execute();return$this->rows[$key];}/** @return bool **/public function offsetExists($key){$this->execute();return isset($this->rows[$key]);}/** @return NULL **/public function offsetUnset($key){$this->execute();unset($this->rows[$key],$this->data[$key]);}}array(),'where'=>array(),'group'=>array(),'having'=>array(),'order'=>array());protected$order=array();protected$limit=NULL;protected$offset=NULL;protected$group='';protected$having='';private$driver;private$structure;private$cacheTableList;public function __construct($tableName,Context$context){$this->tableName=$tableName;$this->driver=$context->getConnection()->getSupplementalDriver();$this->conventions=$context->getConventions();$this->structure=$context->getStructure();$this->delimitedTable=implode('.',array_map(array($this->driver,'delimite'),explode('.',$tableName)));}/** @return string **/public function getTableName(){return$this->tableName;}public function buildInsertQuery(){return"INSERT INTO {$this->delimitedTable}";}public function buildUpdateQuery(){if($this->limit!==NULL||$this->offset){throw new Nette\NotSupportedException('LIMIT clause is not supported in UPDATE query.');}return"UPDATE {$this->delimitedTable} SET ?set".$this->tryDelimite($this->buildConditions());}public function buildDeleteQuery(){if($this->limit!==NULL||$this->offset){throw new Nette\NotSupportedException('LIMIT clause is not supported in DELETE query.');}return"DELETE FROM {$this->delimitedTable}".$this->tryDelimite($this->buildConditions());}/** @return string **/public function buildSelectQuery($columns=NULL){$queryCondition=$this->buildConditions();$queryEnd=$this->buildQueryEnd();$joins=array();$this->parseJoins($joins,$queryCondition);$this->parseJoins($joins,$queryEnd);if($this->select){$querySelect=$this->buildSelect($this->select);$this->parseJoins($joins,$querySelect);}elseif($columns){$prefix=$joins?"{$this->delimitedTable}.":'';$cols=array();foreach($columns as$col){$cols[]=$prefix.$col;}$querySelect=$this->buildSelect($cols);}elseif($this->group&&!$this->driver->isSupported(ISupplementalDriver::SUPPORT_SELECT_UNGROUPED_COLUMNS)){$querySelect=$this->buildSelect(array($this->group));$this->parseJoins($joins,$querySelect);}else{$prefix=$joins?"{$this->delimitedTable}.":'';$querySelect=$this->buildSelect(array($prefix.'*'));}$queryJoins=$this->buildQueryJoins($joins);$query="{$querySelect} FROM {$this->delimitedTable}{$queryJoins}{$queryCondition}{$queryEnd}";if($this->limit!==NULL||$this->offset>0){$this->driver->applyLimit($query,$this->limit,max(0,$this->offset));}return$this->tryDelimite($query);}public function getParameters(){return array_merge($this->parameters['select'],$this->parameters['where'],$this->parameters['group'],$this->parameters['having'],$this->parameters['order']);}public function importConditions(SqlBuilder$builder){$this->where=$builder->where;$this->parameters['where']=$builder->parameters['where'];$this->conditions=$builder->conditions;}public function addSelect($columns){if(is_array($columns)){throw new Nette\InvalidArgumentException('Select column must be a string.');}$this->select[]=$columns;$this->parameters['select']=array_merge($this->parameters['select'],array_slice(func_get_args(),1));}public function getSelect(){return$this->select;}public function addWhere($condition,$parameters=array()){if(is_array($condition)&&is_array($parameters)&&!empty($parameters)){return$this->addWhereComposition($condition,$parameters);}$args=func_get_args();$hash=md5(json_encode($args));if(isset($this->conditions[$hash])){return FALSE;}$this->conditions[$hash]=$condition;$placeholderCount=substr_count($condition,'?');if($placeholderCount>1&&count($args)===2&&is_array($parameters)){$args=$parameters;}else{array_shift($args);}$condition=trim($condition);if($placeholderCount===0&&count($args)===1){$condition.=' ?';}elseif($placeholderCount!==count($args)){throw new Nette\InvalidArgumentException('Argument count does not match placeholder count.');}$replace=NULL;$placeholderNum=0;foreach($args as$arg){preg_match('#(?:.*?\?.*?){'.$placeholderNum.'}(((?:&|\||^|~|\+|-|\*|/|%|\(|,|<|>|=|(?<=\W|^)(?:REGEXP|ALL|AND|ANY|BETWEEN|EXISTS|IN|[IR]?LIKE|OR|NOT|SOME|INTERVAL))\s*)?(?:\(\?\)|\?))#s',$condition,$match,PREG_OFFSET_CAPTURE);$hasOperator=($match[1][0]==='?'&&$match[1][1]===0)?TRUE:!empty($match[2][0]);if($arg===NULL){$replace='IS NULL';if($hasOperator){if(trim($match[2][0])==='NOT'){$replace='IS NOT NULL';}else{throw new Nette\InvalidArgumentException('Column operator does not accept NULL argument.');}}}elseif(is_array($arg)||$arg instanceof Selection){if($hasOperator){if(trim($match[2][0])==='NOT'){$match[2][0]=rtrim($match[2][0]).' IN ';}elseif(trim($match[2][0])!=='IN'){throw new Nette\InvalidArgumentException('Column operator does not accept array argument.');}}else{$match[2][0]='IN ';}if($arg instanceof Selection){$clone=clone$arg;if(!$clone->getSqlBuilder()->select){try{$clone->select($clone->getPrimary());}catch(\LogicException$e){throw new Nette\InvalidArgumentException('Selection argument must have defined a select column.',0,$e);}}if($this->driver->isSupported(ISupplementalDriver::SUPPORT_SUBSELECT)){$arg=NULL;$replace=$match[2][0].'('.$clone->getSql().')';$this->parameters['where']=array_merge($this->parameters['where'],$clone->getSqlBuilder()->getParameters());}else{$arg=array();foreach($clone as$row){$arg[]=array_values(iterator_to_array($row));}}}if($arg!==NULL){if(!$arg){$hasBrackets=strpos($condition,'(')!==FALSE;$hasOperators=preg_match('#AND|OR#',$condition);$hasNot=strpos($condition,'NOT')!==FALSE;$hasPrefixNot=strpos($match[2][0],'NOT')!==FALSE;if(!$hasBrackets&&($hasOperators||($hasNot&&!$hasPrefixNot))){throw new Nette\InvalidArgumentException('Possible SQL query corruption. Add parentheses around operators.');}if($hasPrefixNot){$replace='IS NULL OR TRUE';}else{$replace='IS NULL AND FALSE';}$arg=NULL;}else{$replace=$match[2][0].'(?)';$this->parameters['where'][]=$arg;}}}elseif($arg instanceof SqlLiteral){$this->parameters['where'][]=$arg;}else{if(!$hasOperator){$replace='= ?';}$this->parameters['where'][]=$arg;}if($replace){$condition=substr_replace($condition,$replace,$match[1][1],strlen($match[1][0]));$replace=NULL;}if($arg!==NULL){$placeholderNum++;}}$this->where[]=$condition;return TRUE;}public function getConditions(){return array_values($this->conditions);}public function addOrder($columns){$this->order[]=$columns;$this->parameters['order']=array_merge($this->parameters['order'],array_slice(func_get_args(),1));}public function setOrder(array$columns,array$parameters){$this->order=$columns;$this->parameters['order']=$parameters;}public function getOrder(){return$this->order;}public function setLimit($limit,$offset){$this->limit=$limit;$this->offset=$offset;}public function getLimit(){return$this->limit;}public function getOffset(){return$this->offset;}public function setGroup($columns){$this->group=$columns;$this->parameters['group']=array_slice(func_get_args(),1);}public function getGroup(){return$this->group;}public function setHaving($having){$this->having=$having;$this->parameters['having']=array_slice(func_get_args(),1);}public function getHaving(){return$this->having;}protected function buildSelect(array$columns){return'SELECT '.implode(', ',$columns);}protected function parseJoins(&$joins,&$query){$builder=$this;$query=preg_replace_callback('~ (?(DEFINE) (?P [\w_]*[a-z][\w_]* ) (?P [.:] ) (?P (?&del)? (?&word) (\((?&word)\))? ) ) (?P (?!\.) (?&node)*) \. (?P (?&word) | \* ) ~xi',function($match)use(&$joins,$builder){return$builder->parseJoinsCb($joins,$match);},$query);}public function parseJoinsCb(&$joins,$match){$chain=$match['chain'];if(!empty($chain[0])&&($chain[0]!=='.'&&$chain[0]!==':')){$chain='.'.$chain;}preg_match_all('~ (?(DEFINE) (?P [\w_]*[a-z][\w_]* ) ) (?P [.:])?(?P (?&word))(\((?P (?&word))\))? ~xi',$chain,$keyMatches,PREG_SET_ORDER);$parent=$this->tableName;$parentAlias=preg_replace('#^(.*\.)?(.*)$#','$2',$this->tableName);if($this->driver->isSupported(ISupplementalDriver::SUPPORT_SCHEMA)&&count($keyMatches)>1){$tables=$this->getCachedTableList();if(!isset($tables[$keyMatches[0]['key']])&&isset($tables[$keyMatches[0]['key'].'.'.$keyMatches[1]['key']])){$keyMatch=array_shift($keyMatches);$keyMatches[0]['key']=$keyMatch['key'].'.'.$keyMatches[0]['key'];$keyMatches[0]['del']=$keyMatch['del'];}}if($keyMatches[0]['del']==='.'){if($parent===$keyMatches[0]['key']){return"{$parent}.{$match['column']}";}elseif($parentAlias===$keyMatches[0]['key']){return"{$parentAlias}.{$match['column']}";}}foreach($keyMatches as$keyMatch){if($keyMatch['del']===':'){if(isset($keyMatch['throughColumn'])){$table=$keyMatch['key'];$belongsTo=$this->conventions->getBelongsToReference($table,$keyMatch['throughColumn']);if(!$belongsTo){throw new Nette\InvalidArgumentException("No reference found for \${$parent}->{$keyMatch['key']}.");}list(,$primary)=$belongsTo;}else{$hasMany=$this->conventions->getHasManyReference($parent,$keyMatch['key']);if(!$hasMany){throw new Nette\InvalidArgumentException("No reference found for \${$parent}->related({$keyMatch['key']}).");}list($table,$primary)=$hasMany;}$column=$this->conventions->getPrimary($parent);}else{$belongsTo=$this->conventions->getBelongsToReference($parent,$keyMatch['key']);if(!$belongsTo){throw new Nette\InvalidArgumentException("No reference found for \${$parent}->{$keyMatch['key']}.");}list($table,$column)=$belongsTo;$primary=$this->conventions->getPrimary($table);}$tableAlias=$keyMatch['key']?:preg_replace('#^(.*\.)?(.*)$#','$2',$table);if($parent===$table){$tableAlias=$parentAlias.'_ref';}$joins[$tableAlias.$column]=array($table,$tableAlias,$parentAlias,$column,$primary);$parent=$table;$parentAlias=$tableAlias;}return$tableAlias.".{$match['column']}";}protected function buildQueryJoins(array$joins){$return='';foreach($joins as$join){list($joinTable,$joinAlias,$table,$tableColumn,$joinColumn)=$join;$return.=" LEFT JOIN {$joinTable}".($joinTable!==$joinAlias?" {$joinAlias}":'')." ON {$table}.{$tableColumn} = {$joinAlias}.{$joinColumn}";}return$return;}protected function buildConditions(){return$this->where?' WHERE ('.implode(') AND (',$this->where).')':'';}protected function buildQueryEnd(){$return='';if($this->group){$return.=' GROUP BY '.$this->group;}if($this->having){$return.=' HAVING '.$this->having;}if($this->order){$return.=' ORDER BY '.implode(', ',$this->order);}return$return;}protected function tryDelimite($s){$driver=$this->driver;return preg_replace_callback('#(?<=[^\w`"\[?]|^)[a-z_][a-z0-9_]*(?=[^\w`"(\]]|\z)#i',function($m)use($driver){return strtoupper($m[0])===$m[0]?$m[0]:$driver->delimite($m[0]);},$s);}protected function addWhereComposition(array$columns,array$parameters){if($this->driver->isSupported(ISupplementalDriver::SUPPORT_MULTI_COLUMN_AS_OR_COND)){$conditionFragment='('.implode(' = ? AND ',$columns).' = ?) OR ';$condition=substr(str_repeat($conditionFragment,count($parameters)),0,-4);return$this->addWhere($condition,Nette\Utils\Arrays::flatten($parameters));}else{return$this->addWhere('('.implode(', ',$columns).') IN',$parameters);}}private function getCachedTableList(){if(!$this->cacheTableList){$this->cacheTableList=array_flip(array_map(function($pair){return isset($pair['fullName'])?$pair['fullName']:$pair['name'];},$this->structure->getTables()));}return$this->cacheTableList;}}$meta[self::FILE],'handle'=>$meta[self::HANDLE]);}/** @return string **/protected function getCacheFile($key){return parent::getCacheFile(substr_replace($key,trim(strtr($this->hint,'\\/@','.._'),'.').'-',strpos($key,Nette\Caching\Cache::NAMESPACE_SEPARATOR)+1,0)).'.php';}/** @return string **/public function getDir(){return dirname(parent::getCacheFile(NULL));}}cb=$cb->cb;return;}if(!is_callable($cb,TRUE)){throw new InvalidArgumentException('Invalid callback.');}$this->cb=$cb;}/** @return mixed **/public function __invoke(){if(!is_callable($this->cb)){throw new InvalidStateException("Callback '$this' is not callable.");}return call_user_func_array($this->cb,func_get_args());}/** @return mixed **/public function invoke(){if(!is_callable($this->cb)){throw new InvalidStateException("Callback '$this' is not callable.");}return call_user_func_array($this->cb,func_get_args());}/** @return mixed **/public function invokeArgs(array$args){if(!is_callable($this->cb)){throw new InvalidStateException("Callback '$this' is not callable.");}return call_user_func_array($this->cb,$args);}/** @return bool **/public function isCallable(){return is_callable($this->cb);}/** @return string|array|\Closure **/public function getNative(){return$this->cb;}/** @return Nette\Reflection\GlobalFunction|Nette\Reflection\Method **/public function toReflection(){if(is_string($this->cb)&&strpos($this->cb,'::')){return new Nette\Reflection\Method($this->cb);}elseif(is_array($this->cb)){return new Nette\Reflection\Method($this->cb[0],$this->cb[1]);}elseif(is_object($this->cb)&&!$this->cb instanceof\Closure){return new Nette\Reflection\Method($this->cb,'__invoke');}else{return new Nette\Reflection\GlobalFunction($this->cb);}}/** @return bool **/public function isStatic(){return is_array($this->cb)?is_string($this->cb[0]):is_string($this->cb);}/** @return Callback **/public function bindTo($newthis){if(is_string($this->cb)&&strpos($this->cb,'::')){$this->cb=explode('::',$this->cb);}elseif(!is_array($this->cb)){throw new InvalidStateException("Callback '$this' have not any bound object.");}return new static($newthis,$this->cb[1]);}/** @return string **/public function __toString(){if($this->cb instanceof\Closure){return'{closure}';}elseif(is_string($this->cb)&&$this->cb[0]==="\0"){return'{lambda}';}else{is_callable($this->cb,TRUE,$textual);return$textual;}}}addPanel($panel,$id);}}href(strtr(Debugger::$editor,array('%file'=>rawurlencode($file),'%line'=>$line)))->title("$file:$line")->setHtml(htmlSpecialChars(rtrim($dir,DIRECTORY_SEPARATOR),ENT_IGNORE).DIRECTORY_SEPARATOR.''.htmlSpecialChars(basename($file),ENT_IGNORE).''.($line?":$line":''));}else{return Nette\Utils\Html::el('span')->setText($file.($line?":$line":''));}}public static function htmlDump($var){trigger_error(__METHOD__.'() is deprecated; use Tracy\Dumper::toHtml() instead.',E_USER_DEPRECATED);return Tracy\Dumper::toHtml($var);}public static function clickableDump($var){trigger_error(__METHOD__.'() is deprecated; use Tracy\Dumper::toHtml() instead.',E_USER_DEPRECATED);return Tracy\Dumper::toHtml($var);}public static function textDump($var){trigger_error(__METHOD__.'() is deprecated; use Tracy\Dumper::toText() instead.',E_USER_DEPRECATED);return Tracy\Dumper::toText($var);}}expand($value);}self::getContext()->parameters[$name]=$value;}/** @return mixed **/public static function getVariable($name,$default=NULL){if(isset(self::getContext()->parameters[$name])){return self::getContext()->parameters[$name];}elseif(func_num_args()>1){return$default;}else{throw new InvalidStateException("Unknown environment variable '$name'.");}}/** @return array **/public static function getVariables(){return self::getContext()->parameters;}/** @return string **/public static function expand($s){return self::getContext()->expand($s);}/** @return void **/public static function setContext(DI\Container$context){if(self::$createdAt){throw new Nette\InvalidStateException('Configurator & SystemContainer has already been created automatically by Nette\Environment at '.self::$createdAt);}self::$context=$context;}/** @return Nette\DI\Container **/public static function getContext(){if(self::$context===NULL){self::loadConfig();}return self::$context;}/** @return object **/public static function getService($name){return self::getContext()->getService($name);}/** @return object service **/public static function __callStatic($name,$args){if(!$args&&strncasecmp($name,'get',3)===0){return self::getService(lcfirst(substr($name,3)));}else{throw new MemberAccessException("Call to undefined static method Nette\\Environment::$name().");}}/** @return Nette\Http\Request **/public static function getHttpRequest(){return self::getContext()->getByType('Nette\Http\IRequest');}/** @return Nette\Http\Context **/public static function getHttpContext(){return self::getContext()->getByType('Nette\Http\Context');}/** @return Nette\Http\Response **/public static function getHttpResponse(){return self::getContext()->getByType('Nette\Http\IResponse');}/** @return Nette\Application\Application **/public static function getApplication(){return self::getContext()->getByType('Nette\Application\Application');}/** @return Nette\Security\User **/public static function getUser(){return self::getContext()->getByType('Nette\Security\User');}/** @return Nette\Loaders\RobotLoader **/public static function getRobotLoader(){return self::getContext()->getByType('Nette\Loaders\RobotLoader');}/** @return Nette\Caching\Cache **/public static function getCache($namespace=''){return new Caching\Cache(self::getContext()->getByType('Nette\Caching\IStorage'),$namespace);}/** @return Nette\Http\Session **/public static function getSession($namespace=NULL){return$namespace===NULL?self::getContext()->getByType('Nette\Http\Session'):self::getContext()->getByType('Nette\Http\Session')->getSection($namespace);}/** @return Nette\Utils\ArrayHash **/public static function loadConfig($file=NULL,$section=NULL){if(self::$createdAt){throw new Nette\InvalidStateException('Nette\Configurator has already been created automatically by Nette\Environment at '.self::$createdAt);}elseif(!defined('TEMP_DIR')){throw new Nette\InvalidStateException('Nette\Environment requires constant TEMP_DIR with path to temporary directory.');}$configurator=new Nette\Configurator;$configurator->setDebugMode(!self::isProduction())->setTempDirectory(TEMP_DIR)->addParameters(array('container'=>array('class'=>'EnvironmentContainer')));if($file){$configurator->addConfig($file,$section);}self::$context=$configurator->createContainer();self::$createdAt='?';foreach(debug_backtrace(FALSE)as$row){if(isset($row['file'])&&$row['file']!==__FILE__&&is_file($row['file'])){self::$createdAt="$row[file]:$row[line]";break;}}return self::getConfig();}/** @return mixed **/public static function getConfig($key=NULL,$default=NULL){$params=Nette\Utils\ArrayHash::from(self::getContext()->parameters);if(func_num_args()){return isset($params[$key])?$params[$key]:$default;}else{return$params;}}}getParser()->shortNoEscape=TRUE;$this->addFilter('url','rawurlencode');foreach(array('normalize','toAscii','webalize','padLeft','padRight','reverse')as$name){$this->addFilter($name,'Nette\Utils\Strings::'.$name);}}public function __invoke($s){trigger_error(__METHOD__.'() is deprecated; use compile() instead.',E_USER_DEPRECATED);return$this->setLoader(new Latte\Loaders\StringLoader)->compile($s);}public function getCompiler(){$compiler=parent::getCompiler();if(!$this->fixed){$this->fixed=TRUE;$compiler->addMacro('cache',new Nette\Bridges\CacheLatte\CacheMacro($compiler));Nette\Bridges\ApplicationLatte\UIMacros::install($compiler);Nette\Bridges\FormsLatte\FormMacros::install($compiler);}return$compiler;}public function&__get($name){switch(strtolower($name)){case'parser':case'compiler':$method='get'.ucfirst($name);trigger_error("Magic getters are deprecated. Use $method() method instead.",E_USER_DEPRECATED);$return=$this->$method();return$return;}return parent::__get($name);}}setFile($file);}}/** @return self **/public function setFile($file){$this->file=realpath($file);if(!$this->file){throw new Nette\FileNotFoundException("Missing template file '$file'.");}return$this;}/** @return string template file path **/public function getFile(){return$this->file;}/** @return string **/public function getSource(){return file_get_contents($this->file);}/** @return void **/public function render(){if($this->file==NULL){throw new Nette\InvalidStateException('Template file name was not specified.');}if(!$this->getFilters()){$this->onPrepareFilters($this);}if($latte=$this->getLatte()){return$latte->setLoader(new Latte\Loaders\FileLoader)->render($this->file,$this->getParameters());}$cache=new Caching\Cache($storage=$this->getCacheStorage(),'Nette.FileTemplate');if($storage instanceof Caching\Storages\PhpFileStorage){$storage->hint=str_replace(dirname(dirname($this->file)),'',$this->file);}$cached=$compiled=$cache->load($this->file);if($compiled===NULL){try{$compiled="file\n\n?>".$this->compile();}catch(CompileException$e){throw$e->setSource(file_get_contents($this->file),$e->sourceLine,$this->file);}$cache->save($this->file,$compiled,array(Caching\Cache::FILES=>$this->file,Caching\Cache::CONSTS=>'Nette\Framework::REVISION'));$cached=$cache->load($this->file);}$isFile=$cached!==NULL&&$storage instanceof Caching\Storages\PhpFileStorage;self::load($isFile?$cached['file']:$compiled,$this->getParameters(),$isFile);}}'Nette\Utils\Strings::normalize','toascii'=>'Nette\Utils\Strings::toAscii','webalize'=>'Nette\Utils\Strings::webalize','padleft'=>'Nette\Utils\Strings::padLeft','padright'=>'Nette\Utils\Strings::padRight','reverse'=>'Nette\Utils\Strings::reverse','url'=>'rawurlencode');/** @return callable **/public static function loader($helper){if(method_exists(__CLASS__,$helper)){return array(__CLASS__,$helper);}elseif(isset(self::$helpers[$helper])){return self::$helpers[$helper];}}/** @return Nette\Utils\DateTime **/public static function modifyDate($time,$delta,$unit=NULL){return$time==NULL?NULL:Nette\Utils\DateTime::from($time)->modify($delta.$unit);}/** @return int **/public static function length($var){return is_string($var)?Strings::length($var):count($var);}/** @return string **/public static function null(){return'';}public static function optimizePhp($source,$lineLength=80){return Latte\Helpers::optimizePhp($source,$lineLength);}}source=$source;return$this;}/** @return string **/public function getSource(){return$this->source;}/** @return void **/public function render(){if(!$this->filters){$this->onPrepareFilters($this);}if($latte=$this->getLatte()){return$latte->setLoader(new Latte\Loaders\StringLoader)->render($this->source,$this->getParameters());}$cache=new Caching\Cache($storage=$this->getCacheStorage(),'Nette.Template');$cached=$compiled=$cache->load($this->source);if($compiled===NULL){$compiled=$this->compile();$cache->save($this->source,$compiled,array(Caching\Cache::CONSTS=>'Nette\Framework::REVISION'));$cached=$cache->load($this->source);}$isFile=$cached!==NULL&&$storage instanceof Caching\Storages\PhpFileStorage;self::load($isFile?$cached['file']:$compiled,$this->getParameters(),$isFile);}protected static function load(){foreach(func_get_arg(1)as$__k=>$__v){$$__k=$__v;}unset($__k,$__v);if(func_get_arg(2)){include func_get_arg(0);}else{$res=eval('?>'.func_get_arg(0));if($res===FALSE&&($error=error_get_last())&&$error['type']===E_PARSE){throw new\ErrorException($error['message'],0,$error['type'],$error['file'],$error['line']);}}}/** @return void **/public function save($file){if(file_put_contents($file,$this->__toString(TRUE))===FALSE){throw new Nette\IOException("Unable to save file '$file'.");}}/** @return string **/public function __toString(){ob_start();try{$this->render();return ob_get_clean();}catch(\Exception$e){ob_end_clean();if(func_num_args()){throw$e;}trigger_error(sprintf('Exception in %s(): %s in %s:%i',__METHOD__,$e->getMessage(),$e->getFile(),$e->getLine()),E_USER_ERROR);}}/** @return string **/public function compile(){if(!$this->filters){$this->onPrepareFilters($this);}$code=$this->getSource();foreach($this->filters as$filter){$code=self::extractPhp($code,$blocks);$code=call_user_func($filter,$code);$code=strtr($code,$blocks);}if($latte=$this->getLatte()){return$latte->setLoader(new Latte\Loaders\StringLoader)->compile($code);}return Helpers::optimizePhp($code);}public function setLatte(Latte\Engine$latte){$this->latte=$latte;}/** @return Latte\Engine **/public function getLatte(){if(!$this->latte){return NULL;}$latte=$this->latte instanceof Latte\Engine?$this->latte:new Nette\Latte\Engine;foreach($this->helpers as$key=>$callback){$latte->addFilter($key,$callback);}foreach($this->helperLoaders as$callback){$latte->addFilter(NULL,function($name)use($callback,$latte){if($res=call_user_func($callback,$name)){$latte->addFilter($name,$res);}});}if($this->cacheStorage instanceof Nette\Caching\Storages\PhpFileStorage){$latte->setTempDirectory($this->cacheStorage->getDir());}return$latte;}/** @return self **/public function registerFilter($callback){if($callback instanceof Latte\Engine){$this->latte=$callback;}elseif(is_array($callback)&&$callback[0]instanceof Latte\Engine){$this->latte=$callback[0];}elseif(strpos(Callback::toString($callback),'Latte\Engine')!==FALSE){$this->latte=TRUE;}elseif($this->latte){throw new Nette\DeprecatedException('Adding filters after Latte is not possible.');}else{$this->filters[]=Callback::check($callback);}return$this;}/** @return array **/public function getFilters(){return$this->filters;}/** @return self **/public function registerHelper($name,$callback){$this->helpers[strtolower($name)]=$callback;return$this;}/** @return self **/public function registerHelperLoader($callback){array_unshift($this->helperLoaders,$callback);return$this;}/** @return array **/public function getHelpers(){return$this->helpers;}/** @return array **/public function getHelperLoaders(){return$this->helperLoaders;}/** @return mixed **/public function __call($name,$args){$lname=strtolower($name);if(!isset($this->helpers[$lname])){foreach($this->helperLoaders as$loader){$helper=Callback::invoke($loader,$lname);if($helper){$this->registerHelper($lname,$helper);return Callback::invokeArgs($this->helpers[$lname],$args);}}return parent::__call($name,$args);}return Callback::invokeArgs($this->helpers[$lname],$args);}/** @return self **/public function setTranslator(Nette\Localization\ITranslator$translator=NULL){$this->registerHelper('translate',$translator===NULL?NULL:array($translator,'translate'));return$this;}/** @return self **/public function add($name,$value){if(array_key_exists($name,$this->params)){throw new Nette\InvalidStateException("The variable '$name' already exists.");}$this->params[$name]=$value;return$this;}/** @return self **/public function setParameters(array$params){$this->params=$params+$this->params;return$this;}/** @return array **/public function getParameters(){$this->params['template']=$this;return$this->params;}/** @return void **/public function __set($name,$value){$this->params[$name]=$value;}/** @return mixed value **/public function&__get($name){if(!array_key_exists($name,$this->params)){trigger_error("The variable '$name' does not exist in template.",E_USER_NOTICE);}return$this->params[$name];}/** @return bool **/public function __isset($name){return isset($this->params[$name]);}/** @return void **/public function __unset($name){unset($this->params[$name]);}/** @return self **/public function setCacheStorage(Caching\IStorage$storage){$this->cacheStorage=$storage;return$this;}/** @return Nette\Caching\IStorage **/public function getCacheStorage(){if($this->cacheStorage===NULL){return new Caching\Storages\DevNullStorage;}return$this->cacheStorage;}/** @return string **/private static function extractPhp($source,&$blocks){$res='';$blocks=array();$tokens=token_get_all($source);foreach($tokens as$n=>$token){if(is_array($token)){if($token[0]===T_INLINE_HTML){$res.=$token[1];continue;}elseif($token[0]===T_CLOSE_TAG){if($php!==$res){$res.=str_repeat("\n",substr_count($php,"\n"));}$res.=$token[1];continue;}elseif($token[0]===T_OPEN_TAG&&$token[1]==='?';}elseif($token[0]===T_OPEN_TAG||$token[0]===T_OPEN_TAG_WITH_ECHO){$res.=$id='<@php:p'.count($blocks).'@';$php=&$blocks[$id];}$php.=$token[1];}else{$php.=$token;}}return$res;}}frozen=TRUE;}/** @return bool **/public function isFrozen(){return$this->frozen;}/** @return void **/public function __clone(){$this->frozen=FALSE;}/** @return void **/protected function updating(){if($this->frozen){$class=get_class($this);throw new InvalidStateException("Cannot modify a frozen object $class.");}}}1){foreach(func_get_arg(1)as$__k=>$__v){$$__k=$__v;}unset($__k,$__v);}$res=eval('?>'.func_get_arg(0));if($res===FALSE&&($error=error_get_last())&&$error['type']===E_PARSE){throw new\ErrorException($error['message'],0,$error['type'],$error['file'],$error['line']);}return$res;}/** @return mixed the return value of the included file **/public static function load(){trigger_error(__METHOD__.'() is deprecated.',E_USER_DEPRECATED);if(func_num_args()>1&&is_array(func_get_arg(1))){foreach(func_get_arg(1)as$__k=>$__v){$$__k=$__v;}unset($__k,$__v);}return include func_get_arg(0);}}1,'parameters'=>1);public function __construct(ContainerBuilder$builder=NULL){$this->builder=$builder?:new ContainerBuilder;}/** @return static **/public function addExtension($name,CompilerExtension$extension){if(isset($this->extensions[$name])||isset(self::$reserved[$name])){throw new Nette\InvalidArgumentException("Name '$name' is already used or reserved.");}$this->extensions[$name]=$extension->setCompiler($this,$name);return$this;}/** @return array **/public function getExtensions($type=NULL){return$type?array_filter($this->extensions,function($item)use($type){return$item instanceof$type;}):$this->extensions;}/** @return ContainerBuilder **/public function getContainerBuilder(){return$this->builder;}/** @return static **/public function setClassName($className){$this->className=$className;return$this;}/** @return static **/public function addConfig(array$config){$this->config=Config\Helpers::merge($config,$this->config);return$this;}/** @return static **/public function loadConfig($file){$loader=new Config\Loader;$this->addConfig($loader->load($file));$this->addDependencies($loader->getDependencies());return$this;}/** @return array **/public function getConfig(){return$this->config;}/** @return static **/public function addDependencies(array$files){$this->dependencies=array_merge($this->dependencies,$files);return$this;}/** @return array **/public function getDependencies(){return array_values(array_unique(array_filter($this->dependencies)));}/** @return Nette\PhpGenerator\ClassType[]|string **/public function compile(array$config=NULL,$className=NULL,$parentName=NULL){$this->config=$config?:$this->config;$this->processParameters();$this->processExtensions();$this->processServices();$classes=$this->generateCode($className?:$this->className,$parentName);return func_num_args()?implode("\n\n\n",$classes):$classes;}public function processParameters(){if(isset($this->config['parameters'])){$this->builder->parameters=Helpers::expand($this->config['parameters'],$this->config['parameters'],TRUE);}}public function processExtensions(){$this->config=Helpers::expand(array_diff_key($this->config,self::$reserved),$this->builder->parameters)+array_intersect_key($this->config,self::$reserved);foreach($first=$this->getExtensions('Nette\DI\Extensions\ExtensionsExtension')as$name=>$extension){$extension->setConfig(isset($this->config[$name])?$this->config[$name]:array());$extension->loadConfiguration();}$last=$this->getExtensions('Nette\DI\Extensions\InjectExtension');$this->extensions=array_merge(array_diff_key($this->extensions,$last),$last);$extensions=array_diff_key($this->extensions,$first);foreach(array_intersect_key($extensions,$this->config)as$name=>$extension){if(isset($this->config[$name]['services'])){trigger_error("Support for inner section 'services' inside extension was removed (used in '$name').",E_USER_DEPRECATED);}$extension->setConfig($this->config[$name]?:array());}foreach($extensions as$extension){$extension->loadConfiguration();}if($extra=array_diff_key($this->extensions,$extensions,$first)){$extra=implode("', '",array_keys($extra));throw new Nette\DeprecatedException("Extensions '$extra' were added while container was being compiled.");}elseif($extra=key(array_diff_key($this->config,self::$reserved,$this->extensions))){$hint=Nette\Utils\ObjectMixin::getSuggestion(array_keys(self::$reserved+$this->extensions),$extra);throw new Nette\InvalidStateException("Found section '$extra' in configuration, but corresponding extension is missing".($hint?", did you mean '$hint'?":'.'));}}public function processServices(){$this->parseServices($this->builder,$this->config);}public function generateCode($className,$parentName=NULL){$this->builder->prepareClassList();$state=serialize($this->builder->getDefinitions());foreach($this->extensions as$extension){$extension->beforeCompile();$rc=new\ReflectionClass($extension);$this->dependencies[]=$rc->getFileName();if($state!==serialize($this->builder->getDefinitions())){$this->builder->prepareClassList();$state=serialize($this->builder->getDefinitions());}}$classes=$this->builder->generateClasses($className,$parentName);$classes[0]->addMethod('initialize');$this->addDependencies($this->builder->getDependencies());foreach($this->extensions as$extension){$extension->afterCompile($classes[0]);}return$classes;}/** @return void **/public static function parseServices(ContainerBuilder$builder,array$config,$namespace=NULL){if(!empty($config['factories'])){throw new Nette\DeprecatedException("Section 'factories' is deprecated, move definitions to section 'services' and append key 'autowired: no'.");}$services=isset($config['services'])?$config['services']:array();$depths=array();foreach($services as$name=>$def){$path=array();while(Config\Helpers::isInheriting($def)){$path[]=$def;$def=isset($services[$def[Config\Helpers::EXTENDS_KEY]])?$services[$def[Config\Helpers::EXTENDS_KEY]]:array();if(in_array($def,$path,TRUE)){throw new ServiceCreationException("Circular reference detected for service '$name'.");}}$depths[$name]=count($path);}array_multisort($depths,$services);foreach($services as$origName=>$def){if((string)(int)$origName===(string)$origName){$postfix=$def instanceof Statement&&is_string($def->getEntity())?'.'.$def->getEntity():(is_scalar($def)?".$def":'');$name=(count($builder->getDefinitions())+1).preg_replace('#\W+#','_',$postfix);}else{$name=($namespace?$namespace.'.':'').strtr($origName,'\\','_');}if($def===FALSE){$builder->removeDefinition($name);continue;}$params=$builder->parameters;if(is_array($def)&&isset($def['parameters'])){foreach((array)$def['parameters']as$k=>$v){$v=explode(' ',is_int($k)?$v:$k);$params[end($v)]=$builder::literal('$'.end($v));}}$def=Helpers::expand($def,$params);if(($parent=Config\Helpers::takeParent($def))&&$parent!==$name){$builder->removeDefinition($name);$definition=$builder->addDefinition($name,$parent===Config\Helpers::OVERWRITE?NULL:unserialize(serialize($builder->getDefinition($parent))));}elseif($builder->hasDefinition($name)){$definition=$builder->getDefinition($name);}else{$definition=$builder->addDefinition($name);}try{static::parseService($definition,$def);}catch(\Exception$e){throw new ServiceCreationException("Service '$name': ".$e->getMessage(),NULL,$e);}if($definition->getClass()==='self'||($definition->getFactory()&&$definition->getFactory()->getEntity()==='self')){throw new Nette\DeprecatedException("Replace service definition '$origName: self' with '- $origName'.");}}}/** @return void **/public static function parseService(ServiceDefinition$definition,$config){if($config===NULL){return;}elseif(is_string($config)&&interface_exists($config)){$config=array('class'=>NULL,'implement'=>$config);}elseif($config instanceof Statement&&is_string($config->getEntity())&&interface_exists($config->getEntity())){$config=array('class'=>NULL,'implement'=>$config->getEntity(),'factory'=>array_shift($config->arguments));}elseif(!is_array($config)||isset($config[0],$config[1])){$config=array('class'=>NULL,'create'=>$config);}if(array_key_exists('factory',$config)){$config['create']=$config['factory'];unset($config['factory']);};$known=array('class','create','arguments','setup','autowired','dynamic','inject','parameters','implement','run','tags');if($error=array_diff(array_keys($config),$known)){throw new Nette\InvalidStateException(sprintf("Unknown or deprecated key '%s' in definition of service.",implode("', '",$error)));}$config=self::filterArguments($config);$arguments=array();if(array_key_exists('arguments',$config)){Validators::assertField($config,'arguments','array');$arguments=$config['arguments'];$definition->setArguments($arguments);}if(array_key_exists('class',$config)||array_key_exists('create',$config)){$definition->setClass(NULL);$definition->setFactory(NULL);}if(array_key_exists('class',$config)){Validators::assertField($config,'class','string|Nette\DI\Statement|null');if(!$config['class']instanceof Statement){$definition->setClass($config['class']);}$definition->setFactory($config['class'],$arguments);}if(array_key_exists('create',$config)){Validators::assertField($config,'create','callable|Nette\DI\Statement|null');$definition->setFactory($config['create'],$arguments);}if(isset($config['setup'])){if(Config\Helpers::takeParent($config['setup'])){$definition->setSetup(array());}Validators::assertField($config,'setup','list');foreach($config['setup']as$id=>$setup){Validators::assert($setup,'callable|Nette\DI\Statement',"setup item #$id");$definition->addSetup($setup);}}if(isset($config['parameters'])){Validators::assertField($config,'parameters','array');$definition->setParameters($config['parameters']);}if(isset($config['implement'])){Validators::assertField($config,'implement','string');$definition->setImplement($config['implement']);$definition->setAutowired(TRUE);}if(isset($config['autowired'])){Validators::assertField($config,'autowired','bool');$definition->setAutowired($config['autowired']);}if(isset($config['dynamic'])){Validators::assertField($config,'dynamic','bool');$definition->setDynamic($config['dynamic']);}if(isset($config['inject'])){Validators::assertField($config,'inject','bool');$definition->addTag(Extensions\InjectExtension::TAG_INJECT,$config['inject']);}if(isset($config['run'])){$config['tags']['run']=(bool)$config['run'];}if(isset($config['tags'])){Validators::assertField($config,'tags','array');if(Config\Helpers::takeParent($config['tags'])){$definition->setTags(array());}foreach($config['tags']as$tag=>$attrs){if(is_int($tag)&&is_string($attrs)){$definition->addTag($attrs);}else{$definition->addTag($tag,$attrs);}}}}/** @return array **/public static function filterArguments(array$args){foreach($args as$k=>$v){if($v==='...'){unset($args[$k]);}elseif(is_string($v)&&preg_match('#^[\w\\\\]*::[A-Z][A-Z0-9_]*\z#',$v,$m)){$args[$k]=ContainerBuilder::literal(ltrim($v,':'));}elseif(is_array($v)){$args[$k]=self::filterArguments($v);}elseif($v instanceof Statement){$tmp=self::filterArguments(array($v->getEntity()));$args[$k]=new Statement($tmp[0],self::filterArguments($v->arguments));}}return$args;}}compiler=$compiler;$this->name=$name;return$this;}public function setConfig(array$config){$this->config=$config;return$this;}/** @return array **/public function getConfig(){if(func_num_args()){return Config\Helpers::merge($this->config,$this->getContainerBuilder()->expand(func_get_arg(0)));}return$this->config;}/** @return array **/public function validateConfig(array$expected,array$config=NULL,$name=NULL){if(func_num_args()===1){return$this->config=$this->validateConfig($expected,$this->config);}if($extra=array_diff_key((array)$config,$expected)){$name=$name?:$this->name;$hint=Nette\Utils\ObjectMixin::getSuggestion(array_keys($expected),key($extra));$extra=$hint?key($extra):implode(", $name.",array_keys($extra));throw new Nette\InvalidStateException("Unknown configuration option $name.$extra".($hint?", did you mean $name.$hint?":'.'));}return Config\Helpers::merge($config,$expected);}/** @return ContainerBuilder **/public function getContainerBuilder(){return$this->compiler->getContainerBuilder();}/** @return array **/public function loadFromFile($file){$loader=new Config\Loader;$res=$loader->load($file);$this->compiler->addDependencies($loader->getDependencies());return$res;}/** @return string **/public function prefix($id){return substr_replace($id,$this->name.'.',substr($id,0,1)==='@'?1:0,0);}/** @return void **/public function loadConfiguration(){}/** @return void **/public function beforeCompile(){}/** @return void **/public function afterCompile(Nette\PhpGenerator\ClassType$class){}}$secData){if(is_array($secData)){if(substr($secName,-1)===self::RAW_SECTION){$secName=substr($secName,0,-1);}else{$tmp=array();foreach($secData 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 new 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 new Nette\InvalidStateException("Invalid section [$secName] in file '$file'.");}}if(is_array($secData)&&is_array($cursor)){$secData=Helpers::merge($secData,$cursor);}$cursor=$secData;}return$data;}/** @return string **/public function dump(array$data){$output=array();foreach($data 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);}/** @return void **/private static function build($input,&$output,$prefix){foreach($input 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 new Nette\InvalidArgumentException(sprintf("The '%s' item must be scalar or array, %s given.",$prefix.$key,gettype($val)));}}}}process((array)Neon\Neon::decode(file_get_contents($file)));}private function process(array$arr){$res=array();foreach($arr as$key=>$val){if(substr($key,-1)===self::PREVENT_MERGING){if(!is_array($val)&&$val!==NULL){throw new 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 new 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 new Nette\InvalidStateException("Duplicated key '$key'.");}}if(is_array($val)){$val=$this->process($val);}elseif($val instanceof Neon\Entity){if($val->value===Neon\Neon::CHAIN){$tmp=NULL;foreach($this->process($val->attributes)as$st){$tmp=new Statement($tmp===NULL?$st->getEntity():array($tmp,ltrim($st->getEntity(),':')),$st->arguments);}$val=$tmp;}else{$tmp=$this->process(array($val->value));$val=new Statement($tmp[0],$this->process($val->attributes));}}$res[$key]=$val;}return$res;}/** @return string **/public function dump(array$data){$tmp=array();foreach($data as$name=>$secData){if($parent=Helpers::takeParent($secData)){$name.=' '.self::INHERITING_SEPARATOR.' '.$parent;}$tmp[$name]=$secData;}array_walk_recursive($tmp,function(&$val){if($val instanceof Statement){$val=NeonAdapter::statementToEntity($val);}});return"# generated by Nette\n\n".Neon\Neon::encode($tmp,Neon\Neon::BLOCK);}/** @return Neon\Entity **/public static function statementToEntity(Statement$val){array_walk_recursive($val->arguments,function(&$val){if($val instanceof Statement){$val=NeonAdapter::statementToEntity($val);}});if(is_array($val->entity)&&$val->entity[0]instanceof Statement){return new Neon\Entity(Neon\Neon::CHAIN,array(self::statementToEntity($val->entity[0]),new Neon\Entity('::'.$val->entity[1],$val->arguments)));}else{return new Neon\Entity($val->entity,$val->arguments);}}}$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;}}/** @return mixed **/public static function takeParent(&$data){if(is_array($data)&&isset($data[self::EXTENDS_KEY])){$parent=$data[self::EXTENDS_KEY];unset($data[self::EXTENDS_KEY]);return$parent;}}/** @return bool **/public static function isOverwriting(&$data){return is_array($data)&&isset($data[self::EXTENDS_KEY])&&$data[self::EXTENDS_KEY]===self::OVERWRITE;}/** @return bool **/public static function isInheriting(&$data){return is_array($data)&&isset($data[self::EXTENDS_KEY])&&$data[self::EXTENDS_KEY]!==self::OVERWRITE;}}'Nette\DI\Config\Adapters\PhpAdapter','ini'=>'Nette\DI\Config\Adapters\IniAdapter','neon'=>'Nette\DI\Config\Adapters\NeonAdapter');private$dependencies=array();/** @return array **/public function load($file,$section=NULL){if(!is_file($file)||!is_readable($file)){throw new Nette\FileNotFoundException("File '$file' is missing or is not readable.");}$this->dependencies[]=realpath($file);$data=$this->getAdapter($file)->load($file);if($section){if(isset($data[self::INCLUDES_KEY])){throw new 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 Helpers::merge($data,$merged);}/** @return void **/public function save($data,$file){if(file_put_contents($file,$this->getAdapter($file)->dump($data))===FALSE){throw new Nette\IOException("Cannot write file '$file'.");}}/** @return array **/public function getDependencies(){return array_unique($this->dependencies);}/** @return static **/public function addAdapter($extension,$adapter){$this->adapters[strtolower($extension)]=$adapter;return$this;}/** @return IAdapter **/private function getAdapter($file){$extension=strtolower(pathinfo($file,PATHINFO_EXTENSION));if(!isset($this->adapters[$extension])){throw new Nette\InvalidArgumentException("Unknown file extension '$file'.");}return is_object($this->adapters[$extension])?$this->adapters[$extension]:new$this->adapters[$extension];}private function 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;}}parameters=$params+$this->parameters;}/** @return array **/public function getParameters(){return$this->parameters;}/** @return static **/public function addService($name,$service){if(!is_string($name)||!$name){throw new Nette\InvalidArgumentException(sprintf('Service name must be a non-empty string, %s given.',gettype($name)));}$name=isset($this->meta[self::ALIASES][$name])?$this->meta[self::ALIASES][$name]:$name;if(isset($this->registry[$name])){throw new Nette\InvalidStateException("Service '$name' already exists.");}elseif(!is_object($service)){throw new Nette\InvalidArgumentException(sprintf("Service '%s' must be a object, %s given.",$name,gettype($service)));}elseif(isset($this->meta[self::SERVICES][$name])&&!$service instanceof$this->meta[self::SERVICES][$name]){throw new Nette\InvalidArgumentException(sprintf("Service '%s' must be instance of %s, %s given.",$name,$this->meta[self::SERVICES][$name],get_class($service)));}$this->registry[$name]=$service;return$this;}/** @return void **/public function removeService($name){$name=isset($this->meta[self::ALIASES][$name])?$this->meta[self::ALIASES][$name]:$name;unset($this->registry[$name]);}/** @return object **/public function getService($name){if(!isset($this->registry[$name])){if(isset($this->meta[self::ALIASES][$name])){return$this->getService($this->meta[self::ALIASES][$name]);}$this->registry[$name]=$this->createService($name);}return$this->registry[$name];}/** @return string **/public function getServiceType($name){if(isset($this->meta[self::ALIASES][$name])){return$this->getServiceType($this->meta[self::ALIASES][$name]);}elseif(isset($this->meta[self::SERVICES][$name])){return$this->meta[self::SERVICES][$name];}else{throw new MissingServiceException("Service '$name' not found.");}}/** @return bool **/public function hasService($name){$name=isset($this->meta[self::ALIASES][$name])?$this->meta[self::ALIASES][$name]:$name;return isset($this->registry[$name])||(method_exists($this,$method=self::getMethodName($name))&&($rm=new\ReflectionMethod($this,$method))&&$rm->getName()===$method);}/** @return bool **/public function isCreated($name){if(!$this->hasService($name)){throw new MissingServiceException("Service '$name' not found.");}$name=isset($this->meta[self::ALIASES][$name])?$this->meta[self::ALIASES][$name]:$name;return isset($this->registry[$name]);}/** @return object **/public function createService($name,array$args=array()){$name=isset($this->meta[self::ALIASES][$name])?$this->meta[self::ALIASES][$name]:$name;$method=self::getMethodName($name);if(isset($this->creating[$name])){throw new Nette\InvalidStateException(sprintf('Circular reference detected for services: %s.',implode(', ',array_keys($this->creating))));}elseif(!method_exists($this,$method)||!($rm=new\ReflectionMethod($this,$method))||$rm->getName()!==$method){throw new MissingServiceException("Service '$name' not found.");}$this->creating[$name]=TRUE;try{$service=call_user_func_array(array($this,$method),$args);}catch(\Exception$e){unset($this->creating[$name]);throw$e;}unset($this->creating[$name]);if(!is_object($service)){throw new Nette\UnexpectedValueException("Unable to create service '$name', value returned by method $method() is not object.");}return$service;}/** @return object service or NULL **/public function getByType($class,$need=TRUE){$class=ltrim($class,'\\');if(!empty($this->meta[self::TYPES][$class][TRUE])){if(count($names=$this->meta[self::TYPES][$class][TRUE])===1){return$this->getService($names[0]);}throw new MissingServiceException("Multiple services of type $class found: ".implode(', ',$names).'.');}elseif($need){throw new MissingServiceException("Service of type $class not found.");}}/** @return string[] **/public function findByType($class){$class=ltrim($class,'\\');return empty($this->meta[self::TYPES][$class])?array():call_user_func_array('array_merge',$this->meta[self::TYPES][$class]);}/** @return array of [service name => tag attributes] **/public function findByTag($tag){return isset($this->meta[self::TAGS][$tag])?$this->meta[self::TAGS][$tag]:array();}/** @return object **/public function createInstance($class,array$args=array()){$rc=new\ReflectionClass($class);if(!$rc->isInstantiable()){throw new ServiceCreationException("Class $class is not instantiable.");}elseif($constructor=$rc->getConstructor()){return$rc->newInstanceArgs(Helpers::autowireArguments($constructor,$args,$this));}elseif($args){throw new ServiceCreationException("Unable to pass arguments, class $class has no constructor.");}return new$class;}/** @return void **/public function callInjects($service){Extensions\InjectExtension::callInjects($this,$service);}/** @return mixed **/public function callMethod($function,array$args=array()){return call_user_func_array($function,Helpers::autowireArguments(Nette\Utils\Callback::toReflection($function),$args,$this));}/** @return mixed **/public function expand($s){return Helpers::expand($s,$this->parameters);}public function&__get($name){$this->error(__METHOD__,'getService');$tmp=$this->getService($name);return$tmp;}public function __set($name,$service){$this->error(__METHOD__,'addService');$this->addService($name,$service);}public function __isset($name){$this->error(__METHOD__,'hasService');return$this->hasService($name);}public function __unset($name){$this->error(__METHOD__,'removeService');$this->removeService($name);}private function error($oldName,$newName){if(empty($this->parameters['container']['accessors'])){trigger_error("$oldName() is deprecated; use $newName() or enable di.accessors in configuration.",E_USER_DEPRECATED);}}public static function getMethodName($name){$uname=ucfirst($name);return'createService'.((string)$name===$uname?'__':'').str_replace('.','__',$uname);}}aliases[$name])?$this->aliases[$name]:$name;if(isset($this->definitions[$name])){throw new Nette\InvalidStateException("Service '$name' has already been added.");}return$this->definitions[$name]=$definition?:new ServiceDefinition;}/** @return void **/public function removeDefinition($name){$name=isset($this->aliases[$name])?$this->aliases[$name]:$name;unset($this->definitions[$name]);if($this->classes){foreach($this->classes as&$tmp){foreach($tmp as&$names){$names=array_values(array_diff($names,array($name)));}}}}/** @return ServiceDefinition **/public function getDefinition($name){$service=isset($this->aliases[$name])?$this->aliases[$name]:$name;if(!isset($this->definitions[$service])){throw new MissingServiceException("Service '$name' not found.");}return$this->definitions[$service];}/** @return ServiceDefinition[] **/public function getDefinitions(){return$this->definitions;}/** @return bool **/public function hasDefinition($name){$name=isset($this->aliases[$name])?$this->aliases[$name]:$name;return isset($this->definitions[$name]);}public function addAlias($alias,$service){if(!is_string($alias)||!$alias){throw new Nette\InvalidArgumentException(sprintf('Alias name must be a non-empty string, %s given.',gettype($alias)));}elseif(!is_string($service)||!$service){throw new Nette\InvalidArgumentException(sprintf('Service name must be a non-empty string, %s given.',gettype($service)));}elseif(isset($this->aliases[$alias])){throw new Nette\InvalidStateException("Alias '$alias' has already been added.");}elseif(isset($this->definitions[$alias])){throw new Nette\InvalidStateException("Service '$alias' has already been added.");}$this->aliases[$alias]=$service;}/** @return void **/public function removeAlias($alias){unset($this->aliases[$alias]);}/** @return array **/public function getAliases(){return$this->aliases;}/** @return static **/public function setClassName($name){$this->className=(string)$name;return$this;}/** @return string **/public function getClassName(){return$this->className;}/** @return string|NULL service name or NULL **/public function getByType($class){$class=ltrim($class,'\\');if($this->currentService!==NULL){$curClass=$this->definitions[$this->currentService]->getClass();if($curClass===$class||is_subclass_of($curClass,$class)){return$this->currentService;}}if(empty($this->classes[$class][TRUE])){self::checkCase($class);return;}elseif(count($this->classes[$class][TRUE])===1){return$this->classes[$class][TRUE][0];}else{throw new ServiceCreationException("Multiple services of type $class found: ".implode(', ',$this->classes[$class][TRUE]));}}/** @return ServiceDefinition[] **/public function findByType($class){$class=ltrim($class,'\\');self::checkCase($class);$found=array();if(!empty($this->classes[$class])){foreach(call_user_func_array('array_merge',$this->classes[$class])as$name){$found[$name]=$this->definitions[$name];}}return$found;}/** @return array of [service name => tag attributes] **/public function findByTag($tag){$found=array();foreach($this->definitions as$name=>$def){if(($tmp=$def->getTag($tag))!==NULL){$found[$name]=$tmp;}}return$found;}/** @return array **/public function autowireArguments($class,$method,array$arguments){$rc=new ReflectionClass($class);if(!$rc->hasMethod($method)){if(!Nette\Utils\Arrays::isList($arguments)){throw new ServiceCreationException("Unable to pass specified arguments to $class::$method().");}return$arguments;}$rm=$rc->getMethod($method);if(!$rm->isPublic()){throw new ServiceCreationException("$class::$method() is not callable.");}$this->addDependency($rm->getFileName());return Helpers::autowireArguments($rm,$arguments,$this);}/** @return array **/public function prepareClassList(){unset($this->definitions[self::THIS_CONTAINER]);$this->addDefinition(self::THIS_CONTAINER)->setClass('Nette\DI\Container');$this->classes=FALSE;foreach($this->definitions as$name=>$def){if($def->getImplement()){$this->resolveImplement($def,$name);}if($def->isDynamic()){if(!$def->getClass()){throw new ServiceCreationException("Class is missing in definition of service '$name'.");}$def->setFactory(NULL);continue;}if(!$def->getEntity()){if(!$def->getClass()){throw new ServiceCreationException("Class and factory are missing in definition of service '$name'.");}$def->setFactory($def->getClass(),($factory=$def->getFactory())?$factory->arguments:array());}if(($alias=$this->getServiceName($def->getFactory()->getEntity()))&&(!$def->getImplement()||(!Strings::contains($alias,'\\')&&$this->definitions[$alias]->getImplement()))){$def->setAutowired(FALSE);}}foreach($this->definitions as$name=>$def){$this->resolveServiceClass($name);}$excludedClasses=array();foreach($this->excludedClasses as$class){self::checkCase($class);$excludedClasses+=class_parents($class)+class_implements($class)+array($class=>$class);}$this->classes=array();foreach($this->definitions as$name=>$def){if($class=$def->getImplement()?:$def->getClass()){foreach(class_parents($class)+class_implements($class)+array($class)as$parent){$this->classes[$parent][$def->isAutowired()&&empty($excludedClasses[$parent])][]=(string)$name;}}}foreach($this->classes as$class=>$foo){$rc=new ReflectionClass($class);$this->addDependency($rc->getFileName());}}private function resolveImplement(ServiceDefinition$def,$name){$interface=$def->getImplement();if(!interface_exists($interface)){throw new ServiceCreationException("Interface $interface used in service '$name' not found.");}self::checkCase($interface);$rc=new ReflectionClass($interface);$method=$rc->hasMethod('create')?$rc->getMethod('create'):($rc->hasMethod('get')?$rc->getMethod('get'):NULL);if(count($rc->getMethods())!==1||!$method||$method->isStatic()){throw new ServiceCreationException("Interface $interface used in service '$name' must have just one non-static method create() or get().");}$def->setImplementMode($methodName=$rc->hasMethod('create')?$def::IMPLEMENT_MODE_CREATE:$def::IMPLEMENT_MODE_GET);if(!$def->getClass()&&!$def->getEntity()){$returnType=PhpReflection::getReturnType($method);if(!$returnType){throw new ServiceCreationException("Method $interface::$methodName() used in service '$name' has no @return annotation.");}elseif(!class_exists($returnType)){throw new ServiceCreationException("Check a @return annotation of the $interface::$methodName() method used in service '$name', class '$returnType' cannot be found.");}$def->setClass($returnType);}if($methodName==='get'){if($method->getParameters()){throw new ServiceCreationException("Method $interface::get() used in service '$name' must have no arguments.");}if(!$def->getEntity()){$def->setFactory('@\\'.ltrim($def->getClass(),'\\'));}elseif(!$this->getServiceName($def->getFactory()->getEntity())){throw new ServiceCreationException("Invalid factory in service '$name' definition.");}}if(!$def->parameters){$ctorParams=array();if(!$def->getEntity()){$def->setFactory($def->getClass(),$def->getFactory()?$def->getFactory()->arguments:array());}if(($class=$this->resolveEntityClass($def->getFactory(),array($name=>1)))&&($rc=new ReflectionClass($class))&&($ctor=$rc->getConstructor())){foreach($ctor->getParameters()as$param){$ctorParams[$param->getName()]=$param;}}foreach($method->getParameters()as$param){$hint=PhpReflection::getParameterType($param);if(isset($ctorParams[$param->getName()])){$arg=$ctorParams[$param->getName()];if($hint!==PhpReflection::getParameterType($arg)){throw new ServiceCreationException("Type hint for \${$param->getName()} in $interface::$methodName() doesn't match type hint in $class constructor.");}$def->getFactory()->arguments[$arg->getPosition()]=self::literal('$'.$arg->getName());}elseif(!$def->getSetup()){$hint=Nette\Utils\ObjectMixin::getSuggestion(array_keys($ctorParams),$param->getName());throw new ServiceCreationException("Unused parameter \${$param->getName()} when implementing method $interface::$methodName()".($hint?", did you mean \${$hint}?":'.'));}$paramDef=$hint.' '.$param->getName();if($param->isOptional()){$def->parameters[$paramDef]=$param->getDefaultValue();}else{$def->parameters[]=$paramDef;}}}}/** @return string|NULL **/private function resolveServiceClass($name,$recursive=array()){if(isset($recursive[$name])){throw new ServiceCreationException(sprintf('Circular reference detected for services: %s.',implode(', ',array_keys($recursive))));}$recursive[$name]=TRUE;$def=$this->definitions[$name];$class=$def->getFactory()?$this->resolveEntityClass($def->getFactory()->getEntity(),$recursive):NULL;if($class=$def->getClass()?:$class){$def->setClass($class);if(!class_exists($class)&&!interface_exists($class)){throw new ServiceCreationException("Type $class used in service '$name' not found or is not class or interface.");}self::checkCase($class);}elseif($def->isAutowired()){trigger_error("Type of service '$name' is unknown.",E_USER_NOTICE);}return$class;}/** @return string|NULL **/private function resolveEntityClass($entity,$recursive=array()){$entity=$this->normalizeEntity($entity instanceof Statement?$entity->getEntity():$entity);if(is_array($entity)){if(($service=$this->getServiceName($entity[0]))||$entity[0]instanceof Statement){$entity[0]=$this->resolveEntityClass($entity[0],$recursive);if(!$entity[0]){return;}elseif(isset($this->definitions[$service])&&$this->definitions[$service]->getImplement()){return$entity[1]==='create'?$this->resolveServiceClass($service,$recursive):NULL;}}try{$reflection=Nette\Utils\Callback::toReflection($entity[0]===''?$entity[1]:$entity);$refClass=$reflection instanceof\ReflectionMethod?$reflection->getDeclaringClass():NULL;}catch(\ReflectionException$e){}if(isset($e)||($refClass&&(!$reflection->isPublic()||(PHP_VERSION_ID>=50400&&$refClass->isTrait()&&!$reflection->isStatic())))){$name=array_slice(array_keys($recursive),-1);throw new ServiceCreationException(sprintf("Factory '%s' used in service '%s' is not callable.",Nette\Utils\Callback::toString($entity),$name[0]));}return PhpReflection::getReturnType($reflection);}elseif($service=$this->getServiceName($entity)){if(Strings::contains($service,'\\')){return ltrim($service,'\\');}return$this->definitions[$service]->getImplement()?:$this->resolveServiceClass($service,$recursive);}elseif(is_string($entity)){if(!class_exists($entity)||!($rc=new ReflectionClass($entity))||!$rc->isInstantiable()){$name=array_slice(array_keys($recursive),-1);throw new ServiceCreationException("Class $entity used in service '$name[0]' not found or is not instantiable.");}return ltrim($entity,'\\');}}private function checkCase($class){if((class_exists($class)||interface_exists($class))&&($rc=new ReflectionClass($class))&&$class!==$rc->getName()){throw new ServiceCreationException("Case mismatch on class name '$class', correct name is '{$rc->getName()}'.");}}/** @return static **/public function addExcludedClasses(array$classes){$this->excludedClasses=array_merge($this->excludedClasses,$classes);return$this;}/** @return static **/public function addDependency($file){$this->dependencies[$file]=TRUE;return$this;}/** @return array **/public function getDependencies(){unset($this->dependencies[FALSE]);return array_keys($this->dependencies);}/** @return Nette\PhpGenerator\ClassType[] **/public function generateClasses($className=NULL,$parentName=NULL){$this->prepareClassList();$this->generatedClasses=array();$this->className=$className?:$this->className;$containerClass=$this->generatedClasses[]=new Nette\PhpGenerator\ClassType($this->className);$containerClass->setExtends($parentName?:'Nette\DI\Container');$containerClass->addMethod('__construct')->addBody('parent::__construct(?);',array($this->parameters));$definitions=$this->definitions;ksort($definitions);$meta=$containerClass->addProperty('meta')->setVisibility('protected')->setValue(array(Container::TYPES=>$this->classes));foreach($definitions as$name=>$def){$meta->value[Container::SERVICES][$name]=$def->getClass()?:NULL;foreach($def->getTags()as$tag=>$value){$meta->value[Container::TAGS][$tag][$name]=$value;}}foreach($definitions as$name=>$def){try{$name=(string)$name;$methodName=Container::getMethodName($name);if(!PhpHelpers::isIdentifier($methodName)){throw new ServiceCreationException('Name contains invalid characters.');}$containerClass->addMethod($methodName)->addComment('@return '.($def->getImplement()?:$def->getClass()))->setBody($name===self::THIS_CONTAINER?'return $this;':$this->generateService($name))->setParameters($def->getImplement()?array():$this->convertParameters($def->parameters));}catch(\Exception$e){throw new ServiceCreationException("Service '$name': ".$e->getMessage(),NULL,$e);}}$aliases=$this->aliases;ksort($aliases);$meta->value[Container::ALIASES]=$aliases;return$this->generatedClasses;}/** @return string **/private function generateService($name){$this->currentService=NULL;$def=$this->definitions[$name];if($def->isDynamic()){return PhpHelpers::formatArgs('throw new Nette\\DI\\ServiceCreationException(?);',array("Unable to create dynamic service '$name', it must be added using addService()"));}$entity=$def->getFactory()->getEntity();$serviceRef=$this->getServiceName($entity);$factory=$serviceRef&&!$def->getFactory()->arguments&&!$def->getSetup()&&$def->getImplementMode()!==$def::IMPLEMENT_MODE_CREATE?new Statement(array('@'.self::THIS_CONTAINER,'getService'),array($serviceRef)):$def->getFactory();$code='$service = '.$this->formatStatement($factory).";\n";$this->currentService=$name;if(($class=$def->getClass())&&!$serviceRef&&$class!==$entity&&!(is_string($entity)&&preg_match('#^[\w\\\\]+\z#',$entity)&&is_subclass_of($entity,$class))){$code.=PhpHelpers::formatArgs("if (!\$service instanceof $class) {\n"."\tthrow new Nette\\UnexpectedValueException(?);\n}\n",array("Unable to create service '$name', value returned by factory is not $class type."));}foreach($def->getSetup()as$setup){if(is_string($setup->getEntity())&&strpbrk($setup->getEntity(),':@?\\')===FALSE){$setup->setEntity(array('@self',$setup->getEntity()));}$code.=$this->formatStatement($setup).";\n";}$this->currentService=NULL;$code.='return $service;';if(!$def->getImplement()){return$code;}$factoryClass=$this->generatedClasses[]=new Nette\PhpGenerator\ClassType;$factoryClass->setName(str_replace(array('\\','.'),'_',"{$this->className}_{$def->getImplement()}Impl_{$name}"))->addImplement($def->getImplement())->setFinal(TRUE);$factoryClass->addProperty('container')->setVisibility('private');$factoryClass->addMethod('__construct')->addBody('$this->container = $container;')->addParameter('container')->setTypeHint($this->className);$factoryClass->addMethod($def->getImplementMode())->setParameters($this->convertParameters($def->parameters))->setBody(str_replace('$this','$this->container',$code))->setReturnType(PHP_VERSION_ID>=70000?$def->getClass():NULL);return"return new {$factoryClass->getName()}(\$this);";}/** @return Nette\PhpGenerator\Parameter[] **/private function convertParameters(array$parameters){$res=array();foreach($parameters as$k=>$v){$tmp=explode(' ',is_int($k)?$v:$k);$param=$res[]=new Nette\PhpGenerator\Parameter;$param->setName(end($tmp));if(!is_int($k)){$param=$param->setOptional(TRUE)->setDefaultValue($v);}if(isset($tmp[1])){$param->setTypeHint($tmp[0]);}}return$res;}/** @return string **/public function formatStatement(Statement$statement){$entity=$this->normalizeEntity($statement->getEntity());$arguments=$statement->arguments;if(is_string($entity)&&Strings::contains($entity,'?')){return$this->formatPhp($entity,$arguments);}elseif($service=$this->getServiceName($entity)){$params=array();foreach($this->definitions[$service]->parameters as$k=>$v){$params[]=preg_replace('#\w+\z#','\$$0',(is_int($k)?$v:$k)).(is_int($k)?'':' = '.PhpHelpers::dump($v));}$rm=new\ReflectionFunction(create_function(implode(', ',$params),''));$arguments=Helpers::autowireArguments($rm,$arguments,$this);return$this->formatPhp('$this->?(?*)',array(Container::getMethodName($service),$arguments));}elseif($entity==='not'){return$this->formatPhp('!?',array($arguments[0]));}elseif(is_string($entity)){$rc=new ReflectionClass($entity);if($constructor=$rc->getConstructor()){$this->addDependency($constructor->getFileName());$arguments=Helpers::autowireArguments($constructor,$arguments,$this);}elseif($arguments){throw new ServiceCreationException("Unable to pass arguments, class $entity has no constructor.");}return$this->formatPhp("new $entity".($arguments?'(?*)':''),array($arguments));}elseif(!Nette\Utils\Arrays::isList($entity)||count($entity)!==2){throw new ServiceCreationException(sprintf('Expected class, method or property, %s given.',PhpHelpers::dump($entity)));}elseif(!preg_match('#^\$?'.PhpHelpers::PHP_IDENT.'\z#',$entity[1])){throw new ServiceCreationException("Expected function, method or property name, '$entity[1]' given.");}elseif($entity[0]===''){return$this->formatPhp("$entity[1](?*)",array($arguments));}elseif($entity[0]instanceof Statement){$inner=$this->formatPhp('?',array($entity[0]));if(substr($inner,0,4)==='new '){$inner=PHP_VERSION_ID<50400?"current(array($inner))":"($inner)";}return$this->formatPhp("$inner->?(?*)",array($entity[1],$arguments));}elseif(Strings::contains($entity[1],'$')){Validators::assert($arguments,'list:1',"setup arguments for '".Nette\Utils\Callback::toString($entity)."'");if($this->getServiceName($entity[0])){return$this->formatPhp('?->? = ?',array($entity[0],substr($entity[1],1),$arguments[0]));}else{return$this->formatPhp($entity[0].'::$? = ?',array(substr($entity[1],1),$arguments[0]));}}elseif($service=$this->getServiceName($entity[0])){$class=$this->definitions[$service]->getImplement();if(!$class||!method_exists($class,$entity[1])){$class=$this->definitions[$service]->getClass();}if($class){$arguments=$this->autowireArguments($class,$entity[1],$arguments);}return$this->formatPhp('?->?(?*)',array($entity[0],$entity[1],$arguments));}else{$arguments=$this->autowireArguments($entity[0],$entity[1],$arguments);return$this->formatPhp("$entity[0]::$entity[1](?*)",array($arguments));}}/** @return string **/public function formatPhp($statement,$args){$that=$this;array_walk_recursive($args,function(&$val)use($that){if($val instanceof Statement){$val=ContainerBuilder::literal($that->formatStatement($val));}elseif($val===$that){$val=ContainerBuilder::literal('$this');}elseif($val instanceof ServiceDefinition){$val='@'.current(array_keys($that->getDefinitions(),$val,TRUE));}if(!is_string($val)){return;}elseif(substr($val,0,2)==='@@'){$val=substr($val,1);}elseif(substr($val,0,1)==='@'&&strlen($val)>1){$pair=explode('::',$val,2);$name=$that->getServiceName($pair[0]);if(isset($pair[1])&&preg_match('#^[A-Z][A-Z0-9_]*\z#',$pair[1],$m)){$val=$that->getDefinition($name)->getClass().'::'.$pair[1];}else{if($name===ContainerBuilder::THIS_CONTAINER){$val='$this';}elseif($name===$that->currentService){$val='$service';}else{$val=$that->formatStatement(new Statement(array('@'.ContainerBuilder::THIS_CONTAINER,'getService'),array($name)));}$val.=(isset($pair[1])?PhpHelpers::formatArgs('->?',array($pair[1])):'');}$val=ContainerBuilder::literal($val);}});return PhpHelpers::formatArgs($statement,$args);}/** @return mixed **/public function expand($value){return Helpers::expand($value,$this->parameters);}/** @return Nette\PhpGenerator\PhpLiteral **/public static function literal($phpCode){return new Nette\PhpGenerator\PhpLiteral($phpCode);}public function normalizeEntity($entity){if(is_string($entity)&&Strings::contains($entity,'::')&&!Strings::contains($entity,'?')){$entity=explode('::',$entity);}if(is_array($entity)&&$entity[0]instanceof ServiceDefinition){$entity[0]='@'.current(array_keys($this->definitions,$entity[0],TRUE));}elseif($entity instanceof ServiceDefinition){$entity='@'.current(array_keys($this->definitions,$entity,TRUE));}elseif(is_array($entity)&&$entity[0]===$this){$entity[0]='@'.self::THIS_CONTAINER;}return$entity;}/** @return string of FALSE, if argument is not service name **/public function getServiceName($arg){$arg=$this->normalizeEntity($arg);if(!is_string($arg)||!preg_match('#^@[\w\\\\.].*\z#',$arg)){return FALSE;}$service=substr($arg,1);if($service===self::THIS_SERVICE){$service=$this->currentService;}if(Strings::contains($service,'\\')){if($this->classes===FALSE){return$service;}$res=$this->getByType($service);if(!$res){throw new ServiceCreationException("Reference to missing service of type $service.");}return$res;}$service=isset($this->aliases[$service])?$this->aliases[$service]:$service;if(!isset($this->definitions[$service])){throw new ServiceCreationException("Reference to missing service '$service'.");}return$service;}}tempDirectory=$tempDirectory;}/** @return Container **/public function create(){if(!class_exists($this->class)){$this->loadClass();}return new$this->class;}/** @return string **/protected function generateCode(){$compiler=$this->createCompiler();$config=$this->generateConfig();$this->onCompile($this,$compiler,$config);$code="configFiles as$info){if(is_scalar($info[0])){$code.="// source: $info[0] $info[1]\n";}}$code.="\n".$compiler->compile($config,$this->class,$this->parentClass);if($this->autoRebuild!=='compat'){$this->dependencies=array_merge($this->dependencies,$compiler->getContainerBuilder()->getDependencies());}return$code;}/** @return array **/protected function generateConfig(){$config=array();$loader=$this->createLoader();foreach($this->configFiles as$info){$info=is_scalar($info[0])?$loader->load($info[0],$info[1]):$info[0];$config=Config\Helpers::merge($info,$config);}$this->dependencies=array_merge($this->dependencies,$loader->getDependencies());return Config\Helpers::merge($config,$this->config);}/** @return void **/private function loadClass(){$key=md5(serialize(array($this->config,$this->configFiles,$this->class,$this->parentClass)));$file="$this->tempDirectory/$key.php";if(!$this->isExpired($file)&&(@include$file)!==FALSE){return;}$handle=fopen("$file.lock",'c+');if(!$handle||!flock($handle,LOCK_EX)){throw new Nette\IOException("Unable to acquire exclusive lock on '$file.lock'.");}if(!is_file($file)||$this->isExpired($file)){$this->dependencies=array();$toWrite[$file]=$this->generateCode();$files=$this->dependencies?array_combine($this->dependencies,$this->dependencies):array();$toWrite["$file.meta"]=serialize(@array_map('filemtime',$files));foreach($toWrite as$name=>$content){if(file_put_contents("$name.tmp",$content)!==strlen($content)||!rename("$name.tmp",$name)){@unlink("$name.tmp");throw new Nette\IOException("Unable to create file '$name'.");}}}if((@include$file)===FALSE){throw new Nette\IOException("Unable to include '$file'.");}flock($handle,LOCK_UN);}private function isExpired($file){if($this->autoRebuild){$meta=@unserialize(file_get_contents("$file.meta"));$files=$meta?array_combine($tmp=array_keys($meta),$tmp):array();return$meta!==@array_map('filemtime',$files);}return FALSE;}/** @return Compiler **/protected function createCompiler(){return new Compiler;}/** @return Config\Loader **/protected function createLoader(){return new Config\Loader;}}tempDirectory=$tempDirectory;$this->autoRebuild=$autoRebuild;}/** @return string **/public function load($key,$generator){if(!is_callable($generator)){list($generator,$key)=array($key,$generator);}$class=$this->getClassName($key);if(!class_exists($class,FALSE)){$this->loadFile($class,$generator);}return$class;}/** @return string **/public function getClassName($key){return'Container_'.substr(md5(serialize($key)),0,10);}/** @return void **/private function loadFile($class,$generator){$file="$this->tempDirectory/$class.php";if(!$this->isExpired($file)&&(@include$file)!==FALSE){return;}if(!is_dir($this->tempDirectory)){@mkdir($this->tempDirectory);}$handle=fopen("$file.lock",'c+');if(!$handle||!flock($handle,LOCK_EX)){throw new Nette\IOException("Unable to acquire exclusive lock on '$file.lock'.");}if(!is_file($file)||$this->isExpired($file)){list($toWrite[$file],$toWrite["$file.meta"])=$this->generate($class,$generator);foreach($toWrite as$name=>$content){if(file_put_contents("$name.tmp",$content)!==strlen($content)||!rename("$name.tmp",$name)){@unlink("$name.tmp");throw new Nette\IOException("Unable to create file '$name'.");}}}if((@include$file)===FALSE){throw new Nette\IOException("Unable to include '$file'.");}flock($handle,LOCK_UN);}private function isExpired($file){if($this->autoRebuild){$meta=@unserialize(file_get_contents("$file.meta"));$files=$meta?array_combine($tmp=array_keys($meta),$tmp):array();return$meta!==@array_map('filemtime',$files);}return FALSE;}/** @return array of (code, file[]) **/protected function generate($class,$generator){$compiler=new Compiler;$compiler->getContainerBuilder()->setClassName($class);$code=call_user_func_array($generator,array(&$compiler));$code=$code?:implode("\n\n\n",$compiler->compile());$files=$compiler->getDependencies();$files=$files?array_combine($files,$files):array();return array("getConfig()as$name=>$value){$class->getMethod('initialize')->addBody('define(?, ?);',array($name,$value));}}}array(),'tags'=>array(),'inject'=>NULL);public function beforeCompile(){foreach($this->getConfig()as$class=>$info){$info=$this->validateConfig($this->defaults,$info,$this->prefix($class));if($info['inject']!==NULL){$info['tags'][InjectExtension::TAG_INJECT]=$info['inject'];}$this->addSetups($class,(array)$info['setup']);$this->addTags($class,(array)$info['tags']);}}public function addSetups($type,array$setups){foreach($this->findByType($type)as$def){foreach($setups as$setup){$def->addSetup($setup);}}}public function addTags($type,array$tags){$tags=Nette\Utils\Arrays::normalize($tags,TRUE);foreach($this->findByType($type)as$def){$def->setTags($def->getTags()+$tags);}}private function findByType($type){$type=ltrim($type,'\\');return array_filter($this->getContainerBuilder()->getDefinitions(),function($def)use($type){return$def->getClass()===$type||is_subclass_of($def->getClass(),$type)||(PHP_VERSION_ID<50307&&array_key_exists($type,class_implements($def->getClass())))||$def->getImplement()===$type||is_subclass_of($def->getImplement(),$type)||(PHP_VERSION_ID<50307&&$def->getImplement()&&array_key_exists($type,class_implements($def->getImplement())));});}}FALSE,'accessors'=>FALSE);private$debugMode;private$time;public function __construct($debugMode=FALSE){$this->debugMode=$debugMode;$this->time=microtime(TRUE);}public function loadConfiguration(){$config=$this->validateConfig($this->defaults);if($config['accessors']){$this->getContainerBuilder()->parameters['container']['accessors']=TRUE;}}public function afterCompile(Nette\PhpGenerator\ClassType$class){$initialize=$class->getMethod('initialize');$container=$this->getContainerBuilder();if($this->debugMode&&$this->config['debugger']){Nette\Bridges\DITracy\ContainerPanel::$compilationTime=$this->time;$initialize->addBody($container->formatPhp('?;',array(new Nette\DI\Statement('@Tracy\Bar::addPanel',array(new Nette\DI\Statement('Nette\Bridges\DITracy\ContainerPanel'))))));}foreach(array_filter($container->findByTag('run'))as$name=>$on){$initialize->addBody('$this->getService(?);',array($name));}if(!empty($this->config['accessors'])){$definitions=$container->getDefinitions();ksort($definitions);foreach($definitions as$name=>$def){if(Nette\PhpGenerator\Helpers::isIdentifier($name)){$type=$def->getImplement()?:$def->getClass();$class->addComment("@property $type \$$name");}}}}}getConfig()as$name=>$class){if($class instanceof Nette\DI\Statement){$rc=new\ReflectionClass($class->getEntity());$this->compiler->addExtension($name,$rc->newInstanceArgs($class->arguments));}else{$this->compiler->addExtension($name,new$class);}}}}getContainerBuilder()->getDefinitions()as$def){if($def->getTag(self::TAG_INJECT)&&$def->getClass()){$this->updateDefinition($def);}}}private function updateDefinition($def){$class=$def->getClass();$builder=$this->getContainerBuilder();$injects=array();foreach(self::getInjectProperties($class)as$property=>$type){self::checkType($class,$property,$type,$builder);$injects[]=new DI\Statement('$'.$property,array('@\\'.ltrim($type,'\\')));}foreach(self::getInjectMethods($def->getClass())as$method){$injects[]=new DI\Statement($method);}$setups=$def->getSetup();foreach($injects as$inject){foreach($setups as$key=>$setup){if($setup->getEntity()===$inject->getEntity()){$inject=$setup;unset($setups[$key]);}}array_unshift($setups,$inject);}$def->setSetup($setups);}/** @return array **/public static function getInjectMethods($class){return array_values(array_filter(get_class_methods($class),function($name){return substr($name,0,6)==='inject';}));}/** @return array **/public static function getInjectProperties($class){$res=array();foreach(get_class_vars($class)as$name=>$foo){$rp=new\ReflectionProperty($class,$name);if(PhpReflection::parseAnnotation($rp,'inject')!==NULL){if($type=PhpReflection::parseAnnotation($rp,'var')){$type=PhpReflection::expandClassName($type,PhpReflection::getDeclaringClass($rp));}$res[$name]=$type;}}return$res;}/** @return void **/public static function callInjects(DI\Container$container,$service){if(!is_object($service)){throw new Nette\InvalidArgumentException(sprintf('Service must be object, %s given.',gettype($service)));}foreach(array_reverse(self::getInjectMethods($service))as$method){$container->callMethod(array($service,$method));}foreach(self::getInjectProperties(get_class($service))as$property=>$type){self::checkType($service,$property,$type,$container);$service->$property=$container->getByType($type);}}private static function checkType($class,$name,$type,$container){$rc=PhpReflection::getDeclaringClass(new\ReflectionProperty($class,$name));$fullname=$rc->getName().'::$'.$name;if(!$type){throw new Nette\InvalidStateException("Property $fullname has no @var annotation.");}elseif(!class_exists($type)&&!interface_exists($type)){throw new Nette\InvalidStateException("Class or interface '$type' used in @var annotation at $fullname not found. Check annotation and 'use' statements.");}elseif(!$container->getByType($type,FALSE)){throw new Nette\InvalidStateException("Service of type {$type} used in @var annotation at $fullname not found. Did you register it in configuration file?");}}}getMethod('initialize');foreach($this->getConfig()as$name=>$value){if($value===NULL){continue;}elseif(!is_scalar($value)){throw new 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 new Nette\NotSupportedException('Required function ini_set() is disabled.');}}}}$val){$res[$key]=self::expand($val,$params,$recursive);}return$res;}elseif($var instanceof Statement){return new Statement(self::expand($var->getEntity(),$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 as$n=>$part){if($n % 2===0){$res.=$part;}elseif($part===''){$res.='%';}elseif(isset($recursive[$part])){throw new Nette\InvalidArgumentException(sprintf('Circular reference detected for variables: %s.',implode(', ',array_keys($recursive))));}else{try{$val=Nette\Utils\Arrays::get($params,explode('.',$part));}catch(Nette\InvalidArgumentException$e){throw new Nette\InvalidArgumentException("Missing parameter '$part'.",0,$e);}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 new Nette\InvalidArgumentException("Unable to concatenate non-scalar parameter '$part' into '$var'.");}$res.=$val;}}return$res;}/** @return array **/public static function autowireArguments(\ReflectionFunctionAbstract$method,array$arguments,$container){$optCount=0;$num=-1;$res=array();$methodName=($method instanceof\ReflectionMethod?$method->getDeclaringClass()->getName().'::':'').$method->getName().'()';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=PhpReflection::getParameterType($parameter))&&!PhpReflection::isBuiltinType($class)){$res[$num]=$container->getByType($class,FALSE);if($res[$num]===NULL){if($parameter->allowsNull()){$optCount++;}elseif(class_exists($class)||interface_exists($class)){$rc=new\ReflectionClass($class);if($class!==($hint=$rc->getName())){throw new ServiceCreationException("Service of type {$class} needed by $methodName not found, did you mean $hint?");}throw new ServiceCreationException("Service of type {$class} needed by $methodName not found. Did you register it in configuration file?");}else{throw new ServiceCreationException("Class {$class} needed by $methodName not found. Check type hint and 'use' statements.");}}else{if($container instanceof ContainerBuilder){$res[$num]='@'.$res[$num];}$optCount=0;}}elseif($parameter->isOptional()||$parameter->isDefaultValueAvailable()){$res[$num]=$parameter->isDefaultValueAvailable()?$parameter->getDefaultValue():NULL;$optCount++;}else{throw new ServiceCreationException("Parameter \${$parameter->getName()} in $methodName has no class type hint or default value, so its value must be specified.");}}while(array_key_exists(++$num,$arguments)){$res[$num]=$arguments[$num];unset($arguments[$num]);$optCount=0;}if($arguments){throw new ServiceCreationException("Unable to pass specified arguments to $methodName.");}return$optCount?array_slice($res,0,-$optCount):$res;}}getDocComment()){throw new Nette\InvalidStateException('You have to enable phpDoc comments in opcode cache.');}$ok=TRUE;}if(preg_match("#[\\s*]@$name(?:\\s++([^@]\\S*)?|$)#",trim($ref->getDocComment(),'/*'),$m)){return isset($m[1])?$m[1]:'';}}/** @return \ReflectionClass **/public static function getDeclaringClass(\ReflectionProperty$prop){if(PHP_VERSION_ID>=50400){foreach($prop->getDeclaringClass()->getTraits()as$trait){if($trait->hasProperty($prop->getName())){return self::getDeclaringClass($trait->getProperty($prop->getName()));}}}return$prop->getDeclaringClass();}/** @return string|NULL **/public static function getParameterType(\ReflectionParameter$param){if(PHP_VERSION_ID>=70000){return$param->hasType()?(string)$param->getType():NULL;}elseif($param->isArray()){return'array';}elseif(PHP_VERSION_ID>=50400&&$param->isCallable()){return'callable';}else{try{return($ref=$param->getClass())?$ref->getName():NULL;}catch(\ReflectionException$e){if(preg_match('#Class (.+) does not exist#',$e->getMessage(),$m)){return$m[1];}throw$e;}}}/** @return string|NULL **/public static function getReturnType(\ReflectionFunctionAbstract$func){if(PHP_VERSION_ID>=70000&&$func->hasReturnType()){return(string)$func->getReturnType();}$type=preg_replace('#[|\s].*#','',(string)self::parseAnnotation($func,'return'));if($type){return$func instanceof\ReflectionMethod?self::expandClassName($type,$func->getDeclaringClass()):ltrim($type,'\\');}}/** @return bool **/public static function isBuiltinType($type){return in_array(strtolower($type),array('string','int','float','bool','array','callable'),TRUE);}/** @return string full name **/public static function expandClassName($name,\ReflectionClass$rc){$lower=strtolower($name);if(empty($name)){throw new Nette\InvalidArgumentException('Class name must not be empty.');}elseif(self::isBuiltinType($lower)){return$lower;}elseif($lower==='self'||$lower==='static'||$lower==='$this'){return$rc->getName();}elseif($name[0]==='\\'){return ltrim($name,'\\');}$uses=&self::$cache[$rc->getName()];if($uses===NULL){self::$cache=self::parseUseStatemenets(file_get_contents($rc->getFileName()),$rc->getName())+self::$cache;$uses=&self::$cache[$rc->getName()];}$parts=explode('\\',$name,2);if(isset($uses[$parts[0]])){$parts[0]=$uses[$parts[0]];return implode('\\',$parts);}elseif($rc->inNamespace()){return$rc->getNamespaceName().'\\'.$name;}else{return$name;}}/** @return array **/public static function parseUseStatemenets($code,$forClass=NULL){$tokens=token_get_all($code);$namespace=$class=$classLevel=$level=NULL;$res=$uses=array();while(list(,$token)=each($tokens)){switch(is_array($token)?$token[0]:$token){case T_NAMESPACE:$namespace=ltrim(self::fetch($tokens,array(T_STRING,T_NS_SEPARATOR)).'\\','\\');$uses=array();break;case T_CLASS:case T_INTERFACE:case PHP_VERSION_ID<50400?-1:T_TRAIT:if($name=self::fetch($tokens,T_STRING)){$class=$namespace.$name;$classLevel=$level+1;$res[$class]=$uses;if($class===$forClass){return$res;}}break;case T_USE:while(!$class&&($name=self::fetch($tokens,array(T_STRING,T_NS_SEPARATOR)))){$name=ltrim($name,'\\');if(self::fetch($tokens,T_AS)){$uses[self::fetch($tokens,T_STRING)]=$name;}else{$tmp=explode('\\',$name);$uses[end($tmp)]=$name;}if(!self::fetch($tokens,',')){break;}}break;case T_CURLY_OPEN:case T_DOLLAR_OPEN_CURLY_BRACES:case'{':$level++;break;case'}':if($level===$classLevel){$class=$classLevel=NULL;}$level--;}}return$res;}private static function fetch(&$tokens,$take){$res=NULL;while($token=current($tokens)){list($token,$s)=is_array($token)?$token:array($token,$token);if(in_array($token,(array)$take,TRUE)){$res.=$s;}elseif(!in_array($token,array(T_DOC_COMMENT,T_WHITESPACE,T_COMMENT),TRUE)){break;}next($tokens);}return$res;}}class=ltrim($class,'\\');if($args){$this->setFactory($class,$args);}return$this;}/** @return string|NULL **/public function getClass(){return$this->class;}/** @return static **/public function setFactory($factory,array$args=array()){$this->factory=$factory instanceof Statement?$factory:new Statement($factory,$args);return$this;}/** @return Statement|NULL **/public function getFactory(){return$this->factory;}/** @return string|array|ServiceDefinition|NULL **/public function getEntity(){return$this->factory?$this->factory->getEntity():NULL;}/** @return static **/public function setArguments(array$args=array()){if(!$this->factory){$this->factory=new Statement($this->class);}$this->factory->arguments=$args;return$this;}/** @return static **/public function setSetup(array$setup){foreach($setup as$v){if(!$v instanceof Statement){throw new Nette\InvalidArgumentException('Argument must be Nette\DI\Statement[].');}}$this->setup=$setup;return$this;}/** @return Statement[] **/public function getSetup(){return$this->setup;}/** @return static **/public function addSetup($entity,array$args=array()){$this->setup[]=$entity instanceof Statement?$entity:new Statement($entity,$args);return$this;}/** @return static **/public function setParameters(array$params){$this->parameters=$params;return$this;}/** @return array **/public function getParameters(){return$this->parameters;}/** @return static **/public function setTags(array$tags){$this->tags=$tags;return$this;}/** @return array **/public function getTags(){return$this->tags;}/** @return static **/public function addTag($tag,$attr=TRUE){$this->tags[$tag]=$attr;return$this;}/** @return mixed **/public function getTag($tag){return isset($this->tags[$tag])?$this->tags[$tag]:NULL;}/** @return static **/public function setAutowired($state=TRUE){$this->autowired=(bool)$state;return$this;}/** @return bool **/public function isAutowired(){return$this->autowired;}/** @return static **/public function setDynamic($state=TRUE){$this->dynamic=(bool)$state;return$this;}/** @return bool **/public function isDynamic(){return$this->dynamic;}/** @return static **/public function setImplement($interface){$this->implement=ltrim($interface,'\\');return$this;}/** @return string|NULL **/public function getImplement(){return$this->implement;}/** @return static **/public function setImplementMode($mode){if(!in_array($mode,array(self::IMPLEMENT_MODE_CREATE,self::IMPLEMENT_MODE_GET),TRUE)){throw new Nette\InvalidArgumentException('Argument must be get|create.');}$this->implementMode=$mode;return$this;}/** @return string|NULL **/public function getImplementMode(){return$this->implementMode;}public function setImplementType($type){return$this->setImplementMode($type);}public function getImplementType(){return$this->implementMode;}public function setShared($on){trigger_error(__METHOD__.'() is deprecated.',E_USER_DEPRECATED);$this->autowired=$on?$this->autowired:FALSE;return$this;}public function isShared(){trigger_error(__METHOD__.'() is deprecated.',E_USER_DEPRECATED);}/** @return static **/public function setInject($state=TRUE){return$this->addTag(Extensions\InjectExtension::TAG_INJECT,$state);}/** @return bool|NULL **/public function getInject(){return$this->getTag(Extensions\InjectExtension::TAG_INJECT);}}setEntity($entity);$this->arguments=$arguments;}/** @return static **/public function setEntity($entity){if(!is_string($entity)&&!(is_array($entity)&&isset($entity[0],$entity[1]))&&!$entity instanceof ServiceDefinition&&$entity!==NULL){throw new Nette\InvalidArgumentException('Argument is not valid Statement entity.');}$this->entity=$entity;return$this;}public function getEntity(){return$this->entity;}}callback=$callback;}public function accept(){return call_user_func($this->callback,$this->current(),$this->key(),$this);}}select($mask,'isDir')->select($mask,'isFile');}/** @return Finder **/public static function findFiles($mask){if(!is_array($mask)){$mask=func_get_args();}$finder=new static;return$finder->select($mask,'isFile');}/** @return Finder **/public static function findDirectories($mask){if(!is_array($mask)){$mask=func_get_args();}$finder=new static;return$finder->select($mask,'isDir');}/** @return self **/private function select($masks,$type){$this->cursor=&$this->groups[];$pattern=self::buildPattern($masks);if($type||$pattern){$this->filter(function(RecursiveDirectoryIterator$file)use($type,$pattern){return!$file->isDot()&&(!$type||$file->$type())&&(!$pattern||preg_match($pattern,'/'.strtr($file->getSubPathName(),'\\','/')));});}return$this;}/** @return self **/public function in($path){if(!is_array($path)){$path=func_get_args();}$this->maxDepth=0;return$this->from($path);}/** @return self **/public function from($path){if($this->paths){throw new Nette\InvalidStateException('Directory to search has already been specified.');}if(!is_array($path)){$path=func_get_args();}$this->paths=$path;$this->cursor=&$this->exclude;return$this;}/** @return self **/public function childFirst(){$this->order=RecursiveIteratorIterator::CHILD_FIRST;return$this;}/** @return string **/private static function buildPattern($masks){$pattern=array();foreach($masks as$mask){$mask=rtrim(strtr($mask,'\\','/'),'/');$prefix='';if($mask===''){continue;}elseif($mask==='*'){return NULL;}elseif($mask[0]==='/'){$mask=ltrim($mask,'/');$prefix='(?<=^/)';}$pattern[]=$prefix.strtr(preg_quote($mask,'#'),array('\*\*'=>'.*','\*'=>'[^/]*','\?'=>'[^/]','\[\!'=>'[^','\['=>'[','\]'=>']','\-'=>'-'));}return$pattern?'#/('.implode('|',$pattern).')\z#i':NULL;}/** @return int **/public function count(){return iterator_count($this->getIterator());}/** @return \Iterator **/public function getIterator(){if(!$this->paths){throw new Nette\InvalidStateException('Call in() or from() to specify directory to search.');}elseif(count($this->paths)===1){return$this->buildIterator($this->paths[0]);}else{$iterator=new\AppendIterator();$iterator->append($workaround=new\ArrayIterator(array('workaround PHP bugs #49104, #63077')));foreach($this->paths as$path){$iterator->append($this->buildIterator($path));}unset($workaround[0]);return$iterator;}}/** @return \Iterator **/private function buildIterator($path){$iterator=new RecursiveDirectoryIterator($path,RecursiveDirectoryIterator::FOLLOW_SYMLINKS);if($this->exclude){$filters=$this->exclude;$iterator=new RecursiveCallbackFilterIterator($iterator,function($foo,$bar,RecursiveCallbackFilterIterator$iterator)use($filters){$file=$iterator->getInnerIterator();if(!$file->isDot()&&!$file->isFile()){foreach($filters as$filter){if(!call_user_func($filter,$file)){return FALSE;}}}return TRUE;});}if($this->maxDepth!==0){$iterator=new RecursiveIteratorIterator($iterator,$this->order);$iterator->setMaxDepth($this->maxDepth);}$groups=$this->groups;$iterator=new CallbackFilterIterator($iterator,function($foo,$bar,CallbackFilterIterator$file)use($groups){do{$file=$file->getInnerIterator();}while(!$file instanceof RecursiveDirectoryIterator);foreach($groups as$filters){foreach($filters as$filter){if(!call_user_func($filter,$file)){continue 2;}}return TRUE;}return FALSE;});return$iterator;}/** @return self **/public function exclude($masks){if(!is_array($masks)){$masks=func_get_args();}$pattern=self::buildPattern($masks);if($pattern){$this->filter(function(RecursiveDirectoryIterator$file)use($pattern){return!preg_match($pattern,'/'.strtr($file->getSubPathName(),'\\','/'));});}return$this;}/** @return self **/public function filter($callback){$this->cursor[]=$callback;return$this;}/** @return self **/public function limitDepth($depth){$this->maxDepth=$depth;return$this;}/** @return self **/public function size($operator,$size=NULL){if(func_num_args()===1){if(!preg_match('#^(?:([=<>!]=?|<>)\s*)?((?:\d*\.)?\d+)\s*(K|M|G|)B?\z#i',$operator,$matches)){throw new Nette\InvalidArgumentException('Invalid size predicate format.');}list(,$operator,$size,$unit)=$matches;static$units=array(''=>1,'k'=>1e3,'m'=>1e6,'g'=>1e9);$size*=$units[strtolower($unit)];$operator=$operator?$operator:'=';}return$this->filter(function(RecursiveDirectoryIterator$file)use($operator,$size){return Finder::compare($file->getSize(),$operator,$size);});}/** @return self **/public function date($operator,$date=NULL){if(func_num_args()===1){if(!preg_match('#^(?:([=<>!]=?|<>)\s*)?(.+)\z#i',$operator,$matches)){throw new Nette\InvalidArgumentException('Invalid date predicate format.');}list(,$operator,$date)=$matches;$operator=$operator?$operator:'=';}$date=DateTime::from($date)->format('U');return$this->filter(function(RecursiveDirectoryIterator$file)use($operator,$date){return Finder::compare($file->getMTime(),$operator,$date);});}/** @return bool **/public static function compare($l,$operator,$r){switch($operator){case'>':return$l>$r;case'>=':return$l>=$r;case'<':return$l<$r;case'<=':return$l<=$r;case'=':case'==':return$l==$r;case'!':case'!=':case'<>':return$l!=$r;default:throw new Nette\InvalidArgumentException("Unknown operator $operator.");}}}getInnerIterator()->hasChildren();}public function getChildren(){return new static($this->getInnerIterator()->getChildren(),$this->callback);}}getForm(FALSE);if(!$form||!$form->isAnchored()||!$form->isSubmitted()){$this->setValues($values,$erase);}return$this;}/** @return static **/public function setValues($values,$erase=FALSE){if($values instanceof\Traversable){$values=iterator_to_array($values);}elseif(!is_array($values)){throw new Nette\InvalidArgumentException(sprintf('First parameter must be an array, %s given.',gettype($values)));}foreach($this->getComponents()as$name=>$control){if($control instanceof IControl){if(array_key_exists($name,$values)){$control->setValue($values[$name]);}elseif($erase){$control->setValue(NULL);}}elseif($control instanceof self){if(array_key_exists($name,$values)){$control->setValues($values[$name],$erase);}elseif($erase){$control->setValues(array(),$erase);}}}return$this;}/** @return Nette\Utils\ArrayHash|array **/public function getValues($asArray=FALSE){$values=$asArray?array():new Nette\Utils\ArrayHash;foreach($this->getComponents()as$name=>$control){if($control instanceof IControl&&!$control->isOmitted()){$values[$name]=$control->getValue();}elseif($control instanceof self){$values[$name]=$control->getValues($asArray);}}return$values;}/** @return bool **/public function isValid(){if(!$this->validated){if($this->getErrors()){return FALSE;}$this->validate();}return!$this->getErrors();}/** @return void **/public function validate(array$controls=NULL){foreach($controls===NULL?$this->getComponents():$controls as$control){if($control instanceof IControl||$control instanceof self){$control->validate();}}if($this->onValidate!==NULL){if(!is_array($this->onValidate)&&!$this->onValidate instanceof\Traversable){throw new Nette\UnexpectedValueException('Property Form::$onValidate must be array or Traversable, '.gettype($this->onValidate).' given.');}foreach($this->onValidate as$handler){$params=Nette\Utils\Callback::toReflection($handler)->getParameters();$values=isset($params[1])?$this->getValues($params[1]->isArray()):NULL;Nette\Utils\Callback::invoke($handler,$this,$values);}}$this->validated=TRUE;}/** @return array **/public function getErrors(){$errors=array();foreach($this->getControls()as$control){$errors=array_merge($errors,$control->getErrors());}return array_unique($errors);}/** @return static **/public function setCurrentGroup(ControlGroup$group=NULL){$this->currentGroup=$group;return$this;}/** @return ControlGroup **/public function getCurrentGroup(){return$this->currentGroup;}/** @return static **/public function addComponent(Nette\ComponentModel\IComponent$component,$name,$insertBefore=NULL){parent::addComponent($component,$name,$insertBefore);if($this->currentGroup!==NULL&&$component instanceof IControl){$this->currentGroup->add($component);}return$this;}/** @return \ArrayIterator **/public function getControls(){return$this->getComponents(TRUE,'Nette\Forms\IControl');}/** @return Form **/public function getForm($need=TRUE){return$this->lookup('Nette\Forms\Form',$need);}/** @return Nette\Forms\Controls\TextInput **/public function addText($name,$label=NULL,$cols=NULL,$maxLength=NULL){$control=new Controls\TextInput($label,$maxLength);$control->setHtmlAttribute('size',$cols);return$this[$name]=$control;}/** @return Nette\Forms\Controls\TextInput **/public function addPassword($name,$label=NULL,$cols=NULL,$maxLength=NULL){$control=new Controls\TextInput($label,$maxLength);$control->setHtmlAttribute('size',$cols);return$this[$name]=$control->setHtmlType('password');}/** @return Nette\Forms\Controls\TextArea **/public function addTextArea($name,$label=NULL,$cols=NULL,$rows=NULL){$control=new Controls\TextArea($label);$control->setHtmlAttribute('cols',$cols)->setHtmlAttribute('rows',$rows);return$this[$name]=$control;}/** @return Nette\Forms\Controls\UploadControl **/public function addUpload($name,$label=NULL,$multiple=FALSE){return$this[$name]=new Controls\UploadControl($label,$multiple);}/** @return Nette\Forms\Controls\UploadControl **/public function addMultiUpload($name,$label=NULL){return$this[$name]=new Controls\UploadControl($label,TRUE);}/** @return Nette\Forms\Controls\HiddenField **/public function addHidden($name,$default=NULL){$control=new Controls\HiddenField;$control->setDefaultValue($default);return$this[$name]=$control;}/** @return Nette\Forms\Controls\Checkbox **/public function addCheckbox($name,$caption=NULL){return$this[$name]=new Controls\Checkbox($caption);}/** @return Nette\Forms\Controls\RadioList **/public function addRadioList($name,$label=NULL,array$items=NULL){return$this[$name]=new Controls\RadioList($label,$items);}/** @return Nette\Forms\Controls\CheckboxList **/public function addCheckboxList($name,$label=NULL,array$items=NULL){return$this[$name]=new Controls\CheckboxList($label,$items);}/** @return Nette\Forms\Controls\SelectBox **/public function addSelect($name,$label=NULL,array$items=NULL,$size=NULL){$control=new Controls\SelectBox($label,$items);if($size>1){$control->setHtmlAttribute('size',(int)$size);}return$this[$name]=$control;}/** @return Nette\Forms\Controls\MultiSelectBox **/public function addMultiSelect($name,$label=NULL,array$items=NULL,$size=NULL){$control=new Controls\MultiSelectBox($label,$items);if($size>1){$control->setHtmlAttribute('size',(int)$size);}return$this[$name]=$control;}/** @return Nette\Forms\Controls\SubmitButton **/public function addSubmit($name,$caption=NULL){return$this[$name]=new Controls\SubmitButton($caption);}/** @return Nette\Forms\Controls\Button **/public function addButton($name,$caption=NULL){return$this[$name]=new Controls\Button($caption);}/** @return Nette\Forms\Controls\ImageButton **/public function addImage($name,$src=NULL,$alt=NULL){return$this[$name]=new Controls\ImageButton($src,$alt);}/** @return self **/public function addContainer($name){$control=new self;$control->currentGroup=$this->currentGroup;return$this[$name]=$control;}/** @return void **/public function offsetSet($name,$component){$this->addComponent($component,$name);}/** @return Nette\ComponentModel\IComponent **/public function offsetGet($name){return$this->getComponent($name,TRUE);}/** @return bool **/public function offsetExists($name){return$this->getComponent($name,FALSE)!==NULL;}/** @return void **/public function offsetUnset($name){$component=$this->getComponent($name,FALSE);if($component!==NULL){$this->removeComponent($component);}}public function __clone(){throw new Nette\NotImplementedException('Form cloning is not supported yet.');}}controls=new\SplObjectStorage;}/** @return static **/public function add(){foreach(func_get_args()as$num=>$item){if($item instanceof IControl){$this->controls->attach($item);}elseif($item instanceof\Traversable||is_array($item)){call_user_func_array(array($this,'add'),is_array($item)?$item:iterator_to_array($item));}else{$type=is_object($item)?get_class($item):gettype($item);throw new Nette\InvalidArgumentException("IControl items expected, $type given.");}}return$this;}/** @return IControl[] **/public function getControls(){return iterator_to_array($this->controls);}/** @return static **/public function setOption($key,$value){if($value===NULL){unset($this->options[$key]);}else{$this->options[$key]=$value;}return$this;}/** @return mixed **/public function getOption($key,$default=NULL){return isset($this->options[$key])?$this->options[$key]:$default;}/** @return array **/public function getOptions(){return$this->options;}}monitor('Nette\Forms\Form');parent::__construct();$this->control=Html::el('input',array('type'=>NULL,'name'=>NULL));$this->label=Html::el('label');$this->caption=$caption;$this->rules=new Nette\Forms\Rules($this);$this->setValue(NULL);}/** @return void **/protected function attached($form){if(!$this->isDisabled()&&$form instanceof Form&&$form->isAnchored()&&$form->isSubmitted()){$this->loadHttpData();}}/** @return Form **/public function getForm($need=TRUE){return$this->lookup('Nette\Forms\Form',$need);}/** @return void **/public function loadHttpData(){$this->setValue($this->getHttpData(Form::DATA_TEXT));}/** @return mixed **/public function getHttpData($type,$htmlTail=NULL){return$this->getForm()->getHttpData($type,$this->getHtmlName().$htmlTail);}/** @return string **/public function getHtmlName(){return Nette\Forms\Helpers::generateHtmlName($this->lookupPath('Nette\Forms\Form'));}/** @return static **/public function setValue($value){$this->value=$value;return$this;}/** @return mixed **/public function getValue(){return$this->value;}/** @return bool **/public function isFilled(){$value=$this->getValue();return$value!==NULL&&$value!==array()&&$value!=='';}/** @return static **/public function setDefaultValue($value){$form=$this->getForm(FALSE);if($this->isDisabled()||!$form||!$form->isAnchored()||!$form->isSubmitted()){$this->setValue($value);}return$this;}/** @return static **/public function setDisabled($value=TRUE){if($this->disabled=(bool)$value){$this->omitted=TRUE;$this->setValue(NULL);}return$this;}/** @return bool **/public function isDisabled(){return$this->disabled===TRUE;}/** @return static **/public function setOmitted($value=TRUE){$this->omitted=(bool)$value;return$this;}/** @return bool **/public function isOmitted(){return$this->omitted;}/** @return Html|string **/public function getControl(){$this->setOption('rendered',TRUE);$el=clone$this->control;return$el->addAttributes(array('name'=>$this->getHtmlName(),'id'=>$this->getHtmlId(),'required'=>$this->isRequired(),'disabled'=>$this->isDisabled(),'data-nette-rules'=>Nette\Forms\Helpers::exportRules($this->rules)?:NULL));}/** @return Html|string **/public function getLabel($caption=NULL){$label=clone$this->label;$label->for=$this->getHtmlId();$label->setText($this->translate($caption===NULL?$this->caption:$caption));return$label;}/** @return Html **/public function getControlPrototype(){return$this->control;}/** @return Html **/public function getLabelPrototype(){return$this->label;}/** @return static **/public function setHtmlId($id){$this->control->id=$id;return$this;}/** @return string **/public function getHtmlId(){if(!isset($this->control->id)){$this->control->id=sprintf(self::$idMask,$this->lookupPath());}return$this->control->id;}/** @return static **/public function setHtmlAttribute($name,$value=TRUE){return$this->setAttribute($name,$value);}/** @return static **/public function setAttribute($name,$value=TRUE){$this->control->$name=$value;return$this;}/** @return static **/public function setTranslator(Nette\Localization\ITranslator$translator=NULL){$this->translator=$translator;return$this;}/** @return Nette\Localization\ITranslator|NULL **/public function getTranslator(){if($this->translator===TRUE){return$this->getForm(FALSE)?$this->getForm()->getTranslator():NULL;}return$this->translator;}/** @return string **/public function translate($value,$count=NULL){if($translator=$this->getTranslator()){$tmp=is_array($value)?array(&$value):array(array(&$value));foreach($tmp[0]as&$v){if($v!=NULL&&!$v instanceof Html){$v=$translator->translate($v,$count);}}}return$value;}/** @return static **/public function addRule($validator,$message=NULL,$arg=NULL){$this->rules->addRule($validator,$message,$arg);return$this;}/** @return Nette\Forms\Rules new branch **/public function addCondition($validator,$value=NULL){return$this->rules->addCondition($validator,$value);}/** @return Nette\Forms\Rules new branch **/public function addConditionOn(IControl$control,$validator,$value=NULL){return$this->rules->addConditionOn($control,$validator,$value);}/** @return Nette\Forms\Rules **/public function getRules(){return$this->rules;}/** @return static **/public function setRequired($value=TRUE){$this->rules->setRequired($value);return$this;}/** @return bool **/public function isRequired(){return$this->rules->isRequired();}/** @return void **/public function validate(){if($this->isDisabled()){return;}$this->cleanErrors();$this->rules->validate();}/** @return void **/public function addError($message){$this->errors[]=$message;}/** @return string **/public function getError(){return$this->errors?implode(' ',array_unique($this->errors)):NULL;}/** @return array **/public function getErrors(){return array_unique($this->errors);}/** @return bool **/public function hasErrors(){return(bool)$this->errors;}/** @return void **/public function cleanErrors(){$this->errors=array();}protected static function exportRules($rules){trigger_error(__METHOD__.'() is deprecated; use Nette\Forms\Helpers::exportRules() instead.',E_USER_DEPRECATED);return Nette\Forms\Helpers::exportRules($rules);}/** @return static **/public function setOption($key,$value){if($value===NULL){unset($this->options[$key]);}else{$this->options[$key]=$value;}return$this;}/** @return mixed **/public function getOption($key,$default=NULL){return isset($this->options[$key])?$this->options[$key]:$default;}/** @return array **/public function getOptions(){return$this->options;}}control->type='button';}/** @return bool **/public function isFilled(){$value=$this->getValue();return$value!==NULL&&$value!==array();}/** @return void **/public function getLabel($caption=NULL){return NULL;}/** @return Nette\Utils\Html **/public function getControl($caption=NULL){$this->setOption('rendered',TRUE);$el=clone$this->control;return$el->addAttributes(array('name'=>$this->getHtmlName(),'disabled'=>$this->isDisabled(),'value'=>$this->translate($caption===NULL?$this->caption:$caption)));}}control->type='checkbox';$this->wrapper=Nette\Utils\Html::el();}/** @return static **/public function setValue($value){if(!is_scalar($value)&&$value!==NULL){throw new Nette\InvalidArgumentException(sprintf("Value must be scalar or NULL, %s given in field '%s'.",gettype($value),$this->name));}$this->value=(bool)$value;return$this;}/** @return bool **/public function isFilled(){return$this->getValue()!==FALSE;}/** @return Nette\Utils\Html **/public function getControl(){return$this->wrapper->setHtml($this->getLabelPart()->insert(0,$this->getControlPart()));}/** @return void **/public function getLabel($caption=NULL){return NULL;}/** @return Nette\Utils\Html **/public function getControlPart(){return parent::getControl()->checked($this->value);}/** @return Nette\Utils\Html **/public function getLabelPart(){return parent::getLabel();}/** @return Nette\Utils\Html **/public function getSeparatorPrototype(){return$this->wrapper;}}control->type='checkbox';$this->separator=Html::el('br');}/** @return string **/public function getControl(){$items=$this->getItems();reset($items);$input=parent::getControl();return Nette\Forms\Helpers::createInputList($this->translate($items),array_merge($input->attrs,array('id'=>NULL,'checked?'=>$this->value,'disabled:'=>$this->disabled,'required'=>NULL,'data-nette-rules:'=>array(key($items)=>$input->attrs['data-nette-rules']))),$this->label->attrs,$this->separator);}/** @return Html **/public function getLabel($caption=NULL){return parent::getLabel($caption)->for(NULL);}/** @return Html **/public function getSeparatorPrototype(){return$this->separator;}/** @return Html **/public function getControlPart($key){$key=key(array((string)$key=>NULL));return parent::getControl()->addAttributes(array('id'=>$this->getHtmlId().'-'.$key,'checked'=>in_array($key,(array)$this->value,TRUE),'disabled'=>is_array($this->disabled)?isset($this->disabled[$key]):$this->disabled,'required'=>NULL,'value'=>$key));}/** @return Html **/public function getLabelPart($key=NULL){return func_num_args()?parent::getLabel($this->items[$key])->for($this->getHtmlId().'-'.$key):$this->getLabel();}}setItems($items);}}/** @return void **/public function loadHttpData(){$this->value=$this->getHttpData(Nette\Forms\Form::DATA_TEXT);if($this->value!==NULL){if(is_array($this->disabled)&&isset($this->disabled[$this->value])){$this->value=NULL;}else{$this->value=key(array($this->value=>NULL));}}}/** @return static **/public function setValue($value){if($this->checkAllowedValues&&$value!==NULL&&!array_key_exists((string)$value,$this->items)){$set=Nette\Utils\Strings::truncate(implode(', ',array_map(function($s){return var_export($s,TRUE);},array_keys($this->items))),70,'...');throw new Nette\InvalidArgumentException("Value '$value' is out of allowed set [$set] in field '{$this->name}'.");}$this->value=$value===NULL?NULL:key(array((string)$value=>NULL));return$this;}/** @return string|int **/public function getValue(){return array_key_exists($this->value,$this->items)?$this->value:NULL;}/** @return string|int **/public function getRawValue(){return$this->value;}/** @return bool **/public function isFilled(){return$this->getValue()!==NULL;}/** @return static **/public function setItems(array$items,$useKeys=TRUE){$this->items=$useKeys?$items:array_combine($items,$items);return$this;}/** @return array **/public function getItems(){return$this->items;}/** @return mixed **/public function getSelectedItem(){$value=$this->getValue();return$value===NULL?NULL:$this->items[$value];}/** @return static **/public function setDisabled($value=TRUE){if(!is_array($value)){return parent::setDisabled($value);}parent::setDisabled(FALSE);$this->disabled=array_fill_keys($value,TRUE);if(isset($this->disabled[$this->value])){$this->value=NULL;}return$this;}}setOmitted()->addRule(self::PROTECTION,$message);$this->monitor('Nette\Application\UI\Presenter');}protected function attached($parent){parent::attached($parent);if(!$this->session&&$parent instanceof Nette\Application\UI\Presenter){$this->session=$parent->getSession();}}/** @return static **/public function setValue($value){return$this;}/** @return void **/public function loadHttpData(){$this->value=$this->getHttpData(Nette\Forms\Form::DATA_TEXT);}/** @return string **/public function getToken(){$session=$this->getSession()->getSection(__CLASS__);if(!isset($session->token)){$session->token=Nette\Utils\Random::generate();}return$session->token^$this->getSession()->getId();}/** @return string **/private function generateToken($random=NULL){if($random===NULL){$random=Nette\Utils\Random::generate(10);}return$random.base64_encode(sha1($this->getToken().$random,TRUE));}/** @return Nette\Utils\Html **/public function getControl(){return parent::getControl()->value($this->generateToken());}/** @return bool **/public static function validateCsrf(CsrfProtection$control){$value=$control->getValue();return$control->generateToken(substr($value,0,10))===$value;}/** @return Nette\Http\Session **/private function getSession(){if(!$this->session){$this->session=new Nette\Http\Session($this->getForm()->httpRequest,new Nette\Http\Response);}return$this->session;}}control->type='hidden';if($persistentValue!==NULL){$this->unmonitor('Nette\Forms\Form');$this->persistValue=TRUE;$this->value=(string)$persistentValue;}}/** @return static **/public function setValue($value){if(!is_scalar($value)&&$value!==NULL&&!method_exists($value,'__toString')){throw new Nette\InvalidArgumentException(sprintf("Value must be scalar or NULL, %s given in field '%s'.",gettype($value),$this->name));}if(!$this->persistValue){$this->value=(string)$value;}return$this;}/** @return Nette\Utils\Html **/public function getControl(){$this->setOption('rendered',TRUE);$el=clone$this->control;return$el->addAttributes(array('name'=>$this->getHtmlName(),'disabled'=>$this->isDisabled(),'value'=>$this->value));}/** @return void **/public function getLabel($caption=NULL){return NULL;}/** @return void **/public function addError($message){$this->getForm()->addError($message);}}control->type='image';$this->control->src=$src;$this->control->alt=$alt;}/** @return void **/public function loadHttpData(){parent::loadHttpData();$this->value=$this->value?array((int)array_shift($this->value),(int)array_shift($this->value)):NULL;}/** @return string **/public function getHtmlName(){return parent::getHtmlName().'[]';}}setItems($items);}}/** @return void **/public function loadHttpData(){$this->value=array_keys(array_flip($this->getHttpData(Nette\Forms\Form::DATA_TEXT)));if(is_array($this->disabled)){$this->value=array_diff($this->value,array_keys($this->disabled));}}/** @return static **/public function setValue($values){if(is_scalar($values)||$values===NULL){$values=(array)$values;}elseif(!is_array($values)){throw new Nette\InvalidArgumentException(sprintf("Value must be array or NULL, %s given in field '%s'.",gettype($values),$this->name));}$flip=array();foreach($values as$value){if(!is_scalar($value)&&!method_exists($value,'__toString')){throw new Nette\InvalidArgumentException(sprintf("Values must be scalar, %s given in field '%s'.",gettype($value),$this->name));}$flip[(string)$value]=TRUE;}$values=array_keys($flip);if($this->checkAllowedValues&&($diff=array_diff($values,array_keys($this->items)))){$set=Nette\Utils\Strings::truncate(implode(', ',array_map(function($s){return var_export($s,TRUE);},array_keys($this->items))),70,'...');$vals=(count($diff)>1?'s':'')." '".implode("', '",$diff)."'";throw new Nette\InvalidArgumentException("Value$vals are out of allowed set [$set] in field '{$this->name}'.");}$this->value=$values;return$this;}/** @return array **/public function getValue(){return array_values(array_intersect($this->value,array_keys($this->items)));}/** @return array **/public function getRawValue(){return$this->value;}/** @return bool **/public function isFilled(){return$this->getValue()!==array();}/** @return static **/public function setItems(array$items,$useKeys=TRUE){$this->items=$useKeys?$items:array_combine($items,$items);return$this;}/** @return array **/public function getItems(){return$this->items;}/** @return array **/public function getSelectedItems(){return array_intersect_key($this->items,array_flip($this->value));}/** @return static **/public function setDisabled($value=TRUE){if(!is_array($value)){return parent::setDisabled($value);}parent::setDisabled(FALSE);$this->disabled=array_fill_keys($value,TRUE);$this->value=array_diff($this->value,$value);return$this;}/** @return string **/public function getHtmlName(){return parent::getHtmlName().'[]';}}$value){unset($items[$key]);if(is_array($value)){foreach($value as$val){$res[$key][(string)$val]=$val;}}else{$res[(string)$value]=$value;}}$items=$res;}$this->options=$items;return parent::setItems(Nette\Utils\Arrays::flatten($items,TRUE));}/** @return Nette\Utils\Html **/public function getControl(){$items=array();foreach($this->options as$key=>$value){$items[is_array($value)?$this->translate($key):$key]=$this->translate($value);}return Nette\Forms\Helpers::createSelectBox($items,array('selected?'=>$this->value,'disabled:'=>is_array($this->disabled)?$this->disabled:NULL))->addAttributes(parent::getControl()->attrs)->multiple(TRUE);}}control->type='radio';$this->container=Html::el();$this->separator=Html::el('br');$this->itemLabel=Html::el();}/** @return Html **/public function getControl(){$input=parent::getControl();$items=$this->getItems();$ids=array();if($this->generateId){foreach($items as$value=>$label){$ids[$value]=$input->id.'-'.$value;}}return$this->container->setHtml(Nette\Forms\Helpers::createInputList($this->translate($items),array_merge($input->attrs,array('id:'=>$ids,'checked?'=>$this->value,'disabled:'=>$this->disabled,'data-nette-rules:'=>array(key($items)=>$input->attrs['data-nette-rules']))),array('for:'=>$ids)+$this->itemLabel->attrs,$this->separator));}/** @return Html **/public function getLabel($caption=NULL){return parent::getLabel($caption)->for(NULL);}/** @return Html **/public function getControlPart($key){$key=key(array((string)$key=>NULL));return parent::getControl()->addAttributes(array('id'=>$this->getHtmlId().'-'.$key,'checked'=>in_array($key,(array)$this->value,TRUE),'disabled'=>is_array($this->disabled)?isset($this->disabled[$key]):$this->disabled,'value'=>$key));}/** @return Html **/public function getLabelPart($key=NULL){return func_num_args()?parent::getLabel($this->items[$key])->for($this->getHtmlId().'-'.$key):$this->getLabel();}/** @return Html **/public function getSeparatorPrototype(){return$this->separator;}/** @return Html **/public function getContainerPrototype(){return$this->container;}/** @return Html **/public function getItemLabelPrototype(){return$this->itemLabel;}}prompt=$prompt;return$this;}/** @return mixed **/public function getPrompt(){return$this->prompt;}/** @return static **/public function setItems(array$items,$useKeys=TRUE){if(!$useKeys){$res=array();foreach($items as$key=>$value){unset($items[$key]);if(is_array($value)){foreach($value as$val){$res[$key][(string)$val]=$val;}}else{$res[(string)$value]=$value;}}$items=$res;}$this->options=$items;return parent::setItems(Nette\Utils\Arrays::flatten($items,TRUE));}/** @return Nette\Utils\Html **/public function getControl(){$items=$this->prompt===FALSE?array():array(''=>$this->translate($this->prompt));foreach($this->options as$key=>$value){$items[is_array($value)?$this->translate($key):$key]=$this->translate($value);}return Nette\Forms\Helpers::createSelectBox($items,array('selected?'=>$this->value,'disabled:'=>is_array($this->disabled)?$this->disabled:NULL))->addAttributes(parent::getControl()->attrs);}/** @return void **/public function validate(){parent::validate();if(!$this->isDisabled()&&$this->prompt===FALSE&&$this->getValue()===NULL&&$this->options&&$this->control->size<2){$this->addError(Nette\Forms\Validator::$messages[self::VALID]);}}}control->type='submit';$this->setOmitted(TRUE);}/** @return void **/public function loadHttpData(){parent::loadHttpData();if($this->isFilled()){$this->getForm()->setSubmittedBy($this);}}/** @return bool **/public function isSubmittedBy(){return$this->getForm()->isSubmitted()===$this;}/** @return static **/public function setValidationScope($scope=NULL){if($scope===NULL||$scope===TRUE){$this->validationScope=NULL;}else{$this->validationScope=array();foreach($scope?:array()as$control){if(!$control instanceof Nette\Forms\Container&&!$control instanceof Nette\Forms\IControl){throw new Nette\InvalidArgumentException('Validation scope accepts only Nette\Forms\Container or Nette\Forms\IControl instances.');}$this->validationScope[]=$control;}}return$this;}/** @return array|NULL **/public function getValidationScope(){return$this->validationScope;}/** @return void **/public function click(){$this->onClick($this);}/** @return Nette\Utils\Html **/public function getControl($caption=NULL){$scope=array();foreach((array)$this->validationScope as$control){$scope[]=$control->lookupPath('Nette\Forms\Form');}return parent::getControl($caption)->addAttributes(array('formnovalidate'=>$this->validationScope!==NULL,'data-nette-validation-scope'=>$scope?:NULL));}}control->setName('textarea');}/** @return Nette\Utils\Html **/public function getControl(){$value=$this->getValue();if($value===''){$value=$this->translate($this->emptyValue);}return parent::getControl()->setText($value);}}name));}$this->rawValue=$this->value=$value;return$this;}/** @return string **/public function getValue(){return$this->value===Strings::trim($this->translate($this->emptyValue))?'':$this->value;}/** @return static **/public function setEmptyValue($value){$this->emptyValue=(string)$value;return$this;}/** @return string **/public function getEmptyValue(){return$this->emptyValue;}/** @return static **/public function setMaxLength($length){$this->control->maxlength=$length;return$this;}/** @return static **/public function addFilter($filter){$this->rules->addFilter($filter);return$this;}public function getControl(){$el=parent::getControl();if($this->emptyValue!==''){$el->attrs['data-nette-empty-value']=Strings::trim($this->translate($this->emptyValue));}if(isset($el->placeholder)){$el->placeholder=$this->translate($el->placeholder);}return$el;}public function addRule($validator,$message=NULL,$arg=NULL){if($validator===Form::LENGTH||$validator===Form::MAX_LENGTH){$tmp=is_array($arg)?$arg[1]:$arg;if(is_scalar($tmp)){$this->control->maxlength=isset($this->control->maxlength)?min($this->control->maxlength,$tmp):$tmp;}}return parent::addRule($validator,$message,$arg);}}control->type='text';$this->control->maxlength=$maxLength;}/** @return void **/public function loadHttpData(){$this->setValue($this->getHttpData(Form::DATA_LINE));}/** @return static **/public function setHtmlType($type){return$this->setType($type);}/** @return static **/public function setType($type){$this->control->type=$type;return$this;}/** @return Nette\Utils\Html **/public function getControl(){$input=parent::getControl();foreach($this->getRules()as$rule){if($rule->isNegative||$rule->branch){}elseif(in_array($rule->validator,array(Form::MIN,Form::MAX,Form::RANGE),TRUE)&&in_array($input->type,array('number','range','datetime-local','datetime','date','month','week','time'),TRUE)){if($rule->validator===Form::MIN){$range=array($rule->arg,NULL);}elseif($rule->validator===Form::MAX){$range=array(NULL,$rule->arg);}else{$range=$rule->arg;}if(isset($range[0])&&is_scalar($range[0])){$input->min=isset($input->min)?max($input->min,$range[0]):$range[0];}if(isset($range[1])&&is_scalar($range[1])){$input->max=isset($input->max)?min($input->max,$range[1]):$range[1];}}elseif($rule->validator===Form::PATTERN&&is_scalar($rule->arg)&&in_array($input->type,array('text','search','tel','url','email','password'),TRUE)){$input->pattern=$rule->arg;}}if($input->type!=='password'&&($this->rawValue!==''||$this->emptyValue!=='')){$input->value=$this->rawValue===''?$this->translate($this->emptyValue):$this->rawValue;}return$input;}}control->type='file';$this->control->multiple=(bool)$multiple;}/** @return void **/protected function attached($form){if($form instanceof Nette\Forms\Form){if($form->getMethod()!==Nette\Forms\Form::POST){throw new Nette\InvalidStateException('File upload requires method POST.');}$form->getElementPrototype()->enctype='multipart/form-data';}parent::attached($form);}/** @return void **/public function loadHttpData(){$this->value=$this->getHttpData(Nette\Forms\Form::DATA_FILE);if($this->value===NULL){$this->value=new FileUpload(NULL);}}/** @return string **/public function getHtmlName(){return parent::getHtmlName().($this->control->multiple?'[]':'');}/** @return static **/public function setValue($value){return$this;}/** @return bool **/public function isFilled(){return$this->value instanceof FileUpload?$this->value->isOk():(bool)$this->value;}/** @return bool **/public function isOk(){return$this->value instanceof FileUpload?$this->value->isOk():$this->value&&array_reduce($this->value,function($carry,$fileUpload){return$carry&&$fileUpload->isOk();},TRUE);}}getElementPrototype()->id='frm-'.$name;$tracker=new Controls\HiddenField($name);$tracker->setOmitted();$this[self::TRACKER_ID]=$tracker;$this->setParent(NULL,$name);}}/** @return void **/protected function validateParent(Nette\ComponentModel\IContainer$parent){parent::validateParent($parent);$this->monitor(__CLASS__);}/** @return void **/protected function attached($obj){if($obj instanceof self){throw new Nette\InvalidStateException('Nested forms are forbidden.');}}/** @return static **/public function getForm($need=TRUE){return$this;}/** @return static **/public function setAction($url){$this->getElementPrototype()->action=$url;return$this;}/** @return mixed URI **/public function getAction(){return$this->getElementPrototype()->action;}/** @return static **/public function setMethod($method){if($this->httpData!==NULL){throw new Nette\InvalidStateException(__METHOD__.'() must be called until the form is empty.');}$this->getElementPrototype()->method=strtolower($method);return$this;}/** @return string get | post **/public function getMethod(){return$this->getElementPrototype()->method;}/** @return Controls\CsrfProtection **/public function addProtection($message=NULL){return$this[self::PROTECTOR_ID]=new Controls\CsrfProtection($message);}/** @return ControlGroup **/public function addGroup($caption=NULL,$setAsCurrent=TRUE){$group=new ControlGroup;$group->setOption('label',$caption);$group->setOption('visual',TRUE);if($setAsCurrent){$this->setCurrentGroup($group);}if(!is_scalar($caption)||isset($this->groups[$caption])){return$this->groups[]=$group;}else{return$this->groups[$caption]=$group;}}/** @return void **/public function removeGroup($name){if(is_string($name)&&isset($this->groups[$name])){$group=$this->groups[$name];}elseif($name instanceof ControlGroup&&in_array($name,$this->groups,TRUE)){$group=$name;$name=array_search($group,$this->groups,TRUE);}else{throw new Nette\InvalidArgumentException("Group not found in form '$this->name'");}foreach($group->getControls()as$control){$control->getParent()->removeComponent($control);}unset($this->groups[$name]);}/** @return ControlGroup[] **/public function getGroups(){return$this->groups;}/** @return ControlGroup **/public function getGroup($name){return isset($this->groups[$name])?$this->groups[$name]:NULL;}/** @return static **/public function setTranslator(Nette\Localization\ITranslator$translator=NULL){$this->translator=$translator;return$this;}/** @return Nette\Localization\ITranslator|NULL **/public function getTranslator(){return$this->translator;}/** @return bool **/public function isAnchored(){return TRUE;}/** @return ISubmitterControl|FALSE submittor control **/public function isSubmitted(){if($this->submittedBy===NULL){$this->getHttpData();}return$this->submittedBy;}/** @return bool **/public function isSuccess(){return$this->isSubmitted()&&$this->isValid();}/** @return static **/public function setSubmittedBy(ISubmitterControl$by=NULL){$this->submittedBy=$by===NULL?FALSE:$by;return$this;}/** @return mixed **/public function getHttpData($type=NULL,$htmlName=NULL){if($this->httpData===NULL){if(!$this->isAnchored()){throw new Nette\InvalidStateException('Form is not anchored and therefore can not determine whether it was submitted.');}$data=$this->receiveHttpData();$this->httpData=(array)$data;$this->submittedBy=is_array($data);}if($htmlName===NULL){return$this->httpData;}return Helpers::extractHttpData($this->httpData,$htmlName,$type);}/** @return void **/public function fireEvents(){if(!$this->isSubmitted()){return;}elseif(!$this->getErrors()){$this->validate();}if($this->submittedBy instanceof ISubmitterControl){if($this->isValid()){$this->submittedBy->onClick($this->submittedBy);}else{$this->submittedBy->onInvalidClick($this->submittedBy);}}if(!$this->isValid()){$this->onError($this);}elseif($this->onSuccess!==NULL){if(!is_array($this->onSuccess)&&!$this->onSuccess instanceof\Traversable){throw new Nette\UnexpectedValueException('Property Form::$onSuccess must be array or Traversable, '.gettype($this->onSuccess).' given.');}foreach($this->onSuccess as$handler){$params=Nette\Utils\Callback::toReflection($handler)->getParameters();$values=isset($params[1])?$this->getValues($params[1]->isArray()):NULL;Nette\Utils\Callback::invoke($handler,$this,$values);if(!$this->isValid()){$this->onError($this);break;}}}$this->onSubmit($this);}/** @return array|NULL **/protected function receiveHttpData(){$httpRequest=$this->getHttpRequest();if(strcasecmp($this->getMethod(),$httpRequest->getMethod())){return;}if($httpRequest->isMethod('post')){$data=Nette\Utils\Arrays::mergeTree($httpRequest->getPost(),$httpRequest->getFiles());}else{$data=$httpRequest->getQuery();if(!$data){return;}}if($tracker=$this->getComponent(self::TRACKER_ID,FALSE)){if(!isset($data[self::TRACKER_ID])||$data[self::TRACKER_ID]!==$tracker->getValue()){return;}}return$data;}public function validate(array$controls=NULL){$this->cleanErrors();if($controls===NULL&&$this->submittedBy instanceof ISubmitterControl){$controls=$this->submittedBy->getValidationScope();}$this->validateMaxPostSize();parent::validate($controls);}public function validateMaxPostSize(){if(!$this->submittedBy||strcasecmp($this->getMethod(),'POST')||empty($_SERVER['CONTENT_LENGTH'])){return;}$maxSize=ini_get('post_max_size');$units=array('k'=>10,'m'=>20,'g'=>30);if(isset($units[$ch=strtolower(substr($maxSize,-1))])){$maxSize=(int)$maxSize<<$units[$ch];}if($maxSize>0&&$maxSize<$_SERVER['CONTENT_LENGTH']){$this->addError(sprintf(Validator::$messages[self::MAX_FILE_SIZE],$maxSize));}}/** @return void **/public function addError($message){$this->errors[]=$message;}/** @return array **/public function getErrors(){return array_unique(array_merge($this->errors,parent::getErrors()));}/** @return bool **/public function hasErrors(){return(bool)$this->getErrors();}/** @return void **/public function cleanErrors(){$this->errors=array();}/** @return array **/public function getOwnErrors(){return array_unique($this->errors);}/** @return Nette\Utils\Html **/public function getElementPrototype(){if(!$this->element){$this->element=Nette\Utils\Html::el('form');$this->element->action='';$this->element->method=self::POST;}return$this->element;}/** @return static **/public function setRenderer(IFormRenderer$renderer=NULL){$this->renderer=$renderer;return$this;}/** @return IFormRenderer **/public function getRenderer(){if($this->renderer===NULL){$this->renderer=new Rendering\DefaultFormRenderer;}return$this->renderer;}/** @return void **/public function render(){$args=func_get_args();array_unshift($args,$this);echo call_user_func_array(array($this->getRenderer(),'render'),$args);}/** @return string **/public function __toString(){try{return$this->getRenderer()->render($this);}catch(\Throwable$e){}catch(\Exception$e){}if(isset($e)){if(func_num_args()){throw$e;}trigger_error("Exception in ".__METHOD__."(): {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}",E_USER_ERROR);}}/** @return Nette\Http\IRequest **/private function getHttpRequest(){if(!$this->httpRequest){$factory=new Nette\Http\RequestFactory;$this->httpRequest=$factory->createHttpRequest();}return$this->httpRequest;}/** @return array **/public function getToggles(){$toggles=array();foreach($this->getComponents(TRUE,'Nette\Forms\Controls\BaseControl')as$control){$toggles=$control->getRules()->getToggleStates($toggles);}return$toggles;}}$v){$data[$k]=$v=static::sanitize($itype,$v);if($v===NULL){unset($data[$k]);}}if($type&Form::DATA_KEYS){return$data;}return array_values($data);}else{return static::sanitize($itype,$data);}}private static function sanitize($type,$value){if($type===Form::DATA_TEXT){return is_scalar($value)?Strings::normalizeNewLines($value):NULL;}elseif($type===Form::DATA_LINE){return is_scalar($value)?Strings::trim(strtr($value,"\r\n",' ')):NULL;}elseif($type===Form::DATA_FILE){return$value instanceof Nette\Http\FileUpload?$value:NULL;}else{throw new Nette\InvalidArgumentException('Unknown data type');}}/** @return string **/public static function generateHtmlName($id){$name=str_replace(Nette\ComponentModel\IComponent::NAME_SEPARATOR,'][',$id,$count);if($count){$name=substr_replace($name,'',strpos($name,']'),1).']';}if(is_numeric($name)||in_array($name,self::$unsafeNames,TRUE)){$name='_'.$name;}return$name;}/** @return array **/public static function exportRules(Rules$rules){$payload=array();foreach($rules as$rule){if(!is_string($op=$rule->validator)){if(!Nette\Utils\Callback::isStatic($op)){continue;}$op=Nette\Utils\Callback::toString($op);}if($rule->branch){$item=array('op'=>($rule->isNegative?'~':'').$op,'rules'=>static::exportRules($rule->branch),'control'=>$rule->control->getHtmlName());if($rule->branch->getToggles()){$item['toggle']=$rule->branch->getToggles();}elseif(!$item['rules']){continue;}}else{$item=array('op'=>($rule->isNegative?'~':'').$op,'msg'=>Validator::formatMessage($rule,FALSE));}if(is_array($rule->arg)){$item['arg']=array();foreach($rule->arg as$key=>$value){$item['arg'][$key]=$value instanceof IControl?array('control'=>$value->getHtmlName()):$value;}}elseif($rule->arg!==NULL){$item['arg']=$rule->arg instanceof IControl?array('control'=>$rule->arg->getHtmlName()):$rule->arg;}$payload[]=$item;}return$payload;}/** @return string **/public static function createInputList(array$items,array$inputAttrs=NULL,array$labelAttrs=NULL,$wrapper=NULL){list($inputAttrs,$inputTag)=self::prepareAttrs($inputAttrs,'input');list($labelAttrs,$labelTag)=self::prepareAttrs($labelAttrs,'label');$res='';$input=Html::el();$label=Html::el();list($wrapper,$wrapperEnd)=$wrapper instanceof Html?array($wrapper->startTag(),$wrapper->endTag()):array((string)$wrapper,'');foreach($items as$value=>$caption){foreach($inputAttrs as$k=>$v){$input->attrs[$k]=isset($v[$value])?$v[$value]:NULL;}foreach($labelAttrs as$k=>$v){$label->attrs[$k]=isset($v[$value])?$v[$value]:NULL;}$input->value=$value;$res.=($res===''&&$wrapperEnd===''?'':$wrapper).$labelTag.$label->attributes().'>'.$inputTag.$input->attributes().(Html::$xhtml?' />':'>').($caption instanceof Html?$caption:htmlspecialchars($caption,ENT_NOQUOTES,'UTF-8')).''.$wrapperEnd;}return$res;}/** @return Html **/public static function createSelectBox(array$items,array$optionAttrs=NULL,$selected=NULL){if($selected!==NULL){$optionAttrs['selected?']=$selected;}list($optionAttrs,$optionTag)=self::prepareAttrs($optionAttrs,'option');$option=Html::el();$res=$tmp='';foreach($items as$group=>$subitems){if(is_array($subitems)){$res.=Html::el('optgroup')->label($group)->startTag();$tmp='';}else{$subitems=array($group=>$subitems);}foreach($subitems as$value=>$caption){$option->value=$value;foreach($optionAttrs as$k=>$v){$option->attrs[$k]=isset($v[$value])?$v[$value]:NULL;}if($caption instanceof Html){$caption=clone$caption;$res.=$caption->setName('option')->addAttributes($option->attrs);}else{$res.=$optionTag.$option->attributes().'>'.htmlspecialchars($caption,ENT_NOQUOTES,'UTF-8').'';}}$res.=$tmp;$tmp='';}return Html::el('select')->setHtml($res);}private static function prepareAttrs($attrs,$name){$dynamic=array();foreach((array)$attrs as$k=>$v){$p=str_split($k,strlen($k)-1);if($p[1]==='?'||$p[1]===':'){unset($attrs[$k],$attrs[$p[0]]);if($p[1]==='?'){$dynamic[$p[0]]=array_fill_keys((array)$v,TRUE);}elseif(is_array($v)&&$v){$dynamic[$p[0]]=$v;}else{$attrs[$p[0]]=$v;}}}return array($dynamic,'<'.$name.Html::el(NULL,$attrs)->attributes());}}array('container'=>NULL),'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,'.error'=>NULL),'control'=>array('container'=>'td','.odd'=>NULL,'description'=>'small','requiredsuffix'=>'','errorcontainer'=>'span class=error','erroritem'=>'','.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;/** @return string **/public function render(Nette\Forms\Form$form,$mode=NULL){if($this->form!==$form){$this->form=$form;}$s='';if(!$mode||$mode==='begin'){$s.=$this->renderBegin();}if(!$mode||strtolower($mode)==='ownerrors'){$s.=$this->renderErrors();}elseif($mode==='errors'){$s.=$this->renderErrors(NULL,FALSE);}if(!$mode||$mode==='body'){$s.=$this->renderBody();}if(!$mode||$mode==='end'){$s.=$this->renderEnd();}return$s;}/** @return string **/public function 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();$query=parse_url($el->action,PHP_URL_QUERY);$el->action=str_replace("?$query",'',$el->action);$s='';foreach(preg_split('#[;&]#',$query,NULL,PREG_SPLIT_NO_EMPTY)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])));}}return$el->startTag().($s?"\n\t".$this->getWrapper('hidden container')->setHtml($s):'');}else{return$this->form->getElementPrototype()->startTag();}}/** @return string **/public function renderEnd(){$s='';foreach($this->form->getControls()as$control){if($control instanceof Nette\Forms\Controls\HiddenField&&!$control->getOption('rendered')){$s.=$control->getControl();}}if(iterator_count($this->form->getComponents(TRUE,'Nette\Forms\Controls\TextInput'))<2){$s.='';}if($s){$s=$this->getWrapper('hidden container')->setHtml($s)."\n";}return$s.$this->form->getElementPrototype()->endTag()."\n";}/** @return string **/public function renderErrors(Nette\Forms\IControl$control=NULL,$own=TRUE){$errors=$control?$control->getErrors():($own?$this->form->getOwnErrors():$this->form->getErrors());if(!$errors){return;}$container=$this->getWrapper($control?'control errorcontainer':'error container');$item=$this->getWrapper($control?'control erroritem':'error item');foreach($errors as$error){$item=clone$item;if($error instanceof Html){$item->addHtml($error);}else{$item->setText($error);}$container->addHtml($item);}return"\n".$container->render($control?1:0);}/** @return string **/public function 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 instanceof Html?clone$container:Html::el($container);$id=$group->getOption('id');if($id){$container->id=$id;}$s.="\n".$container->startTag();$text=$group->getOption('label');if($text instanceof Html){$s.=$this->getWrapper('group label')->addHtml($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 instanceof 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);}/** @return string **/public function renderControls($parent){if(!($parent instanceof Nette\Forms\Container||$parent instanceof Nette\Forms\ControlGroup)){throw new Nette\InvalidArgumentException('Argument must be Nette\Forms\Container or Nette\Forms\ControlGroup instance.');}$container=$this->getWrapper('controls container');$buttons=NULL;foreach($parent->getControls()as$control){if($control->getOption('rendered')||$control instanceof Nette\Forms\Controls\HiddenField||$control->getForm(FALSE)!==$this->form){}elseif($control instanceof Nette\Forms\Controls\Button){$buttons[]=$control;}else{if($buttons){$container->addHtml($this->renderPairMulti($buttons));$buttons=NULL;}$container->addHtml($this->renderPair($control));}}if($buttons){$container->addHtml($this->renderPairMulti($buttons));}$s='';if(count($container)){$s.="\n".$container."\n";}return$s;}/** @return string **/public function renderPair(Nette\Forms\IControl$control){$pair=$this->getWrapper('pair container');$pair->addHtml($this->renderLabel($control));$pair->addHtml($this->renderControl($control));$pair->class($this->getValue($control->isRequired()?'pair .required':'pair .optional'),TRUE);$pair->class($control->hasErrors()?$this->getValue('pair .error'):NULL,TRUE);$pair->class($control->getOption('class'),TRUE);if(++$this->counter % 2){$pair->class($this->getValue('pair .odd'),TRUE);}$pair->id=$control->getOption('id');return$pair->render(0);}/** @return string **/public function renderPairMulti(array$controls){$s=array();foreach($controls as$control){if(!$control instanceof Nette\Forms\IControl){throw new Nette\InvalidArgumentException('Argument must be array of Nette\Forms\IControl instances.');}$description=$control->getOption('description');if($description instanceof Html){$description=' '.$control->getOption('description');}elseif(is_string($description)){$description=' '.$this->getWrapper('control description')->setText($control->translate($description));}else{$description='';}$control->setOption('rendered',TRUE);$el=$control->getControl();if($el instanceof Html&&$el->getName()==='input'){$el->class($this->getValue("control .$el->type"),TRUE);}$s[]=$el.$description;}$pair=$this->getWrapper('pair container');$pair->addHtml($this->renderLabel($control));$pair->addHtml($this->getWrapper('control container')->setHtml(implode(' ',$s)));return$pair->render(0);}/** @return string **/public function renderLabel(Nette\Forms\IControl$control){$suffix=$this->getValue('label suffix').($control->isRequired()?$this->getValue('label requiredsuffix'):'');$label=$control->getLabel();if($label instanceof Html){$label->addHtml($suffix);if($control->isRequired()){$label->class($this->getValue('control .required'),TRUE);}}elseif($label!=NULL){$label.=$suffix;}return$this->getWrapper('label container')->setHtml($label);}/** @return string **/public function renderControl(Nette\Forms\IControl$control){$body=$this->getWrapper('control container');if($this->counter % 2){$body->class($this->getValue('control .odd'),TRUE);}$description=$control->getOption('description');if($description instanceof Html){$description=' '.$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;}$control->setOption('rendered',TRUE);$el=$control->getControl();if($el instanceof Html&&$el->getName()==='input'){$el->class($this->getValue("control .$el->type"),TRUE);}return$body->setHtml($el.$description.$this->renderErrors($control));}/** @return Html **/protected function getWrapper($name){$data=$this->getValue($name);return$data instanceof Html?clone$data:Html::el($data);}/** @return string **/protected function getValue($name){$name=explode(' ',$name);$data=&$this->wrappers[$name[0]][$name[1]];return$data;}}control=$control;}/** @return static **/public function setRequired($value=TRUE){if($value){$this->addRule(Form::REQUIRED,is_string($value)?$value:NULL);}else{$this->required=NULL;}return$this;}/** @return bool **/public function isRequired(){return$this->required instanceof Rule?!$this->required->isNegative:FALSE;}/** @return static **/public function addRule($validator,$message=NULL,$arg=NULL){if($validator===Form::VALID||$validator===~Form::VALID){throw new Nette\InvalidArgumentException('You cannot use Form::VALID in the addRule method.');}$rule=new Rule;$rule->control=$this->control;$rule->validator=$validator;$this->adjustOperation($rule);$rule->arg=$arg;$rule->message=$message;if($rule->validator===Form::REQUIRED){$this->required=$rule;}else{$this->rules[]=$rule;}return$this;}/** @return static new branch **/public function addCondition($validator,$arg=NULL){if($validator===Form::VALID||$validator===~Form::VALID){throw new Nette\InvalidArgumentException('You cannot use Form::VALID in the addCondition method.');}return$this->addConditionOn($this->control,$validator,$arg);}/** @return static new branch **/public function addConditionOn(IControl$control,$validator,$arg=NULL){$rule=new Rule;$rule->control=$control;$rule->validator=$validator;$this->adjustOperation($rule);$rule->arg=$arg;$rule->branch=new static($this->control);$rule->branch->parent=$this;$this->rules[]=$rule;return$rule->branch;}/** @return static else branch **/public function elseCondition(){$rule=clone end($this->parent->rules);$rule->isNegative=!$rule->isNegative;$rule->branch=new static($this->parent->control);$rule->branch->parent=$this->parent;$this->parent->rules[]=$rule;return$rule->branch;}/** @return Rules parent branch **/public function endCondition(){return$this->parent;}/** @return static **/public function addFilter($filter){Nette\Utils\Callback::check($filter);$this->rules[]=$rule=new Rule;$rule->control=$this->control;$rule->validator=function(IControl$control)use($filter){$control->setValue(call_user_func($filter,$control->getValue()));return TRUE;};return$this;}/** @return static **/public function toggle($id,$hide=TRUE){$this->toggles[$id]=$hide;return$this;}/** @return array **/public function getToggles($actual=FALSE){return$actual?$this->getToggleStates():$this->toggles;}/** @return array **/public function getToggleStates($toggles=array(),$success=TRUE){foreach($this->toggles as$id=>$hide){$toggles[$id]=($success xor!$hide)||!empty($toggles[$id]);}foreach($this as$rule){if($rule->branch){$toggles=$rule->branch->getToggleStates($toggles,$success&&static::validateRule($rule));}}return$toggles;}/** @return bool **/public function validate(){foreach($this as$rule){$success=$this->validateRule($rule);if($success&&$rule->branch&&!$rule->branch->validate()){return FALSE;}elseif(!$success&&!$rule->branch){$rule->control->addError(Validator::formatMessage($rule,TRUE));return FALSE;}}return TRUE;}/** @return bool **/public static function validateRule(Rule$rule){$args=is_array($rule->arg)?$rule->arg:array($rule->arg);foreach($args as&$val){$val=$val instanceof IControl?$val->getValue():$val;}return$rule->isNegative xor call_user_func(self::getCallback($rule),$rule->control,is_array($rule->arg)?$args:$args[0]);}/** @return \ArrayIterator **/public function getIterator(){$rules=$this->rules;if($this->required){array_unshift($rules,$this->required);}return new\ArrayIterator($rules);}/** @return void **/private function adjustOperation($rule){if(is_string($rule->validator)&&ord($rule->validator[0])>127){$rule->isNegative=TRUE;$rule->validator=~$rule->validator;}if(!is_callable($this->getCallback($rule))){$validator=is_scalar($rule->validator)?" '$rule->validator'":'';throw new Nette\InvalidArgumentException("Unknown validator$validator for control '{$rule->control->name}'.");}}private static function getCallback($rule){$op=$rule->validator;if(is_string($op)&&strncmp($op,':',1)===0){return'Nette\Forms\Validator::validate'.ltrim($op,':');}else{return$op;}}}Rules::$defaultMessages=&Validator::$messages;'Your session has expired. Please return to the home page and try again.',Form::EQUAL=>'Please enter %s.',Form::NOT_EQUAL=>'This value should not be %s.',Form::FILLED=>'This field is required.',Form::BLANK=>'This field should be blank.',Form::MIN_LENGTH=>'Please enter at least %d characters.',Form::MAX_LENGTH=>'Please enter no more 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 valid integer.',Form::FLOAT=>'Please enter a valid number.',Form::MIN=>'Please enter a value greater than or equal to %d.',Form::MAX=>'Please enter a value less than or equal to %d.',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::MAX_POST_SIZE=>'The uploaded data exceeds the limit of %d bytes.',Form::MIME_TYPE=>'The uploaded file is not in the expected format.',Form::IMAGE=>'The uploaded file must be image in format JPEG, GIF or PNG.',Controls\SelectBox::VALID=>'Please select a valid option.');public static function formatMessage(Rule$rule,$withValue=TRUE){$message=$rule->message;if($message instanceof Nette\Utils\Html){return$message;}elseif($message===NULL&&is_string($rule->validator)&&isset(static::$messages[$rule->validator])){$message=static::$messages[$rule->validator];}elseif($message==NULL){trigger_error("Missing validation message for control '{$rule->control->getName()}'.",E_USER_WARNING);}if($translator=$rule->control->getForm()->getTranslator()){$message=$translator->translate($message,is_int($rule->arg)?$rule->arg:NULL);}$message=preg_replace_callback('#%(name|label|value|\d+\$[ds]|[ds])#',function($m)use($rule,$withValue){static$i=-1;switch($m[1]){case'name':return$rule->control->getName();case'label':return$rule->control->translate($rule->control->caption);case'value':return$withValue?$rule->control->getValue():$m[0];default:$args=is_array($rule->arg)?$rule->arg:array($rule->arg);$i=(int)$m[1]?(int)$m[1]-1:$i+1;return isset($args[$i])?($args[$i]instanceof IControl?($withValue?$args[$i]->getValue():"%$i"):$args[$i]):'';}},$message);return$message;}/** @return bool **/public static function 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){continue 2;}}return FALSE;}return TRUE;}/** @return bool **/public static function validateNotEqual(IControl$control,$arg){return!static::validateEqual($control,$arg);}/** @return bool **/public static function validateFilled(IControl$control){return$control->isFilled();}/** @return bool **/public static function validateBlank(IControl$control){return!$control->isFilled();}/** @return bool **/public static function validateValid(IControl$control){return$control->getRules()->validate();}/** @return bool **/public static function validateRange(IControl$control,$range){return Validators::isInRange($control->getValue(),$range);}/** @return bool **/public static function validateMin(IControl$control,$minimum){return Validators::isInRange($control->getValue(),array($minimum,NULL));}/** @return bool **/public static function validateMax(IControl$control,$maximum){return Validators::isInRange($control->getValue(),array(NULL,$maximum));}/** @return bool **/public static function validateLength(IControl$control,$range){if(!is_array($range)){$range=array($range,$range);}$value=$control->getValue();return Validators::isInRange(is_array($value)?count($value):Strings::length($value),$range);}/** @return bool **/public static function validateMinLength(IControl$control,$length){return static::validateLength($control,array($length,NULL));}/** @return bool **/public static function validateMaxLength(IControl$control,$length){return static::validateLength($control,array(NULL,$length));}/** @return bool **/public static function validateSubmitted(Controls\SubmitButton$control){return$control->isSubmittedBy();}/** @return bool **/public static function validateEmail(IControl$control){return Validators::isEmail($control->getValue());}/** @return bool **/public static function validateUrl(IControl$control){if(Validators::isUrl($value=$control->getValue())){return TRUE;}elseif(Validators::isUrl($value="http://$value")){$control->setValue($value);return TRUE;}return FALSE;}/** @return bool **/public static function validatePattern(IControl$control,$pattern){return(bool)Strings::match($control->getValue(),"\x01^(?:$pattern)\\z\x01u");}/** @return bool **/public static function validateInteger(IControl$control){if(Validators::isNumericInt($value=$control->getValue())){if(!is_float($tmp=$value*1)){$control->setValue($tmp);}return TRUE;}return FALSE;}/** @return bool **/public static function validateFloat(IControl$control){$value=str_replace(array(' ',','),array('','.'),$control->getValue());if(Validators::isNumeric($value)){$control->setValue((float)$value);return TRUE;}return FALSE;}/** @return bool **/public static function validateFileSize(Controls\UploadControl$control,$limit){foreach(static::toArray($control->getValue())as$file){if($file->getSize()>$limit||$file->getError()===UPLOAD_ERR_INI_SIZE){return FALSE;}}return TRUE;}/** @return bool **/public static function validateMimeType(Controls\UploadControl$control,$mimeType){$mimeTypes=is_array($mimeType)?$mimeType:explode(',',$mimeType);foreach(static::toArray($control->getValue())as$file){$type=strtolower($file->getContentType());if(!in_array($type,$mimeTypes,TRUE)&&!in_array(preg_replace('#/.*#','/*',$type),$mimeTypes,TRUE)){return FALSE;}}return TRUE;}/** @return bool **/public static function validateImage(Controls\UploadControl$control){foreach(static::toArray($control->getValue())as$file){if(!$file->isImage()){return FALSE;}}return TRUE;}/** @return array **/private static function toArray($value){return$value instanceof Nette\Http\FileUpload?array($value):(array)$value;}}request=$request;$this->response=$response;}/** @return bool **/public function isModified($lastModified=NULL,$etag=NULL){if($lastModified){$this->response->setHeader('Last-Modified',Helpers::formatDate($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 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 TRUE;}}if(empty($match)){return TRUE;}$this->response->setCode(IResponse::S304_NOT_MODIFIED);return FALSE;}/** @return IRequest **/public function getRequest(){return$this->request;}/** @return IResponse **/public function getResponse(){return$this->response;}}error=UPLOAD_ERR_NO_FILE;return;}}$this->name=$value['name'];$this->size=$value['size'];$this->tmpName=$value['tmp_name'];$this->error=$value['error'];}/** @return string **/public function getName(){return$this->name;}/** @return string **/public function getSanitizedName(){return trim(Nette\Utils\Strings::webalize($this->name,'.',FALSE),'.-');}/** @return string|NULL **/public function getContentType(){if($this->isOk()&&$this->type===NULL){$this->type=finfo_file(finfo_open(FILEINFO_MIME_TYPE),$this->tmpName);}return$this->type;}/** @return int **/public function getSize(){return$this->size;}/** @return string **/public function getTemporaryFile(){return$this->tmpName;}/** @return string **/public function __toString(){return(string)$this->tmpName;}/** @return int **/public function getError(){return$this->error;}/** @return bool **/public function isOk(){return$this->error===UPLOAD_ERR_OK;}/** @return static **/public function 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 new Nette\InvalidStateException("Unable to move uploaded file '$this->tmpName' to '$dest'.");}@chmod($dest,0666);$this->tmpName=$dest;return$this;}/** @return bool **/public function isImage(){return in_array($this->getContentType(),array('image/gif','image/png','image/jpeg'),TRUE);}/** @return Nette\Utils\Image **/public function toImage(){return Nette\Utils\Image::fromFile($this->tmpName);}/** @return array|NULL **/public function getImageSize(){return$this->isOk()?@getimagesize($this->tmpName):NULL;}/** @return string|NULL **/public function getContents(){return$this->isOk()?file_get_contents($this->tmpName):NULL;}}setTimezone(new\DateTimeZone('GMT'));return$time->format('D, d M Y H:i:s \G\M\T');}/** @return bool **/public static function ipMatch($ip,$mask){list($mask,$size)=explode('/',$mask.'/');$tmp=function($n){return sprintf('%032b',$n);};$ip=implode('',array_map($tmp,unpack('N*',inet_pton($ip))));$mask=implode('',array_map($tmp,unpack('N*',inet_pton($mask))));$max=strlen($ip);if(!$max||$max!==strlen($mask)||$size<0||$size>$max){return FALSE;}return strncmp($ip,$mask,$size===''?$max:$size)===0;}/** @return void **/public static function 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;header_remove('Set-Cookie');}}foreach(array_values($flatten)as$key=>$header){header($header,$key===0);}}public static function stripSlashes($arr,$onlyKeys=FALSE){$res=array();foreach($arr as$k=>$v){$res[stripslashes($k)]=is_array($v)?self::stripSlashes($v,$onlyKeys):($onlyKeys?$v:stripslashes($v));}return$res;}} value) **/function getHeaders();/** @return void **/function setCookie($name,$value,$expire,$path=NULL,$domain=NULL,$secure=NULL,$httpOnly=NULL);/** @return void **/function deleteCookie($name,$path=NULL,$domain=NULL,$secure=NULL);}url=$url;if($query!==NULL){trigger_error('Nette\Http\Request::__construct(): parameter $query is deprecated.',E_USER_DEPRECATED);$url->setQuery($query);}$this->post=(array)$post;$this->files=(array)$files;$this->cookies=(array)$cookies;$this->headers=array_change_key_case((array)$headers,CASE_LOWER);$this->method=$method?:'GET';$this->remoteAddress=$remoteAddress;$this->remoteHost=$remoteHost;$this->rawBodyCallback=$rawBodyCallback;}/** @return static **/public function getUrl(){return clone$this->url;}/** @return mixed **/public function getQuery($key=NULL,$default=NULL){if(func_num_args()===0){return$this->url->getQueryParameters();}else{return$this->url->getQueryParameter($key,$default);}}/** @return mixed **/public function 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;}}/** @return FileUpload|NULL **/public function getFile($key){if(func_num_args()>1){trigger_error('Calling getFile() with multiple keys is deprecated.',E_USER_DEPRECATED);return Nette\Utils\Arrays::get($this->files,func_get_args(),NULL);}return isset($this->files[$key])?$this->files[$key]:NULL;}/** @return array **/public function getFiles(){return$this->files;}/** @return mixed **/public function getCookie($key,$default=NULL){return isset($this->cookies[$key])?$this->cookies[$key]:$default;}/** @return array **/public function getCookies(){return$this->cookies;}/** @return string **/public function getMethod(){return$this->method;}/** @return bool **/public function isMethod($method){return strcasecmp($this->method,$method)===0;}public function isPost(){return$this->isMethod('POST');}/** @return mixed **/public function getHeader($header,$default=NULL){$header=strtolower($header);return isset($this->headers[$header])?$this->headers[$header]:$default;}/** @return array **/public function getHeaders(){return$this->headers;}/** @return Url|NULL **/public function getReferer(){return isset($this->headers['referer'])?new Url($this->headers['referer']):NULL;}/** @return bool **/public function isSecured(){return$this->url->getScheme()==='https';}/** @return bool **/public function isAjax(){return$this->getHeader('X-Requested-With')==='XMLHttpRequest';}/** @return string|NULL **/public function getRemoteAddress(){return$this->remoteAddress;}/** @return string|NULL **/public function getRemoteHost(){if($this->remoteHost===NULL&&$this->remoteAddress!==NULL){$this->remoteHost=getHostByAddr($this->remoteAddress);}return$this->remoteHost;}/** @return string|NULL **/public function getRawBody(){return$this->rawBodyCallback?call_user_func($this->rawBodyCallback):NULL;}/** @return string|NULL **/public function detectLanguage(array$langs){$header=$this->getHeader('Accept-Language');if(!$header){return 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 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;}}array('#/{2,}#'=>'/'),'url'=>array());private$binary=FALSE;private$proxies=array();/** @return static **/public function setBinary($binary=TRUE){$this->binary=(bool)$binary;return$this;}/** @return static **/public function setProxy($proxy){$this->proxies=(array)$proxy;return$this;}/** @return Request **/public function createHttpRequest(){$url=new UrlScript;$url->setScheme(!empty($_SERVER['HTTPS'])&&strcasecmp($_SERVER['HTTPS'],'off')?'https':'http');$url->setUser(isset($_SERVER['PHP_AUTH_USER'])?$_SERVER['PHP_AUTH_USER']:'');$url->setPassword(isset($_SERVER['PHP_AUTH_PW'])?$_SERVER['PHP_AUTH_PW']:'');if((isset($_SERVER[$tmp='HTTP_HOST'])||isset($_SERVER[$tmp='SERVER_NAME']))&&preg_match('#^([a-z0-9_.-]+|\[[a-f0-9:]+\])(:\d+)?\z#i',$_SERVER[$tmp],$pair)){$url->setHost(strtolower($pair[1]));if(isset($pair[2])){$url->setPort(substr($pair[2],1));}elseif(isset($_SERVER['SERVER_PORT'])){$url->setPort($_SERVER['SERVER_PORT']);}}$requestUrl=isset($_SERVER['REQUEST_URI'])?$_SERVER['REQUEST_URI']:'/';$requestUrl=Strings::replace($requestUrl,$this->urlFilters['url']);$tmp=explode('?',$requestUrl,2);$path=Url::unescape($tmp[0],'%/?#');$path=Strings::fixEncoding(Strings::replace($path,$this->urlFilters['path']));$url->setPath($path);$url->setQuery(isset($tmp[1])?$tmp[1]:'');$lpath=strtolower($path);$script=isset($_SERVER['SCRIPT_NAME'])?strtolower($_SERVER['SCRIPT_NAME']):'';if($lpath!==$script){$max=min(strlen($lpath),strlen($script));for($i=0;$i<$max&&$lpath[$i]===$script[$i];$i++);$path=$i?substr($path,0,strrpos($path,'/',$i-strlen($path)-1)+1):'/';}$url->setScriptPath($path);$useFilter=(!in_array(ini_get('filter.default'),array('','unsafe_raw'))||ini_get('filter.default_flags'));$query=$url->getQueryParameters();$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);if(get_magic_quotes_gpc()){$post=Helpers::stripslashes($post,$useFilter);$cookies=Helpers::stripslashes($cookies,$useFilter);}$reChars='#^['.self::CHARS.']*+\z#u';if(!$this->binary){$list=array(&$query,&$post,&$cookies);while(list($key,$val)=each($list)){foreach($val as$k=>$v){if(is_string($k)&&(!preg_match($reChars,$k)||preg_last_error())){unset($list[$key][$k]);}elseif(is_array($v)){$list[$key][$k]=$v;$list[]=&$list[$key][$k];}else{$list[$key][$k]=(string)preg_replace('#[^'.self::CHARS.']+#u','',$v);}}}unset($list,$key,$val,$k,$v);}$url->setQuery($query);$files=array();$list=array();if(!empty($_FILES)){foreach($_FILES as$k=>$v){if(!is_array($v)||!isset($v['name'],$v['type'],$v['size'],$v['tmp_name'],$v['error'])||(!$this->binary&&is_string($k)&&(!preg_match($reChars,$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(get_magic_quotes_gpc()){$v['name']=stripSlashes($v['name']);}if(!$this->binary&&(!preg_match($reChars,$v['name'])||preg_last_error())){$v['name']='';}if($v['error']!==UPLOAD_ERR_NO_FILE){$v['@']=new FileUpload($v);}continue;}foreach($v['name']as$k=>$foo){if(!$this->binary&&is_string($k)&&(!preg_match($reChars,$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]);}}if(function_exists('apache_request_headers')){$headers=apache_request_headers();}else{$headers=array();foreach($_SERVER as$k=>$v){if(strncmp($k,'HTTP_',5)==0){$k=substr($k,5);}elseif(strncmp($k,'CONTENT_',8)){continue;}$headers[strtr($k,'_','-')]=$v;}}$remoteAddr=isset($_SERVER['REMOTE_ADDR'])?$_SERVER['REMOTE_ADDR']:NULL;$remoteHost=isset($_SERVER['REMOTE_HOST'])?$_SERVER['REMOTE_HOST']:NULL;foreach($this->proxies as$proxy){if(Helpers::ipMatch($remoteAddr,$proxy)&&!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){$proxies=$this->proxies;$xForwardedForWithoutProxies=array_filter(explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']),function($ip)use($proxies){return!array_filter($proxies,function($proxy)use($ip){return Helpers::ipMatch(trim($ip),$proxy);});});$remoteAddr=trim(end($xForwardedForWithoutProxies));if(!empty($_SERVER['HTTP_X_FORWARDED_HOST'])){$xForwardedForRealIpKey=key($xForwardedForWithoutProxies);$xForwardedHost=explode(',',$_SERVER['HTTP_X_FORWARDED_HOST']);if(isset($xForwardedHost[$xForwardedForRealIpKey])){$remoteHost=trim($xForwardedHost[$xForwardedForRealIpKey]);}}break;}}$method=isset($_SERVER['REQUEST_METHOD'])?$_SERVER['REQUEST_METHOD']:NULL;if($method==='POST'&&isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])&&preg_match('#^[A-Z]+\z#',$_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])){$method=$_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'];}$rawBodyCallback=function(){static$rawBody;if(PHP_VERSION_ID>=50600){return file_get_contents('php://input');}elseif($rawBody===NULL){$rawBody=(string)file_get_contents('php://input');}return$rawBody;};return new Request($url,NULL,$post,$files,$cookies,$headers,$method,$remoteAddr,$remoteHost,$rawBodyCallback);}}=50400){if(is_int($code=http_response_code())){$this->code=$code;}}if(PHP_VERSION_ID>=50401){$rm=new\ReflectionMethod('Nette\Http\Helpers::removeDuplicateCookies');header_register_callback($rm->getClosure());}}/** @return static **/public function setCode($code){$code=(int)$code;if($code<100||$code>599){throw new Nette\InvalidArgumentException("Bad HTTP response '$code'.");}self::checkHeaders();$this->code=$code;if(PHP_VERSION_ID>=50400){http_response_code($code);}else{$protocol=isset($_SERVER['SERVER_PROTOCOL'])?$_SERVER['SERVER_PROTOCOL']:'HTTP/1.1';header($protocol.' '.$code,TRUE,$code);}return$this;}/** @return int **/public function getCode(){return$this->code;}/** @return static **/public function setHeader($name,$value){self::checkHeaders();if($value===NULL){header_remove($name);}elseif(strcasecmp($name,'Content-Length')===0&&ini_get('zlib.output_compression')){}else{header($name.': '.$value,TRUE,$this->code);}return$this;}/** @return static **/public function addHeader($name,$value){self::checkHeaders();header($name.': '.$value,FALSE,$this->code);return$this;}/** @return static **/public function setContentType($type,$charset=NULL){$this->setHeader('Content-Type',$type.($charset?'; charset='.$charset:''));return$this;}/** @return void **/public function redirect($url,$code=self::S302_FOUND){$this->setCode($code);$this->setHeader('Location',$url);if(preg_match('#^https?:|^\s*+[a-z0-9+.-]*+[^:]#i',$url)){$escapedUrl=htmlSpecialChars($url,ENT_IGNORE|ENT_QUOTES,'UTF-8');echo"

Redirect

\n\n

Please click here to continue.

";}}/** @return static **/public function setExpiration($time){$this->setHeader('Pragma',NULL);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=DateTime::from($time);$this->setHeader('Cache-Control','max-age='.($time->format('U')-time()));$this->setHeader('Expires',Helpers::formatDate($time));return$this;}/** @return bool **/public function isSent(){return headers_sent();}/** @return mixed **/public function getHeader($header,$default=NULL){$header.=':';$len=strlen($header);foreach(headers_list()as$item){if(strncasecmp($item,$header,$len)===0){return ltrim(substr($item,$len));}}return$default;}/** @return array (name => value) **/public function getHeaders(){$headers=array();foreach(headers_list()as$header){$a=strpos($header,':');$headers[substr($header,0,$a)]=(string)substr($header,$a+2);}return$headers;}public static function date($time=NULL){return Helpers::formatDate($time);}/** @return void **/public function __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)&&preg_match('#^text/html(?:;|$)#',$this->getHeader('Content-Type','text/html'))){echo Nette\Utils\Random::generate(2e3," \t\r\n");self::$fixIE=FALSE;}}/** @return static **/public function setCookie($name,$value,$time,$path=NULL,$domain=NULL,$secure=NULL,$httpOnly=NULL){self::checkHeaders();setcookie($name,$value,$time?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);Helpers::removeDuplicateCookies();return$this;}/** @return void **/public function deleteCookie($name,$path=NULL,$domain=NULL,$secure=NULL){$this->setCookie($name,FALSE,0,$path,$domain,$secure);}public function removeDuplicateCookies(){trigger_error('Use Nette\Http\Helpers::removeDuplicateCookies()',E_USER_WARNING);}private function checkHeaders(){if(headers_sent($file,$line)){throw new Nette\InvalidStateException('Cannot send header after HTTP headers have been sent'.($file?" (output started at $file:$line).":'.'));}elseif($this->warnOnBuffer&&ob_get_length()&&!array_filter(ob_get_status(TRUE),function($i){return!$i['chunk_size'];})){trigger_error('Possible problem: you are sending a HTTP header while already having some data in output buffer. Try Tracy\OutputDebugger or start session earlier.',E_USER_NOTICE);}}}'','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;private$handler;public function __construct(IRequest$request,IResponse$response){$this->request=$request;$this->response=$response;}/** @return void **/public function start(){if(self::$started){return;}$this->configure($this->options);$id=$this->request->getCookie(session_name());if(is_string($id)&&preg_match('#^[0-9a-zA-Z,-]{22,128}\z#i',$id)){session_id($id);}else{unset($_COOKIE[session_name()]);}try{Nette\Utils\Callback::invokeSafe('session_start',array(),function($message)use(&$e){$e=new Nette\InvalidStateException($message);});}catch(\Exception$e){}Helpers::removeDuplicateCookies();if($e){@session_write_close();throw$e;}self::$started=TRUE;$nf=&$_SESSION['__NF'];if(empty($nf['Time'])){$nf['Time']=time();$this->regenerated=TRUE;}$browserKey=$this->request->getCookie('nette-browser');if(!is_string($browserKey)||!preg_match('#^[0-9a-z]{10}\z#',$browserKey)){$browserKey=Nette\Utils\Random::generate();}$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 as$variable=>$value){if((!empty($value['B'])&&$browserClosed)||(!empty($value['T'])&&$now>$value['T'])){if($variable===''){unset($nf['META'][$section],$nf['DATA'][$section]);continue 2;}unset($nf['META'][$section][$variable],$nf['DATA'][$section][$variable]);}}}}}if($this->regenerated){$this->regenerated=FALSE;$this->regenerateId();}register_shutdown_function(array($this,'clean'));}/** @return bool **/public function isStarted(){return(bool)self::$started;}/** @return void **/public function close(){if(self::$started){$this->clean();session_write_close();self::$started=FALSE;}}/** @return void **/public function destroy(){if(!self::$started){throw new 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']);}}/** @return bool **/public function exists(){return self::$started||$this->request->getCookie($this->getName())!==NULL;}/** @return void **/public function regenerateId(){if(self::$started&&!$this->regenerated){if(headers_sent($file,$line)){throw new Nette\InvalidStateException('Cannot regenerate session ID after HTTP headers have been sent'.($file?" (output started at $file:$line).":'.'));}if(session_id()!==''){session_regenerate_id(TRUE);}session_write_close();$backup=$_SESSION;session_start();$_SESSION=$backup;Helpers::removeDuplicateCookies();}$this->regenerated=TRUE;}/** @return string **/public function getId(){return session_id();}/** @return static **/public function setName($name){if(!is_string($name)||!preg_match('#[^0-9.][^.]*\z#A',$name)){throw new Nette\InvalidArgumentException('Session name must be a string and cannot contain dot.');}session_name($name);return$this->setOptions(array('name'=>$name));}/** @return string **/public function getName(){return isset($this->options['name'])?$this->options['name']:session_name();}/** @return SessionSection **/public function getSection($section,$class='Nette\Http\SessionSection'){return new$class($this,$section);}/** @return bool **/public function hasSection($section){if($this->exists()&&!self::$started){$this->start();}return!empty($_SESSION['__NF']['DATA'][$section]);}/** @return \ArrayIterator **/public function getIterator(){if($this->exists()&&!self::$started){$this->start();}if(isset($_SESSION['__NF']['DATA'])){return new\ArrayIterator(array_keys($_SESSION['__NF']['DATA']));}else{return new\ArrayIterator;}}/** @return void **/public function 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']);}}/** @return static **/public function setOptions(array$options){if(self::$started){$this->configure($options);}$this->options=$options+$this->options;if(!empty($options['auto_start'])){$this->start();}return$this;}/** @return array **/public function getOptions(){return$this->options;}/** @return void **/private function configure(array$config){$special=array('cache_expire'=>1,'cache_limiter'=>1,'save_path'=>1,'name'=>1);foreach($config 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 new 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(ini_get("session.$key")!=$value){throw new Nette\NotSupportedException("Unable to set 'session.$key' to '$value' because 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();}}if($this->handler){session_set_save_handler($this->handler);}}/** @return static **/public function setExpiration($time){if(empty($time)){return$this->setOptions(array('gc_maxlifetime'=>self::DEFAULT_FILE_LIFETIME,'cookie_lifetime'=>0));}else{$time=Nette\Utils\DateTime::from($time)->format('U')-time();return$this->setOptions(array('gc_maxlifetime'=>$time,'cookie_lifetime'=>$time));}}/** @return static **/public function setCookieParameters($path,$domain=NULL,$secure=NULL){return$this->setOptions(array('cookie_path'=>$path,'cookie_domain'=>$domain,'cookie_secure'=>$secure));}/** @return array containing items: lifetime, path, domain, secure, httponly **/public function getCookieParameters(){return session_get_cookie_params();}/** @return static **/public function setSavePath($path){return$this->setOptions(array('save_path'=>$path));}/** @return static **/public function setStorage(ISessionStorage$storage){if(self::$started){throw new 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'));return$this;}/** @return static **/public function setHandler(\SessionHandlerInterface$handler){if(self::$started){throw new Nette\InvalidStateException('Unable to set handler when session has been started.');}$this->handler=$handler;return$this;}/** @return void **/private function 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']);$this->response->setCookie('nette-browser',$_SESSION['__NF']['B'],Response::BROWSER,$cookie['path'],$cookie['domain']);}}session=$session;$this->name=$name;}private function start(){if($this->meta===FALSE){$this->session->start();$this->data=&$_SESSION['__NF']['DATA'][$this->name];$this->meta=&$_SESSION['__NF']['META'][$this->name];}}/** @return \ArrayIterator **/public function getIterator(){$this->start();if(isset($this->data)){return new\ArrayIterator($this->data);}else{return new\ArrayIterator;}}/** @return void **/public function __set($name,$value){$this->start();$this->data[$name]=$value;}/** @return mixed **/public 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];}/** @return bool **/public function __isset($name){if($this->session->exists()){$this->start();}return isset($this->data[$name]);}/** @return void **/public function __unset($name){$this->start();unset($this->data[$name],$this->meta[$name]);}/** @return void **/public function offsetSet($name,$value){$this->__set($name,$value);}/** @return mixed **/public function offsetGet($name){return$this->__get($name);}/** @return bool **/public function offsetExists($name){return$this->__isset($name);}/** @return void **/public function offsetUnset($name){$this->__unset($name);}/** @return static **/public function setExpiration($time,$variables=NULL){$this->start();if(empty($time)){$time=NULL;$whenBrowserIsClosed=TRUE;}else{$time=Nette\Utils\DateTime::from($time)->format('U');$max=(int)ini_get('session.gc_maxlifetime');if($max!==0&&($time-time()>$max+3)){trigger_error("The expiration time is greater than the session expiration $max seconds",E_USER_NOTICE);}$whenBrowserIsClosed=FALSE;}foreach(is_array($variables)?$variables:array($variables)as$variable){$this->meta[$variable]['T']=$time;$this->meta[$variable]['B']=$whenBrowserIsClosed;}return$this;}/** @return void **/public function removeExpiration($variables=NULL){$this->start();foreach(is_array($variables)?$variables:array($variables)as$variable){unset($this->meta[$variable]['T'],$this->meta[$variable]['B']);}}/** @return void **/public function remove(){$this->start();$this->data=NULL;$this->meta=NULL;}}80,'https'=>443,'ftp'=>21,'news'=>119,'nntp'=>119);private$scheme='';private$user='';private$password='';private$host='';private$port;private$path='';private$query=array();private$fragment='';public function __construct($url=NULL){if(is_string($url)){$p=@parse_url($url);if($p===FALSE){throw new Nette\InvalidArgumentException("Malformed or unsupported URI '$url'.");}$this->scheme=isset($p['scheme'])?$p['scheme']:'';$this->port=isset($p['port'])?$p['port']:NULL;$this->host=isset($p['host'])?rawurldecode($p['host']):'';$this->user=isset($p['user'])?rawurldecode($p['user']):'';$this->password=isset($p['pass'])?rawurldecode($p['pass']):'';$this->setPath(isset($p['path'])?$p['path']:'');$this->setQuery(isset($p['query'])?$p['query']:array());$this->fragment=isset($p['fragment'])?rawurldecode($p['fragment']):'';}elseif($url instanceof self){foreach($this as$key=>$val){$this->$key=$url->$key;}}}/** @return static **/public function setScheme($value){$this->scheme=(string)$value;return$this;}/** @return string **/public function getScheme(){return$this->scheme;}/** @return static **/public function setUser($value){$this->user=(string)$value;return$this;}/** @return string **/public function getUser(){return$this->user;}/** @return static **/public function setPassword($value){$this->password=(string)$value;return$this;}/** @return string **/public function getPassword(){return$this->password;}/** @return static **/public function setHost($value){$this->host=(string)$value;$this->setPath($this->path);return$this;}/** @return string **/public function getHost(){return$this->host;}/** @return static **/public function setPort($value){$this->port=(int)$value;return$this;}/** @return int **/public function getPort(){return$this->port?$this->port:(isset(self::$defaultPorts[$this->scheme])?self::$defaultPorts[$this->scheme]:NULL);}/** @return static **/public function setPath($value){$this->path=(string)$value;if($this->host&&substr($this->path,0,1)!=='/'){$this->path='/'.$this->path;}return$this;}/** @return string **/public function getPath(){return$this->path;}/** @return static **/public function setQuery($value){$this->query=is_array($value)?$value:self::parseQuery($value);return$this;}/** @return static **/public function appendQuery($value){$this->query=is_array($value)?$value+$this->query:self::parseQuery($this->getQuery().'&'.$value);return$this;}/** @return string **/public function getQuery(){if(PHP_VERSION_ID<50400){return str_replace('+','%20',http_build_query($this->query,'','&'));}return http_build_query($this->query,'','&',PHP_QUERY_RFC3986);}/** @return array **/public function getQueryParameters(){return$this->query;}/** @return mixed **/public function getQueryParameter($name,$default=NULL){return isset($this->query[$name])?$this->query[$name]:$default;}/** @return static **/public function setQueryParameter($name,$value){$this->query[$name]=$value;return$this;}/** @return static **/public function setFragment($value){$this->fragment=(string)$value;return$this;}/** @return string **/public function getFragment(){return$this->fragment;}/** @return string **/public function getAbsoluteUrl(){return$this->getHostUrl().$this->path.(($tmp=$this->getQuery())?'?'.$tmp:'').($this->fragment===''?'':'#'.$this->fragment);}/** @return string **/public function getAuthority(){return$this->host===''?'':($this->user!==''&&$this->scheme!=='http'&&$this->scheme!=='https'?rawurlencode($this->user).($this->password===''?'':':'.rawurlencode($this->password)).'@':'').$this->host.($this->port&&(!isset(self::$defaultPorts[$this->scheme])||$this->port!==self::$defaultPorts[$this->scheme])?':'.$this->port:'');}/** @return string **/public function getHostUrl(){return($this->scheme?$this->scheme.':':'').'//'.$this->getAuthority();}/** @return string **/public function getBasePath(){$pos=strrpos($this->path,'/');return$pos===FALSE?'':substr($this->path,0,$pos+1);}/** @return string **/public function getBaseUrl(){return$this->getHostUrl().$this->getBasePath();}/** @return string **/public function getRelativeUrl(){return(string)substr($this->getAbsoluteUrl(),strlen($this->getBaseUrl()));}/** @return bool **/public function isEqual($url){$url=new self($url);$query=$url->query;ksort($query);$query2=$this->query;ksort($query2);$http=in_array($this->scheme,array('http','https'),TRUE);return$url->scheme===$this->scheme&&!strcasecmp($url->host,$this->host)&&$url->getPort()===$this->getPort()&&($http||$url->user===$this->user)&&($http||$url->password===$this->password)&&self::unescape($url->path,'%/')===self::unescape($this->path,'%/')&&$query===$query2&&$url->fragment===$this->fragment;}/** @return static **/public function canonicalize(){$this->path=preg_replace_callback('#[^!$&\'()*+,/:;=@%]+#',function($m){return rawurlencode($m[0]);},self::unescape($this->path,'%/'));$this->host=strtolower($this->host);return$this;}/** @return string **/public function __toString(){return$this->getAbsoluteUrl();}/** @return string **/public static function unescape($s,$reserved='%;/?:@&=+$,'){if($reserved!==''){$s=preg_replace_callback('#%('.substr(chunk_split(bin2hex($reserved),2,'|'),0,-1).')#i',function($m){return'%25'.strtoupper($m[1]);},$s);}return rawurldecode($s);}/** @return array **/public static function parseQuery($s){parse_str($s,$res);if(get_magic_quotes_gpc()){$res=Helpers::stripSlashes($res);}return$res;}}scriptPath=(string)$value;return$this;}/** @return string **/public function getScriptPath(){return$this->scriptPath;}/** @return string **/public function getBasePath(){$pos=strrpos($this->scriptPath,'/');return$pos===FALSE?'':substr($this->getPath(),0,$pos+1);}/** @return string **/public function getPathInfo(){return(string)substr($this->getPath(),strlen($this->scriptPath));}}sessionHandler=$sessionHandler;}/** @return static **/public function 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;}/** @return bool **/public function isAuthenticated(){$session=$this->getSessionSection(FALSE);return$session&&$session->authenticated;}/** @return static **/public function setIdentity(IIdentity$identity=NULL){$this->getSessionSection(TRUE)->identity=$identity;return$this;}/** @return Nette\Security\IIdentity|NULL **/public function getIdentity(){$session=$this->getSessionSection(FALSE);return$session?$session->identity:NULL;}/** @return static **/public function setNamespace($namespace){if($this->namespace!==$namespace){$this->namespace=(string)$namespace;$this->sessionSection=NULL;}return$this;}/** @return string **/public function getNamespace(){return$this->namespace;}/** @return static **/public function setExpiration($time,$flags=0){$section=$this->getSessionSection(TRUE);if($time){$time=Nette\Utils\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;}/** @return int|NULL **/public function getLogoutReason(){$session=$this->getSessionSection(FALSE);return$session?$session->reason:NULL;}/** @return SessionSection **/protected function getSessionSection($need){if($this->sessionSection!==NULL){return$this->sessionSection;}if(!$need&&!$this->sessionHandler->exists()){return NULL;}$this->sessionSection=$section=$this->sessionHandler->getSection('Nette.Http.UserStorage/'.$this->namespace);if(!$section->identity instanceof 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->expireTimereason=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;}}getIterator();}while($iterator instanceof\IteratorAggregate);}elseif($iterator instanceof\Traversable){if(!$iterator instanceof\Iterator){$iterator=new\IteratorIterator($iterator);}}else{throw new Nette\InvalidArgumentException(sprintf('Invalid argument passed to %s; array or Traversable expected, %s given.',__CLASS__,is_object($iterator)?get_class($iterator):gettype($iterator)));}parent::__construct($iterator,0);}/** @return bool **/public function isFirst($width=NULL){return$this->counter===1||($width&&$this->counter!==0&&(($this->counter-1)%$width)===0);}/** @return bool **/public function isLast($width=NULL){return!$this->hasNext()||($width&&($this->counter %$width)===0);}/** @return bool **/public function isEmpty(){return$this->counter===0;}/** @return bool **/public function isOdd(){return$this->counter % 2===1;}/** @return bool **/public function isEven(){return$this->counter % 2===0;}/** @return int **/public function getCounter(){return$this->counter;}/** @return int **/public function count(){$inner=$this->getInnerIterator();if($inner instanceof\Countable){return$inner->count();}else{throw new Nette\NotSupportedException('Iterator is not countable.');}}/** @return void **/public function next(){parent::next();if(parent::valid()){$this->counter++;}}/** @return void **/public function rewind(){parent::rewind();$this->counter=parent::valid()?1:0;}/** @return mixed **/public function getNextKey(){return$this->getInnerIterator()->key();}/** @return mixed **/public function getNextValue(){return$this->getInnerIterator()->current();}/** @return mixed **/public function __call($name,$args){return ObjectMixin::call($this,$name,$args);}/** @return mixed property value **/public function&__get($name){return ObjectMixin::get($this,$name);}/** @return void **/public function __set($name,$value){ObjectMixin::set($this,$name,$value);}/** @return bool **/public function __isset($name){return ObjectMixin::has($this,$name);}/** @return void **/public function __unset($name){ObjectMixin::remove($this,$name);}}callback=Nette\Utils\Callback::check($callback);}public function accept(){return call_user_func($this->callback,$this->current(),$this->key(),$this);}}callback=Nette\Utils\Callback::check($callback);}public function current(){return call_user_func($this->callback,parent::current(),parent::key());}}getInnerIterator()->hasChildren();}public function getChildren(){return new static($this->getInnerIterator()->getChildren(),$this->callback);}}macroHandlers=new\SplObjectStorage;}/** @return static **/public function addMacro($name,IMacro$macro){$this->macros[$name][]=$macro;$this->macroHandlers->attach($macro);return$this;}/** @return string **/public function compile(array$tokens,$className){$this->templateId=substr(md5($className),0,10);$this->tokens=$tokens;$output='';$this->output=&$output;$this->htmlNode=$this->macroNode=$this->context=NULL;foreach($this->macroHandlers as$handler){$handler->initialize($this);}foreach($tokens as$this->position=>$token){$this->{"process$token->type"}($token);}while($this->htmlNode){if(!empty($this->htmlNode->macroAttrs)){throw new CompileException('Missing '.self::printEndTag($this->htmlNode));}$this->htmlNode=$this->htmlNode->parentNode;}$prologs=$epilogs='';foreach($this->macroHandlers as$handler){$res=$handler->finalize();$handlerName=get_class($handler);$prologs.=empty($res[0])?'':"";$epilogs=(empty($res[1])?'':"").$epilogs;}$output=($prologs?$prologs."\n":'').$output.$epilogs;if($this->macroNode){throw new CompileException('Missing '.self::printEndTag($this->macroNode));}$output=$this->expandTokens($output);$output="params as $__k => $__v) $$__k = $__v; unset($__k, $__v);'.'?>'.$output."contentType=$type;$this->context=NULL;return$this;}/** @return string **/public function getContentType(){return$this->contentType;}/** @return static **/public function setContext($context,$sub=NULL){$this->context=array($context,$sub);return$this;}/** @return array [context, subcontext] **/public function getContext(){return$this->context;}/** @return string **/public function getTemplateId(){return$this->templateId;}/** @return MacroNode|NULL **/public function getMacroNode(){return$this->macroNode;}/** @return int **/public function getLine(){return$this->tokens?$this->tokens[$this->position]->line:NULL;}public function expandTokens($s){return strtr($s,$this->attrCodes);}private function processText(Token$token){if(in_array($this->context[0],array(self::CONTEXT_SINGLE_QUOTED_ATTR,self::CONTEXT_DOUBLE_QUOTED_ATTR),TRUE)){if($token->text===$this->context[0]){$this->setContext(self::CONTEXT_UNQUOTED_ATTR);}elseif($this->lastAttrValue===''){$this->lastAttrValue=$token->text;}}$this->output.=$token->text;}private function processMacroTag(Token$token){if(in_array($this->context[0],array(self::CONTEXT_SINGLE_QUOTED_ATTR,self::CONTEXT_DOUBLE_QUOTED_ATTR,self::CONTEXT_UNQUOTED_ATTR),TRUE)){$this->lastAttrValue=TRUE;}$isRightmost=!isset($this->tokens[$this->position+1])||substr($this->tokens[$this->position+1]->text,0,1)==="\n";if($token->name[0]==='/'){$this->closeMacro((string)substr($token->name,1),$token->value,$token->modifiers,$isRightmost);}else{$this->openMacro($token->name,$token->value,$token->modifiers,$isRightmost&&!$token->empty);if($token->empty){$this->closeMacro($token->name,NULL,NULL,$isRightmost);}}}private function processHtmlTagBegin(Token$token){if($token->closing){while($this->htmlNode){if(strcasecmp($this->htmlNode->name,$token->name)===0){break;}if($this->htmlNode->macroAttrs){throw new CompileException("Unexpected name>, expecting ".self::printEndTag($this->htmlNode));}$this->htmlNode=$this->htmlNode->parentNode;}if(!$this->htmlNode){$this->htmlNode=new HtmlNode($token->name);}$this->htmlNode->closing=TRUE;$this->htmlNode->offset=strlen($this->output);$this->setContext(NULL);}elseif($token->text===''){$this->output.=$token->text;$this->setContext(NULL);return;}$htmlNode=$this->htmlNode;$end='';if(!$htmlNode->closing){$htmlNode->isEmpty=strpos($token->text,'/')!==FALSE;if(in_array($this->contentType,array(self::CONTENT_HTML,self::CONTENT_XHTML),TRUE)){$emptyElement=isset(Helpers::$emptyElements[strtolower($htmlNode->name)]);$htmlNode->isEmpty=$htmlNode->isEmpty||$emptyElement;if($htmlNode->isEmpty){$space=substr(strstr($token->text,'>'),1);if($emptyElement){$token->text=($this->contentType===self::CONTENT_XHTML?' />':'>').$space;}else{$token->text='>';$end="name>".$space;}}}}if($htmlNode->macroAttrs){$code=substr($this->output,$htmlNode->offset).$token->text;$this->output=substr($this->output,0,$htmlNode->offset);$this->writeAttrsMacro($code);}else{$this->output.=$token->text.$end;}if($htmlNode->isEmpty){$htmlNode->closing=TRUE;if($htmlNode->macroAttrs){$this->writeAttrsMacro($end);}}$this->setContext(NULL);if($htmlNode->closing){$this->htmlNode=$this->htmlNode->parentNode;}elseif((($lower=strtolower($htmlNode->name))==='script'||$lower==='style')&&(!isset($htmlNode->attrs['type'])||preg_match('#(java|j|ecma|live)script|json|css#i',$htmlNode->attrs['type']))){$this->setContext($lower==='script'?self::CONTENT_JS:self::CONTENT_CSS);}}private function processHtmlAttribute(Token$token){if(strncmp($token->name,Parser::N_PREFIX,strlen(Parser::N_PREFIX))===0){$name=substr($token->name,strlen(Parser::N_PREFIX));if(isset($this->htmlNode->macroAttrs[$name])){throw new CompileException("Found multiple attributes $token->name.");}elseif($this->macroNode&&$this->macroNode->htmlNode===$this->htmlNode){throw new CompileException("n:attributes must not appear inside macro; found $token->name inside {{$this->macroNode->name}}.");}$this->htmlNode->macroAttrs[$name]=$token->value;return;}$this->lastAttrValue=&$this->htmlNode->attrs[$token->name];$this->output.=$token->text;if(in_array($token->value,array(self::CONTEXT_SINGLE_QUOTED_ATTR,self::CONTEXT_DOUBLE_QUOTED_ATTR),TRUE)){$this->lastAttrValue='';$contextMain=$token->value;}else{$this->lastAttrValue=$token->value;$contextMain=self::CONTEXT_UNQUOTED_ATTR;}$context=NULL;if(in_array($this->contentType,array(self::CONTENT_HTML,self::CONTENT_XHTML),TRUE)){$lower=strtolower($token->name);if(substr($lower,0,2)==='on'){$context=self::CONTENT_JS;}elseif($lower==='style'){$context=self::CONTENT_CSS;}elseif(in_array($lower,array('href','src','action','formaction'),TRUE)||($lower==='data'&&strtolower($this->htmlNode->name)==='object')){$context=self::CONTENT_URL;}}$this->setContext($contextMain,$context);}private function processComment(Token$token){$leftOfs=($tmp=strrpos($this->output,"\n"))===FALSE?0:$tmp+1;$isLeftmost=trim(substr($this->output,$leftOfs))==='';$isRightmost=substr($token->text,-1)==="\n";if($isLeftmost&&$isRightmost){$this->output=substr($this->output,0,$leftOfs);}else{$this->output.=substr($token->text,strlen(rtrim($token->text,"\n")));}}/** @return MacroNode **/public function openMacro($name,$args=NULL,$modifiers=NULL,$isRightmost=FALSE,$nPrefix=NULL){$node=$this->expandMacro($name,$args,$modifiers,$nPrefix);if($node->isEmpty){$this->writeCode($node->openingCode,$this->output,$node->replaced,$isRightmost);}else{$this->macroNode=$node;$node->saved=array(&$this->output,$isRightmost);$this->output=&$node->content;}return$node;}/** @return MacroNode **/public function closeMacro($name,$args=NULL,$modifiers=NULL,$isRightmost=FALSE,$nPrefix=NULL){$node=$this->macroNode;if(!$node||($node->name!==$name&&''!==$name)||$modifiers||($args&&$node->args&&strncmp("$node->args ","$args ",strlen($args)+1))||$nPrefix!==$node->prefix){$name=$nPrefix?"htmlNode->name}> for ".Parser::N_PREFIX.implode(' and '.Parser::N_PREFIX,array_keys($this->htmlNode->macroAttrs)):'{/'.$name.($args?' '.$args:'').$modifiers.'}';throw new CompileException("Unexpected $name".($node?', expecting '.self::printEndTag($node->prefix?$this->htmlNode:$node):''));}$this->macroNode=$node->parentNode;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->replaced,$node->saved[1]);$this->writeCode($node->closingCode,$node->content,$node->replaced,$isRightmost,$isLeftmost);$this->output.=$node->content;return$node;}private function writeCode($code,&$output,$replaced,$isRightmost,$isLeftmost=NULL){if($isRightmost){$leftOfs=($tmp=strrpos($output,"\n"))===FALSE?0:$tmp+1;if($isLeftmost===NULL){$isLeftmost=trim(substr($output,$leftOfs))==='';}if($replaced===NULL){$replaced=preg_match('#<\?php.*\secho\s#As',$code);}if($isLeftmost&&!$replaced){$output=substr($output,0,$leftOfs);}elseif(substr($code,-2)==='?>'){$code.="\n";}}$output.=$code;}/** @return void **/public function writeAttrsMacro($code){$attrs=$this->htmlNode->macroAttrs;$left=$right=array();foreach($this->macros as$name=>$foo){$attrName=MacroNode::PREFIX_INNER."-$name";if(isset($attrs[$attrName])){if($this->htmlNode->closing){$left[]=array('closeMacro',$name,'',MacroNode::PREFIX_INNER);}else{array_unshift($right,array('openMacro',$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('openMacro',$name,$attrs[$attrName],MacroNode::PREFIX_TAG);array_unshift($right,array('closeMacro',$name,'',MacroNode::PREFIX_TAG));unset($attrs[$attrName]);}}foreach($this->macros as$name=>$foo){if(isset($attrs[$name])){if($this->htmlNode->closing){$right[]=array('closeMacro',$name,'',MacroNode::PREFIX_NONE);}else{array_unshift($left,array('openMacro',$name,$attrs[$name],MacroNode::PREFIX_NONE));}unset($attrs[$name]);}}if($attrs){throw new CompileException('Unknown attribute '.Parser::N_PREFIX.implode(' and '.Parser::N_PREFIX,array_keys($attrs)));}if(!$this->htmlNode->closing){$this->htmlNode->attrCode=&$this->attrCodes[$uniq=' n:'.substr(lcg_value(),2,10)];$code=substr_replace($code,$uniq,strrpos($code,'/>')?:strrpos($code,'>'),0);}foreach($left as$item){$node=$this->{$item[0]}($item[1],$item[2],NULL,NULL,$item[3]);if($node->closing||$node->isEmpty){$this->htmlNode->attrCode.=$node->attrCode;if($node->isEmpty){unset($this->htmlNode->macroAttrs[$node->name]);}}}$this->output.=$code;foreach($right as$item){$node=$this->{$item[0]}($item[1],$item[2],NULL,NULL,$item[3]);if($node->closing){$this->htmlNode->attrCode.=$node->attrCode;}}if($right&&substr($this->output,-2)==='?>'){$this->output.="\n";}}/** @return MacroNode **/public function expandMacro($name,$args,$modifiers=NULL,$nPrefix=NULL){$inScript=in_array($this->context[0],array(self::CONTENT_JS,self::CONTENT_CSS),TRUE);if(empty($this->macros[$name])){$hint=($t=Helpers::getSuggestion(array_keys($this->macros),$name))?", did you mean {{$t}}?":'';throw new CompileException("Unknown macro {{$name}}$hint".($inScript?' (in JavaScript or CSS, try to put a space after bracket or use n:syntax=off)':''));}if(strpbrk($name,'=~%^&_')){if($this->context[1]===self::CONTENT_URL){$modifiers=preg_replace('#\|nosafeurl\s?(?=\||\z)#i','',$modifiers,-1,$found);if(!$found&&!preg_match('#\|datastream(?=\s|\||\z)#i',$modifiers)){$modifiers.='|safeurl';}}$modifiers=preg_replace('#\|noescape\s?(?=\||\z)#i','',$modifiers,-1,$found);if(!$found){$modifiers.='|escape';}if(!$found&&$inScript&&$name==='='&&preg_match('#["\'] *\z#',$this->tokens[$this->position-1]->text)){throw new CompileException("Do not place {$this->tokens[$this->position]->text} inside quotes.");}}foreach(array_reverse($this->macros[$name])as$macro){$node=new MacroNode($macro,$name,$args,$modifiers,$this->macroNode,$this->htmlNode,$nPrefix);if($macro->nodeOpened($node)!==FALSE){return$node;}}throw new CompileException('Unknown '.($nPrefix?'attribute '.Parser::N_PREFIX.($nPrefix===MacroNode::PREFIX_NONE?'':"$nPrefix-").$name:'macro {'.$name.($args?" $args":'').'}'));}private static function printEndTag($node){if($node instanceof HtmlNode){return"name}> for ".Parser::N_PREFIX.implode(' and '.Parser::N_PREFIX,array_keys($node->macroAttrs));}else{return"{/$node->name}";}}}array(),'bytes'=>'Latte\Runtime\Filters::bytes','capitalize'=>'Latte\Runtime\Filters::capitalize','datastream'=>'Latte\Runtime\Filters::dataStream','date'=>'Latte\Runtime\Filters::date','escapecss'=>'Latte\Runtime\Filters::escapeCss','escapehtml'=>'Latte\Runtime\Filters::escapeHtml','escapehtmlcomment'=>'Latte\Runtime\Filters::escapeHtmlComment','escapeical'=>'Latte\Runtime\Filters::escapeICal','escapejs'=>'Latte\Runtime\Filters::escapeJs','escapeurl'=>'rawurlencode','escapexml'=>'Latte\Runtime\Filters::escapeXML','firstupper'=>'Latte\Runtime\Filters::firstUpper','implode'=>'implode','indent'=>'Latte\Runtime\Filters::indent','lower'=>'Latte\Runtime\Filters::lower','nl2br'=>'Latte\Runtime\Filters::nl2br','number'=>'number_format','repeat'=>'str_repeat','replace'=>'Latte\Runtime\Filters::replace','replacere'=>'Latte\Runtime\Filters::replaceRe','safeurl'=>'Latte\Runtime\Filters::safeUrl','strip'=>'Latte\Runtime\Filters::strip','striptags'=>'strip_tags','substr'=>'Latte\Runtime\Filters::substring','trim'=>'Latte\Runtime\Filters::trim','truncate'=>'Latte\Runtime\Filters::truncate','upper'=>'Latte\Runtime\Filters::upper');/** @return void **/public function render($name,array$params=array()){$class=$this->getTemplateClass($name);if(!class_exists($class,FALSE)){$this->loadTemplate($name);}$template=new$class($params,$this,$name);$template->render();}/** @return string **/public function renderToString($name,array$params=array()){ob_start(function(){});try{$this->render($name,$params);}catch(\Throwable$e){ob_end_clean();throw$e;}catch(\Exception$e){ob_end_clean();throw$e;}return ob_get_clean();}/** @return string **/public function compile($name){foreach($this->onCompile?:array()as$cb){call_user_func(Helpers::checkCallback($cb),$this);}$this->onCompile=array();$source=$this->getLoader()->getContent($name);try{$tokens=$this->getParser()->setContentType($this->contentType)->parse($source);$code=$this->getCompiler()->setContentType($this->contentType)->compile($tokens,$this->getTemplateClass($name));}catch(\Exception$e){if(!$e instanceof CompileException){$e=new CompileException("Thrown exception '{$e->getMessage()}'",NULL,$e);}$line=isset($tokens)?$this->getCompiler()->getLine():$this->getParser()->getLine();throw$e->setSource($source,$line,$name);}if(!preg_match('#\n|\?#',$name)){$code="".$code;}$code=Helpers::optimizePhp($code);return$code;}/** @return void **/public function warmupCache($name){if(!$this->tempDirectory){throw new\LogicException('Path to temporary directory is not set.');}$class=$this->getTemplateClass($name);if(!class_exists($class,FALSE)){$this->loadTemplate($name);}}/** @return void **/private function loadTemplate($name){if(!$this->tempDirectory){$code=$this->compile($name);if(@eval('?>'.$code)===FALSE){$error=error_get_last();$e=new CompileException('Error in template: '.$error['message']);throw$e->setSource($code,$error['line'],"$name (compiled)");}return;}$file=$this->getCacheFile($name);if(!$this->isExpired($file,$name)&&(@include$file)!==FALSE){return;}if(!is_dir($this->tempDirectory)){@mkdir($this->tempDirectory);}$handle=fopen("$file.lock",'c+');if(!$handle||!flock($handle,LOCK_EX)){throw new\RuntimeException("Unable to acquire exclusive lock '$file.lock'.");}if(!is_file($file)||$this->isExpired($file,$name)){$code=$this->compile($name);if(file_put_contents("$file.tmp",$code)!==strlen($code)||!rename("$file.tmp",$file)){@unlink("$file.tmp");throw new\RuntimeException("Unable to create '$file'.");}}if((include$file)===FALSE){throw new\RuntimeException("Unable to load '$file'.");}flock($handle,LOCK_UN);}/** @return bool **/private function isExpired($file,$name){return$this->autoRefresh&&$this->getLoader()->isExpired($name,(int)@filemtime($file));}/** @return string **/public function getCacheFile($name){$file=$this->getTemplateClass($name);if(preg_match('#\b\w.{10,50}$#',$name,$m)){$file=trim(preg_replace('#\W+#','-',$m[0]),'-').'-'.$file;}return$this->tempDirectory.'/'.$file.'.php';}/** @return string **/public function getTemplateClass($name){return'Template'.md5("$this->tempDirectory\00$name");}/** @return static **/public function addFilter($name,$callback){if($name==NULL){array_unshift($this->filters[NULL],$callback);}else{$this->filters[strtolower($name)]=$callback;}return$this;}/** @return callable[] **/public function getFilters(){return$this->filters;}/** @return mixed **/public function invokeFilter($name,array$args){$lname=strtolower($name);if(!isset($this->filters[$lname])){$args2=$args;array_unshift($args2,$lname);foreach($this->filters[NULL]as$filter){$res=call_user_func_array(Helpers::checkCallback($filter),$args2);if($res!==NULL){return$res;}elseif(isset($this->filters[$lname])){return call_user_func_array(Helpers::checkCallback($this->filters[$lname]),$args);}}$hint=($t=Helpers::getSuggestion(array_keys($this->filters),$name))?", did you mean '$t'?":'.';throw new\LogicException("Filter '$name' is not defined$hint");}return call_user_func_array(Helpers::checkCallback($this->filters[$lname]),$args);}/** @return static **/public function addMacro($name,IMacro$macro){$this->getCompiler()->addMacro($name,$macro);return$this;}/** @return static **/public function setContentType($type){$this->contentType=$type;return$this;}/** @return static **/public function setTempDirectory($path){$this->tempDirectory=$path;return$this;}/** @return static **/public function setAutoRefresh($on=TRUE){$this->autoRefresh=(bool)$on;return$this;}/** @return Parser **/public function getParser(){if(!$this->parser){$this->parser=new Parser;}return$this->parser;}/** @return Compiler **/public function getCompiler(){if(!$this->compiler){$this->compiler=new Compiler;Macros\CoreMacros::install($this->compiler);Macros\BlockMacros::install($this->compiler);}return$this->compiler;}/** @return static **/public function setLoader(ILoader$loader){$this->loader=$loader;return$this;}/** @return ILoader **/public function getLoader(){if(!$this->loader){$this->loader=new Loaders\FileLoader;}return$this->loader;}}sourceCode=(string)$code;$this->sourceLine=(int)$line;$this->sourceName=(string)$name;if(@is_file($name)){$this->message=rtrim($this->message,'.').' in '.str_replace(dirname(dirname($name)),'...',$name).($line?":$line":'');}return$this;}}class RegexpException extends\Exception{public static$messages=array(PREG_INTERNAL_ERROR=>'Internal error',PREG_BACKTRACK_LIMIT_ERROR=>'Backtrack limit was exhausted',PREG_RECURSION_LIMIT_ERROR=>'Recursion limit was exhausted',PREG_BAD_UTF8_ERROR=>'Malformed UTF-8 data',5=>'Offset didn\'t correspond to the begin of a valid UTF-8 code point');public function __construct($message,$code=NULL){parent::__construct($message?:(isset(self::$messages[$code])?self::$messages[$code]:'Unknown error'),$code);}}class RuntimeException extends\Exception{}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,'track'=>1);/** @return callable **/public static function checkCallback($callable){if(!is_callable($callable,FALSE,$text)){throw new\InvalidArgumentException("Callback '$text' is not callable.");}return$callable;}/** @return string **/public static function optimizePhp($source,$lineLength=80){$res=$php='';$lastChar=';';$tokens=new\ArrayIterator(token_get_all($source));foreach($tokens as$n=>$token){if(is_array($token)){if($token[0]===T_INLINE_HTML){$lastChar='';$res.=$token[1];}elseif($token[0]===T_CLOSE_TAG){$next=isset($tokens[$n+1])?$tokens[$n+1]:NULL;if(substr($res,-1)!=='<'&&preg_match('#^<\?php\s*\z#',$php)){$php='';}elseif(is_array($next)&&$next[0]===T_OPEN_TAG&&(!isset($tokens[$n+2][1])||$tokens[$n+2][1]!=='xml')){if(!strspn($lastChar,';{}:/')){$php.=$lastChar=';';}if(substr($next[1],-1)==="\n"){$php.="\n";}$tokens->next();}elseif($next){$res.=preg_replace('#;?(\s)*\z#','$1',$php).$token[1];if(strlen($res)-strrpos($res,"\n")>$lineLength&&(!is_array($next)||strpos($next[1],"\n")===FALSE)){$res.="\n";}$php='';}else{if(!strspn($lastChar,'};')){$php.=';';}}}elseif($token[0]===T_ELSE||$token[0]===T_ELSEIF){if($tokens[$n+1]===':'&&$lastChar==='}'){$php.=';';}$lastChar='';$php.=$token[1];}elseif($token[0]===T_OPEN_TAG&&$token[1]==='?';for($tokens->next();$tokens->valid();$tokens->next()){$token=$tokens->current();$res.=is_array($token)?$token[1]:$token;if($token[0]===T_CLOSE_TAG){break;}}}else{if(!in_array($token[0],array(T_WHITESPACE,T_COMMENT,T_DOC_COMMENT,T_OPEN_TAG),TRUE)){$lastChar='';}$php.=$token[1];}}else{$php.=$lastChar=$token;}}return$res.$php;}/** @return string|NULL **/public static function getSuggestion(array$items,$value){$best=NULL;$min=(strlen($value)/4+1)*10+.1;foreach(array_unique($items,SORT_REGULAR)as$item){$item=is_object($item)?$item->getName():$item;if(($len=levenshtein($item,$value,10,11,10))>0&&$len<$min){$min=$len;$best=$item;}}return$best;}}name=$name;$this->parentNode=$parentNode;}}isExpired($file,time())){if(@touch($file)===FALSE){$tmp=error_get_last();trigger_error("File's modification time is in the future. Cannot update it: $tmp[message]",E_USER_WARNING);}}return file_get_contents($file);}/** @return bool **/public function isExpired($file,$time){return@filemtime($file)>$time;}/** @return string **/public function getChildName($file,$parent=NULL){if($parent&&!preg_match('#/|\\\\|[a-z][a-z0-9+.-]*:#iA',$file)){$file=dirname($parent).'/'.$file;}return$file;}}macro=$macro;$this->name=(string)$name;$this->modifiers=(string)$modifiers;$this->parentNode=$parentNode;$this->htmlNode=$htmlNode;$this->prefix=$prefix;$this->data=new\stdClass;$this->setArgs($args);}public function setArgs($args){$this->args=(string)$args;$this->tokenizer=new MacroTokens($this->args);}}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('snippetArea',array($me,'macroBlock'),array($me,'macroBlockEnd'));$me->addMacro('ifset',array($me,'macroIfset'),'}');$me->addMacro('elseifset',array($me,'macroIfset'),'}');}/** @return void **/public function initialize(){$this->namedBlocks=array();$this->extends=NULL;}/** @return array(prolog, epilog) **/public function finalize(){$last=$this->getCompiler()->getMacroNode();if($last&&$last->name==='block'){$this->getCompiler()->closeMacro($last->name);}$epilog=$prolog=array();if($this->namedBlocks){foreach($this->namedBlocks 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(\$_b->blocks[".var_export($name,TRUE)."][] = '$func')) { "."function $func(\$_b, \$_args) { foreach (\$_args as \$__k => \$__v) \$\$__k = \$__v".($snippet?'; $_control->redrawControl('.var_export((string)substr($name,1),TRUE).', FALSE)':'')."\n?>$codenamedBlocks||$this->extends){$prolog[]='// template extending';$prolog[]='$_l->extends = '.($this->extends?$this->extends:'empty($_g->extended) && isset($_control) && $_control instanceof Nette\Application\UI\Presenter ? $_control->findLayoutTemplateFile() : NULL').'; $_g->extended = TRUE;';$prolog[]='if ($_l->extends) { ob_start(function () {});}';if(!$this->namedBlocks){$epilog[]='if ($_l->extends) { ob_end_clean(); return $template->renderChildTemplate($_l->extends, get_defined_vars());}';}}return array(implode("\n\n",$prolog),implode("\n",$epilog));}public function macroInclude(MacroNode$node,PhpWriter$writer){$destination=$node->tokenizer->fetchWord();if(!preg_match('~#|[\w-]+\z~A',$destination)){return 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 new CompileException("Cannot include $destination block outside of any block.");}$destination=$item->data->name;}$name=strpos($destination,'$')===FALSE?var_export($destination,TRUE):$destination;if(isset($this->namedBlocks[$destination])&&!$parent){$cmd="call_user_func(reset(\$_b->blocks[$name]), \$_b, %node.array? + get_defined_vars())";}else{$cmd='Latte\Macros\BlockMacrosRuntime::callBlock'.($parent?'Parent':'')."(\$_b, $name, %node.array? + ".($parent?'get_defined_vars':'$template->getParameters').'())';}if($node->modifiers){return$writer->write("ob_start(function () {}); $cmd; echo %modify(ob_get_clean())");}else{return$writer->write($cmd);}}public function macroIncludeBlock(MacroNode$node,PhpWriter$writer){if($node->modifiers){trigger_error("Modifiers are not allowed in {{$node->name}}",E_USER_WARNING);}return$writer->write('ob_start(function () {}); $_g->includingBlock = isset($_g->includingBlock) ? ++$_g->includingBlock : 1; $_b->templates[%var]->renderChildTemplate(%node.word, %node.array? + get_defined_vars()); $_g->includingBlock--; echo rtrim(ob_get_clean())',$this->getCompiler()->getTemplateId());}public function macroExtends(MacroNode$node,PhpWriter$writer){if($node->modifiers){trigger_error("Modifiers are not allowed in {{$node->name}}",E_USER_WARNING);}if(!$node->args){throw new CompileException("Missing destination in {{$node->name}}");}if(!empty($node->parentNode)){throw new CompileException("{{$node->name}} must be placed outside any macro.");}if($this->extends!==NULL){throw new CompileException("Multiple {{$node->name}} 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;}public function macroBlock(MacroNode$node,PhpWriter$writer){$name=$node->tokenizer->fetchWord();if($node->name==='#'){trigger_error('Shortcut {#block} is deprecated.',E_USER_DEPRECATED);}elseif($node->name==='block'&&$name===FALSE){return$node->modifiers===''?'':'ob_start(function () {})';}$node->data->name=$name=ltrim($name,'#');if($name==NULL){if($node->name==='define'){throw new CompileException('Missing block name.');}}elseif(strpos($name,'$')!==FALSE){if($node->name==='snippet'){for($parent=$node->parentNode;$parent&&!($parent->name==='snippet'||$parent->name==='snippetArea');$parent=$parent->parentNode);if(!$parent){throw new CompileException('Dynamic snippets are allowed only inside static snippet/snippetArea.');}$parent->data->dynamic=TRUE;$node->data->leave=TRUE;$node->closingCode="dynSnippets[\$_l->dynSnippetId] = ob_get_flush() ?>";if($node->prefix){$node->attrCode=$writer->write("dynSnippetId = \$_control->getSnippetId({$writer->formatWord($name)})) . '\"' ?>");return$writer->write('ob_start()');}$tag=trim($node->tokenizer->fetchWord(),'<>');$tag=$tag?$tag:'div';$node->closingCode.="\n";return$writer->write("?>\n<$tag id=\"dynSnippetId = \$_control->getSnippetId({$writer->formatWord($name)}) ?>\">data->leave=TRUE;$fname=$writer->formatWord($name);$node->closingCode='name==='define'?'':"call_user_func(reset(\$_b->blocks[$fname]), \$_b, 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(\$_b->blocks[$fname]['{$this->getCompiler()->getTemplateId()}'] = '$func')) { "."function $func(\$_b, \$_args) { foreach (\$_args as \$__k => \$__v) \$\$__k = \$__v";}}if($node->name==='snippet'||$node->name==='snippetArea'){if($node->prefix&&isset($node->htmlNode->attrs['id'])){throw new CompileException('Cannot combine HTML attribute id with n:snippet.');}$node->data->name=$name='_'.$name;}if(isset($this->namedBlocks[$name])){throw new CompileException("Cannot redeclare static {$node->name} '$name'");}$prolog=$this->namedBlocks?'':"if (\$_l->extends) { ob_end_clean(); return \$template->renderChildTemplate(\$_l->extends, get_defined_vars()); }\n";$this->namedBlocks[$name]=TRUE;$include='call_user_func(reset($_b->blocks[%var]), $_b, '.(($node->name==='snippet'||$node->name==='snippetArea')?'$template->getParameters()':'get_defined_vars()').')';if($node->modifiers){$include="ob_start(function () {}); $include; echo %modify(ob_get_clean())";}if($node->name==='snippet'){if($node->prefix){$node->attrCode=$writer->write('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=\"getSnippetId(%var) ?>\">\nname==='define'){return$prolog;}else{return$writer->write($prolog.$include,$name);}}public function macroBlockEnd(MacroNode$node,PhpWriter$writer){if(isset($node->data->name)){if($node->name==='snippet'&&$node->prefix===MacroNode::PREFIX_NONE&&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($node->name==='snippetArea'&&empty($node->data->dynamic)){$node->content="snippetMode = isset(\$_snippetMode) && \$_snippetMode; ?>{$node->content}snippetMode = FALSE; ?>";}if(!empty($node->data->dynamic)){$node->content.='dynSnippets)) return $_l->dynSnippets; ?>';}if($node->name==='snippetArea'){$node->content.='';}$this->namedBlocks[$node->data->name]=$tmp=preg_replace('#^\n+|(?<=\n)[ \t]+\z#','',$node->content);$node->content=substr_replace($node->content,$node->openingCode."\n",strspn($node->content,"\n"),strlen($tmp));$node->openingCode='';}}elseif($node->modifiers){return$writer->write('echo %modify(ob_get_clean())');}}public function macroIfset(MacroNode$node,PhpWriter$writer){if($node->modifiers){trigger_error("Modifiers are not allowed in {{$node->name}}",E_USER_WARNING);}if(!preg_match('~#|[\w-]+\z~A',$node->args)){return FALSE;}$list=array();while(($name=$node->tokenizer->fetchWord())!==FALSE){$list[]=preg_match('~#|[\w-]+\z~A',$name)?'$_b->blocks["'.ltrim($name,'#').'"]':$writer->formatArgs(new Latte\MacroTokens($name));}return($node->name==='elseifset'?'} else':'').'if (isset('.implode(', ',$list).')) {';}}blocks[$name])){$hint=isset($context->blocks)&&($t=Latte\Helpers::getSuggestion(array_keys($context->blocks),$name))?", did you mean '$t'?":'.';throw new RuntimeException("Cannot include undefined block '$name'$hint");}$block=reset($context->blocks[$name]);$block($context,$params);}/** @return void **/public static function callBlockParent(\stdClass$context,$name,array$params){if(empty($context->blocks[$name])||($block=next($context->blocks[$name]))===FALSE){throw new RuntimeException("Cannot include undefined parent block '$name'.");}$block($context,$params);prev($context->blocks[$name]);}}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)) {','}');$me->addMacro('elseifset','} elseif (isset(%node.args)) {');$me->addMacro('ifcontent',array($me,'macroIfContent'),array($me,'macroEndIfContent'));$me->addMacro('switch','$_l->switch[] = (%node.args); if (FALSE) {','} array_pop($_l->switch)');$me->addMacro('case','} elseif (end($_l->switch) === (%node.args)) {');$me->addMacro('foreach','',array($me,'macroEndForeach'));$me->addMacro('for','for (%node.args) {','}');$me->addMacro('while','while (%node.args) {','}');$me->addMacro('continueIf',array($me,'macroBreakContinueIf'));$me->addMacro('breakIf',array($me,'macroBreakContinueIf'));$me->addMacro('first','if ($iterator->isFirst(%node.args)) {','}');$me->addMacro('last','if ($iterator->isLast(%node.args)) {','}');$me->addMacro('sep','if (!$iterator->isLast(%node.args)) {','}');$me->addMacro('var',array($me,'macroVar'));$me->addMacro('default',array($me,'macroVar'));$me->addMacro('dump',array($me,'macroDump'));$me->addMacro('debugbreak',array($me,'macroDebugbreak'));$me->addMacro('l','?>{addMacro('r','?>}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('contentType',array($me,'macroContentType'));$me->addMacro('status',array($me,'macroStatus'));$me->addMacro('php',array($me,'macroExpr'));$me->addMacro('class',NULL,NULL,array($me,'macroClass'));$me->addMacro('attr',NULL,NULL,array($me,'macroAttr'));}/** @return array(prolog, epilog) **/public function finalize(){return array('list($_b, $_g, $_l) = $template->initialize('.var_export($this->getCompiler()->getTemplateId(),TRUE).', '.var_export($this->getCompiler()->getContentType(),TRUE).')');}public function macroIf(MacroNode$node,PhpWriter$writer){if($node->modifiers){trigger_error("Modifiers are not allowed in {{$node->name}}",E_USER_WARNING);}if($node->data->capture=($node->args==='')){return'ob_start(function () {})';}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) {');}public function macroEndIf(MacroNode$node,PhpWriter$writer){if($node->data->capture){if($node->args===''){throw new CompileException('Missing condition in {if} macro.');}return$writer->write('if (%node.args) '.(isset($node->data->else)?'{ ob_end_clean(); echo ob_get_clean(); }':'echo ob_get_clean();').' else '.(isset($node->data->else)?'{ $_l->else = ob_get_clean(); ob_end_clean(); echo $_l->else; }':'ob_end_clean();'));}return'}';}public function macroElse(MacroNode$node,PhpWriter$writer){if($node->modifiers){trigger_error("Modifiers are not allowed in {{$node->name}}",E_USER_WARNING);}elseif($node->args){$hint=substr($node->args,0,2)==='if'?', did you mean {elseif}?':'';trigger_error("Arguments are not allowed in {{$node->name}}$hint",E_USER_WARNING);}$ifNode=$node->parentNode;if($ifNode&&$ifNode->name==='if'&&$ifNode->data->capture){if(isset($ifNode->data->else)){throw new CompileException('Macro {if} supports only one {else}.');}$ifNode->data->else=TRUE;return'ob_start(function () {})';}return'} else {';}public function macroIfContent(MacroNode$node,PhpWriter$writer){if(!$node->prefix){throw new CompileException("Unknown macro {{$node->name}}, use n:{$node->name} attribute.");}elseif($node->prefix!==MacroNode::PREFIX_NONE){throw new CompileException("Unknown attribute n:{$node->prefix}-{$node->name}, use n:{$node->name} attribute.");}return$writer->write('ob_start(function () {})');}public function macroEndIfContent(MacroNode$node,PhpWriter$writer){preg_match('#(^.*?>)(.*)(<.*\z)#s',$node->content,$parts);$node->content=$parts[1].''.$parts[2].'ifcontent = ob_get_flush() ?>'.$parts[3];return'if (rtrim($_l->ifcontent) === "") ob_end_clean(); else echo ob_get_clean()';}public function 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 () {})';}}public function macroInclude(MacroNode$node,PhpWriter$writer){$code=$writer->write('$_b->templates[%var]->renderChildTemplate(%node.word, %node.array? + $template->getParameters())',$this->getCompiler()->getTemplateId());if($node->modifiers){return$writer->write('ob_start(function () {}); %raw; echo %modify(ob_get_clean())',$code);}else{return$code;}}public function macroUse(MacroNode$node,PhpWriter$writer){if($node->modifiers){trigger_error("Modifiers are not allowed in {{$node->name}}",E_USER_WARNING);}call_user_func(Latte\Helpers::checkCallback(array($node->tokenizer->fetchWord(),'install')),$this->getCompiler())->initialize();}public function macroCapture(MacroNode$node,PhpWriter$writer){$variable=$node->tokenizer->fetchWord();if(substr($variable,0,1)!=='$'){throw new CompileException("Invalid capture block variable '$variable'");}$node->data->variable=$variable;return'ob_start(function () {})';}public function macroCaptureEnd(MacroNode$node,PhpWriter$writer){return$node->data->variable.$writer->write(' = %modify(ob_get_clean())');}public function macroEndForeach(MacroNode$node,PhpWriter$writer){if($node->modifiers&&$node->modifiers!=='|noiterator'){trigger_error('Only modifier |noiterator is allowed here.',E_USER_WARNING);}if($node->modifiers!=='|noiterator'&&preg_match('#\W(\$iterator|include|require|get_defined_vars)\W#',$this->getCompiler()->expandTokens($node->content))){$node->openingCode='its[] = new Latte\Runtime\CachingIterator('.preg_replace('#(.*)\s+as\s+#i','$1) as ',$writer->formatArgs(),1).') { ?>';$node->closingCode='its); $iterator = end($_l->its) ?>';}else{$node->openingCode='formatArgs().') { ?>';$node->closingCode='';}}public function macroBreakContinueIf(MacroNode$node,PhpWriter$writer){if($node->modifiers){trigger_error("Modifiers are not allowed in {{$node->name}}",E_USER_WARNING);}$cmd=str_replace('If','',$node->name);if($node->parentNode&&$node->parentNode->prefix===$node::PREFIX_NONE){return$writer->write("if (%node.args) { echo \"parentNode->htmlNode->name}>\\n\"; $cmd; }");}return$writer->write("if (%node.args) $cmd");}public function macroClass(MacroNode$node,PhpWriter$writer){if(isset($node->htmlNode->attrs['class'])){throw new CompileException('It is not possible to combine class with n:class.');}return$writer->write('if ($_l->tmp = array_filter(%node.array)) echo \' class="\', %escape(implode(" ", array_unique($_l->tmp))), \'"\'');}public function macroAttr(MacroNode$node,PhpWriter$writer){return$writer->write('echo Latte\Runtime\Filters::htmlAttributes(%node.array)');}public function macroDump(MacroNode$node,PhpWriter$writer){if($node->modifiers){trigger_error("Modifiers are not allowed in {{$node->name}}",E_USER_WARNING);}$args=$writer->formatArgs();return$writer->write('Tracy\Debugger::barDump('.($args?"($args)":'get_defined_vars()').', %var)',$args?:'variables');}public function macroDebugbreak(MacroNode$node,PhpWriter$writer){if($node->modifiers){trigger_error("Modifiers are not allowed in {{$node->name}}",E_USER_WARNING);}return$writer->write(($node->args==NULL?'':'if (!(%node.args)); else').'if (function_exists("debugbreak")) debugbreak(); elseif (function_exists("xdebug_break")) xdebug_break()');}public function macroVar(MacroNode$node,PhpWriter$writer){if($node->modifiers){trigger_error("Modifiers are not allowed in {{$node->name}}",E_USER_WARNING);}if($node->args===''&&$node->parentNode&&$node->parentNode->name==='switch'){return'} else {';}$var=TRUE;$tokens=$writer->preprocess();$res=new Latte\MacroTokens;while($tokens->nextToken()){if($var&&$tokens->isCurrent(Latte\MacroTokens::T_SYMBOL,Latte\MacroTokens::T_VARIABLE)){if($node->name==='default'){$res->append("'".ltrim($tokens->currentValue(),'$')."'");}else{$res->append('$'.ltrim($tokens->currentValue(),'$'));}$var=NULL;}elseif($tokens->isCurrent('=','=>')&&$tokens->depth===0){$res->append($node->name==='default'?'=>':'=');$var=FALSE;}elseif($tokens->isCurrent(',')&&$tokens->depth===0){if($var===NULL){$res->append($node->name==='default'?'=>NULL':'=NULL');}$res->append($node->name==='default'?',':';');$var=TRUE;}elseif($var===NULL&&$node->name==='default'&&!$tokens->isCurrent(Latte\MacroTokens::T_WHITESPACE)){throw new CompileException("Unexpected '{$tokens->currentValue()}' in {default $node->args}");}else{$res->append($tokens->currentToken());}}if($var===NULL){$res->append($node->name==='default'?'=>NULL':'=NULL');}$out=$writer->quoteFilter($res)->joinAll();return$node->name==='default'?"extract(array($out), EXTR_SKIP)":$out;}public function macroExpr(MacroNode$node,PhpWriter$writer){return$writer->write(($node->name==='='?'echo ':'').'%modify(%node.args)');}public function macroContentType(MacroNode$node,PhpWriter$writer){if($node->modifiers){trigger_error("Modifiers are not allowed in {{$node->name}}",E_USER_WARNING);}if(strpos($node->args,'xhtml')!==FALSE){$this->getCompiler()->setContentType(Latte\Compiler::CONTENT_XHTML);}elseif(strpos($node->args,'html')!==FALSE){$this->getCompiler()->setContentType(Latte\Compiler::CONTENT_HTML);}elseif(strpos($node->args,'xml')!==FALSE){$this->getCompiler()->setContentType(Latte\Compiler::CONTENT_XML);}elseif(strpos($node->args,'javascript')!==FALSE){$this->getCompiler()->setContentType(Latte\Compiler::CONTENT_JS);}elseif(strpos($node->args,'css')!==FALSE){$this->getCompiler()->setContentType(Latte\Compiler::CONTENT_CSS);}elseif(strpos($node->args,'calendar')!==FALSE){$this->getCompiler()->setContentType(Latte\Compiler::CONTENT_ICAL);}else{$this->getCompiler()->setContentType(Latte\Compiler::CONTENT_TEXT);}if(strpos($node->args,'/')){return$writer->write('header(%var)',"Content-Type: $node->args");}}public function macroStatus(MacroNode$node,PhpWriter$writer){if($node->modifiers){trigger_error("Modifiers are not allowed in {{$node->name}}",E_USER_WARNING);}return$writer->write((substr($node->args,-1)==='?'?'if (!headers_sent()) ':'').'header((isset($_SERVER["SERVER_PROTOCOL"]) ? $_SERVER["SERVER_PROTOCOL"] : "HTTP/1.1") . " " . %0.var, TRUE, %0.var)',(int)$node->args);}}compiler=$compiler;}public function addMacro($name,$begin,$end=NULL,$attr=NULL){if(!$begin&&!$end&&!$attr){throw new\InvalidArgumentException("At least one argument must be specified for macro '$name'.");}foreach(array($begin,$end,$attr)as$arg){if($arg&&!is_string($arg)){Latte\Helpers::checkCallback($arg);}}$this->macros[$name]=array($begin,$end,$attr);$this->compiler->addMacro($name,$this);return$this;}/** @return void **/public function initialize(){}/** @return array(prolog, epilog) **/public function finalize(){}/** @return bool **/public function nodeOpened(MacroNode$node){list($begin,$end,$attr)=$this->macros[$node->name];$node->isEmpty=!$end;if($node->modifiers&&(!$begin||(is_string($begin)&&strpos($begin,'%modify')===FALSE))&&(!$end||(is_string($end)&&strpos($end,'%modify')===FALSE))&&(!$attr||(is_string($attr)&&strpos($attr,'%modify')===FALSE))){trigger_error("Modifiers are not allowed in {{$node->name}}",E_USER_WARNING);}if($node->args&&(!$begin||(is_string($begin)&&strpos($begin,'%node')===FALSE))&&(!$end||(is_string($end)&&strpos($end,'%node')===FALSE))&&(!$attr||(is_string($attr)&&strpos($attr,'%node')===FALSE))){trigger_error("Arguments are not allowed in {{$node->name}}",E_USER_WARNING);}if($attr&&$node->prefix===$node::PREFIX_NONE){$node->isEmpty=TRUE;$this->compiler->setContext(Latte\Compiler::CONTEXT_DOUBLE_QUOTED_ATTR);$res=$this->compile($node,$attr);if($res===FALSE){return FALSE;}elseif(!$node->attrCode){$node->attrCode="";}$this->compiler->setContext(NULL);}elseif($begin){$res=$this->compile($node,$begin);if($res===FALSE||($node->isEmpty&&$node->prefix)){return FALSE;}elseif(!$node->openingCode){$node->openingCode="";}}elseif(!$end){return FALSE;}}/** @return void **/public function nodeClosed(MacroNode$node){if(isset($this->macros[$node->name][1])){$res=$this->compile($node,$this->macros[$node->name][1]);if(!$node->closingCode){$node->closingCode="";}}}/** @return string **/private function compile(MacroNode$node,$def){$node->tokenizer->reset();$writer=Latte\PhpWriter::using($node,$this->compiler);if(is_string($def)){return$writer->write($def);}else{return call_user_func($def,$node,$writer);}}/** @return Latte\Compiler **/public function getCompiler(){return$this->compiler;}}parse($input));$this->ignored=array(self::T_COMMENT,self::T_WHITESPACE);}public function parse($s){self::$tokenizer=self::$tokenizer?:new Tokenizer(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');return self::$tokenizer->tokenize($s);}/** @return static **/public function append($val,$position=NULL){if($val!=NULL){array_splice($this->tokens,$position===NULL?count($this->tokens):$position,0,is_array($val)?array($val):$this->parse($val));}return$this;}/** @return static **/public function prepend($val){if($val!=NULL){array_splice($this->tokens,0,0,is_array($val)?array($val):$this->parse($val));}return$this;}/** @return string **/public function fetchWord(){$words=$this->fetchWords();return$words?implode(':',$words):FALSE;}/** @return array **/public function fetchWords(){do{$words[]=$this->joinUntil(self::T_WHITESPACE,',',':');}while($this->nextToken(':'));if(count($words)===1&&($space=$this->nextValue(self::T_WHITESPACE))&&(($dot=$this->nextValue('.'))||$this->isPrev('.'))){$words[0].=$space.$dot.$this->joinUntil(',');}$this->nextToken(',');$this->nextAll(self::T_WHITESPACE,self::T_COMMENT);return$words===array('')?array():$words;}public function reset(){$this->depth=0;return parent::reset();}protected function next(){parent::next();if($this->isCurrent('[','(','{')){$this->depth++;}elseif($this->isCurrent(']',')','}')){$this->depth--;}}}getMethods(\ReflectionMethod::IS_PUBLIC),$name))?", did you mean $t()?":'.';throw new LogicException("Call to undefined method $class::$name()$hint");}public static function __callStatic($name,$args){$rc=new\ReflectionClass(get_called_class());$items=array_intersect($rc->getMethods(\ReflectionMethod::IS_PUBLIC),$rc->getMethods(\ReflectionMethod::IS_STATIC));$hint=($t=Helpers::getSuggestion($items,$name))?", did you mean $t()?":'.';throw new LogicException("Call to undefined static method {$rc->getName()}::$name()$hint");}public function&__get($name){$rc=new\ReflectionClass($this);$items=array_diff($rc->getProperties(\ReflectionProperty::IS_PUBLIC),$rc->getProperties(\ReflectionProperty::IS_STATIC));$hint=($t=Helpers::getSuggestion($items,$name))?", did you mean $$t?":'.';throw new LogicException("Attempt to read undeclared property {$rc->getName()}::$$name$hint");}public function __set($name,$value){$rc=new\ReflectionClass($this);$items=array_diff($rc->getProperties(\ReflectionProperty::IS_PUBLIC),$rc->getProperties(\ReflectionProperty::IS_STATIC));$hint=($t=Helpers::getSuggestion($items,$name))?", did you mean $$t?":'.';throw new LogicException("Attempt to write to undeclared property {$rc->getName()}::$$name$hint");}/** @return bool **/public function __isset($name){return FALSE;}public function __unset($name){$class=get_class($this);throw new LogicException("Attempt to unset undeclared property $class::$$name.");}}array('\\{(?![\\s\'"{}])','\\}'),'double'=>array('\\{\\{(?![\\s\'"{}])','\\}\\}'),'asp'=>array('<%\s*','\s*%>'),'python'=>array('\\{[{%]\s*','\s*[%}]\\}'),'off'=>array('[^\x00-\xFF]',''));private$delimiters;private$input;private$output;private$offset;private$context;private$lastHtmlTag;private$syntaxEndTag;private$syntaxEndLevel=0;private$xmlMode;const CONTEXT_HTML_TEXT='htmlText',CONTEXT_CDATA='cdata',CONTEXT_HTML_TAG='htmlTag',CONTEXT_HTML_ATTRIBUTE='htmlAttribute',CONTEXT_RAW='raw',CONTEXT_HTML_COMMENT='htmlComment',CONTEXT_MACRO='macro';/** @return Token[] **/public function parse($input){if(substr($input,0,3)==="\xEF\xBB\xBF"){$input=substr($input,3);}$this->input=$input=str_replace("\r\n","\n",$input);$this->offset=0;$this->output=array();if(!preg_match('##u',$input)){preg_match('#(?:[\x00-\x7F]|[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3})*+#A',$input,$m);$this->offset=strlen($m[0])+1;throw new\InvalidArgumentException('Template is not valid UTF-8 stream.');}$this->setSyntax($this->defaultSyntax);$this->setContext(self::CONTEXT_HTML_TEXT);$this->lastHtmlTag=$this->syntaxEndTag=NULL;$tokenCount=0;while($this->offset{'context'.$this->context[0]}()===FALSE){break;}while($tokenCountoutput)){$this->filter($this->output[$tokenCount++]);}}if($this->context[0]===self::CONTEXT_MACRO){throw new CompileException('Malformed macro');}if($this->offsetaddToken(Token::TEXT,substr($this->input,$this->offset));}return$this->output;}private function contextHtmlText(){$matches=$this->match('~ (?:(?<=\n|^)[ \t]*)?<(?P/?)(?P[a-z0-9:]+)| ## begin of HTML tag !--(?!>))| ## begin of HTML comment (?P'.$this->delimiters[0].') ~xsi');if(!empty($matches['htmlcomment'])){$this->addToken(Token::HTML_TAG_BEGIN,$matches[0]);$this->setContext(self::CONTEXT_HTML_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_HTML_TAG);}else{return$this->processMacro($matches);}}private function contextCData(){$matches=$this->match('~ '.$this->lastHtmlTag.')(?![a-z0-9:])| ## end HTML tag '.$this->delimiters[0].') ~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_HTML_TAG);}else{return$this->processMacro($matches);}}private function contextHtmlTag(){$matches=$this->match('~ (?P\ ?/?>)([ \t]*\n)?| ## end of HTML tag (?P'.$this->delimiters[0].')| \s*(?P[^\s/>={]+)(?:\s*=\s*(?P["\']|[^\s/>{]+))? ## beginning of HTML attribute ~xsi');if(!empty($matches['end'])){$this->addToken(Token::HTML_TAG_END,$matches[0]);$this->setContext(!$this->xmlMode&&in_array($this->lastHtmlTag,array('script','style'),TRUE)?self::CONTEXT_CDATA:self::CONTEXT_HTML_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(strncmp($token->name,self::N_PREFIX,strlen(self::N_PREFIX))===0){$token->value='';if($m=$this->match('~(.*?)'.$matches['value'].'~xsi')){$token->value=$m[1];$token->text.=$m[0];}}else{$this->setContext(self::CONTEXT_HTML_ATTRIBUTE,$matches['value']);}}}else{return$this->processMacro($matches);}}private function contextHtmlAttribute(){$matches=$this->match('~ (?P'.$this->context[1].')| ## end of HTML attribute (?P'.$this->delimiters[0].') ~xsi');if(!empty($matches['quote'])){$this->addToken(Token::TEXT,$matches[0]);$this->setContext(self::CONTEXT_HTML_TAG);}else{return$this->processMacro($matches);}}private function contextHtmlComment(){$matches=$this->match('~ (?P-->)| ## end of HTML comment (?P'.$this->delimiters[0].') ~xsi');if(!empty($matches['htmlcomment'])){$this->addToken(Token::HTML_TAG_END,$matches[0]);$this->setContext(self::CONTEXT_HTML_TEXT);}else{return$this->processMacro($matches);}}private function contextRaw(){$matches=$this->match('~ (?P'.$this->delimiters[0].') ~xsi');return$this->processMacro($matches);}private function contextMacro(){$matches=$this->match('~ (?P\\*.*?\\*'.$this->delimiters[1].'\n{0,2})| (?P(?> '.self::RE_STRING.'| \{(?>'.self::RE_STRING.'|[^\'"{}])*+\}| [^\'"{}] )+?) '.$this->delimiters[1].' (?P[ \t]*(?=\n))? ~xsiA');if(!empty($matches['macro'])){$token=$this->addToken(Token::MACRO_TAG,$this->context[1][1].$matches[0]);list($token->name,$token->value,$token->modifiers,$token->empty)=$this->parseMacroTag($matches['macro']);$this->context=$this->context[1][0];}elseif(!empty($matches['comment'])){$this->addToken(Token::COMMENT,$this->context[1][1].$matches[0]);$this->context=$this->context[1][0];}else{throw new CompileException('Malformed macro');}}private function processMacro($matches){if(!empty($matches['macro'])){$this->setContext(self::CONTEXT_MACRO,array($this->context,$matches['macro']));}else{return FALSE;}}/** @return array **/private function match($re){if(!preg_match($re,$this->input,$matches,PREG_OFFSET_CAPTURE,$this->offset)){if(preg_last_error()){throw new RegexpException(NULL,preg_last_error());}return array();}$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 as$k=>$v){$matches[$k]=$v[0];}return$matches;}/** @return static **/public function setContentType($type){if(strpos($type,'html')!==FALSE){$this->xmlMode=FALSE;$this->setContext(self::CONTEXT_HTML_TEXT);}elseif(strpos($type,'xml')!==FALSE){$this->xmlMode=TRUE;$this->setContext(self::CONTEXT_HTML_TEXT);}else{$this->setContext(self::CONTEXT_RAW);}return$this;}/** @return static **/public function setContext($context,$quote=NULL){$this->context=array($context,$quote);return$this;}/** @return static **/public function setSyntax($type){$type=$type?:$this->defaultSyntax;if(isset($this->syntaxes[$type])){$this->setDelimiters($this->syntaxes[$type][0],$this->syntaxes[$type][1]);}else{throw new\InvalidArgumentException("Unknown syntax '$type'");}return$this;}/** @return static **/public function setDelimiters($left,$right){$this->delimiters=array($left,$right);return$this;}/** @return array **/public function parseMacroTag($tag){if(!preg_match('~^ ( (?P\?|/?[a-z]\w*+(?:[.:]\w+)*+(?!::|\(|\\\\))| ## ?, name, /name, but not function( or class:: or namespace\ (?P!?)(?P/?[=\~#%^&_]?) ## !expression, !=expression, ... )(?P(?:'.self::RE_STRING.'|[^\'"])*?) (?P(?/?\z) ()\z~isx',$tag,$match)){if(preg_last_error()){throw new RegexpException(NULL,preg_last_error());}return FALSE;}if($match['name']===''){$match['name']=$match['shortname']?:'=';if($match['noescape']){if(!$this->shortNoEscape){trigger_error("The noescape shortcut {!...} is deprecated, use {...|noescape} modifier on line {$this->getLine()}.",E_USER_DEPRECATED);}$match['modifiers'].='|noescape';}}return array($match['name'],trim($match['args']),$match['modifiers'],(bool)$match['empty']);}private function addToken($type,$text){$this->output[]=$token=new Token;$token->type=$type;$token->text=$text;$token->line=$this->getLine();return$token;}public function getLine(){return$this->offset?substr_count(substr($this->input,0,$this->offset-1),"\n")+1:1;}protected function filter(Token$token){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;$this->syntaxEndLevel=1;$token->type=Token::COMMENT;}elseif($token->type===Token::HTML_TAG_BEGIN&&$this->lastHtmlTag===$this->syntaxEndTag){$this->syntaxEndLevel++;}elseif($token->type===Token::HTML_TAG_END&&$this->lastHtmlTag===('/'.$this->syntaxEndTag)&&--$this->syntaxEndLevel===0){$this->setSyntax($this->defaultSyntax);}elseif($token->type===Token::MACRO_TAG&&$token->name==='contentType'){$this->setContentType($token->value);}}}tokenizer,$node->modifiers,$compiler);}public function __construct(MacroTokens$tokens,$modifiers=NULL,Compiler$compiler=NULL){$this->tokens=$tokens;$this->modifiers=$modifiers;$this->compiler=$compiler;}/** @return string **/public function write($mask){$mask=preg_replace('#%(node|\d+)\.#','%$1_',$mask);$me=$this;$mask=preg_replace_callback('#%escape(\(([^()]*+|(?1))+\))#',function($m)use($me){return$me->escapeFilter(new MacroTokens(substr($m[1],1,-1)))->joinAll();},$mask);$mask=preg_replace_callback('#%modify(\(([^()]*+|(?1))+\))#',function($m)use($me){return$me->formatModifiers(substr($m[1],1,-1));},$mask);$args=func_get_args();$pos=$this->tokens->position;$word=strpos($mask,'%node_word')===FALSE?NULL:$this->tokens->fetchWord();$code=preg_replace_callback('#([,+]\s*)?%(node_|\d+_|)(word|var|raw|array|args)(\?)?(\s*\+\s*)?()#',function($m)use($me,$word,&$args){list(,$l,$source,$format,$cond,$r)=$m;switch($source){case'node_':$arg=$word;break;case'':$arg=next($args);break;default:$arg=$args[(int)$source+1];break;}switch($format){case'word':$code=$me->formatWord($arg);break;case'args':$code=$me->formatArgs();break;case'array':$code=$me->formatArray();$code=$cond&&$code==='array()'?'':$code;break;case'var':$code=var_export($arg,TRUE);break;case'raw':$code=(string)$arg;break;}if($cond&&$code===''){return$r?$l:$r;}else{return$l.$code.$r;}},$mask);$this->tokens->position=$pos;return$code;}/** @return string **/public function formatModifiers($var){$tokens=new MacroTokens(ltrim($this->modifiers,'|'));$tokens=$this->preprocess($tokens);$tokens=$this->modifiersFilter($tokens,$var);$tokens=$this->quoteFilter($tokens);return$tokens->joinAll();}/** @return string **/public function formatArgs(MacroTokens$tokens=NULL){$tokens=$this->preprocess($tokens);$tokens=$this->quoteFilter($tokens);return$tokens->joinAll();}/** @return string **/public function formatArray(MacroTokens$tokens=NULL){$tokens=$this->preprocess($tokens);$tokens=$this->expandFilter($tokens);$tokens=$this->quoteFilter($tokens);return$tokens->joinAll();}/** @return string **/public function formatWord($s){return(is_numeric($s)||preg_match('#^\$|[\'"]|^true\z|^false\z|^null\z#i',$s))?$this->formatArgs(new MacroTokens($s)):'"'.$s.'"';}/** @return MacroTokens **/public function preprocess(MacroTokens$tokens=NULL){$tokens=$tokens===NULL?$this->tokens:$tokens;$tokens=$this->removeCommentsFilter($tokens);$tokens=$this->shortTernaryFilter($tokens);$tokens=$this->shortArraysFilter($tokens);return$tokens;}/** @return MacroTokens **/public function removeCommentsFilter(MacroTokens$tokens){$res=new MacroTokens;while($tokens->nextToken()){if(!$tokens->isCurrent(MacroTokens::T_COMMENT)){$res->append($tokens->currentToken());}}return$res;}/** @return MacroTokens **/public function shortTernaryFilter(MacroTokens$tokens){$res=new MacroTokens;$inTernary=array();while($tokens->nextToken()){if($tokens->isCurrent('?')){$inTernary[]=$tokens->depth;}elseif($tokens->isCurrent(':')){array_pop($inTernary);}elseif($tokens->isCurrent(',',')',']')&&end($inTernary)===$tokens->depth+!$tokens->isCurrent(',')){$res->append(' : NULL');array_pop($inTernary);}$res->append($tokens->currentToken());}if($inTernary){$res->append(' : NULL');}return$res;}/** @return MacroTokens **/public function shortArraysFilter(MacroTokens$tokens){$res=new MacroTokens;$arrays=array();while($tokens->nextToken()){if($tokens->isCurrent('[')){if($arrays[]=!$tokens->isPrev(']',')',MacroTokens::T_SYMBOL,MacroTokens::T_VARIABLE,MacroTokens::T_KEYWORD)){$res->append('array(');continue;}}elseif($tokens->isCurrent(']')){if(array_pop($arrays)===TRUE){$res->append(')');continue;}}$res->append($tokens->currentToken());}return$res;}/** @return MacroTokens **/public function expandFilter(MacroTokens$tokens){$res=new MacroTokens('array(');$expand=NULL;while($tokens->nextToken()){if($tokens->isCurrent('(expand)')&&$tokens->depth===0){$expand=TRUE;$res->append('),');}elseif($expand&&$tokens->isCurrent(',')&&!$tokens->depth){$expand=FALSE;$res->append(', array(');}else{$res->append($tokens->currentToken());}}if($expand!==NULL){$res->prepend('array_merge(')->append($expand?', array()':')');}return$res->append(')');}/** @return MacroTokens **/public function quoteFilter(MacroTokens$tokens){$res=new MacroTokens;while($tokens->nextToken()){$res->append($tokens->isCurrent(MacroTokens::T_SYMBOL)&&(!$tokens->isPrev()||$tokens->isPrev(',','(','[','=>',':','?','.','<','>','<=','>=','===','!==','==','!=','<>','&&','||','=','and','or','xor','??'))&&(!$tokens->isNext()||$tokens->isNext(',',';',')',']','=>',':','?','.','<','>','<=','>=','===','!==','==','!=','<>','&&','||','and','or','xor','??'))?"'".$tokens->currentValue()."'":$tokens->currentToken());}return$res;}/** @return MacroTokens **/public function modifiersFilter(MacroTokens$tokens,$var){$inside=FALSE;$res=new MacroTokens($var);while($tokens->nextToken()){if($tokens->isCurrent(MacroTokens::T_WHITESPACE)){$res->append(' ');}elseif($inside){if($tokens->isCurrent(':',',')){$res->append(', ');$tokens->nextAll(MacroTokens::T_WHITESPACE);}elseif($tokens->isCurrent('|')){$res->append(')');$inside=FALSE;}else{$res->append($tokens->currentToken());}}else{if($tokens->isCurrent(MacroTokens::T_SYMBOL)){if($this->compiler&&$tokens->isCurrent('escape')){$res=$this->escapeFilter($res);$tokens->nextToken('|');}elseif(!strcasecmp($tokens->currentValue(),'safeurl')){$res->prepend('Latte\Runtime\Filters::safeUrl(');$inside=TRUE;}else{$res->prepend('$template->'.$tokens->currentValue().'(');$inside=TRUE;}}else{throw new CompileException("Modifier name must be alphanumeric string, '{$tokens->currentValue()}' given.");}}}if($inside){$res->append(')');}return$res;}/** @return MacroTokens **/public function escapeFilter(MacroTokens$tokens){$tokens=clone$tokens;switch($this->compiler->getContentType()){case Compiler::CONTENT_XHTML:case Compiler::CONTENT_HTML:$context=$this->compiler->getContext();switch($context[0]){case Compiler::CONTEXT_SINGLE_QUOTED_ATTR:case Compiler::CONTEXT_DOUBLE_QUOTED_ATTR:case Compiler::CONTEXT_UNQUOTED_ATTR:if($context[1]===Compiler::CONTENT_JS){$tokens->prepend('Latte\Runtime\Filters::escapeJs(')->append(')');}elseif($context[1]===Compiler::CONTENT_CSS){$tokens->prepend('Latte\Runtime\Filters::escapeCss(')->append(')');}$tokens->prepend('Latte\Runtime\Filters::escapeHtml(')->append($context[0]===Compiler::CONTEXT_SINGLE_QUOTED_ATTR?', ENT_QUOTES)':', ENT_COMPAT)');if($context[0]===Compiler::CONTEXT_UNQUOTED_ATTR){$tokens->prepend("'\"', ")->append(", '\"'");}return$tokens;case Compiler::CONTEXT_COMMENT:return$tokens->prepend('Latte\Runtime\Filters::escapeHtmlComment(')->append(')');case Compiler::CONTENT_JS:case Compiler::CONTENT_CSS:return$tokens->prepend('Latte\Runtime\Filters::escape'.ucfirst($context[0]).'(')->append(')');default:return$tokens->prepend('Latte\Runtime\Filters::escapeHtml(')->append(', ENT_NOQUOTES)');}case Compiler::CONTENT_XML:$context=$this->compiler->getContext();switch($context[0]){case Compiler::CONTEXT_COMMENT:return$tokens->prepend('Latte\Runtime\Filters::escapeHtmlComment(')->append(')');default:$tokens->prepend('Latte\Runtime\Filters::escapeXml(')->append(')');if($context[0]===Compiler::CONTEXT_UNQUOTED_ATTR){$tokens->prepend("'\"', ")->append(", '\"'");}return$tokens;}case Compiler::CONTENT_JS:case Compiler::CONTENT_CSS:case Compiler::CONTENT_ICAL:return$tokens->prepend('Latte\Runtime\Filters::escape'.ucfirst($this->compiler->getContentType()).'(')->append(')');case Compiler::CONTENT_TEXT:return$tokens;default:return$tokens->prepend('$template->escape(')->append(')');}}}getIterator();}while($iterator instanceof\IteratorAggregate);}elseif($iterator instanceof\Traversable){if(!$iterator instanceof\Iterator){$iterator=new\IteratorIterator($iterator);}}else{throw new\InvalidArgumentException(sprintf('Invalid argument passed to foreach; array or Traversable expected, %s given.',is_object($iterator)?get_class($iterator):gettype($iterator)));}parent::__construct($iterator,0);}/** @return bool **/public function isFirst($width=NULL){return$this->counter===1||($width&&$this->counter!==0&&(($this->counter-1)%$width)===0);}/** @return bool **/public function isLast($width=NULL){return!$this->hasNext()||($width&&($this->counter %$width)===0);}/** @return bool **/public function isEmpty(){return$this->counter===0;}/** @return bool **/public function isOdd(){return$this->counter % 2===1;}/** @return bool **/public function isEven(){return$this->counter % 2===0;}/** @return int **/public function getCounter(){return$this->counter;}/** @return int **/public function count(){$inner=$this->getInnerIterator();if($inner instanceof\Countable){return$inner->count();}else{throw new\LogicException('Iterator is not countable.');}}/** @return void **/public function next(){parent::next();if(parent::valid()){$this->counter++;}}/** @return void **/public function rewind(){parent::rewind();$this->counter=parent::valid()?1:0;}/** @return mixed **/public function getNextKey(){return$this->getInnerIterator()->key();}/** @return mixed **/public function getNextValue(){return$this->getInnerIterator()->current();}public function __call($name,$args){throw new\LogicException(sprintf('Call to undefined method %s::%s().',get_class($this),$name));}public function&__get($name){if(method_exists($this,$m='get'.$name)||method_exists($this,$m='is'.$name)){$ret=$this->$m();return$ret;}throw new\LogicException(sprintf('Attempt to read undeclared property %s::$%s.',get_class($this),$name));}public function __set($name,$value){throw new\LogicException(sprintf('Attempt to write to undeclared property %s::$%s.',get_class($this),$name));}/** @return bool **/public function __isset($name){return method_exists($this,'get'.$name)||method_exists($this,'is'.$name);}public function __unset($name){throw new\LogicException(sprintf('Attempt to unset undeclared property %s::$%s.',get_class($this),$name));}}__toString(TRUE);}$s=(string)$s;if($quotes!==ENT_NOQUOTES&&strpos($s,'`')!==FALSE&&strpbrk($s,' <>"\'')===FALSE){$s.=' ';}return htmlSpecialChars($s,ENT_QUOTES,'UTF-8');}/** @return string **/public static function escapeHtmlComment($s){$s=(string)$s;if($s&&($s[0]==='-'||$s[0]==='>'||$s[0]==='!')){$s=' '.$s;}$s=str_replace('--','- - ',$s);if(substr($s,-1)==='-'){$s.=' ';}return$s;}/** @return string **/public static function escapeXML($s){return htmlSpecialChars(preg_replace('#[\x00-\x08\x0B\x0C\x0E-\x1F]+#','',$s),ENT_QUOTES,'UTF-8');}/** @return string **/public static function escapeCss($s){return addcslashes($s,"\x00..\x1F!\"#$%&'()*+,./:;<=>?@[\\]^`{|}~");}/** @return string **/public static function escapeJs($s){if($s instanceof IHtmlString||$s instanceof\Nette\Utils\IHtmlString){$s=$s->__toString(TRUE);}$json=json_encode($s,PHP_VERSION_ID>=50400?JSON_UNESCAPED_UNICODE:0);if($error=json_last_error()){throw new\RuntimeException(PHP_VERSION_ID>=50500?json_last_error_msg():'JSON encode error',$error);}return str_replace(array("\xe2\x80\xa8","\xe2\x80\xa9",']]>','=1){$s=preg_replace_callback('#<(textarea|pre).*?format($format);}elseif(is_numeric($time)){$time=new\DateTime('@'.$time);$time->setTimeZone(new\DateTimeZone(date_default_timezone_get()));}elseif(!$time instanceof\DateTime&&!$time instanceof\DateTimeInterface){$time=new\DateTime($time);}return strpos($format,'%')===FALSE?$time->format($format):strftime($format,$time->format('U'));}/** @return string **/public static function bytes($bytes,$precision=2){$bytes=round($bytes);$units=array('B','kB','MB','GB','TB','PB');foreach($units as$unit){if(abs($bytes)<1024||$unit===end($units)){break;}$bytes=$bytes/1024;}return round($bytes,$precision).' '.$unit;}/** @return string **/public static function replace($subject,$search,$replacement=''){return str_replace($search,$replacement,$subject);}/** @return string **/public static function replaceRe($subject,$pattern,$replacement=''){$res=preg_replace($pattern,$replacement,$subject);if(preg_last_error()){throw new Latte\RegexpException(NULL,preg_last_error());}return$res;}/** @return string **/public static function dataStream($data,$type=NULL){if($type===NULL){$type=finfo_buffer(finfo_open(FILEINFO_MIME_TYPE),$data);}return'data:'.($type?"$type;":'').'base64,'.base64_encode($data);}/** @return string **/public static function nl2br($value){return nl2br($value,self::$xhtml);}/** @return string **/public static function substring($s,$start,$length=NULL){if($length===NULL){$length=self::length($s);}if(function_exists('mb_substr')){return mb_substr($s,$start,$length,'UTF-8');}return iconv_substr($s,$start,$length,'UTF-8');}/** @return string **/public static function truncate($s,$maxLen,$append="\xE2\x80\xA6"){if(self::length($s)>$maxLen){$maxLen=$maxLen-self::length($append);if($maxLen<1){return$append;}elseif(preg_match('#^.{1,'.$maxLen.'}(?=[\s\x00-/:-@\[-`{-~])#us',$s,$matches)){return$matches[0].$append;}else{return self::substring($s,0,$maxLen).$append;}}return$s;}/** @return string **/public static function lower($s){return mb_strtolower($s,'UTF-8');}/** @return string **/public static function upper($s){return mb_strtoupper($s,'UTF-8');}/** @return string **/public static function firstUpper($s){return self::upper(self::substring($s,0,1)).self::substring($s,1);}/** @return string **/public static function capitalize($s){return mb_convert_case($s,MB_CASE_TITLE,'UTF-8');}/** @return int **/public static function length($s){return strlen(utf8_decode($s));}/** @return string **/public static function trim($s,$charlist=" \t\n\r\0\x0B\xC2\xA0"){$charlist=preg_quote($charlist,'#');$s=preg_replace('#^['.$charlist.']+|['.$charlist.']+\z#u','',$s);if(preg_last_error()){throw new Latte\RegexpException(NULL,preg_last_error());}return$s;}/** @return string **/public static function htmlAttributes($attrs){if(!is_array($attrs)){return'';}$s='';foreach($attrs 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)){$tmp=NULL;foreach($value 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;}$q=strpos($value,'"')===FALSE?'"':"'";$s.=' '.$key.'='.$q.str_replace(array('&',$q,'<'),array('&',$q==='"'?'"':''',self::$xhtml?'<':'<'),$value).(strpos($value,'`')!==FALSE&&strpbrk($value,' <>"\'')===FALSE?' ':'').$q;}return$s;}}value=(string)$value;}/** @return string **/public function __toString(){return$this->value;}}setParameters($params);$this->engine=$engine;$this->name=$name;}/** @return Engine **/public function getEngine(){return$this->engine;}/** @return string **/public function getName(){return$this->name;}/** @return [\stdClass, \stdClass, \stdClass] **/public function initialize($templateId,$contentType){Runtime\Filters::$xhtml=(bool)preg_match('#xml|xhtml#',$contentType);$this->params['_l']=new\stdClass;if(isset($this->params['_b'])){$block=$this->params['_b'];unset($this->params['_b']);}else{$block=new\stdClass;}$block->templates[$templateId]=$this;if(!isset($this->params['_g'])){$this->params['_g']=new\stdClass;}return array($block,$this->params['_g'],$this->params['_l']);}/** @return void **/public function renderChildTemplate($name,array$params=array()){$name=$this->engine->getLoader()->getChildName($name,$this->name);$this->engine->render($name,$params);}/** @return mixed **/public function __call($name,$args){return$this->engine->invokeFilter($name,$args);}/** @return static **/public function setParameters(array$params){$this->params=$params;$this->params['template']=$this;return$this;}/** @return array **/public function getParameters(){return$this->params;}/** @return void **/public function __set($name,$value){$this->params[$name]=$value;}/** @return mixed value **/public function&__get($name){if(!array_key_exists($name,$this->params)){trigger_error("The variable '$name' does not exist in template.",E_USER_NOTICE);}return$this->params[$name];}/** @return bool **/public function __isset($name){return isset($this->params[$name]);}/** @return void **/public function __unset($name){unset($this->params[$name]);}}tokens=$tokens;}/** @return array|NULL **/public function currentToken(){return isset($this->tokens[$this->position])?$this->tokens[$this->position]:NULL;}/** @return string|NULL **/public function currentValue(){return isset($this->tokens[$this->position])?$this->tokens[$this->position][Tokenizer::VALUE]:NULL;}/** @return array|NULL **/public function nextToken(){return$this->scan(func_get_args(),TRUE,TRUE);}/** @return string|NULL **/public function nextValue(){return$this->scan(func_get_args(),TRUE,TRUE,TRUE);}/** @return array[] **/public function nextAll(){return$this->scan(func_get_args(),FALSE,TRUE);}/** @return array[] **/public function nextUntil($arg){return$this->scan(func_get_args(),FALSE,TRUE,FALSE,TRUE);}/** @return string **/public function joinAll(){return$this->scan(func_get_args(),FALSE,TRUE,TRUE);}/** @return string **/public function joinUntil($arg){return$this->scan(func_get_args(),FALSE,TRUE,TRUE,TRUE);}/** @return bool **/public function isCurrent($arg){if(!isset($this->tokens[$this->position])){return FALSE;}$args=func_get_args();$token=$this->tokens[$this->position];return in_array($token[Tokenizer::VALUE],$args,TRUE)||(isset($token[Tokenizer::TYPE])&&in_array($token[Tokenizer::TYPE],$args,TRUE));}/** @return bool **/public function isNext(){return(bool)$this->scan(func_get_args(),TRUE,FALSE);}/** @return bool **/public function isPrev(){return(bool)$this->scan(func_get_args(),TRUE,FALSE,FALSE,FALSE,TRUE);}/** @return static **/public function reset(){$this->position=-1;return$this;}protected function next(){$this->position++;}/** @return mixed **/protected function scan($wanted,$onlyFirst,$advance,$strings=FALSE,$until=FALSE,$prev=FALSE){$res=$onlyFirst?NULL:($strings?'':array());$pos=$this->position+($prev?-1:1);do{if(!isset($this->tokens[$pos])){if(!$wanted&&$advance&&!$prev&&$pos<=count($this->tokens)){$this->next();}return$res;}$token=$this->tokens[$pos];$type=isset($token[Tokenizer::TYPE])?$token[Tokenizer::TYPE]:NULL;if(!$wanted||(in_array($token[Tokenizer::VALUE],$wanted,TRUE)||in_array($type,$wanted,TRUE))^$until){while($advance&&!$prev&&$pos>$this->position){$this->next();}if($onlyFirst){return$strings?$token[Tokenizer::VALUE]:$token;}elseif($strings){$res.=$token[Tokenizer::VALUE];}else{$res[]=$token;}}elseif($until||!in_array($type,$this->ignored,TRUE)){return$res;}$pos+=$prev?-1:1;}while(TRUE);}}re='~('.implode(')|(',$patterns).')~A'.$flags;$this->types=array_keys($patterns);}/** @return array **/public function tokenize($input){preg_match_all($this->re,$input,$tokens,PREG_SET_ORDER);if(preg_last_error()){throw new RegexpException(NULL,preg_last_error());}$len=0;$count=count($this->types);foreach($tokens 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=array(self::VALUE=>$match[0],self::OFFSET=>$len,self::TYPE=>$type);$len+=strlen($match[self::VALUE]);}if($len!==strlen($input)){list($line,$col)=$this->getCoordinates($input,$len);$token=str_replace("\n",'\n',substr($input,$len,10));throw new CompileException("Unexpected '$token' on line $line, column $col.");}return$tokens;}/** @return array of [line, column] **/public static function getCoordinates($text,$offset){$text=substr($text,0,$offset);return array(substr_count($text,"\n")+1,$offset-strrpos("\n".$text,"\n")+1);}}register();class_alias('Nette\Configurator','Nette\Config\Configurator');class_alias('Nette\DI\CompilerExtension','Nette\Config\CompilerExtension');class_alias('Tracy\Bar','Nette\Diagnostics\Bar');class_alias('Tracy\BlueScreen','Nette\Diagnostics\BlueScreen');class_alias('Tracy\Dumper','Nette\Diagnostics\Dumper');class_alias('Latte\CompileException','Nette\Latte\CompileException');class_alias('Latte\IMacro','Nette\Latte\IMacro');class_alias('Latte\Macros\MacroSet','Nette\Latte\Macros\MacroSet');class_alias('Nette\Utils\ArrayHash','Nette\ArrayHash');class_alias('Nette\Utils\ArrayList','Nette\ArrayList');class_alias('Nette\Utils\DateTime','Nette\DateTime');class_alias('Nette\Utils\Image','Nette\Image');class_alias('Nette\Utils\ObjectMixin','Nette\ObjectMixin');class_alias('Nette\Neon\Exception','Nette\Utils\NeonException');class_alias('Nette\Neon\Entity','Nette\Utils\NeonEntity');class_alias('Nette\Neon\Neon','Nette\Utils\Neon');require_once __DIR__.'/shortcuts.php';'Nette\Configurator','Nette\Config\CompilerExtension'=>'Nette\DI\CompilerExtension','Nette\Http\User'=>'Nette\Security\User','Nette\Templating\DefaultHelpers'=>'Nette\Templating\Helpers','Nette\Templating\FilterException'=>'Latte\CompileException','Nette\Utils\PhpGenerator\ClassType'=>'Nette\PhpGenerator\ClassType','Nette\Utils\PhpGenerator\Helpers'=>'Nette\PhpGenerator\Helpers','Nette\Utils\PhpGenerator\Method'=>'Nette\PhpGenerator\Method','Nette\Utils\PhpGenerator\Parameter'=>'Nette\PhpGenerator\Parameter','Nette\Utils\PhpGenerator\PhpLiteral'=>'Nette\PhpGenerator\PhpLiteral','Nette\Utils\PhpGenerator\Property'=>'Nette\PhpGenerator\Property','Nette\Diagnostics\Bar'=>'Tracy\Bar','Nette\Diagnostics\BlueScreen'=>'Tracy\BlueScreen','Nette\Diagnostics\DefaultBarPanel'=>'Tracy\DefaultBarPanel','Nette\Diagnostics\Dumper'=>'Tracy\Dumper','Nette\Diagnostics\FireLogger'=>'Tracy\FireLogger','Nette\Diagnostics\Logger'=>'Tracy\Logger','Nette\Diagnostics\OutputDebugger'=>'Tracy\OutputDebugger','Nette\Latte\ParseException'=>'Latte\CompileException','Nette\Latte\CompileException'=>'Latte\CompileException','Nette\Latte\Compiler'=>'Latte\Compiler','Nette\Latte\HtmlNode'=>'Latte\HtmlNode','Nette\Latte\IMacro'=>'Latte\IMacro','Nette\Latte\MacroNode'=>'Latte\MacroNode','Nette\Latte\MacroTokens'=>'Latte\MacroTokens','Nette\Latte\Parser'=>'Latte\Parser','Nette\Latte\PhpWriter'=>'Latte\PhpWriter','Nette\Latte\Token'=>'Latte\Token','Nette\Latte\Macros\CoreMacros'=>'Latte\Macros\CoreMacros','Nette\Latte\Macros\MacroSet'=>'Latte\Macros\MacroSet','Nette\Latte\Macros\CacheMacro'=>'Nette\Bridges\CacheLatte\CacheMacro','Nette\Latte\Macros\FormMacros'=>'Nette\Bridges\FormsLatte\FormMacros','Nette\Latte\Macros\UIMacros'=>'Nette\Bridges\ApplicationLatte\UIMacros','Nette\ArrayHash'=>'Nette\Utils\ArrayHash','Nette\ArrayList'=>'Nette\Utils\ArrayList','Nette\DateTime'=>'Nette\Utils\DateTime','Nette\Image'=>'Nette\Utils\Image','Nette\ObjectMixin'=>'Nette\Utils\ObjectMixin','Nette\Utils\NeonException'=>'Nette\Neon\Exception','Nette\Utils\NeonEntity'=>'Nette\Neon\Entity','Nette\Utils\Neon'=>'Nette\Neon\Neon');public$list=array('Latte\CompileException'=>'Latte/exceptions','Latte\Compiler'=>'Latte/Compiler','Latte\Engine'=>'Latte/Engine','Latte\Helpers'=>'Latte/Helpers','Latte\HtmlNode'=>'Latte/HtmlNode','Latte\ILoader'=>'Latte/ILoader','Latte\IMacro'=>'Latte/IMacro','Latte\Loaders\FileLoader'=>'Latte/Loaders/FileLoader','Latte\Loaders\StringLoader'=>'Latte/Loaders/StringLoader','Latte\MacroNode'=>'Latte/MacroNode','Latte\MacroTokens'=>'Latte/MacroTokens','Latte\Macros\BlockMacros'=>'Latte/Macros/BlockMacros','Latte\Macros\BlockMacrosRuntime'=>'Latte/Macros/BlockMacrosRuntime','Latte\Macros\CoreMacros'=>'Latte/Macros/CoreMacros','Latte\Macros\MacroSet'=>'Latte/Macros/MacroSet','Latte\Object'=>'Latte/Object','Latte\Parser'=>'Latte/Parser','Latte\PhpWriter'=>'Latte/PhpWriter','Latte\RegexpException'=>'Latte/exceptions','Latte\RuntimeException'=>'Latte/exceptions','Latte\Runtime\CachingIterator'=>'Latte/Runtime/CachingIterator','Latte\Runtime\Filters'=>'Latte/Runtime/Filters','Latte\Runtime\Html'=>'Latte/Runtime/Html','Latte\Runtime\IHtmlString'=>'Latte/Runtime/IHtmlString','Latte\Template'=>'Latte/Template','Latte\Token'=>'Latte/Token','Latte\TokenIterator'=>'Latte/TokenIterator','Latte\Tokenizer'=>'Latte/Tokenizer','NetteModule\ErrorPresenter'=>'Application/ErrorPresenter','NetteModule\MicroPresenter'=>'Application/MicroPresenter','Nette\Application\AbortException'=>'Application/exceptions','Nette\Application\ApplicationException'=>'Application/exceptions','Nette\Application\BadRequestException'=>'Application/exceptions','Nette\Application\ForbiddenRequestException'=>'Application/exceptions','Nette\Application\InvalidPresenterException'=>'Application/exceptions','Nette\ArgumentOutOfRangeException'=>'Utils/exceptions','Nette\Caching\Storages\PhpFileStorage'=>'deprecated/Caching/PhpFileStorage','Nette\Callback'=>'deprecated/Callback','Nette\Configurator'=>'Bootstrap/Configurator','Nette\DI\MissingServiceException'=>'DI/exceptions','Nette\DI\ServiceCreationException'=>'DI/exceptions','Nette\Database\ConnectionException'=>'Database/exceptions','Nette\Database\ConstraintViolationException'=>'Database/exceptions','Nette\Database\Conventions\AmbiguousReferenceKeyException'=>'Database/Conventions/exceptions','Nette\Database\ForeignKeyConstraintViolationException'=>'Database/exceptions','Nette\Database\IReflection'=>'Database/deprecated/IReflection','Nette\Database\NotNullConstraintViolationException'=>'Database/exceptions','Nette\Database\Reflection\AmbiguousReferenceKeyException'=>'Database/deprecated/exceptions','Nette\Database\Reflection\ConventionalReflection'=>'Database/deprecated/ConventionalReflection','Nette\Database\Reflection\DiscoveredReflection'=>'Database/deprecated/DiscoveredReflection','Nette\Database\Reflection\MissingReferenceException'=>'Database/deprecated/exceptions','Nette\Database\UniqueConstraintViolationException'=>'Database/exceptions','Nette\DeprecatedException'=>'Utils/exceptions','Nette\Diagnostics\Debugger'=>'deprecated/Diagnostics/Debugger','Nette\Diagnostics\Helpers'=>'deprecated/Diagnostics/Helpers','Nette\Diagnostics\IBarPanel'=>'deprecated/Diagnostics/IBarPanel','Nette\DirectoryNotFoundException'=>'Utils/exceptions','Nette\Environment'=>'deprecated/Environment','Nette\FileNotFoundException'=>'Utils/exceptions','Nette\FreezableObject'=>'deprecated/Utils/FreezableObject','Nette\IFreezable'=>'deprecated/Utils/IFreezable','Nette\IOException'=>'Utils/exceptions','Nette\InvalidArgumentException'=>'Utils/exceptions','Nette\InvalidStateException'=>'Utils/exceptions','Nette\Latte\Engine'=>'deprecated/Latte/Engine','Nette\Loaders\RobotLoader'=>'RobotLoader/RobotLoader','Nette\Localization\ITranslator'=>'Utils/ITranslator','Nette\Mail\SendException'=>'Mail/exceptions','Nette\Mail\SmtpException'=>'Mail/exceptions','Nette\MemberAccessException'=>'Utils/exceptions','Nette\NotImplementedException'=>'Utils/exceptions','Nette\NotSupportedException'=>'Utils/exceptions','Nette\Object'=>'Utils/Object','Nette\OutOfRangeException'=>'Utils/exceptions','Nette\StaticClassException'=>'Utils/exceptions','Nette\Templating\FileTemplate'=>'deprecated/Templating/FileTemplate','Nette\Templating\Helpers'=>'deprecated/Templating/Helpers','Nette\Templating\IFileTemplate'=>'deprecated/Templating/IFileTemplate','Nette\Templating\ITemplate'=>'deprecated/Templating/ITemplate','Nette\Templating\Template'=>'deprecated/Templating/Template','Nette\UnexpectedValueException'=>'Utils/exceptions','Nette\Utils\AssertionException'=>'Utils/exceptions','Nette\Utils\CallbackFilterIterator'=>'Finder/CallbackFilterIterator','Nette\Utils\Finder'=>'Finder/Finder','Nette\Utils\ImageException'=>'Utils/exceptions','Nette\Utils\JsonException'=>'Utils/exceptions','Nette\Utils\LimitedScope'=>'deprecated/Utils/LimitedScope','Nette\Utils\MimeTypeDetector'=>'deprecated/Utils/MimeTypeDetector','Nette\Utils\RecursiveCallbackFilterIterator'=>'Finder/RecursiveCallbackFilterIterator','Nette\Utils\RegexpException'=>'Utils/exceptions','Nette\Utils\SafeStream'=>'SafeStream/SafeStream','Nette\Utils\TokenIterator'=>'Tokenizer/TokenIterator','Nette\Utils\Tokenizer'=>'Tokenizer/Tokenizer','Nette\Utils\TokenizerException'=>'Tokenizer/TokenizerException','Nette\Utils\UnknownImageFileException'=>'Utils/exceptions','Tracy\Bar'=>'Tracy/Bar','Tracy\BlueScreen'=>'Tracy/BlueScreen','Tracy\Bridges\Nette\TracyExtension'=>'Bridges/Nette/TracyExtension','Tracy\Debugger'=>'Tracy/Debugger','Tracy\DefaultBarPanel'=>'Tracy/DefaultBarPanel','Tracy\Dumper'=>'Tracy/Dumper','Tracy\FireLogger'=>'Tracy/FireLogger','Tracy\Helpers'=>'Tracy/Helpers','Tracy\IBarPanel'=>'Tracy/IBarPanel','Tracy\ILogger'=>'Tracy/ILogger','Tracy\Logger'=>'Tracy/Logger','Tracy\OutputDebugger'=>'Tracy/OutputDebugger');/** @return NetteLoader **/public static function getInstance(){if(self::$instance===NULL){self::$instance=new static;}return self::$instance;}/** @return void **/public function register($prepend=FALSE){spl_autoload_register(array($this,'tryLoad'),TRUE,(bool)$prepend);}/** @return void **/public function tryLoad($type){$type=ltrim($type,'\\');if(isset($this->renamed[$type])){class_alias($this->renamed[$type],$type);trigger_error("Class $type has been renamed to {$this->renamed[$type]}.",E_USER_WARNING);}elseif(isset($this->list[$type])){require __DIR__.'/../'.$this->list[$type].'.php';}elseif(substr($type,0,6)==='Nette\\'&&is_file($file=__DIR__.'/../'.strtr(substr($type,5),'\\','/').'.php')){require$file;}}}'1.0','X-Mailer'=>'Nette Framework');private$attachments=array();private$inlines=array();private$html;public function __construct(){foreach(static::$defaultHeaders as$name=>$value){$this->setHeader($name,$value);}$this->setHeader('Date',date('r'));}/** @return self **/public function setFrom($email,$name=NULL){$this->setHeader('From',$this->formatEmail($email,$name));return$this;}/** @return array **/public function getFrom(){return$this->getHeader('From');}/** @return self **/public function addReplyTo($email,$name=NULL){$this->setHeader('Reply-To',$this->formatEmail($email,$name),TRUE);return$this;}/** @return self **/public function setSubject($subject){$this->setHeader('Subject',$subject);return$this;}/** @return string **/public function getSubject(){return$this->getHeader('Subject');}/** @return self **/public function addTo($email,$name=NULL){$this->setHeader('To',$this->formatEmail($email,$name),TRUE);return$this;}/** @return self **/public function addCc($email,$name=NULL){$this->setHeader('Cc',$this->formatEmail($email,$name),TRUE);return$this;}/** @return self **/public function addBcc($email,$name=NULL){$this->setHeader('Bcc',$this->formatEmail($email,$name),TRUE);return$this;}/** @return array **/private function formatEmail($email,$name){if(!$name&&preg_match('#^(.+) +<(.*)>\z#',$email,$matches)){return array($matches[2]=>$matches[1]);}else{return array($email=>$name);}}/** @return self **/public function setReturnPath($email){$this->setHeader('Return-Path',$email);return$this;}/** @return string **/public function getReturnPath(){return$this->getHeader('Return-Path');}/** @return self **/public function setPriority($priority){$this->setHeader('X-Priority',(int)$priority);return$this;}/** @return int **/public function getPriority(){return$this->getHeader('X-Priority');}/** @return self **/public function setHtmlBody($html,$basePath=NULL){if($basePath===NULL&&($html instanceof Nette\Templating\IFileTemplate||$html instanceof Nette\Application\UI\ITemplate)){$basePath=dirname($html->getFile());$bc=TRUE;}$html=(string)$html;if($basePath){$cids=array();$matches=Strings::matchAll($html,'# (]*\s src\s*=\s* |]*\s background\s*=\s* |<[^<>]+\s style\s*=\s* ["\'][^"\'>]+[:\s] url\( |]*>[^<]+ [:\s] url\() (["\']?)(?![a-z]+:|[/\\#])([^"\'>)\s]+) #ix',PREG_OFFSET_CAPTURE);if($matches&&isset($bc)){trigger_error(__METHOD__.'() missing second argument with image base path.',E_USER_WARNING);}foreach(array_reverse($matches)as$m){$file=rtrim($basePath,'/\\').'/'.urldecode($m[3][0]);if(!isset($cids[$file])){$cids[$file]=substr($this->addEmbeddedFile($file)->getHeader('Content-ID'),1,-1);}$html=substr_replace($html,"{$m[1][0]}{$m[2][0]}cid:{$cids[$file]}",$m[0][1],strlen($m[0][0]));}}if($this->getSubject()==NULL){$html=Strings::replace($html,'#(.+?)#is',function($m)use(&$title){$title=$m[1];});$this->setSubject(html_entity_decode($title,ENT_QUOTES,'UTF-8'));}$this->html=ltrim(str_replace("\r",'',$html),"\n");if($this->getBody()==NULL&&$html!=NULL){$this->setBody($this->buildText($html));}return$this;}/** @return mixed **/public function getHtmlBody(){return$this->html;}/** @return MimePart **/public function addEmbeddedFile($file,$content=NULL,$contentType=NULL){return$this->inlines[$file]=$this->createAttachment($file,$content,$contentType,'inline')->setHeader('Content-ID',$this->getRandomId());}/** @return MimePart **/public function addAttachment($file,$content=NULL,$contentType=NULL){return$this->attachments[]=$this->createAttachment($file,$content,$contentType,'attachment');}/** @return MimePart[] **/public function getAttachments(){return$this->attachments;}/** @return MimePart **/private function createAttachment($file,$content,$contentType,$disposition){$part=new MimePart;if($content===NULL){$content=@file_get_contents($file);if($content===FALSE){throw new Nette\FileNotFoundException("Unable to read file '$file'.");}}else{$content=(string)$content;}$part->setBody($content);$part->setContentType($contentType?$contentType:finfo_buffer(finfo_open(FILEINFO_MIME_TYPE),$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;}/** @return string **/public function generateMessage(){return$this->build()->getEncodedMessage();}/** @return self **/protected function build(){$mail=clone$this;$mail->setHeader('Message-ID',$this->getRandomId());$cursor=$mail;if($mail->attachments){$tmp=$cursor->setContentType('multipart/mixed');$cursor=$cursor->addPart();foreach($mail->attachments 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 as$value){$tmp->addPart($value);}}$alt->setContentType('text/html','UTF-8')->setEncoding(preg_match('#[^\n]{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('#[^\n]{990}#',$text)?self::ENCODING_QUOTED_PRINTABLE:(preg_match('#[\x80-\xFF]#',$text)?self::ENCODING_8BIT:self::ENCODING_7BIT))->setBody($text);return$mail;}/** @return string **/protected function buildText($html){$text=Strings::replace($html,array('#<(style|script|head).*#Uis'=>'','#]#i'=>' $0','#]*href=(?|"([^"]+)"|\'([^\']+)\')[^>]*>(.*?)#i'=>'$2 <$1>','#[\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]+#',' ');return trim($text);}/** @return string **/private function getRandomId(){return'<'.Nette\Utils\Random::generate().'@'.preg_replace('#[^\w.-]+#','',isset($_SERVER['HTTP_HOST'])?$_SERVER['HTTP_HOST']:php_uname('n')).'>';}}headers[$name]);}}elseif(is_array($value)){$tmp=&$this->headers[$name];if(!$append||!is_array($tmp)){$tmp=array();}foreach($value as$email=>$recipient){if($recipient!==NULL&&!Strings::checkEncoding($recipient)){Nette\Utils\Validators::assert($recipient,'unicode',"header '$name'");}if(preg_match('#[\r\n]#',$recipient)){throw new 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 new Nette\InvalidArgumentException('Header is not valid UTF-8 string.');}$this->headers[$name]=preg_replace('#[\r\n]+#',' ',$value);}return$this;}/** @return mixed **/public function getHeader($name){return isset($this->headers[$name])?$this->headers[$name]:NULL;}/** @return self **/public function clearHeader($name){unset($this->headers[$name]);return$this;}/** @return string **/public function getEncodedHeader($name){$offset=strlen($name)+2;if(!isset($this->headers[$name])){return NULL;}elseif(is_array($this->headers[$name])){$s='';foreach($this->headers[$name]as$email=>$name){if($name!=NULL){$s.=self::encodeHeader($name,$offset,TRUE);$email=" <$email>";}$s.=self::append($email.',',$offset);}return ltrim(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 ltrim(self::encodeHeader($this->headers[$name],$offset));}}/** @return array **/public function getHeaders(){return$this->headers;}/** @return self **/public function setContentType($contentType,$charset=NULL){$this->setHeader('Content-Type',$contentType.($charset?"; charset=$charset":''));return$this;}/** @return self **/public function setEncoding($encoding){$this->setHeader('Content-Transfer-Encoding',$encoding);return$this;}/** @return string **/public function getEncoding(){return$this->getHeader('Content-Transfer-Encoding');}/** @return MimePart **/public function addPart(MimePart$part=NULL){return$this->parts[]=$part===NULL?new self:$part;}/** @return self **/public function setBody($body){$this->body=(string)$body;return$this;}/** @return mixed **/public function getBody(){return$this->body;}/** @return string **/public function getEncodedMessage(){$output='';$boundary='--------'.Nette\Utils\Random::generate();foreach($this->headers 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 self::ENCODING_QUOTED_PRINTABLE:$output.=quoted_printable_encode($body);break;case self::ENCODING_BASE64:$output.=rtrim(chunk_split(base64_encode($body),self::LINE_LENGTH,self::EOL));break;case self::ENCODING_7BIT:$body=preg_replace('#[\x80-\xFF]+#','',$body);case self::ENCODING_8BIT:$body=str_replace(array("\x00","\r"),'',$body);$body=str_replace("\n",self::EOL,$body);$output.=$body;break;default:throw new Nette\InvalidStateException('Unknown encoding.');}}if($this->parts){if(substr($output,-strlen(self::EOL))!==self::EOL){$output.=self::EOL;}foreach($this->parts as$part){$output.='--'.$boundary.self::EOL.$part->getEncodedMessage().self::EOL;}$output.='--'.$boundary.'--';}return$output;}/** @return string **/private static function encodeHeader($s,&$offset=0,$quotes=FALSE){if(strspn($s,"!\"#$%&\'()*+,-./0123456789:;<>@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^`abcdefghijklmnopqrstuvwxyz{|}~=? _\r\n\t")===strlen($s)){if($quotes&&preg_match('#[^ a-zA-Z0-9!\#$%&\'*+/?^_`{|}~-]#',$s)){return self::append('"'.addcslashes($s,'"\\').'"',$offset);}return self::append($s,$offset);}$o='';if($offset>=55){$o=self::EOL."\t";$offset=1;}$s=iconv_mime_encode(str_repeat(' ',$old=$offset),$s,array('scheme'=>'B','input-charset'=>'UTF-8','output-charset'=>'UTF-8'));$offset=strlen($s)-strrpos($s,"\n");$s=str_replace("\n ","\n\t",substr($s,$old+2));return$o.$s;}private static function append($s,&$offset=0){if($offset+strlen($s)>self::LINE_LENGTH){$offset=1;$s=self::EOL."\t".$s;}$offset+=strlen($s);return$s;}}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;}$res=Nette\Utils\Callback::invokeSafe('mail',$args,function($message)use(&$info){$info=": $message";});if($res===FALSE){throw new SendException("Unable to send email$info.");}}}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;}$this->persistent=!empty($options['persistent']);}/** @return void **/public function send(Message$mail){$mail=clone$mail;try{if(!$this->connection){$this->connect();}if(($from=$mail->getHeader('Return-Path'))||($from=key($mail->getHeader('From')))){$this->write("MAIL FROM:<$from>",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);if(!$this->persistent){$this->write('QUIT',221);$this->disconnect();}}catch(SmtpException$e){if($this->connection){$this->disconnect();}throw$e;}}/** @return void **/protected function connect(){$this->connection=@stream_socket_client(($this->secure==='ssl'?'ssl://':'').$this->host.':'.$this->port,$errno,$error,$this->timeout);if(!$this->connection){throw new SmtpException($error,$errno);}stream_set_timeout($this->connection,$this->timeout,0);$this->read();$self=isset($_SERVER['HTTP_HOST'])&&preg_match('#^[\w.-]+\z#',$_SERVER['HTTP_HOST'])?$_SERVER['HTTP_HOST']:'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 new 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');}}/** @return void **/protected function disconnect(){fclose($this->connection);$this->connection=NULL;}/** @return void **/protected function write($line,$expectedCode=NULL,$message=NULL){fwrite($this->connection,$line.Message::EOL);if($expectedCode){$response=$this->read();if(!in_array((int)$response,(array)$expectedCode,TRUE)){throw new SmtpException('SMTP server did not accept '.($message?$message:$line).' with error: '.trim($response));}}}/** @return string **/protected function read(){$s='';while(($line=fgets($this->connection,1e3))!=NULL){$s.=$line;if(substr($line,3,1)===' '){break;}}return$s;}}']','{'=>'}','('=>')');private$input;private$tokens;private$pos;/** @return mixed **/public function decode($input){if(!is_string($input)){throw new\InvalidArgumentException(sprintf('Argument must be a string, %s given.',gettype($input)));}elseif(substr($input,0,3)==="\xEF\xBB\xBF"){$input=substr($input,3);}$this->input="\n".str_replace("\r",'',$input);$pattern='~('.implode(')|(',self::$patterns).')~Amix';$this->tokens=preg_split($pattern,$this->input,-1,PREG_SPLIT_NO_EMPTY|PREG_SPLIT_OFFSET_CAPTURE|PREG_SPLIT_DELIM_CAPTURE);$last=end($this->tokens);if($this->tokens&&!preg_match($pattern,$last[0])){$this->pos=count($this->tokens)-1;$this->error();}$this->pos=0;$res=$this->parse(NULL);while(isset($this->tokens[$this->pos])){if($this->tokens[$this->pos][0][0]==="\n"){$this->pos++;}else{$this->error();}}return$res;}/** @return array **/private function parse($indent,$result=NULL,$key=NULL,$hasKey=FALSE){$inlineParser=$indent===FALSE;$value=NULL;$hasValue=FALSE;$tokens=$this->tokens;$n=&$this->pos;$count=count($tokens);$mainResult=&$result;for(;$n<$count;$n++){$t=$tokens[$n][0];if($t===','){if((!$hasKey&&!$hasValue)||!$inlineParser){$this->error();}$this->addValue($result,$hasKey?$key:NULL,$hasValue?$value:NULL);$hasKey=$hasValue=FALSE;}elseif($t===':'||$t==='='){if($hasValue&&(is_array($value)||is_object($value))){$this->error('Unacceptable key');}elseif($hasKey&&$key===NULL&&$hasValue&&!$inlineParser){$n++;$result[]=$this->parse($indent.' ',array(),$value,TRUE);$newIndent=isset($tokens[$n],$tokens[$n+1])?(string)substr($tokens[$n][0],1):'';if(strlen($newIndent)>strlen($indent)){$n++;$this->error('Bad indentation');}elseif(strlen($newIndent)error();}else{$key=(string)$value;$hasKey=TRUE;$hasValue=FALSE;$result=&$mainResult;}}elseif($t==='-'){if($hasKey||$hasValue||$inlineParser){$this->error();}$key=NULL;$hasKey=TRUE;}elseif(isset(self::$brackets[$t])){if($hasValue){if($t!=='('){$this->error();}$n++;if($value instanceof Entity&&$value->value===Neon::CHAIN){end($value->attributes)->attributes=$this->parse(FALSE,array());}else{$value=new Entity($value,$this->parse(FALSE,array()));}}else{$n++;$value=$this->parse(FALSE,array());}$hasValue=TRUE;if(!isset($tokens[$n])||$tokens[$n][0]!==self::$brackets[$t]){$this->error();}}elseif($t===']'||$t==='}'||$t===')'){if(!$inlineParser){$this->error();}break;}elseif($t[0]==="\n"){if($inlineParser){if($hasKey||$hasValue){$this->addValue($result,$hasKey?$key:NULL,$hasValue?$value:NULL);$hasKey=$hasValue=FALSE;}}else{while(isset($tokens[$n+1])&&$tokens[$n+1][0][0]==="\n"){$n++;}if(!isset($tokens[$n+1])){break;}$newIndent=(string)substr($tokens[$n][0],1);if($indent===NULL){$indent=$newIndent;}$minlen=min(strlen($newIndent),strlen($indent));if($minlen&&(string)substr($newIndent,0,$minlen)!==(string)substr($indent,0,$minlen)){$n++;$this->error('Invalid combination of tabs and spaces');}if(strlen($newIndent)>strlen($indent)){if($hasValue||!$hasKey){$n++;$this->error('Bad indentation');}$this->addValue($result,$key,$this->parse($newIndent));$newIndent=isset($tokens[$n],$tokens[$n+1])?(string)substr($tokens[$n][0],1):'';if(strlen($newIndent)>strlen($indent)){$n++;$this->error('Bad indentation');}$hasKey=FALSE;}else{if($hasValue&&!$hasKey){break;}elseif($hasKey){$this->addValue($result,$key,$hasValue?$value:NULL);if($key!==NULL&&!$hasValue&&$newIndent===$indent&&isset($tokens[$n+1])&&$tokens[$n+1][0]==='-'){$result=&$result[$key];}$hasKey=$hasValue=FALSE;}}if(strlen($newIndent)TRUE,'True'=>TRUE,'TRUE'=>TRUE,'yes'=>TRUE,'Yes'=>TRUE,'YES'=>TRUE,'on'=>TRUE,'On'=>TRUE,'ON'=>TRUE,'false'=>FALSE,'False'=>FALSE,'FALSE'=>FALSE,'no'=>FALSE,'No'=>FALSE,'NO'=>FALSE,'off'=>FALSE,'Off'=>FALSE,'OFF'=>FALSE,'null'=>0,'Null'=>0,'NULL'=>0);if($t[0]==='"'){$converted=preg_replace_callback('#\\\\(?:ud[89ab][0-9a-f]{2}\\\\ud[c-f][0-9a-f]{2}|u[0-9a-f]{4}|x[0-9a-f]{2}|.)#i',array($this,'cbString'),substr($t,1,-1));}elseif($t[0]==="'"){$converted=substr($t,1,-1);}elseif(isset($consts[$t])&&(!isset($tokens[$n+1][0])||($tokens[$n+1][0]!==':'&&$tokens[$n+1][0]!=='='))){$converted=$consts[$t]===0?NULL:$consts[$t];}elseif(is_numeric($t)){$converted=$t*1;}elseif(preg_match(self::PATTERN_HEX,$t)){$converted=hexdec($t);}elseif(preg_match(self::PATTERN_DATETIME,$t)){$converted=new\DateTime($t);}else{$converted=$t;}if($hasValue){if($value instanceof Entity){if($value->value!==Neon::CHAIN){$value=new Entity(Neon::CHAIN,array($value));}$value->attributes[]=new Entity($converted);}else{$this->error();}}else{$value=$converted;$hasValue=TRUE;}}}if($inlineParser){if($hasKey||$hasValue){$this->addValue($result,$hasKey?$key:NULL,$hasValue?$value:NULL);}}else{if($hasValue&&!$hasKey){if($result===NULL){$result=$value;}else{$this->error();}}elseif($hasKey){$this->addValue($result,$key,$hasValue?$value:NULL);}}return$mainResult;}private function addValue(&$result,$key,$value){if($key===NULL){$result[]=$value;}elseif($result&&array_key_exists($key,$result)){$this->error("Duplicated key '$key'");}else{$result[$key]=$value;}}private function cbString($m){static$mapping=array('t'=>"\t",'n'=>"\n",'r'=>"\r",'f'=>"\x0C",'b'=>"\x08",'"'=>'"','\\'=>'\\','/'=>'/','_'=>"\xc2\xa0");$sq=$m[0];if(isset($mapping[$sq[1]])){return$mapping[$sq[1]];}elseif($sq[1]==='u'&&strlen($sq)>=6){$lead=hexdec(substr($sq,2,4));$tail=hexdec(substr($sq,8,4));$code=$tail?(0x2400+(($lead-0xD800)<<10)+$tail):$lead;if($code>=0xD800&&$code<=0xDFFF){$this->error("Invalid UTF-8 (lone surrogate) $sq");}return iconv('UTF-32BE','UTF-8//IGNORE',pack('N',$code));}elseif($sq[1]==='x'&&strlen($sq)===4){return chr(hexdec(substr($sq,2)));}else{$this->error("Invalid escaping sequence $sq");}}private function error($message="Unexpected '%s'"){$last=isset($this->tokens[$this->pos])?$this->tokens[$this->pos]:NULL;$offset=$last?$last[1]:strlen($this->input);$text=substr($this->input,0,$offset);$line=substr_count($text,"\n");$col=$offset-strrpos("\n".$text,"\n")+1;$token=$last?str_replace("\n",'',substr($last[0],0,40)):'end';throw new Exception(str_replace('%s',$token,$message)." on line $line, column $col.");}}format('Y-m-d H:i:s O');}elseif($var instanceof Entity){if($var->value===Neon::CHAIN){return implode('',array_map(array($this,'encode'),$var->attributes));}return$this->encode($var->value).'('.(is_array($var->attributes)?substr($this->encode($var->attributes),1,-1):'').')';}if(is_object($var)){$obj=$var;$var=array();foreach($obj as$k=>$v){$var[$k]=$v;}}if(is_array($var)){$isList=!$var||array_keys($var)===range(0,count($var)-1);$s='';if($options&self::BLOCK){if(count($var)===0){return'[]';}foreach($var as$k=>$v){$v=$this->encode($v,self::BLOCK);$s.=($isList?'-':$this->encode($k).':').(strpos($v,"\n")===FALSE?' '.$v."\n":"\n".preg_replace('#^(?=.)#m',"\t",$v).(substr($v,-2,1)==="\n"?'':"\n"));}return$s;}else{foreach($var as$k=>$v){$s.=($isList?'':$this->encode($k).': ').$this->encode($v).', ';}return($isList?'[':'{').substr($s,0,-2).($isList?']':'}');}}elseif(is_string($var)&&!is_numeric($var)&&!preg_match('~[\x00-\x1F]|^\d{4}|^(true|false|yes|no|on|off|null)\z~i',$var)&&preg_match('~^'.Decoder::$patterns[1].'\z~x',$var)){return$var;}elseif(is_float($var)){$var=json_encode($var);return strpos($var,'.')===FALSE?$var.'.0':$var;}else{return json_encode($var,PHP_VERSION_ID>=50400?JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES:0);}}}value=$value;$this->attributes=(array)$attrs;}}encode($var,$options);}/** @return mixed **/public static function decode($input){$decoder=new Decoder;return$decoder->decode($input);}}getName():$from);if(PHP_VERSION_ID>=70000&&$from->isAnonymous()){$class=new static('anonymous');}else{$class=new static($from->getShortName(),new PhpNamespace($from->getNamespaceName()));}$class->type=$from->isInterface()?'interface':(PHP_VERSION_ID>=50400&&$from->isTrait()?'trait':'class');$class->final=$from->isFinal()&&$class->type==='class';$class->abstract=$from->isAbstract()&&$class->type==='class';$class->implements=$from->getInterfaceNames();$class->documents=$from->getDocComment()?array(preg_replace('#^\s*\* ?#m','',trim($from->getDocComment(),"/* \r\n\t"))):array();if($from->getParentClass()){$class->extends=$from->getParentClass()->getName();$class->implements=array_diff($class->implements,$from->getParentClass()->getInterfaceNames());}foreach($from->getProperties()as$prop){if($prop->getDeclaringClass()->getName()===$from->getName()){$class->properties[$prop->getName()]=Property::from($prop);}}foreach($from->getMethods()as$method){if($method->getDeclaringClass()->getName()===$from->getName()){$class->methods[$method->getName()]=Method::from($method)->setNamespace($class->namespace);}}return$class;}public function __construct($name='',PhpNamespace$namespace=NULL){$this->setName($name);$this->namespace=$namespace;}/** @return string PHP code **/public function __toString(){$consts=array();foreach($this->consts as$name=>$value){$consts[]="const $name = ".Helpers::dump($value).";\n";}$properties=array();foreach($this->properties as$property){$doc=str_replace("\n","\n * ",implode("\n",$property->getDocuments()));$properties[]=($property->getDocuments()?(strpos($doc,"\n")===FALSE?"/** $doc */\n":"/**\n * $doc\n */\n"):'').$property->getVisibility().($property->isStatic()?' static':'').' $'.$property->getName().($property->value===NULL?'':' = '.Helpers::dump($property->value)).";\n";}$namespace=$this->namespace;$mapper=function(array$arr)use($namespace){return$namespace?array_map(array($namespace,'unresolveName'),$arr):$arr;};return Strings::normalize(($this->documents?str_replace("\n","\n * ","/**\n".implode("\n",$this->documents))."\n */\n":'').($this->abstract?'abstract ':'').($this->final?'final ':'').$this->type.' '.$this->name.' '.($this->extends?'extends '.implode(', ',$mapper((array)$this->extends)).' ':'').($this->implements?'implements '.implode(', ',$mapper($this->implements)).' ':'')."\n{\n".Strings::indent(($this->traits?'use '.implode(";\nuse ",$mapper($this->traits)).";\n\n":'').($this->consts?implode('',$consts)."\n":'').($this->properties?implode("\n",$properties)."\n":'').($this->methods?"\n".implode("\n\n\n",$this->methods)."\n\n":''),1).'}')."\n";}/** @return PhpNamespace|NULL **/public function getNamespace(){return$this->namespace;}/** @return self **/public function setName($name){$this->name=(string)$name;return$this;}/** @return string **/public function getName(){return$this->name;}/** @return self **/public function setType($type){if(!in_array($type,array('class','interface','trait'),TRUE)){throw new Nette\InvalidArgumentException('Argument must be class|interface|trait.');}$this->type=$type;return$this;}/** @return string **/public function getType(){return$this->type;}/** @return self **/public function setFinal($state=TRUE){$this->final=(bool)$state;return$this;}/** @return bool **/public function isFinal(){return$this->final;}/** @return self **/public function setAbstract($state=TRUE){$this->abstract=(bool)$state;return$this;}/** @return bool **/public function isAbstract(){return$this->abstract;}/** @return self **/public function setExtends($types){if(!is_string($types)&&!(is_array($types)&&array_filter($types,'is_string')===$types)){throw new Nette\InvalidArgumentException('Argument must be string or string[].');}$this->extends=$types;return$this;}/** @return string|string[] **/public function getExtends(){return$this->extends;}/** @return self **/public function addExtend($type){$this->extends=(array)$this->extends;$this->extends[]=(string)$type;return$this;}/** @return self **/public function setImplements(array$types){$this->implements=$types;return$this;}/** @return string[] **/public function getImplements(){return$this->implements;}/** @return self **/public function addImplement($type){$this->implements[]=(string)$type;return$this;}/** @return self **/public function setTraits(array$traits){$this->traits=$traits;return$this;}/** @return string[] **/public function getTraits(){return$this->traits;}/** @return self **/public function addTrait($trait){$this->traits[]=(string)$trait;return$this;}/** @return self **/public function setComment($val){$this->documents=$val?array((string)$val):array();return$this;}/** @return string|NULL **/public function getComment(){return implode($this->documents)?:NULL;}/** @return self **/public function addComment($val){return$this->addDocument($val);}/** @return self **/public function setDocuments(array$s){$this->documents=$s;return$this;}/** @return string[] **/public function getDocuments(){return$this->documents;}/** @return self **/public function addDocument($s){$this->documents[]=(string)$s;return$this;}/** @return self **/public function setConsts(array$consts){$this->consts=$consts;return$this;}/** @return array **/public function getConsts(){return$this->consts;}/** @return self **/public function addConst($name,$value){$this->consts[$name]=$value;return$this;}/** @return self **/public function setProperties(array$props){$this->properties=array();foreach($props as$v){if(!$v instanceof Property){throw new Nette\InvalidArgumentException('Argument must be Nette\PhpGenerator\Property[].');}$this->properties[$v->getName()]=$v;}return$this;}/** @return Property[] **/public function getProperties(){return$this->properties;}/** @return Property **/public function getProperty($name){if(!isset($this->properties[$name])){throw new Nette\InvalidArgumentException("Property '$name' not found.");}return$this->properties[$name];}/** @return Property **/public function addProperty($name,$value=NULL){$property=new Property($name);return$this->properties[$name]=$property->setValue($value);}/** @return self **/public function setMethods(array$methods){$this->methods=array();foreach($methods as$v){if(!$v instanceof Method){throw new Nette\InvalidArgumentException('Argument must be Nette\PhpGenerator\Method[].');}$this->methods[$v->getName()]=$v->setNamespace($this->namespace);}return$this;}/** @return Method[] **/public function getMethods(){return$this->methods;}/** @return Method **/public function getMethod($name){if(!isset($this->methods[$name])){throw new Nette\InvalidArgumentException("Method '$name' not found.");}return$this->methods[$name];}/** @return Method **/public function addMethod($name){$method=new Method($name);if($this->type==='interface'){$method->setVisibility(NULL)->setBody(FALSE);}else{$method->setVisibility('public');}return$this->methods[$name]=$method->setNamespace($this->namespace);}}self::MAX_DEPTH||isset($var[$marker])){throw new Nette\InvalidArgumentException('Nesting level too deep or recursive dependency.');}else{$out='';$outAlt="\n$space";$var[$marker]=TRUE;$counter=0;foreach($var as$k=>&$v){if($k!==$marker){$item=($k===$counter?'':self::_dump($k,$level+1).' => ').self::_dump($v,$level+1);$counter=is_int($k)?max($k+1,$counter):$counter;$out.=($out===''?'':', ').$item;$outAlt.="\t$item,\n$space";}}unset($var[$marker]);}return'array('.(strpos($out,"\n")===FALSE&&strlen($out)<40?$out:$outAlt).')';}elseif($var instanceof\Serializable){$var=serialize($var);return'unserialize('.self::_dump($var,$level).')';}elseif($var instanceof\Closure){throw new Nette\InvalidArgumentException('Cannot dump closure.');}elseif(is_object($var)){if(PHP_VERSION_ID>=70000&&($rc=new\ReflectionObject($var))&&$rc->isAnonymous()){throw new Nette\InvalidArgumentException('Cannot dump anonymous class.');}$arr=(array)$var;$space=str_repeat("\t",$level);$class=get_class($var);static$list=array();if($level>self::MAX_DEPTH||in_array($var,$list,TRUE)){throw new Nette\InvalidArgumentException('Nesting level too deep or recursive dependency.');}else{$out="\n";$list[]=$var;if(method_exists($var,'__sleep')){foreach($var->__sleep()as$v){$props[$v]=$props["\x00*\x00$v"]=$props["\x00$class\x00$v"]=TRUE;}}foreach($arr as$k=>&$v){if(!isset($props)||isset($props[$k])){$out.="$space\t".self::_dump($k,$level+1).' => '.self::_dump($v,$level+1).",\n";}}array_pop($list);$out.=$space;}return$class==='stdClass'?"(object) array($out)":__CLASS__."::createObject('$class', array($out))";}elseif(is_resource($var)){throw new Nette\InvalidArgumentException('Cannot dump resource.');}else{return var_export($var,TRUE);}}/** @return string **/public static function format($statement){$args=func_get_args();return self::formatArgs(array_shift($args),$args);}/** @return string **/public static function formatArgs($statement,array$args){$a=strpos($statement,'?');while($a!==FALSE){if(!$args){throw new Nette\InvalidArgumentException('Insufficient number of arguments.');}$arg=array_shift($args);if(substr($statement,$a+1,1)==='*'){if(!is_array($arg)){throw new Nette\InvalidArgumentException('Argument must be an array.');}$s=substr($statement,0,$a);$sep='';foreach($arg as$tmp){$s.=$sep.self::dump($tmp);$sep=strlen($s)-strrpos($s,"\n")>100?",\n\t":', ';}$statement=$s.substr($statement,$a+2);$a=strlen($s);}else{$arg=substr($statement,$a-1,1)==='$'||in_array(substr($statement,$a-2,2),array('->','::'),TRUE)?self::formatMember($arg):self::_dump($arg);$statement=substr_replace($statement,$arg,$a,1);$a+=strlen($arg);}$a=strpos($statement,'?',$a);}return$statement;}/** @return string **/public static function formatMember($name){return$name instanceof PhpLiteral||!self::isIdentifier($name)?'{'.self::_dump($name).'}':$name;}/** @return bool **/public static function isIdentifier($value){return is_string($value)&&preg_match('#^'.self::PHP_IDENT.'\z#',$value);}public static function createObject($class,array$props){return unserialize('O'.substr(serialize((string)$class),1,-1).substr(serialize($props),1));}/** @return string **/public static function extractNamespace($name){return($pos=strrpos($name,'\\'))?substr($name,0,$pos):'';}/** @return string **/public static function extractShortName($name){return($pos=strrpos($name,'\\'))===FALSE?$name:substr($name,$pos+1);}}isClosure()?NULL:$from->getName());foreach($from->getParameters()as$param){$method->parameters[$param->getName()]=Parameter::from($param);}if($from instanceof\ReflectionMethod){$method->static=$from->isStatic();$method->visibility=$from->isPrivate()?'private':($from->isProtected()?'protected':NULL);$method->final=$from->isFinal();$method->abstract=$from->isAbstract()&&!$from->getDeclaringClass()->isInterface();$method->body=$from->isAbstract()?FALSE:'';}$method->returnReference=$from->returnsReference();$method->variadic=PHP_VERSION_ID>=50600&&$from->isVariadic();$method->documents=$from->getDocComment()?array(preg_replace('#^\s*\* ?#m','',trim($from->getDocComment(),"/* \r\n\t"))):array();if(PHP_VERSION_ID>=70000&&$from->hasReturnType()){$method->returnType=(string)$from->getReturnType();}return$method;}public function __construct($name=NULL){$this->setName($name);}/** @return string PHP code **/public function __toString(){$parameters=array();foreach($this->parameters as$param){$variadic=$this->variadic&&$param===end($this->parameters);$hint=$param->getTypeHint();$parameters[]=($hint?($this->namespace?$this->namespace->unresolveName($hint):$hint).' ':'').($param->isReference()?'&':'').($variadic?'...':'').'$'.$param->getName().($param->isOptional()&&!$variadic?' = '.Helpers::dump($param->defaultValue):'');}$uses=array();foreach($this->uses as$param){$uses[]=($param->isReference()?'&':'').'$'.$param->getName();}return($this->documents?str_replace("\n","\n * ","/**\n".implode("\n",$this->documents))."\n */\n":'').($this->abstract?'abstract ':'').($this->final?'final ':'').($this->visibility?$this->visibility.' ':'').($this->static?'static ':'').'function'.($this->returnReference?' &':'').' '.$this->name.'('.implode(', ',$parameters).')'.($this->uses?' use ('.implode(', ',$uses).')':'').($this->returnType?': '.($this->namespace?$this->namespace->unresolveName($this->returnType):$this->returnType):'').($this->abstract||$this->body===FALSE?';':($this->name?"\n":' ')."{\n".Nette\Utils\Strings::indent(ltrim(rtrim($this->body)."\n"),1).'}');}/** @return self **/public function setName($name){$this->name=$name?(string)$name:NULL;return$this;}/** @return string|NULL **/public function getName(){return$this->name;}/** @return self **/public function setParameters(array$val){$this->parameters=array();foreach($val as$v){if(!$v instanceof Parameter){throw new Nette\InvalidArgumentException('Argument must be Nette\PhpGenerator\Parameter[].');}$this->parameters[$v->getName()]=$v;}return$this;}/** @return Parameter[] **/public function getParameters(){return$this->parameters;}/** @return Parameter **/public function addParameter($name,$defaultValue=NULL){$param=new Parameter($name);if(func_num_args()>1){$param->setOptional(TRUE)->setDefaultValue($defaultValue);}return$this->parameters[$name]=$param;}/** @return self **/public function setUses(array$val){$this->uses=$val;return$this;}/** @return array **/public function getUses(){return$this->uses;}/** @return Parameter **/public function addUse($name){return$this->uses[]=new Parameter($name);}/** @return self **/public function setBody($statement,array$args=NULL){$this->body=func_num_args()>1?Helpers::formatArgs($statement,$args):$statement;return$this;}/** @return string **/public function getBody(){return$this->body;}/** @return self **/public function addBody($statement,array$args=NULL){$this->body.=(func_num_args()>1?Helpers::formatArgs($statement,$args):$statement)."\n";return$this;}/** @return self **/public function setStatic($val){$this->static=(bool)$val;return$this;}/** @return bool **/public function isStatic(){return$this->static;}/** @return self **/public function setVisibility($val){if(!in_array($val,array('public','protected','private',NULL),TRUE)){throw new Nette\InvalidArgumentException('Argument must be public|protected|private|NULL.');}$this->visibility=$val?(string)$val:NULL;return$this;}/** @return string|NULL **/public function getVisibility(){return$this->visibility;}/** @return self **/public function setFinal($val){$this->final=(bool)$val;return$this;}/** @return bool **/public function isFinal(){return$this->final;}/** @return self **/public function setAbstract($val){$this->abstract=(bool)$val;return$this;}/** @return bool **/public function isAbstract(){return$this->abstract;}/** @return self **/public function setReturnReference($val){$this->returnReference=(bool)$val;return$this;}/** @return bool **/public function getReturnReference(){return$this->returnReference;}/** @return self **/public function setVariadic($val){$this->variadic=(bool)$val;return$this;}/** @return bool **/public function isVariadic(){return$this->variadic;}/** @return self **/public function setComment($val){$this->documents=$val?array((string)$val):array();return$this;}/** @return string|NULL **/public function getComment(){return implode($this->documents)?:NULL;}/** @return self **/public function addComment($val){return$this->addDocument($val);}/** @return self **/public function setDocuments(array$val){$this->documents=$val;return$this;}/** @return string[] **/public function getDocuments(){return$this->documents;}/** @return self **/public function addDocument($val){$this->documents[]=(string)$val;return$this;}/** @return self **/public function setNamespace(PhpNamespace$val=NULL){$this->namespace=$val;return$this;}/** @return self **/public function setReturnType($val){$this->returnType=$val?(string)$val:NULL;return$this;}/** @return string|NULL **/public function getReturnType(){return$this->returnType;}}getName());$param->reference=$from->isPassedByReference();if(PHP_VERSION_ID>=70000){$param->typeHint=$from->hasType()?(string)$from->getType():NULL;}elseif($from->isArray()){$param->typeHint='array';}elseif(PHP_VERSION_ID>=50400&&$from->isCallable()){$param->typeHint='callable';}else{try{$param->typeHint=$from->getClass()?$from->getClass()->getName():NULL;}catch(\ReflectionException$e){if(preg_match('#Class (.+) does not exist#',$e->getMessage(),$m)){$param->typeHint=$m[1];}else{throw$e;}}}$param->optional=PHP_VERSION_ID<50407?$from->isOptional()||($param->typeHint&&$from->allowsNull()):$from->isDefaultValueAvailable();$param->defaultValue=(PHP_VERSION_ID===50316?$from->isOptional():$from->isDefaultValueAvailable())?$from->getDefaultValue():NULL;return$param;}public function __construct($name=''){$this->setName($name);}/** @return self **/public function setName($name){$this->name=(string)$name;return$this;}/** @return string **/public function getName(){return$this->name;}/** @return self **/public function setReference($state=TRUE){$this->reference=(bool)$state;return$this;}/** @return bool **/public function isReference(){return$this->reference;}/** @return self **/public function setTypeHint($hint){$this->typeHint=$hint?(string)$hint:NULL;return$this;}/** @return string|NULL **/public function getTypeHint(){return$this->typeHint;}/** @return self **/public function setOptional($state=TRUE){$this->optional=(bool)$state;return$this;}/** @return bool **/public function isOptional(){return$this->optional;}/** @return self **/public function setDefaultValue($val){$this->defaultValue=$val;return$this;}/** @return mixed **/public function getDefaultValue(){return$this->defaultValue;}}documents=$val?array((string)$val):array();return$this;}/** @return string|NULL **/public function getComment(){return implode($this->documents)?:NULL;}/** @return self **/public function addComment($val){return$this->addDocument($val);}/** @return self **/public function setDocuments(array$documents){$this->documents=$documents;return$this;}/** @return string[] **/public function getDocuments(){return$this->documents;}/** @return self **/public function addDocument($document){$this->documents[]=$document;return$this;}/** @return ClassType **/public function addClass($name){return$this->addNamespace(Helpers::extractNamespace($name))->addClass(Helpers::extractShortName($name));}/** @return ClassType **/public function addInterface($name){return$this->addNamespace(Helpers::extractNamespace($name))->addInterface(Helpers::extractShortName($name));}/** @return ClassType **/public function addTrait($name){return$this->addNamespace(Helpers::extractNamespace($name))->addTrait(Helpers::extractShortName($name));}/** @return PhpNamespace **/public function addNamespace($name){if(!isset($this->namespaces[$name])){$this->namespaces[$name]=new PhpNamespace($name);}return$this->namespaces[$name];}/** @return string PHP code **/public function __toString(){foreach($this->namespaces as$namespace){$namespace->setBracketedSyntax(count($this->namespaces)>1&&isset($this->namespaces[NULL]));}return Strings::normalize("documents?"\n".str_replace("\n","\n * ","/**\n".implode("\n",$this->documents))."\n */\n\n":'').implode("\n\n",$this->namespaces))."\n";}}value=(string)$value;}/** @return string **/public function __toString(){return$this->value;}}setName($name);}/** @return self **/public function setName($name){$this->name=(string)$name;return$this;}/** @return string|NULL **/public function getName(){return$this->name?:NULL;}/** @return self **/public function setBracketedSyntax($state=TRUE){$this->bracketedSyntax=(bool)$state;return$this;}/** @return bool **/public function getBracketedSyntax(){return$this->bracketedSyntax;}/** @return self **/public function addUse($name,$alias=NULL,&$aliasOut=NULL){$name=ltrim($name,'\\');if($alias===NULL&&$this->name===Helpers::extractNamespace($name)){$alias=Helpers::extractShortName($name);}if($alias===NULL){$path=explode('\\',$name);$counter=NULL;do{if(empty($path)){$counter++;}else{$alias=array_pop($path).$alias;}}while(isset($this->uses[$alias.$counter])&&$this->uses[$alias.$counter]!==$name);$alias.=$counter;}elseif(isset($this->uses[$alias])&&$this->uses[$alias]!==$name){throw new InvalidStateException("Alias '$alias' used already for '{$this->uses[$alias]}', cannot use for '{$name}'.");}$aliasOut=$alias;$this->uses[$alias]=$name;return$this;}/** @return string[] **/public function getUses(){return$this->uses;}/** @return string **/public function unresolveName($name){if(in_array(strtolower($name),array('self','parent','array','callable','string','bool','float','int',''),TRUE)){return$name;}$name=ltrim($name,'\\');$res=NULL;$lower=strtolower($name);foreach($this->uses as$alias=>$for){if(Strings::startsWith($lower.'\\',strtolower($for).'\\')){$short=$alias.substr($name,strlen($for));if(!isset($res)||strlen($res)>strlen($short)){$res=$short;}}}if(!$res&&Strings::startsWith($lower,strtolower($this->name).'\\')){return substr($name,strlen($this->name)+1);}else{return$res?:($this->name?'\\':'').$name;}}/** @return ClassType **/public function addClass($name){if(!isset($this->classes[$name])){$this->addUse($this->name.'\\'.$name);$this->classes[$name]=new ClassType($name,$this);}return$this->classes[$name];}/** @return ClassType **/public function addInterface($name){return$this->addClass($name)->setType(ClassType::TYPE_INTERFACE);}/** @return ClassType **/public function addTrait($name){return$this->addClass($name)->setType(ClassType::TYPE_TRAIT);}/** @return ClassType[] **/public function getClasses(){return$this->classes;}/** @return string PHP code **/public function __toString(){$uses=array();asort($this->uses);foreach($this->uses as$alias=>$name){$useNamespace=Helpers::extractNamespace($name);if($this->name!==$useNamespace){if($alias===$name||substr($name,-(strlen($alias)+1))==='\\'.$alias){$uses[]="use {$name};";}else{$uses[]="use {$name} as {$alias};";}}}$body=($uses?implode("\n",$uses)."\n\n":'').implode("\n",$this->classes);if($this->bracketedSyntax){return'namespace'.($this->name?' '.$this->name:'')." {\n\n".Strings::indent($body)."\n}\n";}else{return($this->name?"namespace {$this->name};\n\n":'').$body;}}}getName());$defaults=$from->getDeclaringClass()->getDefaultProperties();$prop->value=isset($defaults[$prop->name])?$defaults[$prop->name]:NULL;$prop->static=$from->isStatic();$prop->visibility=$from->isPrivate()?'private':($from->isProtected()?'protected':'public');$prop->documents=$from->getDocComment()?array(preg_replace('#^\s*\* ?#m','',trim($from->getDocComment(),"/* \r\n\t"))):array();return$prop;}public function __construct($name=''){$this->setName($name);}/** @return self **/public function setName($name){$this->name=(string)$name;return$this;}/** @return string **/public function getName(){return$this->name;}/** @return self **/public function setValue($val){$this->value=$val;return$this;}/** @return mixed **/public function getValue(){return$this->value;}/** @return self **/public function setStatic($state=TRUE){$this->static=(bool)$state;return$this;}/** @return bool **/public function isStatic(){return$this->static;}/** @return self **/public function setVisibility($val){if(!in_array($val,array('public','protected','private'),TRUE)){throw new Nette\InvalidArgumentException('Argument must be public|protected|private.');}$this->visibility=(string)$val;return$this;}/** @return string **/public function getVisibility(){return$this->visibility;}/** @return self **/public function setComment($val){$this->documents=$val?array((string)$val):array();return$this;}/** @return string|NULL **/public function getComment(){return implode($this->documents)?:NULL;}/** @return self **/public function addComment($val){return$this->addDocument($val);}/** @return self **/public function setDocuments(array$s){$this->documents=$s;return$this;}/** @return string[] **/public function getDocuments(){return$this->documents;}/** @return self **/public function addDocument($s){$this->documents[]=(string)$s;return$this;}}$v){$this->$k=$v;}}/** @return string **/public function __toString(){return$this->value;}}getName();$member='class';$file=$r->getFileName();}elseif($r instanceof\ReflectionMethod){$type=$r->getDeclaringClass()->getName();$member=$r->getName();$file=$r->getFileName();}elseif($r instanceof\ReflectionFunction){$type=NULL;$member=$r->getName();$file=$r->getFileName();}else{$type=$r->getDeclaringClass()->getName();$member='$'.$r->getName();$file=$r->getDeclaringClass()->getFileName();}if(!self::$useReflection){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 self::$cache[$type][$member];}if(self::$useReflection===NULL){self::$useReflection=(bool)ClassType::from(__CLASS__)->getDocComment();}if(self::$useReflection){$annotations=self::parseComment($r->getDocComment());}else{$outerCache=self::getCache();if(self::$cache===NULL){self::$cache=(array)$outerCache->load('list');self::$timestamps=isset(self::$cache['*'])?self::$cache['*']:array();}if(!isset(self::$cache[$type])&&$file){self::$cache['*'][$file]=filemtime($file);foreach(static::parsePhp(file_get_contents($file))as$class=>$info){foreach($info as$prop=>$comment){if($prop!=='use'){self::$cache[$class][$prop]=self::parseComment($comment);}}}$outerCache->save('list',self::$cache);}if(isset(self::$cache[$type][$member])){$annotations=self::$cache[$type][$member];}else{$annotations=array();}}if($r 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 self::$cache[$type][$member]=$annotations;}/** @return string fully qualified class name **/public static function expandClassName($name,\ReflectionClass$reflector){if(empty($name)){throw new Nette\InvalidArgumentException('Class name must not be empty.');}elseif($name==='self'){return$reflector->getName();}elseif($name[0]==='\\'){return ltrim($name,'\\');}$filename=$reflector->getFileName();$parsed=static::getCache()->load($filename,function(&$dp)use($filename){if(AnnotationsParser::$autoRefresh){$dp[Nette\Caching\Cache::FILES]=$filename;}return AnnotationsParser::parsePhp(file_get_contents($filename));});$uses=array_change_key_case((array)$tmp=&$parsed[$reflector->getName()]['use']);$parts=explode('\\',$name,2);$parts[0]=strtolower($parts[0]);if(isset($uses[$parts[0]])){$parts[0]=$uses[$parts[0]];return implode('\\',$parts);}elseif($reflector->inNamespace()){return$reflector->getNamespaceName().'\\'.$name;}else{return$name;}}/** @return array **/private static function 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]:'','~ (?<=\s|^)@('.self::RE_IDENTIFIER.')[ \t]* ## annotation ( \((?>'.self::RE_STRING.'|[^\'")@]+)+\)| ## (value) [^(@\r\n][^@\r\n]*|) ## value ~xi');foreach($matches 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;}}$res[$name][]=is_array($value)?Nette\Utils\ArrayHash::from($value):$value;}return$res;}/** @return array [class => [prop => comment (or 'use' => [alias => class])] **/public static function parsePhp($code){if(Strings::match($code,'#//nette'.'loader=(\S*)#')){return;}$tokens=@token_get_all($code);$namespace=$class=$classLevel=$level=$docComment=NULL;$res=$uses=array();while(list(,$token)=each($tokens)){switch(is_array($token)?$token[0]:$token){case T_DOC_COMMENT:$docComment=$token[1];break;case T_NAMESPACE:$namespace=self::fetch($tokens,array(T_STRING,T_NS_SEPARATOR)).'\\';$uses=array();break;case T_CLASS:case T_INTERFACE:case PHP_VERSION_ID<50400?-1:T_TRAIT:if($name=self::fetch($tokens,T_STRING)){$class=$namespace.$name;$classLevel=$level+1;$res[$class]=array();if($docComment){$res[$class]['class']=$docComment;}if($uses){$res[$class]['use']=$uses;}}break;case T_FUNCTION:self::fetch($tokens,'&');if($level===$classLevel&&$docComment&&($name=self::fetch($tokens,T_STRING))){$res[$class][$name]=$docComment;}break;case T_VAR:case T_PUBLIC:case T_PROTECTED:self::fetch($tokens,T_STATIC);if($level===$classLevel&&$docComment&&($name=self::fetch($tokens,T_VARIABLE))){$res[$class][$name]=$docComment;}break;case T_USE:while(!$class&&($name=self::fetch($tokens,array(T_STRING,T_NS_SEPARATOR)))){if(self::fetch($tokens,T_AS)){$uses[self::fetch($tokens,T_STRING)]=ltrim($name,'\\');}else{$tmp=explode('\\',$name);$uses[end($tmp)]=$name;}if(!self::fetch($tokens,',')){break;}}break;case T_CURLY_OPEN:case T_DOLLAR_OPEN_CURLY_BRACES:case'{':$level++;break;case'}':if($level===$classLevel){$class=$classLevel=NULL;}$level--;case';':$docComment=NULL;}}return$res;}private static function fetch(&$tokens,$take){$res=NULL;while($token=current($tokens)){list($token,$s)=is_array($token)?$token:array($token,$token);if(in_array($token,(array)$take,TRUE)){$res.=$s;}elseif(!in_array($token,array(T_DOC_COMMENT,T_WHITESPACE,T_COMMENT),TRUE)){break;}next($tokens);}return$res;}/** @return void **/public static function setCacheStorage(Nette\Caching\IStorage$storage){self::$cacheStorage=$storage;}/** @return Nette\Caching\IStorage **/public static function getCacheStorage(){if(!self::$cacheStorage){self::$cacheStorage=new Nette\Caching\Storages\MemoryStorage();}return self::$cacheStorage;}/** @return Nette\Caching\Cache **/private static function getCache(){return new Nette\Caching\Cache(static::getCacheStorage(),'Nette.Reflection.Annotations');}}getName();}/** @return bool **/public function is($type){return$this->isSubclassOf($type)||strcasecmp($this->getName(),ltrim($type,'\\'))===0;}/** @return Method|NULL **/public function getConstructor(){return($ref=parent::getConstructor())?Method::from($this->getName(),$ref->getName()):NULL;}/** @return Extension|NULL **/public function getExtension(){return($name=$this->getExtensionName())?new Extension($name):NULL;}/** @return self[] **/public function getInterfaces(){$res=array();foreach(parent::getInterfaceNames()as$val){$res[$val]=new static($val);}return$res;}/** @return Method **/public function getMethod($name){return new Method($this->getName(),$name);}/** @return Method[] **/public function getMethods($filter=-1){foreach($res=parent::getMethods($filter)as$key=>$val){$res[$key]=new Method($this->getName(),$val->getName());}return$res;}/** @return self|NULL **/public function getParentClass(){return($ref=parent::getParentClass())?new static($ref->getName()):NULL;}/** @return Property[] **/public function getProperties($filter=-1){foreach($res=parent::getProperties($filter)as$key=>$val){$res[$key]=new Property($this->getName(),$val->getName());}return$res;}/** @return Property **/public function getProperty($name){return new Property($this->getName(),$name);}/** @return bool **/public function hasAnnotation($name){$res=AnnotationsParser::getAll($this);return!empty($res[$name]);}/** @return IAnnotation **/public function getAnnotation($name){$res=AnnotationsParser::getAll($this);return isset($res[$name])?end($res[$name]):NULL;}/** @return IAnnotation[][] **/public function getAnnotations(){return AnnotationsParser::getAll($this);}/** @return string **/public function getDescription(){return$this->getAnnotation('description');}public function __call($name,$args){return ObjectMixin::call($this,$name,$args);}public function&__get($name){return ObjectMixin::get($this,$name);}public function __set($name,$value){ObjectMixin::set($this,$name,$value);}public function __isset($name){return ObjectMixin::has($this,$name);}public function __unset($name){ObjectMixin::remove($this,$name);}}getName();}public function getClasses(){$res=array();foreach(parent::getClassNames()as$val){$res[$val]=new ClassType($val);}return$res;}public function getFunctions(){foreach($res=parent::getFunctions()as$key=>$val){$res[$key]=new GlobalFunction($key);}return$res;}public function __call($name,$args){return ObjectMixin::call($this,$name,$args);}public function&__get($name){return ObjectMixin::get($this,$name);}public function __set($name,$value){ObjectMixin::set($this,$name,$value);}public function __isset($name){return ObjectMixin::has($this,$name);}public function __unset($name){ObjectMixin::remove($this,$name);}}value=$name);}public function toCallback(){return new Nette\Callback($this->value);}public function __toString(){return$this->getName().'()';}public function getClosure(){return PHP_VERSION_ID<50400?Nette\Utils\Callback::closure($this->value):parent::getClosure();}/** @return Extension **/public function getExtension(){return($name=$this->getExtensionName())?new Extension($name):NULL;}/** @return Parameter[] **/public function getParameters(){foreach($res=parent::getParameters()as$key=>$val){$res[$key]=new Parameter($this->value,$val->getName());}return$res;}/** @return bool **/public function hasAnnotation($name){$res=AnnotationsParser::getAll($this);return!empty($res[$name]);}/** @return IAnnotation **/public function getAnnotation($name){$res=AnnotationsParser::getAll($this);return isset($res[$name])?end($res[$name]):NULL;}/** @return IAnnotation[][] **/public function getAnnotations(){return AnnotationsParser::getAll($this);}/** @return string **/public function getDescription(){return$this->getAnnotation('description');}public function __call($name,$args){return ObjectMixin::call($this,$name,$args);}public function&__get($name){return ObjectMixin::get($this,$name);}public function __set($name,$value){ObjectMixin::set($this,$name,$value);}public function __isset($name){return ObjectMixin::has($this,$name);}public function __unset($name){ObjectMixin::remove($this,$name);}}=50400){foreach($prop->getDeclaringClass()->getTraits()as$trait){if($trait->hasProperty($prop->getName())){return self::getDeclaringClass($trait->getProperty($prop->getName()));}}}return$prop->getDeclaringClass();}}getName(),$this->getName());}public function __toString(){return parent::getDeclaringClass()->getName().'::'.$this->getName().'()';}public function getClosure($object=NULL){return PHP_VERSION_ID<50400?Nette\Utils\Callback::closure($object?:parent::getDeclaringClass()->getName(),$this->getName()):parent::getClosure($object);}/** @return ClassType **/public function getDeclaringClass(){return new ClassType(parent::getDeclaringClass()->getName());}/** @return self **/public function getPrototype(){$prototype=parent::getPrototype();return new static($prototype->getDeclaringClass()->getName(),$prototype->getName());}/** @return Extension **/public function getExtension(){return($name=$this->getExtensionName())?new Extension($name):NULL;}/** @return Parameter[] **/public function getParameters(){$me=array(parent::getDeclaringClass()->getName(),$this->getName());foreach($res=parent::getParameters()as$key=>$val){$res[$key]=new Parameter($me,$val->getName());}return$res;}/** @return bool **/public function hasAnnotation($name){$res=AnnotationsParser::getAll($this);return!empty($res[$name]);}/** @return IAnnotation **/public function getAnnotation($name){$res=AnnotationsParser::getAll($this);return isset($res[$name])?end($res[$name]):NULL;}/** @return IAnnotation[][] **/public function getAnnotations(){return AnnotationsParser::getAll($this);}/** @return string **/public function getDescription(){return$this->getAnnotation('description');}public function __call($name,$args){return ObjectMixin::call($this,$name,$args);}public function&__get($name){return ObjectMixin::get($this,$name);}public function __set($name,$value){ObjectMixin::set($this,$name,$value);}public function __isset($name){return ObjectMixin::has($this,$name);}public function __unset($name){ObjectMixin::remove($this,$name);}}function=$function,$parameter);}/** @return ClassType **/public function getClass(){return($ref=parent::getClass())?new ClassType($ref->getName()):NULL;}/** @return string **/public function getClassName(){try{return($ref=parent::getClass())?$ref->getName():NULL;}catch(\ReflectionException$e){if(preg_match('#Class (.+) does not exist#',$e->getMessage(),$m)){return$m[1];}throw$e;}}/** @return ClassType **/public function getDeclaringClass(){return($ref=parent::getDeclaringClass())?new ClassType($ref->getName()):NULL;}/** @return Method|GlobalFunction **/public function getDeclaringFunction(){return is_array($this->function)?new Method($this->function[0],$this->function[1]):new GlobalFunction($this->function);}/** @return bool **/public function isDefaultValueAvailable(){if(PHP_VERSION_ID===50316){try{$this->getDefaultValue();return TRUE;}catch(\ReflectionException$e){return FALSE;}}return parent::isDefaultValueAvailable();}public function __toString(){return'$'.parent::getName().' in '.$this->getDeclaringFunction();}public function __call($name,$args){return ObjectMixin::call($this,$name,$args);}public function&__get($name){return ObjectMixin::get($this,$name);}public function __set($name,$value){ObjectMixin::set($this,$name,$value);}public function __isset($name){return ObjectMixin::has($this,$name);}public function __unset($name){ObjectMixin::remove($this,$name);}}getName().'::$'.$this->getName();}/** @return ClassType **/public function getDeclaringClass(){return new ClassType(parent::getDeclaringClass()->getName());}/** @return bool **/public function hasAnnotation($name){$res=AnnotationsParser::getAll($this);return!empty($res[$name]);}/** @return IAnnotation **/public function getAnnotation($name){$res=AnnotationsParser::getAll($this);return isset($res[$name])?end($res[$name]):NULL;}/** @return IAnnotation[][] **/public function getAnnotations(){return AnnotationsParser::getAll($this);}/** @return string **/public function getDescription(){return$this->getAnnotation('description');}public function __call($name,$args){return ObjectMixin::call($this,$name,$args);}public function&__get($name){return ObjectMixin::get($this,$name);}public function __set($name,$value){ObjectMixin::set($this,$name,$value);}public function __isset($name){return ObjectMixin::has($this,$name);}public function __unset($name){ObjectMixin::remove($this,$name);}}classes=$this->getCache()->load($this->getKey(),array($this,'rebuildCallback'));spl_autoload_register(array($this,'tryLoad'),TRUE,(bool)$prepend);return$this;}/** @return void **/public function tryLoad($type){$type=$orig=ltrim($type,'\\');$type=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);}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);}}if(isset($this->classes[$type]['file'])){if($this->classes[$type]['orig']!==$orig){trigger_error("Case mismatch on class name '$orig', correct name is '{$this->classes[$type]['orig']}'.",E_USER_WARNING);}call_user_func(function($file){require$file;},$this->classes[$type]['file']);}else{$this->missing[$type]=TRUE;}}/** @return self **/public function addDirectory($path){$this->scanPaths=array_merge($this->scanPaths,(array)$path);return$this;}/** @return array of class => filename **/public function getIndexedClasses(){$res=array();foreach($this->classes as$info){if(is_array($info)){$res[$info['orig']]=$info['file'];}}return$res;}/** @return void **/public function rebuild(){$this->rebuilt=TRUE;$this->getCache()->save($this->getKey(),Nette\Utils\Callback::closure($this,'rebuildCallback'));}public function rebuildCallback(){$files=$missing=array();foreach($this->classes 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($this->scanPaths as$path){foreach(is_file($path)?array(new SplFileInfo($path)):$this->createFileIterator($path)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));}$files[$file]=array('classes'=>array(),'time'=>filemtime($file));foreach($classes as$class){$info=&$this->classes[strtolower($class)];if(isset($info['file'])){throw new Nette\InvalidStateException("Ambiguous class $class resolution; defined in {$info['file']} and in $file.");}$info=array('file'=>$file,'time'=>filemtime($file),'orig'=>$class);}}}$this->classes+=$missing;return$this->classes;}/** @return \Iterator **/private function createFileIterator($dir){if(!is_dir($dir)){throw new Nette\IOException("File or directory '$dir' not found.");}$ignoreDirs=is_array($this->ignoreDirs)?$this->ignoreDirs:preg_split('#[,\s]+#',$this->ignoreDirs);$disallow=array();foreach($ignoreDirs 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(SplFileInfo$file)use(&$disallow){return!isset($disallow[$file->getPathname()]);})->from($dir)->exclude($ignoreDirs)->filter($filter=function(SplFileInfo$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;}/** @return void **/private function updateFile($file){foreach($this->classes 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'])){throw new Nette\InvalidStateException("Ambiguous class $class resolution; defined in {$info['file']} and in $file.");}$info=array('file'=>$file,'time'=>filemtime($file),'orig'=>$class);}}}/** @return array **/private function scanPhp($code){$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 T_COMMENT:case T_DOC_COMMENT:case T_WHITESPACE:continue 2;case T_NS_SEPARATOR:case T_STRING:if($expected){$name.=$token[1];}continue 2;case T_NAMESPACE:case T_CLASS:case T_INTERFACE:case$T_TRAIT:$expected=$token[0];$name='';continue 2;case T_CURLY_OPEN:case T_DOLLAR_OPEN_CURLY_BRACES:$level++;}}if($expected){switch($expected){case T_CLASS:case T_INTERFACE:case$T_TRAIT:if($name&&$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;}/** @return RobotLoader **/public function setCacheStorage(Nette\Caching\IStorage$storage){$this->cacheStorage=$storage;return$this;}/** @return Nette\Caching\IStorage **/public function getCacheStorage(){return$this->cacheStorage;}/** @return Nette\Caching\Cache **/protected function getCache(){if(!$this->cacheStorage){trigger_error('Missing cache storage.',E_USER_WARNING);$this->cacheStorage=new Nette\Caching\Storages\DevNullStorage;}return new Cache($this->cacheStorage,'Nette.RobotLoader');}/** @return string **/protected function getKey(){return array($this->ignoreDirs,$this->acceptFiles,$this->scanPaths);}}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 FALSE;}}elseif($mode[0]==='x'){if(!$this->checkAndLock($this->handle=fopen($path,'x'.$flag,$use_path),LOCK_EX)){return 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 FALSE;}}else{trigger_error("Unknown mode $mode",E_USER_WARNING);return FALSE;}$tmp='~~'.lcg_value().'.tmp';if(!$this->tempHandle=fopen($path.$tmp,(strpos($mode,'+')?'x+':'x').$flag,$use_path)){$this->clean();return 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(stream_copy_to_stream($this->handle,$this->tempHandle)!==$stat['size']){$this->clean();return FALSE;}if($mode[0]==='a'){fseek($this->tempHandle,0,SEEK_END);}}return TRUE;}/** @return bool **/private function checkAndLock($handle,$lock){if(!$handle){return FALSE;}elseif(!flock($handle,$lock)){fclose($handle);return FALSE;}return TRUE;}private function clean(){flock($this->handle,LOCK_UN);fclose($this->handle);if($this->deleteFile){unlink($this->file);}if($this->tempHandle){fclose($this->tempHandle);unlink($this->tempFile);}}/** @return void **/public function 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);}}}/** @return string **/public function stream_read($length){return fread($this->tempHandle,$length);}/** @return int number of bytes that were successfully stored **/public function stream_write($data){$len=strlen($data);$res=fwrite($this->tempHandle,$data,$len);if($res!==$len){$this->writeError=TRUE;}return$res;}/** @return bool **/public function stream_truncate($size){return ftruncate($this->tempHandle,$size);}/** @return int **/public function stream_tell(){return ftell($this->tempHandle);}/** @return bool **/public function stream_eof(){return feof($this->tempHandle);}/** @return int Return TRUE on success **/public function stream_seek($offset,$whence){return fseek($this->tempHandle,$offset,$whence)===0;}/** @return array **/public function stream_stat(){return fstat($this->tempHandle);}/** @return array **/public function url_stat($path,$flags){$path=substr($path,strpos($path,':')+3);return($flags&STREAM_URL_STAT_LINK)?@lstat($path):@stat($path);}/** @return bool TRUE on success or FALSE on failure **/public function unlink($path){$path=substr($path,strpos($path,':')+3);return unlink($path);}}setId($id);$this->setRoles((array)$roles);$this->data=$data instanceof\Traversable?iterator_to_array($data):(array)$data;}/** @return self **/public function setId($id){$this->id=is_numeric($id)&&!is_float($tmp=$id*1)?$tmp:$id;return$this;}/** @return mixed **/public function getId(){return$this->id;}/** @return self **/public function setRoles(array$roles){$this->roles=$roles;return$this;}/** @return array **/public function getRoles(){return$this->roles;}/** @return array **/public function getData(){return$this->data;}/** @return void **/public function __set($key,$value){if(parent::__isset($key)){parent::__set($key,$value);}else{$this->data[$key]=$value;}}/** @return mixed **/public function&__get($key){if(parent::__isset($key)){return parent::__get($key);}else{return$this->data[$key];}}/** @return bool **/public function __isset($key){return isset($this->data[$key])||parent::__isset($key);}/** @return void **/public function __unset($name){Nette\Utils\ObjectMixin::remove($this,$name);}}= 5.3.7.');}elseif(($len=strlen($salt))<22){throw new Nette\InvalidArgumentException("Salt must be 22 characters long, $len given.");}elseif($cost<4||$cost>31){throw new Nette\InvalidArgumentException("Cost must be in range 4-31, $cost given.");}$hash=crypt($password,'$2y$'.($cost<10?0:'').$cost.'$'.$salt);if(strlen($hash)<60){throw new Nette\InvalidStateException('Hash returned by crypt is invalid.');}return$hash;}/** @return bool **/public static function verify($password,$hash){return preg_match('#^\$2y\$(?P\d\d)\$(?P.{22})#',$hash,$m)&&$m['cost']>=4&&$m['cost']<=31&&self::hash($password,$m)===$hash;}/** @return bool **/public static function needsRehash($hash,array$options=NULL){$cost=isset($options['cost'])?(int)$options['cost']:self::BCRYPT_COST;return!preg_match('#^\$2y\$(?P\d\d)\$(?P.{22})#',$hash,$m)||$m['cost']<$cost;}}array('allRoles'=>array('allPrivileges'=>array('type'=>self::DENY,'assert'=>NULL),'byPrivilege'=>array()),'byRole'=>array()),'byResource'=>array());private$queriedRole,$queriedResource;/** @return self **/public function addRole($role,$parents=NULL){$this->checkRole($role,FALSE);if(isset($this->roles[$role])){throw new Nette\InvalidStateException("Role '$role' already exists in the list.");}$roleParents=array();if($parents!==NULL){if(!is_array($parents)){$parents=array($parents);}foreach($parents as$parent){$this->checkRole($parent);$roleParents[$parent]=TRUE;$this->roles[$parent]['children'][$role]=TRUE;}}$this->roles[$role]=array('parents'=>$roleParents,'children'=>array());return$this;}/** @return bool **/public function hasRole($role){$this->checkRole($role,FALSE);return isset($this->roles[$role]);}/** @return void **/private function checkRole($role,$need=TRUE){if(!is_string($role)||$role===''){throw new Nette\InvalidArgumentException('Role must be a non-empty string.');}elseif($need&&!isset($this->roles[$role])){throw new Nette\InvalidStateException("Role '$role' does not exist.");}}/** @return array **/public function getRoles(){return array_keys($this->roles);}/** @return array **/public function getRoleParents($role){$this->checkRole($role);return array_keys($this->roles[$role]['parents']);}/** @return bool **/public function roleInheritsFrom($role,$inherit,$onlyParents=FALSE){$this->checkRole($role);$this->checkRole($inherit);$inherits=isset($this->roles[$role]['parents'][$inherit]);if($inherits||$onlyParents){return$inherits;}foreach($this->roles[$role]['parents']as$parent=>$foo){if($this->roleInheritsFrom($parent,$inherit)){return TRUE;}}return FALSE;}/** @return self **/public function removeRole($role){$this->checkRole($role);foreach($this->roles[$role]['children']as$child=>$foo){unset($this->roles[$child]['parents'][$role]);}foreach($this->roles[$role]['parents']as$parent=>$foo){unset($this->roles[$parent]['children'][$role]);}unset($this->roles[$role]);foreach($this->rules['allResources']['byRole']as$roleCurrent=>$rules){if($role===$roleCurrent){unset($this->rules['allResources']['byRole'][$roleCurrent]);}}foreach($this->rules['byResource']as$resourceCurrent=>$visitor){if(isset($visitor['byRole'])){foreach($visitor['byRole']as$roleCurrent=>$rules){if($role===$roleCurrent){unset($this->rules['byResource'][$resourceCurrent]['byRole'][$roleCurrent]);}}}}return$this;}/** @return self **/public function removeAllRoles(){$this->roles=array();foreach($this->rules['allResources']['byRole']as$roleCurrent=>$rules){unset($this->rules['allResources']['byRole'][$roleCurrent]);}foreach($this->rules['byResource']as$resourceCurrent=>$visitor){foreach($visitor['byRole']as$roleCurrent=>$rules){unset($this->rules['byResource'][$resourceCurrent]['byRole'][$roleCurrent]);}}return$this;}/** @return self **/public function addResource($resource,$parent=NULL){$this->checkResource($resource,FALSE);if(isset($this->resources[$resource])){throw new Nette\InvalidStateException("Resource '$resource' already exists in the list.");}if($parent!==NULL){$this->checkResource($parent);$this->resources[$parent]['children'][$resource]=TRUE;}$this->resources[$resource]=array('parent'=>$parent,'children'=>array());return$this;}/** @return bool **/public function hasResource($resource){$this->checkResource($resource,FALSE);return isset($this->resources[$resource]);}/** @return void **/private function checkResource($resource,$need=TRUE){if(!is_string($resource)||$resource===''){throw new Nette\InvalidArgumentException('Resource must be a non-empty string.');}elseif($need&&!isset($this->resources[$resource])){throw new Nette\InvalidStateException("Resource '$resource' does not exist.");}}/** @return array **/public function getResources(){return array_keys($this->resources);}/** @return bool **/public function resourceInheritsFrom($resource,$inherit,$onlyParent=FALSE){$this->checkResource($resource);$this->checkResource($inherit);if($this->resources[$resource]['parent']===NULL){return FALSE;}$parent=$this->resources[$resource]['parent'];if($inherit===$parent){return TRUE;}elseif($onlyParent){return FALSE;}while($this->resources[$parent]['parent']!==NULL){$parent=$this->resources[$parent]['parent'];if($inherit===$parent){return TRUE;}}return FALSE;}/** @return self **/public function removeResource($resource){$this->checkResource($resource);$parent=$this->resources[$resource]['parent'];if($parent!==NULL){unset($this->resources[$parent]['children'][$resource]);}$removed=array($resource);foreach($this->resources[$resource]['children']as$child=>$foo){$this->removeResource($child);$removed[]=$child;}foreach($removed as$resourceRemoved){foreach($this->rules['byResource']as$resourceCurrent=>$rules){if($resourceRemoved===$resourceCurrent){unset($this->rules['byResource'][$resourceCurrent]);}}}unset($this->resources[$resource]);return$this;}/** @return self **/public function removeAllResources(){foreach($this->resources as$resource=>$foo){foreach($this->rules['byResource']as$resourceCurrent=>$rules){if($resource===$resourceCurrent){unset($this->rules['byResource'][$resourceCurrent]);}}}$this->resources=array();return$this;}/** @return self **/public function allow($roles=self::ALL,$resources=self::ALL,$privileges=self::ALL,$assertion=NULL){$this->setRule(TRUE,self::ALLOW,$roles,$resources,$privileges,$assertion);return$this;}/** @return self **/public function deny($roles=self::ALL,$resources=self::ALL,$privileges=self::ALL,$assertion=NULL){$this->setRule(TRUE,self::DENY,$roles,$resources,$privileges,$assertion);return$this;}/** @return self **/public function removeAllow($roles=self::ALL,$resources=self::ALL,$privileges=self::ALL){$this->setRule(FALSE,self::ALLOW,$roles,$resources,$privileges);return$this;}/** @return self **/public function removeDeny($roles=self::ALL,$resources=self::ALL,$privileges=self::ALL){$this->setRule(FALSE,self::DENY,$roles,$resources,$privileges);return$this;}/** @return self **/protected function setRule($toAdd,$type,$roles,$resources,$privileges,$assertion=NULL){if($roles===self::ALL){$roles=array(self::ALL);}else{if(!is_array($roles)){$roles=array($roles);}foreach($roles as$role){$this->checkRole($role);}}if($resources===self::ALL){$resources=array(self::ALL);}else{if(!is_array($resources)){$resources=array($resources);}foreach($resources as$resource){$this->checkResource($resource);}}if($privileges===self::ALL){$privileges=array();}elseif(!is_array($privileges)){$privileges=array($privileges);}if($toAdd){foreach($resources as$resource){foreach($roles as$role){$rules=&$this->getRules($resource,$role,TRUE);if(count($privileges)===0){$rules['allPrivileges']['type']=$type;$rules['allPrivileges']['assert']=$assertion;if(!isset($rules['byPrivilege'])){$rules['byPrivilege']=array();}}else{foreach($privileges as$privilege){$rules['byPrivilege'][$privilege]['type']=$type;$rules['byPrivilege'][$privilege]['assert']=$assertion;}}}}}else{foreach($resources as$resource){foreach($roles as$role){$rules=&$this->getRules($resource,$role);if($rules===NULL){continue;}if(count($privileges)===0){if($resource===self::ALL&&$role===self::ALL){if($type===$rules['allPrivileges']['type']){$rules=array('allPrivileges'=>array('type'=>self::DENY,'assert'=>NULL),'byPrivilege'=>array());}continue;}if($type===$rules['allPrivileges']['type']){unset($rules['allPrivileges']);}}else{foreach($privileges as$privilege){if(isset($rules['byPrivilege'][$privilege])&&$type===$rules['byPrivilege'][$privilege]['type']){unset($rules['byPrivilege'][$privilege]);}}}}}}return$this;}/** @return bool **/public function isAllowed($role=self::ALL,$resource=self::ALL,$privilege=self::ALL){$this->queriedRole=$role;if($role!==self::ALL){if($role instanceof IRole){$role=$role->getRoleId();}$this->checkRole($role);}$this->queriedResource=$resource;if($resource!==self::ALL){if($resource instanceof IResource){$resource=$resource->getResourceId();}$this->checkResource($resource);}do{if($role!==NULL&&NULL!==($result=$this->searchRolePrivileges($privilege===self::ALL,$role,$resource,$privilege))){break;}if($privilege===self::ALL){if($rules=$this->getRules($resource,self::ALL)){foreach($rules['byPrivilege']as$privilege=>$rule){if(self::DENY===($result=$this->getRuleType($resource,NULL,$privilege))){break 2;}}if(NULL!==($result=$this->getRuleType($resource,NULL,NULL))){break;}}}else{if(NULL!==($result=$this->getRuleType($resource,NULL,$privilege))){break;}elseif(NULL!==($result=$this->getRuleType($resource,NULL,NULL))){break;}}$resource=$this->resources[$resource]['parent'];}while(TRUE);$this->queriedRole=$this->queriedResource=NULL;return$result;}/** @return mixed **/public function getQueriedRole(){return$this->queriedRole;}/** @return mixed **/public function getQueriedResource(){return$this->queriedResource;}/** @return mixed NULL if no applicable rule is found, otherwise returns ALLOW or DENY **/private function searchRolePrivileges($all,$role,$resource,$privilege){$dfs=array('visited'=>array(),'stack'=>array($role));while(NULL!==($role=array_pop($dfs['stack']))){if(isset($dfs['visited'][$role])){continue;}if($all){if($rules=$this->getRules($resource,$role)){foreach($rules['byPrivilege']as$privilege2=>$rule){if(self::DENY===$this->getRuleType($resource,$role,$privilege2)){return self::DENY;}}if(NULL!==($type=$this->getRuleType($resource,$role,NULL))){return$type;}}}else{if(NULL!==($type=$this->getRuleType($resource,$role,$privilege))){return$type;}elseif(NULL!==($type=$this->getRuleType($resource,$role,NULL))){return$type;}}$dfs['visited'][$role]=TRUE;foreach($this->roles[$role]['parents']as$roleParent=>$foo){$dfs['stack'][]=$roleParent;}}return NULL;}/** @return mixed NULL if a rule does not exist or assertion fails, otherwise returns ALLOW or DENY **/private function getRuleType($resource,$role,$privilege){if(!$rules=$this->getRules($resource,$role)){return NULL;}if($privilege===self::ALL){if(isset($rules['allPrivileges'])){$rule=$rules['allPrivileges'];}else{return NULL;}}elseif(!isset($rules['byPrivilege'][$privilege])){return NULL;}else{$rule=$rules['byPrivilege'][$privilege];}if($rule['assert']===NULL||Nette\Utils\Callback::invoke($rule['assert'],$this,$role,$resource,$privilege)){return$rule['type'];}elseif($resource!==self::ALL||$role!==self::ALL||$privilege!==self::ALL){return NULL;}elseif(self::ALLOW===$rule['type']){return self::DENY;}else{return self::ALLOW;}}/** @return array|NULL **/private function&getRules($resource,$role,$create=FALSE){$null=NULL;if($resource===self::ALL){$visitor=&$this->rules['allResources'];}else{if(!isset($this->rules['byResource'][$resource])){if(!$create){return$null;}$this->rules['byResource'][$resource]=array();}$visitor=&$this->rules['byResource'][$resource];}if($role===self::ALL){if(!isset($visitor['allRoles'])){if(!$create){return$null;}$visitor['allRoles']['byPrivilege']=array();}return$visitor['allRoles'];}if(!isset($visitor['byRole'][$role])){if(!$create){return$null;}$visitor['byRole'][$role]['byPrivilege']=array();}return$visitor['byRole'][$role];}}userlist=$userlist;$this->usersRoles=$usersRoles;}/** @return IIdentity **/public function authenticate(array$credentials){list($username,$password)=$credentials;foreach($this->userlist as$name=>$pass){if(strcasecmp($name,$username)===0){if((string)$pass===(string)$password){return new Identity($name,isset($this->usersRoles[$name])?$this->usersRoles[$name]:NULL);}else{throw new AuthenticationException('Invalid password.',self::INVALID_CREDENTIAL);}}}throw new AuthenticationException("User '$username' not found.",self::IDENTITY_NOT_FOUND);}}storage=$storage;$this->authenticator=$authenticator;$this->authorizator=$authorizator;}/** @return IUserStorage **/public function getStorage(){return$this->storage;}/** @return void **/public function login($id=NULL,$password=NULL){$this->logout(TRUE);if(!$id instanceof IIdentity){$id=$this->getAuthenticator()->authenticate(func_get_args());}$this->storage->setIdentity($id);$this->storage->setAuthenticated(TRUE);$this->onLoggedIn($this);}/** @return void **/public function logout($clearIdentity=FALSE){if($this->isLoggedIn()){$this->onLoggedOut($this);$this->storage->setAuthenticated(FALSE);}if($clearIdentity){$this->storage->setIdentity(NULL);}}/** @return bool **/public function isLoggedIn(){return$this->storage->isAuthenticated();}/** @return IIdentity|NULL **/public function getIdentity(){return$this->storage->getIdentity();}/** @return mixed **/public function getId(){$identity=$this->getIdentity();return$identity?$identity->getId():NULL;}/** @return self **/public function setAuthenticator(IAuthenticator$handler){$this->authenticator=$handler;return$this;}/** @return IAuthenticator **/public function getAuthenticator($need=TRUE){if($need&&!$this->authenticator){throw new Nette\InvalidStateException('Authenticator has not been set.');}return$this->authenticator;}/** @return self **/public function setExpiration($time,$whenBrowserIsClosed=TRUE,$clearIdentity=FALSE){$flags=($whenBrowserIsClosed?IUserStorage::BROWSER_CLOSED:0)|($clearIdentity?IUserStorage::CLEAR_IDENTITY:0);$this->storage->setExpiration($time,$flags);return$this;}/** @return int **/public function getLogoutReason(){return$this->storage->getLogoutReason();}/** @return array **/public function getRoles(){if(!$this->isLoggedIn()){return array($this->guestRole);}$identity=$this->getIdentity();return$identity&&$identity->getRoles()?$identity->getRoles():array($this->authenticatedRole);}/** @return bool **/public function isInRole($role){return in_array($role,$this->getRoles(),TRUE);}/** @return bool **/public function isAllowed($resource=IAuthorizator::ALL,$privilege=IAuthorizator::ALL){foreach($this->getRoles()as$role){if($this->getAuthorizator()->isAllowed($role,$resource,$privilege)){return TRUE;}}return FALSE;}/** @return self **/public function setAuthorizator(IAuthorizator$handler){$this->authorizator=$handler;return$this;}/** @return IAuthorizator **/public function getAuthorizator($need=TRUE){if($need&&!$this->authorizator){throw new Nette\InvalidStateException('Authorizator has not been set.');}return$this->authorizator;}}tokens=$tokens;}/** @return array|NULL **/public function currentToken(){return isset($this->tokens[$this->position])?$this->tokens[$this->position]:NULL;}/** @return string|NULL **/public function currentValue(){return isset($this->tokens[$this->position])?$this->tokens[$this->position][Tokenizer::VALUE]:NULL;}/** @return array|NULL **/public function nextToken(){return$this->scan(func_get_args(),TRUE,TRUE);}/** @return string|NULL **/public function nextValue(){return$this->scan(func_get_args(),TRUE,TRUE,TRUE);}/** @return array[] **/public function nextAll(){return$this->scan(func_get_args(),FALSE,TRUE);}/** @return array[] **/public function nextUntil($arg){return$this->scan(func_get_args(),FALSE,TRUE,FALSE,TRUE);}/** @return string **/public function joinAll(){return$this->scan(func_get_args(),FALSE,TRUE,TRUE);}/** @return string **/public function joinUntil($arg){return$this->scan(func_get_args(),FALSE,TRUE,TRUE,TRUE);}/** @return bool **/public function isCurrent($arg){if(!isset($this->tokens[$this->position])){return FALSE;}$args=func_get_args();$token=$this->tokens[$this->position];return in_array($token[Tokenizer::VALUE],$args,TRUE)||(isset($token[Tokenizer::TYPE])&&in_array($token[Tokenizer::TYPE],$args,TRUE));}/** @return bool **/public function isNext(){return(bool)$this->scan(func_get_args(),TRUE,FALSE);}/** @return bool **/public function isPrev(){return(bool)$this->scan(func_get_args(),TRUE,FALSE,FALSE,FALSE,TRUE);}/** @return self **/public function reset(){$this->position=-1;return$this;}protected function next(){$this->position++;}/** @return mixed **/protected function scan($wanted,$onlyFirst,$advance,$strings=FALSE,$until=FALSE,$prev=FALSE){$res=$onlyFirst?NULL:($strings?'':array());$pos=$this->position+($prev?-1:1);do{if(!isset($this->tokens[$pos])){if(!$wanted&&$advance&&!$prev&&$pos<=count($this->tokens)){$this->next();}return$res;}$token=$this->tokens[$pos];$type=isset($token[Tokenizer::TYPE])?$token[Tokenizer::TYPE]:NULL;if(!$wanted||(in_array($token[Tokenizer::VALUE],$wanted,TRUE)||in_array($type,$wanted,TRUE))^$until){while($advance&&!$prev&&$pos>$this->position){$this->next();}if($onlyFirst){return$strings?$token[Tokenizer::VALUE]:$token;}elseif($strings){$res.=$token[Tokenizer::VALUE];}else{$res[]=$token;}}elseif($until||!in_array($type,$this->ignored,TRUE)){return$res;}$pos+=$prev?-1:1;}while(TRUE);}}re='~('.implode(')|(',$patterns).')~A'.$flags;$keys=array_keys($patterns);$this->types=$keys===range(0,count($patterns)-1)?FALSE:$keys;}/** @return array **/public function tokenize($input){if($this->types){preg_match_all($this->re,$input,$tokens,PREG_SET_ORDER);$len=0;$count=count($this->types);foreach($tokens 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=array(self::VALUE=>$match[0],self::OFFSET=>$len,self::TYPE=>$type);$len+=strlen($match[self::VALUE]);}if($len!==strlen($input)){$errorOffset=$len;}}else{$tokens=preg_split($this->re,$input,-1,PREG_SPLIT_NO_EMPTY|PREG_SPLIT_OFFSET_CAPTURE|PREG_SPLIT_DELIM_CAPTURE);$last=end($tokens);if($tokens&&!preg_match($this->re,$last[0])){$errorOffset=$last[1];}}if(isset($errorOffset)){list($line,$col)=$this->getCoordinates($input,$errorOffset);$token=str_replace("\n",'\n',substr($input,$errorOffset,10));throw new TokenizerException("Unexpected '$token' on line $line, column $col.");}return$tokens;}/** @return array of [line, column] **/public static function getCoordinates($text,$offset){$text=substr($text,0,$offset);return array(substr_count($text,"\n")+1,$offset-strrpos("\n".$text,"\n")+1);}} a, #tracy-debug-bar li > span { color: #000; display: block; padding: 0 .4em; } #tracy-debug-bar li > a:hover { color: black; background: #c3c1b8; } #tracy-debug-logo { cursor: move; } #tracy-debug-logo svg { width: 3.4em; margin: 0 .2em 0 .5em; } /* panels */ #tracy-debug .tracy-panel { font: normal normal 12px/1.5 sans-serif; background: white; color: #333; text-align: left; z-index: 20001; } #tracy-debug h1 { font: normal normal 23px/1.4 Tahoma, sans-serif; color: #575753; margin: -5px -5px 5px; padding: 0 25px 5px 5px; max-width: 700px; word-wrap: break-word; } #tracy-debug .tracy-mode-peek .tracy-inner, #tracy-debug .tracy-mode-float .tracy-inner { max-width: 700px; max-height: 500px; overflow: auto; } #tracy-debug .tracy-panel .tracy-icons { display: none; } #tracy-debug .tracy-mode-peek, #tracy-debug .tracy-mode-float { position: fixed; right: 0; bottom: 0; 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); } #tracy-debug .tracy-mode-peek { display: none; } #tracy-debug .tracy-mode-peek h1 { cursor: move; } #tracy-debug .tracy-mode-float { opacity: .95; transition: opacity 0.2s; } #tracy-debug .tracy-focused { opacity: 1; transition: opacity 0.1s; } #tracy-debug .tracy-mode-float h1 { cursor: move; } #tracy-debug .tracy-mode-float .tracy-icons { display: block; position: absolute; top: 0; right: 5px; font-size: 18px; } #tracy-debug .tracy-icons a { color: #575753; } #tracy-debug .tracy-icons a:hover { color: white; } /* dump */ #tracy-debug pre.tracy-dump div { padding-left: 3ex; } #tracy-debug pre.tracy-dump div div { border-left: 1px solid rgba(0, 0, 0, .1); margin-left: .5ex; } #tracy-debug pre.tracy-dump { background: #FDF5CE; padding: .4em .7em; border: 1px dotted silver; overflow: auto; } #tracy-debug table pre.tracy-dump { padding: 0; margin: 0; border: none; } #tracy-debug .tracy-dump-array, #tracy-debug .tracy-dump-object { color: #C22; } #tracy-debug .tracy-dump-string { color: #35D; } #tracy-debug .tracy-dump-number { color: #090; } #tracy-debug .tracy-dump-null, #tracy-debug .tracy-dump-bool { color: #850; } #tracy-debug .tracy-dump-visibility, #tracy-debug .tracy-dump-hash { font-size: 85%; color: #999; } #tracy-debug .tracy-dump-indent { display: none; } @media print { #tracy-debug * { display: none; } }/** * This file is part of the Tracy (https://tracy.nette.org) */ (function(){ Tracy = window.Tracy || {}; var Panel = Tracy.DebugPanel = function(id) { this.id = 'tracy-debug-panel-' + id; this.elem = document.getElementById(this.id); this.elem.Tracy = this.elem.Tracy || {}; }; Panel.PEEK = 'tracy-mode-peek'; Panel.FLOAT = 'tracy-mode-float'; Panel.WINDOW = 'tracy-mode-window'; Panel.FOCUSED = 'tracy-focused'; Panel.zIndex = 20000; Panel.prototype.init = function() { var _this = this, elem = this.elem; elem.Tracy.onMove = function(coords) { _this.moveConstrains(this, coords); }; draggable(elem, { rightEdge: true, bottomEdge: true, handle: elem.querySelector('h1'), stop: function() { _this.toFloat(); } }); elem.addEventListener('mouseover', function(e) { if (isTargetChanged(e.relatedTarget, this)) { _this.focus(); } }); elem.addEventListener('mouseout', function(e) { if (isTargetChanged(e.relatedTarget, this)) { _this.blur(); } }); elem.addEventListener('click', function() { _this.oldPosition = getPosition(elem); }); document.documentElement.addEventListener('click', function() { if (_this.oldPosition) { var pos = getPosition(elem); setPosition(elem, { right: pos.right - pos.width + _this.oldPosition.width, bottom: pos.bottom - pos.height + _this.oldPosition.height }); } _this.oldPosition = null; }); [].forEach.call(elem.querySelectorAll('.tracy-icons a'), function(a) { a.addEventListener('click', function(e) { if (this.rel === 'close') { _this.toPeek(); } else { _this.toWindow(); } e.preventDefault(); }); }); this.restorePosition(); }; Panel.prototype.is = function(mode) { return this.elem.classList.contains(mode); }; Panel.prototype.focus = function(callback) { var elem = this.elem; if (this.is(Panel.WINDOW)) { elem.Tracy.window.focus(); } else { clearTimeout(elem.Tracy.displayTimeout); elem.Tracy.displayTimeout = setTimeout(function() { elem.classList.add(Panel.FOCUSED); elem.style.display = 'block'; elem.style.zIndex = Panel.zIndex++; if (callback) { callback(); } }, 50); } }; Panel.prototype.blur = function() { var elem = this.elem; elem.classList.remove(Panel.FOCUSED); if (this.is(Panel.PEEK)) { clearTimeout(elem.Tracy.displayTimeout); elem.Tracy.displayTimeout = setTimeout(function() { elem.style.display = 'none'; }, 50); } }; Panel.prototype.toFloat = function() { this.elem.classList.remove(Panel.WINDOW); this.elem.classList.remove(Panel.PEEK); this.elem.classList.add(Panel.FLOAT); this.elem.style.display = 'block'; this.reposition(); }; Panel.prototype.toPeek = function() { this.elem.classList.remove(Panel.WINDOW); this.elem.classList.remove(Panel.FLOAT); this.elem.classList.add(Panel.PEEK); this.elem.style.display = 'none'; localStorage.removeItem(this.id); // delete position }; Panel.prototype.toWindow = function() { var offset = getOffset(this.elem); offset.left += typeof window.screenLeft === 'number' ? window.screenLeft : (window.screenX + 10); offset.top += typeof window.screenTop === 'number' ? window.screenTop : (window.screenY + 50); var win = window.open('', this.id.replace(/-/g, '_'), 'left=' + offset.left + ',top=' + offset.top + ',width=' + this.elem.offsetWidth + ',height=' + (this.elem.offsetHeight + 15) + ',resizable=yes,scrollbars=yes'); if (!win) { return; } var doc = win.document; doc.write('
¤ ×
      ';?>
    • ',trim($panel['tab']),'';endif?>
    • ×

Dumps

dumps

Errors

$count):list($file,$line,$message)=explode('|',$item,3)?>
1?' errors':' error'?> cpuUsage)&&$this->time){foreach(getrusage()as$key=>$val){$this->cpuUsage[$key]-=$val;}$userUsage=-round(($this->cpuUsage['ru_utime.tv_sec']*1e6+$this->cpuUsage['ru_utime.tv_usec'])/$this->time/10000);$systemUsage=-round(($this->cpuUsage['ru_stime.tv_sec']*1e6+$this->cpuUsage['ru_stime.tv_usec'])/$this->time/10000);}$info=array_filter(array('Execution time'=>str_replace(' ',' ',number_format($this->time*1000,1,'.',' ')).' ms','CPU usage user + system'=>isset($userUsage)?(int)$userUsage.' % + '.(int)$systemUsage.' %':NULL,'Peak of allocated memory'=>str_replace(' ',' ',number_format(memory_get_peak_usage()/1000000,2,'.',' ')).' MB','Included files'=>count(get_included_files()),'Classes + interfaces + traits'=>count(get_declared_classes()).' + '.count(get_declared_interfaces()).' + '.(PHP_VERSION_ID>=50400?count(get_declared_traits()):'0'),'Your IP'=>isset($_SERVER['REMOTE_ADDR'])?$_SERVER['REMOTE_ADDR']:NULL,'Server IP'=>isset($_SERVER['SERVER_ADDR'])?$_SERVER['SERVER_ADDR']:NULL,'HHVM'=>defined('HHVM_VERSION')?HHVM_VERSION:NULL,'PHP'=>PHP_VERSION,'Xdebug'=>extension_loaded('xdebug')?phpversion('xdebug'):NULL,'Tracy'=>Debugger::VERSION,'Server'=>isset($_SERVER['SERVER_SOFTWARE'])?$_SERVER['SERVER_SOFTWARE']:NULL)+(array)$this->data);?>

System info

$val):?> 25):?>
time=microtime(TRUE)-Debugger::$time;?> time*1000,1,'.',' '))?> ms /** * This file is part of the Tracy (https://tracy.nette.org) */ html { overflow-y: scroll; } #tracy-bs { font: 9pt/1.5 Verdana, sans-serif; background: white; color: #333; position: absolute; z-index: 20000; left: 0; top: 0; width: 100%; text-align: left; } #tracy-bs * { font: inherit; color: inherit; background: transparent; border: none; margin: 0; padding: 0; text-align: inherit; text-indent: 0; } #tracy-bs b { font-weight: bold; } #tracy-bs i { font-style: italic; } #tracy-bs a { text-decoration: none; color: #328ADC; padding: 2px 4px; margin: -2px -4px; } #tracy-bs a:hover, #tracy-bs a:active, #tracy-bs a:focus { color: #085AA3; } #tracy-bs-toggle { position: absolute; right: .5em; top: .5em; text-decoration: none; background: #CD1818; color: white !important; padding: 3px; } #tracy-bs-error { background: #CD1818; color: white; font: 13pt/1.5 Verdana, sans-serif !important; } #tracy-bs-error a { color: white !important; opacity: 0; font-size: .7em; } #tracy-bs-error:hover a { opacity: .6; } #tracy-bs-error a:hover { opacity: 1; } #tracy-bs-ie-warning { background: black; margin: 1em; padding: .5em; text-align: center; } #tracy-bs h1 { font-size: 15pt; font-weight: normal; text-shadow: 1px 1px 2px rgba(0, 0, 0, .3); margin: .7em 0; } #tracy-bs h2 { font: 14pt/1.5 sans-serif !important; margin: .6em 0; } #tracy-bs h3 { font: bold 10pt/1.5 Verdana, sans-serif !important; margin: 1em 0; padding: 0; } #tracy-bs p, #tracy-bs pre { margin: .8em 0 } #tracy-bs pre, #tracy-bs code, #tracy-bs table { font: 9pt/1.5 Consolas, monospace !important; } #tracy-bs pre, #tracy-bs table { background: #FDF5CE; padding: .4em .7em; border: 1px dotted silver; overflow: auto; } #tracy-bs table pre { padding: 0; margin: 0; border: none; } #tracy-bs table { border-collapse: collapse; width: 100%; } #tracy-bs td, #tracy-bs th { vertical-align: top; text-align: left; padding: 2px 6px; border: 1px solid #e6dfbf; } #tracy-bs th { font-weight: bold; } #tracy-bs tr > :first-child { width: 20%; } #tracy-bs tr:nth-child(2n), #tracy-bs tr:nth-child(2n) pre { background-color: #F7F0CB; } #tracy-bs ol { margin: 1em 0; padding-left: 2.5em; } #tracy-bs ul { font: 7pt/1.5 Verdana, sans-serif !important; padding: 2em 4em; margin: 1em 0 0; color: #777; background: #F6F5F3; border-top: 1px solid #DDD; } #tracy-bs-logo a { position: absolute; bottom: 0; right: 0; width: 100px; height: 50px; background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFoAAAAUBAMAAAD/1DctAAAAMFBMVEWupZzj39rEvbTy8O3X0sz9/PvGwLu8tavQysHq6OS0rKP5+Pbd2dT29fPMxbzPx8DKErMJAAAACXBIWXMAAAsTAAALEwEAmpwYAAACGUlEQVQoFX3TQWgTQRQA0MWLIJJDYehBTykhG5ERTx56K1u8eEhCYtomE7x5L4iLh0ViF7egewuFFqSIYE6hIHsIYQ6CQSg9CDKn4QsNCRlB59C74J/ZNHW1+An5+bOPyf6/s46oz2P+A0yIeZZ2ieEHi6TOnLKTxvWq+b52mxlVO3xnM1s7xLX1504XQH65OnW2dBqn7cCkYsFsfYsWpyY/2salmFTpEyzeR8zosYqMdiPDXdyU52K1wgEa/SjGpdEwUAxqvRfckQCDOyFearsEHe2grvkh/cFAHKvdtI3lcVceKQIOFpv+FOZaNPQBwJZLPp+hfrvT5JZXaUFsR8zqQc9qSgAharkfS5M/5F6nGJJAtXq/eLr3ucZpHccSxOOIPaQhtHohpCH2Xu6rLmQ0djnr4/+J3C6v+AW8/XWYxwYNdlhWj/P5fPSTQwVr0T9lGxdaBCqErNZaqYnEwbkjEB3NasGF3lPdrHa1nnxNOMgj0+neePUPjd2v/qVvUv29ifvc19huQ48qwXShy/9o8o3OSk0cs37mOFd0Ydgvsf/oZEnPVtggfd66lORn9mDyyzXU13SRtH2L6aR5T/snGAcZPfAXz5J1YlJWBEuxdMYqQecpBrlM49xAbmqyHA+xlA1FxBtqT2xmJoNXZlIt74ZBLeJ9ZGDqByNI7p543idzJ23vXEv7IgnsxiS+eNtwNbFdLq7+Bi4wQ0I4SVb9AAAAAElFTkSuQmCC') no-repeat; opacity: .6; padding: 0; margin: 0; } #tracy-bs-logo a:hover, #tracy-bs-logo a:active, #tracy-bs-logo a:focus { opacity: 1; transition: opacity 0.1s; } #tracy-bs div.panel { padding: 1px 25px; } #tracy-bs div.inner { background: #F4F3F1; padding: .1em 1em 1em; border-radius: 8px; } #tracy-bs .outer { overflow: auto; } /* source code */ #tracy-bs pre.php div { min-width: 100%; float: left; white-space: pre; } #tracy-bs .highlight { background: #CD1818; color: white; font-weight: bold; font-style: normal; display: block; padding: 0 .4em; margin: 0 -.4em; } #tracy-bs .line { color: #9F9C7F; font-weight: normal; font-style: normal; } #tracy-bs pre:hover span[title] { border-bottom: 1px solid rgba(0, 0, 0, 0.2); } #tracy-bs a[href^=editor\:] { color: inherit; border-bottom: 1px dotted rgba(0, 0, 0, .3); } #tracy-bs span[data-tracy-href] { border-bottom: 1px dotted rgba(0, 0, 0, .3); } /* toggle */ html.tracy-js #tracy-bs .tracy-collapsed { display: none; } html.tracy-js #tracy-bs .tracy-toggle.tracy-collapsed { display: inline; } #tracy-bs .tracy-toggle { cursor: pointer; } #tracy-bs .tracy-toggle:after { content: " ▼"; opacity: .4; } #tracy-bs .tracy-toggle.tracy-collapsed:after { content: " ►"; opacity: .4; } /* dump */ #tracy-bs .tracy-dump-array, #tracy-bs .tracy-dump-object { color: #C22; } #tracy-bs .tracy-dump-string { color: #35D; } #tracy-bs .tracy-dump-number { color: #090; } #tracy-bs .tracy-dump-null, #tracy-bs .tracy-dump-bool { color: #850; } #tracy-bs .tracy-dump-visibility, #tracy-bs .tracy-dump-hash { font-size: 85%; color: #998; } #tracy-bs .tracy-dump-indent { display: none; } #tracy-bs pre.tracy-dump div { padding-left: 3ex; } #tracy-bs pre.tracy-dump div div { border-left: 1px solid rgba(0, 0, 0, .1); margin-left: .5ex; } #tracy-bs .caused { float: right; padding: .3em .6em; background: #df8075; border-radius: 0 0 0 8px; white-space: nowrap; } #tracy-bs .caused a { color: white; }/** * This file is part of the Tracy (https://tracy.nette.org) */ (function(){ document.body.appendChild(document.getElementById('tracy-bs')); for (var i = 0, styles = []; i < document.styleSheets.length; i++) { var style = document.styleSheets[i]; if (!style.ownerNode.classList.contains('tracy-debug')) { style.oldDisabled = style.disabled; style.disabled = true; styles.push(style); } } document.getElementById('tracy-bs-toggle').addEventListener('click', function(e) { var collapsed = this.classList.contains('tracy-collapsed'); for (i = 0; i < styles.length; i++) { styles[i].disabled = collapsed ? true : styles[i].oldDisabled; } }); document.addEventListener('keyup', function(e) { if (e.keyCode === 27 && !e.shiftKey && !e.altKey && !e.ctrlKey && !e.metaKey) { // ESC document.getElementById('tracy-bs-toggle').click(); } }); })();getCode()?' #'.$exception->getCode():'';?>
<?php echo htmlspecialchars($title.': '.$exception->getMessage().$code,ENT_IGNORE,'UTF-8')?> getPrevious()):?>
getMessage()):?>

getMessage()?:$title.$code,ENT_IGNORE,'UTF-8')?> getMessage()))?>" target="_blank" rel="noreferrer noopener">search► skip error►

getPrevious()):?>
>

Caused by

getCode()?' #'.$ex->getCode():''),ENT_NOQUOTES,'UTF-8')?>

getMessage(),ENT_IGNORE,'UTF-8')?>

getTrace();$expanded=NULL?> getSeverity(),array(E_USER_NOTICE,E_USER_WARNING,E_USER_DEPRECATED)))&&$this->isCollapsed($ex->getFile())){foreach($stack as$key=>$row){if(isset($row['file'])&&!$this->isCollapsed($row['file'])){$expanded=$key;break;}}}?>

Source file

File: getFile(),$ex->getLine())?>

getFile())):?>getFile(),$ex->getLine(),15,$ex instanceof\ErrorException&&isset($ex->context)?$ex->context:NULL)?>

Call stack

    $row):?>
  1. inner-code source  ";if(isset($row['class']))echo htmlspecialchars($row['class'].$row['type'],ENT_NOQUOTES,'UTF-8');if(isset($row['object']))echo'';echo htmlspecialchars($row['function'],ENT_NOQUOTES,'UTF-8'),'(';if(!empty($row['args'])):?>arguments)

    TRUE))?>
    getParameters();}catch(\Exception$e){$params=array();}foreach($row['args']as$k=>$v){echo'\n";}?>
    ',htmlspecialchars(isset($params[$k])?'$'.$params[$k]->name:"#$k",ENT_IGNORE,'UTF-8'),'';echo Dumper::toHtml($v,array(Dumper::LOCATION=>Dumper::LOCATION_CLASS,Dumper::LIVE=>TRUE));echo"
context)&&is_array($ex->context)):?>

Variables

context as$k=>$v){echo'\n";}?>
$',htmlspecialchars($k,ENT_IGNORE,'UTF-8'),'',Dumper::toHtml($v,array(Dumper::LOCATION=>Dumper::LOCATION_CLASS,Dumper::LIVE=>TRUE)),"
getPrevious());?>
'?> count((array)new\Exception)):?>

Exception

Dumper::LOCATION_CLASS,Dumper::LIVE=>TRUE))?>

Environment

$_SERVER

$v)echo'\n";?>
',htmlspecialchars($k,ENT_IGNORE,'UTF-8'),'',Dumper::toHtml($v),"

$_SESSION

empty

$v)echo'\n";?>
',htmlspecialchars($k,ENT_IGNORE,'UTF-8'),'',$k==='__NF'?'Nette Session':Dumper::toHtml($v,array(Dumper::LOCATION=>Dumper::LOCATION_CLASS,Dumper::LIVE=>TRUE)),"

Nette Session

$v)echo'\n";?>
',htmlspecialchars($k,ENT_IGNORE,'UTF-8'),'',Dumper::toHtml($v,array(Dumper::LOCATION=>Dumper::LOCATION_CLASS,Dumper::LIVE=>TRUE)),"

Constants

$v){echo'';echo'\n";}?>
',htmlspecialchars($k,ENT_IGNORE,'UTF-8'),'',Dumper::toHtml($v),"

Included files ()

\n";}?>
',htmlspecialchars($v,ENT_IGNORE,'UTF-8'),"

Configuration options

|.+\z#s','',ob_get_clean())?>

HTTP request

Headers

$v)echo'\n";?>
',htmlspecialchars($k,ENT_IGNORE,'UTF-8'),'',htmlspecialchars($v,ENT_IGNORE,'UTF-8'),"

$

empty

$v)echo'\n";?>
',htmlspecialchars($k,ENT_IGNORE,'UTF-8'),'',Dumper::toHtml($v),"

HTTP response

Headers

';?>

no headers

  • Report generated at
Server Error

Server Error

We're sorry! The server encountered an internal error and was unable to complete your request. Please try again later.

error 500
Tracy is unable to log error.

/** * This file is part of the Tracy (https://tracy.nette.org) */ /* toggle */ .tracy-collapsed { display: none; } .tracy-toggle.tracy-collapsed { display: inline; } .tracy-toggle { cursor: pointer; } .tracy-toggle:after { content: " ▼"; opacity: .4; } .tracy-toggle.tracy-collapsed:after { content: " ►"; } /* dump */ pre.tracy-dump { text-align: left; color: #444; background: white; } pre.tracy-dump div { padding-left: 3ex; } pre.tracy-dump div div { border-left: 1px solid rgba(0, 0, 0, .1); margin-left: .5ex; } .tracy-dump-array, .tracy-dump-object { color: #C22; } .tracy-dump-string { color: #35D; } .tracy-dump-number { color: #090; } .tracy-dump-null, .tracy-dump-bool { color: #850; } .tracy-dump-visibility, .tracy-dump-hash { font-size: 85%; color: #999; } .tracy-dump-indent { display: none; } span[data-tracy-href] { border-bottom: 1px dotted rgba(0, 0, 0, .2); }/** * This file is part of the Tracy (https://tracy.nette.org) */ (function() { var COLLAPSE_COUNT = 7, COLLAPSE_COUNT_TOP = 14; Tracy = window.Tracy || {}; Tracy.Dumper = Tracy.Dumper || {}; Tracy.Dumper.init = function(repository) { if (repository) { [].forEach.call(document.querySelectorAll('.tracy-dump[data-tracy-dump]'), function(el) { try { el.appendChild(build(JSON.parse(el.getAttribute('data-tracy-dump')), repository, el.classList.contains('tracy-collapsed'))); el.classList.remove('tracy-collapsed'); el.removeAttribute('data-tracy-dump'); } catch (e) { if (!(e instanceof UnknownEntityException)) { throw e; } } }); } if (this.inited) { return; } this.inited = true; document.body.addEventListener('click', function(e) { var link; // enables & ctrl key if (e.ctrlKey && (link = closest(e.target, '[data-tracy-href]'))) { location.href = link.getAttribute('data-tracy-href'); return false; } if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) { return; } // enables or toggling if (link = closest(e.target, '.tracy-toggle')) { var collapsed = link.classList.contains('tracy-collapsed'), ref = link.getAttribute('data-tracy-ref') || link.getAttribute('href', 2), dest = link; if (!ref || ref === '#') { ref = '+'; } else if (ref.substr(0, 1) === '#') { dest = document; } ref = ref.match(/(\^\s*([^+\s]*)\s*)?(\+\s*(\S*)\s*)?(.*)/); dest = ref[1] ? closest(dest.parentNode, ref[2]) : dest; dest = ref[3] ? closest(dest.nextElementSibling, ref[4], 'nextElementSibling') : dest; dest = ref[5] ? dest.querySelector(ref[5]) : dest; link.classList.toggle('tracy-collapsed', !collapsed); dest.classList.toggle('tracy-collapsed', !collapsed); e.preventDefault(); } }); }; var build = function(data, repository, collapsed, parentIds) { var type = data === null ? 'null' : typeof data, collapseCount = typeof collapsed === 'undefined' ? COLLAPSE_COUNT_TOP : COLLAPSE_COUNT; if (type === 'null' || type === 'string' || type === 'number' || type === 'boolean') { data = type === 'string' ? '"' + data + '"' : (data + '').toUpperCase(); return createEl(null, null, [ createEl( 'span', {'class': 'tracy-dump-' + type.replace('ean', '')}, [data + '\n'] ) ]); } else if (Array.isArray(data)) { return buildStruct([ createEl('span', {'class': 'tracy-dump-array'}, ['array']), ' (' + (data[0] && data.length || '') + ')' ], ' [ ... ]', data[0] === null ? null : data, collapsed === true || data.length >= collapseCount, repository, parentIds ); } else if (type === 'object' && data.number) { return createEl(null, null, [ createEl('span', {'class': 'tracy-dump-number'}, [data.number + '\n']) ]); } else if (type === 'object' && data.type) { return createEl(null, null, [ createEl('span', null, [data.type + '\n']) ]); } else if (type === 'object') { var id = data.object || data.resource, object = repository[id]; if (!object) { throw new UnknownEntityException; } parentIds = parentIds || []; recursive = parentIds.indexOf(id) > -1; parentIds.push(id); return buildStruct([ createEl('span', { 'class': data.object ? 'tracy-dump-object' : 'tracy-dump-resource', title: object.editor ? 'Declared in file ' + object.editor.file + ' on line ' + object.editor.line : null, 'data-tracy-href': object.editor ? object.editor.url : null }, [object.name]), ' ', createEl('span', {'class': 'tracy-dump-hash'}, ['#' + id]) ], ' { ... }', object.items, collapsed === true || recursive || (object.items && object.items.length >= collapseCount), repository, parentIds ); } }; var buildStruct = function(span, ellipsis, items, collapsed, repository, parentIds) { var res, toggle, div, handler; if (!items || !items.length) { span.push(!items || items.length ? ellipsis + '\n' : '\n'); return createEl(null, null, span); } res = createEl(null, null, [ toggle = createEl('span', {'class': collapsed ? 'tracy-toggle tracy-collapsed' : 'tracy-toggle'}, span), '\n', div = createEl('div', {'class': collapsed ? 'tracy-collapsed' : ''}) ]); if (collapsed) { toggle.addEventListener('click', handler = function() { toggle.removeEventListener('click', handler); createItems(div, items, repository, parentIds); }); } else { createItems(div, items, repository, parentIds); } return res; }; var createEl = function(el, attrs, content) { if (!(el instanceof Node)) { el = el ? document.createElement(el) : document.createDocumentFragment(); } for (var id in attrs || {}) { if (attrs[id] !== null) { el.setAttribute(id, attrs[id]); } } content = content || []; for (id = 0; id < content.length; id++) { var child = content[id]; if (child !== null) { el.appendChild(child instanceof Node ? child : document.createTextNode(child)); } } return el; }; var createItems = function(el, items, repository, parentIds) { for (var i = 0; i < items.length; i++) { var vis = items[i][2]; createEl(el, null, [ createEl('span', {'class': 'tracy-dump-key'}, [items[i][0]]), vis ? ' ' : null, vis ? createEl('span', {'class': 'tracy-dump-visibility'}, [vis === 1 ? 'protected' : 'private']) : null, ' => ', build(items[i][1], repository, null, parentIds) ]); } }; var UnknownEntityException = function() {}; // finds closing maching element var closest = function(el, selector, func) { var matches = el.matches || el.matchesSelector || el.msMatchesSelector || el.mozMatchesSelector || el.webkitMatchesSelector || el.oMatchesSelector; while (el && selector && !(el.nodeType === 1 && matches.call(el, selector))) { el = el[func || 'parentNode']; } return el; }; })();panels[$id]));}$this->panels[$id]=$panel;return$this;}/** @return IBarPanel|NULL **/public function getPanel($id){return isset($this->panels[$id])?$this->panels[$id]:NULL;}/** @return void **/public function render(){@session_start();$session=&$_SESSION['__NF']['tracybar-2.3'];$redirect=preg_match('#^Location:#im',implode("\n",headers_list()));if($redirect){Dumper::fetchLiveData();Dumper::$livePrefix=count($session).'p';}$obLevel=ob_get_level();$panels=array();foreach($this->panels as$id=>$panel){$idHtml=preg_replace('#[^a-z0-9]+#i','-',$id);try{$tab=(string)$panel->getTab();$panelHtml=$tab?(string)$panel->getPanel():NULL;if($tab&&$panel instanceof\Nette\Diagnostics\IBarPanel){$panelHtml=preg_replace('~(["\'.\s#])nette-(debug|inner|collapsed|toggle|toggle-collapsed)(["\'\s])~','$1tracy-$2$3',$panelHtml);$panelHtml=str_replace('tracy-toggle-collapsed','tracy-toggle tracy-collapsed',$panelHtml);}$panels[]=array('id'=>$idHtml,'tab'=>$tab,'panel'=>$panelHtml);}catch(\Throwable$e){}catch(\Exception$e){}if(isset($e)){$panels[]=array('id'=>"error-$idHtml",'tab'=>"Error in $id",'panel'=>'

Error: '.$id.'

'.nl2br(htmlSpecialChars($e,ENT_IGNORE,'UTF-8')).'
');while(ob_get_level()>$obLevel){ob_end_clean();}}}if($redirect){$session[]=array('panels'=>$panels,'liveData'=>Dumper::fetchLiveData());return;}$liveData=Dumper::fetchLiveData();foreach(array_reverse((array)$session)as$reqId=>$info){$panels[]=array('tab'=>'previous','panel'=>NULL,'previous'=>TRUE);foreach($info['panels']as$panel){$panel['id'].='-'.$reqId;$panels[]=$panel;}$liveData+=$info['liveData'];}$session=NULL;require __DIR__.'/assets/Bar/bar.phtml';}}collapsePaths[]=preg_match('#(.+/vendor)/tracy/tracy/src/Tracy$#',strtr(__DIR__,'\\','/'),$m)?$m[1]:__DIR__;}/** @return self **/public function addPanel($panel){if(!in_array($panel,$this->panels,TRUE)){$this->panels[]=$panel;}return$this;}/** @return void **/public function render($exception){$panels=$this->panels;$info=array_filter($this->info);$source=Helpers::getSource();$sourceIsUrl=preg_match('#^https?://#',$source);$title=$exception instanceof\ErrorException?Helpers::errorTypeToString($exception->getSeverity()):Helpers::getClass($exception);$skipError=$sourceIsUrl&&$exception instanceof\ErrorException&&!empty($exception->skippable)?$source.(strpos($source,'?')?'&':'?').'_tracy_skip_error':NULL;require __DIR__.'/assets/BlueScreen/bluescreen.phtml';}/** @return string|NULL **/public static function highlightFile($file,$line,$lines=15,array$vars=NULL){$source=@file_get_contents($file);if($source){$source=static::highlightPhp($source,$line,$lines,$vars);if($editor=Helpers::editorUri($file,$line)){$source=substr_replace($source,' data-tracy-href="'.htmlspecialchars($editor,ENT_QUOTES,'UTF-8').'"',4,0);}return$source;}}/** @return string **/public static function highlightPhp($source,$line,$lines=15,array$vars=NULL){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));$out=$source[0];$source=str_replace('
',"\n",$source[1]);$out.=static::highlightLine($source,$line,$lines);if($vars){$out=preg_replace_callback('#">\$(\w+)( )?
#',function($m)use($vars){return array_key_exists($m[1],$vars)?'" title="'.str_replace('"','"',trim(strip_tags(Dumper::toHtml($vars[$m[1]],array(Dumper::DEPTH=>1))))).$m[0]:$m[0];},$out);}$out=str_replace(' ',' ',$out);return"
$out
";}/** @return string **/public static function highlightLine($html,$line,$lines=15){$source=explode("\n","\n".str_replace("\r\n","\n",$html));$out='';$spans=1;$start=$i=max(1,min($line,count($source)-1)-floor($lines*2/3));while(--$i>=1){if(preg_match('#.*(]*>)#',$source[$i],$m)){if($m[1]!=='
'){$spans++;$out.=$m[1];}break;}}$source=array_slice($source,$start,$lines,TRUE);end($source);$numWidth=strlen((string)key($source));foreach($source as$n=>$s){$spans+=substr_count($s,']+>#',$s,$tags);if($n==$line){$out.=sprintf("%{$numWidth}s: %s\n%s",$n,strip_tags($s),implode('',$tags[0]));}else{$out.=sprintf("%{$numWidth}s: %s\n",$n,$s);}}$out.=str_repeat('',$spans).'';return$out;}/** @return bool **/public function isCollapsed($file){$file=strtr($file,'\\','/').'/';foreach($this->collapsePaths as$path){$path=strtr($path,'\\','/').'/';if(strncmp($file,$path,strlen($path))===0){return TRUE;}}return FALSE;}}render();}}/** @return void **/public static function exceptionHandler($exception,$exit=TRUE){if(!self::$reserved){return;}self::$reserved=NULL;if(!headers_sent()){$protocol=isset($_SERVER['SERVER_PROTOCOL'])?$_SERVER['SERVER_PROTOCOL']:'HTTP/1.1';$code=isset($_SERVER['HTTP_USER_AGENT'])&&strpos($_SERVER['HTTP_USER_AGENT'],'MSIE ')!==FALSE?503:500;header("$protocol $code",TRUE,$code);if(self::isHtmlMode()){header('Content-Type: text/html; charset=UTF-8');}}Helpers::improveException($exception);self::removeOutputBuffers(TRUE);if(self::$productionMode){try{self::log($exception,self::EXCEPTION);}catch(\Throwable$e){}catch(\Exception$e){}if(self::isHtmlMode()){$logged=empty($e);require self::$errorTemplate?:__DIR__.'/assets/Debugger/error.500.phtml';}elseif(PHP_SAPI==='cli'){fwrite(STDERR,'ERROR: application encountered an error and can not continue. '.(isset($e)?"Unable to log error.\n":"Error was logged.\n"));}}elseif(!connection_aborted()&&self::isHtmlMode()){self::getBlueScreen()->render($exception);if(self::$showBar){self::getBar()->render();}}else{self::fireLog($exception);$s=get_class($exception).($exception->getMessage()===''?'':': '.$exception->getMessage()).' in '.$exception->getFile().':'.$exception->getLine()."\nStack trace:\n".$exception->getTraceAsString();try{$file=self::log($exception,self::EXCEPTION);if($file&&!headers_sent()){header("X-Tracy-Error-Log: $file");}echo"$s\n".($file?"(stored in $file)\n":'');if($file&&self::$browser){exec(self::$browser.' '.escapeshellarg($file));}}catch(\Throwable$e){echo"$s\nUnable to log error: {$e->getMessage()}\n";}catch(\Exception$e){echo"$s\nUnable to log error: {$e->getMessage()}\n";}}try{$e=NULL;foreach(self::$onFatalError as$handler){call_user_func($handler,$exception);}}catch(\Throwable$e){}catch(\Exception$e){}if($e){try{self::log($e,self::EXCEPTION);}catch(\Throwable$e){}catch(\Exception$e){}}if($exit){exit($exception instanceof\Error?255:254);}}/** @return bool FALSE to call normal error handler, NULL otherwise **/public static function errorHandler($severity,$message,$file,$line,$context){if(self::$scream){error_reporting(E_ALL|E_STRICT);}if($severity===E_RECOVERABLE_ERROR||$severity===E_USER_ERROR){if(Helpers::findTrace(debug_backtrace(PHP_VERSION_ID>=50306?DEBUG_BACKTRACE_IGNORE_ARGS:FALSE),'*::__toString')){$previous=isset($context['e'])&&($context['e']instanceof\Exception||$context['e']instanceof\Throwable)?$context['e']:NULL;$e=new ErrorException($message,0,$severity,$file,$line,$previous);$e->context=$context;self::exceptionHandler($e);}$e=new ErrorException($message,0,$severity,$file,$line);$e->context=$context;throw$e;}elseif(($severity&error_reporting())!==$severity){return FALSE;}elseif(self::$productionMode&&($severity&self::$logSeverity)===$severity){$e=new ErrorException($message,0,$severity,$file,$line);$e->context=$context;try{self::log($e,self::ERROR);}catch(\Throwable$e){}catch(\Exception$foo){}return NULL;}elseif(!self::$productionMode&&!isset($_GET['_tracy_skip_error'])&&(is_bool(self::$strictMode)?self::$strictMode:((self::$strictMode&$severity)===$severity))){$e=new ErrorException($message,0,$severity,$file,$line);$e->context=$context;$e->skippable=TRUE;self::exceptionHandler($e);}$message='PHP '.Helpers::errorTypeToString($severity).": $message";$count=&self::getBar()->getPanel('Tracy:errors')->data["$file|$line|$message"];if($count++){return NULL;}elseif(self::$productionMode){try{self::log("$message in $file:$line",self::ERROR);}catch(\Throwable$e){}catch(\Exception$foo){}return NULL;}else{self::fireLog(new ErrorException($message,0,$severity,$file,$line));return self::isHtmlMode()?NULL:FALSE;}}private static function isHtmlMode(){return empty($_SERVER['HTTP_X_REQUESTED_WITH'])&&PHP_SAPI!=='cli'&&!preg_match('#^Content-Type: (?!text/html)#im',implode("\n",headers_list()));}private static function removeOutputBuffers($errorOccurred){while(ob_get_level()>self::$obLevel){$tmp=ob_get_status(TRUE);$status=end($tmp);if(in_array($status['name'],array('ob_gzhandler','zlib output compression'))){break;}$fnc=$status['chunk_size']||!$errorOccurred?'ob_end_flush':'ob_end_clean';if(!@$fnc()){break;}}}/** @return BlueScreen **/public static function getBlueScreen(){if(!self::$blueScreen){self::$blueScreen=new BlueScreen;self::$blueScreen->info=array('PHP '.PHP_VERSION,isset($_SERVER['SERVER_SOFTWARE'])?$_SERVER['SERVER_SOFTWARE']:NULL,'Tracy '.self::VERSION);}return self::$blueScreen;}/** @return Bar **/public static function getBar(){if(!self::$bar){self::$bar=new Bar;self::$bar->addPanel($info=new DefaultBarPanel('info'),'Tracy:info');$info->cpuUsage=self::$cpuUsage;self::$bar->addPanel(new DefaultBarPanel('errors'),'Tracy:errors');}return self::$bar;}/** @return void **/public static function setLogger(ILogger$logger){self::$logger=$logger;}/** @return ILogger **/public static function getLogger(){if(!self::$logger){self::$logger=new Logger(self::$logDirectory,self::$email,self::getBlueScreen());self::$logger->directory=&self::$logDirectory;self::$logger->email=&self::$email;}return self::$logger;}/** @return ILogger **/public static function getFireLogger(){if(!self::$fireLogger){self::$fireLogger=new FireLogger;}return self::$fireLogger;}/** @return mixed variable itself or dump **/public static function dump($var,$return=FALSE){if($return){ob_start(function(){});Dumper::dump($var,array(Dumper::DEPTH=>self::$maxDepth,Dumper::TRUNCATE=>self::$maxLen));return ob_get_clean();}elseif(!self::$productionMode){Dumper::dump($var,array(Dumper::DEPTH=>self::$maxDepth,Dumper::TRUNCATE=>self::$maxLen,Dumper::LOCATION=>self::$showLocation));}return$var;}/** @return float elapsed seconds **/public static function timer($name=NULL){static$time=array();$now=microtime(TRUE);$delta=isset($time[$name])?$now-$time[$name]:0;$time[$name]=$now;return$delta;}/** @return mixed variable itself **/public static function barDump($var,$title=NULL,array$options=NULL){if(!self::$productionMode){static$panel;if(!$panel){self::getBar()->addPanel($panel=new DefaultBarPanel('dumps'));}$panel->data[]=array('title'=>$title,'dump'=>Dumper::toHtml($var,(array)$options+array(Dumper::DEPTH=>self::$maxDepth,Dumper::TRUNCATE=>self::$maxLen,Dumper::LOCATION=>self::$showLocation?:Dumper::LOCATION_CLASS|Dumper::LOCATION_SOURCE)));}return$var;}/** @return mixed **/public static function log($message,$priority=ILogger::INFO){return self::getLogger()->log($message,$priority);}/** @return bool was successful? **/public static function fireLog($message){if(!self::$productionMode){return self::getFireLogger()->log($message);}}/** @return bool **/public static function detectDebugMode($list=NULL){$addr=isset($_SERVER['REMOTE_ADDR'])?$_SERVER['REMOTE_ADDR']:php_uname('n');$secret=isset($_COOKIE[self::COOKIE_SECRET])&&is_string($_COOKIE[self::COOKIE_SECRET])?$_COOKIE[self::COOKIE_SECRET]: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 in_array($addr,$list,TRUE)||in_array("$secret@$addr",$list,TRUE);}}id=$id;}/** @return string **/public function getTab(){ob_start(function(){});$data=$this->data;require __DIR__."/assets/Bar/{$this->id}.tab.phtml";return ob_get_clean();}/** @return string **/public function getPanel(){ob_start(function(){});if(is_file(__DIR__."/assets/Bar/{$this->id}.panel.phtml")){$data=$this->data;require __DIR__."/assets/Bar/{$this->id}.panel.phtml";}return ob_get_clean();}}'1;33','null'=>'1;33','number'=>'1;32','string'=>'1;36','array'=>'1;31','key'=>'1;37','object'=>'1;31','visibility'=>'1;30','resource'=>'1;37','indent'=>'1;30');public static$resources=array('stream'=>'stream_get_meta_data','stream-context'=>'stream_context_get_options','curl'=>'curl_getinfo');public static$objectExporters=array('Closure'=>'Tracy\Dumper::exportClosure','SplFileInfo'=>'Tracy\Dumper::exportSplFileInfo','SplObjectStorage'=>'Tracy\Dumper::exportSplObjectStorage','__PHP_Incomplete_Class'=>'Tracy\Dumper::exportPhpIncompleteClass');public static$livePrefix;private static$liveStorage=array();/** @return mixed variable **/public static function dump($var,array$options=NULL){if(PHP_SAPI!=='cli'&&!preg_match('#^Content-Type: (?!text/html)#im',implode("\n",headers_list()))){echo self::toHtml($var,$options);}elseif(self::detectColors()){echo self::toTerminal($var,$options);}else{echo self::toText($var,$options);}return$var;}/** @return string **/public static function toHtml($var,array$options=NULL){$options=(array)$options+array(self::DEPTH=>4,self::TRUNCATE=>150,self::COLLAPSE=>14,self::COLLAPSE_COUNT=>7,self::OBJECT_EXPORTERS=>NULL);$loc=&$options[self::LOCATION];$loc=$loc===TRUE?~0:(int)$loc;$options[self::OBJECT_EXPORTERS]=(array)$options[self::OBJECT_EXPORTERS]+self::$objectExporters;uksort($options[self::OBJECT_EXPORTERS],function($a,$b){return$b===''||(class_exists($a,FALSE)&&($rc=new\ReflectionClass($a))&&$rc->isSubclassOf($b))?-1:1;});$live=!empty($options[self::LIVE])&&$var&&(is_array($var)||is_object($var)||is_resource($var));list($file,$line,$code)=$loc?self::findLocation():NULL;$locAttrs=$file&&$loc&self::LOCATION_SOURCE?Helpers::formatHtml(' title="%in file % on line %" data-tracy-href="%"',"$code\n",$file,$line,Helpers::editorUri($file,$line)):NULL;return'
":'>').($live?'':self::dumpVar($var,$options)).($file&&$loc&self::LOCATION_LINK?'in '.Helpers::editorLink($file,$line).'':'')."
\n";}/** @return string **/public static function toText($var,array$options=NULL){return htmlspecialchars_decode(strip_tags(self::toHtml($var,$options)),ENT_QUOTES);}/** @return string **/public static function toTerminal($var,array$options=NULL){return htmlspecialchars_decode(strip_tags(preg_replace_callback('#|#',function($m){return"\033[".(isset($m[1],Dumper::$terminalColors[$m[1]])?Dumper::$terminalColors[$m[1]]:'0').'m';},self::toHtml($var,$options))),ENT_QUOTES);}/** @return string **/private static function dumpVar(&$var,array$options,$level=0){if(method_exists(__CLASS__,$m='dump'.gettype($var))){return self::$m($var,$options,$level);}else{return"unknown type\n";}}private static function dumpNull(){return"NULL\n";}private static function dumpBoolean(&$var){return''.($var?'TRUE':'FALSE')."\n";}private static function dumpInteger(&$var){return"$var\n";}private static function dumpDouble(&$var){$var=is_finite($var)?($tmp=json_encode($var)).(strpos($tmp,'.')===FALSE?'.0':''):str_replace('.0','',var_export($var,TRUE));return"$var\n";}private static function dumpString(&$var,$options){return'"'.htmlspecialchars(self::encodeString($var,$options[self::TRUNCATE]),ENT_NOQUOTES,'UTF-8').'"'.(strlen($var)>1?' ('.strlen($var).')':'')."\n";}private static function dumpArray(&$var,$options,$level){static$marker;if($marker===NULL){$marker=uniqid("\x00",TRUE);}$out='array (';if(empty($var)){return$out.")\n";}elseif(isset($var[$marker])){return$out.(count($var)-1).") [ RECURSION ]\n";}elseif(!$options[self::DEPTH]||$level<$options[self::DEPTH]){$collapsed=$level?count($var)>=$options[self::COLLAPSE_COUNT]:(is_int($options[self::COLLAPSE])?count($var)>=$options[self::COLLAPSE]:$options[self::COLLAPSE]);$out=''.$out.count($var).")\n';$var[$marker]=TRUE;foreach($var as$k=>&$v){if($k!==$marker){$k=preg_match('#^\w{1,50}\z#',$k)?$k:'"'.htmlspecialchars(self::encodeString($k,$options[self::TRUNCATE]),ENT_NOQUOTES,'UTF-8').'"';$out.=' '.str_repeat('| ',$level).''.''.$k.' => '.self::dumpVar($v,$options,$level+1);}}unset($var[$marker]);return$out.'
';}else{return$out.count($var).") [ ... ]\n";}}private static function dumpObject(&$var,$options,$level){$fields=self::exportObject($var,$options[self::OBJECT_EXPORTERS]);$editor=NULL;if($options[self::LOCATION]&self::LOCATION_CLASS){$rc=$var instanceof\Closure?new\ReflectionFunction($var):new\ReflectionClass($var);$editor=Helpers::editorUri($rc->getFileName(),$rc->getStartLine());}$out='getFileName(),$rc->getStartLine(),$editor):'').'>'.htmlspecialchars(Helpers::getClass($var)).' #'.substr(md5(spl_object_hash($var)),0,4).'';static$list=array();if(empty($fields)){return$out."\n";}elseif(in_array($var,$list,TRUE)){return$out." { RECURSION }\n";}elseif(!$options[self::DEPTH]||$level<$options[self::DEPTH]||$var instanceof\Closure){$collapsed=$level?count($fields)>=$options[self::COLLAPSE_COUNT]:(is_int($options[self::COLLAPSE])?count($fields)>=$options[self::COLLAPSE]:$options[self::COLLAPSE]);$out=''.$out."\n';$list[]=$var;foreach($fields as$k=>&$v){$vis='';if(isset($k[0])&&$k[0]==="\x00"){$vis=' '.($k[1]==='*'?'protected':'private').'';$k=substr($k,strrpos($k,"\x00")+1);}$k=preg_match('#^\w{1,50}\z#',$k)?$k:'"'.htmlspecialchars(self::encodeString($k,$options[self::TRUNCATE]),ENT_NOQUOTES,'UTF-8').'"';$out.=' '.str_repeat('| ',$level).''.''.$k."$vis => ".self::dumpVar($v,$options,$level+1);}array_pop($list);return$out.'';}else{return$out." { ... }\n";}}private static function dumpResource(&$var,$options,$level){$type=get_resource_type($var);$out=''.htmlSpecialChars($type,ENT_IGNORE,'UTF-8').' resource '.'#'.intval($var).'';if(isset(self::$resources[$type])){$out="$out\n
";foreach(call_user_func(self::$resources[$type],$var)as$k=>$v){$out.=' '.str_repeat('| ',$level).''.''.htmlSpecialChars($k,ENT_IGNORE,'UTF-8').' => '.self::dumpVar($v,$options,$level+1);}return$out.'
';}return"$out\n";}/** @return mixed **/private static function toJson(&$var,$options,$level=0){if(is_bool($var)||is_null($var)||is_int($var)){return$var;}elseif(is_float($var)){return is_finite($var)?(strpos($tmp=json_encode($var),'.')?$var:array('number'=>"$tmp.0")):array('type'=>(string)$var);}elseif(is_string($var)){return self::encodeString($var,$options[self::TRUNCATE]);}elseif(is_array($var)){static$marker;if($marker===NULL){$marker=uniqid("\x00",TRUE);}if(isset($var[$marker])||$level>=$options[self::DEPTH]){return array(NULL);}$res=array();$var[$marker]=TRUE;foreach($var as$k=>&$v){if($k!==$marker){$k=preg_match('#^\w{1,50}\z#',$k)?$k:'"'.self::encodeString($k,$options[self::TRUNCATE]).'"';$res[]=array($k,self::toJson($v,$options,$level+1));}}unset($var[$marker]);return$res;}elseif(is_object($var)){$obj=&self::$liveStorage[spl_object_hash($var)];if($obj&&$obj['level']<=$level){return array('object'=>$obj['id']);}if($options[self::LOCATION]&self::LOCATION_CLASS){$rc=$var instanceof\Closure?new\ReflectionFunction($var):new\ReflectionClass($var);$editor=Helpers::editorUri($rc->getFileName(),$rc->getStartLine());}static$counter=1;$obj=$obj?:array('id'=>self::$livePrefix.'0'.$counter++,'name'=>Helpers::getClass($var),'editor'=>empty($editor)?NULL:array('file'=>$rc->getFileName(),'line'=>$rc->getStartLine(),'url'=>$editor),'level'=>$level,'object'=>$var);if($level<$options[self::DEPTH]||!$options[self::DEPTH]){$obj['level']=$level;$obj['items']=array();foreach(self::exportObject($var,$options[self::OBJECT_EXPORTERS])as$k=>$v){$vis=0;if(isset($k[0])&&$k[0]==="\x00"){$vis=$k[1]==='*'?1:2;$k=substr($k,strrpos($k,"\x00")+1);}$k=preg_match('#^\w{1,50}\z#',$k)?$k:'"'.self::encodeString($k,$options[self::TRUNCATE]).'"';$obj['items'][]=array($k,self::toJson($v,$options,$level+1),$vis);}}return array('object'=>$obj['id']);}elseif(is_resource($var)){$obj=&self::$liveStorage[(string)$var];if(!$obj){$type=get_resource_type($var);$obj=array('id'=>self::$livePrefix.(int)$var,'name'=>$type.' resource');if(isset(self::$resources[$type])){foreach(call_user_func(self::$resources[$type],$var)as$k=>$v){$obj['items'][]=array($k,self::toJson($v,$options,$level+1));}}}return array('resource'=>$obj['id']);}else{return array('type'=>'unknown type');}}/** @return array **/public static function fetchLiveData(){$res=array();foreach(self::$liveStorage as$obj){$id=$obj['id'];unset($obj['level'],$obj['object'],$obj['id']);$res[$id]=$obj;}self::$liveStorage=array();return$res;}/** @return string UTF-8 **/public static function encodeString($s,$maxLength=NULL){static$table;if($table===NULL){foreach(array_merge(range("\x00","\x1F"),range("\x7F","\xFF"))as$ch){$table[$ch]='\x'.str_pad(dechex(ord($ch)),2,'0',STR_PAD_LEFT);}$table['\\']='\\\\';$table["\r"]='\r';$table["\n"]='\n';$table["\t"]='\t';}if(preg_match('#[^\x09\x0A\x0D\x20-\x7E\xA0-\x{10FFFF}]#u',$s)||preg_last_error()){if($shortened=($maxLength&&strlen($s)>$maxLength)){$s=substr($s,0,$maxLength);}$s=strtr($s,$table);}elseif($shortened=($maxLength&&strlen(utf8_decode($s))>$maxLength)){if(function_exists('iconv_substr')){$s=iconv_substr($s,0,$maxLength,'UTF-8');}else{$i=$len=0;do{if(($s[$i]<"\x80"||$s[$i]>="\xC0")&&(++$len>$maxLength)){$s=substr($s,0,$i);break;}}while(isset($s[++$i]));}}return$s.(empty($shortened)?'':' ... ');}/** @return array **/private static function exportObject($obj,array$exporters){foreach($exporters as$type=>$dumper){if(!$type||$obj instanceof$type){return call_user_func($dumper,$obj);}}return(array)$obj;}/** @return array **/private static function exportClosure(\Closure$obj){$rc=new\ReflectionFunction($obj);$res=array();foreach($rc->getParameters()as$param){$res[]='$'.$param->getName();}return array('file'=>$rc->getFileName(),'line'=>$rc->getStartLine(),'variables'=>$rc->getStaticVariables(),'parameters'=>implode(', ',$res));}/** @return array **/private static function exportSplFileInfo(\SplFileInfo$obj){return array('path'=>$obj->getPathname());}/** @return array **/private static function exportSplObjectStorage(\SplObjectStorage$obj){$res=array();foreach(clone$obj as$item){$res[]=array('object'=>$item,'data'=>$obj[$item]);}return$res;}/** @return array **/private static function exportPhpIncompleteClass(\__PHP_Incomplete_Class$obj){$info=array('className'=>NULL,'private'=>array(),'protected'=>array(),'public'=>array());foreach((array)$obj as$name=>$value){if($name==='__PHP_Incomplete_Class_Name'){$info['className']=$value;}elseif(preg_match('#^\x0\*\x0(.+)\z#',$name,$m)){$info['protected'][$m[1]]=$value;}elseif(preg_match('#^\x0(.+)\x0(.+)\z#',$name,$m)){$info['private'][$m[1].'::$'.$m[2]]=$value;}else{$info['public'][$name]=$value;}}return$info;}/** @return array [file, line, code] **/private static function findLocation(){foreach(debug_backtrace(PHP_VERSION_ID>=50306?DEBUG_BACKTRACE_IGNORE_ARGS:FALSE)as$item){if(isset($item['class'])&&$item['class']===__CLASS__){$location=$item;continue;}elseif(isset($item['function'])){try{$reflection=isset($item['class'])?new\ReflectionMethod($item['class'],$item['function']):new\ReflectionFunction($item['function']);if($reflection->isInternal()||preg_match('#\s@tracySkipLocation\s#',$reflection->getDocComment())){$location=$item;continue;}}catch(\ReflectionException$e){}}break;}if(isset($location['file'],$location['line'])&&is_file($location['file'])){$lines=file($location['file']);$line=$lines[$location['line']-1];return array($location['file'],$location['line'],trim(preg_match('#\w*dump(er::\w+)?\(.*\)#i',$line,$m)?$m[0]:$line));}}/** @return bool **/private static function detectColors(){return self::$terminalColors&&(getenv('ConEmuANSI')==='ON'||getenv('ANSICON')!==FALSE||getenv('term')==='xterm-256color'||(defined('STDOUT')&&function_exists('posix_isatty')&&posix_isatty(STDOUT)));}}array());/** @return bool was successful? **/public function log($message,$priority=self::DEBUG){if(!isset($_SERVER['HTTP_X_FIRELOGGER'])||headers_sent()){return FALSE;}$item=array('name'=>'PHP','level'=>$priority,'order'=>count($this->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||$args[0]instanceof\Throwable)){$e=array_shift($args);$trace=$e->getTrace();if(isset($trace[0]['class'])&&$trace[0]['class']==='Tracy\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 instanceof\ErrorException?'':Helpers::getClass($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']==='Tracy\Debugger'&&($trace[1]['function']==='fireLog')){unset($trace[0]);}foreach($trace 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 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;$this->payload['logs'][]=$this->jsonDump($item,-1);foreach(str_split(base64_encode(@json_encode($this->payload)),4990)as$k=>$v){header("FireLogger-de11e-$k:$v");}return TRUE;}/** @return string **/private function jsonDump(&$var,$level=0){if(is_bool($var)||is_null($var)||is_int($var)||is_float($var)){return$var;}elseif(is_string($var)){return Dumper::encodeString($var,$this->maxLength);}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<$this->maxDepth||!$this->maxDepth){$var[$marker]=TRUE;$res=array();foreach($var as$k=>&$v){if($k!==$marker){$res[$this->jsonDump($k)]=$this->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<$this->maxDepth||!$this->maxDepth){$list[]=$var;$res=array("\x00"=>'(object) '.Helpers::getClass($var));foreach($arr as$k=>&$v){if(isset($k[0])&&$k[0]==="\x00"){$k=substr($k,strrpos($k,"\x00")+1);}$res[$this->jsonDump($k)]=$this->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';}}}strlen($m[0])){$file='...'.$m[0];}$file=strtr($file,'/',DIRECTORY_SEPARATOR);return self::formatHtml('
%%%',$editor,$file.($line?":$line":''),rtrim(dirname($file),DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR,basename($file),$line?":$line":'');}else{return self::formatHtml('%',$file.($line?":$line":''));}}/** @return string **/public static function editorUri($file,$line=NULL){if(Debugger::$editor&&$file&&is_file($file)){return strtr(Debugger::$editor,array('%file'=>rawurlencode($file),'%line'=>$line?(int)$line:1));}}public static function formatHtml($mask){$args=func_get_args();return preg_replace_callback('#%#',function()use(&$args,&$count){return htmlspecialchars($args[++$count],ENT_IGNORE|ENT_QUOTES,'UTF-8');},$mask);}public static function findTrace(array$trace,$method,&$index=NULL){$m=explode('::',$method);foreach($trace 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;}}}/** @return string **/public static function getClass($obj){return current(explode("\x00",get_class($obj)));}public static function fixStack($exception){if(function_exists('xdebug_get_function_stack')){$stack=array();foreach(array_slice(array_reverse(xdebug_get_function_stack()),2,-1)as$row){$frame=array('file'=>$row['file'],'line'=>$row['line'],'function'=>isset($row['function'])?$row['function']:'*unknown*','args'=>array());if(!empty($row['class'])){$frame['type']=isset($row['type'])&&$row['type']==='dynamic'?'->':'::';$frame['class']=$row['class'];}$stack[]=$frame;}$ref=new\ReflectionProperty('Exception','trace');$ref->setAccessible(TRUE);$ref->setValue($exception,$stack);}return$exception;}public static function fixEncoding($s){if(PHP_VERSION_ID<50400){return@iconv('UTF-16','UTF-8//IGNORE',iconv('UTF-8','UTF-16//IGNORE',$s));}else{return htmlspecialchars_decode(htmlspecialchars($s,ENT_NOQUOTES|ENT_IGNORE,'UTF-8'),ENT_NOQUOTES);}}public static function errorTypeToString($type){$types=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 standards',E_DEPRECATED=>'Deprecated',E_USER_DEPRECATED=>'User Deprecated');return isset($types[$type])?$types[$type]:'Unknown error';}public static function getSource(){if(isset($_SERVER['REQUEST_URI'])){return(!empty($_SERVER['HTTPS'])&&strcasecmp($_SERVER['HTTPS'],'off')?'https://':'http://').(isset($_SERVER['HTTP_HOST'])?$_SERVER['HTTP_HOST']:'').$_SERVER['REQUEST_URI'];}else{return empty($_SERVER['argv'])?'CLI':'CLI: '.implode(' ',$_SERVER['argv']);}}public static function improveException($e){$message=$e->getMessage();if(!$e instanceof\Error&&!$e instanceof\ErrorException){}elseif(preg_match('#^Call to undefined function (\S+\\\\)?(\w+)\(#',$message,$m)){$funcs=get_defined_functions();$funcs=array_merge($funcs['internal'],$funcs['user']);$hint=self::getSuggestion($funcs,$m[1].$m[2])?:self::getSuggestion($funcs,$m[2]);$message.=", did you mean $hint()?";}elseif(preg_match('#^Call to undefined method (\S+)::(\w+)#',$message,$m)){$hint=self::getSuggestion(get_class_methods($m[1]),$m[2]);$message.=", did you mean $hint()?";}elseif(preg_match('#^Undefined variable: (\w+)#',$message,$m)&&!empty($e->context)){$hint=self::getSuggestion(array_keys($e->context),$m[1]);$message="Undefined variable $$m[1], did you mean $$hint?";}elseif(preg_match('#^Undefined property: (\S+)::\$(\w+)#',$message,$m)){$rc=new\ReflectionClass($m[1]);$items=array_diff($rc->getProperties(\ReflectionProperty::IS_PUBLIC),$rc->getProperties(\ReflectionProperty::IS_STATIC));$hint=self::getSuggestion($items,$m[2]);$message.=", did you mean $$hint?";}elseif(preg_match('#^Access to undeclared static property: (\S+)::\$(\w+)#',$message,$m)){$rc=new\ReflectionClass($m[1]);$items=array_intersect($rc->getProperties(\ReflectionProperty::IS_PUBLIC),$rc->getProperties(\ReflectionProperty::IS_STATIC));$hint=self::getSuggestion($items,$m[2]);$message.=", did you mean $$hint?";}if(isset($hint)){$ref=new\ReflectionProperty($e,'message');$ref->setAccessible(TRUE);$ref->setValue($e,$message);}}/** @return string|NULL **/public static function getSuggestion(array$items,$value){$best=NULL;$min=(strlen($value)/4+1)*10+.1;foreach(array_unique($items,SORT_REGULAR)as$item){$item=is_object($item)?$item->getName():$item;if(($len=levenshtein($item,$value,10,11,10))>0&&$len<$min){$min=$len;$best=$item;}}return$best;}}directory=$directory;$this->email=$email;$this->blueScreen=$blueScreen;$this->mailer=array($this,'defaultMailer');}/** @return string logged error filename **/public function log($message,$priority=self::INFO){if(!$this->directory){throw new\LogicException('Directory is not specified.');}elseif(!is_dir($this->directory)){throw new\RuntimeException("Directory '$this->directory' is not found or is not directory.");}$exceptionFile=$message instanceof\Exception||$message instanceof\Throwable?$this->getExceptionFile($message):NULL;$line=$this->formatLogLine($message,$exceptionFile);$file=$this->directory.'/'.strtolower($priority?:self::INFO).'.log';if(!@file_put_contents($file,$line.PHP_EOL,FILE_APPEND|LOCK_EX)){throw new\RuntimeException("Unable to write to log file '$file'. Is directory writable?");}if($exceptionFile){$this->logException($message,$exceptionFile);}if(in_array($priority,array(self::ERROR,self::EXCEPTION,self::CRITICAL),TRUE)){$this->sendEmail($message);}return$exceptionFile;}/** @return string **/protected function formatMessage($message){if($message instanceof\Exception||$message instanceof\Throwable){while($message){$tmp[]=($message instanceof\ErrorException?Helpers::errorTypeToString($message->getSeverity()).': '.$message->getMessage():Helpers::getClass($message).': '.$message->getMessage()).' in '.$message->getFile().':'.$message->getLine();$message=$message->getPrevious();}$message=implode($tmp,"\ncaused by ");}elseif(!is_string($message)){$message=Dumper::toText($message);}return trim($message);}/** @return string **/protected function formatLogLine($message,$exceptionFile=NULL){return implode(' ',array(@date('[Y-m-d H-i-s]'),preg_replace('#\s*\r?\n\s*#',' ',$this->formatMessage($message)),' @ '.Helpers::getSource(),$exceptionFile?' @@ '.basename($exceptionFile):NULL));}/** @return string **/public function getExceptionFile($exception){$dir=strtr($this->directory.'/','\\/',DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR);$hash=substr(md5(preg_replace('~(Resource id #)\d+~','$1',$exception)),0,10);foreach(new\DirectoryIterator($this->directory)as$file){if(strpos($file,$hash)){return$dir.$file;}}return$dir.'exception--'.@date('Y-m-d--H-i')."--$hash.html";}/** @return string logged error filename **/protected function logException($exception,$file=NULL){$file=$file?:$this->getExceptionFile($exception);if($handle=@fopen($file,'x')){ob_start();ob_start(function($buffer)use($handle){fwrite($handle,$buffer);},4096);$bs=$this->blueScreen?:new BlueScreen;$bs->render($exception);ob_end_flush();ob_end_clean();fclose($handle);}return$file;}/** @return void **/protected function sendEmail($message){$snooze=is_numeric($this->emailSnooze)?$this->emailSnooze:@strtotime($this->emailSnooze)-time();if($this->email&&$this->mailer&&@filemtime($this->directory.'/email-sent')+$snoozedirectory.'/email-sent','sent')){call_user_func($this->mailer,$message,implode(', ',(array)$this->email));}}/** @return void **/public function defaultMailer($message,$email){$host=preg_replace('#[^\w.-]+#','',isset($_SERVER['HTTP_HOST'])?$_SERVER['HTTP_HOST']:php_uname('n'));$parts=str_replace(array("\r\n","\n"),array("\n",PHP_EOL),array('headers'=>implode("\n",array('From: '.($this->fromEmail?:"noreply@$host"),'X-Mailer: Tracy','Content-Type: text/plain; charset=UTF-8','Content-Transfer-Encoding: 8bit'))."\n",'subject'=>"PHP: An error occurred on the server $host",'body'=>$this->formatMessage($message)."\n\nsource: ".Helpers::getSource()));mail($email,$parts['subject'],$parts['body'],$parts['headers']);}}start();}public function start(){foreach(get_included_files()as$file){if(fread(fopen($file,'r'),3)===self::BOM){$this->list[]=array($file,1,self::BOM);}}ob_start(array($this,'handler'),PHP_VERSION_ID>=50400?1:2);}public function handler($s,$phase){$trace=debug_backtrace(PHP_VERSION_ID>=50306?DEBUG_BACKTRACE_IGNORE_ARGS:FALSE);if(isset($trace[0]['file'],$trace[0]['line'])){$stack=$trace;unset($stack[0]['line'],$stack[0]['args']);$i=count($this->list);if($i&&$this->list[$i-1][3]===$stack){$this->list[$i-1][2].=$s;}else{$this->list[]=array($trace[0]['file'],$trace[0]['line'],$s,$stack);}}if($phase===PHP_OUTPUT_HANDLER_FINAL){return$this->renderHtml();}}private function renderHtml(){$res='';foreach($this->list as$item){$stack=array();foreach(array_slice($item[3],1)as$t){$t+=array('class'=>'','type'=>'','function'=>'');$stack[]="$t[class]$t[type]$t[function]()".(isset($t['file'],$t['line'])?' in '.basename($t['file']).":$t[line]":'');}$res.=Helpers::editorLink($item[0],$item[1]).' '.''.str_replace(self::BOM,'BOM',Dumper::toHtml($item[2]))."
\n";}return$res.'
';}}$value){if($recursive&&is_array($value)){$obj->$key=static::from($value,TRUE);}else{$obj->$key=$value;}}return$obj;}/** @return \RecursiveArrayIterator **/public function getIterator(){return new\RecursiveArrayIterator((array)$this);}/** @return int **/public function count(){return count((array)$this);}/** @return void **/public function offsetSet($key,$value){if(!is_scalar($key)){throw new Nette\InvalidArgumentException(sprintf('Key must be either a string or an integer, %s given.',gettype($key)));}$this->$key=$value;}/** @return mixed **/public function offsetGet($key){return$this->$key;}/** @return bool **/public function offsetExists($key){return isset($this->$key);}/** @return void **/public function offsetUnset($key){unset($this->$key);}}list);}/** @return int **/public function count(){return count($this->list);}/** @return void **/public function offsetSet($index,$value){if($index===NULL){$this->list[]=$value;}elseif($index<0||$index>=count($this->list)){throw new Nette\OutOfRangeException('Offset invalid or out of range');}else{$this->list[(int)$index]=$value;}}/** @return mixed **/public function offsetGet($index){if($index<0||$index>=count($this->list)){throw new Nette\OutOfRangeException('Offset invalid or out of range');}return$this->list[(int)$index];}/** @return bool **/public function offsetExists($index){return$index>=0&&$indexlist);}/** @return void **/public function offsetUnset($index){if($index<0||$index>=count($this->list)){throw new Nette\OutOfRangeException('Offset invalid or out of range');}array_splice($this->list,(int)$index,1);}}$v){if(is_array($v)&&is_array($arr2[$k])){$res[$k]=self::mergeTree($v,$arr2[$k]);}}return$res;}/** @return int|FALSE offset if it is found, FALSE otherwise **/public static function searchKey($arr,$key){$foo=array($key=>NULL);return array_search(key($foo),array_keys($arr),TRUE);}/** @return void **/public static function insertBefore(array&$arr,$key,array$inserted){$offset=self::searchKey($arr,$key);$arr=array_slice($arr,0,$offset,TRUE)+$inserted+array_slice($arr,$offset,count($arr),TRUE);}/** @return void **/public static function insertAfter(array&$arr,$key,array$inserted){$offset=self::searchKey($arr,$key);$offset=$offset===FALSE?count($arr):$offset+1;$arr=array_slice($arr,0,$offset,TRUE)+$inserted+array_slice($arr,$offset,count($arr),TRUE);}/** @return void **/public static function renameKey(array&$arr,$oldKey,$newKey){$offset=self::searchKey($arr,$oldKey);if($offset!==FALSE){$keys=array_keys($arr);$keys[$offset]=$newKey;$arr=array_combine($keys,$arr);}}/** @return array **/public static function grep(array$arr,$pattern,$flags=0){return Strings::pcre('preg_grep',array($pattern,$arr,$flags));}/** @return array **/public static function flatten(array$arr,$preserveKeys=FALSE){$res=array();$cb=$preserveKeys?function($v,$k)use(&$res){$res[$k]=$v;}:function($v)use(&$res){$res[]=$v;};array_walk_recursive($arr,$cb);return$res;}/** @return bool **/public static function isList($value){return is_array($value)&&(!$value||array_keys($value)===range(0,count($value)-1));}/** @return array|\stdClass **/public static function associate(array$arr,$path){$parts=is_array($path)?$path:preg_split('#(\[\]|->|=|\|)#',$path,NULL,PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);if(!$parts||$parts[0]==='='||$parts[0]==='|'||$parts===array('->')){throw new Nette\InvalidArgumentException("Invalid path '$path'.");}$res=$parts[0]==='->'?new\stdClass:array();foreach($arr as$rowOrig){$row=(array)$rowOrig;$x=&$res;for($i=0;$i'){if(isset($parts[++$i])){$x=&$x->{$row[$parts[$i]]};}else{$row=is_object($rowOrig)?$rowOrig:(object)$row;}}elseif($part!=='|'){$x=&$x[(string)$row[$part]];}}if($x===NULL){$x=$row;}}return$res;}/** @return array **/public static function normalize(array$arr,$filling=NULL){$res=array();foreach($arr as$k=>$v){$res[is_int($k)?$v:$k]=is_int($k)?$filling:$v;}return$res;}/** @return mixed **/public static function pick(array&$arr,$key,$default=NULL){if(array_key_exists($key,$arr)){$value=$arr[$key];unset($arr[$key]);return$value;}elseif(func_num_args()<3){throw new Nette\InvalidArgumentException("Missing item '$key'.");}else{return$default;}}}=50400){if(is_string($callable)&&function_exists($callable)){$r=new\ReflectionFunction($callable);return$r->getClosure();}elseif(is_array($callable)&&method_exists($callable[0],$callable[1])){$r=new\ReflectionMethod($callable[0],$callable[1]);return$r->getClosure($callable[0]);}}self::check($callable);$_callable_=$callable;return function()use($_callable_){return call_user_func_array($_callable_,func_get_args());};}/** @return mixed **/public static function invoke($callable){self::check($callable);return call_user_func_array($callable,array_slice(func_get_args(),1));}/** @return mixed **/public static function invokeArgs($callable,array$args=array()){self::check($callable);return call_user_func_array($callable,$args);}/** @return mixed **/public static function invokeSafe($function,array$args,$onError){$prev=set_error_handler(function($severity,$message,$file,$line,$context=NULL,$stack=NULL)use($onError,&$prev,$function){if($file===''&&defined('HHVM_VERSION')){$file=$stack[1]['file'];}if($file===__FILE__){$msg=preg_replace("#^$function\(.*?\): #",'',$message);if($onError($msg,$severity)!==FALSE){return;}}return$prev?call_user_func_array($prev,func_get_args()):FALSE;});try{$res=call_user_func_array($function,$args);restore_error_handler();return$res;}catch(\Throwable$e){restore_error_handler();throw$e;}catch(\Exception$e){restore_error_handler();throw$e;}}/** @return callable **/public static function check($callable,$syntax=FALSE){if(!is_callable($callable,$syntax)){throw new Nette\InvalidArgumentException($syntax?'Given value is not a callable type.':sprintf("Callback '%s' is not callable.",self::toString($callable)));}return$callable;}/** @return string **/public static function toString($callable){if($callable instanceof\Closure){$inner=self::unwrap($callable);return'{closure'.($inner instanceof\Closure?'}':' '.self::toString($inner).'}');}elseif(is_string($callable)&&$callable[0]==="\0"){return'{lambda}';}else{is_callable($callable,TRUE,$textual);return$textual;}}/** @return \ReflectionMethod|\ReflectionFunction **/public static function toReflection($callable){if($callable instanceof\Closure){$callable=self::unwrap($callable);}elseif($callable instanceof Nette\Callback){$callable=$callable->getNative();}$class=class_exists('Nette\Reflection\Method')?'Nette\Reflection\Method':'ReflectionMethod';if(is_string($callable)&&strpos($callable,'::')){return new$class($callable);}elseif(is_array($callable)){return new$class($callable[0],$callable[1]);}elseif(is_object($callable)&&!$callable instanceof\Closure){return new$class($callable,'__invoke');}else{$class=class_exists('Nette\Reflection\GlobalFunction')?'Nette\Reflection\GlobalFunction':'ReflectionFunction';return new$class($callable);}}/** @return bool **/public static function isStatic($callable){return is_array($callable)?is_string($callable[0]):is_string($callable);}/** @return callable **/public static function unwrap(\Closure$closure){$r=new\ReflectionFunction($closure);if(substr($r->getName(),-1)==='}'){$vars=$r->getStaticVariables();return isset($vars['_callable_'])?$vars['_callable_']:$closure;}elseif($obj=$r->getClosureThis()){return array($obj,$r->getName());}elseif($class=$r->getClosureScopeClass()){return array($class->getName(),$r->getName());}else{return$r->getName();}}}format('Y-m-d H:i:s'),$time->getTimezone());}elseif(is_numeric($time)){if($time<=self::YEAR){$time+=time();}$tmp=new static('@'.$time);return$tmp->setTimeZone(new\DateTimeZone(date_default_timezone_get()));}else{return new static($time);}}/** @return string **/public function __toString(){return$this->format('Y-m-d H:i:s');}/** @return static **/public function modifyClone($modify=''){$dolly=clone$this;return$modify?$dolly->modify($modify):$dolly;}/** @return static **/public function setTimestamp($timestamp){$zone=$this->getTimezone();$this->__construct('@'.$timestamp);return$this->setTimeZone($zone);}/** @return int|string **/public function getTimestamp(){$ts=$this->format('U');return is_float($tmp=$ts*1)?$ts:$tmp;}/** @return static|FALSE **/public static function createFromFormat($format,$time,$timezone=NULL){if($timezone===NULL){$timezone=new\DateTimeZone(date_default_timezone_get());}elseif(is_string($timezone)){$timezone=new\DateTimeZone($timezone);}elseif(!$timezone instanceof\DateTimeZone){throw new Nette\InvalidArgumentException('Invalid timezone given');}$date=parent::createFromFormat($format,$time,$timezone);return$date?static::from($date):FALSE;}}isDir()){static::createDir($dest.'/'.$iterator->getSubPathName());}else{static::copy($item,$dest.'/'.$iterator->getSubPathName());}}}else{static::createDir(dirname($dest));if(@stream_copy_to_stream(fopen($source,'r'),fopen($dest,'w'))===FALSE){throw new Nette\IOException("Unable to copy file '$source' to '$dest'.");}}}/** @return void **/public static function delete($path){if(is_file($path)||is_link($path)){$func=DIRECTORY_SEPARATOR==='\\'&&is_dir($path)?'rmdir':'unlink';if(!@$func($path)){throw new Nette\IOException("Unable to delete '$path'.");}}elseif(is_dir($path)){foreach(new\FilesystemIterator($path)as$item){static::delete($item);}if(!@rmdir($path)){throw new Nette\IOException("Unable to delete directory '$path'.");}}}/** @return void **/public static function rename($name,$newName,$overwrite=TRUE){if(!$overwrite&&file_exists($newName)){throw new Nette\InvalidStateException("File or directory '$newName' already exists.");}elseif(!file_exists($name)){throw new Nette\IOException("File or directory '$name' not found.");}else{static::createDir(dirname($newName));static::delete($newName);if(!@rename($name,$newName)){throw new Nette\IOException("Unable to rename file or directory '$name' to '$newName'.");}}}/** @return string **/public static function read($file){$content=@file_get_contents($file);if($content===FALSE){throw new Nette\IOException("Unable to read file '$file'.");}return$content;}/** @return void **/public static function write($file,$content,$mode=0666){static::createDir(dirname($file));if(@file_put_contents($file,$content)===FALSE){throw new Nette\IOException("Unable to write file '$file'.");}if($mode!==NULL&&!@chmod($file,$mode)){throw new Nette\IOException("Unable to chmod file '$file'.");}}/** @return bool **/public static function isAbsolute($path){return(bool)preg_match('#([a-z]:)?[/\\\\]|[a-z][a-z0-9+.-]*://#Ai',$path);}}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,'track'=>1);/** @return static **/public static function el($name=NULL,$attrs=NULL){$el=new 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;}/** @return static **/public function setName($name,$isEmpty=NULL){if($name!==NULL&&!is_string($name)){throw new Nette\InvalidArgumentException(sprintf('Name must be string or NULL, %s given.',gettype($name)));}$this->name=$name;$this->isEmpty=$isEmpty===NULL?isset(static::$emptyElements[$name]):(bool)$isEmpty;return$this;}/** @return string **/public function getName(){return$this->name;}/** @return bool **/public function isEmpty(){return$this->isEmpty;}/** @return static **/public function addAttributes(array$attrs){$this->attrs=array_merge($this->attrs,$attrs);return$this;}/** @return void **/public function __set($name,$value){$this->attrs[$name]=$value;}/** @return mixed HTML attribute value **/public function&__get($name){return$this->attrs[$name];}/** @return bool **/public function __isset($name){return isset($this->attrs[$name]);}/** @return void **/public function __unset($name){unset($this->attrs[$name]);}/** @return static **/public function __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 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;}/** @return static **/public function href($path,$query=NULL){if($query){$query=http_build_query($query,NULL,'&');if($query!==''){$path.='?'.$query;}}$this->attrs['href']=$path;return$this;}/** @return static **/public function data($name,$value=NULL){if(func_num_args()===1){$this->attrs['data']=$name;}else{$this->attrs["data-$name"]=is_bool($value)?json_encode($value):$value;}return$this;}/** @return static **/public function setHtml($html){if(is_array($html)){throw new Nette\InvalidArgumentException(sprintf('Textual content must be a scalar, %s given.',gettype($html)));}$this->removeChildren();$this->children[]=(string)$html;return$this;}/** @return string **/public function getHtml(){$s='';foreach($this->children as$child){if(is_object($child)){$s.=$child->render();}else{$s.=$child;}}return$s;}/** @return static **/public function setText($text){if(!is_array($text)&&!$text instanceof self){$text=htmlspecialchars((string)$text,ENT_NOQUOTES,'UTF-8');}return$this->setHtml($text);}/** @return string **/public function getText(){return html_entity_decode(strip_tags($this->getHtml()),ENT_QUOTES,'UTF-8');}/** @return static **/public function add($child){return$this->addHtml($child);}/** @return static **/public function addHtml($child){return$this->insert(NULL,$child);}/** @return static **/public function addText($text){$text=htmlspecialchars($text,ENT_NOQUOTES,'UTF-8');return$this->insert(NULL,$text);}/** @return static created element **/public function create($name,$attrs=NULL){$this->insert(NULL,$child=static::el($name,$attrs));return$child;}/** @return static **/public function insert($index,$child,$replace=FALSE){if($child instanceof self||is_scalar($child)){if($index===NULL){$this->children[]=$child;}else{array_splice($this->children,(int)$index,$replace?1:0,array($child));}}else{throw new Nette\InvalidArgumentException(sprintf('Child node must be scalar or Html object, %s given.',is_object($child)?get_class($child):gettype($child)));}return$this;}/** @return void **/public function offsetSet($index,$child){$this->insert($index,$child,TRUE);}/** @return static|string **/public function offsetGet($index){return$this->children[$index];}/** @return bool **/public function offsetExists($index){return isset($this->children[$index]);}/** @return void **/public function offsetUnset($index){if(isset($this->children[$index])){array_splice($this->children,(int)$index,1);}}/** @return int **/public function count(){return count($this->children);}/** @return void **/public function removeChildren(){$this->children=array();}/** @return \ArrayIterator **/public function getIterator(){return new\ArrayIterator($this->children);}/** @return array **/public function getChildren(){return$this->children;}/** @return string **/public function render($indent=NULL){$s=$this->startTag();if(!$this->isEmpty){if($indent!==NULL){$indent++;}foreach($this->children 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;}public function __toString(){try{return$this->render();}catch(\Throwable$e){}catch(\Exception$e){}trigger_error("Exception in ".__METHOD__."(): {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}",E_USER_ERROR);}/** @return string **/public function startTag(){if($this->name){return'<'.$this->name.$this->attributes().(static::$xhtml&&$this->isEmpty?' />':'>');}else{return'';}}/** @return string **/public function endTag(){return$this->name&&!$this->isEmpty?'name.'>':'';}/** @return string **/public function attributes(){if(!is_array($this->attrs)){return'';}$s='';$attrs=$this->attrs;if(isset($attrs['data'])&&is_array($attrs['data'])){foreach($attrs['data']as$key=>$value){$attrs['data-'.$key]=$value;}unset($attrs['data']);}foreach($attrs 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(strncmp($key,'data-',5)===0){$value=Json::encode($value);}else{$tmp=NULL;foreach($value 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);}}elseif(is_float($value)){$value=rtrim(rtrim(number_format($value,10,'.',''),'0'),'.');}else{$value=(string)$value;}$q=strpos($value,'"')===FALSE?'"':"'";$s.=' '.$key.'='.$q.str_replace(array('&',$q,'<'),array('&',$q==='"'?'"':''',self::$xhtml?'<':'<'),$value).(strpos($value,'`')!==FALSE&&strpbrk($value,' <>"\'')===FALSE?' ':'').$q;}$s=str_replace('@','@',$s);return$s;}public function __clone(){foreach($this->children as$key=>$value){if(is_object($value)){$this->children[$key]=clone$value;}}}}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)));}/** @return static **/public static function fromFile($file,&$format=NULL){if(!extension_loaded('gd')){throw new Nette\NotSupportedException('PHP extension GD is not loaded.');}static$funcs=array(self::JPEG=>'imagecreatefromjpeg',self::PNG=>'imagecreatefrompng',self::GIF=>'imagecreatefromgif');$info=@getimagesize($file);$format=$info[2];if(!isset($funcs[$format])){throw new UnknownImageFileException(is_file($file)?"Unknown type of file '$file'.":"File '$file' not found.");}return new static(Callback::invokeSafe($funcs[$format],array($file),function($message){throw new ImageException($message);}));}public static function getFormatFromString($s){trigger_error(__METHOD__.'() is deprecated; use finfo_buffer() instead.',E_USER_DEPRECATED);$types=array('image/jpeg'=>self::JPEG,'image/gif'=>self::GIF,'image/png'=>self::PNG);$type=finfo_buffer(finfo_open(FILEINFO_MIME_TYPE),$s);return isset($types[$type])?$types[$type]:NULL;}/** @return static **/public static function fromString($s,&$format=NULL){if(!extension_loaded('gd')){throw new Nette\NotSupportedException('PHP extension GD is not loaded.');}if(func_num_args()>1){$format=@static::getFormatFromString($s);}return new static(Callback::invokeSafe('imagecreatefromstring',array($s),function($message){throw new ImageException($message);}));}/** @return static **/public static function fromBlank($width,$height,$color=NULL){if(!extension_loaded('gd')){throw new Nette\NotSupportedException('PHP extension GD is not loaded.');}$width=(int)$width;$height=(int)$height;if($width<1||$height<1){throw new Nette\InvalidArgumentException('Image width and height must be greater than zero.');}$image=imagecreatetruecolor($width,$height);if(is_array($color)){$color+=array('alpha'=>0);$color=imagecolorresolvealpha($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 new static($image);}public function __construct($image){$this->setImageResource($image);imagesavealpha($image,TRUE);}/** @return int **/public function getWidth(){return imagesx($this->image);}/** @return int **/public function getHeight(){return imagesy($this->image);}/** @return static **/protected function setImageResource($image){if(!is_resource($image)||get_resource_type($image)!=='gd'){throw new Nette\InvalidArgumentException('Image is not valid.');}$this->image=$image;return$this;}/** @return resource **/public function getImageResource(){return$this->image;}/** @return static **/public function 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->image,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->image,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;}/** @return array **/public static function calculateSize($srcWidth,$srcHeight,$newWidth,$newHeight,$flags=self::FIT){if(substr($newWidth,-1)==='%'){$newWidth=round($srcWidth/100*abs(substr($newWidth,0,-1)));$percents=TRUE;}else{$newWidth=(int)abs($newWidth);}if(substr($newHeight,-1)==='%'){$newHeight=round($srcHeight/100*abs(substr($newHeight,0,-1)));$flags|=empty($percents)?0:self::STRETCH;}else{$newHeight=(int)abs($newHeight);}if($flags&self::STRETCH){if(empty($newWidth)||empty($newHeight)){throw new Nette\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 new Nette\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 array(max((int)$newWidth,1),max((int)$newHeight,1));}/** @return static **/public function 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->image,0,0,$left,$top,$width,$height);$this->image=$newImage;return$this;}/** @return array **/public static function calculateCutout($srcWidth,$srcHeight,$left,$top,$newWidth,$newHeight){if(substr($newWidth,-1)==='%'){$newWidth=round($srcWidth/100*substr($newWidth,0,-1));}if(substr($newHeight,-1)==='%'){$newHeight=round($srcHeight/100*substr($newHeight,0,-1));}if(substr($left,-1)==='%'){$left=round(($srcWidth-$newWidth)/100*substr($left,0,-1));}if(substr($top,-1)==='%'){$top=round(($srcHeight-$newHeight)/100*substr($top,0,-1));}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 array($left,$top,$newWidth,$newHeight);}/** @return static **/public function sharpen(){imageconvolution($this->image,array(array(-1,-1,-1),array(-1,24,-1),array(-1,-1,-1)),16,0);return$this;}/** @return static **/public function 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*substr($left,0,-1));}if(substr($top,-1)==='%'){$top=round(($this->getHeight()-$image->getHeight())/100*substr($top,0,-1));}if($opacity===100){imagecopy($this->image,$image->getImageResource(),$left,$top,0,0,$image->getWidth(),$image->getHeight());}elseif($opacity!=0){$cutting=imagecreatetruecolor($image->getWidth(),$image->getHeight());imagecopy($cutting,$this->image,0,0,$left,$top,$image->getWidth(),$image->getHeight());imagecopy($cutting,$image->getImageResource(),0,0,0,0,$image->getWidth(),$image->getHeight());imagecopymerge($this->image,$cutting,$left,$top,0,0,$image->getWidth(),$image->getHeight(),$opacity);}return$this;}/** @return bool TRUE on success or FALSE on failure. **/public function save($file=NULL,$quality=NULL,$type=NULL){if($type===NULL){switch(strtolower($ext=pathinfo($file,PATHINFO_EXTENSION))){case'jpg':case'jpeg':$type=self::JPEG;break;case'png':$type=self::PNG;break;case'gif':$type=self::GIF;break;default:throw new Nette\InvalidArgumentException("Unsupported file extension '$ext'.");}}switch($type){case self::JPEG:$quality=$quality===NULL?85:max(0,min(100,(int)$quality));return imagejpeg($this->image,$file,$quality);case self::PNG:$quality=$quality===NULL?9:max(0,min(9,(int)$quality));return imagepng($this->image,$file,$quality);case self::GIF:return imagegif($this->image,$file);default:throw new Nette\InvalidArgumentException("Unsupported image type '$type'.");}}/** @return string **/public function toString($type=self::JPEG,$quality=NULL){ob_start(function(){});$this->save(NULL,$quality,$type);return ob_get_clean();}/** @return string **/public function __toString(){try{return$this->toString();}catch(\Throwable$e){}catch(\Exception$e){}if(isset($e)){if(func_num_args()){throw$e;}trigger_error("Exception in ".__METHOD__."(): {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}",E_USER_ERROR);}}/** @return bool TRUE on success or FALSE on failure. **/public function send($type=self::JPEG,$quality=NULL){if(!in_array($type,array(self::JPEG,self::PNG,self::GIF),TRUE)){throw new Nette\InvalidArgumentException("Unsupported image type '$type'.");}header('Content-Type: '.image_type_to_mime_type($type));return$this->save(NULL,$quality,$type);}/** @return mixed **/public function __call($name,$args){$function='image'.$name;if(!function_exists($function)){return parent::__call($name,$args);}foreach($args as$key=>$value){if($value instanceof self){$args[$key]=$value->getImageResource();}elseif(is_array($value)&&isset($value['red'])){$args[$key]=imagecolorallocatealpha($this->image,$value['red'],$value['green'],$value['blue'],$value['alpha'])?:imagecolorresolvealpha($this->image,$value['red'],$value['green'],$value['blue'],$value['alpha']);}}array_unshift($args,$this->image);$res=call_user_func_array($function,$args);return is_resource($res)&&get_resource_type($res)==='gd'?$this->setImageResource($res):$res;}public function __clone(){ob_start(function(){});imagegd2($this->image);$this->setImageResource(imagecreatefromstring(ob_get_clean()));}}'The maximum stack depth has been exceeded',JSON_ERROR_STATE_MISMATCH=>'Syntax error, malformed JSON',JSON_ERROR_CTRL_CHAR=>'Unexpected control character found',JSON_ERROR_SYNTAX=>'Syntax error, malformed JSON',5=>'Invalid UTF-8 sequence');final public function __construct(){throw new Nette\StaticClassException;}/** @return string **/public static function encode($value,$options=0){$flags=PHP_VERSION_ID>=50400?(JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES|($options&self::PRETTY?JSON_PRETTY_PRINT:0)):0;if(PHP_VERSION_ID<50500){$json=Callback::invokeSafe('json_encode',array($value,$flags),function($message){throw new JsonException($message);});}else{$json=json_encode($value,$flags);}if($error=json_last_error()){$message=isset(static::$messages[$error])?static::$messages[$error]:(PHP_VERSION_ID>=50500?json_last_error_msg():'Unknown error');throw new JsonException($message,$error);}$json=str_replace(array("\xe2\x80\xa8","\xe2\x80\xa9"),array('\u2028','\u2029'),$json);return$json;}/** @return mixed **/public static function decode($json,$options=0){$json=(string)$json;if(!preg_match('##u',$json)){throw new JsonException('Invalid UTF-8 sequence',5);}$forceArray=(bool)($options&self::FORCE_ARRAY);if(!$forceArray&&preg_match('#(?<=[^\\\\]")\\\\u0000(?:[^"\\\\]|\\\\.)*+"\s*+:#',$json)){throw new JsonException(static::$messages[JSON_ERROR_CTRL_CHAR]);}$args=array($json,$forceArray,512);if(PHP_VERSION_ID>=50400&&!(defined('JSON_C_VERSION')&&PHP_INT_SIZE>4)){$args[]=JSON_BIGINT_AS_STRING;}$value=call_user_func_array('json_decode',$args);if($value===NULL&&$json!==''&&strcasecmp(trim($json," \t\n\r"),'null')!==0){$error=json_last_error();throw new JsonException(isset(static::$messages[$error])?static::$messages[$error]:'Unknown error',$error);}return$value;}}getName();}if($callback===NULL){return Nette\Utils\ObjectMixin::getExtensionMethod($class,$name);}else{Nette\Utils\ObjectMixin::setExtensionMethod($class,$name,$callback);}}/** @return mixed property value **/public function&__get($name){return Nette\Utils\ObjectMixin::get($this,$name);}/** @return void **/public function __set($name,$value){Nette\Utils\ObjectMixin::set($this,$name,$value);}/** @return bool **/public function __isset($name){return Nette\Utils\ObjectMixin::has($this,$name);}/** @return void **/public function __unset($name){Nette\Utils\ObjectMixin::remove($this,$name);}}$name instanceof\Closure){return call_user_func_array($_this->$name,$args);}elseif($isProp==='event'){if(is_array($_this->$name)||$_this->$name instanceof\Traversable){foreach($_this->$name as$handler){Callback::invokeArgs($handler,$args);}}elseif($_this->$name!==NULL){throw new Nette\UnexpectedValueException("Property $class::$$name must be array or NULL, ".gettype($_this->$name).' given.');}}elseif(($methods=&self::getMethods($class))&&isset($methods[$name])&&is_array($methods[$name])){list($op,$rp,$type)=$methods[$name];if(count($args)!==($op==='get'?0:1)){throw new Nette\InvalidArgumentException("$class::$name() expects ".($op==='get'?'no':'1').' argument, '.count($args).' given.');}elseif($type&&$args&&!self::checkType($args[0],$type)){throw new Nette\InvalidArgumentException("Argument passed to $class::$name() must be $type, ".gettype($args[0]).' given.');}if($op==='get'){return$rp->getValue($_this);}elseif($op==='set'){$rp->setValue($_this,$args[0]);}elseif($op==='add'){$val=$rp->getValue($_this);$val[]=$args[0];$rp->setValue($_this,$val);}return$_this;}elseif($cb=self::getExtensionMethod($class,$name)){array_unshift($args,$_this);return Callback::invokeArgs($cb,$args);}else{$hint=self::getSuggestion(array_merge(get_class_methods($class),self::parseFullDoc($class,'~^[ \t*]*@method[ \t]+(?:\S+[ \t]+)??(\w+)\(~m'),array_keys(self::getExtensionMethods($class))),$name);if(method_exists($class,$name)){$class='parent';}throw new MemberAccessException("Call to undefined method $class::$name()".($hint?", did you mean $hint()?":'.'));}}/** @return void **/public static function callStatic($class,$method,$args){$hint=self::getSuggestion(array_filter(get_class_methods($class),function($m)use($class){$rm=new\ReflectionMethod($class,$m);return$rm->isStatic();}),$method);throw new MemberAccessException("Call to undefined static method $class::$method()".($hint?", did you mean $hint()?":'.'));}/** @return mixed property value **/public static function&get($_this,$name){$class=get_class($_this);$uname=ucfirst($name);$methods=&self::getMethods($class);if($name===''){throw new MemberAccessException("Cannot read a class '$class' property without name.");}elseif(isset($methods[$m='get'.$uname])||isset($methods[$m='is'.$uname])){if($methods[$m]===0){$rm=new\ReflectionMethod($class,$m);$methods[$m]=$rm->returnsReference();}if($methods[$m]===TRUE){return$_this->$m();}else{$val=$_this->$m();return$val;}}elseif(isset($methods[$name])){if(preg_match('#^(is|get|has)([A-Z]|$)#',$name)&&($rm=new\ReflectionMethod($class,$name))&&!$rm->getNumberOfRequiredParameters()){$source='';foreach(debug_backtrace(PHP_VERSION_ID>=50306?DEBUG_BACKTRACE_IGNORE_ARGS:FALSE)as$item){if(isset($item['file'])&&dirname($item['file'])!==__DIR__){$source=" in $item[file]:$item[line]";break;}}trigger_error("Did you forgot parentheses after $name$source?",E_USER_WARNING);}$val=Callback::closure($_this,$name);return$val;}elseif(isset($methods['set'.$uname])){throw new MemberAccessException("Cannot read a write-only property $class::\$$name.");}else{$hint=self::getSuggestion(array_merge(array_keys(get_class_vars($class)),self::parseFullDoc($class,'~^[ \t*]*@property(?:-read)?[ \t]+(?:\S+[ \t]+)??\$(\w+)~m')),$name);throw new MemberAccessException("Cannot read an undeclared property $class::\$$name".($hint?", did you mean \$$hint?":'.'));}}/** @return void **/public static function set($_this,$name,$value){$class=get_class($_this);$uname=ucfirst($name);$methods=&self::getMethods($class);if($name===''){throw new MemberAccessException("Cannot write to a class '$class' property without name.");}elseif(self::hasProperty($class,$name)){$_this->$name=$value;}elseif(isset($methods[$m='set'.$uname])){$_this->$m($value);}elseif(isset($methods['get'.$uname])||isset($methods['is'.$uname])){throw new MemberAccessException("Cannot write to a read-only property $class::\$$name.");}else{$hint=self::getSuggestion(array_merge(array_keys(get_class_vars($class)),self::parseFullDoc($class,'~^[ \t*]*@property(?:-write)?[ \t]+(?:\S+[ \t]+)??\$(\w+)~m')),$name);throw new MemberAccessException("Cannot write to an undeclared property $class::\$$name".($hint?", did you mean \$$hint?":'.'));}}/** @return void **/public static function remove($_this,$name){$class=get_class($_this);if(!self::hasProperty($class,$name)){throw new MemberAccessException("Cannot unset the property $class::\$$name.");}}/** @return bool **/public static function has($_this,$name){$name=ucfirst($name);$methods=&self::getMethods(get_class($_this));return$name!==''&&(isset($methods['get'.$name])||isset($methods['is'.$name]));}/** @return mixed **/private static function hasProperty($class,$name){$prop=&self::$props[$class][$name];if($prop===NULL){$prop=FALSE;try{$rp=new\ReflectionProperty($class,$name);if($rp->isPublic()&&!$rp->isStatic()){$prop=$name>='onA'&&$name<'on_'?'event':TRUE;}}catch(\ReflectionException$e){}}return$prop;}/** @return array **/private static function&getMethods($class){if(!isset(self::$methods[$class])){self::$methods[$class]=array_fill_keys(get_class_methods($class),0)+self::getMagicMethods($class);if($parent=get_parent_class($class)){self::$methods[$class]+=self::getMethods($parent);}}return self::$methods[$class];}/** @method. @return array **/public static function getMagicMethods($class){$rc=new\ReflectionClass($class);preg_match_all('~^ [ \t*]* @method [ \t]+ (?: [^\s(]+ [ \t]+ )? (set|get|is|add) ([A-Z]\w*) [ \t]* (?: \( [ \t]* ([^)$\s]+) )? ()~mx',$rc->getDocComment(),$matches,PREG_SET_ORDER);$methods=array();foreach($matches as$m){list(,$op,$prop,$type)=$m;$name=$op.$prop;$prop=strtolower($prop[0]).substr($prop,1).($op==='add'?'s':'');if($rc->hasProperty($prop)&&($rp=$rc->getProperty($prop))&&!$rp->isStatic()){$rp->setAccessible(TRUE);if($op==='get'||$op==='is'){$type=NULL;$op='get';}elseif(!$type&&preg_match('#@var[ \t]+(\S+)'.($op==='add'?'\[\]#':'#'),$rp->getDocComment(),$m)){$type=$m[1];}if($rc->inNamespace()&&preg_match('#^[A-Z]\w+(\[|\||\z)#',$type)){$type=$rc->getNamespaceName().'\\'.$type;}$methods[$name]=array($op,$rp,$type);}}return$methods;}/** @return bool **/public static function checkType(&$val,$type){if(strpos($type,'|')!==FALSE){$found=NULL;foreach(explode('|',$type)as$type){$tmp=$val;if(self::checkType($tmp,$type)){if($val===$tmp){return TRUE;}$found[]=$tmp;}}if($found){$val=$found[0];return TRUE;}return FALSE;}elseif(substr($type,-2)==='[]'){if(!is_array($val)){return FALSE;}$type=substr($type,0,-2);$res=array();foreach($val as$k=>$v){if(!self::checkType($v,$type)){return FALSE;}$res[$k]=$v;}$val=$res;return TRUE;}switch(strtolower($type)){case NULL:case'mixed':return TRUE;case'bool':case'boolean':return($val===NULL||is_scalar($val))&&settype($val,'bool');case'string':return($val===NULL||is_scalar($val)||(is_object($val)&&method_exists($val,'__toString')))&&settype($val,'string');case'int':case'integer':return($val===NULL||is_bool($val)||is_numeric($val))&&((float)(int)$val===(float)$val)&&settype($val,'int');case'float':return($val===NULL||is_bool($val)||is_numeric($val))&&settype($val,'float');case'scalar':case'array':case'object':case'callable':case'resource':case'null':return call_user_func("is_$type",$val);default:return$val instanceof$type;}}/** @return void **/public static function setExtensionMethod($class,$name,$callback){$name=strtolower($name);self::$extMethods[$name][$class]=Callback::check($callback);self::$extMethods[$name]['']=NULL;}/** @return mixed **/public static function getExtensionMethod($class,$name){$list=&self::$extMethods[strtolower($name)];$cache=&$list[''][$class];if(isset($cache)){return$cache;}foreach(array($class)+class_parents($class)+class_implements($class)as$cl){if(isset($list[$cl])){return$cache=$list[$cl];}}return$cache=FALSE;}/** @return array **/public static function getExtensionMethods($class){$res=array();foreach(array_keys(self::$extMethods)as$name){if($cb=self::getExtensionMethod($class,$name)){$res[$name]=$cb;}}return$res;}/** @return string|NULL **/public static function getSuggestion(array$items,$value){$norm=preg_replace($re='#^(get|set|has|is|add)(?=[A-Z])#','',$value);$best=NULL;$min=(strlen($value)/4+1)*10+.1;foreach(array_unique($items)as$item){if($item!==$value&&(($len=levenshtein($item,$value,10,11,10))<$min||($len=levenshtein(preg_replace($re,'',$item),$norm,10,11,10)+20)<$min)){$min=$len;$best=$item;}}return$best;}private static function parseFullDoc($class,$pattern){$rc=new\ReflectionClass($class);do{$doc[]=$rc->getDocComment();}while($rc=$rc->getParentClass());return preg_match_all($pattern,implode($doc),$m)?$m[1]:array();}}page=(int)$page;return$this;}/** @return int **/public function getPage(){return$this->base+$this->getPageIndex();}/** @return int **/public function getFirstPage(){return$this->base;}/** @return int|NULL **/public function getLastPage(){return$this->itemCount===NULL?NULL:$this->base+max(0,$this->getPageCount()-1);}/** @return static **/public function setBase($base){$this->base=(int)$base;return$this;}/** @return int **/public function getBase(){return$this->base;}/** @return int **/protected function getPageIndex(){$index=max(0,$this->page-$this->base);return$this->itemCount===NULL?$index:min($index,max(0,$this->getPageCount()-1));}/** @return bool **/public function isFirst(){return$this->getPageIndex()===0;}/** @return bool **/public function isLast(){return$this->itemCount===NULL?FALSE:$this->getPageIndex()>=$this->getPageCount()-1;}/** @return int|NULL **/public function getPageCount(){return$this->itemCount===NULL?NULL:(int)ceil($this->itemCount/$this->itemsPerPage);}/** @return static **/public function setItemsPerPage($itemsPerPage){$this->itemsPerPage=max(1,(int)$itemsPerPage);return$this;}/** @return int **/public function getItemsPerPage(){return$this->itemsPerPage;}/** @return static **/public function setItemCount($itemCount){$this->itemCount=($itemCount===FALSE||$itemCount===NULL)?NULL:max(0,(int)$itemCount);return$this;}/** @return int|NULL **/public function getItemCount(){return$this->itemCount;}/** @return int **/public function getOffset(){return$this->getPageIndex()*$this->itemsPerPage;}/** @return int|NULL **/public function getCountdownOffset(){return$this->itemCount===NULL?NULL:max(0,$this->itemCount-($this->getPageIndex()+1)*$this->itemsPerPage);}/** @return int|NULL **/public function getLength(){return$this->itemCount===NULL?$this->itemsPerPage:min($this->itemsPerPage,$this->itemCount-$this->getPageIndex()*$this->itemsPerPage);}}=70000){for($i=0;$i<$length;$i++){$res.=$charlist[random_int(0,$chLen-1)];}return$res;}$windows=defined('PHP_WINDOWS_VERSION_BUILD');$bytes='';if(function_exists('openssl_random_pseudo_bytes')&&(PHP_VERSION_ID>=50400||!defined('PHP_WINDOWS_VERSION_BUILD'))){$bytes=openssl_random_pseudo_bytes($length,$secure);if(!$secure){$bytes='';}}if(strlen($bytes)<$length&&function_exists('mcrypt_create_iv')&&(PHP_VERSION_ID>=50307||!$windows)){$bytes=mcrypt_create_iv($length,MCRYPT_DEV_URANDOM);}if(strlen($bytes)<$length&&!$windows&&@is_readable('/dev/urandom')){$bytes=file_get_contents('/dev/urandom',FALSE,NULL,-1,$length);}if(strlen($bytes)<$length){$rand3=md5(serialize($_SERVER),TRUE);$charlist=str_shuffle($charlist);for($i=0;$i<$length;$i++){if($i % 5===0){list($rand1,$rand2)=explode(' ',microtime());$rand1+=lcg_value();}$rand1*=$chLen;$res.=$charlist[($rand1+$rand2+ord($rand3[$i % strlen($rand3)]))%$chLen];$rand1-=(int)$rand1;}return$res;}for($i=0;$i<$length;$i++){$res.=$charlist[($i+ord($bytes[$i]))%$chLen];}return$res;}}=0xD800&&$code<=0xDFFF)||$code>0x10FFFF){throw new Nette\InvalidArgumentException('Code point must be in range 0x0 to 0xD7FF or 0xE000 to 0x10FFFF.');}return iconv('UTF-32BE','UTF-8//IGNORE',pack('N',$code));}/** @return bool **/public static function startsWith($haystack,$needle){return strncmp($haystack,$needle,strlen($needle))===0;}/** @return bool **/public static function endsWith($haystack,$needle){return strlen($needle)===0||substr($haystack,-strlen($needle))===$needle;}/** @return bool **/public static function contains($haystack,$needle){return strpos($haystack,$needle)!==FALSE;}/** @return string **/public static function substring($s,$start,$length=NULL){if(function_exists('mb_substr')){if($length===NULL&&PHP_VERSION_ID<50408){$length=self::length($s);}return mb_substr($s,$start,$length,'UTF-8');}elseif($length===NULL){$length=self::length($s);}elseif($start<0&&$length<0){$start+=self::length($s);}return iconv_substr($s,$start,$length,'UTF-8');}/** @return string **/public static function normalize($s){$s=self::normalizeNewLines($s);$s=preg_replace('#[\x00-\x08\x0B-\x1F\x7F-\x9F]+#u','',$s);$s=preg_replace('#[\t ]+$#m','',$s);$s=trim($s,"\n");return$s;}/** @return string **/public static function normalizeNewLines($s){return str_replace(array("\r\n","\r"),"\n",$s);}/** @return string ASCII **/public static function toAscii($s){static$transliterator=NULL;if($transliterator===NULL&&class_exists('Transliterator',FALSE)){$transliterator=\Transliterator::create('Any-Latin; Latin-ASCII');}$s=preg_replace('#[^\x09\x0A\x0D\x20-\x7E\xA0-\x{2FF}\x{370}-\x{10FFFF}]#u','',$s);$s=strtr($s,'`\'"^~?',"\x01\x02\x03\x04\x05\x06");$s=str_replace(array("\xE2\x80\x9E","\xE2\x80\x9C","\xE2\x80\x9D","\xE2\x80\x9A","\xE2\x80\x98","\xE2\x80\x99","\xC2\xB0"),array("\x03","\x03","\x03","\x02","\x02","\x02","\x04"),$s);if($transliterator!==NULL){$s=$transliterator->transliterate($s);}if(ICONV_IMPL==='glibc'){$s=str_replace(array("\xC2\xBB","\xC2\xAB","\xE2\x80\xA6","\xE2\x84\xA2","\xC2\xA9","\xC2\xAE"),array('>>','<<','...','TM','(c)','(R)'),$s);$s=@iconv('UTF-8','WINDOWS-1250//TRANSLIT//IGNORE',$s);$s=strtr($s,"\xa5\xa3\xbc\x8c\xa7\x8a\xaa\x8d\x8f\x8e\xaf\xb9\xb3\xbe\x9c\x9a\xba\x9d\x9f\x9e"."\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3"."\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8"."\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf8\xf9\xfa\xfb\xfc\xfd\xfe"."\x96\xa0\x8b\x97\x9b\xa6\xad\xb7",'ALLSSSSTZZZallssstzzzRAAAALCCCEEEEIIDDNNOOOOxRUUUUYTsraaaalccceeeeiiddnnooooruuuuyt- <->|-.');$s=preg_replace('#[^\x00-\x7F]++#','',$s);}else{$s=@iconv('UTF-8','ASCII//TRANSLIT//IGNORE',$s);}$s=str_replace(array('`',"'",'"','^','~','?'),'',$s);return strtr($s,"\x01\x02\x03\x04\x05\x06",'`\'"^~?');}/** @return string **/public static function webalize($s,$charlist=NULL,$lower=TRUE){$s=self::toAscii($s);if($lower){$s=strtolower($s);}$s=preg_replace('#[^a-z0-9'.preg_quote($charlist,'#').']+#i','-',$s);$s=trim($s,'-');return$s;}/** @return string **/public static function truncate($s,$maxLen,$append="\xE2\x80\xA6"){if(self::length($s)>$maxLen){$maxLen=$maxLen-self::length($append);if($maxLen<1){return$append;}elseif($matches=self::match($s,'#^.{1,'.$maxLen.'}(?=[\s\x00-/:-@\[-`{-~])#us')){return$matches[0].$append;}else{return self::substring($s,0,$maxLen).$append;}}return$s;}/** @return string **/public static function indent($s,$level=1,$chars="\t"){if($level>0){$s=self::replace($s,'#(?:^|[\r\n]+)(?=[^\r\n])#','$0'.str_repeat($chars,$level));}return$s;}/** @return string **/public static function lower($s){return mb_strtolower($s,'UTF-8');}/** @return string **/public static function firstLower($s){return self::lower(self::substring($s,0,1)).self::substring($s,1);}/** @return string **/public static function upper($s){return mb_strtoupper($s,'UTF-8');}/** @return string **/public static function firstUpper($s){return self::upper(self::substring($s,0,1)).self::substring($s,1);}/** @return string **/public static function capitalize($s){return mb_convert_case($s,MB_CASE_TITLE,'UTF-8');}/** @return bool **/public static function compare($left,$right,$len=NULL){if($len<0){$left=self::substring($left,$len,-$len);$right=self::substring($right,$len,-$len);}elseif($len!==NULL){$left=self::substring($left,0,$len);$right=self::substring($right,0,$len);}return self::lower($left)===self::lower($right);}/** @return string **/public static function findPrefix($strings){if(!is_array($strings)){$strings=func_get_args();}$first=array_shift($strings);for($i=0;$i="\x80"&&$first[$i]>="\x80"&&$first[$i]<"\xC0"){$i--;}return substr($first,0,$i);}}}return$first;}/** @return int **/public static function length($s){return function_exists('mb_strlen')?mb_strlen($s,'UTF-8'):strlen(utf8_decode($s));}/** @return string **/public static function trim($s,$charlist=self::TRIM_CHARACTERS){$charlist=preg_quote($charlist,'#');return self::replace($s,'#^['.$charlist.']+|['.$charlist.']+\z#u','');}/** @return string **/public static function padLeft($s,$length,$pad=' '){$length=max(0,$length-self::length($s));$padLen=self::length($pad);return str_repeat($pad,$length/$padLen).self::substring($pad,0,$length %$padLen).$s;}/** @return string **/public static function padRight($s,$length,$pad=' '){$length=max(0,$length-self::length($s));$padLen=self::length($pad);return$s.str_repeat($pad,$length/$padLen).self::substring($pad,0,$length %$padLen);}/** @return string **/public static function reverse($s){return@iconv('UTF-32LE','UTF-8',strrev(@iconv('UTF-8','UTF-32BE',$s)));}public static function random($length=10,$charlist='0-9a-z'){return Random::generate($length,$charlist);}/** @return string|FALSE returns FALSE if the needle was not found **/public static function before($haystack,$needle,$nth=1){$pos=self::pos($haystack,$needle,$nth);return$pos===FALSE?FALSE:substr($haystack,0,$pos);}/** @return string|FALSE returns FALSE if the needle was not found **/public static function after($haystack,$needle,$nth=1){$pos=self::pos($haystack,$needle,$nth);return$pos===FALSE?FALSE:(string)substr($haystack,$pos+strlen($needle));}/** @return int|FALSE offset in bytes or FALSE if the needle was not found **/private static function pos($haystack,$needle,$nth=1){if(!$nth){return FALSE;}elseif($nth>0){if(strlen($needle)===0){return 0;}$pos=0;while(FALSE!==($pos=strpos($haystack,$needle,$pos))&&--$nth){$pos++;}}else{$len=strlen($haystack);if(strlen($needle)===0){return$len;}$pos=$len-1;while(FALSE!==($pos=strrpos($haystack,$needle,$pos-$len))&&++$nth){$pos--;}}return$pos;}/** @return array **/public static function split($subject,$pattern,$flags=0){return self::pcre('preg_split',array($pattern,$subject,-1,$flags|PREG_SPLIT_DELIM_CAPTURE));}/** @return mixed **/public static function match($subject,$pattern,$flags=0,$offset=0){if($offset>strlen($subject)){return NULL;}return self::pcre('preg_match',array($pattern,$subject,&$m,$flags,$offset))?$m:NULL;}/** @return array **/public static function matchAll($subject,$pattern,$flags=0,$offset=0){if($offset>strlen($subject)){return array();}self::pcre('preg_match_all',array($pattern,$subject,&$m,($flags&PREG_PATTERN_ORDER)?$flags:($flags|PREG_SET_ORDER),$offset));return$m;}/** @return string **/public static function replace($subject,$pattern,$replacement=NULL,$limit=-1){if(is_object($replacement)||is_array($replacement)){if($replacement instanceof Nette\Callback){$replacement=$replacement->getNative();}if(!is_callable($replacement,FALSE,$textual)){throw new Nette\InvalidStateException("Callback '$textual' is not callable.");}return self::pcre('preg_replace_callback',array($pattern,$replacement,$subject,$limit));}elseif($replacement===NULL&&is_array($pattern)){$replacement=array_values($pattern);$pattern=array_keys($pattern);}return self::pcre('preg_replace',array($pattern,$replacement,$subject,$limit));}public static function pcre($func,$args){static$messages=array(PREG_INTERNAL_ERROR=>'Internal error',PREG_BACKTRACK_LIMIT_ERROR=>'Backtrack limit was exhausted',PREG_RECURSION_LIMIT_ERROR=>'Recursion limit was exhausted',PREG_BAD_UTF8_ERROR=>'Malformed UTF-8 data',PREG_BAD_UTF8_OFFSET_ERROR=>'Offset didn\'t correspond to the begin of a valid UTF-8 code point',6=>'Failed due to limited JIT stack space');$res=Callback::invokeSafe($func,$args,function($message)use($args){throw new RegexpException($message.' in pattern: '.implode(' or ',(array)$args[0]));});if(($code=preg_last_error())&&($res===NULL||!in_array($func,array('preg_filter','preg_replace_callback','preg_replace')))){throw new RegexpException((isset($messages[$code])?$messages[$code]:'Unknown error').' (pattern: '.implode(' or ',(array)$args[0]).')',$code);}return$res;}}'is_bool','boolean'=>'is_bool','int'=>'is_int','integer'=>'is_int','float'=>'is_float','number'=>NULL,'numeric'=>array(__CLASS__,'isNumeric'),'numericint'=>array(__CLASS__,'isNumericInt'),'string'=>'is_string','unicode'=>array(__CLASS__,'isUnicode'),'array'=>'is_array','list'=>array('Nette\Utils\Arrays','isList'),'object'=>'is_object','resource'=>'is_resource','scalar'=>'is_scalar','callable'=>array(__CLASS__,'isCallable'),'null'=>'is_null','email'=>array(__CLASS__,'isEmail'),'url'=>array(__CLASS__,'isUrl'),'uri'=>array(__CLASS__,'isUri'),'none'=>array(__CLASS__,'isNone'),'type'=>array(__CLASS__,'isType'),'identifier'=>array(__CLASS__,'isPhpIdentifier'),'pattern'=>NULL,'alnum'=>'ctype_alnum','alpha'=>'ctype_alpha','digit'=>'ctype_digit','lower'=>'ctype_lower','upper'=>'ctype_upper','space'=>'ctype_space','xdigit'=>'ctype_xdigit');protected static$counters=array('string'=>'strlen','unicode'=>array('Nette\Utils\Strings','length'),'array'=>'count','list'=>'count','alnum'=>'strlen','alpha'=>'strlen','digit'=>'strlen','lower'=>'strlen','space'=>'strlen','upper'=>'strlen','xdigit'=>'strlen');/** @return void **/public static function assert($value,$expected,$label='variable'){if(!static::is($value,$expected)){$expected=str_replace(array('|',':'),array(' or ',' in range '),$expected);if(is_array($value)){$type='array('.count($value).')';}elseif(is_object($value)){$type='object '.get_class($value);}elseif(is_string($value)&&strlen($value)<40){$type="string '$value'";}else{$type=gettype($value);}throw new AssertionException("The $label expects to be $expected, $type given.");}}/** @return void **/public static function assertField($arr,$field,$expected=NULL,$label="item '%' in array"){self::assert($arr,'array','first argument');if(!array_key_exists($field,$arr)){throw new AssertionException('Missing '.str_replace('%',$field,$label).'.');}elseif($expected){static::assert($arr[$field],$expected,str_replace('%',$field,$label));}}/** @return bool **/public static function is($value,$expected){foreach(explode('|',$expected)as$item){list($type)=$item=explode(':',$item,2);if(isset(static::$validators[$type])){if(!call_user_func(static::$validators[$type],$value)){continue;}}elseif($type==='number'){if(!is_int($value)&&!is_float($value)){continue;}}elseif($type==='pattern'){if(preg_match('|^'.(isset($item[1])?$item[1]:'').'\z|',$value)){return TRUE;}continue;}elseif(!$value instanceof$type){continue;}if(isset($item[1])){$length=$value;if(isset(static::$counters[$type])){$length=call_user_func(static::$counters[$type],$value);}$range=explode('..',$item[1]);if(!isset($range[1])){$range[1]=$range[0];}if(($range[0]!==''&&$length<$range[0])||($range[1]!==''&&$length>$range[1])){continue;}}return TRUE;}return FALSE;}/** @return bool **/public static function isNumericInt($value){return is_int($value)||is_string($value)&&preg_match('#^-?[0-9]+\z#',$value);}/** @return bool **/public static function isNumeric($value){return is_float($value)||is_int($value)||is_string($value)&&preg_match('#^-?[0-9]*[.]?[0-9]+\z#',$value);}/** @return bool **/public static function isCallable($value){return$value&&is_callable($value,TRUE);}/** @return bool **/public static function isUnicode($value){return is_string($value)&&preg_match('##u',$value);}/** @return bool **/public static function isNone($value){return$value==NULL;}/** @return bool **/public static function isList($value){return Arrays::isList($value);}/** @return bool **/public static function isInRange($value,$range){return(!isset($range[0])||$range[0]===''||$value>=$range[0])&&(!isset($range[1])||$range[1]===''||$value<=$range[1]);}/** @return bool **/public static function isEmail($value){$atom="[-a-z0-9!#$%&'*+/=?^_`{|}~]";$alpha="a-z\x80-\xFF";return(bool)preg_match("(^ (\"([ !#-[\\]-~]*|\\\\[ -~])+\"|$atom+(\\.$atom+)*) # quoted or unquoted @ ([0-9$alpha]([-0-9$alpha]{0,61}[0-9$alpha])?\\.)+ # domain - RFC 1034 [$alpha]([-0-9$alpha]{0,17}[$alpha])? # top domain \\z)ix",$value);}/** @return bool **/public static function isUrl($value){$alpha="a-z\x80-\xFF";return(bool)preg_match("(^ https?://( (([-_0-9$alpha]+\\.)* # subdomain [0-9$alpha]([-0-9$alpha]{0,61}[0-9$alpha])?\\.)? # domain [$alpha]([-0-9$alpha]{0,17}[$alpha])? # top domain |\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3} # IPv4 |\[[0-9a-f:]{3,39}\] # IPv6 )(:\\d{1,5})? # port (/\\S*)? # path \\z)ix",$value);}/** @return bool **/public static function isUri($value){return(bool)preg_match('#^[a-z\d+\.-]+:\S+\z#i',$value);}/** @return bool **/public static function isType($type){return class_exists($type)||interface_exists($type)||(PHP_VERSION_ID>=50400&&trait_exists($type));}/** @return bool **/public static function isPhpIdentifier($value){return is_string($value)&&preg_match('#^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*\z#',$value);}}u]dh/w5GBMB