Initial commit
This commit is contained in:
493
app/classes/plugin.php
Normal file
493
app/classes/plugin.php
Normal file
@ -0,0 +1,493 @@
|
||||
<?php
|
||||
/**
|
||||
* app/classes/plugin.php
|
||||
*
|
||||
* This class is used as a foundation for all plugins to build from.
|
||||
*
|
||||
* @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\Navigation;
|
||||
use TheTempusProject\Houdini\Classes\Filters;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
use TheTempusProject\Canary\Canary as Debug;
|
||||
use TheTempusProject\Bedrock\Classes\Database;
|
||||
|
||||
class Plugin {
|
||||
public $required_models = [];
|
||||
public $models = [];
|
||||
public $errors = [];
|
||||
|
||||
// Global Properties
|
||||
public $module;
|
||||
public $initialized = false;
|
||||
public static $installer;
|
||||
public static $db;
|
||||
public static $installFlags = PLUGIN_INSTALL_FLAGS;
|
||||
public static $pluginFolders = [];
|
||||
public static $pluginsAvailable = [];
|
||||
public static $pluginsActive = [];
|
||||
|
||||
// Basic Required Info
|
||||
public $pluginName = 'Default Plugin Name';
|
||||
public $pluginAuthor = 'TheTempusProject';
|
||||
public $pluginWebsite = 'https://TheTempusProject.com';
|
||||
public $pluginVersion = 0.0;
|
||||
public $pluginDescription = 'The Default Plugin Description';
|
||||
|
||||
// Front-end Properties
|
||||
public $admin_links = [];
|
||||
public $main_links = [];
|
||||
public $footer_links = [];
|
||||
public $filters = [];
|
||||
|
||||
// Install Related
|
||||
public $configName = '';
|
||||
public $configMatrix = [];
|
||||
public $resourceMatrix = [];
|
||||
public $preferenceMatrix = [];
|
||||
public $permissionMatrix = [];
|
||||
|
||||
const PLUGIN_FLAG_MAP = [
|
||||
'preferences_installed' => 'installPreferences',
|
||||
'permissions_installed' => 'installPermissions',
|
||||
'configs_installed' => 'installConfigs',
|
||||
'models_installed' => 'installModels',
|
||||
'resources_installed' => 'installResources',
|
||||
];
|
||||
|
||||
public function __construct( $load = false ) {
|
||||
if ( true === $this->initialized && false == $load ) {
|
||||
return;
|
||||
}
|
||||
self::$db = Database::getInstance();
|
||||
if ( ! isset( self::$installer ) ) {
|
||||
self::$installer = new Installer();
|
||||
}
|
||||
if ( ! isset( $this->module ) ) {
|
||||
$this->module = self::$installer->getModule( getClassName( $this ) );
|
||||
}
|
||||
if ( true == $load ) {
|
||||
if ( $this->checkEnabled() ) {
|
||||
$this->loadAdminNav();
|
||||
$this->loadMainNav();
|
||||
$this->loadFooterNav();
|
||||
$this->loadFilters();
|
||||
}
|
||||
$this->initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
public function install( $options ) {
|
||||
Debug::log( 'Installing Plugin: ' . $this->pluginName );
|
||||
$module_data = [];
|
||||
$errors = [];
|
||||
|
||||
foreach ( self::PLUGIN_FLAG_MAP as $flag_name => $function_name ) {
|
||||
if ( empty( $options[$flag_name] ) ) {
|
||||
$module_data[ $flag_name ] = INSTALL_STATUS_SKIPPED;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( 'installModels' != $function_name ) {
|
||||
$result = $this->$function_name( $options );
|
||||
} else {
|
||||
$model_options = $this->convertPluginOptionsToModelOptions( $options );
|
||||
$result = $this->$function_name( $model_options );
|
||||
}
|
||||
|
||||
if ( empty( $result ) ) {
|
||||
$errors[] = ['errorInfo' => get_class($this) . " Failed to execute $flag_name properly."];
|
||||
$module_data[ $flag_name ] = INSTALL_STATUS_FAIL;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( 'installResources' === $function_name ) {
|
||||
$module_data[ $flag_name ] = $result;
|
||||
continue;
|
||||
}
|
||||
|
||||
$module_data[ $flag_name ] = INSTALL_STATUS_SUCCESS;
|
||||
continue;
|
||||
}
|
||||
|
||||
return [ $module_data, $errors ];
|
||||
}
|
||||
|
||||
public function uninstall( $options ) {
|
||||
Debug::log( 'Uninstalling Plugin: ' . $this->pluginName );
|
||||
$module_data = [];
|
||||
$errors = [];
|
||||
|
||||
foreach ( self::PLUGIN_FLAG_MAP as $flag_name => $function_name ) {
|
||||
$function_name = 'un' . $function_name;
|
||||
if ( empty( $options[$flag_name] ) ) {
|
||||
$module_data[ $flag_name ] = INSTALL_STATUS_SKIPPED;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( 'installModels' != $function_name ) {
|
||||
$result = $this->$function_name( $options );
|
||||
} else {
|
||||
$model_options = $this->convertPluginOptionsToModelOptions( $options );
|
||||
$result = $this->$function_name( $model_options );
|
||||
}
|
||||
|
||||
if ( empty( $result ) ) {
|
||||
$errors[] = ['errorInfo' => get_class($this) . " Failed to execute $flag_name properly."];
|
||||
$module_data[ $flag_name ] = INSTALL_STATUS_FAIL;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( 'uninstallResources' === $function_name ) {
|
||||
$module_data[ $flag_name ] = $result;
|
||||
continue;
|
||||
}
|
||||
|
||||
$module_data[ $flag_name ] = INSTALL_STATUS_UNINSTALLED;
|
||||
continue;
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
public function installModels( $options ) {
|
||||
$class = get_class($this);
|
||||
$nameArray = explode( '\\', $class );
|
||||
$name = array_pop( $nameArray );
|
||||
$directory = PLUGIN_DIRECTORY . lcfirst($name) . DIRECTORY_SEPARATOR . 'models' . DIRECTORY_SEPARATOR;
|
||||
if ( ! file_exists( $directory ) ) {
|
||||
Debug::log( 'models directory is empty' );
|
||||
return true;
|
||||
}
|
||||
$models = self::$installer->getModelList( $directory );
|
||||
$error = false;
|
||||
foreach ( $models as $model ) {
|
||||
$result = self::$installer->installModel( $model, $options, true, false );
|
||||
|
||||
if ( $result === false ) {
|
||||
$error = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ( $error ) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public function uninstallModels( $options ) {
|
||||
$class = get_class($this);
|
||||
$nameArray = explode( '\\', $class );
|
||||
$name = array_pop( $nameArray );
|
||||
$directory = PLUGIN_DIRECTORY . lcfirst($name) . DIRECTORY_SEPARATOR . 'models' . DIRECTORY_SEPARATOR;
|
||||
if ( ! file_exists( $directory ) ) {
|
||||
Debug::log( 'models directory is empty' );
|
||||
return true;
|
||||
}
|
||||
$models = self::$installer->getModelList( $directory );
|
||||
$error = false;
|
||||
foreach ( $models as $model ) {
|
||||
$result = self::$installer->uninstallModel( $model, $options, true, false );
|
||||
|
||||
if ( $result === false ) {
|
||||
$error = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ( $error ) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public function installPermissions( $options = '' ) {
|
||||
if ( empty( $this->permissionMatrix ) ) {
|
||||
Debug::log( 'permissionMatrix is empty' );
|
||||
return true;
|
||||
}
|
||||
$perms = new Permissions();
|
||||
foreach ( $this->permissionMatrix as $name => $details ) {
|
||||
$perms->add( $name, $details );
|
||||
}
|
||||
return $perms->save( true );
|
||||
}
|
||||
|
||||
public function uninstallPermissions( $options = '' ) {
|
||||
if ( empty( $this->permissionMatrix ) ) {
|
||||
Debug::log( 'permissionMatrix is empty' );
|
||||
return true;
|
||||
}
|
||||
$perms = new Permissions();
|
||||
foreach ( $this->permissionMatrix as $name => $details ) {
|
||||
$perms->remove( $name, true );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function installConfigs( $options = '' ) {
|
||||
if ( empty( $this->configMatrix ) || empty( $this->configName )) {
|
||||
Debug::log( 'configMatrix is empty' );
|
||||
return true;
|
||||
}
|
||||
$config = new Config( CONFIG_JSON );
|
||||
// should have some sort of DELTA functionality and safeguards
|
||||
$config->addCategory( $this->configName );
|
||||
foreach ( $this->configMatrix as $name => $details ) {
|
||||
$config->add( $this->configName, $name, $details );
|
||||
}
|
||||
return $config->save();
|
||||
}
|
||||
|
||||
public function uninstallConfigs( $options = '' ) {
|
||||
if ( empty( $this->configName ) ) {
|
||||
return true;
|
||||
}
|
||||
$config = new Config( CONFIG_JSON );
|
||||
return $config->removeCategory( $this->configName, true, true );
|
||||
}
|
||||
|
||||
public function installPreferences( $options = '' ) {
|
||||
$prefs = new Preferences();
|
||||
if ( empty( $this->preferenceMatrix ) ) {
|
||||
Debug::log( 'preferenceMatrix is empty' );
|
||||
return true;
|
||||
}
|
||||
foreach ( $this->preferenceMatrix as $name => $details ) {
|
||||
$prefs->add( $name, $details );
|
||||
}
|
||||
return $prefs->save( true );
|
||||
}
|
||||
|
||||
public function uninstallPreferences( $options = '' ) {
|
||||
if ( empty( $this->preferenceMatrix ) ) {
|
||||
Debug::log( 'preferenceMatrix is empty' );
|
||||
return true;
|
||||
}
|
||||
$prefs = new Preferences();
|
||||
foreach ( $this->preferenceMatrix as $name => $details ) {
|
||||
$prefs->remove( $name, true );
|
||||
}
|
||||
return $prefs->save( true );
|
||||
}
|
||||
|
||||
public function installResources( $options = '' ) {
|
||||
if ( empty( $this->resourceMatrix ) ) {
|
||||
Debug::log( 'resourceMatrix is empty' );
|
||||
return true;
|
||||
}
|
||||
$ids = [];
|
||||
foreach( $this->resourceMatrix as $tableName => $entries ) {
|
||||
foreach ( $entries as $entry ) {
|
||||
foreach ( $entry as $key => $value ) {
|
||||
if ( '{time}' == $value ) {
|
||||
$entry[$key] = time();
|
||||
}
|
||||
}
|
||||
self::$db->insert( $tableName, $entry );
|
||||
$id = self::$db->lastId();
|
||||
if ( $id ) {
|
||||
$ids[] = $id;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $ids;
|
||||
}
|
||||
|
||||
public function uninstallResources( $options = '' ) {
|
||||
if ( empty( $this->resourceMatrix ) ) {
|
||||
Debug::log( 'resourceMatrix is empty' );
|
||||
return true;
|
||||
}
|
||||
$ids = $this->module['resources_installed'];
|
||||
$data = [];
|
||||
foreach( $this->resourceMatrix as $tableName => $entries ) {
|
||||
foreach ($ids as $id) {
|
||||
$data[] = self::$db->delete( $tableName, $id );
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loaders
|
||||
*/
|
||||
public function loadAdminNav() {
|
||||
if ( !empty( $this->admin_links ) ) {
|
||||
foreach( $this->admin_links as $key => $link ) {
|
||||
Navigation::addLink( App::ADMIN_MENU_NAME, $link );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function loadMainNav() {
|
||||
if ( !empty( $this->main_links ) ) {
|
||||
foreach( $this->main_links as $key => $link ) {
|
||||
Navigation::addLink( App::MAIN_MENU_NAME, $link );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function loadFooterNav() {
|
||||
if ( !empty( $this->footer_links ) ) {
|
||||
foreach( $this->footer_links as $key => $link ) {
|
||||
Navigation::addLink( App::FOOTER_MENU_NAME, $link );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function loadFilters() {
|
||||
if ( ! empty( $this->filters ) ) {
|
||||
foreach( $this->filters as $filter ) {
|
||||
Filters::add( $filter['name'], $filter['find'], $filter['replace'], $filter['enabled'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function convertPluginOptionsToModelOptions( $options ) {
|
||||
$data = [];
|
||||
foreach (self::PLUGIN_FLAG_MAP as $pluginValue => $modelValue) {
|
||||
if ( isset( $options[$pluginValue] ) ) {
|
||||
$data[$modelValue] = $options[$pluginValue];
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
public static function getPluginDirectories( $forceRefresh = false ) {
|
||||
if ( !empty( self::$pluginFolders ) && true !== $forceRefresh ) {
|
||||
return self::$pluginFolders;
|
||||
}
|
||||
$pluginFolders = [];
|
||||
if ( ! PLUGINS_ENABLED && true !== $forceRefresh ) {
|
||||
Debug::warn('Plugins disabled');
|
||||
return $pluginFolders;
|
||||
}
|
||||
|
||||
if ( ! file_exists( PLUGIN_DIRECTORY ) ) {
|
||||
Debug::warn("Plugins folder is missing: $dir");
|
||||
return $pluginFolders;
|
||||
}
|
||||
|
||||
// get a list of all plugins in the plugin directory
|
||||
$pluginDirectories = scandir( PLUGIN_DIRECTORY );
|
||||
array_shift( $pluginDirectories ); // remove the .
|
||||
array_shift( $pluginDirectories ); // remove the ..
|
||||
|
||||
foreach ( $pluginDirectories as $key => $pluginName ) {
|
||||
$pluginDirectory = PLUGIN_DIRECTORY . $pluginName;
|
||||
if ( is_file( $pluginDirectory ) ) {
|
||||
continue; // skip any files in the main plugin directory if they exist
|
||||
}
|
||||
|
||||
// get a list of all directories in this plugin directory
|
||||
$pluginFolders[ $pluginName ] = [];
|
||||
$pluginDirectory .= DIRECTORY_SEPARATOR;
|
||||
$pluginDirectoryArray = scandir( $pluginDirectory );
|
||||
array_shift( $pluginDirectoryArray ); // remove the .
|
||||
array_shift( $pluginDirectoryArray ); // remove the ..
|
||||
|
||||
// loop over each sub-directory insider plugin directory
|
||||
foreach ( $pluginDirectoryArray as $key => $file ) {
|
||||
$currentFolder = $pluginDirectory . $file . DIRECTORY_SEPARATOR;
|
||||
switch ( $file ) {
|
||||
case 'controllers':
|
||||
case 'config':
|
||||
case 'models':
|
||||
case 'views':
|
||||
case 'templates':
|
||||
break;
|
||||
case 'forms.php':
|
||||
$currentFolder = rtrim( $currentFolder, DIRECTORY_SEPARATOR );
|
||||
break;
|
||||
case 'plugin.php':
|
||||
$currentFolder = rtrim( $currentFolder, DIRECTORY_SEPARATOR );
|
||||
break;
|
||||
default:
|
||||
continue 2; // break if we aren't looking for whatever we found
|
||||
}
|
||||
$pluginFolders[ $pluginName ][] = [ $currentFolder => $file ];
|
||||
}
|
||||
}
|
||||
|
||||
self::$pluginFolders = $pluginFolders;
|
||||
return self::$pluginFolders;
|
||||
}
|
||||
|
||||
public static function getActivePlugins( $forceRefresh = false ) {
|
||||
if ( ! empty( self::$pluginsActive ) && true !== $forceRefresh ) {
|
||||
return self::$pluginsActive;
|
||||
}
|
||||
if ( ! isset( self::$installer ) ) {
|
||||
self::$installer = new Installer();
|
||||
}
|
||||
$out = [];
|
||||
$plugins = self::$installer->getAvailablePlugins( $forceRefresh );
|
||||
|
||||
if ( ! empty( $plugins ) ) {
|
||||
foreach ( $plugins as $plugin ) {
|
||||
if ( !isset( $plugin->class_object )) {
|
||||
continue;
|
||||
}
|
||||
$installedPlugin = $plugin->class_object->module;
|
||||
if ( !isset( $installedPlugin['enabled'] ) || !$installedPlugin['enabled'] ) {
|
||||
continue;
|
||||
}
|
||||
$out[] = [
|
||||
$plugin->name => $installedPlugin['class'],
|
||||
];
|
||||
}
|
||||
}
|
||||
self::$pluginsActive = $out;
|
||||
return self::$pluginsActive;
|
||||
}
|
||||
|
||||
public static function enable( $name, $save = true ) {
|
||||
if ( ! isset( self::$installer ) ) {
|
||||
self::$installer = new Installer();
|
||||
}
|
||||
$module = self::$installer->getModule( $name );
|
||||
if ( empty( $module ) ) {
|
||||
Debug::warn( "plugin not found: $name" );
|
||||
return false;
|
||||
}
|
||||
if ( ! isset( $module['enabled'] ) ) {
|
||||
Debug::error( "plugin enabled not set: $name" );
|
||||
return false;
|
||||
}
|
||||
$module['enabled'] = true;
|
||||
return self::$installer->setModule( $name, $module, $save );
|
||||
}
|
||||
|
||||
public static function disable( $name, $save = true ) {
|
||||
if ( ! isset( self::$installer ) ) {
|
||||
self::$installer = new Installer();
|
||||
}
|
||||
$module = self::$installer->getModule( $name );
|
||||
if ( empty($module) ) {
|
||||
Debug::warn( "plugin not found: $name" );
|
||||
return false;
|
||||
}
|
||||
if ( ! isset( $module['enabled'] ) ) {
|
||||
Debug::error( "plugin not enabled: $name" );
|
||||
return false;
|
||||
}
|
||||
$module['enabled'] = false;
|
||||
return self::$installer->setModule( $name, $module, $save );
|
||||
}
|
||||
|
||||
public function checkEnabled() {
|
||||
$name = ucfirst( strtolower( $this->pluginName ) );
|
||||
if ( isset( $this->module['enabled'] ) ) {
|
||||
return $this->module['enabled'];
|
||||
}
|
||||
Debug::warn( "install not found: {$this->pluginName}" );
|
||||
return false;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user