* @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 'App Data |
';
echo 'Controller: | ';
echo var_export( self::$controllerName, true );
echo '
|
';
echo 'Method: | ';
echo var_export( self::$methodName, true );
echo '
|
';
echo 'GET: | ';
echo var_export( $_GET, true );
echo '
|
';
echo 'POST: | ';
echo var_export( $_POST, true );
echo '
|
';
echo 'Authentication |
';
echo 'isLoggedIn: | ';
echo var_export( self::$isLoggedIn, true );
echo '
|
';
echo 'isAdmin: | ';
echo var_export( self::$isAdmin, true );
echo '
|
';
echo 'isMod: | ';
echo var_export( self::$isMod, true );
echo '
|
';
echo 'isMember: | ';
echo var_export( self::$isMember, true );
echo '
|
';
echo 'User Data |
';
echo 'activeUser: | ';
echo var_export( self::$activeUser, true );
echo ' |
';
echo 'activeGroup: | ';
echo var_export( self::$activeGroup, true );
echo ' |
';
echo 'activePerms: | ';
echo var_export( self::$activePerms, true );
echo ' |
';
echo 'activePrefs: | ';
echo var_export( self::$activePrefs, true );
echo ' |
';
echo 'Autoload |
';
echo $autoload;
echo '
';
parent::printDebug();
}
}