* @link https://TheTempusProject.com * @license https://opensource.org/licenses/MIT [MIT LICENSE] */ namespace TheTempusProject; use TheTempusProject\Bedrock\Bin\Bedrock; use TheTempusProject\Bedrock\Classes\Config; use TheTempusProject\Bedrock\Functions\Input; use TheTempusProject\Bedrock\Functions\Session; use TheTempusProject\Bedrock\Functions\Cookie; use TheTempusProject\Bedrock\Functions\Check; use TheTempusProject\Bedrock\Functions\Date; use TheTempusProject\Canary\Bin\Canary as Debug; use TheTempusProject\Hermes\Functions\Redirect; use TheTempusProject\Hermes\Functions\Route as Routes; use TheTempusProject\Houdini\Classes\Views; use TheTempusProject\Houdini\Classes\Components; use TheTempusProject\Houdini\Classes\Filters; use TheTempusProject\Houdini\Classes\Issues; use TheTempusProject\Houdini\Classes\Navigation; use TheTempusProject\Classes\Installer; use TheTempusProject\Classes\Plugin; use TheTempusProject\Models\Sessions; use TheTempusProject\Models\User; use TheTempusProject\Models\Group; use TheTempusProject\Models\Routes as RoutesModel; class TheTempusProject extends Bedrock { const MAIN_MENU_NAME = 'topNavLeft'; const ADMIN_MENU_NAME = 'adminMenu'; const FOOTER_MENU_NAME = 'footerMenu'; public static $plugins = []; public static $activeGroup; public static $activePerms; public static $activePrefs; public static $activeSession; public static $activeUser; public static $topNavRight = ''; public static $topNavRightDropdown = ''; public static $isLoggedIn = false; public static $isMember = false; public static $isAdmin = false; public static $isMod = false; private $initialized = false; public $footer_links = [ [ 'text' => 'Terms of Service', 'url' => '{ROOT_URL}home/terms', ], ]; public $admin_links = [ [ 'text' => ' Home', 'url' => '{ROOT_URL}admin/index', ], [ 'text' => ' Settings', 'url' => '{ROOT_URL}admin/settings', ], [ 'text' => ' Users', 'url' => '{ROOT_URL}admin/users', ], [ 'text' => ' Groups', 'url' => '{ROOT_URL}admin/groups', ], [ 'text' => ' Contact', 'url' => '{ROOT_URL}admin/contact', ], [ 'text' => ' Tokens', 'url' => '{ROOT_URL}admin/tokens', ], [ 'text' => ' Modules', 'url' => [ [ 'text' => ' Plugins', 'url' => '{ROOT_URL}admin/plugins', ], [ 'text' => ' Composer', 'url' => '{ROOT_URL}admin/composer', ], ], ], [ 'text' => ' Logs', 'url' => [ [ 'text' => ' Logs', 'url' => '{ROOT_URL}admin/logs', ], [ 'text' => ' Admin', 'url' => '{ROOT_URL}admin/admin', ], [ 'text' => ' Errors', 'url' => '{ROOT_URL}admin/errors', ], [ 'text' => ' Logins', 'url' => '{ROOT_URL}admin/logins', ], ], ], ]; public $main_links = [ [ 'text' => 'Home', 'url' => '{ROOT_URL}home/index', ], [ 'text' => 'Admin', 'url' => '{ROOT_URL}admin/index', 'filter' => 'admin', ], ]; public $filters = [ [ 'name' => 'bbCode.bold', 'find' => '#\[b\](.*?)\[/b\]#is', 'replace' => '$1', 'enabled' => true, 'example' => '[b]Bold Text[/b]', ], [ 'name' => 'bbCode.paragraph', 'find' => '#\[p\](.*?)\[/p\]#is', 'replace' => '

$1

', 'enabled' => true, 'example' => '[p]Paragraph[/p]', ], [ 'name' => 'bbCode.italic', 'find' => '#\[i\](.*?)\[/i\]#is', 'replace' => '$1', 'enabled' => true, 'example' => '[i]Italic[/i]', ], [ 'name' => 'bbCode.underline', 'find' => '#\[u\](.*?)\[/u\]#is', 'replace' => '$1', 'enabled' => true, 'example' => '[u]Underline[/u]', ], [ 'name' => 'bbCode.strike', 'find' => '#\[s\](.*?)\[/s\]#is', 'replace' => '$1', 'enabled' => true, 'example' => '[s]Strike-through[/s]', ], [ 'name' => 'bbCode.code', 'find' => '#\[code\](.*?)\[/code\]#is', 'replace' => '$1', 'enabled' => true, 'example' => '[code]

Is it a paragraph though?

[/code]', ], [ 'name' => 'bbCode.color', 'find' => '#\[color=(.*?)\](.*?)\[/color\]#is', 'replace' => "$2", 'enabled' => true, 'example' => '[color=red]This is an alert color![/color]', ], [ 'name' => 'bbCode.image', 'find' => '#\[img\](.*?)\[/img\]#is', 'replace' => "", 'enabled' => true, 'example' => '[img]/images/logo.png[/img]', ], [ 'name' => 'bbCode.url', 'find' => '#\[url=(.*?)\](.*?)\[/url\]#is', 'replace' => "$2", 'enabled' => true, 'example' => '[url=https://google.com]Bing.com[/url]', ], [ 'name' => 'bbCode.quote', 'find' => '#\[quote=(.*?)\](.*?)\[/quote\]#is', 'replace' => "
$2
", 'enabled' => true, 'example' => '[quote=WhoSaidIt]What they said.[/quote]', ], [ 'name' => 'bbCode.list', 'find' => '#\[list\](.*?)\[/list\]#is', 'replace' => '', 'enabled' => true, 'example' => '[list][/list]', ], [ 'name' => 'bbCode.listItem', 'find' => '#\(\.\)(.*)$#m', 'replace' => '
  • $1
  • ', 'enabled' => true, 'example' => '[list](.)Item1 (.)Item2[/list]', ], [ 'name' => 'icons.check', 'find' => '#\(c\)#is', 'replace' => '✔', 'enabled' => true, 'example' => '(c)', ], [ 'name' => 'icons.close', 'find' => '#\(x\)#is', 'replace' => '✖', 'enabled' => true, 'example' => '(x)', ], [ 'name' => 'icons.exclaim', 'find' => '#\(!\)#is', 'replace' => '❕', 'enabled' => true, 'example' => '(!)', ], [ 'name' => 'icons.question', 'find' => '#\(\?\)#is', 'replace' => '❔', 'enabled' => true, 'example' => '(?)', ], ]; public static $configMatrix = [ "main" => [ "logo" => [ "type" => "file", "pretty" => "Site Logo (Used mostly in emails)", "default" => "images/logo.png" ], "name" => [ "type" => "text", "pretty" => "Site Name", "default" => "TTP Example" ], "template" => [ "type" => "text", "pretty" => "Default Site Template", "default" => "default" ], "tokenEnabled" => [ "type" => "radio", "pretty" => "Enable CSRF Token for all forms.", "default" => true ], "loginLimit" => [ "type" => "text", "pretty" => "Maximum Login Attempts per hour", "default" => 5 ] ], "database" => [ "dbEnabled" => [ "type" => "radio", "pretty" => "Database Enabled", "default" => true, "protected" => true ], "dbHost" => [ "type" => "text", "pretty" => "Database Host (IE: http://localhost:3306)", "default" => "127.0.0.1", "protected" => true ], "dbMaxQuery" => [ "type" => "text", "pretty" => "Maximum results per query", "default" => 100, "protected" => true ], "dbName" => [ "type" => "text", "pretty" => "Database Name", "default" => "ttp-example", "protected" => true ], "dbPassword" => [ "type" => "text", "pretty" => "Database Password", "default" => "", "protected" => true ], "dbPrefix" => [ "type" => "text", "pretty" => "Database table Prefix", "default" => "TTP_", "protected" => true ], "dbUsername" => [ "type" => "text", "pretty" => "Database Username", "default" => "root", "protected" => true ] ] ]; public static $userCPlinks = []; /** * The constructor takes care of everything that we will need before * finally calling appload to instantiate the appropriate controller/method. */ public function __construct() { // Initialize the parent app parent::__construct(); Debug::info( 'Requested URL: ' . $this->getCurrentUrl() ); // load our own config self::$activeConfig->load( CONFIG_JSON ); // instead of htaccess it should check which server type and use that method if ( ! Check::isNginx() && ! file_exists( HTACCESS_LOCATION ) && ! file_exists( INSTALLER_LOCATION ) ) { echo file_get_contents( ERRORS_DIRECTORY . '533.html' ); exit(); } // Authenticate our session $this->authenticate(); // Load any filter we need $this->loadFilters(); // Notify admins if the installer is still around if ( self::$isAdmin ) { if ( file_exists( INSTALLER_LOCATION ) ) { if ( Debug::status() ) { Debug::warn( 'You have not removed the installer yet.' ); } else { Issues::add( 'error', 'You have not removed the installer. This is a security risk that should be corrected immediately.' ); } } } // Load nav links $this->loadLinks(); // Load active plugins $plugins = Plugin::getActivePlugins(); foreach ( $plugins as $plugin ) { foreach ($plugin as $name => $class) { self::$plugins[ $name ] = new $class( true ); } } // load the damn usercp menu n a retarded fashion self::$userCPlinks[] = (object) [ "url" => "{ROOT_URL}usercp", "name" => "Profile" ]; self::$userCPlinks[] = (object) [ "url" => "{ROOT_URL}usercp/settings", "name" => "Settings" ]; self::$userCPlinks[] = (object) [ "url" => "{ROOT_URL}usercp/email", "name" => "Change Email" ]; self::$userCPlinks[] = (object) [ "url" => "{ROOT_URL}usercp/password", "name" => "Change Password" ]; Debug::gend(); } /** * Handles the permissions, preferences, login, and group setup for any active user. * * @return (bool) */ public function authenticate() { $user = new User; $group = new Group; $sessions = new Sessions; // Set defaults self::$activePerms = $group->getDefaultPermissions(); // PERMISSIONS_JSON self::$activePrefs = $user->getDefaultPreferences(); // PREFERENCES_JSON if ( !$sessions->checkSession( Session::get( 'SessionID' ) ) && !$sessions->checkCookie( Cookie::get( 'RememberToken' ), true ) ) { Debug::info( 'Sessions->authenticate - Could not authenticate cookie or session' ); return false; } self::$isLoggedIn = true; self::$activeSession = $sessions::$activeSession; self::$activeUser = $user->get( self::$activeSession->userID ); self::$activePrefs = self::$activeUser->prefs; self::$activeGroup = $group->findById( self::$activeUser->userGroup ); if ( !empty( self::$activeGroup ) ) { self::$activePerms = self::$activeGroup->perms; self::$isAdmin = !empty(self::$activeGroup->perms['adminAccess']); } else { self::$isAdmin = false; } return true; } public static function dateTimeCallback( $data ) { if ( empty( $data[2] ) ) { return ''; } return Date::formatTimestamp( $data[1], $data[2] ); } public function loadFilters() { // These Filter have to be loaded here because they have calculated values $this->filters[] = [ 'name' => 'mentions', 'find' => '#(^|\s)@([a-zA-Z_]+\w*)#', 'replace' => '$1@$2$3', 'enabled' => true, 'example' => '@username', ]; $this->filters[] = [ 'name' => 'hashtags', 'find' => '#(^|\s)\#([a-zA-Z\_\-]+\w*)#', 'replace' => '$1#$2$3', 'enabled' => true, 'example' => '#hash-tag', ]; $this->filters[] = [ 'name' => 'admin', 'find' => '#{ADMIN}(.*?){/ADMIN}#is', 'replace' => ( self::$isAdmin ? '$1' : '' ), 'enabled' => true, 'example' => '{ADMIN}Only visible to users who are an admin.{ADMIN}', ]; $this->filters[] = [ 'name' => 'loggedin', 'find' => '#{LOGGEDIN}(.*?){/LOGGEDIN}#is', 'replace' => ( self::$isLoggedIn ? '$1' : '' ), 'enabled' => true, 'example' => '{LOGGEDIN}Only visible to users who are logged-in{LOGGEDIN}', ]; $this->filters[] = [ 'name' => 'dtc', 'find' => '#{DTC(.*?)}(.*?){/DTC}#is', 'replace' => [ __CLASS__, 'dateTimeCallback' ], 'enabled' => true, 'callback' => true, 'example' => '{DTC=date}000000000{DTC}', ]; if ( ! empty( $this->filters ) ) { foreach( $this->filters as $filter ) { Filters::add( $filter['name'], $filter['find'], $filter['replace'], $filter['enabled'], ( $filter['callback'] ?? false ) ); } } } public function loadLinks() { foreach ( $this->footer_links as $key => $link ) { Navigation::addLink( self::FOOTER_MENU_NAME, $link ); } foreach ( $this->main_links as $key => $link ) { Navigation::addLink( self::MAIN_MENU_NAME, $link ); } foreach ( $this->admin_links as $key => $link ) { Navigation::addLink( self::ADMIN_MENU_NAME, $link ); } } public function load( $url = '' ) { $routes = new RoutesModel; if (empty($url)) { $url = trim(Input::get('url'), '/'); $url = str_ireplace( '.php', '', $url ); } $route = $routes->findByOriginalUrl($url); if (false !== $route) { $route = $route; if ('internal' === $route->redirect_type) { $this->setUrl($route->forwarded_url); } else { Redirect::external($route->forwarded_url); } } parent::load(); } public static function handle_shutdown() { if ( ! Debug::status( 'console' ) ) { return; } echo '
    '; echo '
    '; echo '
    '; echo '

    '; echo 'Running the shutdown handler'; echo '

    '; Components::set( 'DEBUGGING_LOG', Debug::dump() ); $error = error_get_last(); echo '

    '; if ( !empty( $error ) ) { echo 'Looks like there was an error:

    ' . print_r( $error, true ) . '
    '; // log_error( $error["type"], $error["message"], $error["file"], $error["line"] ); } else { echo 'Shutting down without error.'; } echo '

    '; echo Views::simpleView( 'debug' ); echo '
    '; echo '
    '; echo '
    '; } /** * Echos useful information about the installation. * * @return (null) */ public function printDebug() { $autoload = 'Vendor Autoloaded: '; $autoload .= var_export( VENDOR_AUTOLOADED, true ); $autoload .= ''; if ( VENDOR_AUTOLOADED === false ) { $autoload .= 'Core Autoloaded: '; $autoload .= var_export( defined( 'BEDROCK_AUTOLOADED' ), true ); $autoload .= ''; $autoload .= 'Project Autoloaded: '; $autoload .= var_export( defined( 'TEMPUS_PROJECT_AUTOLOADED' ), true ); $autoload .= ''; $autoload .= 'Debugger Autoloaded: '; $autoload .= var_export( defined( 'CANARY_AUTOLOADED' ), true ); $autoload .= ''; } $autoload .= 'Core Constants Loaded: '; $autoload .= var_export( BEDROCK_CONSTANTS_LOADED, true ); $autoload .= ''; $autoload .= 'Project Constants Loaded: '; $autoload .= var_export( TEMPUS_PROJECT_CONSTANTS_LOADED, true ); $autoload .= ''; $autoload .= 'Debugger Constants Loaded: '; $autoload .= var_export( CANARY_CONSTANTS_LOADED, true ); $autoload .= ''; echo '
    '; echo '

    Tempus Project Debugging Info

    '; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo $autoload; echo '

    App Data

    Controller: '; echo var_export( self::$controllerName, true ); echo '
    Method: '; echo var_export( self::$methodName, true ); echo '
    GET: '; echo var_export( $_GET, true ); echo '
    POST: '; echo var_export( $_POST, true ); echo '

    Authentication

    isLoggedIn: '; echo var_export( self::$isLoggedIn, true ); echo '
    isAdmin: '; echo var_export( self::$isAdmin, true ); echo '
    isMod: '; echo var_export( self::$isMod, true ); echo '
    isMember: '; echo var_export( self::$isMember, true ); echo '

    User Data

    activeUser:
    ';
            echo var_export( self::$activeUser, true );
            echo '
    activeGroup:
    ';
            echo var_export( self::$activeGroup, true );
            echo '
    activePerms:
    ';
            echo var_export( self::$activePerms, true );
            echo '
    activePrefs:
    ';
            echo var_export( self::$activePrefs, true );
            echo '

    Autoload

    '; parent::printDebug(); } }