plugin position for dashboard, new plugins for welcome message and visits

This commit is contained in:
Diego Najar 2021-03-19 15:54:09 -03:00
parent fc12ebadc8
commit adb84d792d
15 changed files with 240 additions and 116 deletions

View file

@ -296,6 +296,20 @@ class Plugin {
return $this->save(); return $this->save();
} }
public function configure($args)
{
foreach ($this->db as $field=>$value) {
if (isset($args[$field])) {
$finalValue = Sanitize::html( $args[$field] );
if ($finalValue==='false') { $finalValue = false; }
elseif ($finalValue==='true') { $finalValue = true; }
settype($finalValue, gettype($value));
$this->db[$field] = $finalValue;
}
}
return $this->save();
}
public function setField($field, $value) public function setField($field, $value)
{ {
$this->db[$field] = Sanitize::html($value); $this->db[$field] = Sanitize::html($value);

View file

@ -1,7 +1,7 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); <?php defined('BLUDIT') or die('Bludit CMS.');
// ============================================================================ // ============================================================================
// Check role // Authorization
// ============================================================================ // ============================================================================
checkRole(array('admin')); checkRole(array('admin'));
@ -11,19 +11,8 @@ checkRole(array('admin'));
// ============================================================================ // ============================================================================
// ============================================================================ // ============================================================================
// Main before POST // Main
// ============================================================================
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
changePluginsPosition(explode(',',$_POST['plugin-list']));
Redirect::page('plugins-position');
}
// ============================================================================
// POST Method
// ============================================================================ // ============================================================================
// ============================================================================ // HTML <title>
// Main after POST $layout['title'] = $L->g('Plugin') . ' - ' . $layout['title'];
// ============================================================================
// Title of the page
$layout['title'] .= ' - '.$L->g('Plugins');

View file

@ -27,7 +27,7 @@
<div id="dashboard" class="container-fluid"> <div id="dashboard" class="container-fluid">
<div class="row"> <div class="row">
<div class="col-7"> <div class="col-7">
<?php Theme::plugins('dashboard') ?> <?php execPluginsByHook('dashboard') ?>
</div> </div>
<div class="col-5"> <div class="col-5">

View file

@ -1,51 +1,80 @@
<?php defined('BLUDIT') or die('Bludit CMS.'); ?> <?php defined('BLUDIT') or die('Bludit CMS.'); ?>
<?php echo Bootstrap::formOpen(array('id'=>'jsform', 'class'=>'tab-content')); ?> <script>
// ============================================================================
// Variables for the view
// ============================================================================
<div class="align-middle"> // ============================================================================
<div class="float-end mt-1"> // Functions for the view
<button type="button" class="btn btn-primary btn-sm jsbuttonSave" name="save"><?php $L->p('Save') ?></button> // ============================================================================
<a class="btn btn-secondary btn-sm" href="<?php echo HTML_PATH_ADMIN_ROOT.'plugins' ?>" role="button"><?php $L->p('Cancel') ?></a> function changePluginsPosition() {
$("li.list-group-item").each(function(index, value) {
var args = {
position: index,
className: $(this).data("class-name")
};
console.log(index);
api.configurePlugin(args).then(function(response) {
if (response.status == 0) {
logs('Plugin configured: ' + response.data.key);
} else {
logs('An error occurred while trying to configured the plugin.');
showAlertError(response.message);
}
});
});
showAlertInfo("<?php $L->p('The changes have been saved') ?>");
}
// ============================================================================
// Events for the view
// ============================================================================
$(document).ready(function() {
$("#btnSave").on("click", function() {
changePluginsPosition();
});
});
// ============================================================================
// Initlization for the view
// ============================================================================
$(document).ready(function() {
$('.list-group-sortable').sortable({
placeholderClass: 'list-group-item'
});
});
</script>
<div class="d-flex align-items-center mb-4">
<h2 class="m-0"><i class="bi bi-arrow-down-up"></i><?php $L->p('Plugins position') ?></h2>
<div class="ms-auto">
<button id="btnSave" type="button" class="btn btn-primary btn-sm"><?php $L->p('Save') ?></button>
<a id="btnCancel" class="btn btn-secondary btn-sm" href="<?php echo HTML_PATH_ADMIN_ROOT . 'plugins' ?>" role="button"><?php $L->p('Cancel') ?></a>
</div> </div>
<?php echo Bootstrap::pageTitle(array('title'=>$L->g('Plugins position'), 'icon'=>'tags')); ?>
</div> </div>
<div class="alert alert-primary"><?php $L->p('Drag and Drop to sort the plugins') ?></div> <div class="alert alert-primary">
<?php $L->p('Drag and Drop to sort the plugins') ?>
</div>
<?php <?php echo Bootstrap::formTitle(array('title' => $L->g('Website plugins'))) ?>
// Token CSRF
echo Bootstrap::formInputHidden(array(
'name'=>'tokenCSRF',
'value'=>$security->getTokenCSRF()
));
echo Bootstrap::formInputHidden(array( <ul class="website-plugins list-group list-group-sortable">
'name'=>'plugin-list', <?php foreach ($plugins['siteSidebar'] as $plugin): ?>
'value'=>'' <li class="list-group-item" data-class-name="<?php echo $plugin->className() ?>">
)); <i class="bi bi-arrows-expand"></i><?php echo $plugin->name() ?>
</li>
<?php endforeach; ?>
</ul>
echo '<ul class="list-group list-group-sortable">'; <?php echo Bootstrap::formTitle(array('title' => $L->g('Dashboard plugins'))) ?>
foreach ($plugins['siteSidebar'] as $Plugin) {
echo '<li class="list-group-item" data-plugin="'.$Plugin->className().'"><span class="bi-arrows-v"></span> '.$Plugin->name().'</li>';
}
echo '</ul>';
?>
<?php echo Bootstrap::formClose(); ?> <ul class="dashboard-plugins list-group list-group-sortable">
<?php foreach ($plugins['dashboard'] as $plugin): ?>
<script> <li class="list-group-item" data-class-name="<?php echo $plugin->className() ?>">
$(document).ready(function() { <i class="bi bi-arrows-expand"></i><?php echo $plugin->name() ?>
$('.list-group-sortable').sortable({ </li>
placeholderClass: 'list-group-item' <?php endforeach; ?>
}); </ul>
$(".jsbuttonSave").on("click", function() {
var tmp = [];
$("li.list-group-item").each(function() {
tmp.push( $(this).attr("data-plugin") );
});
$("#jsplugin-list").attr("value", tmp.join(",") );
$("#jsform").submit();
});
});
</script>

View file

@ -9,11 +9,42 @@
// Functions for the view // Functions for the view
// ============================================================================ // ============================================================================
function configurePlugin(className) {
var args = {
className: className
};
$('input').each(function() {
var key = $(this).attr('name');
var value = $(this).val();
args[key] = value;
});
$('select').each(function() {
var key = $(this).attr('name');
var value = $(this).val();
args[key] = value;
});
api.configurePlugin(args).then(function(response) {
if (response.status == 0) {
logs('Plugin configured: ' + response.data.key);
showAlertInfo("<?php $L->p('The changes have been saved') ?>");
} else {
logs('An error occurred while trying to configured the plugin.');
showAlertError(response.message);
}
});
}
// ============================================================================ // ============================================================================
// Events for the view // Events for the view
// ============================================================================ // ============================================================================
$(document).ready(function() { $(document).ready(function() {
// No events for the view yet $('#btnSave').on('click', function() {
var className = $(this).data('class-name');
configurePlugin(className);
});
}); });
// ============================================================================ // ============================================================================
@ -24,29 +55,20 @@
}); });
</script> </script>
<?php echo Bootstrap::formOpen(array('name' => 'pluginSettings')); ?> <div class="d-flex align-items-center mb-4">
<div class="d-flex align-items-center mb-3">
<h2 class="m-0"><i class="bi bi-node-plus"></i><?php echo $plugin->name() ?></h2> <h2 class="m-0"><i class="bi bi-node-plus"></i><?php echo $plugin->name() ?></h2>
<?php if ($plugin->formButtons()) : ?> <?php if ($plugin->formButtons()) : ?>
<div class="ms-auto"> <div class="ms-auto">
<button type="submit" class="btn btn-primary btn-sm" name="save"><?php $L->p('Save') ?></button> <button id="btnSave" type="button" class="btn btn-primary btn-sm" data-class-name="<?php echo $plugin->className() ?>"><?php $L->p('Save') ?></button>
<a class="btn btn-secondary btn-sm" href="<?php echo HTML_PATH_ADMIN_ROOT . 'plugins' ?>" role="button"><?php $L->p('Cancel') ?></a> <a id="btnCancel" class="btn btn-secondary btn-sm" href="<?php echo HTML_PATH_ADMIN_ROOT . 'plugins' ?>" role="button"><?php $L->p('Cancel') ?></a>
</div> </div>
<?php endif; ?> <?php endif; ?>
</div> </div>
<?php <?php
echo Bootstrap::formInputHidden(array(
'name' => 'tokenCSRF',
'value' => $security->getTokenCSRF()
));
if ($plugin->description()) { if ($plugin->description()) {
echo '<div class="alert alert-primary" role="alert">'.$plugin->description().'</div>'; echo '<div class="alert alert-primary" role="alert">'.$plugin->description().'</div>';
} }
echo $plugin->form(); echo $plugin->form();
?> ?>
<?php echo Bootstrap::formClose(); ?>

View file

@ -9,9 +9,9 @@
// Functions for the view // Functions for the view
// ============================================================================ // ============================================================================
function activatePlugin(pluginClassName) { function activatePlugin(className) {
var args = { var args = {
pluginClassName: pluginClassName className: className
}; };
api.activatePlugin(args).then(function(response) { api.activatePlugin(args).then(function(response) {
if (response.status == 0) { if (response.status == 0) {
@ -24,9 +24,9 @@
}); });
} }
function deactivatePlugin(pluginClassName) { function deactivatePlugin(className) {
var args = { var args = {
pluginClassName: pluginClassName className: className
}; };
api.deactivatePlugin(args).then(function(response) { api.deactivatePlugin(args).then(function(response) {
if (response.status == 0) { if (response.status == 0) {
@ -59,13 +59,13 @@
}); });
$('.activatePlugin').on('click', function() { $('.activatePlugin').on('click', function() {
var pluginClassName = $(this).data('class-name'); var className = $(this).data('class-name');
activatePlugin(pluginClassName); activatePlugin(className);
}); });
$('.deactivatePlugin').on('click', function() { $('.deactivatePlugin').on('click', function() {
var pluginClassName = $(this).data('class-name'); var className = $(this).data('class-name');
deactivatePlugin(pluginClassName); deactivatePlugin(className);
}); });
}); });

View file

@ -129,6 +129,12 @@ function buildPlugins()
return $a->position()>$b->position(); return $a->position()>$b->position();
} }
); );
// Sort the plugins by the position for the dashboard
uasort($plugins['dashboard'], function ($a, $b) {
return $a->position()>$b->position();
}
);
} }
} }

View file

@ -600,19 +600,19 @@ function uploadPageFile($pageKey) {
/* Install and activate a plugin === Bludit v4 /* Install and activate a plugin === Bludit v4
@pluginClassName string The plugin PHP class name @className string The plugin PHP class name
@return string/bool Returns TRUE on successful install, FALSE otherwise @return string/bool Returns TRUE on successful install, FALSE otherwise
*/ */
function activatePlugin($pluginClassName) { function activatePlugin($className) {
global $plugins; global $plugins;
global $syslog; global $syslog;
if (!isset($plugins['all'][$pluginClassName])) { if (!isset($plugins['all'][$className])) {
Log::set(__FUNCTION__.LOG_SEP.'The plugin doesn\'t exist: '.$pluginClassName, LOG_TYPE_ERROR); Log::set(__FUNCTION__.LOG_SEP.'The plugin doesn\'t exist: '.$className, LOG_TYPE_ERROR);
return false; return false;
} }
$plugin = $plugins['all'][$pluginClassName]; $plugin = $plugins['all'][$className];
if ($plugin->install()) { if ($plugin->install()) {
$syslog->add(array( $syslog->add(array(
'dictionaryKey'=>'plugin-activated', 'dictionaryKey'=>'plugin-activated',
@ -628,19 +628,19 @@ function activatePlugin($pluginClassName) {
/* Uninstall and deactivate a plugin === Bludit v4 /* Uninstall and deactivate a plugin === Bludit v4
@pluginClassName string The plugin PHP class name @className string The plugin PHP class name
@return string/bool Returns TRUE on successful install, FALSE otherwise @return string/bool Returns TRUE on successful install, FALSE otherwise
*/ */
function deactivatePlugin($pluginClassName) { function deactivatePlugin($className) {
global $plugins; global $plugins;
global $syslog; global $syslog;
if (!isset($plugins['all'][$pluginClassName])) { if (!isset($plugins['all'][$className])) {
Log::set(__FUNCTION__.LOG_SEP.'The plugin doesn\'t exist: '.$pluginClassName, LOG_TYPE_ERROR); Log::set(__FUNCTION__.LOG_SEP.'The plugin doesn\'t exist: '.$className, LOG_TYPE_ERROR);
return false; return false;
} }
$plugin = $plugins['all'][$pluginClassName]; $plugin = $plugins['all'][$className];
if ($plugin->uninstall()) { if ($plugin->uninstall()) {
$syslog->add(array( $syslog->add(array(
'dictionaryKey'=>'plugin-deactivated', 'dictionaryKey'=>'plugin-deactivated',
@ -654,6 +654,34 @@ function deactivatePlugin($pluginClassName) {
return false; return false;
} }
/* Change plugins settings === Bludit v4
@args array The array $args supports all the keys from the plugin database
@return bool Returns TRUE on successful configure, FALSE otherwise
*/
function configurePlugin($args) {
global $plugins;
global $syslog;
// Plugin class name
$className = $args['className'];
// Check if the plugin exists
if (!isset($plugins['all'][$className])) {
Log::set(__FUNCTION__.LOG_SEP.'The plugin doesn\'t exist: '.$className, LOG_TYPE_ERROR);
return false;
}
$plugin = $plugins['all'][$className];
$plugin->configure($args);
$syslog->add(array(
'dictionaryKey'=>'plugin-configured',
'notes'=>$plugin->name()
));
Log::set(__FUNCTION__.LOG_SEP.'Plugin configured: '.$className, LOG_TYPE_INFO);
return true;
}
// Re-index database of categories // Re-index database of categories
// If you create/edit/remove a page is necessary regenerate the database of categories // If you create/edit/remove a page is necessary regenerate the database of categories
function reindexCategories() { function reindexCategories() {
@ -878,27 +906,7 @@ function deactivateAllPlugin() {
return false; return false;
} }
function changePluginsPosition($pluginClassList) {
global $plugins;
global $syslog;
global $L;
foreach ($pluginClassList as $position=>$pluginClassName) {
if (isset($plugins['all'][$pluginClassName])) {
$plugin = $plugins['all'][$pluginClassName];
$plugin->setPosition(++$position);
}
}
// Add to syslog
$syslog->add(array(
'dictionaryKey'=>'plugins-sorted',
'notes'=>''
));
Alert::set($L->g('The changes have been saved'));
return true;
}
// Execute the plugins by hook // Execute the plugins by hook
function execPluginsByHook($hook, $args = array()) { function execPluginsByHook($hook, $args = array()) {

View file

@ -48,28 +48,32 @@ class HTML {
public static function jquery() public static function jquery()
{ {
// https://jquery.com/
return '<script src="'.DOMAIN_CORE_VENDORS.'jquery/jquery.min.js?version='.BLUDIT_VERSION.'"></script>'.PHP_EOL; return '<script src="'.DOMAIN_CORE_VENDORS.'jquery/jquery.min.js?version='.BLUDIT_VERSION.'"></script>'.PHP_EOL;
} }
public static function jsBootstrap($attributes='') public static function jsBootstrap($attributes='')
{ {
// https://getbootstrap.com/
return '<script '.$attributes.' src="'.DOMAIN_CORE_VENDORS.'bootstrap/bootstrap.bundle.min.js?version='.BLUDIT_VERSION.'"></script>'.PHP_EOL; return '<script '.$attributes.' src="'.DOMAIN_CORE_VENDORS.'bootstrap/bootstrap.bundle.min.js?version='.BLUDIT_VERSION.'"></script>'.PHP_EOL;
} }
public static function cssBootstrap() public static function cssBootstrap()
{ {
// https://getbootstrap.com/
return '<link rel="stylesheet" type="text/css" href="'.DOMAIN_CORE_VENDORS.'bootstrap/bootstrap.min.css?version='.BLUDIT_VERSION.'">'.PHP_EOL; return '<link rel="stylesheet" type="text/css" href="'.DOMAIN_CORE_VENDORS.'bootstrap/bootstrap.min.css?version='.BLUDIT_VERSION.'">'.PHP_EOL;
} }
public static function cssBootstrapIcons() public static function cssBootstrapIcons()
{ {
// https://icons.getbootstrap.com/
return '<link rel="stylesheet" type="text/css" href="'.DOMAIN_CORE_VENDORS.'bootstrap-icons/bootstrap-icons.css?version='.BLUDIT_VERSION.'">'.PHP_EOL; return '<link rel="stylesheet" type="text/css" href="'.DOMAIN_CORE_VENDORS.'bootstrap-icons/bootstrap-icons.css?version='.BLUDIT_VERSION.'">'.PHP_EOL;
} }
public static function jsSortable($attributes='') public static function jsSortable($attributes='')
{ {
// https://github.com/psfpro/bootstrap-html5sortable // https://github.com/psfpro/bootstrap-html5sortable
return '<script '.$attributes.' src="'.DOMAIN_CORE_JS.'jquery.sortable.min.js?version='.BLUDIT_VERSION.'"></script>'.PHP_EOL; return '<script '.$attributes.' src="'.DOMAIN_CORE_VENDORS.'bootstrap-html5sortable/jquery.sortable.min.js?version='.BLUDIT_VERSION.'"></script>'.PHP_EOL;
} }
} }

View file

@ -321,7 +321,7 @@ class API {
@return string @return string
*/ */
async activatePlugin(args) { async activatePlugin(args) {
var url = this.apiURL + "plugins/" + args['pluginClassName']; var url = this.apiURL + "plugins/" + args['className'];
var body = Object.assign({}, this.body, args); var body = Object.assign({}, this.body, args);
try { try {
var response = await fetch(url, { var response = await fetch(url, {
@ -340,13 +340,13 @@ class API {
} }
} }
/* Uninstall and deactivate a plugin === Bludit v4 /* Deactivate and uninstall a plugin === Bludit v4
@args array @args array
@return string @return string
*/ */
async deactivatePlugin(args) { async deactivatePlugin(args) {
var url = this.apiURL + "plugins/" + args['pluginClassName']; var url = this.apiURL + "plugins/" + args['className'];
var body = Object.assign({}, this.body, args); var body = Object.assign({}, this.body, args);
try { try {
var response = await fetch(url, { var response = await fetch(url, {
@ -365,4 +365,29 @@ class API {
} }
} }
/* Configure a plugin
@args array Arguments can be any of the fields from the plugin database
@return string The plugin class name
*/
async configurePlugin(args) {
var url = this.apiURL + "plugins/" + args['className'];
var body = Object.assign({}, this.body, args);
try {
var response = await fetch(url, {
credentials: "same-origin",
method: "PUT",
body: JSON.stringify(body),
headers: new Headers({
"Content-Type": "application/json"
})
});
var json = await response.json();
return json;
} catch (err) {
console.log(err);
return true;
}
}
} }

View file

@ -397,5 +397,7 @@
"are-you-sure-you-want-to-delete-this-user": "Are you sure you want to delete this user?", "are-you-sure-you-want-to-delete-this-user": "Are you sure you want to delete this user?",
"are-you-sure-you-want-to-delete-this-page": "Are you sure you want to delete this page?", "are-you-sure-you-want-to-delete-this-page": "Are you sure you want to delete this page?",
"are-you-sure-you-want-to-delete-this-category?": "Are you sure you want to delete this category?", "are-you-sure-you-want-to-delete-this-category?": "Are you sure you want to delete this category?",
"are-you-sure-you-want-to-change-the-password?": "Are you sure you want to change the password?" "are-you-sure-you-want-to-change-the-password?": "Are you sure you want to change the password?",
"website-plugins": "Website plugins",
"dashboard-plugins": "Dashboard plugins"
} }

View file

@ -283,6 +283,11 @@ class pluginAPI extends Plugin {
$pluginClassName = $parmB; $pluginClassName = $parmB;
$data = $this->deactivatePlugin($pluginClassName); $data = $this->deactivatePlugin($pluginClassName);
} }
// (PUT) /api/plugins/:key
elseif ( ($method==='PUT') && ($parmA==='plugins') && !empty($parmB) ) {
$inputs['className'] = $parmB;
$data = $this->configurePlugin($inputs);
}
// (GET) /api/helper/:name // (GET) /api/helper/:name
elseif ( ($method==='GET') && ($parmA==='helper') && !empty($parmB) ) { elseif ( ($method==='GET') && ($parmA==='helper') && !empty($parmB) ) {
$name = $parmB; $name = $parmB;
@ -1009,4 +1014,24 @@ class pluginAPI extends Plugin {
'message'=>'An error occurred while trying to uninstall the plugin.' 'message'=>'An error occurred while trying to uninstall the plugin.'
); );
} }
/* Configure a plugin === Bludit v4
Referer to the function configurePlugin() from functions.php
*/
private function configurePlugin($args)
{
if (configurePlugin($args)) {
return array(
'status'=>'0',
'message'=>'Plugin configured.',
'data'=>array('key'=>$args['className'])
);
}
return array(
'status'=>'1',
'message'=>'An error occurred while trying to configure the plugin.'
);
}
} }

View file

@ -51,7 +51,7 @@ class pluginVisitsStats extends Plugin {
$labelUnique = $L->g('Unique'); $labelUnique = $L->g('Unique');
return <<<EOF return <<<EOF
<div class="pluginVisitsStats"> <div class="pluginVisitsStats mb-4">
<h3 class="m-0 p-0"><i class="bi bi-bar-chart"></i>$label</h3> <h3 class="m-0 p-0"><i class="bi bi-bar-chart"></i>$label</h3>
<canvas id="visits-stats"></canvas> <canvas id="visits-stats"></canvas>
</div> </div>

View file

@ -26,8 +26,8 @@ class pluginWelcome extends Plugin {
$labelGoodNight = $L->g('good-night'); $labelGoodNight = $L->g('good-night');
return <<<EOF return <<<EOF
<div class="pluginWelcome"> <div class="pluginWelcome mb-4">
<h2 id="hello-message" class="m-0 p-0"><i class="bi bi-emoji-laughing"></i>Welcome</h3> <h2 id="hello-message" class="m-0 p-0"><i class="bi bi-emoji-laughing"></i>Welcome</h2>
</div> </div>
<script> <script>