diff --git a/app/classes/api_controller.php b/app/classes/api_controller.php index 99faa73..b23fbe4 100644 --- a/app/classes/api_controller.php +++ b/app/classes/api_controller.php @@ -18,6 +18,8 @@ use TheTempusProject\Hermes\Functions\Redirect; use TheTempusProject\Bedrock\Functions\Session; use TheTempusProject\Bedrock\Classes\Config; use TheTempusProject\Models\Token; +use TheTempusProject\Canary\Bin\Canary as Debug; +use TheTempusProject\Houdini\Classes\Views; class ApiController extends Controller { protected static $canAccessApplicationApi = false; @@ -26,16 +28,15 @@ class ApiController extends Controller { protected static $authToken; public function __construct( $secure = true ) { + header('Content-Type: application/json; charset=utf-8'); parent::__construct(); - $this->verifyApiRequest(); - if ( $secure && ! $this->canUseApi() ) { - Session::flash( 'error', 'You do not have permission to view this page.' ); - return Redirect::home(); - } + Template::setTemplate( 'api' ); Template::noFollow(); Template::noIndex(); - Template::addHeader( 'Content-Type: application/json; charset=utf-8' ); - Template::setTemplate( 'api' ); + $res = $this->verifyApiRequest(); + if ( $secure && ! $this->canUseApi() ) { + exit( $res ); + } } protected function canUseApi() { @@ -72,16 +73,16 @@ class ApiController extends Controller { } else { $secret = $this->getSecretToken(); if ( empty( $secret ) ) { - return; + return Views::simpleView( 'api.response', ['response' => json_encode( [ 'error' => 'invalid secret' ], true )]); } $token = $tokens->findBySecret( $secret ); } if ( empty( $token ) ) { - return; + return Views::simpleView( 'api.response', ['response' => json_encode( [ 'error' => 'invalid token' ], true )]); } self::$authToken = $token; if ( $token->expiresAt <= time() && empty( $secret ) ) { - return; + return Views::simpleView( 'api.response', ['response' => json_encode( [ 'error' => 'token expired' ], true )]); } if ( $token->expiresAt <= time() ) { self::$canAccessAuthenticationApi = true; diff --git a/app/classes/forms.php b/app/classes/forms.php index d4402e7..1d6c4cb 100644 --- a/app/classes/forms.php +++ b/app/classes/forms.php @@ -114,6 +114,7 @@ class Forms extends Check { self::addHandler( 'install', __CLASS__, 'install' ); self::addHandler( 'adminCreateToken', __CLASS__, 'adminCreateToken' ); self::addHandler( 'apiLogin', __CLASS__, 'apiLogin' ); + self::addHandler( 'updatePreference', __CLASS__, 'updatePreference' ); self::addHandler( 'installStart', __CLASS__, 'install', [ 'start' ] ); self::addHandler( 'installAgreement', __CLASS__, 'install', [ 'agreement' ] ); self::addHandler( 'installCheck', __CLASS__, 'install', [ 'check' ] ); @@ -650,4 +651,16 @@ class Forms extends Check { } return true; } + + public static function updatePreference() { + if ( !Input::exists( 'prefName' ) ) { + self::addUserError( 'You must specify a name' ); + return false; + } + if ( !Input::exists( 'prefValue' ) ) { + self::addUserError( 'You must specify a value' ); + return false; + } + return true; + } } diff --git a/app/classes/preferences.php b/app/classes/preferences.php index b059ffa..3bf15fa 100644 --- a/app/classes/preferences.php +++ b/app/classes/preferences.php @@ -13,6 +13,7 @@ namespace TheTempusProject\Classes; use TheTempusProject\Houdini\Classes\Issues; use TheTempusProject\Houdini\Classes\Forms; +use TheTempusProject\Houdini\Classes\Template; use TheTempusProject\Canary\Bin\Canary as Debug; use TheTempusProject\Bedrock\Functions\Check; use TheTempusProject\Bedrock\Functions\Upload; @@ -186,17 +187,92 @@ class Preferences { } public function getFormHtml( $populated = [] ) { + // dv( self::$preferences ); $form = ''; + // Added so i can force some sort of ordering + $inputTypes = [ + 'file' => [], + 'select' => [], + 'timezone' => [], + 'checkbox' => [], + 'switch' => [], + ]; foreach ( self::$preferences as $name => $details ) { $tempPrefsArray = $this->normalizePreferenceArray( $name, $details ); if ( isset( $populated[ $name ] ) ) { - $tempPrefsArray['default'] = $populated[$name]; + $tempPrefsArray['value'] = $populated[$name]; + } else { + $tempPrefsArray['value'] = $tempPrefsArray['default']; } - $form .= Forms::getFormFieldHtml( $name, $tempPrefsArray['pretty'], $tempPrefsArray['type'], $tempPrefsArray['default'], $tempPrefsArray['options'] ); + // $form .= Forms::getFormFieldHtml( $name, $tempPrefsArray['pretty'], $tempPrefsArray['type'], $tempPrefsArray['default'], $tempPrefsArray['options'] ); + if ( $tempPrefsArray['type'] == 'checkbox' ) { + $tempPrefsArray['type'] = 'switch'; + } + $inputTypes[ $tempPrefsArray['type'] ][] = self::getFormFieldHtml( $name, $tempPrefsArray['pretty'], $tempPrefsArray['type'], $tempPrefsArray['value'], $tempPrefsArray['options'] ); + } + foreach ( $inputTypes as $skip => $items ) { + $form .= implode( ' ', $items ); } return $form; } + public static function getFormFieldHtml( $fieldname, $fieldTitle, $type, $defaultValue = '', $options = null ) { + $html = ''; + switch ( $type ) { + case 'radio': + case 'bool': + case 'boolean': + $fieldHtml = Forms::getRadioHtml( $fieldname, [ 'true', 'false' ], $defaultValue ); + break; + case 'select': + $fieldHtml = Forms::getSelectHtml( $fieldname, $options, $defaultValue ); + break; + case 'customSelect': + if ( empty( $options ) ) { + $options = '{' . $fieldname . '-options}'; + } + $fieldHtml = Forms::getSelectHtml( $fieldname, $options, $defaultValue ); + break; + case 'block': + $fieldHtml = Forms::getTextBlockHtml( $fieldname, $defaultValue ); + break; + case 'text': + case 'url': + $fieldHtml = Forms::getTextHtml( $fieldname, $defaultValue ); + break; + case 'checkbox': + $fieldHtml = Forms::getCheckboxHtml( $fieldname, $defaultValue ); + break; + case 'switch': + $fieldHtml = Forms::getSwitchHtml( $fieldname, $defaultValue ); + break; + case 'timezone': + $fieldHtml = Forms::getTimezoneHtml( $defaultValue ); + break; + case 'file': + $fieldHtml = Forms::getFileHtml( $fieldname ); + break; + default: + Debug::error( "unknown field type: $type" ); + break; + } + + $html .= '
'; + $html .= ''; + $html .= '
'; + $html .= $fieldHtml; + $html .= '
'; + if ( 'file' === $type ) { + $html .= '
'; + $html .= '

Current Image

'; + $html .= '
'; + $html .= 'User Avatar'; + $html .= '
'; + } + $html .= '
'; + return Template::parse( $html ); + } + public function convertFormToArray( $fillMissing = true, $defaultsOnly = true ) { $prefsArray = []; foreach ( self::$preferences as $name => $details ) { diff --git a/app/config/constants.php b/app/config/constants.php index 2f59171..2f1863c 100644 --- a/app/config/constants.php +++ b/app/config/constants.php @@ -38,7 +38,7 @@ if ( ! defined( 'CONFIG_DIRECTORY' ) ) { # Tempus Debugger define( 'CANARY_SECURE_HASH', 'd73ed7591a30f0ca7d686a0e780f0d05' ); # Tempus Project Core -define( 'APP_NAME', 'All The Bookmarks'); +define( 'APP_NAME', 'The Tempus Project'); define( 'TP_DEFAULT_LOGO', 'images/logo.png'); // Check define( 'MINIMUM_PHP_VERSION', 8.1); diff --git a/app/controllers/admin/home.php b/app/controllers/admin/home.php index c4a7704..6572929 100644 --- a/app/controllers/admin/home.php +++ b/app/controllers/admin/home.php @@ -32,12 +32,12 @@ class Home extends AdminController { } public function index() { + Components::set( 'commentDash', '' ); if ( class_exists( 'TheTempusProject\Plugins\Comments' ) ) { $plugin = new CommentPlugin; if ( ! $plugin->checkEnabled() ) { Debug::info( 'Comments Plugin is disabled in the control panel.' ); - Components::set( 'commentDash', '' ); } else { $comments = new Comments; $commentList = Views::simpleView( 'comments.admin.dashboard', $comments->recent( 'all', 5 ) ); diff --git a/app/controllers/admin/routes.php b/app/controllers/admin/routes.php index e21307b..0f65ccc 100644 --- a/app/controllers/admin/routes.php +++ b/app/controllers/admin/routes.php @@ -37,19 +37,25 @@ class Routes extends AdminController { public function create() { if ( Input::exists( 'redirect_type' ) ) { - if ( !TTPForms::check( 'createRoute' ) ) { - Issues::add( 'error', [ 'There was an error with your route.' => Check::userErrors() ] ); - } - if ( self::$routes->create( - Input::post( 'original_url' ), - Input::post( 'forwarded_url' ), - Input::post( 'nickname' ), - Input::post( 'redirect_type' ) - ) ) { - Session::flash( 'success', 'Route Created' ); - Redirect::to( 'admin/routes' ); - } + return Views::view( 'admin.routes.create' ); } + + if ( !TTPForms::check( 'createRoute' ) ) { + Issues::add( 'error', [ 'There was an error with your route.' => Check::userErrors() ] ); + return Views::view( 'admin.routes.create' ); + } + + if ( self::$routes->create( + Input::post( 'original_url' ), + Input::post( 'forwarded_url' ), + Input::post( 'nickname' ), + Input::post( 'redirect_type' ) + ) ) { + Session::flash( 'success', 'Route Created' ); + Redirect::to( 'admin/routes' ); + } + + Issues::add( 'error', 'There was an unknown error saving your redirect.' ); Views::view( 'admin.routes.create' ); } diff --git a/app/controllers/api/login.php b/app/controllers/api/login.php index 279a1cb..74536eb 100644 --- a/app/controllers/api/login.php +++ b/app/controllers/api/login.php @@ -27,15 +27,14 @@ class Login extends ApiController { parent::__construct( false ); self::$tokens = new Token; self::$user = new User; - // Template::addHeader( 'Access-Control-Allow-Origin: *' ); - // Template::addHeader( 'Content-Type: application/json; charset=utf-8' ); + Template::addHeader( 'Access-Control-Allow-Origin: *' ); + Template::addHeader( 'Content-Type: application/json; charset=utf-8' ); } public function index() { - header('Access-Control-Allow-Origin: *'); - if ( !Forms::check( 'apiLogin' ) ) { + if ( ! Forms::check( 'apiLogin' ) ) { $responseType = 'error'; - $response = 'malformed input1'; + $response = 'malformed input'; return Views::view( 'api.response', ['response' => json_encode( [ $responseType => $response ], true )]); } $user = self::$user->authorize( Input::post( 'username' ), Input::post( 'password' ) ); @@ -45,7 +44,7 @@ class Login extends ApiController { return Views::view( 'api.response', ['response' => json_encode( [ $responseType => $response ], true )]); } $responseType = 'token'; - $token = self::$tokens->findOrCreateUserToken( $user->ID ); + $token = self::$tokens->findOrCreateUserToken( $user->ID, true ); return Views::view( 'api.response', ['response' => json_encode( [ $responseType => $token ], true )]); } } \ No newline at end of file diff --git a/app/controllers/home.php b/app/controllers/home.php index daf116d..16659f1 100644 --- a/app/controllers/home.php +++ b/app/controllers/home.php @@ -27,13 +27,13 @@ use TheTempusProject\TheTempusProject as App; class Home extends Controller { public function index() { self::$title = '{SITENAME}'; - self::$pageDescription = 'This is the homepage of your new Tempus Project Installation. Thank you for installing. find more info at https://thetempusproject.com'; + self::$pageDescription = '{SITENAME} is here to provide you a better, faster, and easier - way to create and manage your own web applications.'; Views::view( 'index' ); } public function login() { self::$title = 'Portal - {SITENAME}'; - self::$pageDescription = 'Please log in to use {SITENAME} member features.'; + self::$pageDescription = 'Please log in to access all of the great features {SITENAME} has to offer.'; if ( App::$isLoggedIn ) { return Issues::add( 'notice', 'You are already logged in. Please click here to log out.' ); } @@ -69,7 +69,7 @@ class Home extends Controller { public function profile( $id = null ) { self::$title = 'User Profile - {SITENAME}'; - self::$pageDescription = 'User Profiles for {SITENAME}'; + self::$pageDescription = 'User Profile - {SITENAME}'; if ( !App::$isLoggedIn ) { return Issues::add( 'notice', 'You must be logged in to view this page.' ); } @@ -89,38 +89,22 @@ class Home extends Controller { Views::view( 'termsPage' ); } - public function hashtag( $id = null ) { - self::$title = 'HashTag - {SITENAME}'; - self::$pageDescription = 'HashTags for {SITENAME}'; - if ( !App::$isLoggedIn ) { - return Issues::add( 'notice', 'You must be logged in to view this page.' ); - } - // this should look up comments and blog posts with the hashtag in them - Views::view( 'hashtags' ); - } - public function about() { self::$title = 'About - {SITENAME}'; - self::$pageDescription = '{SITENAME} Terms and Conditions of use. Please use {SITENAME} safely.'; + self::$pageDescription = '{SITENAME} was started by a developer with years of industry experience which has lead to a refined no-nonsense tool for everyone. Find out more about us here.'; Views::view( 'about' ); } - public function contact() { - self::$title = 'Contact Us - {SITENAME}'; - self::$pageDescription = '{SITENAME} Terms and Conditions of use. Please use {SITENAME} safely.'; - Views::view( 'contact' ); - } - public function privacy() { self::$title = 'Privacy Policy - {SITENAME}'; - self::$pageDescription = '{SITENAME} Terms and Conditions of use. Please use {SITENAME} safely.'; + self::$pageDescription = 'At {SITENAME} you privacy is very important to us. On this page you can find a detailed outline of all the information we collect and how its used.'; Components::set( 'PRIVACY', Views::simpleView( 'privacy' ) ); Views::raw( '
{PRIVACY}
' ); } public function faq() { self::$title = 'Frequently Asked Questions - {SITENAME}'; - self::$pageDescription = '{SITENAME} Terms and Conditions of use. Please use {SITENAME} safely.'; + self::$pageDescription = 'Many times, we aren\'t the first to ask why or how something works. Here you will find a list of {SITENAME} commonly asked questions and our best answers.' ; Views::view( 'faq' ); } } diff --git a/app/controllers/register.php b/app/controllers/register.php index f07cb19..275fdc2 100644 --- a/app/controllers/register.php +++ b/app/controllers/register.php @@ -27,6 +27,7 @@ use TheTempusProject\Classes\Forms; class Register extends Controller { public function confirm( $code = null ) { + Template::noIndex(); self::$title = 'Confirm Email'; if ( !isset( $code ) && !Input::exists( 'confirmationCode' ) ) { return Views::view( 'confirmation' ); @@ -43,8 +44,8 @@ class Register extends Controller { } public function index() { - self::$title = 'Register'; - self::$pageDescription = 'Many features of the site are disabled or even hidden from unregistered users. On this page you can sign up for an account to access all the app has to offer.'; + self::$title = '{SITENAME} Sign Up'; + self::$pageDescription = 'Many features of {SITENAME} are disabled or hidden from unregistered users. On this page you can sign up for an account to access all the app has to offer.'; Components::set( 'TERMS', Views::simpleView( 'terms' ) ); if ( App::$isLoggedIn ) { return Issues::add( 'notice', 'You are currently logged in.' ); @@ -94,6 +95,7 @@ class Register extends Controller { public function resend() { self::$title = 'Resend Confirmation'; + Template::noIndex(); if ( !App::$isLoggedIn ) { return Issues::add( 'notice', 'Please log in to resend your confirmation email.' ); } @@ -110,6 +112,7 @@ class Register extends Controller { public function reset( $code = null ) { self::$title = 'Password Reset'; + Template::noIndex(); if ( !isset( $code ) && !Input::exists( 'resetCode' ) ) { Issues::add( 'info', 'Please provide a reset code.' ); return Views::view( 'password_reset_code' ); diff --git a/app/controllers/usercp.php b/app/controllers/usercp.php index 55f7c58..39a5444 100644 --- a/app/controllers/usercp.php +++ b/app/controllers/usercp.php @@ -36,12 +36,12 @@ class Usercp extends Controller { Redirect::home(); } Template::noIndex(); - $menu = Views::simpleView( 'nav.usercp', App::$userCPlinks ); - Navigation::activePageSelect( $menu, null, true, true ); } public function email() { self::$title = 'Email Settings'; + $menu = Views::simpleView( 'nav.usercp', App::$userCPlinks ); + Navigation::activePageSelect( $menu, null, true, true ); if ( App::$activeUser->confirmed != '1' ) { return Issues::add( 'notice', 'You need to confirm your email address before you can make modifications. If you would like to resend that confirmation link, please click here', true ); } @@ -68,11 +68,15 @@ class Usercp extends Controller { public function index() { self::$title = 'User Control Panel'; + $menu = Views::simpleView( 'nav.usercp', App::$userCPlinks ); + Navigation::activePageSelect( $menu, null, true, true ); Views::view( 'profile', App::$activeUser ); } public function password() { self::$title = 'Password Settings'; + $menu = Views::simpleView( 'nav.usercp', App::$userCPlinks ); + Navigation::activePageSelect( $menu, null, true, true ); if ( !Input::exists() ) { return Views::view( 'user_cp.password_change' ); } @@ -94,11 +98,12 @@ class Usercp extends Controller { public function settings() { self::$title = 'Preferences'; + $menu = Views::simpleView( 'nav.usercp', App::$userCPlinks ); + Navigation::activePageSelect( $menu, null, true, true ); $prefs = new Preferences; $fields = App::$activePrefs; if ( Input::exists( 'submit' ) ) { $fields = $prefs->convertFormToArray( true, false ); - // dv( $fields ); // @TODO now i may need to rework the form checker to work with this.... // if (!Forms::check('userPrefs')) { // Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] ); @@ -110,4 +115,37 @@ class Usercp extends Controller { Components::set( 'PREFERENCES_FORM', $prefs->getFormHtml( $fields ) ); Views::view( 'user_cp.settings', App::$activeUser ); } + + public function updatePref() { + Template::setTemplate( 'api' ); + if ( ! App::$isLoggedIn ) { + return Views::view( 'api.response', ['response' => json_encode( [ 'error' => 'Not Logged In' ], true )]); + } + if ( ! Forms::check( 'updatePreference' ) ) { + return Views::view( 'api.response', ['response' => json_encode( [ 'error' => Check::userErrors() ], true )]); + } + $name = Input::post( 'prefName' ); + $value = Input::post('prefValue' ); + + if ( 'false' === $value ) { + $value = false; + } elseif ( 'true' === $value ) { + $value = true; + } + + if ( empty( Preferences::get( $name ) ) ) { + return Views::view( 'api.response', ['response' => json_encode( [ 'error' => 'Unknown Preference' ], true )]); + } + + $prefs = new Preferences; + $fields1 = $prefs->convertFormToArray( true, false ); + $fields3 = $fields1; + + if ( isset( $fields1[ $name ] ) ) { + $fields3[ $name ] = $value; + } + $result = self::$user->updatePrefs( $fields3, App::$activeUser->ID ); + + return Views::view( 'api.response', ['response' => json_encode( $result, true )]); + } } diff --git a/app/css/main-dark.css b/app/css/main-dark.css index 226a12b..4e9e249 100644 --- a/app/css/main-dark.css +++ b/app/css/main-dark.css @@ -21,9 +21,14 @@ .context-second-bg { background-color: #1e1e1e; } +.context-third-bg { + background-color: #3a3a3a; +} .bg-default { background-color: #2c2c2c; } + + .bg-none,.bg-warning { color: #000 !important; } @@ -135,3 +140,14 @@ body { .text-shadow-3 { text-shadow: 0 .5rem 1.5rem rgba(255, 255, 255, .25); } + +.form-control { + background-color: #1f1f1f; + color: #e0e0e0; +} +.form-control:focus { + color: #e0e0e0; + border-color: #1e90ff; + background-color: #1f1f1f; + box-shadow: 0 0 0 .25rem rgba(30, 144, 255, .5); +} \ No newline at end of file diff --git a/app/css/main.css b/app/css/main.css index 7f64ee8..c05624d 100644 --- a/app/css/main.css +++ b/app/css/main.css @@ -92,8 +92,10 @@ html { pre { white-space: pre-wrap; } + body { - background-image: linear-gradient(180deg, #eee, #fff 100px, #fff); + background-color: #e4e4e4; + /* background-image: linear-gradient(180deg, #eee, #fff 100px, #fff); */ } @media ( min-width: 768px ) { .main { diff --git a/app/images/ttp.png b/app/images/ttp.png index 2ad7269..ebb70f8 100644 Binary files a/app/images/ttp.png and b/app/images/ttp.png differ diff --git a/app/js/main.js b/app/js/main.js index 5b38519..47b416a 100644 --- a/app/js/main.js +++ b/app/js/main.js @@ -102,7 +102,10 @@ document.addEventListener('DOMContentLoaded', function () { // Check if dark mode is saved in localStorage if (localStorage.getItem('darkMode') === 'enabled') { darkModeStylesheet.disabled = false; - toggleButton.checked = true; + + if ( toggleButton ) { + toggleButton.checked = true; + } if ( enableButton ) { enableButton.innerText = 'Disable Now'; @@ -119,35 +122,48 @@ document.addEventListener('DOMContentLoaded', function () { if ( enableButton ) { enableButton.addEventListener('click', function () { - if (darkModeStylesheet.disabled) { - darkModeStylesheet.disabled = false; - localStorage.setItem('darkMode', 'enabled'); - enableButton.innerText = 'Disable Now'; - } else { - darkModeStylesheet.disabled = true; - localStorage.setItem('darkMode', 'disabled'); - enableButton.innerText = 'Enable Now'; - } + if (darkModeStylesheet.disabled) { + darkModeStylesheet.disabled = false; + localStorage.setItem('darkMode', 'enabled'); + enableButton.innerText = 'Disable Now'; + } else { + darkModeStylesheet.disabled = true; + localStorage.setItem('darkMode', 'disabled'); + enableButton.innerText = 'Enable Now'; + } }); } - toggleButton.addEventListener('click', function () { - if (darkModeStylesheet.disabled) { - darkModeStylesheet.disabled = false; - localStorage.setItem('darkMode', 'enabled'); - } else { - darkModeStylesheet.disabled = true; - localStorage.setItem('darkMode', 'disabled'); - } - - document.querySelectorAll('.table-striped').forEach((table) => { - if (localStorage.getItem('darkMode') === 'enabled') { - table.classList.add('table-dark'); - table.classList.remove('table-light'); - } else { - table.classList.add('table-light'); - table.classList.remove('table-dark'); - } - }); - }); + if ( toggleButton ) { + toggleButton.addEventListener('click', function () { + if (darkModeStylesheet.disabled) { + toggleDarkModePref( true ); + darkModeStylesheet.disabled = false; + localStorage.setItem('darkMode', 'enabled'); + } else { + toggleDarkModePref( false ); + darkModeStylesheet.disabled = true; + localStorage.setItem('darkMode', 'disabled'); + } + + document.querySelectorAll('.table-striped').forEach((table) => { + if (localStorage.getItem('darkMode') === 'enabled') { + table.classList.add('table-dark'); + table.classList.remove('table-light'); + } else { + table.classList.add('table-light'); + table.classList.remove('table-dark'); + } + }); + }); + } + + function toggleDarkModePref( value ) { + var fields = {}; + fields.prefName = 'darkMode'; + fields.prefValue = value; + $.post( '/usercp/updatePref', fields ).done(function(response) { + // alert('Timer updated successfully!'); + }); + } }); diff --git a/app/models/routes.php b/app/models/routes.php index 63a23d1..8333692 100644 --- a/app/models/routes.php +++ b/app/models/routes.php @@ -72,7 +72,7 @@ class Routes extends DatabaseModel { return false; } if ( !Check::simpleName( $nickname ) ) { - Debug::warn( 'Invalid route nickname: ' . $name ); + Debug::warn( 'Invalid route nickname: ' . $nickname ); return false; } if ( 'external' == $type && !Check::url( $forwarded_url ) ) { diff --git a/app/models/token.php b/app/models/token.php index 167e961..fe9198a 100644 --- a/app/models/token.php +++ b/app/models/token.php @@ -94,10 +94,15 @@ class Token extends DatabaseModel { return false; } - public function findOrCreateUserToken( $user_id ) { + public function findOrCreateUserToken( $user_id, $refresh = false ) { $test = $this->findUserToken( $user_id ); if ( ! empty( $test ) ) { - return $test->token; + if ( ! empty( $refresh ) ) { + $token = $this->refresh( $test->ID, 'user' ); + } else { + $token = $test->token; + } + return $token; } $expiration = Config::getValue( 'api/UserAccessTokenExpiration' ); diff --git a/app/models/user.php b/app/models/user.php index 5eb8a38..62012fa 100644 --- a/app/models/user.php +++ b/app/models/user.php @@ -121,6 +121,11 @@ class User extends DatabaseModel { '50', ], ], + 'darkMode' => [ + 'pretty' => 'Enable Dark-Mode viewing', + 'type' => 'checkbox', + 'default' => 'false', + ], ]; protected static $avatars; protected static $preferences; diff --git a/app/plugins/blog/controllers/admin/blog.php b/app/plugins/blog/controllers/admin/blog.php index adfc451..36b9097 100644 --- a/app/plugins/blog/controllers/admin/blog.php +++ b/app/plugins/blog/controllers/admin/blog.php @@ -46,7 +46,7 @@ class Blog extends AdminController { return $this->index(); } - $result = self::$posts->newPost( Input::post( 'title' ), Input::post( 'blogPost' ), Input::post( 'submit' ) ); + $result = self::$posts->newPost( Input::post( 'title' ), Input::post( 'blogPost' ), Input::post( 'slug' ), Input::post( 'submit' ) ); if ( $result ) { Issues::add( 'success', 'Your post has been created.' ); return $this->index(); @@ -67,7 +67,7 @@ class Blog extends AdminController { Issues::add( 'error', [ 'There was an error with your form.' => Check::userErrors() ] ); return $this->index(); } - if ( self::$posts->updatePost( $data, Input::post( 'title' ), Input::post( 'blogPost' ), Input::post( 'submit' ) ) === true ) { + if ( self::$posts->updatePost( $data, Input::post( 'title' ), Input::post( 'blogPost' ), Input::post( 'slug' ), Input::post( 'submit' ) ) === true ) { Issues::add( 'success', 'Post Updated.' ); return $this->index(); } diff --git a/app/plugins/blog/controllers/blog.php b/app/plugins/blog/controllers/blog.php index b14100b..80cc7c8 100644 --- a/app/plugins/blog/controllers/blog.php +++ b/app/plugins/blog/controllers/blog.php @@ -62,12 +62,17 @@ class Blog extends Controller { return $this->index(); } - $plugin = new Comments; - if ( ! $plugin->checkEnabled() ) { - Issues::add( 'error', 'Comments are disabled.' ); + if ( class_exists( 'TheTempusProject\Plugins\Comments' ) ) { + $plugin = new Comments; + if ( ! $plugin->checkEnabled() ) { + Issues::add( 'error', 'Comments are disabled.' ); + return $this->index(); + } + $comments = new CommentsModel; + } else { + Debug::info( 'error', 'Comments plugin missing.' ); return $this->index(); } - $comments = new CommentsModel; switch ( $sub ) { case 'post': @@ -100,7 +105,10 @@ class Blog extends Controller { } $post = self::$posts->findById( $id ); if ( empty( $post ) ) { - return $this->index(); + $post = self::$posts->findBySlug( $id ); + if ( empty( $post ) ) { + return $this->index(); + } } Debug::log( 'Controller initiated: ' . __METHOD__ . '.' ); self::$title = 'Blog Post'; @@ -111,25 +119,24 @@ class Blog extends Controller { Components::set( 'CONTENT_ID', $id ); Components::set( 'COMMENT_TYPE', self::$posts->tableName ); + Components::set( 'NEWCOMMENT', '' ); + Components::set( 'count', '0' ); + Components::set( 'COMMENTS', '' ); - $plugin = new Comments; - if ( ! $plugin->checkEnabled() ) { - Components::set( 'NEWCOMMENT', '' ); - Components::set( 'count', '0' ); - Components::set( 'COMMENTS', '' ); - } else { - $comments = new CommentsModel; - if ( App::$isLoggedIn ) { - Components::set( 'NEWCOMMENT', Views::simpleView( 'comments.create' ) ); - } else { - Components::set( 'NEWCOMMENT', '' ); + if ( class_exists( 'TheTempusProject\Plugins\Comments' ) ) { + $plugin = new Comments; + if ( $plugin->checkEnabled() ) { + $comments = new CommentsModel; + if ( App::$isLoggedIn ) { + Components::set( 'NEWCOMMENT', Views::simpleView( 'comments.create' ) ); + } else { + Components::set( 'NEWCOMMENT', '' ); + } + Components::set( 'count', $comments->count( self::$posts->tableName, $post->ID ) ); + Components::set( 'COMMENTS', Views::simpleView( 'comments.list', $comments->display( 10, self::$posts->tableName, $post->ID ) ) ); } - Components::set( 'count', $comments->count( self::$posts->tableName, $post->ID ) ); - Components::set( 'COMMENTS', Views::simpleView( 'comments.list', $comments->display( 10, self::$posts->tableName, $post->ID ) ) ); } - $post = self::$posts->findById( $id ); - self::$title .= ' - ' . $post->title; self::$pageDescription = strip_tags( $post->contentSummaryNoLink ); Views::view( 'blog.post', $post ); diff --git a/app/plugins/blog/models/posts.php b/app/plugins/blog/models/posts.php index 471f51d..212ac2b 100644 --- a/app/plugins/blog/models/posts.php +++ b/app/plugins/blog/models/posts.php @@ -32,6 +32,7 @@ class Posts extends DatabaseModel { [ 'edited', 'int', '10' ], [ 'draft', 'int', '1' ], [ 'title', 'varchar', '86' ], + [ 'slug', 'varchar', '64' ], [ 'content', 'text', '' ], ]; @@ -45,7 +46,7 @@ class Posts extends DatabaseModel { } } - public function newPost( $title, $post, $draft ) { + public function newPost( $title, $post, $slug, $draft ) { if ( !Check::dataTitle( $title ) ) { Debug::info( 'modelBlog: illegal title.' ); @@ -59,6 +60,7 @@ class Posts extends DatabaseModel { $fields = [ 'author' => App::$activeUser->ID, 'draft' => $draft, + 'slug' => $slug, 'created' => time(), 'edited' => time(), 'content' => Sanitize::rich( $post ), @@ -73,7 +75,7 @@ class Posts extends DatabaseModel { return true; } - public function updatePost( $id, $title, $content, $draft ) { + public function updatePost( $id, $title, $content, $slug, $draft ) { if ( empty( self::$log ) ) { self::$log = new Log; } @@ -94,6 +96,7 @@ class Posts extends DatabaseModel { } $fields = [ 'draft' => $draft, + 'slug' => $slug, 'edited' => time(), 'content' => Sanitize::rich( $content ), 'title' => $title, @@ -131,39 +134,47 @@ class Posts extends DatabaseModel { } $draft = ''; $authorName = self::$user->getUsername( $instance->author ); - $cleanPost = Sanitize::contentShort( $instance->content ); - $postSpace = explode( ' ', $cleanPost ); - $postLine = explode( "\n", $cleanPost ); - // summary by words: 100 - $spaceSummary = implode( ' ', array_splice( $postSpace, 0, 100 ) ); - // summary by lines: 5 - $lineSummary = implode( "\n", array_splice( $postLine, 0, 5 ) ); - if ( strlen( $spaceSummary ) < strlen( $lineSummary ) ) { - $contentSummary = $spaceSummary; - if ( count( $postSpace, 1 ) <= 100 ) { - $contentSummaryNoLink = $contentSummary; - $contentSummary .= '... Read More'; - } + + // Summarize + if ( ! empty( $instance->slug ) ) { + $identifier = $instance->slug; + } else { + $identifier = $instance->ID; + } + + $cleanPost = Sanitize::contentShort( $instance->content ); + // By Word + $wordsArray = explode( ' ', $cleanPost ); + $wordSummary = implode( ' ', array_splice( $wordsArray, 0, 100 ) ); + // By Line + $linesArray = explode( "\n", $cleanPost ); + $lineSummary = implode( "\n", array_splice( $linesArray, 0, 5 ) ); + + if ( strlen( $wordSummary ) < strlen( $lineSummary ) ) { + $contentSummaryNoLink = $wordSummary; + $contentSummary = $wordSummary . '... Read More'; } else { - // @todo: need to refine this after testing $contentSummaryNoLink = $lineSummary; - $contentSummary = $lineSummary . '... Read More'; + $contentSummary = $lineSummary . '... Read More'; + } + + $instance->contentSummaryNoLink = $contentSummaryNoLink; + $instance->contentSummary = $contentSummary; + + if ( isset( $params['stripHtml'] ) && $params['stripHtml'] === true ) { + $instance->contentSummary = strip_tags( $instance->content ); } if ( $instance->draft != '0' ) { $draft = ' Draft'; } $instance->isDraft = $draft; $instance->authorName = $authorName; - $instance->contentSummaryNoLink = $contentSummaryNoLink; - $instance->contentSummary = $contentSummary; - if ( isset( $params['stripHtml'] ) && $params['stripHtml'] === true ) { - $instance->contentSummary = strip_tags( $instance->content ); - } if ( self::$comments !== false ) { $instance->commentCount = self::$comments->count( 'blog', $instance->ID ); } $instance->content = Filters::applyOne( 'mentions.0', $instance->content, true ); $instance->content = Filters::applyOne( 'hashtags.0', $instance->content, true ); + $out[] = $instance; if ( !empty( $end ) ) { $out = $out[0]; @@ -291,6 +302,22 @@ class Posts extends DatabaseModel { return $this->filter( $postData->results() ); } + public function findBySlug( $slug, $includeDraft = false ) { + $whereClause = []; + if ( $includeDraft !== true ) { + $whereClause = ['draft', '=', '0', 'AND']; + } + + $whereClause = array_merge( $whereClause, ['slug', '=', $slug] ); + + $postData = self::$db->get( $this->tableName, $whereClause ); + if ( !$postData->count() ) { + Debug::info( 'No Blog posts found.' ); + return false; + } + return $this->filter( $postData->first() ); + } + public function byMonth( $month, $year = 0, $includeDraft = false ) { if ( 0 === $year ) { $year = date( 'Y' ); diff --git a/app/plugins/blog/views/admin/create.html b/app/plugins/blog/views/admin/create.html index 7ae25f5..00d9d00 100644 --- a/app/plugins/blog/views/admin/create.html +++ b/app/plugins/blog/views/admin/create.html @@ -12,6 +12,14 @@
+ +
+ +
+ +
+
+
diff --git a/app/plugins/blog/views/admin/edit.html b/app/plugins/blog/views/admin/edit.html index 986ff11..957a2e8 100644 --- a/app/plugins/blog/views/admin/edit.html +++ b/app/plugins/blog/views/admin/edit.html @@ -12,6 +12,14 @@
+ +
+ +
+ +
+
+
diff --git a/app/plugins/blog/views/list.html b/app/plugins/blog/views/list.html index a924026..0a42697 100644 --- a/app/plugins/blog/views/list.html +++ b/app/plugins/blog/views/list.html @@ -1,7 +1,7 @@ {LOOP}

{title}

- +
{contentSummary}
diff --git a/app/plugins/blog/views/post.html b/app/plugins/blog/views/post.html index b955657..3484817 100644 --- a/app/plugins/blog/views/post.html +++ b/app/plugins/blog/views/post.html @@ -3,7 +3,7 @@

{title}


- + {content} {ADMIN}
diff --git a/app/plugins/blog/views/sidebar.html b/app/plugins/blog/views/sidebar.html index 07ca483..85eb67e 100644 --- a/app/plugins/blog/views/sidebar.html +++ b/app/plugins/blog/views/sidebar.html @@ -5,7 +5,7 @@
    {LOOP} -
  1. {title}
  2. +
  3. {title}
  4. {/LOOP} {ALT}
  5. No Posts to show
  6. @@ -13,6 +13,6 @@
\ No newline at end of file diff --git a/app/plugins/blog/views/sidebar2.html b/app/plugins/blog/views/sidebar2.html index b135d93..d64ac19 100644 --- a/app/plugins/blog/views/sidebar2.html +++ b/app/plugins/blog/views/sidebar2.html @@ -2,7 +2,7 @@

Archives

    {LOOP} -
  • ({count}) {monthText} {year}
  • +
  • ({count}) {monthText} {year}
  • {/LOOP} {ALT}
  • None To Show
  • diff --git a/app/plugins/bugreport/views/create.html b/app/plugins/bugreport/views/create.html index a3607c9..8230842 100644 --- a/app/plugins/bugreport/views/create.html +++ b/app/plugins/bugreport/views/create.html @@ -1,5 +1,6 @@

    Bug Report

    +

    Thank you for visiting our bug reporting page. We value our users' input highly and in an effort to better serve your needs, please fill out the form below to help us address this issue.

    We read each and every bug report submitted, and by submitting this form you allow us to send you a follow-up email.

    diff --git a/app/plugins/comments/controllers/admin/comments.php b/app/plugins/comments/controllers/admin/comments.php index 8967873..4c9ead6 100644 --- a/app/plugins/comments/controllers/admin/comments.php +++ b/app/plugins/comments/controllers/admin/comments.php @@ -49,13 +49,13 @@ class Comments extends AdminController { $this->index(); } - public function viewComments( $contentIID = null ) { - if ( empty( $contentIID ) ) { + public function viewComments( $contentID = null ) { + if ( empty( $contentID ) ) { Issues::add( 'error', 'Content ID not found.' ); return $this->index(); } $contentData = self::$comments->findById( $data ); - if ( empty( $contentIID ) ) { + if ( empty( $contentID ) ) { return Views::view( 'comments.list', $commentData ); } Issues::add( 'error', 'Comment not found.' ); diff --git a/app/plugins/comments/views/list.html b/app/plugins/comments/views/list.html index 3fc478b..1cdf0fc 100644 --- a/app/plugins/comments/views/list.html +++ b/app/plugins/comments/views/list.html @@ -28,7 +28,7 @@ {/LOOP} {ALT} -
  • +
  • Be the first to comment.

    diff --git a/app/plugins/notifications/models/notification.php b/app/plugins/notifications/models/notification.php index 75af1c3..e83b6b2 100644 --- a/app/plugins/notifications/models/notification.php +++ b/app/plugins/notifications/models/notification.php @@ -115,7 +115,7 @@ class Notification extends DatabaseModel { ]; if ( !self::$db->update( $this->tableName, $id, $fields ) ) { new CustomException( 'notificationDelete' ); - Debug::error( "Bookmarks: $id not updated" ); + Debug::error( "Notifications: $id not updated" ); return false; } return true; diff --git a/app/plugins/notifications/views/nav/recentNotificationsDropdown.html b/app/plugins/notifications/views/nav/recentNotificationsDropdown.html index afffdaf..0715826 100644 --- a/app/plugins/notifications/views/nav/recentNotificationsDropdown.html +++ b/app/plugins/notifications/views/nav/recentNotificationsDropdown.html @@ -3,13 +3,13 @@ -
- - -https://www.bookmarkninja.com/ - - -simple robust versatile -sleek -clean -intuitive -modern - -A cleaner app for managing bookmarks to cut down on the clutter - -Available accross all devices and systems. - -regardless of windows or mac, android or apple, wwe have you covered - - -bring all your bookmarks at once, simply export from your current browser and use our import tool - -stop straining your eyes! Not only can you use our dark mode feature, but we have several styles to choose from to customize your experience - - -no mobile app necessary - - -privacy is key! but sharing is ok -by defaults everything is set to private, but usiing the web interface will alow you to share single links or entire lists/folders - + \ No newline at end of file diff --git a/app/views/install/configure.html b/app/views/install/configure.html index a5eac74..3b4c616 100644 --- a/app/views/install/configure.html +++ b/app/views/install/configure.html @@ -1,5 +1,5 @@ -{installer-nav} -
+
+ {installer-nav}
Configure diff --git a/app/views/install/models.html b/app/views/install/models.html index 9b7bd7a..85cba5d 100644 --- a/app/views/install/models.html +++ b/app/views/install/models.html @@ -1,5 +1,5 @@ -{installer-nav} -
+
+ {installer-nav}

All models are required for proper installation of The Tempus Project. In this step, we will add the database tables required for these models. In the next step, you'll be able to select which plugins you would like installed.

diff --git a/app/views/install/nav.html b/app/views/install/nav.html index 84a3eb2..a1e937a 100644 --- a/app/views/install/nav.html +++ b/app/views/install/nav.html @@ -1,12 +1,12 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/views/install/plugins.html b/app/views/install/plugins.html index 94ad294..3adcca6 100644 --- a/app/views/install/plugins.html +++ b/app/views/install/plugins.html @@ -1,5 +1,5 @@ -{installer-nav} -
+
+ {installer-nav}

diff --git a/app/views/install/resources.html b/app/views/install/resources.html index d271668..666f678 100644 --- a/app/views/install/resources.html +++ b/app/views/install/resources.html @@ -1,5 +1,5 @@ -{installer-nav} -

+
+ {installer-nav}

diff --git a/app/views/install/routing.html b/app/views/install/routing.html index 1511e4e..c3306e9 100644 --- a/app/views/install/routing.html +++ b/app/views/install/routing.html @@ -1,5 +1,5 @@ -{installer-nav} -

+
+ {installer-nav}

The Tempus Project uses rewrites in htaccess files (Apache), or location directives (Nginx), to automatically route all incoming traffic through the app. In this step, we will help set-up and then test that the required configurations have been made.

diff --git a/app/views/install/start.html b/app/views/install/start.html deleted file mode 100644 index 3fa11a4..0000000 --- a/app/views/install/start.html +++ /dev/null @@ -1,13 +0,0 @@ -
-
-
- {installer-nav} -

Welcome to The Tempus Project Installer.

-

This installer will guide you through the process of installing and configuring The Tempus Project. Do not forget to delete this file once you have completed installation.

- - -
- -
-
-
\ No newline at end of file diff --git a/app/views/install/agreement.html b/app/views/install/terms.html similarity index 81% rename from app/views/install/agreement.html rename to app/views/install/terms.html index 5db62c6..69ab428 100644 --- a/app/views/install/agreement.html +++ b/app/views/install/terms.html @@ -1,7 +1,7 @@ -{installer-nav} -
+
+ {installer-nav}
-
+
{TERMS}
diff --git a/app/views/install/adminUser.html b/app/views/install/user.html similarity index 95% rename from app/views/install/adminUser.html rename to app/views/install/user.html index 736092a..69d8c74 100644 --- a/app/views/install/adminUser.html +++ b/app/views/install/user.html @@ -1,5 +1,5 @@ -{installer-nav} -
+
+ {installer-nav}
diff --git a/app/views/install/check.html b/app/views/install/verify.html similarity index 91% rename from app/views/install/check.html rename to app/views/install/verify.html index 6c763ab..6b7fcfe 100644 --- a/app/views/install/check.html +++ b/app/views/install/verify.html @@ -1,5 +1,5 @@ -{installer-nav} -
+
+ {installer-nav}

Requirements

diff --git a/app/views/install/welcome.html b/app/views/install/welcome.html new file mode 100644 index 0000000..b95adea --- /dev/null +++ b/app/views/install/welcome.html @@ -0,0 +1,17 @@ +
+
+
+
+ {installer-nav} +

Welcome to The Tempus Project Installer.

+

+ This installer will guide you through the process of installing and configuring The Tempus Project. Do not forget to delete this file once you have completed installation. +

+ + +
+ +
+
+
+
\ No newline at end of file diff --git a/app/views/login.html b/app/views/login.html index 6ed5b17..54aa03c 100644 --- a/app/views/login.html +++ b/app/views/login.html @@ -8,7 +8,7 @@
logo -

AllTheBookmarks

+

{SITENAME}

@@ -26,7 +26,7 @@
- Forgot password? diff --git a/app/views/nav/statusLoggedOut.html b/app/views/nav/statusLoggedOut.html index aecd27d..b9c8dfc 100644 --- a/app/views/nav/statusLoggedOut.html +++ b/app/views/nav/statusLoggedOut.html @@ -1,4 +1,3 @@ -