
Fixed config switches not registering the correct current value Added better ux when image uploads are disabled Fixed an issue where uploaded files were not being handled correctly Added the ability to disable user registrations Fixed some variables being unintendedly protected
386 lines
14 KiB
PHP
386 lines
14 KiB
PHP
<?php
|
|
/**
|
|
* app/classes/preferences.php
|
|
*
|
|
* This class handles all the hard-coded preferences.
|
|
*
|
|
* @version 3.0
|
|
* @author Joey Kimsey <Joey@thetempusproject.com>
|
|
* @link https://TheTempusProject.com
|
|
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
|
*/
|
|
namespace TheTempusProject\Classes;
|
|
|
|
use TheTempusProject\Houdini\Classes\Issues;
|
|
use TheTempusProject\Houdini\Classes\Forms;
|
|
use TheTempusProject\Houdini\Classes\Template;
|
|
use TheTempusProject\Canary\Bin\Canary as Debug;
|
|
use TheTempusProject\Bedrock\Functions\Check;
|
|
use TheTempusProject\Bedrock\Functions\Upload;
|
|
use TheTempusProject\Bedrock\Functions\Input;
|
|
use TheTempusProject\TheTempusProject as App;
|
|
use TheTempusProject\Bedrock\Classes\Config;
|
|
|
|
class Preferences {
|
|
public static $preferences = false;
|
|
private static $location = false;
|
|
private static $initialized = false;
|
|
|
|
/**
|
|
* Default constructor which will attempt to load the preferences from the location specified.
|
|
*
|
|
* @param {string} [$location]
|
|
* @return {null|object}
|
|
*/
|
|
public function __construct( $location = '' ) {
|
|
if ( self::$initialized !== false ) {
|
|
Debug::log( 'Preferences already initialized.' );
|
|
return $this;
|
|
}
|
|
if ( empty( $location ) ) {
|
|
$location = PREFERENCES_JSON;
|
|
}
|
|
self::$initialized = $this->load( $location );
|
|
if ( self::$initialized !== false ) {
|
|
Debug::log( 'Preferences initialization succeeded.' );
|
|
return $this;
|
|
}
|
|
Debug::warn( 'Preferences initialization failed.' );
|
|
}
|
|
|
|
/**
|
|
* Attempts to retrieve then set the preferences from a file.
|
|
* @note This function will reset the preferences every time it is used.
|
|
*
|
|
* @param {string} [$location]
|
|
* @return {bool}
|
|
*/
|
|
public function load( $location ) {
|
|
self::$preferences = $this->getPrefsFile( $location );
|
|
self::$location = $location;
|
|
if ( self::$preferences === false || empty( self::$preferences ) ) {
|
|
Debug::warn( 'Preferences load failed.' );
|
|
return false;
|
|
}
|
|
Debug::log( 'Preferences load succeeded.' );
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Opens and decodes the preferences json from the location provided.
|
|
*
|
|
* @param {string} [$location]
|
|
* @return {bool|array}
|
|
*/
|
|
public function getPrefsFile( $location ) {
|
|
if ( file_exists( $location ) ) {
|
|
Debug::debug( "Preferences json found: $location" );
|
|
return json_decode( file_get_contents( $location ), true );
|
|
} else {
|
|
Debug::warn( "Preferences json not found: $location" );
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Retrieves the preference option for $name.
|
|
*
|
|
* @param {string} [$name]
|
|
* @return {WILD}
|
|
*/
|
|
public static function get( $name ) {
|
|
if ( self::$preferences === false ) {
|
|
return Debug::warn( 'Preferences not loaded.' );
|
|
}
|
|
if ( isset( self::$preferences[$name] ) ) {
|
|
return self::$preferences[$name];
|
|
}
|
|
return Debug::warn( "Preference not found: $name" );
|
|
}
|
|
|
|
public function getType( $name ) {
|
|
$pref = $this->get( $name );
|
|
if ( empty( $pref ) || empty( $pref['type'] ) ) {
|
|
return Debug::warn( "Preference Type not found: $name" );
|
|
}
|
|
return $pref['type'];
|
|
}
|
|
|
|
public function getDefault( $name ) {
|
|
$pref = $this->get( $name );
|
|
if ( empty( $pref ) || empty( $pref['default'] ) ) {
|
|
return Debug::warn( "Preference Default not found: $name" );
|
|
}
|
|
return $pref['default'];
|
|
}
|
|
|
|
public function getOptions( $name ) {
|
|
$pref = $this->get( $name );
|
|
if ( empty( $pref ) || empty( $pref['options'] ) ) {
|
|
return Debug::warn( "Preference Options not found: $name" );
|
|
}
|
|
return $pref['options'];
|
|
}
|
|
|
|
public function getPrettyName( $name ) {
|
|
$pref = $this->get( $name );
|
|
if ( empty( $pref ) || empty( $pref['pretty'] ) ) {
|
|
return Debug::warn( "Preference Pretty Name not found: $name" );
|
|
}
|
|
return $pref['pretty'];
|
|
}
|
|
|
|
/**
|
|
* Saves the current preferences.
|
|
*
|
|
* @param {bool} [$default] - Whether or not to save a default copy.
|
|
* @return {bool}
|
|
*/
|
|
public function save( $backup = true ) {
|
|
if ( self::$preferences === false ) {
|
|
Debug::warn( 'Preferences not loaded.' );
|
|
return false;
|
|
}
|
|
if ( self::$location === false ) {
|
|
Debug::warn( 'Preferences location not set.' );
|
|
return false;
|
|
}
|
|
if ( $backup ) {
|
|
$locationArray = explode( '.', self::$location );
|
|
$locationArray[] = 'bak';
|
|
$backupLoction = implode( '.', $locationArray );
|
|
if ( !file_put_contents( $backupLoction, json_encode( self::$preferences ) ) ) {
|
|
return false;
|
|
}
|
|
}
|
|
if ( file_put_contents( self::$location, json_encode( self::$preferences ) ) ) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Adds a new preference to the $preferences array.
|
|
*
|
|
* @param {string} [$name]
|
|
* @param {string} [$value]
|
|
* @return {bool}
|
|
*/
|
|
public function add( $name, $details ) {
|
|
if ( !Check::simpleName( $name ) ) {
|
|
Debug::error( "Preference name invalid: $name" );
|
|
return false;
|
|
}
|
|
if ( isset( self::$preferences[$name] ) ) {
|
|
Debug::warn( "Preference already exists: $name" );
|
|
return false;
|
|
}
|
|
if ( self::$preferences === false ) {
|
|
self::$preferences = [];
|
|
}
|
|
$prefsArray = $this->normalizePreferenceArray( $name, $details );
|
|
if ( false === $prefsArray ) {
|
|
Debug::warn( 'Preference array failed to load properly.' );
|
|
return false;
|
|
}
|
|
self::$preferences[$name] = $prefsArray;
|
|
return true;
|
|
}
|
|
|
|
public function getFormHtml( $populated = [] ) {
|
|
// dv( self::$preferences );
|
|
$form = '';
|
|
// Added so i can force some sort of ordering
|
|
$inputTypes = [
|
|
'file' => [],
|
|
'select' => [],
|
|
'timezone' => [],
|
|
'checkbox' => [],
|
|
'switch' => [],
|
|
];
|
|
foreach ( self::$preferences as $name => $details ) {
|
|
$tempPrefsArray = $this->normalizePreferenceArray( $name, $details );
|
|
if ( isset( $populated[ $name ] ) ) {
|
|
$tempPrefsArray['value'] = $populated[$name];
|
|
} else {
|
|
$tempPrefsArray['value'] = $tempPrefsArray['default'];
|
|
}
|
|
// $form .= Forms::getFormFieldHtml( $name, $tempPrefsArray['pretty'], $tempPrefsArray['type'], $tempPrefsArray['default'], $tempPrefsArray['options'] );
|
|
if ( $tempPrefsArray['type'] == 'checkbox' ) {
|
|
$tempPrefsArray['type'] = 'switch';
|
|
}
|
|
|
|
if ( 'file' === $tempPrefsArray['type'] ) {
|
|
// dv( Config::getValue( 'uploads/images' ) );
|
|
if ( ! Config::getValue( 'uploads/images' ) ) {
|
|
Debug::info( 'Preference hidden because uploads are disabled.' );
|
|
continue;
|
|
}
|
|
}
|
|
|
|
$inputTypes[ $tempPrefsArray['type'] ][] = self::getFormFieldHtml( $name, $tempPrefsArray['pretty'], $tempPrefsArray['type'], $tempPrefsArray['value'], $tempPrefsArray['options'] );
|
|
}
|
|
foreach ( $inputTypes as $skip => $items ) {
|
|
$form .= implode( ' ', $items );
|
|
}
|
|
return $form;
|
|
}
|
|
|
|
public static function getFormFieldHtml( $fieldname, $fieldTitle, $type, $defaultValue = '', $options = null ) {
|
|
$html = '';
|
|
switch ( $type ) {
|
|
case 'radio':
|
|
case 'bool':
|
|
case 'boolean':
|
|
$fieldHtml = Forms::getRadioHtml( $fieldname, [ 'true', 'false' ], $defaultValue );
|
|
break;
|
|
case 'select':
|
|
$fieldHtml = Forms::getSelectHtml( $fieldname, $options, $defaultValue );
|
|
break;
|
|
case 'customSelect':
|
|
if ( empty( $options ) ) {
|
|
$options = '{' . $fieldname . '-options}';
|
|
}
|
|
$fieldHtml = Forms::getSelectHtml( $fieldname, $options, $defaultValue );
|
|
break;
|
|
case 'block':
|
|
$fieldHtml = Forms::getTextBlockHtml( $fieldname, $defaultValue );
|
|
break;
|
|
case 'text':
|
|
case 'url':
|
|
$fieldHtml = Forms::getTextHtml( $fieldname, $defaultValue );
|
|
break;
|
|
case 'checkbox':
|
|
$fieldHtml = Forms::getCheckboxHtml( $fieldname, $defaultValue );
|
|
break;
|
|
case 'switch':
|
|
$fieldHtml = Forms::getSwitchHtml( $fieldname, $defaultValue );
|
|
break;
|
|
case 'timezone':
|
|
$fieldHtml = Forms::getTimezoneHtml( $defaultValue );
|
|
break;
|
|
case 'file':
|
|
$fieldHtml = Forms::getFileHtml( $fieldname );
|
|
break;
|
|
default:
|
|
Debug::error( "unknown field type: $type" );
|
|
break;
|
|
}
|
|
|
|
$html .= '<div class="mb-3 row">';
|
|
$html .= '<label for="' . $fieldname . '" class="col-lg-6 col-form-label text-end">' . $fieldTitle . '</label>';
|
|
$html .= '<div class="col-lg-6">';
|
|
$html .= $fieldHtml;
|
|
$html .= '</div>';
|
|
if ( 'file' === $type ) {
|
|
$html .= '<div class="mb-3 row">';
|
|
$html .= '<h4 class="col-lg-6 col-form-label text-end">Current Image</h4>';
|
|
$html .= '<div class="col-lg-6">';
|
|
$html .= '<img alt="User Avatar" src="{ROOT_URL}' . $defaultValue . '" class="img-circle img-fluid p-2 avatar-125">';
|
|
$html .= '</div>';
|
|
}
|
|
$html .= '</div>';
|
|
return Template::parse( $html );
|
|
}
|
|
|
|
public function convertFormToArray( $fillMissing = true, $defaultsOnly = true ) {
|
|
$prefsArray = [];
|
|
foreach ( self::$preferences as $name => $details ) {
|
|
if ( true === $fillMissing ) {
|
|
if ( true !== $defaultsOnly && !empty( App::$activePrefs[$name] ) ) {
|
|
$prefsArray[$name] = App::$activePrefs[$name];
|
|
} else {
|
|
$prefsArray[$name] = $details['default'];
|
|
}
|
|
}
|
|
if ( Input::exists( $name ) ) {
|
|
$prefsArray[$name] = Input::post( $name );
|
|
}
|
|
if ( 'file' == $details['type'] ) {
|
|
if ( Input::exists( $name ) ) {
|
|
$folder = UPLOAD_DIRECTORY . App::$activeUser->username . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR;
|
|
$upload = Upload::image( $name, $folder );
|
|
if ( $upload ) {
|
|
$route = str_replace( APP_ROOT_DIRECTORY, '', $folder );
|
|
$prefsArray[$name] = $route . Upload::last();
|
|
} else {
|
|
Issues::add( 'error', [ 'There was an error with your upload.' => Check::userErrors() ] );
|
|
unset( $prefsArray[$name] );
|
|
}
|
|
}
|
|
}
|
|
if ( 'checkbox' == $details['type'] ) {
|
|
if ( Input::exists( $name ) ) {
|
|
$prefsArray[$name] = true;
|
|
} else {
|
|
$prefsArray[$name] = false;
|
|
}
|
|
}
|
|
}
|
|
return $prefsArray;
|
|
}
|
|
|
|
public function getDefaultPreferencesArray() {
|
|
if ( self::$preferences === false ) {
|
|
Debug::warn( 'Preferences not loaded.' );
|
|
return false;
|
|
}
|
|
$prefsArray = [];
|
|
foreach ( self::$preferences as $name => $details ) {
|
|
$tempPrefsArray = $this->normalizePreferenceArray( $name, $details );
|
|
$prefsArray[$name] = $tempPrefsArray['default'];
|
|
}
|
|
return $prefsArray;
|
|
}
|
|
|
|
public function normalizePreferenceArray( $name, $prefsArray ) {
|
|
if ( !is_array( $prefsArray ) ) {
|
|
Debug::warn( 'Preference array was not an array.' );
|
|
return false;
|
|
}
|
|
if ( !isset( $prefsArray['type'] ) ) {
|
|
if ( isset( $prefsArray['options'] ) ) {
|
|
$prefsArray['type'] = 'select';
|
|
} else {
|
|
$prefsArray['type'] = 'text';
|
|
}
|
|
}
|
|
if ( !isset( $prefsArray['pretty'] ) ) {
|
|
$prefsArray['pretty'] = ucfirst( $name );
|
|
}
|
|
if ( !isset( $prefsArray['default'] ) ) {
|
|
$prefsArray['default'] = '';
|
|
}
|
|
if ( ( empty( $prefsArray['avatar'] ) ) || ( $prefsArray['avatar'] == 'defaultAvatar.png' ) ) {
|
|
$prefsArray['avatar'] = IMAGE_DIRECTORY . 'defaultAvatar.png';
|
|
}
|
|
if ( !isset( $prefsArray['options'] ) ) {
|
|
$prefsArray['options'] = null;
|
|
}
|
|
return $prefsArray;
|
|
}
|
|
|
|
/**
|
|
* Removes an existing preference from the $preferences array.
|
|
*
|
|
* @param {string} [$name]
|
|
* @param {bool} [$save]
|
|
* @return {bool}
|
|
*/
|
|
public function remove( $name, $save = false ) {
|
|
if ( self::$preferences === false ) {
|
|
Debug::warn( 'Preferences not loaded.' );
|
|
return false;
|
|
}
|
|
if ( !isset( self::$preferences[$name] ) ) {
|
|
Debug::error( "Preference does not exist: $name" );
|
|
return false;
|
|
}
|
|
unset( self::$preferences[$name] );
|
|
if ( $save === true ) {
|
|
return $this->save( true );
|
|
}
|
|
return true;
|
|
}
|
|
}
|