Compare commits

...

9 Commits

Author SHA1 Message Date
a1f786876e bugfix 2025-06-21 02:29:57 -04:00
46390c2447 wip 2025-02-25 14:03:12 -05:00
c40b29e812 Apple PWA fixes 2025-02-07 16:14:00 -05:00
4dd66c6f56 share display fix 2025-02-06 04:50:54 -05:00
2ac64e5c49 image update 2025-02-05 22:46:24 -05:00
5590592ebe composer bump 2025-02-05 22:05:19 -05:00
b65dda1328 composer changes 2025-02-05 20:56:39 -05:00
f928e87141 bugfixes 2025-02-05 20:45:41 -05:00
a6b241c7f0 add qr-codes, share button, and pwa config toggle 2025-02-05 19:39:54 -05:00
35 changed files with 582 additions and 319 deletions

1
.gitignore vendored
View File

@ -65,3 +65,4 @@ vendor/canary/logs/*
components/* components/*
mailhog.log mailhog.log
uploads/* uploads/*
images/qr-codes/

View File

@ -74,7 +74,7 @@ class Config extends BedrockConfig {
$html .= '<div class="mb-3 row">'; $html .= '<div class="mb-3 row">';
$html .= '<h4 class="col-lg-3 col-form-label text-end">Current Value</h4>'; $html .= '<h4 class="col-lg-3 col-form-label text-end">Current Value</h4>';
$html .= '<div class="col-lg-6">'; $html .= '<div class="col-lg-6">';
$html .= '<input type="text" class="form-control" name="'.$name.'Text" value="'.$node['value'] . '">'; $html .= '<input type="text" class="form-control" name="'.$fieldname.'Text" value="'.$node['value'] . '">';
$html .= '</div>'; $html .= '</div>';
$html .= '</div>'; $html .= '</div>';
$html .= '<div class="mb-3 row">'; $html .= '<div class="mb-3 row">';

View File

@ -164,7 +164,7 @@ class Email {
} }
} }
$data->MAIL_FOOT = Views::simpleView( 'email.foot' ); $data->MAIL_FOOT = Views::simpleView( 'email.foot' );
$data->MAIL_TITLE = self::$title; $data->MAIL_TITLE = Template::parse( self::$title );
$data->MAIL_BODY = Template::parse( self::$message, $data ); $data->MAIL_BODY = Template::parse( self::$message, $data );
$subject = Template::parse( self::$subject, $data ); $subject = Template::parse( self::$subject, $data );
$body = Views::simpleView( 'email.template', $data ); $body = Views::simpleView( 'email.template', $data );

View File

@ -358,6 +358,10 @@ class Forms extends Check {
self::addUserError( 'Invalid Email.' ); self::addUserError( 'Invalid Email.' );
return false; return false;
} }
if ( $user->usernameExists( Input::post( 'username' ) ) ) {
self::addUserError( 'A user with that username is already registered.' );
return false;
}
if ( !$user->noEmailExists( Input::post( 'email' ) ) ) { if ( !$user->noEmailExists( Input::post( 'email' ) ) ) {
self::addUserError( 'A user with that email is already registered.' ); self::addUserError( 'A user with that email is already registered.' );
return false; return false;

View File

@ -76,25 +76,6 @@ class Images extends AdminController {
Views::view( 'admin.images.upload' ); Views::view( 'admin.images.upload' );
} }
private function getFolderObject( $folder, $subdirs = '' ) { private function getFolderObject( $folder, $subdirs = '' ) {
$names = explode( DIRECTORY_SEPARATOR, $folder ); $names = explode( DIRECTORY_SEPARATOR, $folder );
$folderName = array_pop( $names ); $folderName = array_pop( $names );
@ -155,28 +136,6 @@ class Images extends AdminController {
return $dirs; return $dirs;
} }
public function __construct() { public function __construct() {
parent::__construct(); parent::__construct();
self::$title = 'Admin - Images'; self::$title = 'Admin - Images';
@ -204,25 +163,6 @@ class Images extends AdminController {
Debug::error( 'There was an error with your upload.'); Debug::error( 'There was an error with your upload.');
Issues::add( 'error', [ 'There was an error with your upload.' => Check::userErrors() ] ); Issues::add( 'error', [ 'There was an error with your upload.' => Check::userErrors() ] );
} }
// if ( self::$token->create(
// Input::post( 'name' ),
// Input::post( 'notes' ),
// Input::post( 'token_type' )
// ) ) {
// Session::flash( 'success', 'Token Created' );
// Redirect::to( 'admin/images' );
// }
} }
Views::view( 'admin.images.create' ); Views::view( 'admin.images.create' );
} }
@ -261,7 +201,6 @@ class Images extends AdminController {
} }
public function rename() { public function rename() {
if ( ! Input::exists( 'fileLocation' ) ) { if ( ! Input::exists( 'fileLocation' ) ) {
Session::flash( 'warning', 'Unknown image.' ); Session::flash( 'warning', 'Unknown image.' );
Redirect::to( 'admin/images' ); Redirect::to( 'admin/images' );
@ -274,7 +213,6 @@ class Images extends AdminController {
Issues::add( 'error', [ 'There was an error renaming the image.' => Check::userErrors() ] ); Issues::add( 'error', [ 'There was an error renaming the image.' => Check::userErrors() ] );
} else { } else {
$result = $this->renameFile( Input::post( 'filelocation' ), Input::post( 'newname' ) ); $result = $this->renameFile( Input::post( 'filelocation' ), Input::post( 'newname' ) );
if ( ! empty( $result ) ) { if ( ! empty( $result ) ) {
Session::flash( 'success', 'Image has been renamed.' ); Session::flash( 'success', 'Image has been renamed.' );
Redirect::to( 'admin/images' ); Redirect::to( 'admin/images' );

View File

@ -25,6 +25,7 @@ use TheTempusProject\TheTempusProject as App;
use TheTempusProject\Classes\Controller; use TheTempusProject\Classes\Controller;
use TheTempusProject\Classes\Forms; use TheTempusProject\Classes\Forms;
use TheTempusProject\Bedrock\Classes\Config; use TheTempusProject\Bedrock\Classes\Config;
use TheTempusProject\Plugins\Turnstile;
class Register extends Controller { class Register extends Controller {
public function confirm( $code = null ) { public function confirm( $code = null ) {
@ -47,11 +48,19 @@ class Register extends Controller {
public function index() { public function index() {
self::$title = '{SITENAME} Sign Up'; 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.'; 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.';
if ( ! Config::getValue( 'main/registrationEnabled' ) ) { if ( ! Config::getValue( 'main/registrationEnabled' ) ) {
return Issues::add( 'notice', 'The site administrator has disable the ability to register a new account.' ); return Issues::add( 'notice', 'The site administrator has disable the ability to register a new account.' );
} }
$turnstile = '';
if ( class_exists( 'TheTempusProject\Plugins\Turnstile' ) ) {
$turnstile = new Turnstile;
if ( ! $turnstile->checkEnabled() ) {
Components::set( 'TURNSTILE_WIDGET', '' );
$turnstile = '';
}
} else {
Components::set( 'TURNSTILE_WIDGET', '' );
}
Components::set( 'TERMS', Views::simpleView( 'auth.terms' ) ); Components::set( 'TERMS', Views::simpleView( 'auth.terms' ) );
if ( App::$isLoggedIn ) { if ( App::$isLoggedIn ) {
return Issues::add( 'notice', 'You are currently logged in.' ); return Issues::add( 'notice', 'You are currently logged in.' );
@ -59,10 +68,20 @@ class Register extends Controller {
if ( ! Input::exists() ) { if ( ! Input::exists() ) {
return Views::view( 'auth.register' ); return Views::view( 'auth.register' );
} }
if ( Input::exists( 'userEmail' ) ) {
// for the really bad AI / headless bots
Session::flash( 'success', 'Thank you for registering! Please check your email to confirm your account.' );
Redirect::to( 'home/index' );
}
if ( ! Forms::check( 'register' ) ) { if ( ! Forms::check( 'register' ) ) {
Issues::add( 'error', [ 'There was an error with your registration.' => Check::userErrors() ] ); Issues::add( 'error', [ 'There was an error with your registration.' => Check::userErrors() ] );
return Views::view( 'auth.register' ); return Views::view( 'auth.register' );
} }
if ( ! empty( $turnstile ) ) {
if ( empty( $turnstile->verify() ) ) {
return Views::view( 'auth.register' );
}
}
self::$user->create( [ self::$user->create( [
'username' => Input::post( 'username' ), 'username' => Input::post( 'username' ),
'password' => Hash::make( Input::post( 'password' ) ), 'password' => Hash::make( Input::post( 'password' ) ),

View File

@ -9,6 +9,15 @@
* @license https://opensource.org/licenses/MIT [MIT LICENSE] * @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/ */
.context-popover {
background-color: #383838;
color: white;
}
.context-popover .popover-header {
background-color: #2c2c2c;
}
.context-main-border { .context-main-border {
border-color: #f5f5f5!important; border-color: #f5f5f5!important;
} }

View File

@ -8,6 +8,40 @@
* @link https://TheTempusProject.com * @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE] * @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/ */
.facebook {
border-color: #1877F2 !important; /* Facebook Blue */
color: #1877F2 !important;
}
.x-black {
border-color: #000000 !important; /* X (formerly Twitter) Black */
color: #000000 !important;
}
.reddit {
border-color: #FF4500 !important; /* Reddit Orange */
color: #FF4500 !important;
}
.opera {
border-color: #FF1B2D !important; /* Opera Red */
color: #FF1B2D !important;
}
.firefox {
border-color: #FF7139 !important; /* Firefox Orange */
color: #FF7139 !important;
}
.edge {
border-color: #0078D7 !important; /* Microsoft Edge Blue */
color: #0078D7 !important;
}
.safari {
border-color: #0B78E3 !important; /* Safari Blue */
color: #0B78E3 !important;
}
.context-main-border { .context-main-border {
border-color: #1e1e1e!important; border-color: #1e1e1e!important;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

After

Width:  |  Height:  |  Size: 117 KiB

View File

@ -8,6 +8,96 @@
* @link https://TheTempusProject.com * @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE] * @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/ */
/**
* Progressive Web-App
**/
let deferredPrompt;
const installPrompt = document.getElementById("install-prompt");
const chromeMessage = document.getElementById("chrome-install-message");
const iosMessage = document.getElementById("ios-install-message");
const installButton = document.getElementById("install-button");
const dismissButton = document.querySelector("#install-prompt .btn-close");
// Check if the user previously dismissed the prompt
if ( ! localStorage.getItem("pwaInstallDismissed") ) {
window.addEventListener("beforeinstallprompt", (event) => {
event.preventDefault();
deferredPrompt = event;
installPrompt.classList.remove("d-none");
installPrompt.classList.add("d-block"); // Show the alert
if ( chromeMessage ) {
chromeMessage.classList.remove("d-none");
chromeMessage.classList.add("d-block"); // Show the prompt
}
});
if ( isIos() && ! isInStandaloneMode() ) {
installPrompt.classList.remove("d-none");
installPrompt.classList.add("d-block"); // Show the alert
if ( iosMessage ) {
iosMessage.classList.remove("d-none");
iosMessage.classList.add("d-block"); // Show the prompt
}
}
}
// ios REQUIRES a service worker
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/app/js/sw.js')
.then(() => console.log('Service Worker Registered'));
}
// Handle Install Button Click
if ( installButton ) {
installButton.addEventListener("click", async () => {
if ( deferredPrompt ) {
deferredPrompt.prompt();
const { outcome } = await deferredPrompt.userChoice;
if (outcome === "dismissed") {
setInstallDismissed(); // Store that the user dismissed the prompt
}
deferredPrompt = null; // Reset prompt
installPrompt.classList.remove("d-block");
installPrompt.classList.add("d-none");
}
});
}
// Handle Close Button Click
if ( dismissButton ) {
dismissButton.addEventListener("click", () => {
setInstallDismissed(); // Store that the user dismissed the prompt
});
}
// Function to remember user choice for 7 days
function setInstallDismissed() {
localStorage.setItem("pwaInstallDismissed", Date.now() + 7 * 24 * 60 * 60 * 1000);
installPrompt.classList.remove("d-block"); // Hide the prompt
installPrompt.classList.add("d-none");
}
// Check if the 7-day period has passed
if (localStorage.getItem("pwaInstallDismissed")) {
const dismissUntil = parseInt(localStorage.getItem("pwaInstallDismissed"), 10);
if (Date.now() < dismissUntil) {
//
} else {
localStorage.removeItem("pwaInstallDismissed"); // Reset after 7 days
}
}
function isIos() {
return /iphone|ipad|ipod/i.test(navigator.userAgent);
}
function isInStandaloneMode() {
return window.matchMedia('(display-mode: standalone)').matches || window.navigator.standalone;
}
/** /**
* Automatically selects/de-selects all check boxes associated with that field * Automatically selects/de-selects all check boxes associated with that field
**/ **/
@ -211,10 +301,13 @@ document.querySelectorAll('[data-bs-toggle="collapse"]').forEach(button => {
}); });
// this should load all popovers // this should load all popovers
document.addEventListener("DOMContentLoaded", function () { document.addEventListener("DOMContentLoaded", function () {
var popoverTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]')); var popoverTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]'));
var popoverList = popoverTriggerList.map(function (popoverTriggerEl) { var popoverList = popoverTriggerList.map(function (popoverTriggerEl) {
return new bootstrap.Popover(popoverTriggerEl); return new bootstrap.Popover(popoverTriggerEl, {
customClass: 'context-popover',
});
}); });
}); });

1
app/js/sw.js Normal file
View File

@ -0,0 +1 @@
self.addEventListener('fetch', () => {});

View File

@ -59,7 +59,7 @@ class Sessions extends DatabaseModel {
public function checkSession( $sessionID ) { public function checkSession( $sessionID ) {
$user = new User; $user = new User;
// @todo lets put this on some sort of realistic checking regime other than check everything every time // @todo lets put this on some sort of realistic checking regime other than check everything every time
if ( $sessionID == false ) { if ( empty( $sessionID ) ) {
Debug::log( 'sessionID false' ); Debug::log( 'sessionID false' );
return false; return false;
} }

View File

@ -641,7 +641,7 @@ class User extends DatabaseModel {
Debug::error( 'User not created.' ); Debug::error( 'User not created.' );
return false; return false;
} }
return true; return self::$db->lastId();
} }
/** /**

View File

@ -21,6 +21,7 @@ use TheTempusProject\Bedrock\Functions\Input;
use TheTempusProject\Bedrock\Functions\Session; use TheTempusProject\Bedrock\Functions\Session;
use TheTempusProject\Hermes\Functions\Redirect; use TheTempusProject\Hermes\Functions\Redirect;
use TheTempusProject\Models\Contact as ContactModel; use TheTempusProject\Models\Contact as ContactModel;
use TheTempusProject\Plugins\Turnstile;
class Contact extends Controller { class Contact extends Controller {
protected static $contact; protected static $contact;
@ -29,6 +30,16 @@ class Contact extends Controller {
self::$contact = new ContactModel; self::$contact = new ContactModel;
self::$title = 'Contact - {SITENAME}'; self::$title = 'Contact - {SITENAME}';
self::$pageDescription = 'At {SITENAME}, we value our users\' input. You can provide any contact or suggestions using this form.'; self::$pageDescription = 'At {SITENAME}, we value our users\' input. You can provide any contact or suggestions using this form.';
$turnstile = '';
if ( class_exists( 'TheTempusProject\Plugins\Turnstile' ) ) {
$turnstile = new Turnstile;
if ( ! $turnstile->checkEnabled() ) {
Components::set( 'TURNSTILE_WIDGET', '' );
$turnstile = '';
}
} else {
Components::set( 'TURNSTILE_WIDGET', '' );
}
if ( ! Input::exists() ) { if ( ! Input::exists() ) {
return Views::view( 'contact.create' ); return Views::view( 'contact.create' );
} }
@ -36,6 +47,11 @@ class Contact extends Controller {
Issues::add( 'error', [ 'There was an error with your form, please check your submission and try again.' => Check::userErrors() ] ); Issues::add( 'error', [ 'There was an error with your form, please check your submission and try again.' => Check::userErrors() ] );
return Views::view( 'contact.create' ); return Views::view( 'contact.create' );
} }
if ( ! empty( $turnstile ) ) {
if ( empty( $turnstile->verify() ) ) {
return Views::view( 'contact.create' );
}
}
$result = self::$contact->create( Input::post( 'name' ), Input::post( 'contactEmail' ), Input::post( 'entry' ) ); $result = self::$contact->create( Input::post( 'name' ), Input::post( 'contactEmail' ), Input::post( 'entry' ) );
if ( $result ) { if ( $result ) {
Session::flash( 'success', 'Thank you! Your contact has been received.' ); Session::flash( 'success', 'Thank you! Your contact has been received.' );

View File

@ -40,6 +40,7 @@
<!-- Submit Button --> <!-- Submit Button -->
<div class="text-center"> <div class="text-center">
{TURNSTILE_WIDGET}
<button type="submit" name="submit" value="submit" class="btn btn-primary btn-lg">Submit</button> <button type="submit" name="submit" value="submit" class="btn btn-primary btn-lg">Submit</button>
</div> </div>
</form> </form>

View File

@ -35,8 +35,6 @@ class Notifications extends AdminController {
self::$notifications = new NotificationsModel; self::$notifications = new NotificationsModel;
self::$user = new User; self::$user = new User;
self::$group = new Group; self::$group = new Group;
$view = Navigation::activePageSelect( 'nav.admin', '/admin/Notifications' );
Components::set( 'ADMINNAV', $view );
} }
public function index( $data = null ) { public function index( $data = null ) {

View File

@ -121,21 +121,21 @@ class Notification extends DatabaseModel {
return true; return true;
} }
public function filter( $messageArray, $filters = [] ) { public function filter( $entities, $filters = [] ) {
$out = []; $out = [];
foreach ( $messageArray as $message ) { foreach ( $entities as $entity ) {
if ( !is_object( $message ) ) { if ( !is_object( $entity ) ) {
$message = $messageArray; $entity = $entities;
$end = true; $end = true;
} }
if ( $message->seenAt == 0 ) { if ( $entity->seenAt == 0 ) {
$message->unseenBadge = Views::simpleView( 'notifications.unseenBadge' ); $entity->unseenBadge = Views::simpleView( 'notifications.unseenBadge' );
$message->markReadLink = '<a href="{ROOT_URL}notifications/markRead/'.$message->ID.'" class="btn btn-sm btn-primary"><i class="fa-solid fa-fw fa-envelope-open"></i></a>'; $entity->markReadLink = '<a href="{ROOT_URL}notifications/markRead/'.$entity->ID.'" class="btn btn-sm btn-primary"><i class="fa-solid fa-fw fa-envelope-open"></i></a>';
} else { } else {
$message->unseenBadge = ''; $entity->unseenBadge = '';
$message->markReadLink = ''; $entity->markReadLink = '';
} }
$out[] = (object) $message; $out[] = (object) $entity;
if ( !empty( $end ) ) { if ( !empty( $end ) ) {
$out = $out[0]; $out = $out[0];
break; break;

View File

@ -0,0 +1,85 @@
<?php
/**
* app/plugins/turnstile/plugin.php
*
* This houses all of the main plugin info and functionality.
*
* @package TP Turnstile
* @version 5.0.1
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Plugins;
use TheTempusProject\TheTempusProject as App;
use TheTempusProject\Classes\Plugin;
use TheTempusProject\Models\Notification;
use TheTempusProject\Houdini\Classes\Components;
use TheTempusProject\Houdini\Classes\Views;
use TheTempusProject\Bedrock\Classes\Config;
use TheTempusProject\Bedrock\Functions\Input;
use TheTempusProject\Houdini\Classes\Issues;
class Turnstile extends Plugin {
private static $loaded = false;
public $pluginName = 'TP Turnstile';
public $pluginAuthor = 'JoeyK';
public $pluginWebsite = 'https://TheTempusProject.com';
public $modelVersion = '1.0';
public $pluginVersion = '3.0';
public $pluginDescription = 'A simple plugin which adds a site wide cloudflare turnstile integration.';
public $configName = 'turnstile';
public $configMatrix = [
'secretKey' => [
'type' => 'text',
'pretty' => 'Turnstile Secret Key',
'default' => 'xxxxxxxxxxxxx',
],
'apiKey' => [
'type' => 'text',
'pretty' => 'Turnstile API Key',
'default' => 'xxxxxxxxxxxxxx',
],
];
public function __construct( $load = false ) {
parent::__construct( $load );
if ( ! self::$loaded ) {
if ( $this->checkEnabled() ) {
Components::set( 'TURNSTILE_API_KEY', Config::getValue( 'turnstile/apiKey' ) );
Components::set( 'TURNSTILE_WIDGET', Views::simpleView( 'turnstile.widget') );
Components::append( 'TEMPLATE_JS_INCLUDES', '<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>' );
}
self::$loaded = true;
}
}
public function verify() {
if ( ! Input::exists('cf-turnstile-response') ) {
Issues::add( 'notice', 'Turnstile verification failed. Please try again.' );
return false;
}
$verify_url = "https://challenges.cloudflare.com/turnstile/v0/siteverify";
$data = [
"secret" => Config::getValue( 'turnstile/secretKey' ),
"response" => Input::post('cf-turnstile-response'),
"remoteip" => $_SERVER["REMOTE_ADDR"] // Optional, helps detect abuse
];
$options = [
"http" => [
"header" => "Content-Type: application/x-www-form-urlencoded",
"method" => "POST",
"content" => http_build_query($data)
]
];
$context = stream_context_create($options);
$response = file_get_contents($verify_url, false, $context);
$result = json_decode($response, true);
if ( ! $result["success"]) {
Issues::add( 'notice', 'Turnstile verification failed. Please try again. If the issue persists, please contact the site administrator.' );
return false;
}
return true;
}
}

View File

@ -0,0 +1 @@
<div class="cf-turnstile" data-sitekey="{TURNSTILE_API_KEY}"></div>

View File

@ -19,6 +19,15 @@ use TheTempusProject\Houdini\Classes\Components;
use TheTempusProject\Bedrock\Classes\Config; use TheTempusProject\Bedrock\Classes\Config;
use TheTempusProject\Bedrock\Functions\Input; use TheTempusProject\Bedrock\Functions\Input;
use TheTempusProject\TheTempusProject as App; use TheTempusProject\TheTempusProject as App;
use Endroid\QrCode\Builder\Builder;
use Endroid\QrCode\Encoding\Encoding;
use Endroid\QrCode\ErrorCorrectionLevel;
use Endroid\QrCode\Label\LabelAlignment;
use Endroid\QrCode\Label\Font\OpenSans;
use Endroid\QrCode\RoundBlockSizeMode;
use Endroid\QrCode\Writer\PngWriter;
use TheTempusProject\Hermes\Functions\Route as Routes;
use TheTempusProject\Canary\Bin\Canary as Debug;
class DefaultLoader extends Loader { class DefaultLoader extends Loader {
private static $loaded = false; private static $loaded = false;
@ -40,13 +49,63 @@ class DefaultLoader extends Loader {
Components::set( 'FONT_AWESOME_URL', self::FONT_AWESOME_URL ); Components::set( 'FONT_AWESOME_URL', self::FONT_AWESOME_URL );
} }
$this->addJs( '<script language="JavaScript" crossorigin="anonymous" type="text/javascript" src="{ROOT_URL}app/js/main.js"></script>' ); $this->addJs( '<script language="JavaScript" crossorigin="anonymous" type="text/javascript" src="{ROOT_URL}app/js/main.js"></script>' );
$this->addJs( '<script language="JavaScript" crossorigin="anonymous" type="text/javascript" src="{ROOT_URL}app/js/sw.js"></script>' );
Components::setIfNull( 'LOGO', Config::getValue( 'main/logo' ) ?? TP_DEFAULT_LOGO ); Components::setIfNull( 'LOGO', Config::getValue( 'main/logo' ) ?? TP_DEFAULT_LOGO );
if ( ! empty( Config::getValue( 'share/enabled' ) ) ) {
$currentUrl = Routes::getAddress() . Input::get( 'url' );
$folder = IMAGE_DIRECTORY . 'qr-codes' . DIRECTORY_SEPARATOR ;
$filename = md5( $currentUrl ) . '.png';
if ( ! file_exists( $folder ) ) {
Debug::Info( 'Creating Directory because it does not exist' );
mkdir( $folder, 0777, true );
}
if ( ! empty( Config::getValue( 'share/qr' ) ) ) {
if ( ! file_exists( $folder . $filename ) ) {
Debug::Info( 'Creating qr-image because it does not exist' );
$builder = new Builder(
writer: new PngWriter(),
writerOptions: [],
validateResult: false,
data: Routes::getAddress() . Input::get( 'url' ),
encoding: new Encoding('UTF-8'),
errorCorrectionLevel: ErrorCorrectionLevel::High,
size: 200,
margin: 10,
roundBlockSizeMode: RoundBlockSizeMode::Margin,
logoPath: APP_ROOT_DIRECTORY . DIRECTORY_SEPARATOR . Config::getValue( 'main/logo' ),
logoResizeToWidth: 30,
logoPunchoutBackground: true,
labelText: Config::getValue( 'main/name' ),
labelFont: new OpenSans(14),
labelAlignment: LabelAlignment::Center
);
$result = $builder->build();
$result->saveToFile( $folder . $filename );
}
Components::set( 'QR_CODE','<img src="{ROOT_URL}images/qr-codes/' . $filename . '" alt="QR Code" class="img-fluid mb-2">' );
} else {
Components::setIfNull( 'QR_CODE', '' );
}
Components::setIfNull( 'SHARE_IMAGE', Views::simpleView( 'footer.share' ) );
} else {
Components::setIfNull( 'SHARE_IMAGE', '' );
}
if ( ! empty( Config::getValue( 'main/pwa' ) ) ) {
Components::setIfNull( 'PWA', Views::simpleView( 'pwa') );
} else {
Components::setIfNull( 'PWA', '' );
}
Components::setIfNull( 'COPY', Views::simpleView( 'footer.copy') ); Components::setIfNull( 'COPY', Views::simpleView( 'footer.copy') );
Components::setIfNull( 'SOCIAL', Views::simpleView( 'footer.social') ); Components::setIfNull( 'SOCIAL', Views::simpleView( 'footer.social') );
Components::prepend( 'FOOTER_LEFT', Views::simpleView( 'footer.left', Navigation::getMenuLinks( App::CONTACT_FOOTER_MENU_NAME ) ) ); Components::prepend( 'FOOTER_LEFT', Views::simpleView( 'footer.left', Navigation::getMenuLinks( App::CONTACT_FOOTER_MENU_NAME ) ) );
Components::prepend( 'FOOTER_CENTER', Views::simpleView( 'footer.center', Navigation::getMenuLinks( App::INFO_FOOTER_MENU_NAME ) ) ); Components::prepend( 'FOOTER_CENTER', Views::simpleView( 'footer.center', Navigation::getMenuLinks( App::INFO_FOOTER_MENU_NAME ) ) );
Components::prepend( 'FOOTER_RIGHT', Views::simpleView( 'footer.right') ); Components::prepend( 'FOOTER_RIGHT', Views::simpleView( 'footer.right') );
Components::setIfNull( 'FOOT', Views::simpleView( 'footer.container') ); Components::setIfNull( 'FOOT', Views::simpleView( 'footer.container') );
/** /**
* Top-Nav * Top-Nav
*/ */

View File

@ -28,7 +28,12 @@
{AUTHOR} {AUTHOR}
{ROBOT} {ROBOT}
<link rel="icon" href="{ROOT_URL}images/favicon.ico" sizes="32x32"> <link rel="icon" href="{ROOT_URL}images/favicon.ico" sizes="32x32">
<!-- Apple PWA -->
<link rel="apple-touch-icon" href="{ROOT_URL}images/apple-touch-icon.png"><!-- 180×180 --> <link rel="apple-touch-icon" href="{ROOT_URL}images/apple-touch-icon.png"><!-- 180×180 -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title" content="{SITENAME}">
<!-- PWA -->
<link rel="manifest" href="{ROOT_URL}manifest.webmanifest"> <link rel="manifest" href="{ROOT_URL}manifest.webmanifest">
<!-- Required CSS --> <!-- Required CSS -->
<!-- <link rel="stylesheet" href="{FONT_AWESOME_URL}fontawesome.min.css" crossorigin="anonymous"> --> <!-- <link rel="stylesheet" href="{FONT_AWESOME_URL}fontawesome.min.css" crossorigin="anonymous"> -->
@ -91,6 +96,7 @@
</div> </div>
</div> </div>
{/ISSUES} {/ISSUES}
{PWA}
<!-- Main Page Content --> <!-- Main Page Content -->
{CONTENT} {CONTENT}
</div> </div>

View File

@ -19,7 +19,7 @@
<tbody> <tbody>
{LOOP} {LOOP}
<tr> <tr>
<td align="center">{ID}</td> <td class="text-center">{ID}</td>
<td><a href='{ROOT_URL}admin/users/view/{ID}' class="text-decoration-none">{usernamePretty}</a></td> <td><a href='{ROOT_URL}admin/users/view/{ID}' class="text-decoration-none">{usernamePretty}</a></td>
<td>{DTC date}{registered}{/DTC}</td> <td>{DTC date}{registered}{/DTC}</td>
<td><a href="{ROOT_URL}admin/users/edit/{ID}" class="btn btn-sm btn-warning"><i class="fa fa-fw fa-pencil"></i></a></td> <td><a href="{ROOT_URL}admin/users/edit/{ID}" class="btn btn-sm btn-warning"><i class="fa fa-fw fa-pencil"></i></a></td>
@ -31,7 +31,7 @@
{/LOOP} {/LOOP}
{ALT} {ALT}
<tr> <tr>
<td align="center" colspan="6"> <td class="text-center" colspan="6">
No results to show. No results to show.
</td> </td>
</tr> </tr>

View File

@ -15,6 +15,7 @@
<label for="email" class="col-lg-6 col-form-label text-lg-end">Email:</label> <label for="email" class="col-lg-6 col-form-label text-lg-end">Email:</label>
<div class="col-lg-2"> <div class="col-lg-2">
<input type="email" class="form-control" name="email" id="email" required> <input type="email" class="form-control" name="email" id="email" required>
<input type="email" class="d-none" name="userEmail" id="userEmail">
</div> </div>
</div> </div>
@ -42,6 +43,13 @@
</div> </div>
</div> </div>
<!-- Cloudflare Turnstile Widget -->
<div class="mb-3 row">
<div class="col-2 offset-5">
{TURNSTILE_WIDGET}
</div>
</div>
<!-- Terms of Service --> <!-- Terms of Service -->
<div class="mb-3 text-center"> <div class="mb-3 text-center">
<div class=""> <div class="">

View File

@ -1,4 +1,5 @@
<div class="col-12 col-sm-6 col-md-3 col-lg-2 mb-3 text-center"> <div class="col-12 col-sm-6 col-md-3 col-lg-2 mb-3 text-center">
{SHARE_IMAGE}
<h5>Dark Mode</h5> <h5>Dark Mode</h5>
<div class="material-switch px-4 mt-2"> <div class="material-switch px-4 mt-2">
<input name="dark-mode-toggle" type="checkbox" id="dark-mode-toggle" class="form-check-input"> <input name="dark-mode-toggle" type="checkbox" id="dark-mode-toggle" class="form-check-input">

View File

@ -0,0 +1,17 @@
<div class="text-center mb-3">
<h5 class="mb-3">Share</h5>
<div class="px-4 mt-2">
<!-- Share Button (visible only on medium+ screens) -->
<button type="button" class="btn btn-outline-primary"
data-bs-toggle="popover" data-bs-html="true" title="Share" data-bs-placement="top" data-bs-trigger="focus"
data-bs-content='
{QR_CODE}
<div class="d-flex justify-content-between">
<a href="https://www.reddit.com/submit?type=LINK&url={CURRENT_URL_SAFE}" target="_blank" class="mx-1 btn btn-lg reddit"><i class="fa-brands fa-fw fa-reddit"></i></a>
<a href="https://www.facebook.com/sharer/sharer.php?u={CURRENT_URL_SAFE}" target="_blank" class="mx-1 btn btn-lg facebook"><i class="fa-brands fa-fw fa-facebook"></i></a>
<a href="https://x.com/intent/tweet?url={CURRENT_URL_SAFE}" target="_blank" class="mx-1 btn btn-lg x-black"><i class="fa-brands fa-fw fa-x"></i></a>
</div>'>
Share
</button>
</div>
</div>

18
app/views/pwa.html Normal file
View File

@ -0,0 +1,18 @@
<div class="container pt-4 d-none" id="install-prompt">
<div class="row">
<div class="alert alert-success alert-dismissible w-100 d-none" role="alert" id="chrome-install-message">
<div class="d-flex justify-content-between align-items-center">
{SITENAME} is now available as a Progressive Web App, click the button to install now.
<button class="btn btn-md btn-outline-primary mx-2" id="install-button">Install App</button>
</div>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<div class="alert alert-success alert-dismissible w-100 d-none" role="alert" id="ios-install-message">
<div class="d-flex justify-content-between align-items-center">
{SITENAME} is now available as a Progressive-Web-App, tap <img src="/images/share-icon.png" width="20"> and then "Add to Home Screen".
</div>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
</div>
</div>

View File

@ -9,13 +9,13 @@
<p class="text-center text-lg-start"> <p class="text-center text-lg-start">
At this time, the best recommendation available is to contact us for more information. At this time, the best recommendation available is to contact us for more information.
The site here is actively maintained so feel free to utilize any of our available resources for contact. The site here is actively maintained so feel free to utilize any of our available resources for contact.
In addition to the site here, you can contact the lead developer (me) directly through <a href="https://joeykimsey.com">JoeyKimsey.com</a>. In addition to the site here, you can contact the lead developer (me) directly through <a href="https://joeykimsey.com" class="text-white text-decoration-none">JoeyKimsey.com</a>.
</p> </p>
<p class="text-muted text-center text-lg-start"> <p class="text-muted text-center text-lg-start">
Right now, this entire system was built and managed by myself. As stated, I have used my own version of this for years, but translating it to a publicly available product is not a 1-to-1 job. There may be bugs or issues encountered while you use the product. I can't guarantee a fix for every need in every case immediately, but I do actively keep track of bugs and work hard to ensure everyone has a great experience using the app. Right now, this entire system was built and managed by myself. As stated, I have used my own version of this for years, but translating it to a publicly available product is not a 1-to-1 job. There may be bugs or issues encountered while you use the product. I can't guarantee a fix for every need in every case immediately, but I do actively keep track of bugs and work hard to ensure everyone has a great experience using the app.
</p> </p>
<p class="text-center text-lg-start"> <p class="text-center text-lg-start">
If you encounter any bugs, feel free to report them <a href="/bugreport" class="text-decoration-none">here</a>. Likewise, there are forms for feedback, reviews, suggestions, and a general contact form. Thanks for taking the time to check out the product! If you encounter any bugs, feel free to report them <a href="/bugreport" class="text-white text-decoration-none">here</a>. Likewise, there are forms for feedback, reviews, suggestions, and a general contact form. Thanks for taking the time to check out the product!
</p> </p>
<div class="text-center mt-4 pb-4"> <div class="text-center mt-4 pb-4">
{loggedin} {loggedin}

View File

@ -317,7 +317,13 @@ class TheTempusProject extends Bedrock {
"pretty" => "Maximum Login session length. (in seconds)", "pretty" => "Maximum Login session length. (in seconds)",
"default" => 604800, // 60 * 60 * 24 * 7 "default" => 604800, // 60 * 60 * 24 * 7
"value" => 604800, // 60 * 60 * 24 * 7 "value" => 604800, // 60 * 60 * 24 * 7
] ],
"pwa" => [
"type" => "radio",
"pretty" => "Enable PWA banner for installs",
"default" => false,
"value" => false,
],
], ],
"maintenance" => [ "maintenance" => [
"enabled" => [ "enabled" => [
@ -333,6 +339,20 @@ class TheTempusProject extends Bedrock {
"value" => "Currently the site is undergoing maintenance. Only administrators will be able to sign in.", "value" => "Currently the site is undergoing maintenance. Only administrators will be able to sign in.",
] ]
], ],
"share" => [
"enabled" => [
"type" => "radio",
"pretty" => "Enables the share popover.",
"default" => false,
"value" => false,
],
"qr"=> [
"type" => "radio",
"pretty" => "Enables a custom qr-code in the share popover.",
"default" => false,
"value" => false,
]
],
"uploads" => [ "uploads" => [
"images" => [ "images" => [
"type" => "radio", "type" => "radio",

View File

@ -23,8 +23,9 @@
], ],
"require": "require":
{ {
"endroid/qr-code": "^6.0",
"fortawesome/font-awesome": "4.7", "fortawesome/font-awesome": "4.7",
"thetempusproject/bedrock": "1.1.5", "thetempusproject/bedrock": "1.1.6",
"thetempusproject/canary": "1.0.9", "thetempusproject/canary": "1.0.9",
"thetempusproject/houdini": "2.0.5", "thetempusproject/houdini": "2.0.5",
"twbs/bootstrap": "5.2.3" "twbs/bootstrap": "5.2.3"

379
composer.lock generated
View File

@ -4,37 +4,151 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "63640223834a7eeb9b4a211cd45cc6df", "content-hash": "10e7ce6b744b46b0c10780dbd7786ecb",
"packages": [ "packages": [
{ {
"name": "components/jquery", "name": "bacon/bacon-qr-code",
"version": "1.9.1", "version": "v3.0.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/components/jquery.git", "url": "https://github.com/Bacon/BaconQrCode.git",
"reference": "ae5c0c13cf163b3751ce55f9d9e97c1ba7ff796d" "reference": "f9cc1f52b5a463062251d666761178dbdb6b544f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/components/jquery/zipball/ae5c0c13cf163b3751ce55f9d9e97c1ba7ff796d", "url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/f9cc1f52b5a463062251d666761178dbdb6b544f",
"reference": "ae5c0c13cf163b3751ce55f9d9e97c1ba7ff796d", "reference": "f9cc1f52b5a463062251d666761178dbdb6b544f",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"robloach/component-installer": "*" "dasprid/enum": "^1.0.3",
"ext-iconv": "*",
"php": "^8.1"
}, },
"type": "component", "require-dev": {
"extra": { "phly/keep-a-changelog": "^2.12",
"component": { "phpunit/phpunit": "^10.5.11 || 11.0.4",
"files": [ "spatie/phpunit-snapshot-assertions": "^5.1.5",
"jquery.min.js", "squizlabs/php_codesniffer": "^3.9"
"jquery-migrate.js", },
"jquery-migrate.min.js", "suggest": {
"jquery.min.map" "ext-imagick": "to generate QR code images"
},
"type": "library",
"autoload": {
"psr-4": {
"BaconQrCode\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-2-Clause"
], ],
"scripts": [ "authors": [
"jquery.js" {
] "name": "Ben Scholzen 'DASPRiD'",
"email": "mail@dasprids.de",
"homepage": "https://dasprids.de/",
"role": "Developer"
}
],
"description": "BaconQrCode is a QR code generator for PHP.",
"homepage": "https://github.com/Bacon/BaconQrCode",
"support": {
"issues": "https://github.com/Bacon/BaconQrCode/issues",
"source": "https://github.com/Bacon/BaconQrCode/tree/v3.0.1"
},
"time": "2024-10-01T13:55:55+00:00"
},
{
"name": "dasprid/enum",
"version": "1.0.6",
"source": {
"type": "git",
"url": "https://github.com/DASPRiD/Enum.git",
"reference": "8dfd07c6d2cf31c8da90c53b83c026c7696dda90"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/DASPRiD/Enum/zipball/8dfd07c6d2cf31c8da90c53b83c026c7696dda90",
"reference": "8dfd07c6d2cf31c8da90c53b83c026c7696dda90",
"shasum": ""
},
"require": {
"php": ">=7.1 <9.0"
},
"require-dev": {
"phpunit/phpunit": "^7 || ^8 || ^9 || ^10 || ^11",
"squizlabs/php_codesniffer": "*"
},
"type": "library",
"autoload": {
"psr-4": {
"DASPRiD\\Enum\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-2-Clause"
],
"authors": [
{
"name": "Ben Scholzen 'DASPRiD'",
"email": "mail@dasprids.de",
"homepage": "https://dasprids.de/",
"role": "Developer"
}
],
"description": "PHP 7.1 enum implementation",
"keywords": [
"enum",
"map"
],
"support": {
"issues": "https://github.com/DASPRiD/Enum/issues",
"source": "https://github.com/DASPRiD/Enum/tree/1.0.6"
},
"time": "2024-08-09T14:30:48+00:00"
},
{
"name": "endroid/qr-code",
"version": "6.0.3",
"source": {
"type": "git",
"url": "https://github.com/endroid/qr-code.git",
"reference": "bdbb06e767efe9abe3c00461662b4059a6cd0b55"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/endroid/qr-code/zipball/bdbb06e767efe9abe3c00461662b4059a6cd0b55",
"reference": "bdbb06e767efe9abe3c00461662b4059a6cd0b55",
"shasum": ""
},
"require": {
"bacon/bacon-qr-code": "^3.0",
"php": "^8.2"
},
"require-dev": {
"endroid/quality": "dev-main",
"ext-gd": "*",
"khanamiryan/qrcode-detector-decoder": "^2.0.2",
"setasign/fpdf": "^1.8.2"
},
"suggest": {
"ext-gd": "Enables you to write PNG images",
"khanamiryan/qrcode-detector-decoder": "Enables you to use the image validator",
"roave/security-advisories": "Makes sure package versions with known security issues are not installed",
"setasign/fpdf": "Enables you to use the PDF writer"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "6.x-dev"
}
},
"autoload": {
"psr-4": {
"Endroid\\QrCode\\": "src/"
} }
}, },
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
@ -43,20 +157,30 @@
], ],
"authors": [ "authors": [
{ {
"name": "John Resig", "name": "Jeroen van den Enden",
"email": "jeresig@gmail.com" "email": "info@endroid.nl"
} }
], ],
"description": "jQuery JavaScript Library", "description": "Endroid QR Code",
"homepage": "http://jquery.com", "homepage": "https://github.com/endroid/qr-code",
"keywords": [
"code",
"endroid",
"php",
"qr",
"qrcode"
],
"support": { "support": {
"forum": "http://forum.jquery.com", "issues": "https://github.com/endroid/qr-code/issues",
"irc": "irc://irc.freenode.org/jquery", "source": "https://github.com/endroid/qr-code/tree/6.0.3"
"issues": "http://bugs.jquery.com",
"source": "https://github.com/jquery/jquery",
"wiki": "http://docs.jquery.com/"
}, },
"time": "2014-10-11T11:52:45+00:00" "funding": [
{
"url": "https://github.com/endroid",
"type": "github"
}
],
"time": "2024-10-29T19:28:52+00:00"
}, },
{ {
"name": "fortawesome/font-awesome", "name": "fortawesome/font-awesome",
@ -110,204 +234,13 @@
}, },
"time": "2016-10-24T15:52:54+00:00" "time": "2016-10-24T15:52:54+00:00"
}, },
{
"name": "kriswallsmith/assetic",
"version": "v1.4.0",
"source": {
"type": "git",
"url": "https://github.com/kriswallsmith/assetic.git",
"reference": "e911c437dbdf006a8f62c2f59b15b2d69a5e0aa1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/kriswallsmith/assetic/zipball/e911c437dbdf006a8f62c2f59b15b2d69a5e0aa1",
"reference": "e911c437dbdf006a8f62c2f59b15b2d69a5e0aa1",
"shasum": ""
},
"require": {
"php": ">=5.3.1",
"symfony/process": "~2.1|~3.0"
},
"conflict": {
"twig/twig": "<1.27"
},
"require-dev": {
"leafo/lessphp": "^0.3.7",
"leafo/scssphp": "~0.1",
"meenie/javascript-packer": "^1.1",
"mrclay/minify": "<2.3",
"natxet/cssmin": "3.0.4",
"patchwork/jsqueeze": "~1.0|~2.0",
"phpunit/phpunit": "~4.8 || ^5.6",
"psr/log": "~1.0",
"ptachoire/cssembed": "~1.0",
"symfony/phpunit-bridge": "~2.7|~3.0",
"twig/twig": "~1.23|~2.0",
"yfix/packager": "dev-master"
},
"suggest": {
"leafo/lessphp": "Assetic provides the integration with the lessphp LESS compiler",
"leafo/scssphp": "Assetic provides the integration with the scssphp SCSS compiler",
"leafo/scssphp-compass": "Assetic provides the integration with the SCSS compass plugin",
"patchwork/jsqueeze": "Assetic provides the integration with the JSqueeze JavaScript compressor",
"ptachoire/cssembed": "Assetic provides the integration with phpcssembed to embed data uris",
"twig/twig": "Assetic provides the integration with the Twig templating engine"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.4-dev"
}
},
"autoload": {
"files": [
"src/functions.php"
],
"psr-0": {
"Assetic": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Kris Wallsmith",
"email": "kris.wallsmith@gmail.com",
"homepage": "http://kriswallsmith.net/"
}
],
"description": "Asset Management for PHP",
"homepage": "https://github.com/kriswallsmith/assetic",
"keywords": [
"assets",
"compression",
"minification"
],
"support": {
"issues": "https://github.com/kriswallsmith/assetic/issues",
"source": "https://github.com/kriswallsmith/assetic/tree/master"
},
"time": "2016-11-11T18:43:20+00:00"
},
{
"name": "robloach/component-installer",
"version": "0.0.12",
"source": {
"type": "git",
"url": "https://github.com/RobLoach/component-installer.git",
"reference": "1864f25db21fc173e02a359f646acd596c1b0460"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/RobLoach/component-installer/zipball/1864f25db21fc173e02a359f646acd596c1b0460",
"reference": "1864f25db21fc173e02a359f646acd596c1b0460",
"shasum": ""
},
"require": {
"kriswallsmith/assetic": "1.*",
"php": ">=5.3.2"
},
"require-dev": {
"composer/composer": "1.*"
},
"type": "composer-installer",
"extra": {
"class": "ComponentInstaller\\Installer"
},
"autoload": {
"psr-0": {
"ComponentInstaller": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Rob Loach",
"email": "robloach@gmail.com",
"homepage": "http://robloach.net"
}
],
"description": "Allows installation of Components via Composer.",
"support": {
"issues": "https://github.com/RobLoach/component-installer/issues",
"source": "https://github.com/RobLoach/component-installer/tree/master"
},
"abandoned": "oomphinc/composer-installers-extender",
"time": "2013-08-31T23:46:48+00:00"
},
{
"name": "symfony/process",
"version": "v3.4.47",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
"reference": "b8648cf1d5af12a44a51d07ef9bf980921f15fca"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/b8648cf1d5af12a44a51d07ef9bf980921f15fca",
"reference": "b8648cf1d5af12a44a51d07ef9bf980921f15fca",
"shasum": ""
},
"require": {
"php": "^5.5.9|>=7.0.8"
},
"type": "library",
"autoload": {
"psr-4": {
"Symfony\\Component\\Process\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/process/tree/v3.4.47"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-10-24T10:57:07+00:00"
},
{ {
"name": "thetempusproject/bedrock", "name": "thetempusproject/bedrock",
"version": "1.1.5", "version": "1.1.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://git.thetempusproject.com/the-tempus-project/bedrock", "url": "https://git.thetempusproject.com/the-tempus-project/bedrock",
"reference": "39d350df061b4c69266bbbe152976cf7254e4c08" "reference": "cfa53c9e7058f78559ee8615431645c7eef972f8"
}, },
"require": { "require": {
"php": ">=8.1.0", "php": ">=8.1.0",
@ -346,7 +279,7 @@
"php", "php",
"thetempusproject" "thetempusproject"
], ],
"time": "2025-02-04T12:20:56+00:00" "time": "2025-02-06T03:02:46+00:00"
}, },
{ {
"name": "thetempusproject/canary", "name": "thetempusproject/canary",

BIN
images/apple-touch-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
images/icon-maskWhite.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
images/share-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -194,12 +194,12 @@ class Install extends Controller {
*/ */
public function configure() { public function configure() {
if ( Forms::Check( 'installConfigure' ) ) { if ( Forms::Check( 'installConfigure' ) ) {
$logo = $baseConfig['main']['template']['default']; TheTempusProject::$activeConfig->load( BEDROCK_CONFIG_JSON );
$baseConfig = TheTempusProject::$configMatrix;
$logo = $baseConfig['main']['logo']['default'];
if ( Input::exists( 'logo' ) && Upload::image( 'logo', 'System' ) ) { if ( Input::exists( 'logo' ) && Upload::image( 'logo', 'System' ) ) {
$logo = 'Uploads/Images/System/' . Upload::last(); $logo = 'Uploads/Images/System/' . Upload::last();
} }
TheTempusProject::$activeConfig->load( BEDROCK_CONFIG_JSON );
$baseConfig = TheTempusProject::$configMatrix;
$baseConfig['main']['logo']['value'] = $logo; $baseConfig['main']['logo']['value'] = $logo;
$baseConfig['main']['name']['value'] = Input::postNull( 'siteName' ); $baseConfig['main']['name']['value'] = Input::postNull( 'siteName' );
$baseConfig['database']['dbEnabled']['value'] = $baseConfig['database']['dbEnabled']['default']; $baseConfig['database']['dbEnabled']['value'] = $baseConfig['database']['dbEnabled']['default'];