Mini Shell

Direktori : /usr/src/lsws/lsws-6.3.1/add-ons/webcachemgr/src/
Upload File :
Current File : //usr/src/lsws/lsws-6.3.1/add-ons/webcachemgr/src/WPInstallStorage.php

<?php

/** *********************************************
 * LiteSpeed Web Server Cache Manager
 *
 * @author LiteSpeed Technologies, Inc. (https://www.litespeedtech.com)
 * @copyright (c) 2018-2021
 * *******************************************
 */

namespace Lsc\Wp;

use Lsc\Wp\Context\Context;
use Lsc\Wp\Panel\ControlPanel;

/**
 * map to data file
 */
class WPInstallStorage
{

    /**
     * @var string
     */
    const CMD_ADD_CUST_WPINSTALLS = 'addCustWPInstalls';

    /**
     * @since 1.13.3
     * @var string
     */
    const CMD_ADD_NEW_WPINSTALL = 'addNewWPInstall';

    /**
     * @deprecated 1.13.3  Use CMD_DISCOVER_NEW2 instead.
     * @var string
     */
    const CMD_DISCOVER_NEW = 'discoverNew';

    /**
     * @since 1.13.3
     * @var string
     */
    const CMD_DISCOVER_NEW2 = 'discoverNew2';

    /**
     * @var string
     */
    const CMD_FLAG = 'flag';

    /**
     * @var string
     */
    const CMD_MASS_UNFLAG = 'mass_unflag';

    /**
     * @deprecated 1.13.3  Use CMD_SCAN2 instead for now.
     * @var string
     */
    const CMD_SCAN = 'scan';

    /**
     * @since 1.13.3
     * @var string
     */
    const CMD_SCAN2 = 'scan2';

    /**
     * @var string
     */
    const CMD_UNFLAG = 'unflag';

    /**
     * @var string
     */
    const DATA_VERSION = '1.5';

    /**
     * @var int
     */
    const ERR_NOT_EXIST = 1;

    /**
     * @var int
     */
    const ERR_CORRUPTED = 2;

    /**
     * @var int
     */
    const ERR_VERSION_HIGH = 3;

    /**
     * @var int
     */
    const ERR_VERSION_LOW = 4;

    /**
     * @var string
     */
    protected $dataFile;

    /**
     * @var string
     */
    protected $customDataFile;

    /**
     * @var null|WPInstall[]  Key is path
     */
    protected $wpInstalls = null;

    /**
     * @var null|WPInstall[]  Key is path
     */
    protected $custWpInstalls = null;

    /**
     * @var int
     */
    protected $error;

    /**
     * @var WPInstall[]
     */
    protected $workingQueue = array();

    /**
     *
     * @param string  $dataFile
     * @param string  $custDataFile
     * @throws LSCMException  Thrown indirectly.
     */
    public function __construct( $dataFile, $custDataFile = '' )
    {
        $this->dataFile = $dataFile;
        $this->customDataFile = $custDataFile;
        $this->error = $this->init();
    }

    /**
     *
     * @return int
     * @throws LSCMException  Thrown indirectly.
     */
    protected function init()
    {
        $dataExists = false;

        try {
            if ( file_exists($this->dataFile) ) {
                $dataExists = true;
                $this->wpInstalls = $this->getDataFileData($this->dataFile);
            }

            if ( $this->customDataFile != ''
                    && file_exists($this->customDataFile) ) {

                $dataExists = true;
                $this->custWpInstalls =
                    $this->getDataFileData($this->customDataFile);
            }
        }
        catch ( LSCMException $e ) {
            Logger::debug($e->getMessage());
            return $e->getCode();
        }

        if ( !$dataExists ) {
            return self::ERR_NOT_EXIST;
        }

        return 0;
    }

    /**
     *
     * @param string  $dataFile
     * @return WPInstall[]
     * @throws LSCMException  Thrown indirectly.
     */
    protected function getDataFileData( $dataFile )
    {
        $content = file_get_contents($dataFile);

        if ( ($data = json_decode($content, true)) === null ) {
            /*
             * Data file may be in old serialized format. Try unserializing.
             */
             $data = unserialize($content);
        }

        if ( $data === false || !is_array($data) || !isset($data['__VER__']) ) {
            throw new LSCMException(
                "$dataFile - Data is corrupt.",
                self::ERR_CORRUPTED
            );
        }

        if ( ($err = $this->verifyDataFileVer($dataFile, $data['__VER__'])) ) {
            throw new LSCMException(
                "$dataFile - Data file version issue.",
                $err
            );
        }

        unset($data['__VER__']);

        $wpInstalls = array();

        foreach ( $data as $utf8Path => $idata ) {
            $path = utf8_decode($utf8Path);
            $i = new WPInstall($path);

            $idata[WPInstall::FLD_SITEURL] =
                    urldecode($idata[WPInstall::FLD_SITEURL]);
            $idata[WPInstall::FLD_SERVERNAME] =
                    urldecode($idata[WPInstall::FLD_SERVERNAME]);

            $i->initData($idata);
            $wpInstalls[$path] = $i;
        }

        return $wpInstalls;
    }

    /**
     *
     * @return int
     */
    public function getError()
    {
        return $this->error;
    }

    /**
     *
     * @param bool  $nonFatalOnly
     * @return int
     */
    public function getCount( $nonFatalOnly = false )
    {
        $count = 0;

        if ( !$nonFatalOnly ) {

            if ( $this->wpInstalls != null ) {
                $count += count($this->wpInstalls);
            }

            if ( $this->custWpInstalls != null ) {
                $count += count($this->custWpInstalls);
            }
        }
        else {

            foreach ( $this->wpInstalls as $install ) {

                if ( !$install->hasFatalError() ) {
                    $count++;
                }
            }

            foreach ( $this->custWpInstalls as $custInstall ) {

                if ( !$custInstall->hasFatalError() ) {
                    $count++;
                }
            }
        }

        return $count;
    }

    /**
     *
     * @return null|WPInstall[]
     *
     * @noinspection PhpUnused
     */
    public function getWPInstalls()
    {
        return $this->wpInstalls;
    }

    /**
     *
     * @return null|WPInstall[]
     *
     * @noinspection PhpUnused
     */
    public function getCustWPInstalls()
    {
        return $this->custWpInstalls;
    }

    /**
     *
     * @return null|WPInstall[]
     */
    public function getAllWPInstalls()
    {
        if ( $this->wpInstalls != null ) {

            if ( $this->custWpInstalls != null ) {
                return array_merge($this->wpInstalls, $this->custWpInstalls);
            }
            else {
                return $this->wpInstalls;
            }
        }
        elseif ( $this->custWpInstalls != null ) {
            return $this->custWpInstalls;
        }
        else {
            return null;
        }
    }

    /**
     * Get all known WPInstall paths.
     *
     * @return string[]
     */
    public function getPaths()
    {
        $paths = array();

        if ( $this->wpInstalls != null ) {
            $paths = array_keys($this->wpInstalls);
        }

        if ( $this->custWpInstalls != null ) {
            $paths = array_merge($paths, array_keys($this->custWpInstalls));
        }

        return $paths;
    }

    /**
     *
     * @param string  $path
     * @return WPInstall|null
     */
    public function getWPInstall( $path )
    {
        if ( ($realPath = realpath($path)) === false ) {
            $index = $path;
        }
        else {
            $index = $realPath;
        }

        if ( isset($this->wpInstalls[$index]) ) {
            return $this->wpInstalls[$index];
        }
        elseif ( isset($this->custWpInstalls[$index]) ) {
            return $this->custWpInstalls[$index];
        }

        return null;
    }

    /**
     *
     * @return WPInstall[]
     */
    public function getWorkingQueue()
    {
        return $this->workingQueue;
    }

    /**
     *
     * @param WPInstall  $wpInstall
     */
    public function addWPInstall( WPInstall $wpInstall )
    {
        $this->wpInstalls[$wpInstall->getPath()] = $wpInstall;
    }

    /**
     *
     * @throws LSCMException  Thrown indirectly.
     */
    public function syncToDisk()
    {
        $this->saveDataFile($this->dataFile, $this->wpInstalls);

        if ( $this->customDataFile != '' ) {
            $this->saveDataFile($this->customDataFile, $this->custWpInstalls);
        }
    }

    /**
     *
     * @param string       $dataFile
     * @param WPInstall[]  $wpInstalls
     * @throws LSCMException  Thrown indirectly.
     */
    protected function saveDataFile( $dataFile, $wpInstalls )
    {
        $data = array( '__VER__' => self::DATA_VERSION );

        if ( !empty($wpInstalls) ) {

            foreach ( $wpInstalls as $path => $install ) {

                if ( !$install->shouldRemove() ) {
                    $utf8Path = utf8_encode($path);

                    $data[$utf8Path] = $install->getData();

                    $siteUrl = &$data[$utf8Path][WPInstall::FLD_SITEURL];
                    $siteUrl = urlencode($siteUrl);

                    $serverName = &$data[$utf8Path][WPInstall::FLD_SERVERNAME];
                    $serverName = urlencode($serverName);
                }
            }

            ksort($data);
        }

        $file_str = json_encode($data);
        file_put_contents($dataFile, $file_str, LOCK_EX);
        chmod($dataFile, 0600);

        $this->log("Data file saved $dataFile", Logger::L_DEBUG);
    }

    /**
     *
     * @param string  $dataFile
     * @param string  $dataFileVer
     * @return int
     * @throws LSCMException  Thrown indirectly.
     */
    protected function verifyDataFileVer( $dataFile, $dataFileVer )
    {
        $res = version_compare($dataFileVer, self::DATA_VERSION);

        if ( $res == 1 ) {
            Logger::info(
                'Data file version is higher than expected and cannot be used.'
            );

            return self::ERR_VERSION_HIGH;
        }

        if ( $res == -1 && !$this->updateDataFile($dataFile, $dataFileVer) ) {
            return self::ERR_VERSION_LOW;
        }

        return 0;
    }

    /**
     *
     * @param string  $dataFile
     * @param string  $dataFileVer
     * @return bool
     * @throws LSCMException  Thrown indirectly.
     */
    public static function updateDataFile( $dataFile, $dataFileVer )
    {
        Logger::info(
            "$dataFile - Old data file version detected. Attempting to "
                . 'update...'
        );

        /**
         * Currently no versions are upgradeable to 1.5
         */
        $updatableVersions = array();

        if ( ! in_array($dataFileVer, $updatableVersions)
                || ! Util::createBackup($dataFile) ) {

            Logger::error(
                "$dataFile - Data file could not be updated to version "
                    . self::DATA_VERSION
            );

            return false;
        }

        /**
         * Upgrade funcs will be called here.
         */

        return true;
    }

    /**
     *
     * @param string  $action
     * @return string[]
     * @throws LSCMException  Thrown indirectly.
     */
    protected function prepareActionItems( $action )
    {
        switch ($action) {
            case self::CMD_SCAN:
            case self::CMD_SCAN2:
            case self::CMD_DISCOVER_NEW:
            case self::CMD_DISCOVER_NEW2:

                try
                {
                    return ControlPanel::getClassInstance()->getDocRoots();
                }
                catch ( LSCMException $e )
                {
                    throw new LSCMException(
                        $e->getMessage()
                            . " Could not prepare $action action items."
                    );
                }

            case UserCommand::CMD_MASS_ENABLE:
            case UserCommand::CMD_MASS_DISABLE:
            case UserCommand::CMD_MASS_UPGRADE:
            case UserCommand::CMD_MASS_DASH_NOTIFY:
            case UserCommand::CMD_MASS_DASH_DISABLE:
            case self::CMD_MASS_UNFLAG:
                return $this->getPaths();
            default:
                throw new LSCMException('Missing parameter(s).');
        }
    }

    /**
     *
     * @param string    $action
     * @param string    $path
     * @param string[]  $extraArgs
     * @throws LSCMException  Thrown indirectly.
     */
    protected function doWPInstallAction( $action, $path, $extraArgs )
    {
        if ( ($wpInstall = $this->getWPInstall($path)) == null ) {
            $wpInstall = new WPInstall($path);
            $this->addWPInstall($wpInstall);
        }

        switch ($action) {

            case self::CMD_FLAG:

                if ( !$wpInstall->hasValidPath() ) {
                    return;
                }

                if ( $wpInstall->addUserFlagFile(false) ) {
                    $wpInstall->setCmdStatusAndMsg(
                        UserCommand::EXIT_SUCC,
                        'Flag file set'
                    );
                }
                else {
                    $wpInstall->setCmdStatusAndMsg(
                        UserCommand::EXIT_FAIL,
                        'Could not create flag file'
                    );
                }

                $this->workingQueue[$path] = $wpInstall;

                return;

            case self::CMD_UNFLAG:
            case self::CMD_MASS_UNFLAG:

                if ( !$wpInstall->hasValidPath() ) {
                    return;
                }

                $wpInstall->removeFlagFile();

                $wpInstall->setCmdStatusAndMsg(
                    UserCommand::EXIT_SUCC,
                    'Flag file unset'
                );

                $this->workingQueue[$path] = $wpInstall;

                return;

            case UserCommand::CMD_ENABLE:
            case UserCommand::CMD_DISABLE:
            case UserCommand::CMD_DASH_NOTIFY:
            case UserCommand::CMD_DASH_DISABLE:

                if ( $wpInstall->hasFatalError() ) {
                    $wpInstall->refreshStatus();

                    if ( $wpInstall->hasFatalError() ) {
                        $wpInstall->addUserFlagFile(false);

                        $wpInstall->setCmdStatusAndMsg(
                            UserCommand::EXIT_FAIL,
                            'Install skipped and flagged due to Error status.'
                        );

                        $this->workingQueue[$path] = $wpInstall;

                        return;
                    }
                }

                break;

            case UserCommand::CMD_MASS_UPGRADE:
                $allowedVers =
                    PluginVersion::getInstance()->getAllowedVersions();

                if ( !in_array($extraArgs[1], $allowedVers) ) {
                    throw new LSCMException(
                        'Selected LSCWP version ('
                            . htmlspecialchars($extraArgs[1]) . ') is invalid.'
                    );
                }
                break;

            //no default
        }

        if ( UserCommand::issue($action, $wpInstall, $extraArgs) ) {

            if ( $action == UserCommand::CMD_MASS_UPGRADE
                    && ($wpInstall->getCmdStatus() & UserCommand::EXIT_FAIL)
                    && preg_match('/Download failed. Not Found/', $wpInstall->getCmdMsg()) ) {

                $this->syncToDisk();

                throw new LSCMException(
                    'Could not download version '
                        . htmlspecialchars($extraArgs[1]) . '.'
                );
            }

            if ( $action == UserCommand::CMD_MASS_ENABLE
                    && ($wpInstall->getCmdStatus() & UserCommand::EXIT_FAIL)
                    && preg_match('/Source Package not available/', $wpInstall->getCmdMsg()) ) {

                $this->syncToDisk();

                throw new LSCMException($wpInstall->getCmdMsg());
            }

            $this->workingQueue[$path] = $wpInstall;
        }
    }

    /**
     *
     * @param string               $action
     * @param null|string[]        $list
     * @param string[]|string[][]  $extraArgs
     * @return string[]
     * @throws LSCMException  Thrown indirectly.
     */
    public function doAction( $action, $list, $extraArgs = array() )
    {
        if ( $list === null ) {
            $list = $this->prepareActionItems($action);
        }

        $count = count($list);
        $this->log("doAction {$action} for {$count} items", Logger::L_VERBOSE);
        $endTime = $count > 1 ? Context::getActionTimeout() : 0;
        $finishedList = array();

        switch ( $action ) {

            case self::CMD_SCAN:
            case self::CMD_DISCOVER_NEW:
                $forceRefresh = ($action == self::CMD_SCAN);

                foreach ( $list as $path ) {
                    $this->scan($path, $forceRefresh);

                    $finishedList[] = $path;

                    if ( $endTime && time() >= $endTime ) {
                        break;
                    }
                }

                break;

            case self::CMD_ADD_NEW_WPINSTALL:

                foreach ( $list as $path) {
                    $this->addNewWPInstall($path);

                    $finishedList[] = $path;

                    if ( $endTime && time() >= $endTime ) {
                        break;
                    }
                }

                break;

            case self::CMD_ADD_CUST_WPINSTALLS:
                $wpInstallsInfo = $extraArgs[0];

                $this->addCustomInstallations($wpInstallsInfo);
                break;

            default:

                if ( $action == UserCommand::CMD_ENABLE
                        || $action == UserCommand::CMD_MASS_ENABLE ) {

                    /**
                     * Ensure that current version is locally downloaded.
                     */
                    $currVer = PluginVersion::getCurrentVersion();
                    PluginVersion::getInstance()->setActiveVersion($currVer);
                }

                foreach ( $list as $path ) {
                    $this->doWPInstallAction($action, $path, $extraArgs);

                    $finishedList[] = $path;

                    if ( $endTime && time() >= $endTime ) {
                        break;
                    }
                }
        }

        $this->syncToDisk();

        if ( $action == self::CMD_SCAN || $action == self::CMD_SCAN2 ) {
            /**
             * Explicitly clear any data file errors after scanning in case of
             * multiple actions performed in the same process (cli).
             */
            $this->error = 0;
        }

        return $finishedList;
    }

    /**
     *
     * @deprecated 1.13.3  Use $this->scan2() instead.
     *
     * @param string  $docroot
     * @param bool    $forceRefresh
     * @return void
     * @throws LSCMException  Thrown indirectly.
     */
    protected function scan( $docroot, $forceRefresh = false )
    {
        $depth = Context::getScanDepth();
        $cmd = "find -L $docroot -maxdepth $depth -name wp-admin -print";
        $directories = shell_exec($cmd);

        /**
         * Example:
         * /home/user/public_html/wordpress/wp-admin
         * /home/user/public_html/blog/wp-admin
         * /home/user/public_html/wp/wp-admin
         */
        $hasMatches = preg_match_all(
            "|$docroot(.*)(?=/wp-admin)|",
            $directories,
            $matches
        );

        if ( ! $hasMatches ) {
            /**
             *  Nothing found.
             */
            return;
        }

        foreach ( $matches[1] as $path ) {
            $wp_path = realpath($docroot . $path);
            $refresh = $forceRefresh;

            if ( !isset($this->wpInstalls[$wp_path]) ) {
                $this->wpInstalls[$wp_path] = new WPInstall($wp_path);
                $refresh = true;
                $this->log(
                    "New installation found: $wp_path",
                    Logger::L_INFO
                );

                if ( $this->custWpInstalls != null &&
                        isset($this->custWpInstalls[$wp_path]) ) {

                    unset($this->custWpInstalls[$wp_path]);

                    $this->log(
                        "Installation removed from custom data file: $wp_path",
                        Logger::L_INFO
                    );
                }
            }
            else {
                $this->log(
                    "Installation already found: $wp_path",
                    Logger::L_DEBUG
                );
            }

            if ( $refresh ) {
                $this->wpInstalls[$wp_path]->refreshStatus();
                $this->workingQueue[$wp_path] = $this->wpInstalls[$wp_path];
            }
        }
    }

    /**
     *
     * @since 1.13.3
     *
     * @param string   $docroot
     * @return string[]
     * @throws LSCMException  Thrown indirectly.
     */
    public function scan2( $docroot )
    {
        $depth = Context::getScanDepth();
        $cmd = "find -L $docroot -maxdepth $depth -name wp-admin -print";
        $directories = shell_exec($cmd);

        /**
         * Example:
         * /home/user/public_html/wordpress/wp-admin
         * /home/user/public_html/blog/wp-admin
         * /home/user/public_html/wp/wp-admin
         */
        $hasMatches = preg_match_all(
            "|$docroot(.*)(?=/wp-admin)|",
            $directories,
            $matches
        );

        if ( ! $hasMatches ) {
            /**
             *  Nothing found.
             */
            return array();
        }

        $wpPaths = array();

        foreach ( $matches[1] as $path ) {
            $wpPath = realpath($docroot . $path);
            $wpPaths[] = $wpPath;
        }

        return $wpPaths;
    }

    /**
     * Add a new WPInstall object to WPInstallStorage's $wpInstalls[] given a
     * path to a WordPress installation and refresh it's status . If a WPInstall
     * object already exists for the given path, refresh it's status.
     *
     * @since 1.13.3
     *
     * @param string  $wpPath
     * @throws LSCMException  Thrown indirectly.
     */
    protected function addNewWPInstall( $wpPath )
    {
        if ( ($realPath = realpath($wpPath)) !== false ) {
            $wpPath = $realPath;
        }

        if ( !isset($this->wpInstalls[$wpPath]) ) {
            $this->wpInstalls[$wpPath] = new WPInstall($wpPath);
            $this->log("New installation found: $wpPath", Logger::L_INFO);

            if ( $this->custWpInstalls != null &&
                isset($this->custWpInstalls[$wpPath]) ) {

                unset($this->custWpInstalls[$wpPath]);

                $this->log(
                    "Installation removed from custom data file: $wpPath",
                    Logger::L_INFO
                );
            }
        }
        else {
            $this->log(
                "Installation already found: $wpPath",
                Logger::L_DEBUG
            );
        }

        $this->wpInstalls[$wpPath]->refreshStatus();
        $this->workingQueue[$wpPath] = $this->wpInstalls[$wpPath];
    }

    /**
     *
     * @param string[]  $wpInstallsInfo
     * @return void
     * @throws LSCMException  Thrown indirectly.
     */
    protected function addCustomInstallations( $wpInstallsInfo )
    {
        if ( $this->customDataFile == '' ) {
            $this->log(
                'No custom data file set, could not add custom Installation.',
                Logger::L_INFO
            );

            return;
        }

        if ( $this->custWpInstalls == null ) {
            $this->custWpInstalls = array();
        }

        $count = count($wpInstallsInfo);

        for ( $i = 0; $i < $count; $i++ ) {
            $infoString = $wpInstallsInfo[$i];
            $info = preg_split('/\s+/', trim($infoString));

            $line = $i + 1;

            if ( count($info) != 4 ) {
                $this->log(
                    'Incorrect number of values for custom installation input '
                        . "string on line $line. Skipping.",
                    Logger::L_INFO
                );

                continue;
            }

            $wpPath = $info[0];
            $docroot = $info[1];
            $serverName = $info[2];
            $siteUrl = $info[3];

            if ( !file_exists("$wpPath/wp-admin") ) {
                $this->log(
                    "No 'wp-admin' directory found for $wpPath on line "
                        . "$line. Skipping.",
                    Logger::L_INFO
                );

                continue;
            }

            if ( !(substr($wpPath, 0, strlen($docroot)) === $docroot) ) {
                $this->log(
                    "docroot not contained in $wpPath on line $line. "
                        . 'Skipping.',
                    Logger::L_INFO
                );

                continue;
            }

            if ( !isset($this->wpInstalls[$wpPath]) ) {
                $this->custWpInstalls[$wpPath] = new WPInstall($wpPath);
                $this->custWpInstalls[$wpPath]->setDocRoot($docroot);
                $this->custWpInstalls[$wpPath]->setServerName($serverName);
                $this->custWpInstalls[$wpPath]->setSiteUrlDirect($siteUrl);
                $this->custWpInstalls[$wpPath]->refreshStatus();

                $this->log(
                    "New installation added to custom data file: $wpPath",
                    Logger::L_INFO
                );
            }
            else {
                $this->log(
                    "Installation already found during scan: $wpPath. "
                        . 'Skipping.',
                    Logger::L_INFO
                );
            }
        }
    }

    /**
     * Get all WPInstall command messages as a key=>value array.
     *
     * @return string[][]
     */
    public function getAllCmdMsgs()
    {
        $succ = $fail = $err = array();

        foreach ( $this->workingQueue as $WPInstall ) {
            $cmdStatus = $WPInstall->getCmdStatus();

            if ( $cmdStatus & UserCommand::EXIT_SUCC ) {
                $msgType = &$succ;
            }
            elseif ( $cmdStatus & UserCommand::EXIT_FAIL ) {
                $msgType = &$fail;
            }
            elseif ( $cmdStatus & UserCommand::EXIT_ERROR ) {
                $msgType = &$err;
            }
            else {
                continue;
            }

            if ( $msg = $WPInstall->getCmdMsg() ) {
                $msgType[] = "{$WPInstall->getPath()} - $msg";
            }
        }

        return array( 'succ' => $succ, 'fail' => $fail, 'err' => $err );
    }

    /**
     *
     * @param string  $msg
     * @param int     $level
     * @throws LSCMException  Thrown indirectly.
     */
    protected function log( $msg, $level )
    {
        $msg = "WPInstallStorage - {$msg}";

        switch ($level) {

            case Logger::L_ERROR:
                Logger::error($msg);
                break;

            case Logger::L_WARN:
                Logger::warn($msg);
                break;

            case Logger::L_NOTICE:
                Logger::notice($msg);
                break;

            case Logger::L_INFO:
                Logger::info($msg);
                break;

            case Logger::L_VERBOSE:
                Logger::verbose($msg);
                break;

            case Logger::L_DEBUG:
                Logger::debug($msg);
                break;

            //no default
        }
    }

}

Zerion Mini Shell 1.0