Merge branch 'main' into joeykimsey-com

This commit is contained in:
Joey Kimsey
2025-01-14 14:13:07 -05:00
203 changed files with 5333 additions and 3375 deletions

View File

@ -39,7 +39,7 @@ class Admin extends AdminController {
}
public function index() {
return Views::view( 'admin.logs.admin_list', self::$log->listPaginated( 'admin' ) );
return Views::view( 'admin.logs.admin_list', self::$log->list( 'admin' ) );
}
public function view( $id = null ) {

View File

@ -59,6 +59,6 @@ class Composer extends AdminController {
$out[] = (object) $versionsInstalled[ $name ];
}
Views::view( 'admin.modules.composer.dependencies', $out );
Views::view( 'admin.modules.dependencies', $out );
}
}

View File

@ -39,7 +39,7 @@ class Errors extends AdminController {
}
public function index() {
return Views::view( 'admin.logs.error_list', self::$log->listPaginated( 'error' ) );
return Views::view( 'admin.logs.error_list', self::$log->list( 'error' ) );
}
public function view( $id = null ) {

View File

@ -15,8 +15,11 @@ use TheTempusProject\Houdini\Classes\Views;
use TheTempusProject\Houdini\Classes\Components;
use TheTempusProject\Classes\AdminController;
use TheTempusProject\Models\User;
use TheTempusProject\Plugins\Comments;
use TheTempusProject\Plugins\Blog;
use TheTempusProject\Models\Comments;
use TheTempusProject\Models\Posts;
use TheTempusProject\Plugins\Comments as CommentPlugin;
use TheTempusProject\Plugins\Blog as BlogPlugin;
use TheTempusProject\Canary\Bin\Canary as Debug;
class Home extends AdminController {
public static $user;
@ -30,17 +33,29 @@ class Home extends AdminController {
public function index() {
if ( class_exists( 'TheTempusProject\Plugins\Comments' ) ) {
$comments = new Comments;
self::$comments = $comments->getModel();
$comments = Views::simpleView( 'comments.admin.dashboard', self::$comments->recent( 'all', 5 ) );
Components::set( 'commentDash', $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 ) );
Components::set( 'commentDash', $commentList );
}
}
if ( class_exists( 'TheTempusProject\Plugins\Blog' ) ) {
$blog = new Blog;
self::$posts = $blog->posts;
$posts = Views::simpleView( 'blog.admin.dashboard', self::$posts->recent( 5 ) );
Components::set( 'blogDash', $posts );
$plugin = new BlogPlugin;
if ( ! $plugin->checkEnabled() ) {
Debug::info( 'Blog Plugin is disabled in the control panel.' );
Components::set( 'blogDash', '' );
} else {
$posts = new Posts;
$postsList = Views::simpleView( 'blog.admin.dashboard', $posts->recent( 5 ) );
Components::set( 'blogDash', $postsList );
}
}
self::$user = new User;

View File

@ -39,7 +39,7 @@ class Logins extends AdminController {
}
public function index() {
return Views::view( 'admin.logs.login_list', self::$log->listPaginated( 'login' ) );
return Views::view( 'admin.logs.login_list', self::$log->list( 'login' ) );
}
public function view( $id = null ) {

View File

@ -26,8 +26,8 @@ class Logs extends AdminController {
}
public function index( $data = null ) {
Views::view( 'admin.logs.error_list', self::$log->listPaginated( 'error' ) );
Views::view( 'admin.logs.admin_list', self::$log->listPaginated( 'admin' ) );
Views::view( 'admin.logs.login_list', self::$log->listPaginated( 'login' ) );
Views::view( 'admin.logs.error_list', self::$log->list( 'error' ) );
Views::view( 'admin.logs.admin_list', self::$log->list( 'admin' ) );
Views::view( 'admin.logs.login_list', self::$log->list( 'login' ) );
}
}

View File

@ -39,7 +39,12 @@ class Plugins extends AdminController {
}
public function disable( $name = null ) {
if ( empty( $name ) ) {
Session::flash( 'error', 'Unknown Plugin.' );
Redirect::to( 'admin/plugins' );
}
Components::set( 'PLUGIN', $name );
self::$title = 'Admin - Disable ' . $name;
if ( !Input::exists( 'installHash' ) ) {
return Views::view( 'admin.modules.plugins.disable' );
}
@ -52,7 +57,12 @@ class Plugins extends AdminController {
}
public function enable( $name = null ) {
if ( empty( $name ) ) {
Session::flash( 'error', 'Unknown Plugin.' );
Redirect::to( 'admin/plugins' );
}
Components::set( 'PLUGIN', $name );
self::$title = 'Admin - Enable ' . $name;
if ( !Input::exists( 'installHash' ) ) {
return Views::view( 'admin.modules.plugins.enable' );
}
@ -71,6 +81,7 @@ class Plugins extends AdminController {
}
$name = strtolower( $name );
Components::set( 'PLUGIN', $name );
self::$title = 'Admin - Install ' . $name;
if ( ! Input::exists( 'installHash' ) ) {
return Views::view( 'admin.modules.plugins.install' );
}
@ -95,6 +106,7 @@ class Plugins extends AdminController {
}
$name = strtolower($name);
Components::set( 'PLUGIN', $name );
self::$title = 'Admin - Uninstall ' . $name;
if ( !Input::exists( 'uninstallHash' ) ) {
return Views::view( 'admin.modules.plugins.uninstall' );

View File

@ -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' );
}

View File

@ -1,8 +1,8 @@
<?php
/**
* app/controllers/admin/contact.php
* app/controllers/admin/send_mail.php
*
* This is the admin contact controller. The only real use is to send out emails to the various lists.
* This is the admin email controller. The only real use is to send out emails to the various lists.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
@ -19,13 +19,13 @@ use TheTempusProject\Houdini\Classes\Views;
use TheTempusProject\Models\User;
use TheTempusProject\Models\Subscribe;
class Contact extends AdminController {
class SendMail extends AdminController {
public static $user;
public static $subscribe;
public function __construct() {
parent::__construct();
self::$title = 'Admin - Contact';
self::$title = 'Admin - Send Mail';
self::$user = new User;
self::$subscribe = new Subscribe;
}

View File

@ -0,0 +1,90 @@
<?php
/**
* app/controllers/admin/tokens.php
*
* This is the admin app/user tokens controller.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Controllers\Admin;
use TheTempusProject\Classes\Forms as TTPForms;
use TheTempusProject\Houdini\Classes\Views;
use TheTempusProject\Houdini\Classes\Issues;
use TheTempusProject\Houdini\Classes\Navigation;
use TheTempusProject\Houdini\Classes\Components;
use TheTempusProject\Houdini\Classes\Forms;
use TheTempusProject\Classes\AdminController;
use TheTempusProject\Models\Token;
use TheTempusProject\Bedrock\Functions\Input;
use TheTempusProject\Bedrock\Functions\Check;
use TheTempusProject\Hermes\Functions\Redirect;
use TheTempusProject\Bedrock\Functions\Session;
class Tokens extends AdminController {
public static $token;
public function __construct() {
parent::__construct();
self::$title = 'Admin - Tokens';
self::$token = new Token;
$view = Navigation::activePageSelect( 'nav.admin', '/admin/tokens' );
Components::set( 'ADMINNAV', $view );
}
public function create() {
if ( Input::exists( 'submit' ) ) {
if ( !TTPForms::check( 'adminCreateToken' ) ) {
Issues::add( 'error', [ 'There was an error with your token.' => Check::userErrors() ] );
}
if ( self::$token->create(
Input::post( 'name' ),
Input::post( 'notes' ),
Input::post( 'token_type' )
) ) {
Session::flash( 'success', 'Token Created' );
Redirect::to( 'admin/tokens' );
}
}
Views::view( 'admin.tokens.create' );
}
public function delete( $id = null ) {
if ( self::$token->delete( [ $id ] ) ) {
Session::flash( 'success', 'Token deleted.' );
}
Redirect::to( 'admin/tokens' );
}
public function edit( $id = null ) {
$token = self::$token->findById( $id );
if ( Input::exists( 'submit' ) ) {
if ( !TTPForms::check( 'adminEditToken' ) ) {
Issues::add( 'error', [ 'There was an error with your token.' => Check::userErrors() ] );
} else {
if ( self::$token->update(
$id,
Input::post( 'name' ),
Input::post( 'notes' ),
Input::post( 'token_type' )
) ) {
Session::flash( 'success', 'Token Updated' );
Redirect::to( 'admin/tokens' );
}
}
}
Forms::selectOption( $token->token_type );
return Views::view( 'admin.tokens.edit', $token );
}
public function index() {
return Views::view( 'admin.tokens.list', self::$token->listPaginated() );
}
public function view( $id = null ) {
return Views::view( 'admin.tokens.view', self::$token->findById( $id ) );
}
}

View File

@ -26,6 +26,7 @@ use TheTempusProject\Classes\AdminController;
use TheTempusProject\Models\User;
use TheTempusProject\Models\Group;
use TheTempusProject\TheTempusProject as App;
use TheTempusProject\Houdini\Classes\Template;
class Users extends AdminController {
public static $user;
@ -63,8 +64,11 @@ class Users extends AdminController {
}
}
}
$select = Forms::getFormFieldHtml( 'groupSelect', 'User Group', 'select', Config::getValue( 'group/defaultGroup' ), self::$group->listGroupsSimple() );
$select = Forms::getSelectHtml(
'groupSelect',
self::$group->listGroupsSimple(),
Config::getValue( 'group/defaultGroup' ),
);
Components::set( 'groupSelect', $select );
Views::view( 'admin.users.create' );
}
@ -132,9 +136,15 @@ class Users extends AdminController {
$userGroup = $userData->userGroup;
}
Forms::selectRadio( 'confirmed', $userData->confirmed );
$avatar = Forms::getFormFieldHtml( 'avatar', 'User Avatar', 'file', $avatarLocation );
$select = Forms::getFormFieldHtml( 'groupSelect', 'User Group', 'select', $userGroup, self::$group->listGroupsSimple() );
$avatar = $this->getAvatar( 'avatar', $avatarLocation );
Components::set( 'AvatarSettings', $avatar );
$select = Forms::getSelectHtml(
'groupSelect',
self::$group->listGroupsSimple(),
$userGroup,
);
Components::set( 'groupSelect', $select );
Views::view( 'admin.users.edit', $userData );
}
@ -153,4 +163,28 @@ class Users extends AdminController {
}
$this->index();
}
private function getAvatar( $name, $value ) {
$fieldname = str_ireplace( '/', '-', $name );
$html = '';
$fieldHtml = '';
$fieldHtml = Forms::getFileHtml( $fieldname );
$html .= '<div class="mb-3 row">';
$html .= ' <label for="' . $fieldname . '" class="col-lg-6 col-form-label text-end">' . ucfirst( $fieldname ) . '</label>';
$html .= ' <div class="col-lg-2">';
$html .= ' ' . $fieldHtml;
$html .= ' </div>';
$html .= '</div>';
$html .= '<div class="mb-3 row">';
$html .= ' <h4 class="col-lg-6 col-form-label text-end">Current Image</h4>';
$html .= ' <div class="col-lg-2">';
$html .= ' <img alt="User Avatar" src="{ROOT_URL}' . $value . '" class="img-circle img-fluid p-2 avatar-125">';
$html .= ' </div>';
$html .= '</div>';
return Template::parse( $html );
}
}

View File

@ -0,0 +1,38 @@
<?php
/**
* app/controllers/api/auth.php
*
* This is the api authentication controller.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Controllers\Api;
use TheTempusProject\Models\User;
use TheTempusProject\Classes\ApiController;
use TheTempusProject\Houdini\Classes\Views;
use TheTempusProject\Models\Token;
class Auth extends ApiController {
public static $tokens;
public function __construct() {
parent::__construct();
self::$tokens = new Token;
}
public function refresh() {
$token = self::$tokens->refresh( self::$authToken->ID );
if ( empty( $token ) ) {
$responseType = 'error';
$response = 'IRDK';
} else {
$responseType = 'token';
$response = $token;
}
Views::view( 'api.response', ['response' => json_encode( [ $responseType => $response ], true )]);
}
}

View File

@ -0,0 +1,50 @@
<?php
/**
* app/controllers/api/auth.php
*
* This is the api authentication controller.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Controllers\Api;
use TheTempusProject\Classes\ApiController;
use TheTempusProject\Houdini\Classes\Views;
use TheTempusProject\Models\Token;
use TheTempusProject\Models\User;
use TheTempusProject\Houdini\Classes\Template;
use TheTempusProject\Classes\Forms;
use TheTempusProject\Bedrock\Functions\Input;
class Login extends ApiController {
public static $tokens;
public static $user;
public function __construct() {
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' );
}
public function index() {
if ( ! Forms::check( 'apiLogin' ) ) {
$responseType = 'error';
$response = 'malformed input';
return Views::view( 'api.response', ['response' => json_encode( [ $responseType => $response ], true )]);
}
$user = self::$user->authorize( Input::post( 'username' ), Input::post( 'password' ) );
if ( ! $user ) {
$responseType = 'error';
$response = 'bad credentials';
return Views::view( 'api.response', ['response' => json_encode( [ $responseType => $response ], true )]);
}
$responseType = 'token';
$token = self::$tokens->findOrCreateUserToken( $user->ID, true );
return Views::view( 'api.response', ['response' => json_encode( [ $responseType => $token ], true )]);
}
}

View File

@ -52,7 +52,7 @@ class Home extends Controller {
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 <a href="' . Routes::getAddress() . 'home/logout">click here</a> to log out.' );
}
@ -88,7 +88,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.' );
}
@ -105,17 +105,13 @@ class Home extends Controller {
self::$title = 'Terms and Conditions - {SITENAME}';
self::$pageDescription = '{SITENAME} Terms and Conditions of use. Please use {SITENAME} safely.';
Components::set( 'TERMS', Views::simpleView( 'terms' ) );
Views::raw( '<div class="terms-page">{TERMS}</div>' );
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} 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 about() {

View File

@ -27,24 +27,25 @@ 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( 'email.confirmation' );
return Views::view( 'confirmation' );
}
if ( Forms::check( 'emailConfirmation' ) ) {
$code = Input::post( 'confirmationCode' );
}
if ( !self::$user->confirm( $code ) ) {
Issues::add( 'error', 'There was an error confirming your account, please try again.' );
return Views::view( 'email.confirmation' );
return Views::view( 'confirmation' );
}
Session::flash( 'success', 'You have successfully confirmed your email address.' );
Redirect::to( 'home/index' );
}
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,43 +95,45 @@ 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.' );
}
if ( App::$activeUser->data()->confirmed == '1' ) {
if ( App::$activeUser->confirmed == '1' ) {
return Issues::add( 'notice', 'Your account has already been confirmed.' );
}
if ( !Forms::check( 'confirmationResend' ) ) {
return Views::view( 'email.confirmation_resend' );
return Views::view( 'confirmation_resend' );
}
Email::send( App::$activeUser->data()->email, 'confirmation', App::$activeUser->data()->confirmationCode, [ 'template' => true ] );
Email::send( App::$activeUser->email, 'confirmation', App::$activeUser->confirmationCode, [ 'template' => true ] );
Session::flash( 'success', 'Your confirmation email has been sent to the email for your account.' );
Redirect::to( 'home/index' );
}
public function reset( $code = null ) {
self::$title = 'Password Reset';
Template::noIndex();
if ( !isset( $code ) && !Input::exists( 'resetCode' ) ) {
Issues::add( 'error', 'No reset code provided.' );
Issues::add( 'info', 'Please provide a reset code.' );
return Views::view( 'password_reset_code' );
}
if ( Input::exists( 'resetCode' ) ) {
if ( Forms::check( 'password_reset_code' ) ) {
if ( Forms::check( 'passwordResetCode' ) ) {
$code = Input::post( 'resetCode' );
}
}
if ( !self::$user->checkCode( $code ) ) {
if ( ! self::$user->checkCode( $code ) ) {
Issues::add( 'error', 'There was an error with your reset code. Please try again.' );
return Views::view( 'password_reset_code' );
}
if ( !Input::exists() ) {
Components::set( 'resetCode', $code );
if ( ! Input::exists('password') ) {
return Views::view( 'password_reset' );
}
if ( !Forms::check( 'passwordReset' ) ) {
if ( ! Forms::check( 'passwordReset' ) ) {
Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] );
return Views::view( 'password_reset' );
}
Components::set( 'resetCode', $code );
self::$user->changePassword( $code, Input::post( 'password' ) );
Email::send( self::$user->data()->email, 'passwordChange', null, [ 'template' => true ] );
Session::flash( 'success', 'Your Password has been changed, please use your new password to log in.' );

View File

@ -36,13 +36,14 @@ class Usercp extends Controller {
Redirect::home();
}
Template::noIndex();
Navigation::activePageSelect( 'nav.usercp', null, 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 <a href="{BASE}register/resend">click here</a>', true );
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 <a href="/register/resend">click here</a>', true );
}
if ( !Input::exists() ) {
return Views::view( 'user_cp.email_change' );
@ -67,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' );
}
@ -93,6 +98,8 @@ 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' ) ) {
@ -108,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 )]);
}
}