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: 
<?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
 */

namespace MvcCore {
    
    require_once('Config.php');

    /**
     * Core debug tools
     * - printing any value by var_dump(); in fixed 
     *   bar at browser window right bottom border
     * - timing printing
     * - debuging shortcut functions initialization
     * - exceptions hdd logging or printing in development mode
     */
    class Debug
    {
        const
            DEBUG = 'debug',
            INFO = 'info',
            WARNING = 'warning',
            ERROR = 'error',
            EXCEPTION = 'exception',
            CRITICAL = 'critical',
            JAVASCRIPT = 'javascript';

        /**
         * Email recepient to send information about exceptions or errors.
         * 'admin@localhost' by default.
         * @var string
         */
        public static $EmailRecepient = 'admin@localhost';

        /**
         * Relative path from app root to store any log information.
         * '/Var/Logs' by default.
         * @var mixed
         */
        public static $LogDirectory = '/Var/Logs';

        /**
         * Semaphore to execute Init(); method only one time.
         * TRUE if development, FALSE if anything else
         * @var boolean
         */
        protected static $development = NULL;
    
        /**
         * Debuging and loging handlers, this shoud be customized in extended class.
         * @var array
         */
        protected static $handlers = array(
            'timer'             => 'timerHandler',
            'dump'              => 'dumpHandler',
            'barDump'           => 'dumpHandler',
            'log'               => 'dumpHandler',
            'fireLog'           => 'dumpHandler',
            'exceptionHandler'  => 'exceptionHandler',
            'shutdownHandler'   => 'ShutdownHandler',
        );

        /**
         * Store for printed dumps by output buffering to send it at response end.
         * @var array
         */
        protected static $dumps = array();

        /**
         * Store timers start points.
         * @var array
         */
        protected static $timers = array();

        /**
         * True for cofigured debug class as \MvcCore\Debug, FALSE for any other configured extension
         * @var bool
         */
        protected static $originalDebugClass = TRUE;

        /**
         * Initialize global development shorthands.
         * @param string $logDirectory relative path from app root
         * @var callable
         */
        public static $InitGlobalShortHands = array();

        /**
         * Initialize debuging and loging.
         * @return void
         */
        public static function Init () {
            if (!is_null(static::$development)) return;
            $app = \MvcCore::GetInstance();
            $configClass = $app->GetConfigClass();
            static::$development = $configClass::IsDevelopment();
            $cfg = $configClass::GetSystem();
            
            if (isset($cfg->debug)) {
                $cfgDebug = & $cfg->debug;
                if (isset($cfgDebug->emailRecepient)) {
                    static::$EmailRecepient = $cfgDebug->emailRecepient;
                }
                if (isset($cfgDebug->logDirectory)) {
                    static::$LogDirectory = $cfgDebug->logDirectory;
                }
            }
            
            $scriptPath = php_sapi_name() == 'cli'
                ? str_replace('\\', '/', getcwd()) . '/' . $_SERVER['SCRIPT_FILENAME']
                : str_replace('\\', '/', $_SERVER['SCRIPT_FILENAME']);
            $lastSlas = strrpos($scriptPath, '/');
            $appRoot = substr($scriptPath, 0, $lastSlas !== FALSE ? $lastSlas : strlen($scriptPath));
            static::$LogDirectory = $appRoot . static::$LogDirectory;

            static::$originalDebugClass = $app->GetDebugClass() == __CLASS__;
            static::initLogDirectory(static::$LogDirectory);
            static::initHandlers();
            $initGlobalShortHandsHandler = static::$InitGlobalShortHands;
            $initGlobalShortHandsHandler(static::$LogDirectory);
        }

        /**
         * Initialize debuging and loging handlers.
         * @return void
         */
        protected static function initHandlers () {
            foreach (static::$handlers as $key => $value) {
                static::$handlers[$key] = array(__CLASS__, $value);
            }
            static::$handlers = (object) static::$handlers;
            register_shutdown_function(self::$handlers->shutdownHandler);
        }

        /**
         * If log directory doesn't exist, create new directory - relative from app root.
         * @param string $logDirectory relative path from app root
         * @return void
         */
        protected static function initLogDirectory ($logDirectory) {
            if (!is_dir($logDirectory)) mkdir($logDirectory, 0777, TRUE);
            if (!is_writable($logDirectory)) {
                try {
                    chmod($logDirectory, 0777);
                } catch (\Exception $e) {
                    die('['.static::class.'] ' . $e->getMessage());
                }
            }
        }

        /**
         * Starts/stops stopwatch.
         * @param  string  $name time pointer name
         * @return float         elapsed seconds
         */
        public static function Timer ($name = NULL) {
            return static::BarDump(
                call_user_func(static::$handlers->timer, $name),
                $name
            );
        }

        /**
         * Dumps information about a variable in readable format.
         * @tracySkipLocation
         * @param  mixed  $value    variable to dump
         * @param  bool   $return   return output instead of printing it? (bypasses $productionMode)
         * @return mixed            variable itself or dump
         */
        public static function Dump ($value, $return = FALSE) {
            if (static::$originalDebugClass) {
                $args = func_get_args();
                $options = isset($args[2]) ? array('dieDumpCall' => TRUE) : array() ;
                if ($return) $options['doNotStore'] = TRUE;
                $options['backtraceIndex'] = 1;
                $result = static::dumpHandler($value, NULL, $options);
            } else {
                $result = call_user_func(static::$handlers->dump, $value, $return);
            }
            if ($return) return $result;
        }

        /**
         * Dumps information about a variable in Tracy Debug Bar.
         * @tracySkipLocation
         * @param  mixed    $value      variable to dump
         * @param  string   $title      optional title
         * @param  array    $options    dumper options
         * @return mixed                variable itself
         */
        public static function BarDump ($value, $title = NULL, $options = array()) {
            return call_user_func_array(static::$handlers->barDump, func_get_args());
        }

        /**
         * Logs message or exception.
         * @param  string|\Exception    $value
         * @param  string               $priority
         * @return string               logged error filename
         */
        public static function Log ($value, $priority = self::INFO) {
            $args = func_get_args();
            if (static::$originalDebugClass) {
                $content = date('[Y-m-d H-i-s]') . "\n" . static::dumpHandler(
                    $value, NULL, array('doNotStore' => TRUE, 'backtraceIndex' => 1)
                );
                $content = str_replace("\n", "\n\t", $content) . "\n";
                $fullPath = static::$LogDirectory . DIRECTORY_SEPARATOR . $priority . '.log';
                file_put_contents($fullPath, $content, FILE_APPEND);
                return $fullPath;
            } else {
                return @call_user_func_array(static::$handlers->log, $args);
            }
        }

        /**
         * Sends message to FireLogger console.
         * @param   mixed   $message    message to log
         * @param   string  $priority   priority
         * @return  bool                was successful?
         */
        public static function FireLog ($message, $priority = self::DEBUG) {
            // TODO: implement simple firelog
            $args = func_get_args();
            if (static::$originalDebugClass) {
                $args = array($message, NULL, array('priority' => $priority));
            }
            return call_user_func_array(static::$handlers->fireLog, $args);
        }

        /**
         * Handler to catch uncaught exception.
         * @param  \Exception|\Throwable
         * @return void
         */
        public static function Exception ($exception, $exit = TRUE) {
            return call_user_func_array(static::$handlers->exceptionHandler, func_get_args());
        }

        /**
         * Print all catched dumps at the end of sended response body.
         * @return void
         */
        public static function ShutdownHandler () {
            if (!count(static::$dumps)) return;
            $dumps = '';
            $dieDump = FALSE;
            foreach (static::$dumps as $values) {
                $dumps .= '<div class="item">';
                if (!is_null($values[1])) {
                    $dumps .= '<pre class="title">'.$values[1].'</pre>';
                }
                $dumps .= '<div class="value">'
                    .preg_replace("#\[([^\]]*)\]=>([^\n]*)\n(\s*)#", "[$1] => ", 
                        str_replace("<required>","&lt;required&gt;", $values[0])
                    )
                    .'</div></div>';
                if (isset($values[2]['dieDumpCall']) && $values[2]['dieDumpCall']) $dieDump = TRUE;
            }
            $template = file_get_contents(dirname(__FILE__).'/debug.html');
            echo str_replace(
                array('%mvccoreDumps%', '%mvccoreDumpsCount%', '%mvccoreDumpsClose%'),
                array($dumps, count(static::$dumps), $dieDump ? ';' : 'q();'),
                $template
            );
        }

        /**
         * Starts/stops stopwatch.
         * @param  string  name
         * @return float   elapsed seconds
         */
        protected static function timerHandler ($name = NULL) {
            $now = microtime(TRUE);
            if (is_null($name)) return $now - \MvcCore::GetInstance()->GetMicrotime();
            $difference = isset(static::$timers[$name]) ? $now - static::$timers[$name] : 0;
            static::$timers[$name] = $now;
            return $difference;
        }

        /**
         * Dump any variable into string throw output buffering, 
         * store result for printing later. Return printed variable string.
         * @param mixed $var
         * @param string $title
         * @param array $options
         * @return string
         */
        protected static function dumpHandler ($var, $title = NULL, $options = array()) {
            ob_start();
            var_dump($var);
            // format xdebug first small element with file:
            $content = preg_replace("#\</small\>\n#", '</small>', ob_get_clean(), 1);
            $content = preg_replace("#\<small\>([^\>]*)\>#", '', $content, 1);
            $backtraceIndex = isset($options['backtraceIndex']) ? $options['backtraceIndex'] : 2 ;
            $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, $backtraceIndex + 1);
            $originalPlace = (object) $backtrace[$backtraceIndex];
            $content = '<small class="file">' . $originalPlace->file . ':' . $originalPlace->line . '</small>' . $content;
            if (!isset($options['doNotStore'])) static::$dumps[] = array($content, $title, $options);
            return $content;
        }

        /**
         * Exception printing for development, logging for production.
         * @param \Exception $e
         * @return void
         */
        protected static function exceptionHandler (\Exception $e, $exit = TRUE) {
            throw $e;
            //if ($exit) exit;
        }
    }

}

namespace {
    \MvcCore\Debug::$InitGlobalShortHands = function () {
        /**
            * Dump a variable.
            * @param  mixed  $value variable to dump
            * @param  string $title optional title
            * @param  array  $options   dumper options
            * @return mixed  variable itself
            */
        function x ($value, $title = NULL, $options = array()) {
            return \MvcCore\Debug::BarDump($value, $title, $options);
        }
        /**
            * Dumps variables about a variable.
            * @param  ...mixed  variables to dump
            */
        function xx () {
            $args = func_get_args();
            foreach ($args as $arg) \MvcCore\Debug::BarDump($arg);
        }
        /**
            * Dump a variable and die. If no variable, throw stop exception.
            * @param  mixed  $var       variable to dump
            * @param  string $title optional title
            * @param  array  $options   dumper options
            * @throws \Exception
            * @return void
            */
        function xxx ($var = NULL, $title = NULL, $options = array()) {
            $args = func_get_args();
            if (count($args) === 0) {
                throw new \Exception("Stopped.");
            } else {
                @header("Content-Type: text/html; charset=utf-8");
                foreach ($args as $arg) \MvcCore\Debug::Dump($arg, FALSE, TRUE);
            }
            echo ob_get_clean();
            die();
        }
    };
}
MvcCore API documentation generated by ApiGen