Overview

Namespaces

  • MvcCore
    • Ext
      • Auth
        • Virtual
      • Debug
        • Tracy
      • Form
        • Core
        • Validators
      • Request
      • Router
        • Lang
      • View
        • Helpers
  • None

Classes

  • MvcCore
  • MvcCore\Config
  • MvcCore\Controller
  • MvcCore\Debug
  • MvcCore\Ext\Auth
  • MvcCore\Ext\Auth\Controller
  • MvcCore\Ext\Auth\SignInForm
  • MvcCore\Ext\Auth\SignOutForm
  • MvcCore\Ext\Auth\User
  • MvcCore\Ext\Auth\Virtual\Controller
  • MvcCore\Ext\Auth\Virtual\Form
  • MvcCore\Ext\Auth\Virtual\User
  • MvcCore\Ext\Debug\Tracy
  • MvcCore\Ext\Debug\Tracy\AuthPanel
  • MvcCore\Ext\Debug\Tracy\IncludePanel
  • MvcCore\Ext\Debug\Tracy\MvcCorePanel
  • MvcCore\Ext\Debug\Tracy\RoutingPanel
  • MvcCore\Ext\Debug\Tracy\SessionPanel
  • MvcCore\Ext\Form
  • MvcCore\Ext\Form\Button
  • MvcCore\Ext\Form\Checkbox
  • MvcCore\Ext\Form\CheckboxGroup
  • MvcCore\Ext\Form\Core\Base
  • MvcCore\Ext\Form\Core\Configuration
  • MvcCore\Ext\Form\Core\Field
  • MvcCore\Ext\Form\Core\FieldGroup
  • MvcCore\Ext\Form\Core\Helpers
  • MvcCore\Ext\Form\Core\Validator
  • MvcCore\Ext\Form\Core\View
  • MvcCore\Ext\Form\CountrySelect
  • MvcCore\Ext\Form\Date
  • MvcCore\Ext\Form\DateTime
  • MvcCore\Ext\Form\Email
  • MvcCore\Ext\Form\Hidden
  • MvcCore\Ext\Form\NoType
  • MvcCore\Ext\Form\Number
  • MvcCore\Ext\Form\Password
  • MvcCore\Ext\Form\RadioGroup
  • MvcCore\Ext\Form\Range
  • MvcCore\Ext\Form\ResetButton
  • MvcCore\Ext\Form\ResetInput
  • MvcCore\Ext\Form\Select
  • MvcCore\Ext\Form\SubmitButton
  • MvcCore\Ext\Form\SubmitInput
  • MvcCore\Ext\Form\Text
  • MvcCore\Ext\Form\Textarea
  • MvcCore\Ext\Form\Time
  • MvcCore\Ext\Form\Validators\CompanyId
  • MvcCore\Ext\Form\Validators\CompanyVatId
  • MvcCore\Ext\Form\Validators\Date
  • MvcCore\Ext\Form\Validators\Email
  • MvcCore\Ext\Form\Validators\FloatVal
  • MvcCore\Ext\Form\Validators\Integer
  • MvcCore\Ext\Form\Validators\Maxlength
  • MvcCore\Ext\Form\Validators\MaxSelectedOptions
  • MvcCore\Ext\Form\Validators\MinSelectedOptions
  • MvcCore\Ext\Form\Validators\NumberField
  • MvcCore\Ext\Form\Validators\Pattern
  • MvcCore\Ext\Form\Validators\Phone
  • MvcCore\Ext\Form\Validators\RangeField
  • MvcCore\Ext\Form\Validators\SafeString
  • MvcCore\Ext\Form\Validators\Time
  • MvcCore\Ext\Form\Validators\Url
  • MvcCore\Ext\Form\Validators\ValueInOptions
  • MvcCore\Ext\Form\Validators\ZipCode
  • MvcCore\Ext\Request\ApacheDpi
  • MvcCore\Ext\Request\Cli
  • MvcCore\Ext\Router\Lang
  • MvcCore\Ext\Router\Lang\Route
  • MvcCore\Ext\Router\Media
  • MvcCore\Ext\Router\MediaSiteKey
  • MvcCore\Ext\View\Helpers\Assets
  • MvcCore\Ext\View\Helpers\Css
  • MvcCore\Ext\View\Helpers\Js
  • MvcCore\Ext\View\Helpers\LineBreaks
  • MvcCore\Model
  • MvcCore\Request
  • MvcCore\Response
  • MvcCore\Route
  • MvcCore\Router
  • MvcCore\Session
  • MvcCore\Tool
  • MvcCore\View

Exceptions

  • MvcCore\Ext\Form\Core\Exception
  • Overview
  • Namespace
  • Class
  • Tree
   1:    2:    3:    4:    5:    6:    7:    8:    9:   10:   11:   12:   13:   14:   15:   16:   17:   18:   19:   20:   21:   22:   23:   24:   25:   26:   27:   28:   29:   30:   31:   32:   33:   34:   35:   36:   37:   38:   39:   40:   41:   42:   43:   44:   45:   46:   47:   48:   49:   50:   51:   52:   53:   54:   55:   56:   57:   58:   59:   60:   61:   62:   63:   64:   65:   66:   67:   68:   69:   70:   71:   72:   73:   74:   75:   76:   77:   78:   79:   80:   81:   82:   83:   84:   85:   86:   87:   88:   89:   90:   91:   92:   93:   94:   95:   96:   97:   98:   99:  100:  101:  102:  103:  104:  105:  106:  107:  108:  109:  110:  111:  112:  113:  114:  115:  116:  117:  118:  119:  120:  121:  122:  123:  124:  125:  126:  127:  128:  129:  130:  131:  132:  133:  134:  135:  136:  137:  138:  139:  140:  141:  142:  143:  144:  145:  146:  147:  148:  149:  150:  151:  152:  153:  154:  155:  156:  157:  158:  159:  160:  161:  162:  163:  164:  165:  166:  167:  168:  169:  170:  171:  172:  173:  174:  175:  176:  177:  178:  179:  180:  181:  182:  183:  184:  185:  186:  187:  188:  189:  190:  191:  192:  193:  194:  195:  196:  197:  198:  199:  200:  201:  202:  203:  204:  205:  206:  207:  208:  209:  210:  211:  212:  213:  214:  215:  216:  217:  218:  219:  220:  221:  222:  223:  224:  225:  226:  227:  228:  229:  230:  231:  232:  233:  234:  235:  236:  237:  238:  239:  240:  241:  242:  243:  244:  245:  246:  247:  248:  249:  250:  251:  252:  253:  254:  255:  256:  257:  258:  259:  260:  261:  262:  263:  264:  265:  266:  267:  268:  269:  270:  271:  272:  273:  274:  275:  276:  277:  278:  279:  280:  281:  282:  283:  284:  285:  286:  287:  288:  289:  290:  291:  292:  293:  294:  295:  296:  297:  298:  299:  300:  301:  302:  303:  304:  305:  306:  307:  308:  309:  310:  311:  312:  313:  314:  315:  316:  317:  318:  319:  320:  321:  322:  323:  324:  325:  326:  327:  328:  329:  330:  331:  332:  333:  334:  335:  336:  337:  338:  339:  340:  341:  342:  343:  344:  345:  346:  347:  348:  349:  350:  351:  352:  353:  354:  355:  356:  357:  358:  359:  360:  361:  362:  363:  364:  365:  366:  367:  368:  369:  370:  371:  372:  373:  374:  375:  376:  377:  378:  379:  380:  381:  382:  383:  384:  385:  386:  387:  388:  389:  390:  391:  392:  393:  394:  395:  396:  397:  398:  399:  400:  401:  402:  403:  404:  405:  406:  407:  408:  409:  410:  411:  412:  413:  414:  415:  416:  417:  418:  419:  420:  421:  422:  423:  424:  425:  426:  427:  428:  429:  430:  431:  432:  433:  434:  435:  436:  437:  438:  439:  440:  441:  442:  443:  444:  445:  446:  447:  448:  449:  450:  451:  452:  453:  454:  455:  456:  457:  458:  459:  460:  461:  462:  463:  464:  465:  466:  467:  468:  469:  470:  471:  472:  473:  474:  475:  476:  477:  478:  479:  480:  481:  482:  483:  484:  485:  486:  487:  488:  489:  490:  491:  492:  493:  494:  495:  496:  497:  498:  499:  500:  501:  502:  503:  504:  505:  506:  507:  508:  509:  510:  511:  512:  513:  514:  515:  516:  517:  518:  519:  520:  521:  522:  523:  524:  525:  526:  527:  528:  529:  530:  531:  532:  533:  534:  535:  536:  537:  538:  539:  540:  541:  542:  543:  544:  545:  546:  547:  548:  549:  550:  551:  552:  553:  554:  555:  556:  557:  558:  559:  560:  561:  562:  563:  564:  565:  566:  567:  568:  569:  570:  571:  572:  573:  574:  575:  576:  577:  578:  579:  580:  581:  582:  583:  584:  585:  586:  587:  588:  589:  590:  591:  592:  593:  594:  595:  596:  597:  598:  599:  600:  601:  602:  603:  604:  605:  606:  607:  608:  609:  610:  611:  612:  613:  614:  615:  616:  617:  618:  619:  620:  621:  622:  623:  624:  625:  626:  627:  628:  629:  630:  631:  632:  633:  634:  635:  636:  637:  638:  639:  640:  641:  642:  643:  644:  645:  646:  647:  648:  649:  650:  651:  652:  653:  654:  655:  656:  657:  658:  659:  660:  661:  662:  663:  664:  665:  666:  667:  668:  669:  670:  671:  672:  673:  674:  675:  676:  677:  678:  679:  680:  681:  682:  683:  684:  685:  686:  687:  688:  689:  690:  691:  692:  693:  694:  695:  696:  697:  698:  699:  700:  701:  702:  703:  704:  705:  706:  707:  708:  709:  710:  711:  712:  713:  714:  715:  716:  717:  718:  719:  720:  721:  722:  723:  724:  725:  726:  727:  728:  729:  730:  731:  732:  733:  734:  735:  736:  737:  738:  739:  740:  741:  742:  743:  744:  745:  746:  747:  748:  749:  750:  751:  752:  753:  754:  755:  756:  757:  758:  759:  760:  761:  762:  763:  764:  765:  766:  767:  768:  769:  770:  771:  772:  773:  774:  775:  776:  777:  778:  779:  780:  781:  782:  783:  784:  785:  786:  787:  788:  789:  790:  791:  792:  793:  794:  795:  796:  797:  798:  799:  800:  801:  802:  803:  804:  805:  806:  807:  808:  809:  810:  811:  812:  813:  814:  815:  816:  817:  818:  819:  820:  821:  822:  823:  824:  825:  826:  827:  828:  829:  830:  831:  832:  833:  834:  835:  836:  837:  838:  839:  840:  841:  842:  843:  844:  845:  846:  847:  848:  849:  850:  851:  852:  853:  854:  855:  856:  857:  858:  859:  860:  861:  862:  863:  864:  865:  866:  867:  868:  869:  870:  871:  872:  873:  874:  875:  876:  877:  878:  879:  880:  881:  882:  883:  884:  885:  886:  887:  888:  889:  890:  891:  892:  893:  894:  895:  896:  897:  898:  899:  900:  901:  902:  903:  904:  905:  906:  907:  908:  909:  910:  911:  912:  913:  914:  915:  916:  917:  918:  919:  920:  921:  922:  923:  924:  925:  926:  927:  928:  929:  930:  931:  932:  933:  934:  935:  936:  937:  938:  939:  940:  941:  942:  943:  944:  945:  946:  947:  948:  949:  950:  951:  952:  953:  954:  955:  956:  957:  958:  959:  960:  961:  962:  963:  964:  965:  966:  967:  968:  969:  970:  971:  972:  973:  974:  975:  976:  977:  978:  979:  980:  981:  982:  983:  984:  985:  986:  987:  988:  989:  990:  991:  992:  993:  994:  995:  996:  997:  998:  999: 1000: 1001: 1002: 1003: 1004: 1005: 1006: 1007: 1008: 1009: 1010: 1011: 1012: 1013: 1014: 1015: 1016: 1017: 1018: 1019: 1020: 1021: 1022: 1023: 1024: 1025: 1026: 1027: 1028: 1029: 1030: 1031: 1032: 1033: 1034: 1035: 1036: 1037: 1038: 1039: 1040: 1041: 1042: 1043: 1044: 1045: 
<?php

/**
 * MvcCore
 *
 * This source file is subject to the BSD 3 License
 * For the full copyright and license information, please view 
 * the LICENSE.md file that are distributed with this source code.
 *
 * @copyright   Copyright (c) 2016 Tom Flídr (https://github.com/mvccore/mvccore)
 * @license     https://mvccore.github.io/docs/mvccore/4.0.0/LICENCE.md
 */

require_once('MvcCore/Request.php');
require_once('MvcCore/Response.php');
require_once('MvcCore/Router.php');
require_once('MvcCore/Route.php');
require_once('MvcCore/Config.php');
require_once('MvcCore/Debug.php');

/**
 * Application MVC core:
 * - main application objects container
 * - MvcCore compile mode managing
 * - store for main core class names to use them later 
 *   for run, creating instances or static usage
 * - application run processing:
 *   - completing request and response
 *   - calling pre/post handlers
 *   - controller/action dispatching
 *   - error handling and error responses
 */
class MvcCore
{
    /**
     * MvcCore - version:
     * Comparation by PHP function version_compare();
     * @see http://php.net/manual/en/function.version-compare.php
     */
    const VERSION = '4.2.0';
    /**
     * MvcCore application mode describing that the application is compiled in one big php file.
     * In PHP app mode should be packed php files or any asset files - phtml templates, ini files 
     * or any static files. Unknown asset files or binary files are included as binary or base64 string.
     * This mode has always best speed, because it shoud not work with hard drive if you dont want.
     * Only with many or with large asset files, there may be greater demands on memory and processor, 
     * which shouldn't be good for your application. Be aware to do that. 
     * Result application packed in PHP mode has special '\Packager_Php_Wrapper' class included 
     * before any application content. This special class handles allowed file operations and assets 
     * as binary or base64 encoded. Everything shoud be configured before PHP packing.
     * This mode has always four submodes started with PHP substring. All PHP package modes are:
     * 'PHP_PRESERVE_HDD', 'PHP_PRESERVE_PACKAGE', 'PHP_STRICT_HDD' and 'PHP_STRICT_PACKAGE'.
     * So to check if app is in PHP package mode - check it by substr();
     * @var string
     */
    const COMPILED_PHP = 'PHP';

    /**
     * MvcCore application mode describing that the application is compiled in one big phar file.
     * There could be any content included but there is no speed advantages, but it is
     * still good way to pack your app into single file tool for any web-hosting needs:-)
     * This mode has always lower speed then PHP mode, because it fully emulates hard drive 
     * for content of this file and it costs a time. But it has lower memory usage then PHP mode.
     * @see http://php.net/manual/en/phar.creating.php
     * @var string
     */
    const COMPILED_PHAR = 'PHAR';

    /**
     * MvcCore application mode describing that the application is in the state before 
     * their own compilation into PHP or PHAR archive. This mode is always used to generate final 
     * javascript and css files into teporary directory to pack them into result php/phar file.
     * Shortcut SFU means "Single File Url". Application running in this mode has to generate
     * single file urls in form: "index.php?..." and everithing has to work properly before 
     * application will be compiled into PHP/PHAR package. Use this mode in index.php before 
     * application compilation to generate and test everything necessary before app compilation by:
     * MvcCore::GetInstance()->Run(TRUE); --> true means switch temporary into SFU mode.
     * @var string
     */
    const COMPILED_SFU = 'SFU';

    /**
     * MvcCore application mode describing that the application is running as standard php project
     * in many files using autoloading or anything else.
     * @var string
     */
    const NOT_COMPILED = '';

    /**
     * Application instance for current request.
     * @var MvcCore
     */
    protected static $instance;

    /**
     * Describes application running as standard php project or as single file.
     * It shoud has values 'PHP', 'PHAR', 'SFU' or ''.
     * @var string
     */
    protected $compiled = null;
    
    /**
     * Time when \MvcCore::Run has been called.
     * @var int
     */
    protected $microtime = 0;
    
    /**
     * Application currently dispatched controller instance
     * @var \MvcCore\Controller
     */
    protected $controller = NULL;

    /**
     * Request object - parsed uri, query params, app paths...
     * @var \MvcCore\Request
     */
    protected $request;

    /**
     * Response object - headers and rendered body
     * @var \MvcCore\Response
     */
    protected $response;
    
    /**
     * Application http route.
     * @var \MvcCore\Router
     */
    protected $router = null;
    
    /**
     * Pre route custom closure calls.
     * Params in closure function has to be:
     *  - reference for request
     *  - reference for response
     * @example
     *   \MvcCore::AddPreRouteHandler(function (\MvcCore\Request & $request, \MvcCore\Response & $response) {
     *      $request->customVar = 'custom_value';
     *   });
     * @var callable[]
     */
    protected $preRouteHandlers = array();

    /**
     * Pre dispatch custom closure calls.
     * Params in closure function has to be:
     *  - reference for request
     *  - reference for response
     * @example
     *   \MvcCore::AddPreDispatchHandler(function (\MvcCore\Request & $request, \MvcCore\Response & $response) {
     *      $request->customVar = 'custom_value';
     *   });
     * @var callable[]
     */
    protected $preDispatchHandlers = array();

    /**
     * Post dispatch custom closure calls.
     * Params in closure function has to be:
     *  - reference for request
     *  - reference for response
     * @example
     *   \MvcCore::AddPostDispatchHandler(function (\MvcCore\Request & $request, \MvcCore\Response & $response) {
     *      $response->Output = 'custom_value';
     *   });
     * @var callable[]
     */
    protected $postDispatchHandlers = array();

    /**
     * Class to load and parse system config.
     * @var string
     */
    protected $configClass = '\MvcCore\Config';

    /**
     * Class to configure session proxy class.
     * @var string
     */
    protected $sessionClass = '\MvcCore\Session';

    /**
     * Class to create http request object.
     * @var string
     */
    protected $requestClass = '\MvcCore\Request';

    /**
     * Class to create http response object.
     * @var string
     */
    protected $responseClass = '\MvcCore\Response';

    /**
     * Class to create and dispatch request by its routes.
     * @var string
     */
    protected $routerClass = '\MvcCore\Router';

    /**
     * Class to create and render controller view.
     * @var string
     */
    protected $viewClass = '\MvcCore\View';

    /**
     * Class to handle any application error to render or log.
     * @var string
     */
    protected $debugClass = '\MvcCore\Debug';

    /**
     * Application directory with subdirectories by default: 
     * 'Controllers', 'Models' and 'Views'.
     * @var string
     */
    protected $appDir = 'App';

    /**
     * Controllers directory name for all controller classes, 
     * it has to be placed directly in application directory.
     * @var string
     */
    protected $controllersDir = 'Controllers';

    /**
     * Views directory name for all view elements, it has to be 
     * placed directly in application directory.
     * @var string
     */
    protected $viewsDir = 'Views';

    /**
     * Default controller name.
     * @var string
     */
    protected $defaultControllerName = 'Index';

    /**
     * Default controller action name.
     * @var string
     */
    protected $defaultControllerDefaultActionName = 'Index';

    /**
     * Default controller error action name.
     * @var string
     */
    protected $defaultControllerErrorActionName = 'Error';

    /**
     * Default controller error action name.
     * @var string
     */
    protected $defaultControllerNotFoundActionName = 'NotFound';


    /***********************************************************************************
     *                                  static calls
     ***********************************************************************************/

    /**
     * Static constructor (called internaly - do not call this in application).
     * It initializes application compilation mode before \MvcCore::GetInstance()->Run();
     * @return void
     */
    public static function StaticInit () {
        $instance = static::GetInstance();
        $instance->microtime = microtime(TRUE);
        if (is_null($instance->compiled)) {
            $compiled = static::NOT_COMPILED;
            if (strpos(__FILE__, 'phar://') === 0) {
                $compiled = static::COMPILED_PHAR;
            } else if (class_exists('\Packager_Php_Wrapper')) {
                $compiled = constant('\Packager_Php_Wrapper::FS_MODE');
            }
            $instance->compiled = $compiled;
        }
    }

    /**
     * Returns singleton \MvcCore application instance.
     * @return \MvcCore
     */
    public static function & GetInstance () {
        if (!static::$instance) static::$instance = new static();
        return static::$instance;
    }

    /**
     * Add pre route handler into queue.
     * Closure functions has to be void.
     * Params in closure function has to be:
     *  - reference for request
     *  - reference for response
     * @param callable $handler
     * @return void
     */
    public static function AddPreRouteHandler (callable $handler) {
        static::GetInstance()->preRouteHandlers[] = $handler;
    }

    /**
     * Add pre dispatch handler into queue.
     * Closure functions has to be void.
     * Params in closure function has to be:
     *  - reference for request
     *  - reference for response
     * @param callable $handler
     * @return void
     */
    public static function AddPreDispatchHandler (callable $handler) {
        static::GetInstance()->preDispatchHandlers[] = $handler;
    }

    /**
     * Add post dispatch handler into queue.
     * Closure functions has to be void.
     * Params in closure function has to be:
     *  - reference for request
     *  - reference for response
     * @param callable $handler
     * @return void
     */
    public static function AddPostDispatchHandler (callable $handler) {
        static::GetInstance()->postDispatchHandlers[] = $handler;
    }

    /**
     * Starts a session, standardly called in \MvcCore\Controller::Init();
     * But is shoud be called anywhere before, for example in any prerequest handler
     * to redesign request before MVC dispatching.
     * @return void
     */
    public static function SessionStart () {
        $sessionClass = \MvcCore::GetInstance()->sessionClass;
        $sessionClass::Start();
    }


    /***********************************************************************************
     *                                getters and setters
     ***********************************************************************************/

    /**
     * Get application compilation state value.
     * @return string
     */
    public function GetCompiled () {
        return $this->compiled;
    }

    /**
     * Get application request class, extended from \MvcCore\Request.
     * @return string
     */
    public function GetRequestClass () {
        return $this->requestClass;
    }

    /**
     * Get application response class, extended from \MvcCore\Response.
     * @return string
     */
    public function GetResponseClass () {
        return $this->responseClass;
    }

    /**
     * Get application router class, extended from \MvcCore\Router.
     * @return string
     */
    public function GetRouterClass () {
        return $this->routerClass;
    }

    /**
     * Get application config class, extended from \MvcCore\Config.
     * @return string
     */
    public function GetConfigClass () {
        return $this->configClass;
    }

    /**
     * Get application session class, extended from \MvcCore\Session.
     * @return string
     */
    public function GetSessionClass () {
        return $this->sessionClass;
    }

    /**
     * Get application view class, extended from \MvcCore\View.
     * @return string
     */
    public function GetViewClass () {
        return $this->viewClass;
    }

    /**
     * Get application debug class, extended from \MvcCore\Debug.
     * @return string
     */
    public function GetDebugClass () {
        return $this->debugClass;
    }

    /**
     * Get microtime, when MvcCore.php has been declarated.
     * @return string
     */
    public function GetMicrotime () {
        return $this->microtime;
    }

    /**
     * Returns currently used instance of \MvcCore\Router
     * @return \MvcCore\Router
     */
    public function GetRouter () {
        return $this->router;
    }

    /**
     * Returns instance of \MvcCore\Controller, currently dispatched by request.
     * @return \MvcCore\Controller
     */
    public function & GetController () {
        return $this->controller;
    }

    /**
     * Get application request instance, extended from \MvcCore\Request
     * @return \MvcCore\Request
     */
    public function & GetRequest () {
        return $this->request;
    }

    /**
     * Get application response instance, extended from \MvcCore\Response
     * @return \MvcCore\Response
     */
    public function & GetResponse () {
        return $this->response;
    }

    /**
     * Get application directory, where are 'Controllers',
     * 'Models' and 'Views' directories located. 'App' value by default.
     * @return string
     */
    public function GetAppDir () {
        return $this->appDir;
    }

    /**
     * Get controllers directory, where are controllers located.
     * 'Controllers' directory shoud be located in Application directory.
     * 'Controllers' value by default.
     * @return string
     */
    public function GetControllersDir () {
        return $this->controllersDir;
    }

    /**
     * Get views directory, where are views located.
     * 'Views' directory shoud be located in Application directory.
     * 'Views' value by default.
     * @return string
     */
    public function GetViewsDir () {
        return $this->viewsDir;
    }

    /**
     * Returns array with default controller name and default action nam.
     * @return array
     */
    public function GetDefaultControllerAndActionNames () {
        return array($this->defaultControllerName, $this->defaultControllerDefaultActionName);
    }

    /**
     * Set application compilation state value.
     * @param string $compiled
     * @return \MvcCore
     */
    public function SetCompiled ($compiled = '') {
        $this->compiled = $compiled;
        return $this;
    }

    /**
     * Set config class, extended from \MvcCore\Config.
     * Core configuration method.
     * @param string $configClass 
     * @return \MvcCore
     */
    public function SetConfigClass ($configClass) {
        @class_exists($configClass); // load the class
        $this->configClass = $configClass;
        return $this;
    }

    /**
     * Set session class, extended from \MvcCore\Session.
     * Core configuration method.
     * @param string $sessionClass
     * @return \MvcCore
     */
    public function SetSessionClass ($sessionClass) {
        @class_exists($sessionClass); // load the class
        $this->sessionClass = $sessionClass;
        return $this;
    }

    /**
     * Set request class, extended from \MvcCore\Request.
     * Core configuration method.
     * @param string $requestClass
     * @return \MvcCore
     */
    public function SetRequestClass ($requestClass) {
        @class_exists($requestClass); // load the class
        $this->requestClass = $requestClass;
        return $this;
    }

    /**
     * Set request class, extended from \MvcCore\Response.
     * Core configuration method.
     * @param string $responseClass
     * @return \MvcCore
     */
    public function SetResponseClass ($responseClass) {
        @class_exists($responseClass); // load the class
        $this->responseClass = $responseClass;
        return $this;
    }

    /**
     * Set router class, extended from \MvcCore\Router.
     * Core configuration method.
     * @param string $routerClass
     * @return \MvcCore
     */
    public function SetRouterClass ($routerClass) {
        @class_exists($routerClass); // load the class
        $this->routerClass = $routerClass;
        return $this;
    }

    /**
     * Set view class, extended from \MvcCore\View.
     * Core configuration method.
     * @param string $viewClass
     * @return \MvcCore
     */
    public function SetViewClass ($viewClass) {
        @class_exists($viewClass); // load the class
        $this->viewClass = $viewClass;
        return $this;
    }

    /**
     * Set debug class, extended from \MvcCore\Debug.
     * Core configuration method.
     * @param string $debugClass
     * @return \MvcCore
     */
    public function SetDebugClass ($debugClass) {
        @class_exists($debugClass); // load the class
        $this->debugClass = $debugClass;
        return $this;
    }

    /**
     * Set application directory, where are 'Controllers',
     * 'Models' and 'Views' directories located. 'App' value by default.
     * Core configuration method.
     * @param string $appDir
     * @return \MvcCore
     */
    public function SetAppDir ($appDir) {
        $this->appDir = $appDir;
        return $this;
    }

    /**
     * Set controllers directory, where are controllers located.
     * 'Controllers' directory shoud be located in Application directory.
     * 'Controllers' value by default.
     * Core configuration method.
     * @param string $controllersDir
     * @return \MvcCore
     */
    public function SetControllersDir ($controllersDir) {
        $this->controllersDir = $controllersDir;
        return $this;
    }

    /**
     * Set views directory, where are views located.
     * 'Views' directory shoud be located in Application directory.
     * 'Views' value by default.
     * Core configuration method.
     * @param string $viewsDir
     * @return \MvcCore
     */
    public function SetViewsDir ($viewsDir) {
        $this->viewsDir = $viewsDir;
        return $this;
    }

    /**
     * Set default controller name.
     * 'Default' value by default.
     * Core configuration method.
     * @param string $defaultControllerName
     * @return \MvcCore
     */
    public function SetDefaultControllerName ($defaultControllerName) {
        $this->defaultControllerName = $defaultControllerName;
        return $this;
    }

    /**
     * Set default controller default action name.
     * 'Default' value by default.
     * Core configuration method.
     * @param string $defaultActionName
     * @return \MvcCore
     */
    public function SetDefaultControllerDefaultActionName ($defaultActionName) {
        $this->defaultControllerDefaultActionName = $defaultActionName;
        return $this;
    }

    /**
     * Set default controller common error action name.
     * 'Error' value by default.
     * Core configuration method.
     * @param string $defaultControllerErrorActionName
     * @return \MvcCore
     */
    public function SetDefaultControllerErrorActionName ($defaultControllerErrorActionName) {
        $this->defaultControllerErrorActionName = $defaultControllerErrorActionName;
        return $this;
    }

    /**
     * Set default controller not found error action name.
     * 'NotFound' value by default.
     * Core configuration method.
     * @param string $defaultControllerNotFoundActionName
     * @return \MvcCore
     */
    public function SetDefaultControllerNotFoundActionName ($defaultControllerNotFoundActionName) {
        $this->defaultControllerNotFoundActionName = $defaultControllerNotFoundActionName;
        return $this;
    }


    /***********************************************************************************
     *                                normal dispatching
     ***********************************************************************************/

    /**
     * Run application.
     * @param bool $singleFileUrl Set 'Single File Url' mode to compile assets and test everything before compilation
     * @return \MvcCore
     */
    public function Run ($singleFileUrl = FALSE) {
        if ($singleFileUrl) $this->compiled = static::COMPILED_SFU;
        return $this->process();
    }

    /**
     * Process request.
     *  1. Init debuginf and loging handlers if necessary
     *  2. Complete request.
     *  3. Call pre route handlers queue.
     *  4. Route request by configured router.
     *  5. Call pre dispatch handlers queue.
     *  6. Dispatch request
     *      - process controller methods
     *      - render and send view result
     *  7. Call post dispatch handlers queue.
     *  8. Write session and exit
     * @return \MvcCore
     */
    protected function process () {
        $this->request = \MvcCore\Request::GetInstance($_SERVER, $_GET, $_POST);
        $this->response = \MvcCore\Response::GetInstance();
        $debugClass = $this->debugClass;
        $debugClass::Init();
        if (!$this->processCustomHandlers($this->preRouteHandlers))         return $this->Terminate();
        if (!$this->routeRequest())                                         return $this->Terminate();
        if (!$this->processCustomHandlers($this->preDispatchHandlers))      return $this->Terminate();
        if (!$this->DispatchMvcRequest($this->router->GetCurrentRoute()))   return $this->Terminate();
        if (!$this->processCustomHandlers($this->postDispatchHandlers))     return $this->Terminate();
        return $this->Terminate();
    }

    /**
     * Route request by router obtained by \MvcCore\Router::GetInstance();
     * Store requested route inside router class to get it later by: 
     * MvcCore\Router::GetCurrentRoute();
     * @return bool
     */
    protected function routeRequest () {
        $routerClass = $this->routerClass;
        $this->router = $routerClass::GetInstance();
        try {
            $this->router->Route($this->request);
            return TRUE;
        } catch (\Exception $e) {
            return $this->DispatchException($e);
        }
    }

    /**
     * Process preroute, prerequest and postdispatch handlers queue by queues index
     * @param callable[] $handlers
     * @return bool
     */
    protected function processCustomHandlers (& $handlers = array()) {
        if (!$this->IsAppRequest()) return TRUE;
        $result = TRUE;
        foreach ($handlers as $handler) {
            if (is_callable($handler)) {
                try {
                    $handler($this->request, $this->response);
                } catch (\Exception $e) {
                    $this->DispatchException($e);
                    $result = FALSE;
                    break;
                }
            }
        }
        return $result;
    }

    /**
     * If controller class exists - try to dispatch controller, if only view file exists - try to render this view file.
     * @param \MvcCore\Request $request 
     * @param \MvcCore\Route $route 
     * @return bool
     */
    public function DispatchMvcRequest (\MvcCore\Route & $route = NULL) {
        if (is_null($route)) return $this->DispatchException(new \Exception('No route for request', 404));
        list ($controllerNamePascalCase, $actionNamePascalCase) = array($route->Controller, $route->Action);
        $actionName = $actionNamePascalCase . 'Action';
        $coreControllerName = '\MvcCore\Controller';
        $requestParams = $this->request->Params;
        $viewScriptFullPath = \MvcCore\View::GetViewScriptFullPath(
            \MvcCore\View::$ScriptsDir,
            $requestParams['controller'] . '/' . $requestParams['action']
        );
        if ($controllerNamePascalCase == 'Controller') {
            $controllerName = $coreControllerName;
        } else {
            // App_Controllers_$controllerNamePascalCase
            $controllerName = $this->CompleteControllerName($controllerNamePascalCase);
            if (!class_exists($controllerName)) {
                // if controller doesn't exists - check if at least view exists
                if (file_exists($viewScriptFullPath)) {
                    // if view exists - change controller name to core controller, if not let it go to exception
                    $controllerName = $coreControllerName;
                }
            }
        }
        return $this->DispatchControllerAction($controllerName, $actionName, $viewScriptFullPath, function (\Exception & $e) {
            return $this->DispatchException($e);
        });
    }

    /**
     * Dispatch controller by full class name and by action name.
     * @param string $controllerClassFullName
     * @param string $actionName 
     * @param callable $exceptionCallback 
     * @return bool
     */
    public function DispatchControllerAction ($controllerClassFullName, $actionName, $viewScriptFullPath, callable $exceptionCallback) {
        $this->controller = NULL;
        try {
            $this->controller = new $controllerClassFullName($this->request, $this->response);
        } catch (\Exception $e) {
            return $this->DispatchException(new \ErrorException($e->getMessage(), 404));
        }
        if (!method_exists($this->controller, $actionName) && $controllerClassFullName !== '\MvcCore\Controller') {
            if (!file_exists($viewScriptFullPath)) {
                $this->DispatchException(new \ErrorException(
                    "Controller '$controllerClassFullName' has not method '$actionName' "
                    ."or view doesn't exists in path: '$viewScriptFullPath'.", 404
                ));
            }
        }
        list($controllerNameDashed, $actionNameDashed) = array(
            $this->request->Params['controller'], $this->request->Params['action']
        );
        try {
            // \MvcCore\Debug::Timer('dispatch');
            $this->controller->Init();
            // \MvcCore\Debug::Timer('dispatch');
            $this->controller->PreDispatch();
            // \MvcCore\Debug::Timer('dispatch');
            if (method_exists($this->controller, $actionName)) $this->controller->$actionName();
            // \MvcCore\Debug::Timer('dispatch');
            $this->controller->Render($controllerNameDashed, $actionNameDashed);
            // \MvcCore\Debug::Timer('dispatch');
        } catch (\Exception $e) {
            return $exceptionCallback($e);
        }
        return TRUE;
    }

    /**
     * Generates url by:
     * - 'Controller:Action' name and params array
     *   (for routes configuration when routes array has keys with 'Controller:Action' strings
     *   and routes has not controller name and action name defined inside)
     * - route name and params array
     *   (route name is key in routes configuration array, should be any string
     *   but routes must have information about controller name and action name inside)
     * Result address should have two forms:
     * - nice rewrited url by routes configuration
     *   (for apps with .htaccess supporting url_rewrite and when first param is key in routes configuration array)
     * - for all other cases is url form: index.php?controller=ctrlName&action=actionName
     *   (when first param is not founded in routes configuration array)
     * @param string $controllerActionOrRouteName   Should be 'Controller:Action' combination or just any route name as custom specific string
     * @param array  $params                        optional
     * @return string
     */
    public function Url ($controllerActionOrRouteName = 'Index:Index', $params = array()) {
        return \MvcCore\Router::GetInstance()->Url($controllerActionOrRouteName, $params);
    }

    /**
     * Terminates any request, writes session and exits.
     * The only place in application where is called 'echo ....';
     * @return void
     */
    public function Terminate () {
        $sessionClass = $this->sessionClass;
        $sessionClass::Close();
        $this->response->Send(); // headers (if necessary) and echo
        exit;
    }


    /***********************************************************************************
     *                          request error dispatching
     ***********************************************************************************/
    
    /**
     * Process exception:
     *  - if PHP package packing to determinate dependencies
     *      - do not log or render nothing
     *  - if production mode
     *      - log error and try to render error page by App_Controller_Default::Error();
     *  - if development
     *      - print exception into browser
     * @param \Exception $e 
     * @return bool
     */
    public function DispatchException (\Exception $e) {
        if (class_exists('\Packager_Php')) return FALSE; // packing process
        if ($e->getCode() == 404) {
            \MvcCore\Debug::Log($e, \MvcCore\Debug::ERROR);
            $this->RenderNotFound($e->getMessage());
        } else if (\MvcCore\Config::IsDevelopment()) {
            \MvcCore\Debug::Exception($e);
        } else {
            \MvcCore\Debug::Log($e, \MvcCore\Debug::EXCEPTION);
            $this->RenderError($e);
        }
        return FALSE;
    }

    /**
     * Render error by Default controller Error action,
     * if there is no controller/action like that or any other exception happends,
     * it is processed very simple response with 500 http code.
     * @param \Exception $e
     * @return void
     */
    public function RenderError (\Exception $e) {
        $defaultCtrlFullName = $this->GetDefaultControllerIfHasAction(
            $this->defaultControllerErrorActionName
        );
        $exceptionMessage = $e->getMessage();
        if ($defaultCtrlFullName) {
            $this->request->Params = array_merge($this->request->Params, array(
                'code'      => 500,
                'message'   => $exceptionMessage,
                'controller'=> \MvcCore\Tool::GetDashedFromPascalCase($this->defaultControllerName),
                'action'    => \MvcCore\Tool::GetDashedFromPascalCase($this->defaultControllerErrorActionName),
            ));
            $this->DispatchControllerAction(
                $defaultCtrlFullName,
                $this->defaultControllerErrorActionName . "Action",
                '',
                function (\Exception & $e) use ($exceptionMessage) {
                    \MvcCore\Debug::Log($e, \MvcCore\Debug::EXCEPTION);
                    $this->RenderError500PlainText($exceptionMessage . PHP_EOL . PHP_EOL . $e->getMessage());
                }
            );
        } else {
            $this->RenderError500PlainText($exceptionMessage);
        }
    }

    /**
     * Render not found controller action or not found plain text response.
     * @return void
     */
    public function RenderNotFound ($exceptionMessage = '') {
        if (!$exceptionMessage) $exceptionMessage = 'Page not found.';
        $defaultCtrlFullName = $this->GetDefaultControllerIfHasAction(
            $this->defaultControllerNotFoundActionName
        );
        if ($defaultCtrlFullName) {
            $this->request->Params = array_merge($this->request->Params, array(
                'code'      => 404,
                'message'   => $exceptionMessage,
                'controller'=> \MvcCore\Tool::GetDashedFromPascalCase($this->defaultControllerName),
                'action'    => \MvcCore\Tool::GetDashedFromPascalCase($this->defaultControllerNotFoundActionName),
            ));
            $this->DispatchControllerAction(
                $defaultCtrlFullName,
                $this->defaultControllerNotFoundActionName . "Action",
                '',
                function (\Exception & $e) {
                    \MvcCore\Debug::Log($e, \MvcCore\Debug::EXCEPTION);
                    $this->RenderError404PlainText();
                }
            );
        } else {
            $this->RenderError404PlainText();
        }
    }

    /**
     * Process very simple internal server error (500) as plain text response.
     * @param string $text
     * @return void
     */
    public function RenderError500PlainText ($text = '') {
        if (!$text) $text = 'Internal Server Error.';
        $this->response = (new \MvcCore\Response(
            \MvcCore\Response::INTERNAL_SERVER_ERROR,
            array('Content-Type' => 'text/plain'),
            "Error 500:".PHP_EOL.PHP_EOL.$text
        ));
    }

    /**
     * Process very simple not found error (404) as plain text response.
     * @return void
     */
    public function RenderError404PlainText () {
        $this->response = (new \MvcCore\Response(
            \MvcCore\Response::NOT_FOUND,
            array('Content-Type' => 'text/plain'),
            'Error 404 – Page Not Found.'
        ));
    }


    /***********************************************************************************
     *                                  helper methods
     ***********************************************************************************/

    /**
     * Check if Default application controller ('App_Controllers_Default') has specific action.
     * If default controller has specific action - return default controller full name, else empty string.
     * @param string $actionName
     * @return string
     */
    public function GetDefaultControllerIfHasAction ($actionName) {
        $defaultControllerName = $this->CompleteControllerName($this->defaultControllerName);
        if (class_exists($defaultControllerName) && method_exists($defaultControllerName, $actionName.'Action')) {
            return $defaultControllerName;
        }
        return '';
    }

    /**
     * Complete MvcCore application controller full name always in form: 
     * 'App_Controller_$controllerNamePascalCase'
     * @param string $controllerNamePascalCase
     * @return string 
     */
    public function CompleteControllerName ($controllerNamePascalCase) {
        $firstChar = substr($controllerNamePascalCase, 0, 1);
        if ($firstChar == '\\') return $controllerNamePascalCase;
        return implode('\\', array(
            $this->appDir,
            $this->controllersDir,
            $controllerNamePascalCase
        ));
    }

    /**
     * Return if this is default controller error action dispatching process
     * @return bool
     */
    public function IsErrorDispatched () {
        $defaultCtrlName = \MvcCore\Tool::GetDashedFromPascalCase($this->defaultControllerName);
        $errorActionName = \MvcCore\Tool::GetDashedFromPascalCase($this->defaultControllerErrorActionName);
        $params = $this->request->Params;
        return $params['controller'] == $defaultCtrlName && $params['action'] == $errorActionName;
    }

    /**
     * Return if this is default controller not found action dispatching process
     * @return bool
     */
    public function IsNotFoundDispatched () {
        $defaultCtrlName = \MvcCore\Tool::GetDashedFromPascalCase($this->defaultControllerName);
        $errorActionName = \MvcCore\Tool::GetDashedFromPascalCase($this->defaultControllerNotFoundActionName);
        $params = $this->request->Params;
        return $params['controller'] == $defaultCtrlName && $params['action'] == $errorActionName;
    }

    /**
     * Return true if request is on any application script,
     * return false if request is on any asset
     * @return bool
     */
    public function IsAppRequest () {
        $params = $this->request->Params;
        $ctrlName = isset($params['controller']) ? $params['controller'] : '';
        if ($ctrlName != 'controller') return true;
        $actionName = isset($params['action']) ? $params['action'] : '';
        return $actionName != 'asset';
    }
}
\MvcCore::StaticInit();
MvcCore API documentation generated by ApiGen