1
0
Fork 0
mirror of https://github.com/DanielnetoDotCom/YouPHPTube synced 2025-10-03 09:49:28 +02:00

Now you can create plugins directly from the AVideo

This commit is contained in:
Daniel Neto 2024-11-14 15:26:44 -03:00
parent 011066baa9
commit bcd92a864c
7 changed files with 448 additions and 262 deletions

View file

@ -1,265 +1,227 @@
<?php
require_once __DIR__.'/../videos/configuration.php';
header('Content-Type: application/json');
if(!User::isAdmin()){
forbiddenPage('You Must be admin');
}
if(!empty($global['disableAdvancedConfigurations'])){
forbiddenPage('Configuration disabled');
}
use iamcal\SQLParser;
$parser = new SQLParser();
try {
$parser = new SQLParser();
$pluginName = $_REQUEST['pluginName'];
$sql = $_REQUEST['createTableSQL'];
// Plugin name and SQL file (replace these with dynamic input as needed)
$pluginName = $_REQUEST['pluginName'];
$sql = $_REQUEST['createTableSQL'];
$parser->parse($sql);
//var_dump($parser->tables);exit;
$pluginDir = __DIR__."/plugins/{$pluginName}/";
echo $pluginDir, PHP_EOL;
_mkdir($pluginDir);
$pluginDirInstall = "{$pluginDir}/install/";
_mkdir($pluginDirInstall);
file_put_contents($pluginDirInstall . "install.sql", $sql);
$pluginDirObjects = "{$pluginDir}/Objects/";
_mkdir($pluginDirObjects);
$pluginDirView = "{$pluginDir}/View/";
_mkdir($pluginDirView);
$includeTables = array();
$editorNavTabs = array();
$editorNavContent = array();
$active = true;
foreach ($parser->tables as $value) {
$classname = ucwords($value['name']);
$tableName = ucwords(str_replace("_", " ", $value['name']));
$editorNavTabs[] = "<li class=\"" . ($active ? "active" : "") . "\"><a data-toggle=\"tab\" href=\"#{$classname}\"><?php echo __(\"{$tableName}\"); ?></a></li>";
$editorNavContent[] = "<div id=\"{$classname}\" class=\"tab-pane fade " . ($active ? "in active" : "") . "\" style=\"padding: 10px;\">
<?php
include \$global['systemRootPath'] . 'plugin/{$pluginName}/View/{$classname}/index_body.php';
?>
</div>";
$active = false;
$includeTables[] = "require_once \$global['systemRootPath'] . 'plugin/{$pluginName}/Objects/{$classname}.php';";
$columnsVars = array();
$columnsString = array();
$columnsGet = array();
$columnsSet = array();
$columnsForm = array();
$columnsFooter = array();
$columnsGrid = array();
$columnsClearJQuery = array();
$columnsDatatable = array();
$columnsEdit = array();
$columnsAdd = array();
$columnsGetAll = array();
foreach ($value['fields'] as $value2) {
if ($value2['name'] == 'created' || $value2['name'] == 'modified') {
continue;
}
$columnsVars[] = '$' . $value2['name'];
$type = strtolower($value2['type']);
if ($type == 'text' || $type == 'varchar') {
$columnsString[] = "'{$value2['name']}'";
}
$fieldName = ucwords(str_replace("_", " ", $value2['name']));
$columnsClearJQuery[] = "$('#{$classname}{$value2['name']}').val('');";
$columnsEdit[] = "$('#{$classname}{$value2['name']}').val(data.{$value2['name']});";
if ($value2['name'] != 'id') {
$columnsAdd[] = "\$o->set" . ucfirst($value2['name']) . "(\$_POST['{$value2['name']}']);";
}
if ($type == 'int' || $type == 'tinyint') {
$columnsGet[] = "
function get" . ucfirst($value2['name']) . "() {
return intval(\$this->{$value2['name']});
} ";
$columnsSet[] = "
function set" . ucfirst($value2['name']) . "(\${$value2['name']}) {
\$this->{$value2['name']} = intval(\${$value2['name']});
} ";
} else if ($type == 'float') {
$columnsGet[] = "
function get" . ucfirst($value2['name']) . "() {
return floatval(\$this->{$value2['name']});
} ";
$columnsSet[] = "
function set" . ucfirst($value2['name']) . "(\${$value2['name']}) {
\$this->{$value2['name']} = floatval(\${$value2['name']});
} ";
} else {
$columnsGet[] = "
function get" . ucfirst($value2['name']) . "() {
return \$this->{$value2['name']};
} ";
$columnsSet[] = "
function set" . ucfirst($value2['name']) . "(\${$value2['name']}) {
\$this->{$value2['name']} = \${$value2['name']};
} ";
}
if(preg_match("/^(.*)_id/i", $value2['name'], $matches)){
$columnsGetAll[] = "static function getAll" . ucfirst($matches[1]) . "() {
global \$global;
\$table = \"{$matches[1]}\";
\$sql = \"SELECT * FROM {\$table} WHERE 1=1 \";
\$sql .= self::getSqlFromPost();
\$res = sqlDAL::readSql(\$sql);
\$fullData = sqlDAL::fetchAllAssoc(\$res);
sqlDAL::close(\$res);
\$rows = array();
if (\$res != false) {
foreach (\$fullData as \$row) {
\$rows[] = \$row;
}
} else {
/**
*
* @var array \$global
* @var object \$global['mysqli']
*/
_error_log(\$sql . ' Error : (' . \$global['mysqli']->errno . ') ' . \$global['mysqli']->error);
}
return \$rows;
}";
$columnsForm[] = '<div class="form-group col-sm-12">
<label for="' . $classname . $value2['name'] . '"><?php echo __("' . $fieldName . '"); ?>:</label>
<select class="form-control input-sm" name="' . $value2['name'] . '" id="' . $classname . $value2['name'] . '">
<?php
$options = '.$classname.'::getAll' . ucfirst($matches[1]) . '();
foreach ($options as $value) {
echo \'<option value="\'.$value[\'id\'].\'">\'.$value[\'id\'].\'</option>\';
}
?>
</select>
</div>';
}else if ($value2['name'] == 'id') {
$columnsGrid[] = "<th>#</th>";
$columnsDatatable[] = '{"data": "id"}';
$columnsForm[] = '<input type="hidden" name="id" id="' . $classname . 'id" value="" >';
} else if ($value2['name'] == 'status') {
$columnsGrid[] = '<th><?php echo __("' . $fieldName . '"); ?></th>';
$columnsDatatable[] = '{"data": "' . $value2['name'] . '"}';
$columnsForm[] = '<div class="form-group col-sm-12">
<label for="status"><?php echo __("Status"); ?>:</label>
<select class="form-control input-sm" name="status" id="' . $classname . 'status">
<option value="a"><?php echo __("Active"); ?></option>
<option value="i"><?php echo __("Inactive"); ?></option>
</select>
</div>';
} else {
$columnsGrid[] = '<th><?php echo __("' . $fieldName . '"); ?></th>';
$columnsDatatable[] = '{"data": "' . $value2['name'] . '"}';
if($type == 'text'){
$columnsForm[] = '<div class="form-group col-sm-12">
<label for="' . $classname . $value2['name'] . '"><?php echo __("' . $fieldName . '"); ?>:</label>
<textarea id="' . $classname . $value2['name'] . '" name="' . $value2['name'] . '" class="form-control input-sm" placeholder="<?php echo __("' . $fieldName . '"); ?>" required="true"></textarea>
</div>';
}else if($type == 'int'){
$columnsForm[] = '<div class="form-group col-sm-12">
<label for="' . $classname . $value2['name'] . '"><?php echo __("' . $fieldName . '"); ?>:</label>
<input type="number" step="1" id="' . $classname . $value2['name'] . '" name="' . $value2['name'] . '" class="form-control input-sm" placeholder="<?php echo __("' . $fieldName . '"); ?>" required="true">
</div>';
}else if($type == 'float'){
$columnsForm[] = '<div class="form-group col-sm-12">
<label for="' . $classname . $value2['name'] . '"><?php echo __("' . $fieldName . '"); ?>:</label>
<input type="number" step="0.01" id="' . $classname . $value2['name'] . '" name="' . $value2['name'] . '" class="form-control input-sm" placeholder="<?php echo __("' . $fieldName . '"); ?>" required="true">
</div>';
}else if($type == 'datetime'){
$columnsForm[] = '<div class="form-group col-sm-12">
<label for="' . $classname . $value2['name'] . '"><?php echo __("' . $fieldName . '"); ?>:</label>
<input type="text" id="' . $classname . $value2['name'] . '" name="' . $value2['name'] . '" class="form-control input-sm" placeholder="<?php echo __("' . $fieldName . '"); ?>" required="true" autocomplete="off">
</div>';
$columnsFooter[] = '<script> $(document).ready(function () {$(\'#' . $classname . $value2['name'] . '\').datetimepicker({format: \'yyyy-mm-dd hh:ii\',autoclose: true });});</script>';
}else{
$columnsForm[] = '<div class="form-group col-sm-12">
<label for="' . $classname . $value2['name'] . '"><?php echo __("' . $fieldName . '"); ?>:</label>
<input type="text" id="' . $classname . $value2['name'] . '" name="' . $value2['name'] . '" class="form-control input-sm" placeholder="<?php echo __("' . $fieldName . '"); ?>" required="true">
</div>';
}
}
// Sanitize and format plugin name
$pluginName = preg_replace('/[^a-zA-Z0-9_]/', '', ucfirst($pluginName));
if (!preg_match('/^[A-Z][A-Za-z0-9_]*$/', $pluginName)) {
throw new Exception('Invalid plugin name. It must start with an uppercase letter and contain only letters, numbers, and underscores.');
}
$templatesDir = __DIR__.'/templates/';
$parser->parse($sql);
$classFile = "{$pluginDirObjects}{$classname}.php";
$modelTemplate = file_get_contents("{$templatesDir}model.php");
$search = array('{classname}', '{tablename}', '{pluginName}', '{columnsVars}', '{columnsString}', '{columnsGetAll}', '{columnsGet}', '{columnsSet}');
$replace = array($classname, $value['name'], $pluginName, implode(",", $columnsVars), implode(",", $columnsString), implode(PHP_EOL, $columnsGetAll), implode(PHP_EOL, $columnsGet), implode(PHP_EOL, $columnsSet));
$data = str_replace($search, $replace, $modelTemplate);
file_put_contents($classFile, $data);
// Define plugin directories
$pluginZip = "plugins/{$pluginName}.zip";
$pluginDir = "plugins/{$pluginName}/";
_mkdir($pluginDir);
$pluginDirInstall = "{$pluginDir}install/";
_mkdir($pluginDirInstall);
$installFilePath = $pluginDirInstall . "install.sql";
file_put_contents($installFilePath, $sql);
$response['createdFiles'][] = $installFilePath;
$dir = "{$pluginDirView}{$classname}/";
_mkdir($dir);
$pluginDirObjects = "{$pluginDir}Objects/";
_mkdir($pluginDirObjects);
$file = "{$dir}index.php";
$modelTemplate = file_get_contents("{$templatesDir}index.php");
$search = array('{classname}', '{pluginName}');
$replace = array($classname, $pluginName);
$data = str_replace($search, $replace, $modelTemplate);
file_put_contents($file, $data);
$pluginDirView = "{$pluginDir}View/";
_mkdir($pluginDirView);
$file = "{$dir}index_body.php";
$modelTemplate = file_get_contents("{$templatesDir}index_body.php");
$search = array('{classname}','{tablename}', '{pluginName}', '{columnsForm}', '{columnsFooter}', '{columnsGrid}', '{$columnsClearJQuery}', '{columnsDatatable}', '{$columnsEdit}');
$replace = array($classname,$value['name'], $pluginName, implode(PHP_EOL, $columnsForm), implode(PHP_EOL, $columnsFooter), implode(PHP_EOL, $columnsGrid), implode(PHP_EOL, $columnsClearJQuery), implode("," . PHP_EOL, $columnsDatatable), implode(PHP_EOL, $columnsEdit));
$data = str_replace($search, $replace, $modelTemplate);
file_put_contents($file, $data);
// Initialize arrays to build templates and file paths
$includeTables = [];
$editorNavTabs = [];
$editorNavContent = [];
$active = true;
$response['tables'] = array();
$file = "{$dir}list.json.php";
$modelTemplate = file_get_contents("{$templatesDir}list.json.php");
$search = array('{classname}', '{pluginName}');
$replace = array($classname, $pluginName);
$data = str_replace($search, $replace, $modelTemplate);
file_put_contents($file, $data);
// Process each table found in SQL
foreach ($parser->tables as $table) {
$tableName = $table['name'];
$response['tables'][] = $tableName; // Add table name to response
$file = "{$dir}delete.json.php";
$modelTemplate = file_get_contents("{$templatesDir}delete.json.php");
$search = array('{classname}', '{pluginName}');
$replace = array($classname, $pluginName);
$data = str_replace($search, $replace, $modelTemplate);
file_put_contents($file, $data);
$classname = ucwords($tableName);
$includeTables[] = "require_once \$global['systemRootPath'] . 'plugin/{$pluginName}/Objects/{$classname}.php';";
// HTML for editor navigation
$editorNavTabs[] = "<li class=\"" . ($active ? "active" : "") . "\"><a data-toggle=\"tab\" href=\"#{$classname}\"><?php echo __(\"{$tableName}\"); ?></a></li>";
$editorNavContent[] = "<div id=\"{$classname}\" class=\"tab-pane fade " . ($active ? "in active" : "") . "\" style=\"padding: 10px;\">
<?php include \$global['systemRootPath'] . 'plugin/{$pluginName}/View/{$classname}/index_body.php'; ?>
</div>";
$active = false;
$file = "{$dir}add.json.php";
$modelTemplate = file_get_contents("{$templatesDir}add.json.php");
$search = array('{classname}', '{pluginName}', '{columnsAdd}');
$replace = array($classname, $pluginName, implode(PHP_EOL, $columnsAdd));
$data = str_replace($search, $replace, $modelTemplate);
file_put_contents($file, $data);
// Initialize column-specific arrays
$columnsVars = [];
$columnsString = [];
$columnsGet = [];
$columnsSet = [];
$columnsForm = [];
$columnsFooter = [];
$columnsGrid = [];
$columnsClearJQuery = [];
$columnsDatatable = [];
$columnsEdit = [];
$columnsAdd = [];
$columnsGetAll = [];
// Process each field in the table
foreach ($table['fields'] as $field) {
if ($field['name'] === 'created' || $field['name'] === 'modified') {
continue;
}
// Initialize fields
$columnsVars[] = '$' . $field['name'];
$type = strtolower($field['type']);
$fieldName = ucwords(str_replace("_", " ", $field['name']));
if ($type === 'text' || $type === 'varchar') {
$columnsString[] = "'{$field['name']}'";
}
// Generate field-related template replacements based on type
if ($field['name'] != 'id') {
$columnsAdd[] = "\$o->set" . ucfirst($field['name']) . "(\$_POST['{$field['name']}']);";
}
if ($type == 'int' || $type == 'tinyint') {
$columnsGet[] = "function get" . ucfirst($field['name']) . "() { return intval(\$this->{$field['name']}); }";
$columnsSet[] = "function set" . ucfirst($field['name']) . "(\${$field['name']}) { \$this->{$field['name']} = intval(\${$field['name']}); }";
} elseif ($type == 'float') {
$columnsGet[] = "function get" . ucfirst($field['name']) . "() { return floatval(\$this->{$field['name']}); }";
$columnsSet[] = "function set" . ucfirst($field['name']) . "(\${$field['name']}) { \$this->{$field['name']} = floatval(\${$field['name']}); }";
} else {
$columnsGet[] = "function get" . ucfirst($field['name']) . "() { return \$this->{$field['name']}; }";
$columnsSet[] = "function set" . ucfirst($field['name']) . "(\${$field['name']}) { \$this->{$field['name']} = \${$field['name']}; }";
}
// Example code for creating getAll functions based on field name pattern
if (preg_match("/^(.*)_id/i", $field['name'], $matches)) {
$columnsGetAll[] = "static function getAll" . ucfirst($matches[1]) . "() {
global \$global;
\$table = \"{$matches[1]}\";
\$sql = \"SELECT * FROM {\$table} WHERE 1=1 \";
\$res = sqlDAL::readSql(\$sql);
\$rows = sqlDAL::fetchAllAssoc(\$res);
sqlDAL::close(\$res);
return \$rows;
}";
}
}
// Create class and view files for each table
$classFile = "{$pluginDirObjects}{$classname}.php";
$modelTemplate = file_get_contents("templates/model.php");
$data = str_replace(
['{classname}', '{tablename}', '{pluginName}', '{columnsVars}', '{columnsString}', '{columnsGetAll}', '{columnsGet}', '{columnsSet}'],
[$classname, $tableName, $pluginName, implode(",", $columnsVars), implode(",", $columnsString), implode(PHP_EOL, $columnsGetAll), implode(PHP_EOL, $columnsGet), implode(PHP_EOL, $columnsSet)],
$modelTemplate
);
file_put_contents($classFile, $data);
$response['createdFiles'][] = $classFile;
$dir = "{$pluginDirView}{$classname}/";
_mkdir($dir);
// index.php
$indexFile = "{$dir}index.php";
$indexTemplate = file_get_contents("templates/index.php");
$indexData = str_replace(['{classname}', '{pluginName}'], [$classname, $pluginName], $indexTemplate);
file_put_contents($indexFile, $indexData);
$response['createdFiles'][] = $indexFile;
// index_body.php
$indexBodyFile = "{$dir}index_body.php";
$indexBodyTemplate = file_get_contents("templates/index_body.php");
$indexBodyData = str_replace(
['{classname}', '{tablename}', '{pluginName}', '{columnsForm}', '{columnsFooter}', '{columnsGrid}', '{$columnsClearJQuery}', '{columnsDatatable}', '{$columnsEdit}'],
[$classname, $tableName, $pluginName, implode(PHP_EOL, $columnsForm), implode(PHP_EOL, $columnsFooter), implode(PHP_EOL, $columnsGrid), implode(PHP_EOL, $columnsClearJQuery), implode("," . PHP_EOL, $columnsDatatable), implode(PHP_EOL, $columnsEdit)],
$indexBodyTemplate
);
file_put_contents($indexBodyFile, $indexBodyData);
$response['createdFiles'][] = $indexBodyFile;
// list.json.php
$listFile = "{$dir}list.json.php";
$listTemplate = file_get_contents("templates/list.json.php");
$listData = str_replace(['{classname}', '{pluginName}'], [$classname, $pluginName], $listTemplate);
file_put_contents($listFile, $listData);
$response['createdFiles'][] = $listFile;
// delete.json.php
$deleteFile = "{$dir}delete.json.php";
$deleteTemplate = file_get_contents("templates/delete.json.php");
$deleteData = str_replace(['{classname}', '{pluginName}'], [$classname, $pluginName], $deleteTemplate);
file_put_contents($deleteFile, $deleteData);
$response['createdFiles'][] = $deleteFile;
// add.json.php
$addFile = "{$dir}add.json.php";
$addTemplate = file_get_contents("templates/add.json.php");
$addData = str_replace(['{classname}', '{pluginName}', '{columnsAdd}'], [$classname, $pluginName, implode(PHP_EOL, $columnsAdd)], $addTemplate);
file_put_contents($addFile, $addData);
$response['createdFiles'][] = $addFile;
}
// Finalize main plugin and editor files
$pluginFile = "{$pluginDir}{$pluginName}.php";
$pluginTemplate = file_get_contents("templates/plugin.php");
$pluginData = str_replace(
['{pluginName}', '{includeTables}', '{tablename}', '{uid}'],
[$pluginName, implode(PHP_EOL, $includeTables), $pluginName, uniqid()],
$pluginTemplate
);
file_put_contents($pluginFile, $pluginData);
$response['createdFiles'][] = $pluginFile;
$editorFile = "{$pluginDir}View/editor.php";
$editorTemplate = file_get_contents("templates/editor.php");
$editorData = str_replace(
['{pluginName}', '{editorNavTabs}', '{editorNavContent}'],
[$pluginName, implode(PHP_EOL, $editorNavTabs), implode(PHP_EOL, $editorNavContent)],
$editorTemplate
);
file_put_contents($editorFile, $editorData);
$response['createdFiles'][] = $editorFile;
// Populate response with plugin details
$response['pluginName'] = $pluginName;
$response['pluginDir'] = $pluginDir;
$response['msg'] = "Plugin '{$pluginName}' created successfully.";
$response['zipDirectory'] = zipDirectory( __DIR__."/{$pluginDir}", __DIR__."/{$pluginZip}");
$response['zipDownload'] = "{$global['webSiteRootURL']}CreatePlugin/{$pluginZip}";
rrmdir(__DIR__."/{$pluginDir}");
} catch (Exception $e) {
$response['error'] = true;
$response['msg'] = $e->getMessage();
}
$pluginFile = "{$pluginDir}$pluginName.php";
$pluginTemplate = file_get_contents("{$templatesDir}plugin.php");
$search = array('{pluginName}', '{includeTables}', '{tablename}', '{uid}');
$replace = array($pluginName, implode(PHP_EOL, $includeTables), $pluginName, "5ee8405eaaa16");
$data = str_replace($search, $replace, $pluginTemplate);
file_put_contents($pluginFile, $data);
$pluginFile = "{$pluginDir}View/editor.php";
$pluginTemplate = file_get_contents("{$templatesDir}editor.php");
$search = array('{pluginName}', '{editorNavTabs}', '{editorNavContent}');
$replace = array($pluginName, implode(PHP_EOL, $editorNavTabs), implode(PHP_EOL, $editorNavContent));
$data = str_replace($search, $replace, $pluginTemplate);
file_put_contents($pluginFile, $data);
echo json_encode($response);
// Helper function to create directories if they don't exist
function _mkdir($dir) {
if (!is_dir($dir)) {
mkdir($dir);
mkdir($dir, 0777, true);
}
}

View file

@ -0,0 +1,38 @@
<?php
require_once __DIR__.'/../videos/configuration.php';
header('Content-Type: application/json');
if(!User::isAdmin()){
forbiddenPage('You Must be admin');
}
if(!empty($global['disableAdvancedConfigurations'])){
forbiddenPage('Configuration disabled');
}
$response = ['error' => false, 'msg' => ''];
if (!isset($_POST['fileName'])) {
$response['error'] = true;
$response['msg'] = 'File name not specified.';
echo json_encode($response);
exit;
}
$fileName = basename($_POST['fileName']); // Sanitize file name
$filePath = __DIR__ . '/plugins/' . $fileName;
if (file_exists($filePath) && pathinfo($filePath, PATHINFO_EXTENSION) === 'zip') {
if (unlink($filePath)) {
$response['msg'] = 'File deleted successfully.';
} else {
$response['error'] = true;
$response['msg'] = 'Failed to delete the file.';
}
} else {
$response['error'] = true;
$response['msg'] = 'File does not exist or is not a zip file.';
}
echo json_encode($response);

View file

@ -10,74 +10,156 @@ if (!empty($global['disableAdvancedConfigurations'])) {
}
$page = new Page('Create plugin');
// Define the plugins directory
$pluginsDir = __DIR__ . '/plugins/';
?>
<div class="container">
<div class="panel panel-default">
<div class="panel-heading">
<h2>Create New Plugin</h2>
<h2><i class="fas fa-plug"></i> Create New Plugin</h2>
<p>
<i class="fas fa-info-circle"></i>
This tool will generate a base code structure for a new plugin based on the SQL you provide.
This is not the final plugin code but serves as a starting point to help you kickstart your plugin development process.
After creating this base, you can add custom logic and features as needed to complete your plugin.
</p>
<ul>
<li><i class="fas fa-file-signature"></i> Provide a name for the plugin.</li>
<li><i class="fas fa-database"></i> Optionally, enter the SQL code to create your plugin's table in the text area below.</li>
<li><i class="fas fa-check-circle"></i> Click "<i class="fas fa-plus-circle"></i> Create Plugin" to submit the data.</li>
</ul>
<small>
For more detailed instructions on how to further develop and customize your plugin, please refer to the
<a href="https://github.com/WWBN/AVideo/wiki/How-to-code-a-AVideo-Platform-plugin" target="_blank">AVideo Plugin Development Guide</a> on GitHub.
</small>
</div>
<div class="panel-body">
<form id="createPluginForm">
<div class="form-group">
<label for="pluginName">Plugin Name</label>
<label for="pluginName"><i class="fas fa-tag"></i> Plugin Name</label>
<input type="text" class="form-control" id="pluginName" name="pluginName" placeholder="Enter Plugin Name" required>
</div>
<div class="form-group">
<label for="createTableSQL">CREATE TABLE SQL</label>
<textarea class="form-control" id="createTableSQL" name="createTableSQL" rows="5" placeholder="Paste your CREATE TABLE SQL here" required></textarea>
<label for="createTableSQL"><i class="fas fa-database"></i> CREATE TABLE SQL (Optional)</label>
<textarea class="form-control" id="createTableSQL" name="createTableSQL" rows="5" placeholder="Paste your CREATE TABLE SQL here (optional)"></textarea>
</div>
<button type="button" id="createPluginButton" class="btn btn-primary btn-block">Create Plugin</button>
<button type="button" id="createPluginButton" class="btn btn-success btn-block"><i class="fas fa-plus-circle"></i> Create Plugin</button>
</form>
<div id="responseMessage" class="alert" style="display:none; margin-top: 10px;"></div>
</div>
<!-- Section for additional information -->
<div class="panel-footer">
<h3>Instructions:</h3>
<ul>
<li>Enter the SQL code to create your plugin's table in the text area below.</li>
<li>Provide a name for the plugin. The name must start with an uppercase letter, contain only letters, numbers, and underscores, and should have no spaces.</li>
<li>Invalid characters will be automatically removed as you type.</li>
<li>Click "Create Plugin" to submit the data.</li>
</ul>
<h3><i class="fas fa-folder-open"></i> Existing Plugin Zips</h3>
<div id="zipFilesList">
<!-- Zip files list will be loaded here -->
</div>
</div>
</div>
</div>
<script>
var listModal = getPleaseWait();
var deleteModal = getPleaseWait();
$(document).ready(function() {
// Auto-format plugin name input
$('#pluginName').on('input', function() {
let value = $(this).val();
// Remove invalid characters and ensure the first letter is uppercase
value = value.replace(/[^a-zA-Z0-9_]/g, ''); // Remove any character that is not a letter, number, or underscore
value = value.replace(/[^a-zA-Z0-9_]/g, ''); // Remove any invalid character
if (value.length > 0) {
value = value.charAt(0).toUpperCase() + value.slice(1); // Ensure the first letter is uppercase
value = value.charAt(0).toUpperCase() + value.slice(1); // Capitalize first letter
}
$(this).val(value);
});
// AJAX submit on button click
// AJAX to create plugin
$('#createPluginButton').on('click', function() {
let pluginName = $('#pluginName').val();
let createTableSQL = $('#createTableSQL').val();
if (pluginName && createTableSQL) {
if (pluginName) {
modal.showPleaseWait();
$.ajax({
url: webSiteRootURL + 'CreatePlugin/create.json.php',
type: 'POST',
data: {
pluginName: pluginName,
createTableSQL: createTableSQL
pluginName,
createTableSQL
},
success: function(response) {
$('#responseMessage').removeClass('alert-danger').addClass('alert-success').text('Plugin created successfully!').show();
modal.hidePleaseWait();
if (response.error) {
$('#responseMessage').removeClass('alert-success').addClass('alert-danger').text('Error: ' + response.msg).show();
} else {
let successMessage = '<i class="fas fa-check-circle"></i> Plugin created successfully!<br>' +
'<i class="fas fa-plug"></i> Plugin Name: ' + response.pluginName + '<br>' +
'<i class="fas fa-folder"></i> Plugin Directory: ' + response.pluginDir + '<br>' +
'<i class="fas fa-database"></i> Tables Found: ' + response.tables.join(', ') + '<br>' +
'<i class="fas fa-file-code"></i> Files Created: <ul>';
response.createdFiles.forEach(file => successMessage += '<li>' + file + '</li>');
successMessage += '</ul>';
$('#responseMessage').removeClass('alert-danger').addClass('alert-success').html(successMessage).show();
loadZipFiles();
}
},
error: function() {
$('#responseMessage').removeClass('alert-success').addClass('alert-danger').text('An error occurred while creating the plugin.').show();
modal.hidePleaseWait();
$('#responseMessage').removeClass('alert-success').addClass('alert-danger').text('An error occurred while creating the plugin. Please try again later.').show();
}
});
} else {
$('#responseMessage').removeClass('alert-success').addClass('alert-danger').text('Please fill in both fields.').show();
$('#responseMessage').removeClass('alert-success').addClass('alert-danger').text('Please fill the name').show();
}
});
// Function to load zip files
function loadZipFiles() {
listModal.showPleaseWait();
$.getJSON(webSiteRootURL + 'CreatePlugin/list_zip_files.php', function(data) {
listModal.hidePleaseWait();
if (data.length === 0) {
$('#zipFilesList').html('<p><i class="fas fa-info-circle"></i> No zip files available.</p>');
} else {
let listHtml = '<ul class="list-group">';
data.forEach(file => {
listHtml += '<li class="list-group-item">' +
' <a href="' + webSiteRootURL + 'CreatePlugin/plugins/' + file + '" class="btn btn-sm btn-primary" download><i class="fas fa-download"></i> Download</a> ' +
' <button class="btn btn-sm btn-danger" onclick="deleteZipFile(\'' + file + '\')"><i class="fas fa-trash-alt"></i> Delete</button> ' +
file +
'</li>';
});
listHtml += '</ul>';
$('#zipFilesList').html(listHtml);
}
});
}
// Function to delete zip file
window.deleteZipFile = function(fileName) {
deleteModal.showPleaseWait();
$.ajax({
url: webSiteRootURL + 'CreatePlugin/delete_zip_file.php',
type: 'POST',
data: {
fileName
},
success: function(response) {
deleteModal.hidePleaseWait();
if (response.error) {
alert('Error: ' + response.msg);
} else {
loadZipFiles(); // Refresh list
}
}
});
};
// Initial load of zip files
loadZipFiles();
});
</script>
<?php

View file

@ -0,0 +1,24 @@
<?php
require_once __DIR__.'/../videos/configuration.php';
header('Content-Type: application/json');
if(!User::isAdmin()){
forbiddenPage('You Must be admin');
}
if(!empty($global['disableAdvancedConfigurations'])){
forbiddenPage('Configuration disabled');
}
$pluginsDir = __DIR__ . '/plugins/';
$files = [];
// Check if directory exists
if (is_dir($pluginsDir)) {
foreach (glob($pluginsDir . "*.zip") as $file) {
$files[] = basename($file); // Add only the file name
}
}
echo json_encode($files);