Merge branch 'main' into thetempusproject-com
This commit is contained in:
@ -73,7 +73,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 Image</h4>';
|
$html .= '<h4 class="col-lg-3 col-form-label text-end">Current Image</h4>';
|
||||||
$html .= '<div class="col-lg-6">';
|
$html .= '<div class="col-lg-6">';
|
||||||
$html .= '<img alt="User Avatar" src="{ROOT_URL}' . $node['value'] . '" class="img-circle img-fluid p-2 avatar-125">';
|
$html .= '<img alt="configured image" src="{ROOT_URL}' . $node['value'] . '" class="img-circle img-fluid p-2 avatar-125">';
|
||||||
$html .= '</div>';
|
$html .= '</div>';
|
||||||
}
|
}
|
||||||
$html .= '</div>';
|
$html .= '</div>';
|
||||||
|
@ -121,7 +121,6 @@ class DatabaseModel extends BedrockDatabaseModel {
|
|||||||
$errors = [];
|
$errors = [];
|
||||||
foreach ( self::$installFlags as $flag_name ) {
|
foreach ( self::$installFlags as $flag_name ) {
|
||||||
if ( empty( $options[$flag_name] ) ) {
|
if ( empty( $options[$flag_name] ) ) {
|
||||||
$module_data[ $flag_name ] = INSTALL_STATUS_SKIPPED;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,6 +115,8 @@ class Forms extends Check {
|
|||||||
self::addHandler( 'adminCreateToken', __CLASS__, 'adminCreateToken' );
|
self::addHandler( 'adminCreateToken', __CLASS__, 'adminCreateToken' );
|
||||||
self::addHandler( 'apiLogin', __CLASS__, 'apiLogin' );
|
self::addHandler( 'apiLogin', __CLASS__, 'apiLogin' );
|
||||||
self::addHandler( 'updatePreference', __CLASS__, 'updatePreference' );
|
self::addHandler( 'updatePreference', __CLASS__, 'updatePreference' );
|
||||||
|
self::addHandler( 'renameIImage', __CLASS__, 'renameIImage' );
|
||||||
|
self::addHandler( 'addImage', __CLASS__, 'addImage' );
|
||||||
self::addHandler( 'installStart', __CLASS__, 'install', [ 'start' ] );
|
self::addHandler( 'installStart', __CLASS__, 'install', [ 'start' ] );
|
||||||
self::addHandler( 'installAgreement', __CLASS__, 'install', [ 'agreement' ] );
|
self::addHandler( 'installAgreement', __CLASS__, 'install', [ 'agreement' ] );
|
||||||
self::addHandler( 'installCheck', __CLASS__, 'install', [ 'check' ] );
|
self::addHandler( 'installCheck', __CLASS__, 'install', [ 'check' ] );
|
||||||
@ -663,4 +665,28 @@ class Forms extends Check {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function renameIImage() {
|
||||||
|
if ( !Input::exists( 'filelocation' ) ) {
|
||||||
|
self::addUserError( 'You must specify a location' );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( !Input::exists( 'newname' ) ) {
|
||||||
|
self::addUserError( 'You must specify a new name' );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function addImage() {
|
||||||
|
if ( !Input::exists( 'folderSelect' ) ) {
|
||||||
|
self::addUserError( 'You must specify a location' );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( !Input::exists( 'uploadImage' ) ) {
|
||||||
|
self::addUserError( 'You must include a file.' );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -158,6 +158,10 @@ class Installer {
|
|||||||
} else {
|
} else {
|
||||||
self::$installJson['modules'][$name]['enabled_txt'] = '<span class="text-danger">No</span>';
|
self::$installJson['modules'][$name]['enabled_txt'] = '<span class="text-danger">No</span>';
|
||||||
}
|
}
|
||||||
|
// in this case only, we save an array to remove the objects later, so an array stored is a success.
|
||||||
|
if ( ! empty( self::$installJson['modules'][$name]['resources_installed'] ) && is_array( self::$installJson['modules'][$name]['resources_installed'] ) ) {
|
||||||
|
self::$installJson['modules'][$name]['resources_installed'] = INSTALL_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return self::$installJson['modules'][$name];
|
return self::$installJson['modules'][$name];
|
||||||
}
|
}
|
||||||
@ -422,7 +426,7 @@ class Installer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// exclude any flags that have already been successfully installed
|
// exclude any flags that have already been successfully installed
|
||||||
if ( !empty( $module_data->$flag_type ) && $module_data->$flag_type == INSTALL_STATUS_SUCCESS ) {
|
if ( ! empty( $module_data->$flag_type ) && $module_data->$flag_type == INSTALL_STATUS_SUCCESS ) {
|
||||||
Debug::warn( "$flag_type has already been successfully installed" );
|
Debug::warn( "$flag_type has already been successfully installed" );
|
||||||
$flags[ $flag_type ] = false;
|
$flags[ $flag_type ] = false;
|
||||||
}
|
}
|
||||||
@ -530,7 +534,7 @@ class Installer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach ( $flags as $flag_type ) {
|
foreach ( $flags as $flag_type ) {
|
||||||
if ( ! in_array( $modelInfo[ $flag_type ], [ INSTALL_STATUS_SUCCESS, INSTALL_STATUS_NOT_REQUIRED ] ) ) {
|
if ( empty( $modelInfo[ $flag_type ] ) || ! in_array( $modelInfo[ $flag_type ], [ INSTALL_STATUS_SUCCESS, INSTALL_STATUS_NOT_REQUIRED ] ) ) {
|
||||||
$modelInfo['installStatus'] = INSTALL_STATUS_PARTIALLY_INSTALLED;
|
$modelInfo['installStatus'] = INSTALL_STATUS_PARTIALLY_INSTALLED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -245,7 +245,7 @@ class Permissions {
|
|||||||
|
|
||||||
public static function getFieldEditHtml( $name, $default, $pretty ) {
|
public static function getFieldEditHtml( $name, $default, $pretty ) {
|
||||||
$fieldname = str_ireplace( '/', '-', $name );
|
$fieldname = str_ireplace( '/', '-', $name );
|
||||||
$fieldHtml = Forms::getSwitchHtml( $fieldname, [ 'true', 'false' ], $default );
|
$fieldHtml = Forms::getSwitchHtml( $fieldname, $default );
|
||||||
$html = '';
|
$html = '';
|
||||||
$html .= '<div class="mb-3 row">';
|
$html .= '<div class="mb-3 row">';
|
||||||
$html .= '<label for="' . $fieldname . '" class="col-lg-6 col-form-label text-end">' . $pretty . '</label>';
|
$html .= '<label for="' . $fieldname . '" class="col-lg-6 col-form-label text-end">' . $pretty . '</label>';
|
||||||
|
@ -89,7 +89,7 @@ class Plugin {
|
|||||||
|
|
||||||
foreach ( self::PLUGIN_FLAG_MAP as $flag_name => $function_name ) {
|
foreach ( self::PLUGIN_FLAG_MAP as $flag_name => $function_name ) {
|
||||||
if ( empty( $options[$flag_name] ) ) {
|
if ( empty( $options[$flag_name] ) ) {
|
||||||
$module_data[ $flag_name ] = INSTALL_STATUS_SKIPPED;
|
// $module_data[ $flag_name ] = INSTALL_STATUS_SKIPPED;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,7 +280,7 @@ class Plugin {
|
|||||||
public function installResources( $options = '' ) {
|
public function installResources( $options = '' ) {
|
||||||
if ( empty( $this->resourceMatrix ) ) {
|
if ( empty( $this->resourceMatrix ) ) {
|
||||||
Debug::log( 'resourceMatrix is empty' );
|
Debug::log( 'resourceMatrix is empty' );
|
||||||
return true;
|
return INSTALL_STATUS_NOT_REQUIRED;
|
||||||
}
|
}
|
||||||
$ids = [];
|
$ids = [];
|
||||||
foreach( $this->resourceMatrix as $tableName => $entries ) {
|
foreach( $this->resourceMatrix as $tableName => $entries ) {
|
||||||
|
@ -276,7 +276,7 @@ class Preferences {
|
|||||||
$html .= '<div class="mb-3 row">';
|
$html .= '<div class="mb-3 row">';
|
||||||
$html .= '<h4 class="col-lg-6 col-form-label text-start text-lg-end">Current Image</h4>';
|
$html .= '<h4 class="col-lg-6 col-form-label text-start text-lg-end">Current Image</h4>';
|
||||||
$html .= '<div class="col-lg-6">';
|
$html .= '<div class="col-lg-6">';
|
||||||
$html .= '<img alt="User Avatar" src="{ROOT_URL}' . $defaultValue . '" class="img-circle img-fluid p-2 avatar-125">';
|
$html .= '<img alt="preferred image" src="{ROOT_URL}' . $defaultValue . '" class="img-circle img-fluid p-2">';
|
||||||
$html .= '</div>';
|
$html .= '</div>';
|
||||||
}
|
}
|
||||||
$html .= '</div>';
|
$html .= '</div>';
|
||||||
|
@ -39,7 +39,7 @@ if ( ! defined( 'CONFIG_DIRECTORY' ) ) {
|
|||||||
define( 'CANARY_SECURE_HASH', 'd73ed7591a30f0ca7d686a0e780f0d05' );
|
define( 'CANARY_SECURE_HASH', 'd73ed7591a30f0ca7d686a0e780f0d05' );
|
||||||
# Tempus Project Core
|
# Tempus Project Core
|
||||||
define( 'APP_NAME', 'The Tempus Project');
|
define( 'APP_NAME', 'The Tempus Project');
|
||||||
define( 'TP_DEFAULT_LOGO', 'images/logo.png');
|
define( 'TP_DEFAULT_LOGO', 'images/logoWhite.png');
|
||||||
// Check
|
// Check
|
||||||
define( 'MINIMUM_PHP_VERSION', 8.1);
|
define( 'MINIMUM_PHP_VERSION', 8.1);
|
||||||
// Cookies
|
// Cookies
|
||||||
|
@ -23,8 +23,154 @@ use TheTempusProject\Bedrock\Functions\Input;
|
|||||||
use TheTempusProject\Bedrock\Functions\Check;
|
use TheTempusProject\Bedrock\Functions\Check;
|
||||||
use TheTempusProject\Hermes\Functions\Redirect;
|
use TheTempusProject\Hermes\Functions\Redirect;
|
||||||
use TheTempusProject\Bedrock\Functions\Session;
|
use TheTempusProject\Bedrock\Functions\Session;
|
||||||
|
use TheTempusProject\Hermes\Functions\Route as Routes;
|
||||||
|
use TheTempusProject\Bedrock\Functions\Upload;
|
||||||
|
use RecursiveIteratorIterator;
|
||||||
|
use RecursiveDirectoryIterator;
|
||||||
|
use FilesystemIterator;
|
||||||
|
|
||||||
class Images extends AdminController {
|
class Images extends AdminController {
|
||||||
|
private $directories = [
|
||||||
|
APP_ROOT_DIRECTORY . 'images',
|
||||||
|
APP_ROOT_DIRECTORY . 'app/images',
|
||||||
|
APP_ROOT_DIRECTORY . 'app/plugins'
|
||||||
|
];
|
||||||
|
|
||||||
|
private $excludedDirectories = [
|
||||||
|
'.',
|
||||||
|
'..',
|
||||||
|
'vendor',
|
||||||
|
'docker',
|
||||||
|
'logs',
|
||||||
|
'gitlab',
|
||||||
|
'uploads',
|
||||||
|
'config',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function upload() {
|
||||||
|
if ( Input::exists( 'submit' ) ) {
|
||||||
|
$route = '';
|
||||||
|
$destination = '';
|
||||||
|
if ( !TTPForms::check( 'addImage' ) ) {
|
||||||
|
Issues::add( 'error', [ 'There was an error with your image upload.' => Check::userErrors() ] );
|
||||||
|
} else {
|
||||||
|
$folder = Input::post( 'folderSelect' ) . DIRECTORY_SEPARATOR;
|
||||||
|
// dv( $folder );
|
||||||
|
$upload = Upload::image( 'uploadImage', $folder );
|
||||||
|
if ( $upload ) {
|
||||||
|
$route = str_replace( APP_ROOT_DIRECTORY, '', $folder );
|
||||||
|
$destination = $route . Upload::last();
|
||||||
|
Issues::add( 'success', 'Image uploaded.' );
|
||||||
|
} else {
|
||||||
|
Issues::add( 'error', [ 'There was an error with your image upload.' => Check::userErrors() ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$folders = $this->getDirectoriesRecursive( APP_ROOT_DIRECTORY );
|
||||||
|
$folderHtml = $this->generateFolderHtml( $folders );
|
||||||
|
Components::set( 'FOLDER_SELECT_ROOT', APP_ROOT_DIRECTORY );
|
||||||
|
Components::set( 'FOLDER_SELECT', Views::simpleView( 'forms.folderSelect', $folderHtml ) );
|
||||||
|
Views::view( 'admin.images.upload' );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private function getFolderObject( $folder, $subdirs = '' ) {
|
||||||
|
$names = explode( DIRECTORY_SEPARATOR, $folder );
|
||||||
|
$folderName = array_pop( $names );
|
||||||
|
$out = [
|
||||||
|
'folderName' => $folderName,
|
||||||
|
'location' => $folder,
|
||||||
|
'subdirs' => $subdirs,
|
||||||
|
];
|
||||||
|
if ( ! empty( $subdirs ) ) {
|
||||||
|
$out['folderexpand'] = '<i class="fa-solid fa-caret-down justify-content-end"></i>';
|
||||||
|
} else {
|
||||||
|
$out['folderexpand'] = '';
|
||||||
|
}
|
||||||
|
return (object) $out;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function generateFolderHtml( $folders ) {
|
||||||
|
$rows = [];
|
||||||
|
foreach ( $folders as $top => $sub ) {
|
||||||
|
$object = $this->getFolderObject( $top );
|
||||||
|
if ( $top == $sub ) {
|
||||||
|
$html = '';
|
||||||
|
} else {
|
||||||
|
$children = $this->generateFolderHtml( $sub );
|
||||||
|
Components::set( 'parentfolderName', $object->folderName );
|
||||||
|
$html = Views::simpleView( 'forms.folderSelectParent', $children );
|
||||||
|
Components::set( 'parentfolderName', '' );
|
||||||
|
}
|
||||||
|
$rows[] = $this->getFolderObject( $top, $html );
|
||||||
|
}
|
||||||
|
return $rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getDirectoriesRecursive( $directory ) {
|
||||||
|
$dirs = [];
|
||||||
|
|
||||||
|
$directory = rtrim( $directory, DIRECTORY_SEPARATOR );
|
||||||
|
$directory = $directory. DIRECTORY_SEPARATOR;
|
||||||
|
|
||||||
|
$files = scandir( $directory );
|
||||||
|
$filteredFiles = array_values( array_diff( $files, $this->excludedDirectories ) );
|
||||||
|
|
||||||
|
foreach ( $filteredFiles as $key => $filename ) {
|
||||||
|
$long_name = $directory . $filename;
|
||||||
|
$is_dir = ( ( strpos( $filename, '.' ) === false ) && ( is_dir( $long_name ) === true ) );
|
||||||
|
if ( $is_dir ) {
|
||||||
|
$recursive_dirs = $this->getDirectoriesRecursive( $long_name );
|
||||||
|
if ( empty( $recursive_dirs ) ) {
|
||||||
|
$recursive_dirs = $long_name;
|
||||||
|
}
|
||||||
|
$dirs[$long_name] = $recursive_dirs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $dirs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
@ -76,39 +222,147 @@ class Images extends AdminController {
|
|||||||
Views::view( 'admin.images.create' );
|
Views::view( 'admin.images.create' );
|
||||||
}
|
}
|
||||||
|
|
||||||
public function delete( $id = null ) {
|
public function delete() {
|
||||||
if ( self::$token->delete( [ $id ] ) ) {
|
if ( self::$token->delete( [ $id ] ) ) {
|
||||||
Session::flash( 'success', 'Token deleted.' );
|
Session::flash( 'success', 'Token deleted.' );
|
||||||
}
|
}
|
||||||
Redirect::to( 'admin/images' );
|
Redirect::to( 'admin/images' );
|
||||||
}
|
}
|
||||||
|
|
||||||
public function edit( $id = null ) {
|
public function rename() {
|
||||||
$token = self::$token->findById( $id );
|
|
||||||
if ( Input::exists( 'submit' ) ) {
|
if ( ! Input::exists( 'fileLocation' ) ) {
|
||||||
if ( !TTPForms::check( 'adminEditToken' ) ) {
|
Session::flash( 'warning', 'Unknown image.' );
|
||||||
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/images' );
|
Redirect::to( 'admin/images' );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Components::set( 'filelocation', Input::get( 'fileLocation' ) );
|
||||||
|
|
||||||
|
if ( Input::exists( 'submit' ) ) {
|
||||||
|
if ( !TTPForms::check( 'renameIImage' ) ) {
|
||||||
|
Issues::add( 'error', [ 'There was an error renaming the image.' => Check::userErrors() ] );
|
||||||
|
} else {
|
||||||
|
$result = $this->renameFile( Input::post( 'filelocation' ), Input::post( 'newname' ) );
|
||||||
|
|
||||||
|
if ( ! empty( $result ) ) {
|
||||||
|
Session::flash( 'success', 'Image has been renamed.' );
|
||||||
|
Redirect::to( 'admin/images' );
|
||||||
|
} else {
|
||||||
|
Issues::add( 'error', [ 'There was an error with the install.' => $this->installer->getErrors() ] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Forms::selectOption( $token->token_type );
|
}
|
||||||
return Views::view( 'admin.images.edit', $token );
|
|
||||||
|
return Views::view( 'admin.images.rename' );
|
||||||
}
|
}
|
||||||
|
|
||||||
public function index() {
|
public function index() {
|
||||||
return Views::view( 'admin.images.list', self::$token->listPaginated() );
|
return Views::view( 'admin.images.list.combined', $this->getAllImageDetails() );
|
||||||
}
|
}
|
||||||
|
|
||||||
public function view( $id = null ) {
|
public function view() {
|
||||||
return Views::view( 'admin.images.view', self::$token->findById( $id ) );
|
if ( Input::exists( 'fileLocation' ) ) {
|
||||||
|
return Views::view( 'admin.images.view', $this->getImageByLocation( Input::get( 'fileLocation' ) ) );
|
||||||
|
}
|
||||||
|
return $this->index();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getAllImages() {
|
||||||
|
$files = [];
|
||||||
|
foreach ($this->directories as $dir) {
|
||||||
|
if ($dir === 'app/plugins') {
|
||||||
|
$pluginDirs = glob($dir . '/*', GLOB_ONLYDIR);
|
||||||
|
foreach ($pluginDirs as $pluginDir) {
|
||||||
|
$imageDir = $pluginDir . '/images';
|
||||||
|
if (is_dir($imageDir)) {
|
||||||
|
$files = array_merge($files, $this->scanDirectoryRecursively($imageDir));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$files = array_merge($files, $this->scanDirectory($dir));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $files;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function scanDirectory($path) {
|
||||||
|
return glob($path . '/*.{jpg,jpeg,png,gif,webp}', GLOB_BRACE) ?: [];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function scanDirectoryRecursively($path) {
|
||||||
|
$files = [];
|
||||||
|
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS));
|
||||||
|
|
||||||
|
foreach ($iterator as $file) {
|
||||||
|
if (preg_match('/\.(jpg|jpeg|png|gif|webp)$/i', $file->getFilename())) {
|
||||||
|
$files[] = $file->getPathname();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $files;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getAllImageDetails() {
|
||||||
|
$images = [];
|
||||||
|
$files = $this->getAllImages();
|
||||||
|
foreach ( $files as $file ) {
|
||||||
|
$images[] = $this->getImageByLocation( $file );
|
||||||
|
}
|
||||||
|
return $images;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getImageByLocation( $location ) {
|
||||||
|
$realPath = realpath( $location );
|
||||||
|
|
||||||
|
return (object) [
|
||||||
|
'filename' => basename( $location ),
|
||||||
|
'extension' => pathinfo( $location , PATHINFO_EXTENSION),
|
||||||
|
'fileSize' => $this->formatFileSize(filesize( $location )),
|
||||||
|
'location' => $realPath,
|
||||||
|
'locationSafe' => urlencode( $realPath ),
|
||||||
|
'url' => Routes::getAddress() . str_replace( APP_ROOT_DIRECTORY, '', $realPath ),
|
||||||
|
'folder' => dirname( $location )
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function formatFileSize($size) {
|
||||||
|
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
|
||||||
|
$i = 0;
|
||||||
|
while ($size >= 1024 && $i < count($units) - 1) {
|
||||||
|
$size /= 1024;
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
return round($size, 2) . ' ' . $units[$i];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function renameFile( $currentLocation, $newFilename ) {
|
||||||
|
// Ensure the file exists
|
||||||
|
if (!file_exists($currentLocation)) {
|
||||||
|
throw new \Exception("File does not exist: $currentLocation");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract directory and current extension
|
||||||
|
$directory = dirname($currentLocation);
|
||||||
|
$currentExtension = pathinfo($currentLocation, PATHINFO_EXTENSION);
|
||||||
|
$newExtension = pathinfo($newFilename, PATHINFO_EXTENSION);
|
||||||
|
|
||||||
|
// Ensure the file extension has not changed
|
||||||
|
if (strcasecmp($currentExtension, $newExtension) !== 0) {
|
||||||
|
throw new \Exception("File extension cannot be changed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct the new file path
|
||||||
|
$newLocation = $directory . DIRECTORY_SEPARATOR . $newFilename;
|
||||||
|
|
||||||
|
// Ensure the new file name does not already exist
|
||||||
|
if (file_exists($newLocation)) {
|
||||||
|
throw new \Exception("A file with the new name already exists: $newFilename");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt to rename the file
|
||||||
|
if (!rename($currentLocation, $newLocation)) {
|
||||||
|
throw new \Exception("Failed to rename file.");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,14 @@ class Group extends DatabaseModel {
|
|||||||
'pretty' => 'Access Administrator Areas',
|
'pretty' => 'Access Administrator Areas',
|
||||||
'default' => false,
|
'default' => false,
|
||||||
],
|
],
|
||||||
|
'uploadImages' => [
|
||||||
|
'pretty' => 'Upload images (such as avatars)',
|
||||||
|
'default' => false,
|
||||||
|
],
|
||||||
|
'maintenanceAccess' => [
|
||||||
|
'pretty' => 'Upload images (such as avatars)',
|
||||||
|
'default' => false,
|
||||||
|
],
|
||||||
];
|
];
|
||||||
public $resourceMatrix = [
|
public $resourceMatrix = [
|
||||||
[
|
[
|
||||||
|
@ -47,12 +47,6 @@ class User extends DatabaseModel {
|
|||||||
public $searchFields = [
|
public $searchFields = [
|
||||||
'username',
|
'username',
|
||||||
];
|
];
|
||||||
public $permissionMatrix = [
|
|
||||||
'uploadImages' => [
|
|
||||||
'pretty' => 'Upload images (such as avatars)',
|
|
||||||
'default' => false,
|
|
||||||
],
|
|
||||||
];
|
|
||||||
public $preferenceMatrix = [
|
public $preferenceMatrix = [
|
||||||
'gender' => [
|
'gender' => [
|
||||||
'pretty' => 'Gender',
|
'pretty' => 'Gender',
|
||||||
|
@ -45,19 +45,19 @@
|
|||||||
<!-- Navbar Toggler (Left) -->
|
<!-- Navbar Toggler (Left) -->
|
||||||
|
|
||||||
<!-- Centered Logo (Now inside normal document flow) -->
|
<!-- Centered Logo (Now inside normal document flow) -->
|
||||||
<a href="/" class="d-flex align-items-center text-white text-decoration-none d-md-none mx-auto">
|
<a href="/" class="align-items-center text-white text-decoration-none d-flex d-md-none">
|
||||||
<img src="{ROOT_URL}{LOGO}" width="40" height="32" alt="{SITENAME} Logo" class="bi">
|
<img src="{ROOT_URL}{LOGO}" width="40" height="32" alt="{SITENAME} Logo" class="bi">
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<!-- Logo (Normal Position for Large Screens) -->
|
<!-- Logo (Normal Position for Large Screens) -->
|
||||||
<a href="/" class="d-flex align-items-center text-white text-decoration-none d-none d-md-flex">
|
<a href="/" class="align-items-center text-white text-decoration-none d-none d-md-flex">
|
||||||
<img src="{ROOT_URL}{LOGO}" width="40" height="32" alt="{SITENAME} Logo" class="bi">
|
<img src="{ROOT_URL}{LOGO}" width="40" height="32" alt="{SITENAME} Logo" class="bi">
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<div class="navbar-expand-md flex-grow-1">
|
<div class="navbar-expand-md flex-grow-1">
|
||||||
<div class="collapse navbar-collapse d-md-flex" id="mainMenu">
|
<div class="collapse navbar-collapse d-md-flex" id="mainMenu">
|
||||||
<!-- Centered Navigation -->
|
<!-- Centered Navigation -->
|
||||||
<div class="d-none d-md-block d-flex justify-content-center w-100 position-absolute start-50 translate-middle-x">
|
<div class="d-none d-md-block d-flex justify-content-center position-absolute start-50 translate-middle-x">
|
||||||
{topNavLeft}
|
{topNavLeft}
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex justify-content-center flex-grow-1 d-md-none">
|
<div class="d-flex justify-content-center flex-grow-1 d-md-none">
|
||||||
@ -77,6 +77,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div class="d-flex flex-column min-vh-100">
|
<div class="d-flex flex-column min-vh-100">
|
||||||
<div class="flex-container flex-grow-1">
|
<div class="flex-container flex-grow-1">
|
||||||
{ISSUES}
|
{ISSUES}
|
||||||
|
@ -44,7 +44,7 @@ class Bugreport extends Plugin {
|
|||||||
],
|
],
|
||||||
];
|
];
|
||||||
public $permissionMatrix = [
|
public $permissionMatrix = [
|
||||||
'bugReport' => [
|
'canSendBugReports' => [
|
||||||
'pretty' => 'Can Submit Bug Reports',
|
'pretty' => 'Can Submit Bug Reports',
|
||||||
'default' => false,
|
'default' => false,
|
||||||
],
|
],
|
||||||
|
@ -40,7 +40,7 @@ class Contact extends Plugin {
|
|||||||
],
|
],
|
||||||
];
|
];
|
||||||
public $permissionMatrix = [
|
public $permissionMatrix = [
|
||||||
'contact' => [
|
'canUseContactForm' => [
|
||||||
'pretty' => 'Can Submit Contact',
|
'pretty' => 'Can Submit Contact',
|
||||||
'default' => true,
|
'default' => true,
|
||||||
],
|
],
|
||||||
|
30
app/views/admin/images/list/combined.html
Normal file
30
app/views/admin/images/list/combined.html
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<div class="container py-5 context-main-bg">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
{ADMIN_BREADCRUMBS}
|
||||||
|
<a href="{ROOT_URL}admin/images/upload" class="btn btn-sm btn-primary">Create</a>
|
||||||
|
</div>
|
||||||
|
<div class="row row-cols-1 row-cols-sm-2 row-cols-md-3 g-3">
|
||||||
|
{LOOP}
|
||||||
|
<div class="col">
|
||||||
|
<div class="card h-100 shadow-sm context-other-bg">
|
||||||
|
<div class="d-flex justify-content-center align-items-center context-other-bg" style="height: 250px;">
|
||||||
|
<img src="{url}" class="img-fluid p-2" style="max-width: 100%; max-height: 100%; object-fit: contain;">
|
||||||
|
</div>
|
||||||
|
<div class="card-body context-third-bg d-flex flex-column">
|
||||||
|
<div class="flex-grow-1">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<div class="">
|
||||||
|
<a href="{ROOT_URL}admin/images/view?fileLocation={locationSafe}" class="btn btn-sm btn-outline-primary">View</a>
|
||||||
|
<a href="{url}" class="btn btn-sm btn-outline-primary" target="_blank">Open</a>
|
||||||
|
<a href="{ROOT_URL}admin/images/rename?fileLocation={locationSafe}" class="btn btn-sm btn-outline-warning">Rename</a>
|
||||||
|
<a href="{ROOT_URL}admin/images/delete?fileLocation={locationSafe}" class="btn btn-sm btn-outline-danger">Delete</a>
|
||||||
|
</div>
|
||||||
|
<small class="text-muted">{filename}</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/LOOP}
|
||||||
|
</div>
|
||||||
|
</div>
|
35
app/views/admin/images/rename.html
Normal file
35
app/views/admin/images/rename.html
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<div class="context-main-bg context-main p-3">
|
||||||
|
<legend class="text-center">Rename Image</legend>
|
||||||
|
<hr>
|
||||||
|
{ADMIN_BREADCRUMBS}
|
||||||
|
<form method="post">
|
||||||
|
<fieldset>
|
||||||
|
<!-- Name -->
|
||||||
|
<div class="mb-3 row">
|
||||||
|
<label for="nickname" class="col-lg-6 col-form-label text-end">Location:</label>
|
||||||
|
<div class="col-lg-2">
|
||||||
|
<input type="hidden" class="form-control" name="filelocation" id="filelocation" value="{filelocation}">
|
||||||
|
<strong>
|
||||||
|
{filelocation}
|
||||||
|
</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Forward URL -->
|
||||||
|
<div class="mb-3 row">
|
||||||
|
<label for="newname" class="col-lg-6 col-form-label text-end">New filename ( Extensions cannot be modified ):</label>
|
||||||
|
<div class="col-lg-2">
|
||||||
|
<input type="text" class="form-control" name="newname" id="newname" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Hidden Token -->
|
||||||
|
<input type="hidden" name="token" value="{TOKEN}">
|
||||||
|
|
||||||
|
<!-- Submit Button -->
|
||||||
|
<div class="text-center">
|
||||||
|
<button type="submit" name="submit" value="submit" class="btn btn-primary btn-lg">Save</button>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
</div>
|
29
app/views/admin/images/upload.html
Normal file
29
app/views/admin/images/upload.html
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="container p-4 context-main-bg mb-4 text-center">
|
||||||
|
<h3 class="mb-4">Image Upload</h3>
|
||||||
|
<hr>
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<form method="post" enctype="multipart/form-data">
|
||||||
|
<fieldset>
|
||||||
|
<div class="mb-3 row">
|
||||||
|
<label for="avatar" class="h4 col-lg-6 col-form-label text-start text-lg-end">Image</label>
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<input type="file" class="form-control" name="uploadImage" id="uploadImage">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3 row">
|
||||||
|
<span class="h4 col-lg-6 col-form-label text-start text-lg-end">Destination Folder</span>
|
||||||
|
<div class="col-lg-6">
|
||||||
|
{FOLDER_SELECT}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
<input type="hidden" name="token" value="{TOKEN}">
|
||||||
|
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block">Update</button><br>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
66
app/views/admin/images/view.html
Normal file
66
app/views/admin/images/view.html
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<div class="container py-4">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-md-8">
|
||||||
|
{ADMIN_BREADCRUMBS}
|
||||||
|
<div class="card shadow">
|
||||||
|
<!-- Card Header -->
|
||||||
|
<div class="card-header text-center bg-dark text-white">
|
||||||
|
<h3 class="card-title mb-0">{filename}</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Card Body -->
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row align-items-center">
|
||||||
|
<!-- User Image -->
|
||||||
|
<div class="col-md-4 text-center">
|
||||||
|
<img src="{url}" alt="User Pic" class="img-fluid" style="max-width: 150px;">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- User Details -->
|
||||||
|
<div class="col-md-8">
|
||||||
|
<table class="table table-borderless">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">filename</th>
|
||||||
|
<td>{filename}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">extension</th>
|
||||||
|
<td>{extension}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">fileSize</th>
|
||||||
|
<td>{fileSize}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">location</th>
|
||||||
|
<td>{location}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">url</th>
|
||||||
|
<td>{url}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">folder</th>
|
||||||
|
<td>{folder}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Admin Controls -->
|
||||||
|
<div class="card-footer text-center">
|
||||||
|
{ADMIN}
|
||||||
|
<a href="{ROOT_URL}admin/images/rename?fileLocation={locationSafe}" class="btn btn-warning btn-sm me-2" data-bs-toggle="tooltip" title="Rename image">
|
||||||
|
<i class="fa fa-fw fa-pencil"></i>
|
||||||
|
</a>
|
||||||
|
<a href="{ROOT_URL}admin/images/delete?fileLocation={locationSafe}" class="btn btn-danger btn-sm" data-bs-toggle="tooltip" title="Delete image">
|
||||||
|
<i class="fa fa-fw fa-trash"></i>
|
||||||
|
</a>
|
||||||
|
{/ADMIN}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
17
app/views/forms/folderSelect.html
Normal file
17
app/views/forms/folderSelect.html
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
Folder: <strong>{FOLDER_SELECT_ROOT}</strong>
|
||||||
|
<div class="list-group mx-0 mx-auto">
|
||||||
|
{LOOP}
|
||||||
|
<label class="list-group-item d-flex justify-content-between align-items-center">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<input class="form-check-input me-2" type="radio" name="folderSelect" value="{location}" data-bs-toggle="collapse" data-bs-target="#top-{folderName}">
|
||||||
|
<span>
|
||||||
|
{folderName}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{folderexpand}
|
||||||
|
</label>
|
||||||
|
<div id="top-{folderName}" class="collapse">
|
||||||
|
{subdirs}
|
||||||
|
</div>
|
||||||
|
{/LOOP}
|
||||||
|
</div>
|
6
app/views/forms/folderSelectChild.html
Normal file
6
app/views/forms/folderSelectChild.html
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<label class="list-group-item">
|
||||||
|
<input class="form-check-input me-2" type="radio" name="folderSelect" value="{location}">
|
||||||
|
<span>
|
||||||
|
{folderName}
|
||||||
|
</span>
|
||||||
|
</label>
|
14
app/views/forms/folderSelectParent.html
Normal file
14
app/views/forms/folderSelectParent.html
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{LOOP}
|
||||||
|
<label class="list-group-item d-flex justify-content-between align-items-center">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<input class="form-check-input me-2" type="radio" name="folderSelect" value="{location}" data-bs-toggle="collapse" data-bs-target="#{parentfolderName}-{folderName}">
|
||||||
|
<span>
|
||||||
|
{folderName}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{folderexpand}
|
||||||
|
</label>
|
||||||
|
<div id="{parentfolderName}-{folderName}" class="collapse">
|
||||||
|
{subdirs}
|
||||||
|
</div>
|
||||||
|
{/LOOP}
|
@ -10,7 +10,7 @@
|
|||||||
<form method="post">
|
<form method="post">
|
||||||
<input type="hidden" name="token" value="{TOKEN}">
|
<input type="hidden" name="token" value="{TOKEN}">
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<button class="btn btn-lg btn-primary center-block" type="submit" name="submit" value="submit">Generate</button><br>
|
<button class="btn btn-lg btn-primary center-block mb-3" type="submit" name="submit" value="submit">Generate</button><br>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<div class="text-center my-4">
|
<div class="text-center my-4">
|
||||||
<form method="post">
|
<form method="post">
|
||||||
<input type="hidden" name="token" value="{TOKEN}">
|
<input type="hidden" name="token" value="{TOKEN}">
|
||||||
<button class="btn btn-lg btn-primary center-block" type="submit" name="submit" value="submit">I Agree</button><br>
|
<button class="btn btn-lg btn-primary center-block mb-3" type="submit" name="submit" value="submit">I Agree</button><br>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<form method="post">
|
<form method="post">
|
||||||
<input type="hidden" name="token" value="{TOKEN}">
|
<input type="hidden" name="token" value="{TOKEN}">
|
||||||
<button class="btn btn-lg btn-primary center-block" type="submit" name="submit" value="submit">Check</button><br>
|
<button class="btn btn-lg btn-primary center-block mb-3" type="submit" name="submit" value="submit">Check</button><br>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -3,13 +3,13 @@
|
|||||||
<div class="col-md-10 text-center">
|
<div class="col-md-10 text-center">
|
||||||
<div class="context-main-bg my-3 pb-3 rounded">
|
<div class="context-main-bg my-3 pb-3 rounded">
|
||||||
{installer-nav}
|
{installer-nav}
|
||||||
<h1 class="mt-4">Welcome to The Tempus Project Installer.</h1>
|
<h1 class="mt-5 mb-4">Welcome to The Tempus Project Installer.</h1>
|
||||||
<p>
|
<p class="lead p-3">
|
||||||
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.
|
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.
|
||||||
</p>
|
</p>
|
||||||
<form method="post">
|
<form method="post">
|
||||||
<input type="hidden" name="token" value="{TOKEN}">
|
<input type="hidden" name="token" value="{TOKEN}">
|
||||||
<button class="btn btn-lg btn-primary center-block" type="submit" name="submit" id="submit" value="submit">Begin Installation</button><br>
|
<button class="btn btn-lg btn-primary center-block mb-3" type="submit" name="submit" id="submit" value="submit">Begin Installation</button><br>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -584,7 +584,7 @@ class TheTempusProject extends Bedrock {
|
|||||||
$url = trim( Input::get( 'url' ), '/' );
|
$url = trim( Input::get( 'url' ), '/' );
|
||||||
$url = str_ireplace( '.php', '', $url );
|
$url = str_ireplace( '.php', '', $url );
|
||||||
}
|
}
|
||||||
$route = $routes->findByOriginalUrl($url);
|
$route = $routes->findByOriginalUrl( $url );
|
||||||
if (false !== $route) {
|
if (false !== $route) {
|
||||||
$route = $route;
|
$route = $route;
|
||||||
if ('internal' === $route->redirect_type) {
|
if ('internal' === $route->redirect_type) {
|
||||||
@ -593,6 +593,26 @@ class TheTempusProject extends Bedrock {
|
|||||||
Redirect::external($route->forwarded_url);
|
Redirect::external($route->forwarded_url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( 'home/login' !== $url ) {
|
||||||
|
if ( Config::getValue( 'maintenance/enabled' ) ) {
|
||||||
|
if ( ! self::$isLoggedIn ) {
|
||||||
|
Session::flash( 'notice', Config::getValue( 'maintenance/maintenanceMessage' ) );
|
||||||
|
Redirect::to( 'home/login' );
|
||||||
|
}
|
||||||
|
if ( self::$activeGroup->ID != 1 ) {
|
||||||
|
if ( empty( self::$activeGroup->perms['maintenanceAccess'] ) ) {
|
||||||
|
Session::flash( 'notice', Config::getValue( 'maintenance/maintenanceMessage' ) );
|
||||||
|
Redirect::to( 'home/login' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} elseif ( Config::getValue( 'maintenance/enabled' ) ) {
|
||||||
|
if ( ! self::$isLoggedIn ) {
|
||||||
|
Issues::add( 'notice', Config::getValue( 'maintenance/maintenanceMessage' ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
parent::load();
|
parent::load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,19 +2,22 @@
|
|||||||
"name": "thetempusproject/thetempusproject",
|
"name": "thetempusproject/thetempusproject",
|
||||||
"type": "project",
|
"type": "project",
|
||||||
"description": "The aim of this project is to provide a simple and stable platform for rapidly prototyping new web applications.",
|
"description": "The aim of this project is to provide a simple and stable platform for rapidly prototyping new web applications.",
|
||||||
|
"license": "MIT",
|
||||||
|
"minimum-stability": "dev",
|
||||||
"keywords":
|
"keywords":
|
||||||
[
|
[
|
||||||
"thetempusproject",
|
"thetempusproject",
|
||||||
|
"php",
|
||||||
|
"mvc",
|
||||||
"framework"
|
"framework"
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
|
||||||
"homepage": "https://TheTempusProject.com",
|
"homepage": "https://TheTempusProject.com",
|
||||||
"authors":
|
"authors":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "Joey Kimsey",
|
"name": "Joey Kimsey",
|
||||||
"email": "Joey@thetempusproject.com",
|
"email": "Joey@thetempusproject.com",
|
||||||
"homepage": "https://TheTempusProject.com",
|
"homepage": "https://JoeyKimsey.com",
|
||||||
"role": "Lead Developer"
|
"role": "Lead Developer"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -22,9 +25,9 @@
|
|||||||
{
|
{
|
||||||
"components/jquery": "1.9.*",
|
"components/jquery": "1.9.*",
|
||||||
"fortawesome/font-awesome": "4.7",
|
"fortawesome/font-awesome": "4.7",
|
||||||
"thetempusproject/bedrock": "1.1.1",
|
"thetempusproject/bedrock": "1.1.2",
|
||||||
"thetempusproject/canary": "1.0.6",
|
"thetempusproject/canary": "1.0.7",
|
||||||
"thetempusproject/houdini": "2.0.2",
|
"thetempusproject/houdini": "2.0.3",
|
||||||
"twbs/bootstrap": "5.2.3"
|
"twbs/bootstrap": "5.2.3"
|
||||||
},
|
},
|
||||||
"autoload":
|
"autoload":
|
||||||
@ -61,6 +64,5 @@
|
|||||||
"robloach/component-installer": true
|
"robloach/component-installer": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"minimum-stability": "dev",
|
|
||||||
"prefer-stable": true
|
"prefer-stable": true
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user