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:
parent
011066baa9
commit
bcd92a864c
7 changed files with 448 additions and 262 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -105,3 +105,4 @@ install/bulkCreateUser.php
|
||||||
plugin/WebAuthnLogin/
|
plugin/WebAuthnLogin/
|
||||||
plugin/UserOTPLogin/
|
plugin/UserOTPLogin/
|
||||||
test*
|
test*
|
||||||
|
CreatePlugin/plugins/
|
||||||
|
|
|
@ -1,265 +1,227 @@
|
||||||
<?php
|
<?php
|
||||||
require_once __DIR__.'/../videos/configuration.php';
|
require_once __DIR__.'/../videos/configuration.php';
|
||||||
|
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
if(!User::isAdmin()){
|
if(!User::isAdmin()){
|
||||||
forbiddenPage('You Must be admin');
|
forbiddenPage('You Must be admin');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(!empty($global['disableAdvancedConfigurations'])){
|
if(!empty($global['disableAdvancedConfigurations'])){
|
||||||
forbiddenPage('Configuration disabled');
|
forbiddenPage('Configuration disabled');
|
||||||
}
|
}
|
||||||
|
|
||||||
use iamcal\SQLParser;
|
use iamcal\SQLParser;
|
||||||
|
|
||||||
$parser = new SQLParser();
|
try {
|
||||||
|
$parser = new SQLParser();
|
||||||
|
|
||||||
$pluginName = $_REQUEST['pluginName'];
|
// Plugin name and SQL file (replace these with dynamic input as needed)
|
||||||
$sql = $_REQUEST['createTableSQL'];
|
$pluginName = $_REQUEST['pluginName'];
|
||||||
|
$sql = $_REQUEST['createTableSQL'];
|
||||||
|
|
||||||
$parser->parse($sql);
|
// Sanitize and format plugin name
|
||||||
//var_dump($parser->tables);exit;
|
$pluginName = preg_replace('/[^a-zA-Z0-9_]/', '', ucfirst($pluginName));
|
||||||
$pluginDir = __DIR__."/plugins/{$pluginName}/";
|
if (!preg_match('/^[A-Z][A-Za-z0-9_]*$/', $pluginName)) {
|
||||||
echo $pluginDir, PHP_EOL;
|
throw new Exception('Invalid plugin name. It must start with an uppercase letter and contain only letters, numbers, and underscores.');
|
||||||
_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>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$templatesDir = __DIR__.'/templates/';
|
$parser->parse($sql);
|
||||||
|
|
||||||
$classFile = "{$pluginDirObjects}{$classname}.php";
|
// Define plugin directories
|
||||||
$modelTemplate = file_get_contents("{$templatesDir}model.php");
|
$pluginZip = "plugins/{$pluginName}.zip";
|
||||||
$search = array('{classname}', '{tablename}', '{pluginName}', '{columnsVars}', '{columnsString}', '{columnsGetAll}', '{columnsGet}', '{columnsSet}');
|
$pluginDir = "plugins/{$pluginName}/";
|
||||||
$replace = array($classname, $value['name'], $pluginName, implode(",", $columnsVars), implode(",", $columnsString), implode(PHP_EOL, $columnsGetAll), implode(PHP_EOL, $columnsGet), implode(PHP_EOL, $columnsSet));
|
_mkdir($pluginDir);
|
||||||
$data = str_replace($search, $replace, $modelTemplate);
|
|
||||||
file_put_contents($classFile, $data);
|
|
||||||
|
|
||||||
|
$pluginDirInstall = "{$pluginDir}install/";
|
||||||
|
_mkdir($pluginDirInstall);
|
||||||
|
$installFilePath = $pluginDirInstall . "install.sql";
|
||||||
|
file_put_contents($installFilePath, $sql);
|
||||||
|
$response['createdFiles'][] = $installFilePath;
|
||||||
|
|
||||||
$dir = "{$pluginDirView}{$classname}/";
|
$pluginDirObjects = "{$pluginDir}Objects/";
|
||||||
_mkdir($dir);
|
_mkdir($pluginDirObjects);
|
||||||
|
|
||||||
$file = "{$dir}index.php";
|
$pluginDirView = "{$pluginDir}View/";
|
||||||
$modelTemplate = file_get_contents("{$templatesDir}index.php");
|
_mkdir($pluginDirView);
|
||||||
$search = array('{classname}', '{pluginName}');
|
|
||||||
$replace = array($classname, $pluginName);
|
|
||||||
$data = str_replace($search, $replace, $modelTemplate);
|
|
||||||
file_put_contents($file, $data);
|
|
||||||
|
|
||||||
$file = "{$dir}index_body.php";
|
// Initialize arrays to build templates and file paths
|
||||||
$modelTemplate = file_get_contents("{$templatesDir}index_body.php");
|
$includeTables = [];
|
||||||
$search = array('{classname}','{tablename}', '{pluginName}', '{columnsForm}', '{columnsFooter}', '{columnsGrid}', '{$columnsClearJQuery}', '{columnsDatatable}', '{$columnsEdit}');
|
$editorNavTabs = [];
|
||||||
$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));
|
$editorNavContent = [];
|
||||||
$data = str_replace($search, $replace, $modelTemplate);
|
$active = true;
|
||||||
file_put_contents($file, $data);
|
|
||||||
|
$response['tables'] = array();
|
||||||
|
|
||||||
$file = "{$dir}list.json.php";
|
// Process each table found in SQL
|
||||||
$modelTemplate = file_get_contents("{$templatesDir}list.json.php");
|
foreach ($parser->tables as $table) {
|
||||||
$search = array('{classname}', '{pluginName}');
|
$tableName = $table['name'];
|
||||||
$replace = array($classname, $pluginName);
|
$response['tables'][] = $tableName; // Add table name to response
|
||||||
$data = str_replace($search, $replace, $modelTemplate);
|
|
||||||
file_put_contents($file, $data);
|
|
||||||
|
|
||||||
$file = "{$dir}delete.json.php";
|
$classname = ucwords($tableName);
|
||||||
$modelTemplate = file_get_contents("{$templatesDir}delete.json.php");
|
$includeTables[] = "require_once \$global['systemRootPath'] . 'plugin/{$pluginName}/Objects/{$classname}.php';";
|
||||||
$search = array('{classname}', '{pluginName}');
|
|
||||||
$replace = array($classname, $pluginName);
|
// HTML for editor navigation
|
||||||
$data = str_replace($search, $replace, $modelTemplate);
|
$editorNavTabs[] = "<li class=\"" . ($active ? "active" : "") . "\"><a data-toggle=\"tab\" href=\"#{$classname}\"><?php echo __(\"{$tableName}\"); ?></a></li>";
|
||||||
file_put_contents($file, $data);
|
$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";
|
// Initialize column-specific arrays
|
||||||
$modelTemplate = file_get_contents("{$templatesDir}add.json.php");
|
$columnsVars = [];
|
||||||
$search = array('{classname}', '{pluginName}', '{columnsAdd}');
|
$columnsString = [];
|
||||||
$replace = array($classname, $pluginName, implode(PHP_EOL, $columnsAdd));
|
$columnsGet = [];
|
||||||
$data = str_replace($search, $replace, $modelTemplate);
|
$columnsSet = [];
|
||||||
file_put_contents($file, $data);
|
$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";
|
echo json_encode($response);
|
||||||
$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);
|
|
||||||
|
|
||||||
|
// Helper function to create directories if they don't exist
|
||||||
function _mkdir($dir) {
|
function _mkdir($dir) {
|
||||||
if (!is_dir($dir)) {
|
if (!is_dir($dir)) {
|
||||||
mkdir($dir);
|
mkdir($dir, 0777, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
38
CreatePlugin/delete_zip_file.php
Normal file
38
CreatePlugin/delete_zip_file.php
Normal 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);
|
|
@ -10,74 +10,156 @@ if (!empty($global['disableAdvancedConfigurations'])) {
|
||||||
}
|
}
|
||||||
|
|
||||||
$page = new Page('Create plugin');
|
$page = new Page('Create plugin');
|
||||||
|
|
||||||
|
// Define the plugins directory
|
||||||
|
$pluginsDir = __DIR__ . '/plugins/';
|
||||||
?>
|
?>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<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>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<form id="createPluginForm">
|
<form id="createPluginForm">
|
||||||
<div class="form-group">
|
<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>
|
<input type="text" class="form-control" id="pluginName" name="pluginName" placeholder="Enter Plugin Name" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="createTableSQL">CREATE TABLE SQL</label>
|
<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" required></textarea>
|
<textarea class="form-control" id="createTableSQL" name="createTableSQL" rows="5" placeholder="Paste your CREATE TABLE SQL here (optional)"></textarea>
|
||||||
</div>
|
</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>
|
</form>
|
||||||
<div id="responseMessage" class="alert" style="display:none; margin-top: 10px;"></div>
|
<div id="responseMessage" class="alert" style="display:none; margin-top: 10px;"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Section for additional information -->
|
||||||
<div class="panel-footer">
|
<div class="panel-footer">
|
||||||
<h3>Instructions:</h3>
|
<h3><i class="fas fa-folder-open"></i> Existing Plugin Zips</h3>
|
||||||
<ul>
|
<div id="zipFilesList">
|
||||||
<li>Enter the SQL code to create your plugin's table in the text area below.</li>
|
<!-- Zip files list will be loaded here -->
|
||||||
<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>
|
</div>
|
||||||
<li>Invalid characters will be automatically removed as you type.</li>
|
|
||||||
<li>Click "Create Plugin" to submit the data.</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
var listModal = getPleaseWait();
|
||||||
|
var deleteModal = getPleaseWait();
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
// Auto-format plugin name input
|
// Auto-format plugin name input
|
||||||
$('#pluginName').on('input', function() {
|
$('#pluginName').on('input', function() {
|
||||||
let value = $(this).val();
|
let value = $(this).val();
|
||||||
// Remove invalid characters and ensure the first letter is uppercase
|
value = value.replace(/[^a-zA-Z0-9_]/g, ''); // Remove any invalid character
|
||||||
value = value.replace(/[^a-zA-Z0-9_]/g, ''); // Remove any character that is not a letter, number, or underscore
|
|
||||||
if (value.length > 0) {
|
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);
|
$(this).val(value);
|
||||||
});
|
});
|
||||||
|
|
||||||
// AJAX submit on button click
|
// AJAX to create plugin
|
||||||
$('#createPluginButton').on('click', function() {
|
$('#createPluginButton').on('click', function() {
|
||||||
let pluginName = $('#pluginName').val();
|
let pluginName = $('#pluginName').val();
|
||||||
let createTableSQL = $('#createTableSQL').val();
|
let createTableSQL = $('#createTableSQL').val();
|
||||||
|
|
||||||
if (pluginName && createTableSQL) {
|
if (pluginName) {
|
||||||
|
modal.showPleaseWait();
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: webSiteRootURL + 'CreatePlugin/create.json.php',
|
url: webSiteRootURL + 'CreatePlugin/create.json.php',
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
data: {
|
data: {
|
||||||
pluginName: pluginName,
|
pluginName,
|
||||||
createTableSQL: createTableSQL
|
createTableSQL
|
||||||
},
|
},
|
||||||
success: function(response) {
|
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() {
|
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 {
|
} 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>
|
</script>
|
||||||
<?php
|
<?php
|
||||||
|
|
24
CreatePlugin/list_zip_files.php
Normal file
24
CreatePlugin/list_zip_files.php
Normal 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);
|
|
@ -23,14 +23,14 @@ function getDurationFromFile($file)
|
||||||
if (!file_exists($videoFile)) {
|
if (!file_exists($videoFile)) {
|
||||||
$file_headers = @get_headers($videoFile);
|
$file_headers = @get_headers($videoFile);
|
||||||
if (!$file_headers || $file_headers[0] == 'HTTP/1.1 404 Not Found') {
|
if (!$file_headers || $file_headers[0] == 'HTTP/1.1 404 Not Found') {
|
||||||
error_log('getDurationFromFile try 1, File (' . $videoFile . ') Not Found original='.$file);
|
error_log('getDurationFromFile try 1, File (' . $videoFile . ') Not Found original=' . $file);
|
||||||
$videoFile = $hls;
|
$videoFile = $hls;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!file_exists($videoFile)) {
|
if (!file_exists($videoFile)) {
|
||||||
$file_headers = @get_headers($videoFile);
|
$file_headers = @get_headers($videoFile);
|
||||||
if (!$file_headers || $file_headers[0] == 'HTTP/1.1 404 Not Found') {
|
if (!$file_headers || $file_headers[0] == 'HTTP/1.1 404 Not Found') {
|
||||||
error_log('getDurationFromFile try 2, File (' . $videoFile . ') Not Found original='.$file);
|
error_log('getDurationFromFile try 2, File (' . $videoFile . ') Not Found original=' . $file);
|
||||||
$videoFile = '';
|
$videoFile = '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -243,6 +243,82 @@ function unzipDirectory($filename, $destination)
|
||||||
return $return_val === 0;
|
return $return_val === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function zipDirectory($source, $destination)
|
||||||
|
{
|
||||||
|
// Set memory limit and execution time to avoid issues with large files
|
||||||
|
ini_set('memory_limit', '-1');
|
||||||
|
set_time_limit(0);
|
||||||
|
|
||||||
|
// Check if the source directory exists
|
||||||
|
if (!is_dir($source)) {
|
||||||
|
_error_log("zipDirectory: Source directory does not exist: {$source}");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the destination directory exists, create it if it doesn't
|
||||||
|
$destinationDir = dirname($destination);
|
||||||
|
if (!is_dir($destinationDir)) {
|
||||||
|
if (!mkdir($destinationDir, 0755, true)) {
|
||||||
|
_error_log("zipDirectory: Failed to create destination directory: {$destinationDir}");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_error_log("zipDirectory: Destination directory created: {$destinationDir}");
|
||||||
|
}
|
||||||
|
chmod($source, 0755);
|
||||||
|
|
||||||
|
// Escape the input parameters to prevent command injection attacks
|
||||||
|
$sourceOriginal = rtrim($source, '/'); // Remove trailing slash for consistency
|
||||||
|
$destinationOriginal = $destination;
|
||||||
|
$source = escapeshellarg($source);
|
||||||
|
$destination = escapeshellarg($destination);
|
||||||
|
|
||||||
|
// Build the command for zipping the directory
|
||||||
|
$cmd = "zip -r -q {$destination} {$source} 2>&1";
|
||||||
|
|
||||||
|
// Log the command for debugging purposes
|
||||||
|
_error_log("zipDirectory: {$cmd}");
|
||||||
|
|
||||||
|
// Execute the command and capture the output and return value
|
||||||
|
exec($cmd, $output, $return_val);
|
||||||
|
|
||||||
|
if ($return_val !== 0) {
|
||||||
|
// Log the output and return value
|
||||||
|
_error_log("zipDirectory: Command failed with return value {$return_val}");
|
||||||
|
_error_log("zipDirectory: Command output: " . implode("\n", $output));
|
||||||
|
|
||||||
|
// Try using PHP's ZipArchive class as a fallback
|
||||||
|
if (class_exists('ZipArchive')) {
|
||||||
|
$zip = new ZipArchive();
|
||||||
|
if ($zip->open($destinationOriginal, ZipArchive::CREATE | ZipArchive::OVERWRITE) === true) {
|
||||||
|
$dirIterator = new RecursiveDirectoryIterator($sourceOriginal);
|
||||||
|
$files = new RecursiveIteratorIterator($dirIterator, RecursiveIteratorIterator::LEAVES_ONLY);
|
||||||
|
|
||||||
|
// Get the base directory name to use as root folder in the zip
|
||||||
|
$baseFolder = basename($sourceOriginal);
|
||||||
|
|
||||||
|
foreach ($files as $name => $file) {
|
||||||
|
if (!$file->isDir()) {
|
||||||
|
$filePath = $file->getRealPath();
|
||||||
|
// Calculate relative path, including the base folder
|
||||||
|
$relativePath = $baseFolder . '/' . substr($filePath, strlen($sourceOriginal) + 1);
|
||||||
|
$zip->addFile($filePath, $relativePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$zip->close();
|
||||||
|
_error_log("zipDirectory: Success using ZipArchive for {$destination}");
|
||||||
|
} else {
|
||||||
|
_error_log("zipDirectory: Error opening zip archive using ZipArchive: {$destination}");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_error_log("zipDirectory: Error: ZipArchive class is not available");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_error_log("zipDirectory: Success {$destination}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return file_exists($destinationOriginal);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function getPIDUsingPort($port)
|
function getPIDUsingPort($port)
|
||||||
|
@ -396,7 +472,7 @@ function execAsync($command, $keyword = null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(empty($output)){
|
if (empty($output)) {
|
||||||
return $output;
|
return $output;
|
||||||
}
|
}
|
||||||
$pid = (int)$output[0];
|
$pid = (int)$output[0];
|
||||||
|
@ -420,12 +496,12 @@ function findProcess($keyword)
|
||||||
//var_dump($pgrepOutput);
|
//var_dump($pgrepOutput);
|
||||||
if ($retval === 0) {
|
if ($retval === 0) {
|
||||||
foreach ($pgrepOutput as $pgrepPid) {
|
foreach ($pgrepOutput as $pgrepPid) {
|
||||||
if(preg_match('/pgrep /i', $pgrepPid)){
|
if (preg_match('/pgrep /i', $pgrepPid)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(preg_match('/([0-9]+) (.*)/i', $pgrepPid, $matches)){
|
if (preg_match('/([0-9]+) (.*)/i', $pgrepPid, $matches)) {
|
||||||
if(!empty($matches[2])){
|
if (!empty($matches[2])) {
|
||||||
$output[] = array('pid'=>(int)$matches[1], 'command'=>trim($matches[2]));
|
$output[] = array('pid' => (int)$matches[1], 'command' => trim($matches[2]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//$output[] = (int)$pgrepPid;
|
//$output[] = (int)$pgrepPid;
|
||||||
|
|
|
@ -68,6 +68,9 @@ $wwbnIndexPlugin = AVideoPlugin::isEnabledByName('WWBNIndex');
|
||||||
<button type="button" class="btn btn-default" id="upload">
|
<button type="button" class="btn btn-default" id="upload">
|
||||||
<i class="fas fa-plus"></i> <?php echo __("Upload a Plugin"); ?>
|
<i class="fas fa-plus"></i> <?php echo __("Upload a Plugin"); ?>
|
||||||
</button>
|
</button>
|
||||||
|
<button type="button" class="btn btn-primary" id="createPlugin" onclick="avideoModalIframeFull(webSiteRootURL + 'CreatePlugin/');">
|
||||||
|
<i class="fas fa-plus-circle"></i> <?php echo __("Create a Plugin"); ?>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div style="text-align: right; padding: 5px;">
|
<div style="text-align: right; padding: 5px;">
|
||||||
<span class="badge" id="PluginTagsTotal">...</span>
|
<span class="badge" id="PluginTagsTotal">...</span>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue