diff --git a/app/classes/config.php b/app/classes/config.php
index 6f3609c..0a28176 100644
--- a/app/classes/config.php
+++ b/app/classes/config.php
@@ -73,7 +73,7 @@ class Config extends BedrockConfig {
$html .= '
';
$html .= '
' . $pretty . ' ';
diff --git a/app/classes/plugin.php b/app/classes/plugin.php
index 76b1c67..7364455 100644
--- a/app/classes/plugin.php
+++ b/app/classes/plugin.php
@@ -89,7 +89,7 @@ class Plugin {
foreach ( self::PLUGIN_FLAG_MAP as $flag_name => $function_name ) {
if ( empty( $options[$flag_name] ) ) {
- $module_data[ $flag_name ] = INSTALL_STATUS_SKIPPED;
+ // $module_data[ $flag_name ] = INSTALL_STATUS_SKIPPED;
continue;
}
@@ -280,7 +280,7 @@ class Plugin {
public function installResources( $options = '' ) {
if ( empty( $this->resourceMatrix ) ) {
Debug::log( 'resourceMatrix is empty' );
- return true;
+ return INSTALL_STATUS_NOT_REQUIRED;
}
$ids = [];
foreach( $this->resourceMatrix as $tableName => $entries ) {
diff --git a/app/classes/preferences.php b/app/classes/preferences.php
index c32d08c..c582d1b 100644
--- a/app/classes/preferences.php
+++ b/app/classes/preferences.php
@@ -276,7 +276,7 @@ class Preferences {
$html .= '
';
$html .= '
Current Image ';
$html .= '
';
- $html .= '
';
+ $html .= '
';
$html .= '
';
}
$html .= '
';
diff --git a/app/config/constants.php b/app/config/constants.php
index 2f1863c..ab609ba 100644
--- a/app/config/constants.php
+++ b/app/config/constants.php
@@ -39,7 +39,7 @@ if ( ! defined( 'CONFIG_DIRECTORY' ) ) {
define( 'CANARY_SECURE_HASH', 'd73ed7591a30f0ca7d686a0e780f0d05' );
# Tempus Project Core
define( 'APP_NAME', 'The Tempus Project');
-define( 'TP_DEFAULT_LOGO', 'images/logo.png');
+define( 'TP_DEFAULT_LOGO', 'images/logoWhite.png');
// Check
define( 'MINIMUM_PHP_VERSION', 8.1);
// Cookies
diff --git a/app/controllers/admin/images.php b/app/controllers/admin/images.php
index 0499c41..e2abda8 100644
--- a/app/controllers/admin/images.php
+++ b/app/controllers/admin/images.php
@@ -23,8 +23,154 @@ use TheTempusProject\Bedrock\Functions\Input;
use TheTempusProject\Bedrock\Functions\Check;
use TheTempusProject\Hermes\Functions\Redirect;
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 {
+ 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'] = '
';
+ } 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() {
parent::__construct();
@@ -76,39 +222,147 @@ class Images extends AdminController {
Views::view( 'admin.images.create' );
}
- public function delete( $id = null ) {
+ public function delete() {
if ( self::$token->delete( [ $id ] ) ) {
Session::flash( 'success', 'Token deleted.' );
}
Redirect::to( 'admin/images' );
}
- public function edit( $id = null ) {
- $token = self::$token->findById( $id );
+ public function rename() {
+
+ if ( ! Input::exists( 'fileLocation' ) ) {
+ Session::flash( 'warning', 'Unknown image.' );
+ Redirect::to( 'admin/images' );
+ }
+
+ Components::set( 'filelocation', Input::get( 'fileLocation' ) );
+
if ( Input::exists( 'submit' ) ) {
- if ( !TTPForms::check( 'adminEditToken' ) ) {
- Issues::add( 'error', [ 'There was an error with your token.' => Check::userErrors() ] );
+ if ( !TTPForms::check( 'renameIImage' ) ) {
+ Issues::add( 'error', [ 'There was an error renaming the image.' => Check::userErrors() ] );
} else {
- if ( self::$token->update(
- $id,
- Input::post( 'name' ),
- Input::post( 'notes' ),
- Input::post( 'token_type' )
- ) ) {
- Session::flash( 'success', 'Token Updated' );
+ $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() {
- return Views::view( 'admin.images.list', self::$token->listPaginated() );
+ return Views::view( 'admin.images.list.combined', $this->getAllImageDetails() );
}
- public function view( $id = null ) {
- return Views::view( 'admin.images.view', self::$token->findById( $id ) );
+ public function view() {
+ 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;
}
}
diff --git a/app/models/group.php b/app/models/group.php
index f5331a3..d5a85f1 100644
--- a/app/models/group.php
+++ b/app/models/group.php
@@ -46,6 +46,14 @@ class Group extends DatabaseModel {
'pretty' => 'Access Administrator Areas',
'default' => false,
],
+ 'uploadImages' => [
+ 'pretty' => 'Upload images (such as avatars)',
+ 'default' => false,
+ ],
+ 'maintenanceAccess' => [
+ 'pretty' => 'Upload images (such as avatars)',
+ 'default' => false,
+ ],
];
public $resourceMatrix = [
[
diff --git a/app/models/user.php b/app/models/user.php
index 286663d..90c52de 100644
--- a/app/models/user.php
+++ b/app/models/user.php
@@ -47,12 +47,6 @@ class User extends DatabaseModel {
public $searchFields = [
'username',
];
- public $permissionMatrix = [
- 'uploadImages' => [
- 'pretty' => 'Upload images (such as avatars)',
- 'default' => false,
- ],
- ];
public $preferenceMatrix = [
'gender' => [
'pretty' => 'Gender',
diff --git a/app/plugins/blog/templates/blog.tpl b/app/plugins/blog/templates/blog.tpl
index eb9530f..cb23a4e 100644
--- a/app/plugins/blog/templates/blog.tpl
+++ b/app/plugins/blog/templates/blog.tpl
@@ -45,19 +45,19 @@
-
+
-
+
-
+
{topNavLeft}
@@ -77,6 +77,7 @@
+
{ISSUES}
diff --git a/app/plugins/bugreport/plugin.php b/app/plugins/bugreport/plugin.php
index d54e69d..6a4be8e 100644
--- a/app/plugins/bugreport/plugin.php
+++ b/app/plugins/bugreport/plugin.php
@@ -44,7 +44,7 @@ class Bugreport extends Plugin {
],
];
public $permissionMatrix = [
- 'bugReport' => [
+ 'canSendBugReports' => [
'pretty' => 'Can Submit Bug Reports',
'default' => false,
],
diff --git a/app/plugins/contact/plugin.php b/app/plugins/contact/plugin.php
index 98cf81b..6bdf78a 100644
--- a/app/plugins/contact/plugin.php
+++ b/app/plugins/contact/plugin.php
@@ -40,7 +40,7 @@ class Contact extends Plugin {
],
];
public $permissionMatrix = [
- 'contact' => [
+ 'canUseContactForm' => [
'pretty' => 'Can Submit Contact',
'default' => true,
],
diff --git a/app/views/admin/images/list/combined.html b/app/views/admin/images/list/combined.html
new file mode 100644
index 0000000..f237802
--- /dev/null
+++ b/app/views/admin/images/list/combined.html
@@ -0,0 +1,30 @@
+
+
+ {ADMIN_BREADCRUMBS}
+
Create
+
+
+ {LOOP}
+
+
+
+
+
+
+
+
+ {/LOOP}
+
+
\ No newline at end of file
diff --git a/app/views/admin/images/rename.html b/app/views/admin/images/rename.html
new file mode 100644
index 0000000..f429c88
--- /dev/null
+++ b/app/views/admin/images/rename.html
@@ -0,0 +1,35 @@
+
+
Rename Image
+
+ {ADMIN_BREADCRUMBS}
+
+
\ No newline at end of file
diff --git a/app/views/admin/images/upload.html b/app/views/admin/images/upload.html
new file mode 100644
index 0000000..5ad1b0c
--- /dev/null
+++ b/app/views/admin/images/upload.html
@@ -0,0 +1,29 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/views/admin/images/view.html b/app/views/admin/images/view.html
new file mode 100644
index 0000000..fde455e
--- /dev/null
+++ b/app/views/admin/images/view.html
@@ -0,0 +1,66 @@
+
+
+
+ {ADMIN_BREADCRUMBS}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ filename
+ {filename}
+
+
+ extension
+ {extension}
+
+
+ fileSize
+ {fileSize}
+
+
+ location
+ {location}
+
+
+ url
+ {url}
+
+
+ folder
+ {folder}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/views/auth/register.html b/app/views/auth/register.html
index 9fec3f3..23281cd 100644
--- a/app/views/auth/register.html
+++ b/app/views/auth/register.html
@@ -1,12 +1,3 @@
-
-
-
-
-
-
-
-
-