From 43ff675b5e3a442df3207b20f0a08b83480fd299 Mon Sep 17 00:00:00 2001 From: ma0048 Date: Wed, 5 May 2021 13:37:19 +0200 Subject: [PATCH 01/14] installation von extensions auf mehreren servern ermoeglicht --- .../system/extensions/CLI_Manager.php | 5 +-- .../controllers/system/extensions/Manager.php | 8 +++-- application/libraries/ExtensionsLib.php | 32 ++++++++++++------- .../models/system/Extensions_model.php | 2 +- .../views/system/extensions/manager.php | 7 +++- system/dbupdate_3.3.php | 32 +++++++++++++++++-- 6 files changed, 66 insertions(+), 20 deletions(-) diff --git a/application/controllers/system/extensions/CLI_Manager.php b/application/controllers/system/extensions/CLI_Manager.php index ed8a5f7a5..110fad9e8 100644 --- a/application/controllers/system/extensions/CLI_Manager.php +++ b/application/controllers/system/extensions/CLI_Manager.php @@ -28,9 +28,10 @@ class CLI_Manager extends CLI_Controller * die Commandline ohne Upload durchzufuehren. * @param $extensioName string Name der Extension * @param $filename Url Encoded Pfad zum tgz File der Extension + * @param $perform_sql boolean ob die SQL Befehle ausgeführt werden */ - public function uploadExtension($extensionName = null, $filename = null) + public function uploadExtension($extensionName = null, $filename = null, $perform_sql = true) { - $this->extensionslib->installExtension($extensionName, urldecode($filename)); + $this->extensionslib->installExtension($extensionName, urldecode($filename), $perform_sql); } } diff --git a/application/controllers/system/extensions/Manager.php b/application/controllers/system/extensions/Manager.php index aa4e76e9c..429c967ae 100644 --- a/application/controllers/system/extensions/Manager.php +++ b/application/controllers/system/extensions/Manager.php @@ -87,9 +87,13 @@ class Manager extends Auth_Controller * die Commandline ohne Upload durchzufuehren. * @param $extensioName string Name der Extension * @param $filename Url Encoded Pfad zum tgz File der Extension + * @param $perform_sql boolean ob die SQL Befehle ausgeführt werden */ - public function uploadExtension($extensionName = null, $filename = null) + public function uploadExtension($extensionName = null, $filename = null, $perform_sql = true) { - $this->extensionslib->installExtension($extensionName, urldecode($filename)); + $perform_sql = $this->input->post('databasechange'); + $perform_sql = isset($perform_sql) ? false : true; + + $this->extensionslib->installExtension($extensionName, urldecode($filename), $perform_sql); } } diff --git a/application/libraries/ExtensionsLib.php b/application/libraries/ExtensionsLib.php index cec40a753..6598ec2e8 100644 --- a/application/libraries/ExtensionsLib.php +++ b/application/libraries/ExtensionsLib.php @@ -64,7 +64,7 @@ class ExtensionsLib * @param $extensionName string Name of Extension (optional) * @param $filename Path to tgz Extension File (optional) */ - public function installExtension($extensionName = null, $filename = null) + public function installExtension($extensionName = null, $filename = null, $perform_sql = true) { $extensionDB = null; // contains data from DB about an extension $extensionJson = null; // contains the extension.json data @@ -114,7 +114,7 @@ class ExtensionsLib $this->_installExtension($extensionJson); // records extension data in DB - if (!$this->_errorOccurred) // if no error occurred + if (!$this->_errorOccurred && $perform_sql === true) // if no error occurred { // Loads and executes neede SQL scripts $this->_loadSQLs( @@ -173,6 +173,9 @@ class ExtensionsLib $result = $this->_ci->ExtensionsModel->load($extensionId); if (hasData($result)) // if something was found { + $extensionServer = $result->retval[0]->server_kurzbz; + if ($extensionServer !== SERVER_NAME) + return false; $extensionName = $result->retval[0]->name; // extension name $this->_delSoftLinks($extensionName); // not to be checked, could fail if the extension is disabled // remove the extension from the extensions installation directory @@ -180,10 +183,9 @@ class ExtensionsLib // Select all the version of this extension $this->_ci->ExtensionsModel->addSelect('extension_id'); - $result = $this->_ci->ExtensionsModel->loadWhere(array('name' => $extensionName)); + $result = $this->_ci->ExtensionsModel->loadWhere(array('name' => $extensionName, 'server_kurzbz' => SERVER_NAME)); if (hasData($result)) // if something was found { - $extsArray = array(); foreach ($result->retval as $key => $extension) // loops on them { // Remove them all @@ -328,7 +330,7 @@ class ExtensionsLib // Loads the last version of the previous installation of this extension $this->_ci->ExtensionsModel->addOrder('version', 'DESC'); $this->_ci->ExtensionsModel->addLimit(1); - $result = $this->_ci->ExtensionsModel->loadWhere(array('name' => $extensionName)); + $result = $this->_ci->ExtensionsModel->loadWhere(array('name' => $extensionName, 'server_kurzbz' => SERVER_NAME)); if (isError($result)) { $this->_errorOccurred = true; @@ -550,7 +552,8 @@ class ExtensionsLib 'license' => isset($extensionJson->license) ? $extensionJson->license : null, 'url' => isset($extensionJson->url) ? $extensionJson->url : null, 'core_version' => $extensionJson->core_version, - 'dependencies' => isset($extensionJson->dependencies) ? $extensionJson->dependencies : null + 'dependencies' => isset($extensionJson->dependencies) ? $extensionJson->dependencies : null, + 'server_kurzbz' => SERVER_NAME, ) ); if (isSuccess($result)) @@ -738,11 +741,18 @@ class ExtensionsLib mkdir($extensionPath.$targetDirectory); } - // Create the symlink - $_addSoftLinks = symlink( - $extensionPath.$targetDirectory, - $rootPath.$targetDirectory.'/'.ExtensionsLib::EXTENSIONS_DIR_NAME.'/'.$extensionName - ); + if (!file_exists($rootPath.$targetDirectory.'/'.ExtensionsLib::EXTENSIONS_DIR_NAME.'/'.$extensionName)) + { + // Create the symlink + $_addSoftLinks = symlink( + $extensionPath.$targetDirectory, + $rootPath.$targetDirectory.'/'.ExtensionsLib::EXTENSIONS_DIR_NAME.'/'.$extensionName + ); + }else + { + $_addSoftLinks = true; + } + if (!$_addSoftLinks) { log_message('error', 'Failed to create Symlink to '.$extensionPath.$targetDirectory); diff --git a/application/models/system/Extensions_model.php b/application/models/system/Extensions_model.php index 8898ebd50..1beef4d8b 100644 --- a/application/models/system/Extensions_model.php +++ b/application/models/system/Extensions_model.php @@ -31,7 +31,7 @@ class Extensions_model extends DB_Model */ public function getInstalledExtensions() { - $query = 'SELECT extension_id, e1.name, e1.version, description, license, url, core_version, dependencies, enabled + $query = 'SELECT extension_id, e1.name, e1.version, description, license, url, core_version, dependencies, enabled, e1.server_kurzbz FROM system.tbl_extensions e1 INNER JOIN ( SELECT name, MAX(version) AS version diff --git a/application/views/system/extensions/manager.php b/application/views/system/extensions/manager.php index 6c48bc80a..01111f295 100644 --- a/application/views/system/extensions/manager.php +++ b/application/views/system/extensions/manager.php @@ -108,6 +108,7 @@ URL Minimum required Core version Dependes on (extensions) + Server Enabled   @@ -124,6 +125,7 @@ %s %s %s + %s @@ -143,6 +145,7 @@ $extension->url, $extension->core_version, count($extension->dependencies) == 0 ? 'None' : json_encode($extension->dependencies), + $extension->server_kurzbz, $extension->extension_id, $extension->enabled === true ? 'checked' : '', $extension->extension_id @@ -160,7 +163,9 @@ - +
+ + diff --git a/system/dbupdate_3.3.php b/system/dbupdate_3.3.php index e658d7a97..0bcff4928 100644 --- a/system/dbupdate_3.3.php +++ b/system/dbupdate_3.3.php @@ -956,13 +956,39 @@ if ($result = @$db->db_query("SELECT conname FROM pg_constraint WHERE conname = // UNIQUE INDEX uidx_extensions_name_version if ($result = $db->db_query("SELECT 0 FROM pg_class WHERE relname = 'uidx_extensions_name_version'")) { - if ($db->db_num_rows($result) == 0) + if ($db->db_num_rows($result) == 1) { - $qry = 'CREATE UNIQUE INDEX uidx_extensions_name_version ON system.tbl_extensions USING btree (name, version);'; + $qry = 'DROP INDEX system.uidx_extensions_name_version'; if (!$db->db_query($qry)) echo 'uidx_extensions_name_version '.$db->db_last_error().'
'; else - echo '
Created unique uidx_extensions_name_version'; + echo '
Dropped unique uidx_extensions_name_version'; + } +} + +// stud_selfservice boolean fuer public.tbl_vorlage +if(!@$db->db_query("SELECT server_kurzbz FROM system.tbl_extensions LIMIT 1")) +{ + $qry = "ALTER TABLE system.tbl_extensions ADD COLUMN server_kurzbz varchar(64); + ALTER TABLE system.tbl_extensions ADD CONSTRAINT fk_extensios_server_kurzbz FOREIGN KEY (server_kurzbz) REFERENCES system.tbl_server(server_kurzbz) ON UPDATE CASCADE ON DELETE RESTRICT;"; + + if(!$db->db_query($qry)) + echo 'App: '.$db->db_last_error().'
'; + else + echo '
Neue Spalte server_kurzbz in system.tbl_extensions hinzugefügt'; +} + + +// UNIQUE INDEX uidx_extensions_name_version_server +if ($result = $db->db_query("SELECT 0 FROM pg_class WHERE relname = 'uidx_extensions_name_version_server'")) +{ + if ($db->db_num_rows($result) == 0) + { + $qry = 'CREATE UNIQUE INDEX uidx_extensions_name_version_server ON system.tbl_extensions USING btree (name, version, server_kurzbz);'; + if (!$db->db_query($qry)) + echo 'uidx_extensions_name_version_server '.$db->db_last_error().'
'; + else + echo '
Created unique uidx_extensions_name_version_server'; } } From 194979be6d599c1351104890c79c8a59dbe9e37c Mon Sep 17 00:00:00 2001 From: ma0048 Date: Wed, 19 May 2021 09:58:44 +0200 Subject: [PATCH 02/14] aktivieren/deaktivieren nur auf dem jeweiligen server moeglich und bug fixed wenn server_kurz null ist --- application/libraries/ExtensionsLib.php | 70 ++++++++++++++++--------- 1 file changed, 46 insertions(+), 24 deletions(-) diff --git a/application/libraries/ExtensionsLib.php b/application/libraries/ExtensionsLib.php index 6598ec2e8..665ad237c 100644 --- a/application/libraries/ExtensionsLib.php +++ b/application/libraries/ExtensionsLib.php @@ -87,10 +87,16 @@ class ExtensionsLib { $this->_extractExtension($uploadData->fullPath); // extract the archive of the uploaded extension + if (!$this->_errorOccurred) // if no error occurred + { + // Retives data about any previous installation of this extension on this server + $extensionDB = $this->_loadPreviousInstallation($uploadData->extensionName, true); + } + if (!$this->_errorOccurred) // if no error occurred { // Retives data about any previous installation of this extension - $extensionDB = $this->_loadPreviousInstallation($uploadData->extensionName); + $extensionDBNull = $this->_loadPreviousInstallation($uploadData->extensionName, false); } if (!$this->_errorOccurred) // if no error occurred @@ -112,7 +118,7 @@ class ExtensionsLib $this->_cleanPreviousInstallation($extensionJson); // cleans any previous installation - $this->_installExtension($extensionJson); // records extension data in DB + $this->_installExtension($extensionJson, $extensionDBNull); // records extension data in DB if (!$this->_errorOccurred && $perform_sql === true) // if no error occurred { @@ -321,7 +327,7 @@ class ExtensionsLib /** * Loads any previous installations of the given extension from DB */ - private function _loadPreviousInstallation($extensionName) + private function _loadPreviousInstallation($extensionName, $onServer) { $extensionDB = null; @@ -330,7 +336,11 @@ class ExtensionsLib // Loads the last version of the previous installation of this extension $this->_ci->ExtensionsModel->addOrder('version', 'DESC'); $this->_ci->ExtensionsModel->addLimit(1); - $result = $this->_ci->ExtensionsModel->loadWhere(array('name' => $extensionName, 'server_kurzbz' => SERVER_NAME)); + if ($onServer) + $result = $this->_ci->ExtensionsModel->loadWhere(array('name' => $extensionName, 'server_kurzbz' => SERVER_NAME)); + else + $result = $this->_ci->ExtensionsModel->loadWhere(array('name' => $extensionName, 'server_kurzbz' => NULL)); + if (isError($result)) { $this->_errorOccurred = true; @@ -540,22 +550,24 @@ class ExtensionsLib /** * Insert extension's data into the DB */ - private function _installExtension($extensionJson) + private function _installExtension($extensionJson, $extensionDBNull) { $this->_printStart('Adding new entry in the DB'); - $result = $this->_ci->ExtensionsModel->insert( - array( - 'name' => $extensionJson->name, - 'description' => isset($extensionJson->description) ? $extensionJson->description : null, - 'version' => $extensionJson->version, - 'license' => isset($extensionJson->license) ? $extensionJson->license : null, - 'url' => isset($extensionJson->url) ? $extensionJson->url : null, - 'core_version' => $extensionJson->core_version, - 'dependencies' => isset($extensionJson->dependencies) ? $extensionJson->dependencies : null, - 'server_kurzbz' => SERVER_NAME, - ) - ); + $sqlArr = + array('name' => $extensionJson->name, + 'description' => isset($extensionJson->description) ? $extensionJson->description : null, + 'version' => $extensionJson->version, + 'license' => isset($extensionJson->license) ? $extensionJson->license : null, + 'url' => isset($extensionJson->url) ? $extensionJson->url : null, + 'core_version' => $extensionJson->core_version, + 'dependencies' => isset($extensionJson->dependencies) ? $extensionJson->dependencies : null, + 'server_kurzbz' => SERVER_NAME); + if (is_null($extensionDBNull)) + $result = $this->_ci->ExtensionsModel->insert($sqlArr); + else + $result = $this->_ci->ExtensionsModel->update($extensionDBNull->extension_id, $sqlArr); + if (isSuccess($result)) { $this->_printSuccess(true); @@ -633,14 +645,17 @@ class ExtensionsLib $this->_printMessage('Current extension directory: '.$this->UPLOAD_PATH.$extensionName); $this->_printMessage('Directory where it will be moved: '.$this->EXTENSIONS_PATH.$extensionName); - if (rename($this->UPLOAD_PATH.$extensionName.'/', $this->EXTENSIONS_PATH.$extensionName)) + if (!file_exists($this->EXTENSIONS_PATH.$extensionName)) { - $this->_printSuccess(true); - } - else - { - $this->_errorOccurred = true; - $this->_printFailure('error while moving'); + if (rename($this->UPLOAD_PATH.$extensionName.'/', $this->EXTENSIONS_PATH.$extensionName)) + { + $this->_printSuccess(true); + } + else + { + $this->_errorOccurred = true; + $this->_printFailure('error while moving'); + } } $this->_printEnd(); @@ -758,6 +773,9 @@ class ExtensionsLib log_message('error', 'Failed to create Symlink to '.$extensionPath.$targetDirectory); break; } + }else + { + $_addSoftLinks = true; } } } @@ -826,6 +844,10 @@ class ExtensionsLib $result = $this->_ci->ExtensionsModel->load($extensionId); if (hasData($result)) { + $extensionServer = $result->retval[0]->server_kurzbz; + if ($extensionServer !== SERVER_NAME) + return false; + $extensionName = $result->retval[0]->name; // extension name // If to be enabled From 75647a5e24ded2de8ca361a7f04e33bbf3638c51 Mon Sep 17 00:00:00 2001 From: ma0048 Date: Wed, 19 May 2021 10:02:18 +0200 Subject: [PATCH 03/14] tabs hinzugefuegt --- application/libraries/ExtensionsLib.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/application/libraries/ExtensionsLib.php b/application/libraries/ExtensionsLib.php index 665ad237c..16bc18416 100644 --- a/application/libraries/ExtensionsLib.php +++ b/application/libraries/ExtensionsLib.php @@ -554,15 +554,15 @@ class ExtensionsLib { $this->_printStart('Adding new entry in the DB'); - $sqlArr = - array('name' => $extensionJson->name, - 'description' => isset($extensionJson->description) ? $extensionJson->description : null, - 'version' => $extensionJson->version, - 'license' => isset($extensionJson->license) ? $extensionJson->license : null, - 'url' => isset($extensionJson->url) ? $extensionJson->url : null, - 'core_version' => $extensionJson->core_version, - 'dependencies' => isset($extensionJson->dependencies) ? $extensionJson->dependencies : null, - 'server_kurzbz' => SERVER_NAME); + $sqlArr = array('name' => $extensionJson->name, + 'description' => isset($extensionJson->description) ? $extensionJson->description : null, + 'version' => $extensionJson->version, + 'license' => isset($extensionJson->license) ? $extensionJson->license : null, + 'url' => isset($extensionJson->url) ? $extensionJson->url : null, + 'core_version' => $extensionJson->core_version, + 'dependencies' => isset($extensionJson->dependencies) ? $extensionJson->dependencies : null, + 'server_kurzbz' => SERVER_NAME); + if (is_null($extensionDBNull)) $result = $this->_ci->ExtensionsModel->insert($sqlArr); else From 063a3fa524aeec7e5ae8c913c899feb489d28617 Mon Sep 17 00:00:00 2001 From: Paolo Date: Wed, 15 Sep 2021 18:08:08 +0200 Subject: [PATCH 04/14] - Added missing column server_kurzbz to system/dbupdate_3.3.php column check - Changed the server column position in the extension manager view - Removed public method getInstalledExtensions from application/models/system/Extensions_model.php - Fixes, comments and indentations in application/libraries/ExtensionsLib.php --- application/libraries/ExtensionsLib.php | 132 ++++++++++-------- .../models/system/Extensions_model.php | 17 +-- .../views/system/extensions/manager.php | 5 +- system/dbupdate_3.3.php | 2 +- 4 files changed, 79 insertions(+), 77 deletions(-) diff --git a/application/libraries/ExtensionsLib.php b/application/libraries/ExtensionsLib.php index 16bc18416..ac74c1a64 100644 --- a/application/libraries/ExtensionsLib.php +++ b/application/libraries/ExtensionsLib.php @@ -37,6 +37,7 @@ class ExtensionsLib { $this->UPLOAD_PATH = APPPATH.'tmp/'; $this->EXTENSIONS_PATH = APPPATH.'extensions/'; + // Get code igniter instance $this->_ci =& get_instance(); @@ -52,6 +53,13 @@ class ExtensionsLib // Set default values fot class properties $this->_errorOccurred = false; $this->_currentInstalledExtensionVersion = 0; + + // If SERVER_NAME is _not_ declared or it is an empty string + if (!defined('SERVER_NAME') || (defined('SERVER_NAME') && isEmptyString(SERVER_NAME))) + { + $this->_printError('Global constant SERVER_NAME is not declared or it is not valid'); + exit(); + } } // ------------------------------------------------------------------------------------------------- @@ -89,14 +97,8 @@ class ExtensionsLib if (!$this->_errorOccurred) // if no error occurred { - // Retives data about any previous installation of this extension on this server - $extensionDB = $this->_loadPreviousInstallation($uploadData->extensionName, true); - } - - if (!$this->_errorOccurred) // if no error occurred - { - // Retives data about any previous installation of this extension - $extensionDBNull = $this->_loadPreviousInstallation($uploadData->extensionName, false); + // Retrieves data about any previous installation of this extension on this server + $extensionDB = $this->_loadPreviousInstallation($uploadData->extensionName); } if (!$this->_errorOccurred) // if no error occurred @@ -116,9 +118,10 @@ class ExtensionsLib $this->_printStart('Proceding with the installation of the extension: '.$extensionJson->name); $this->_printEnd(); - $this->_cleanPreviousInstallation($extensionJson); // cleans any previous installation + // Remove any previous installation from file system and database + $this->_cleanPreviousInstallation($extensionJson); - $this->_installExtension($extensionJson, $extensionDBNull); // records extension data in DB + $this->_installExtension($extensionJson); // records extension data in DB if (!$this->_errorOccurred && $perform_sql === true) // if no error occurred { @@ -179,10 +182,10 @@ class ExtensionsLib $result = $this->_ci->ExtensionsModel->load($extensionId); if (hasData($result)) // if something was found { - $extensionServer = $result->retval[0]->server_kurzbz; - if ($extensionServer !== SERVER_NAME) - return false; - $extensionName = $result->retval[0]->name; // extension name + // If this server is _not_ the same where the extension was installed then exit with a failure + if (getData($result)[0]->server_kurzbz != SERVER_NAME) return false; + + $extensionName = getData($result)[0]->name; // extension name $this->_delSoftLinks($extensionName); // not to be checked, could fail if the extension is disabled // remove the extension from the extensions installation directory $delExtension = $this->_rrm($this->EXTENSIONS_PATH.$extensionName); @@ -192,7 +195,7 @@ class ExtensionsLib $result = $this->_ci->ExtensionsModel->loadWhere(array('name' => $extensionName, 'server_kurzbz' => SERVER_NAME)); if (hasData($result)) // if something was found { - foreach ($result->retval as $key => $extension) // loops on them + foreach (getData($result) as $key => $extension) // loops on them { // Remove them all $result = $this->_ci->ExtensionsModel->delete($extension->extension_id); @@ -212,7 +215,11 @@ class ExtensionsLib */ public function getInstalledExtensions() { - return $this->_ci->ExtensionsModel->getInstalledExtensions(); + $this->_ci->ExtensionsModel->addOrder('name', 'ASC'); + $this->_ci->ExtensionsModel->addOrder('server_kurzbz', 'ASC'); + $this->_ci->ExtensionsModel->addOrder('version', 'ASC'); + + return $this->_ci->ExtensionsModel->load(); } /** @@ -327,7 +334,7 @@ class ExtensionsLib /** * Loads any previous installations of the given extension from DB */ - private function _loadPreviousInstallation($extensionName, $onServer) + private function _loadPreviousInstallation($extensionName) { $extensionDB = null; @@ -336,21 +343,26 @@ class ExtensionsLib // Loads the last version of the previous installation of this extension $this->_ci->ExtensionsModel->addOrder('version', 'DESC'); $this->_ci->ExtensionsModel->addLimit(1); - if ($onServer) - $result = $this->_ci->ExtensionsModel->loadWhere(array('name' => $extensionName, 'server_kurzbz' => SERVER_NAME)); - else - $result = $this->_ci->ExtensionsModel->loadWhere(array('name' => $extensionName, 'server_kurzbz' => NULL)); + // Loads extensions installed on this server + $result = $this->_ci->ExtensionsModel->loadWhere( + array( + 'name' => $extensionName, + 'server_kurzbz' => SERVER_NAME + ) + ); + + // In an error occurred if (isError($result)) { $this->_errorOccurred = true; - $this->_printFailure('data base error: '.$result->retval); + $this->_printFailure('data base error: '.getData($result)); } - else + else // otherwise { if (hasData($result)) // if found { - $extensionDB = $result->retval[0]; // return it! + $extensionDB = getData($result)[0]; // return it! } else { @@ -412,36 +424,41 @@ class ExtensionsLib if (isset($extensionJson->version)) { $extensionJson->currentInstalledVersion = 0; // default current installed version of this extension - - if ($extensionDB != null) // if no previous installation was found in DB + + // If a previous installation was found in DB + if ($extensionDB != null) { + // Then get the data from database $extensionJson->extension_id = $extensionDB->extension_id; // get the extension_id from DB $extensionJson->currentInstalledVersion = $extensionDB->version; // get the current installed version from DB + // Prompt a summary $this->_printMessage('Extension already installed!'); $this->_printMessage('Current version: '.$extensionDB->version); $this->_printMessage('Version of the uploaded extension: '.$extensionJson->version); + // Check if the version of the uploaded extension is the same + // as the one from the dataabase if ($extensionJson->version == $extensionDB->version) { $this->_printMessage('Updating the same version!'); } - elseif ($extensionJson->version > $extensionDB->version) + elseif ($extensionJson->version > $extensionDB->version) // or it is higher { $this->_printMessage('Updating to a new version!'); } - else // downgrade is not possible + else // otherwise is lower, then the downgrade is not possible { $extensionJson = null; $this->_printFailure('downgrade must be performed manually'); } } - else + else // otherwise if it is not installed on this server { $this->_printMessage('Version of the uploaded extension: '.$extensionJson->version); } - // If no errors occurred + // If no errors occurred then check the JSON file content within the uploaded extension if ($extensionJson != null) { require_once('version.php'); // get the core version @@ -459,7 +476,7 @@ class ExtensionsLib // Gets the required dependencies $result = $this->_ci->ExtensionsModel->getDependencies($extensionJson->dependencies); // If they are matcheds - if (hasData($result) && count($result->retval) == count($extensionJson->dependencies)) + if (hasData($result) && count(getData($result)) == count($extensionJson->dependencies)) { if (isset($extensionJson->dependencies)) { @@ -550,24 +567,23 @@ class ExtensionsLib /** * Insert extension's data into the DB */ - private function _installExtension($extensionJson, $extensionDBNull) + private function _installExtension($extensionJson) { $this->_printStart('Adding new entry in the DB'); - $sqlArr = array('name' => $extensionJson->name, - 'description' => isset($extensionJson->description) ? $extensionJson->description : null, - 'version' => $extensionJson->version, - 'license' => isset($extensionJson->license) ? $extensionJson->license : null, - 'url' => isset($extensionJson->url) ? $extensionJson->url : null, - 'core_version' => $extensionJson->core_version, - 'dependencies' => isset($extensionJson->dependencies) ? $extensionJson->dependencies : null, - 'server_kurzbz' => SERVER_NAME); - - if (is_null($extensionDBNull)) - $result = $this->_ci->ExtensionsModel->insert($sqlArr); - else - $result = $this->_ci->ExtensionsModel->update($extensionDBNull->extension_id, $sqlArr); - + // Insert into database the extension information + $result = $this->_ci->ExtensionsModel->insert( + array( + 'name' => $extensionJson->name, + 'description' => isset($extensionJson->description) ? $extensionJson->description : null, + 'version' => $extensionJson->version, + 'license' => isset($extensionJson->license) ? $extensionJson->license : null, + 'url' => isset($extensionJson->url) ? $extensionJson->url : null, + 'core_version' => $extensionJson->core_version, + 'dependencies' => isset($extensionJson->dependencies) ? $extensionJson->dependencies : null, + 'server_kurzbz' => SERVER_NAME + ) + ); if (isSuccess($result)) { $this->_printSuccess(true); @@ -603,11 +619,11 @@ class ExtensionsLib { // If a directory with the same value of the version is present in the sql scripts directory if (($files = glob($pkgSQLsPath.'/'.$sqlDir.'/*'.ExtensionsLib::SQL_FILE_EXTENSION)) != false) - { + { // Loads every sql files - foreach ($files as $file) - { - $sql = file_get_contents($file); // gets the entire content of the file + foreach ($files as $file) + { + $sql = file_get_contents($file); // gets the entire content of the file $this->_printMessage('Executing query:'); $this->_printMessage($sql); @@ -623,11 +639,11 @@ class ExtensionsLib else { $this->_printMessage('Query result:'); - var_dump($result->retval); // KEEP IT!!! + var_dump(getData($result)); // KEEP IT!!! $this->_ci->eprintflib->printEOL(); } - } - } + } + } } $this->_printSuccess(!$this->_errorOccurred); @@ -816,7 +832,7 @@ class ExtensionsLib { // Remove them all from file system and DB $this->_printMessage('Removing entries in the DB related to this extension and from extensions directory'); - $this->delExtension($result->retval[0]->extension_id); + $this->delExtension(getData($result)[0]->extension_id); } } else // otherwise @@ -844,11 +860,10 @@ class ExtensionsLib $result = $this->_ci->ExtensionsModel->load($extensionId); if (hasData($result)) { - $extensionServer = $result->retval[0]->server_kurzbz; - if ($extensionServer !== SERVER_NAME) - return false; + // If this server is _not_ the same where the extension was installed then exit with a failure + if (getData($result)[0]->server_kurzbz != SERVER_NAME) return false; - $extensionName = $result->retval[0]->name; // extension name + $extensionName = getData($result)[0]->name; // extension name // If to be enabled if ($enabled === true) @@ -940,3 +955,4 @@ class ExtensionsLib $this->_printInfo('------------------------------------------------------------------------------------------'); } } + diff --git a/application/models/system/Extensions_model.php b/application/models/system/Extensions_model.php index 1beef4d8b..2dadaed0c 100644 --- a/application/models/system/Extensions_model.php +++ b/application/models/system/Extensions_model.php @@ -26,22 +26,6 @@ class Extensions_model extends DB_Model ); } - /** - * - */ - public function getInstalledExtensions() - { - $query = 'SELECT extension_id, e1.name, e1.version, description, license, url, core_version, dependencies, enabled, e1.server_kurzbz - FROM system.tbl_extensions e1 - INNER JOIN ( - SELECT name, MAX(version) AS version - FROM system.tbl_extensions - GROUP BY name) e2 - ON (e1.name = e2.name AND e1.version = e2.version)'; - - return $this->execQuery($query); - } - /** * */ @@ -50,3 +34,4 @@ class Extensions_model extends DB_Model return $this->execQuery($sql); } } + diff --git a/application/views/system/extensions/manager.php b/application/views/system/extensions/manager.php index 01111f295..ed85e45ea 100644 --- a/application/views/system/extensions/manager.php +++ b/application/views/system/extensions/manager.php @@ -103,12 +103,12 @@ Name Description + Server Version Licence URL Minimum required Core version Dependes on (extensions) - Server Enabled   @@ -140,12 +140,12 @@ $tableRow, $extension->name, $extension->description, + $extension->server_kurzbz, $extension->version, $extension->license, $extension->url, $extension->core_version, count($extension->dependencies) == 0 ? 'None' : json_encode($extension->dependencies), - $extension->server_kurzbz, $extension->extension_id, $extension->enabled === true ? 'checked' : '', $extension->extension_id @@ -171,3 +171,4 @@ load->view('templates/footer'); ?> + diff --git a/system/dbupdate_3.3.php b/system/dbupdate_3.3.php index 9141753aa..b8cbf8b53 100644 --- a/system/dbupdate_3.3.php +++ b/system/dbupdate_3.3.php @@ -5195,7 +5195,7 @@ $tabellen=array( "system.tbl_cronjob" => array("cronjob_id","server_kurzbz","titel","beschreibung","file","last_execute","aktiv","running","jahr","monat","tag","wochentag","stunde","minute","standalone","reihenfolge","updateamum", "updatevon","insertamum","insertvon","variablen"), "system.tbl_benutzerrolle" => array("benutzerberechtigung_id","rolle_kurzbz","berechtigung_kurzbz","uid","funktion_kurzbz","oe_kurzbz","art","studiensemester_kurzbz","start","ende","negativ","updateamum", "updatevon","insertamum","insertvon","kostenstelle_id","anmerkung"), "system.tbl_berechtigung" => array("berechtigung_kurzbz","beschreibung"), - "system.tbl_extensions" => array("extension_id","name","version","description","license","url","core_version","dependencies","enabled"), + "system.tbl_extensions" => array("extension_id","name","version","description","license","url","core_version","dependencies","enabled", "server_kurzbz"), "system.tbl_log" => array("log_id","person_id","zeitpunkt","app","oe_kurzbz","logtype_kurzbz","logdata","insertvon","taetigkeit_kurzbz"), "system.tbl_logtype" => array("logtype_kurzbz", "data_schema"), "system.tbl_filters" => array("filter_id","app","dataset_name","filter_kurzbz","person_id","description","sort","default_filter","filter","oe_kurzbz","statistik_kurzbz"), From 023e0fc9340e7c165829b52f38626cd3d250c1df Mon Sep 17 00:00:00 2001 From: Paolo Date: Mon, 27 Sep 2021 12:45:55 +0200 Subject: [PATCH 05/14] - Added new phrases fot the extension manager - Renamed uploadExtension to installExtension in application/controllers/system/extensions/CLI_Manager.php - Adapted controller system/extensions/Manager.php to use FHC_Controller functionalities - Changed controller system/extensions/Manager->uploadExtension to get parameters from HTTP post and HTTP file - Changed view system/extensions/manager.php to use templates/FHC-Header, ajaxlib, tablewidget, phrases and the CI upload library - Added new column type array to application/widgets/TableWidget.php - Added new type boolean to the public/js/AjaxLib.js result when checked by the hasData method - Added new JS public/js/ExtensionsManager.js that contains the extensions manager JS - Added new view system/extensions/tableWidget.php to display the extensions manager TableWidget --- .../system/extensions/CLI_Manager.php | 7 +- .../controllers/system/extensions/Manager.php | 35 +-- .../views/system/extensions/manager.php | 206 ++++-------------- .../views/system/extensions/tableWidget.php | 95 ++++++++ application/widgets/TableWidget.php | 13 ++ public/js/AjaxLib.js | 9 +- public/js/ExtensionsManager.js | 81 +++++++ public/js/TableWidget.js | 1 + system/phrasesupdate.php | 105 ++++++++- 9 files changed, 365 insertions(+), 187 deletions(-) create mode 100644 application/views/system/extensions/tableWidget.php create mode 100644 public/js/ExtensionsManager.js diff --git a/application/controllers/system/extensions/CLI_Manager.php b/application/controllers/system/extensions/CLI_Manager.php index 110fad9e8..fab511d09 100644 --- a/application/controllers/system/extensions/CLI_Manager.php +++ b/application/controllers/system/extensions/CLI_Manager.php @@ -11,8 +11,8 @@ class CLI_Manager extends CLI_Controller * */ public function __construct() - { - parent::__construct(); + { + parent::__construct(); // Load helpers to upload files $this->load->helper('form'); @@ -30,8 +30,9 @@ class CLI_Manager extends CLI_Controller * @param $filename Url Encoded Pfad zum tgz File der Extension * @param $perform_sql boolean ob die SQL Befehle ausgeführt werden */ - public function uploadExtension($extensionName = null, $filename = null, $perform_sql = true) + public function installExtension($extensionName, $filename, $perform_sql = true) { $this->extensionslib->installExtension($extensionName, urldecode($filename), $perform_sql); } } + diff --git a/application/controllers/system/extensions/Manager.php b/application/controllers/system/extensions/Manager.php index 429c967ae..571b283e8 100644 --- a/application/controllers/system/extensions/Manager.php +++ b/application/controllers/system/extensions/Manager.php @@ -11,8 +11,8 @@ class Manager extends Auth_Controller * */ public function __construct() - { - parent::__construct( + { + parent::__construct( array( 'index' => 'system/extensions:r', 'toggleExtension' => 'system/extensions:rw', @@ -21,11 +21,20 @@ class Manager extends Auth_Controller ) ); - // Load helpers to upload files + // Loads the form helper $this->load->helper('form'); + // Loads WidgetLib + $this->load->library('WidgetLib'); + // Loads the extensions library $this->load->library('ExtensionsLib'); + + $this->loadPhrases( + array( + 'extensions' + ) + ); } /** @@ -50,7 +59,7 @@ class Manager extends Auth_Controller $extension_id = $this->input->post('extension_id'); $enabled = $this->input->post('enabled'); - if ($enabled === 'true') + if ($enabled === true) { $toggleExtension = $this->extensionslib->enableExtension($extension_id); } @@ -59,9 +68,7 @@ class Manager extends Auth_Controller $toggleExtension = $this->extensionslib->disableExtension($extension_id); } - $this->output - ->set_content_type('application/json') - ->set_output(json_encode($toggleExtension)); + $this->outputJsonSuccess($toggleExtension); } /** @@ -69,15 +76,11 @@ class Manager extends Auth_Controller */ public function delExtension() { - $delExtension = false; - $extension_id = $this->input->post('extension_id'); $delExtension = $this->extensionslib->delExtension($extension_id); - $this->output - ->set_content_type('application/json') - ->set_output(json_encode($delExtension)); + $this->outputJsonSuccess($delExtension); } /** @@ -89,11 +92,11 @@ class Manager extends Auth_Controller * @param $filename Url Encoded Pfad zum tgz File der Extension * @param $perform_sql boolean ob die SQL Befehle ausgeführt werden */ - public function uploadExtension($extensionName = null, $filename = null, $perform_sql = true) + public function uploadExtension() { - $perform_sql = $this->input->post('databasechange'); - $perform_sql = isset($perform_sql) ? false : true; + $performSql = $this->input->post('performSql'); - $this->extensionslib->installExtension($extensionName, urldecode($filename), $perform_sql); + $this->extensionslib->installExtension(null, null, $performSql); } } + diff --git a/application/views/system/extensions/manager.php b/application/views/system/extensions/manager.php index ed85e45ea..ea1f0e9ae 100644 --- a/application/views/system/extensions/manager.php +++ b/application/views/system/extensions/manager.php @@ -1,174 +1,58 @@ -load->view('templates/header', array('title' => 'Extensions manager', 'jqueryV1' => true, 'tablesort' => true)); ?> +load->view( + 'templates/FHC-Header', + array( + // Title + 'title' => 'Extensions manager', - + // FHC JS & CSS includes + 'ajaxlib' => true, + 'dialoglib' => true, + 'tabulator' => true, + 'tablewidget' => true, + 'phrases' => array( + 'extensions' + ), + 'customJSs' => array('public/js/ExtensionsManager.js') + ) + ); +?> +
+ - '; - } - elseif (isError($extensions)) - { - echo 'An error occurred while retriving extenions list.'; - } - elseif (hasData($extensions)) - { - ?> +
+ load->view('system/extensions/tableWidget.php'); ?> +
+ +
- List of installed extensions + +
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - '; - - foreach ($extensions->retval as $key => $extension) - { - echo sprintf( - $tableRow, - $extension->name, - $extension->description, - $extension->server_kurzbz, - $extension->version, - $extension->license, - $extension->url, - $extension->core_version, - count($extension->dependencies) == 0 ? 'None' : json_encode($extension->dependencies), - $extension->extension_id, - $extension->enabled === true ? 'checked' : '', - $extension->extension_id - ); - } - ?> - - -
NameDescriptionServerVersionLicenceURLMinimum required Core versionDependes on (extensions)Enabled 
%s%s%s%s%s%s%s%s - - - Remove -
- - -
- - - -
- - - +
+
+ + +
+ +
-load->view('templates/footer'); ?> +load->view('templates/FHC-Footer'); ?> diff --git a/application/views/system/extensions/tableWidget.php b/application/views/system/extensions/tableWidget.php new file mode 100644 index 000000000..d2b6fe1aa --- /dev/null +++ b/application/views/system/extensions/tableWidget.php @@ -0,0 +1,95 @@ + ' + SELECT e.extension_id, + e.name, + e.description, + e.server_kurzbz, + e.version, + e.license, + e.url, + e.core_version, + e.dependencies, + e.enabled + FROM system.tbl_extensions e + ORDER BY e.name ASC, + e.server_kurzbz ASC, + e.version ASC + ', + 'tableUniqueId' => 'extensionsListTableWidget', + 'requiredPermissions' => 'system/extensions', + 'datasetRepresentation' => 'tabulator', + 'additionalColumns' => array('Delete'), + 'columnsAliases' => array( + 'Extension ID', + 'Name', + 'Description', + 'Server', + 'Version', + 'License', + 'URL', + 'Core version', + 'Dependencies', + 'Enabled' + ), + 'formatRow' => function($datasetRaw) { + + if ($datasetRaw->{'description'} == null) + { + $datasetRaw->{'description'} = '-'; + } + + if ($datasetRaw->{'server_kurzbz'} == null) + { + $datasetRaw->{'server_kurzbz'} = '-'; + } + + if ($datasetRaw->{'url'} == null) + { + $datasetRaw->{'url'} = '-'; + } + + if ($datasetRaw->{'license'} == null) + { + $datasetRaw->{'license'} = '-'; + } + + return $datasetRaw; + }, + 'datasetRepOptions' => '{ + height: "100%", + layout: "fitColumns", + persistentLayout: true, + persistentSort: true, + persistentFilter: true, + autoResize: false + }', + 'datasetRepFieldsDefs' => '{ + extension_id: {visible: false}, + url: { + formatter: "link" + }, + enabled: { + aligh: "center", + headerSort: false, + editor: true, + formatter: "tickCross", + cellEdited: function(cell) { + if (cell.getValue() != cell.getOldValue()) toggleExtension(cell.getData().extension_id, cell.getValue()); + } + }, + Delete: { + headerSort: false, + formatter: "buttonCross", + width: 100, + align: "center", + cellClick: function(e, cell) { + deleteExtension(cell.getData().extension_id, cell.getRow()); + } + } + }' + ); + + echo $this->widgetlib->widget('TableWidget', $tableWidgetArray); +?> + diff --git a/application/widgets/TableWidget.php b/application/widgets/TableWidget.php index 5a000601f..a0d452747 100644 --- a/application/widgets/TableWidget.php +++ b/application/widgets/TableWidget.php @@ -381,6 +381,19 @@ class TableWidget extends Widget { $rawDatasetRow->{$columnName} = ($columnValue === true ? 'true' : 'false'); } + // if it is an array + elseif (is_array($columnValue)) + { + // Default is an empty string + $rawDatasetRow->{$columnName} = ''; + + // For each element of the array + foreach ($columnValue as $value) + { + $rawDatasetRow->{$columnName} .= $value."\n"; // concatenate each element of the array + } + } + // if it is a date/timestamp elseif (DateTime::createFromFormat('Y-m-d H:i:s', $columnValue) !== false) { $rawDatasetRow->{$columnName} = date(self::DEFAULT_DATE_FORMAT, strtotime($columnValue)); diff --git a/public/js/AjaxLib.js b/public/js/AjaxLib.js index 283061dad..b8fc5a424 100644 --- a/public/js/AjaxLib.js +++ b/public/js/AjaxLib.js @@ -96,16 +96,17 @@ var FHC_AjaxClient = { hasData: function(response) { var hasData = false; - if (FHC_AjaxClient.isSuccess(response)) - { + if (FHC_AjaxClient.isSuccess(response)) + { if ((jQuery.type(response.retval) == "object" && !jQuery.isEmptyObject(response.retval)) || (jQuery.isArray(response.retval) && response.retval.length > 0) || (jQuery.type(response.retval) == "string" && response.retval.trim() != "") - || jQuery.type(response.retval) == "number") + || jQuery.type(response.retval) == "number" + || jQuery.type(response.retval) == "boolean") { hasData = true; } - } + } return hasData; }, diff --git a/public/js/ExtensionsManager.js b/public/js/ExtensionsManager.js new file mode 100644 index 000000000..71e3583f5 --- /dev/null +++ b/public/js/ExtensionsManager.js @@ -0,0 +1,81 @@ +/** + * FH-Complete + * + * @package + * @author + * @copyright Copyright (c) 2016-2021 + * @license GPLv3 + * @link https://fhcomplete.net + * @since Version 1.0.0 + */ + +/** + * Toggle the status of an extension + */ +function toggleExtension(extensionId, enabled) +{ + FHC_AjaxClient.ajaxCallPost( + "system/extensions/Manager/toggleExtension", + { + extension_id: extensionId, + enabled: enabled + }, + { + successCallback: function(data, textStatus, jqXHR) { + if (FHC_AjaxClient.hasData(data) && FHC_AjaxClient.getData(data) === true) + { + FHC_DialogLib.alertSuccess(FHC_PhrasesLib.t("extensions", "changeSuccess")); + } + else + { + FHC_DialogLib.alertError(FHC_PhrasesLib.t("extensions", "changeError")); + } + }, + errorCallback: function(data) { + FHC_DialogLib.alertError(FHC_PhrasesLib.t("extensions", "changeError")); + } + } + ); +} + +/** + * Delete an extension + * cellRow: tabulator row reference + */ +function deleteExtension(extensionId, cellRow) +{ + FHC_AjaxClient.ajaxCallPost( + "system/extensions/Manager/delExtension", + { + extension_id: extensionId + }, + { + successCallback: function(data, textStatus, jqXHR) { + if (FHC_AjaxClient.hasData(data) && FHC_AjaxClient.getData(data) === true) + { + cellRow.delete(); // delete the row from the tabulator + FHC_DialogLib.alertSuccess(FHC_PhrasesLib.t("extensions", "changeSuccess")); + } + else + { + FHC_DialogLib.alertError(FHC_PhrasesLib.t("extensions", "changeError")); + } + }, + errorCallback: function() { + FHC_DialogLib.alertError(FHC_PhrasesLib.t("extensions", "changeError")); + } + } + ); +} + +/** + * When JQuery is up + */ +$(document).ready(function() { + + $("#uploadExtension").click(function() { + $("form").submit(); + }); + +}); + diff --git a/public/js/TableWidget.js b/public/js/TableWidget.js index 6df20066e..6bfc8b610 100644 --- a/public/js/TableWidget.js +++ b/public/js/TableWidget.js @@ -896,3 +896,4 @@ $(document).ready(function() { FHC_TableWidget.display(); }); + diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 7cd0419ae..ec951a3b2 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -25,7 +25,6 @@ //flag for at least one new phrase $new = false; - $phrases = array( //******************* CORE/global array( @@ -12472,6 +12471,106 @@ array( ) ) ), + array( + 'app' => 'core', + 'category' => 'extensions', + 'phrase' => 'title', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Extensions manager', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Extensions manager', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'extensions', + 'phrase' => 'uploadExtension', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Upload extension', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Upload extension', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'extensions', + 'phrase' => 'performSql', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Do not perform SQL', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Do not perform SQL', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'extensions', + 'phrase' => 'changeSuccess', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'The extension have been correctly changed', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'The extension have been correctly changed', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'extensions', + 'phrase' => 'changeError', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'An error occurred while changing the extension', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'An error occurred while changing the extension', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), ); @@ -12594,5 +12693,5 @@ foreach ($phrases as $phrase) } } -if(!$new) - echo 'Keine neuen Phrasen
'; +if (!$new) echo 'Keine neuen Phrasen
'; + From e1c0d046cb0157802148a87c10c06a4f9071972e Mon Sep 17 00:00:00 2001 From: Paolo Date: Tue, 28 Sep 2021 09:11:18 +0200 Subject: [PATCH 06/14] HTML fixes views/system/extensions/manager.php --- .../views/system/extensions/manager.php | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/application/views/system/extensions/manager.php b/application/views/system/extensions/manager.php index ea1f0e9ae..43b61267f 100644 --- a/application/views/system/extensions/manager.php +++ b/application/views/system/extensions/manager.php @@ -39,16 +39,24 @@ -
- - +
+
+ +
+
+ +

-
- - +
+
+ +
+
+ +
From 8bbc68ca75c7098a05dbe3ce52205af873f1442d Mon Sep 17 00:00:00 2001 From: Paolo Date: Fri, 5 Nov 2021 13:19:44 +0100 Subject: [PATCH 07/14] Bufix: in case the file name contains not escaped / then it prints out an error and quit the execution --- application/libraries/ExtensionsLib.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/application/libraries/ExtensionsLib.php b/application/libraries/ExtensionsLib.php index ac74c1a64..39a83931b 100644 --- a/application/libraries/ExtensionsLib.php +++ b/application/libraries/ExtensionsLib.php @@ -91,6 +91,13 @@ class ExtensionsLib $uploadData = $this->_uploadExtension(); // perform the upload of the file and returns info about it } + // If the given filename is the upper directory or the current one + if (trim($uploadData->fullPath) == '..' || trim($uploadData->fullPath) == '.') + { + $this->_printFailure('wrong file name: / has to be escaped with %2F'); + $uploadData = null; // then it is a wrong one! + } + if ($uploadData != null) // if no error occurred { $this->_extractExtension($uploadData->fullPath); // extract the archive of the uploaded extension @@ -321,6 +328,16 @@ class ExtensionsLib $this->_printFailure('provided an invalid archive'); } catch (PharException $pe) + { + $this->_errorOccurred = true; + $this->_printFailure('phar error occurred'); + } + catch (InvalidArgumentException $iae) + { + $this->_errorOccurred = true; + $this->_printFailure('wrong file name'); + } + catch (Exception $e) { $this->_errorOccurred = true; $this->_printFailure('generic error occurred, check logs'); From 15f9762d018239d01888bf6f4c3af12431f5c1ff Mon Sep 17 00:00:00 2001 From: Paolo Date: Fri, 4 Mar 2022 12:26:37 +0100 Subject: [PATCH 08/14] - Fixed errors/violations noticed by PHPMD and PHPCS - Removed parameter perform_sql from public method controllers/system/extensions/CLI_Manager->installExtension - Added new public method controllers/system/extensions/CLI_Manager->installExtensionNoSQL - Improved code quality in controllers/system/extensions/Manager->toggleExtension - controllers/system/extensions/Manager->uploadExtension better check of HTTP POST parameter notPerformSql - application/views/system/extensions/manager.php renamed checkbox performSql to notPerformSql - application/views/system/extensions/tableWidget.php removed PHP close tag at the end of the file - Improved code quality in application/widgets/TableWidget.php - Removed private method _getColumnsNames from application/widgets/TableWidget.php - Improved code quality in application/libraries/ExtensionsLib.php - Added new private methods _getExtensionsPath and _getUploadPath to application/libraries/ExtensionsLib.php - Changed application/libraries/ExtensionsLib->_toggleExtension to public method toggleExtension - Removed private properties UPLOAD_PATH and EXTENSIONS_PATH from application/libraries/ExtensionsLib - Added use imports in application/libraries/ExtensionsLib - application/libraries/ExtensionsLib->installExtension changed parameters default values --- .../system/extensions/CLI_Manager.php | 12 +- .../controllers/system/extensions/Manager.php | 33 +- application/libraries/ExtensionsLib.php | 328 +++++++++--------- .../views/system/extensions/manager.php | 4 +- .../views/system/extensions/tableWidget.php | 3 +- application/widgets/TableWidget.php | 95 +++-- 6 files changed, 235 insertions(+), 240 deletions(-) diff --git a/application/controllers/system/extensions/CLI_Manager.php b/application/controllers/system/extensions/CLI_Manager.php index fab511d09..b5288cbae 100644 --- a/application/controllers/system/extensions/CLI_Manager.php +++ b/application/controllers/system/extensions/CLI_Manager.php @@ -30,9 +30,17 @@ class CLI_Manager extends CLI_Controller * @param $filename Url Encoded Pfad zum tgz File der Extension * @param $perform_sql boolean ob die SQL Befehle ausgeführt werden */ - public function installExtension($extensionName, $filename, $perform_sql = true) + public function installExtension($extensionName, $filename) { - $this->extensionslib->installExtension($extensionName, urldecode($filename), $perform_sql); + $this->extensionslib->installExtension($extensionName, urldecode($filename), true); + } + + /** + * Install an extension, same as installExtension but without running the SQL statements + */ + public function installExtensionNoSQL($extensionName, $filename) + { + $this->extensionslib->installExtension($extensionName, urldecode($filename), false); } } diff --git a/application/controllers/system/extensions/Manager.php b/application/controllers/system/extensions/Manager.php index 571b283e8..62fa70806 100644 --- a/application/controllers/system/extensions/Manager.php +++ b/application/controllers/system/extensions/Manager.php @@ -31,10 +31,10 @@ class Manager extends Auth_Controller $this->load->library('ExtensionsLib'); $this->loadPhrases( - array( - 'extensions' - ) - ); + array( + 'extensions' + ) + ); } /** @@ -54,21 +54,16 @@ class Manager extends Auth_Controller */ public function toggleExtension() { - $toggleExtension = false; - $extension_id = $this->input->post('extension_id'); $enabled = $this->input->post('enabled'); - if ($enabled === true) - { - $toggleExtension = $this->extensionslib->enableExtension($extension_id); - } - else - { - $toggleExtension = $this->extensionslib->disableExtension($extension_id); - } + // Clean the parameter + if ($enabled !== true) $enable = false; - $this->outputJsonSuccess($toggleExtension); + // Output the enable/disable of the extension + $this->outputJsonSuccess( + $this->extensionslib->toggleExtension($extension_id, $enable) + ); } /** @@ -94,9 +89,13 @@ class Manager extends Auth_Controller */ public function uploadExtension() { - $performSql = $this->input->post('performSql'); + $notPerformSql = $this->input->post('notPerformSql'); - $this->extensionslib->installExtension(null, null, $performSql); + // It converts the notPerformSql parameter from the checkbox value to a boolean one + if ($notPerformSql == 'on') $notPerformSql = true; + if ($notPerformSql !== true) $notPerformSql = false; + + $this->extensionslib->installExtension(null, null, !$notPerformSql); } } diff --git a/application/libraries/ExtensionsLib.php b/application/libraries/ExtensionsLib.php index 39a83931b..6f1ef0869 100644 --- a/application/libraries/ExtensionsLib.php +++ b/application/libraries/ExtensionsLib.php @@ -2,6 +2,9 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); +use \stdClass as stdClass; +use \PharData as PharData; + /** * Library to manage core extensions */ @@ -15,11 +18,18 @@ class ExtensionsLib const EXTENSION_JSON_NAME = 'extension.json'; // file that contains extension data const EXTENSIONS_DIR_NAME = 'extensions'; // name of the directories where will be created the symlinks - private $_ci; + const UPLOAD_PATH = 'tmp/'; - private $ARCHIVE_EXTENSIONS = array('.tgz', '.tbz2'); // accepted file extensions for an uploaded extension - private $UPLOAD_PATH; // temporary directory to store the upload file and checks the archive - private $EXTENSIONS_PATH; // directory where all the extensions are + private $_ci; // Code igniter instance + + private $_errorOccurred; // boolean, true if an error occurred while installing an extension + private $_currentInstalledExtensionVersion; // contains the version of the current installation of an extension + + // NOTE: the following have been declared as properties to maintain compatibility with previous PHP versions + // where arrays cannot be declared as constants + + // Accepted file extensions for an uploaded extension + private $ARCHIVE_EXTENSIONS = array('.tgz', '.tbz2'); // Directories that are part of the extension archive private $SOFTLINK_TARGET_DIRECTORIES = array( @@ -27,17 +37,11 @@ class ExtensionsLib DOC_ROOT => array('public') ); - private $_errorOccurred; // boolean, true if an error occurred while installing an extension - private $_currentInstalledExtensionVersion; // contains the version of the current installation of an extension - /** * Class constructor */ public function __construct() { - $this->UPLOAD_PATH = APPPATH.'tmp/'; - $this->EXTENSIONS_PATH = APPPATH.'extensions/'; - // Get code igniter instance $this->_ci =& get_instance(); @@ -72,20 +76,20 @@ class ExtensionsLib * @param $extensionName string Name of Extension (optional) * @param $filename Path to tgz Extension File (optional) */ - public function installExtension($extensionName = null, $filename = null, $perform_sql = true) + public function installExtension($extensionName, $filename, $perform_sql) { $extensionDB = null; // contains data from DB about an extension $extensionJson = null; // contains the extension.json data $this->_printInfo('WARNING!!! Please do not change page or stop this procedure before it is finished'); - if (!is_null($extensionName) && !is_null($filename)) - { - $uploadData = new stdClass(); - $uploadData->fullPath = $filename; - $uploadData->extensionName = $extensionName; - } - else + // Create an object with the given paramenters + $uploadData = new stdClass(); + $uploadData->fullPath = $filename; + $uploadData->extensionName = $extensionName; + + // If no extension name or file name are provided + if (is_null($extensionName) || is_null($filename)) { $this->_loadUploadLibrary(); // loads CI upload library $uploadData = $this->_uploadExtension(); // perform the upload of the file and returns info about it @@ -98,7 +102,8 @@ class ExtensionsLib $uploadData = null; // then it is a wrong one! } - if ($uploadData != null) // if no error occurred + // If the no error occurred + if ($uploadData != null) { $this->_extractExtension($uploadData->fullPath); // extract the archive of the uploaded extension @@ -128,13 +133,14 @@ class ExtensionsLib // Remove any previous installation from file system and database $this->_cleanPreviousInstallation($extensionJson); - $this->_installExtension($extensionJson); // records extension data in DB + // Records extension data in DB + $this->_installExtension($extensionJson); if (!$this->_errorOccurred && $perform_sql === true) // if no error occurred { - // Loads and executes neede SQL scripts + // Loads and executes needed SQL scripts $this->_loadSQLs( - $this->UPLOAD_PATH.$extensionJson->name.'/'.ExtensionsLib::SQL_DIRECTORY, + $this->_getUploadPath().$extensionJson->name.DIRECTORY_SEPARATOR.ExtensionsLib::SQL_DIRECTORY, $extensionJson ); } @@ -151,14 +157,6 @@ class ExtensionsLib $this->_createSymLinks($extensionJson->name); } } - else - { - $this->_errorOccurred = true; - } - } - else - { - $this->_errorOccurred = true; } if ($this->_errorOccurred === false) // if no errors occurred @@ -193,16 +191,21 @@ class ExtensionsLib if (getData($result)[0]->server_kurzbz != SERVER_NAME) return false; $extensionName = getData($result)[0]->name; // extension name - $this->_delSoftLinks($extensionName); // not to be checked, could fail if the extension is disabled - // remove the extension from the extensions installation directory - $delExtension = $this->_rrm($this->EXTENSIONS_PATH.$extensionName); + + // Not to be checked, could fail if the extension is disabled + $this->_delSoftLinks($extensionName); + + // Remove the extension from the extensions installation directory + $delExtension = $this->_rrm($this->_getExtensionsPath().$extensionName); // Select all the version of this extension $this->_ci->ExtensionsModel->addSelect('extension_id'); $result = $this->_ci->ExtensionsModel->loadWhere(array('name' => $extensionName, 'server_kurzbz' => SERVER_NAME)); - if (hasData($result)) // if something was found + + // If something was found + if (hasData($result)) { - foreach (getData($result) as $key => $extension) // loops on them + foreach (getData($result) as $extension) // loops on them { // Remove them all $result = $this->_ci->ExtensionsModel->delete($extension->extension_id); @@ -230,19 +233,49 @@ class ExtensionsLib } /** - * To enable an extension + * To enable/disable an extension */ - public function enableExtension($extensionId) + public function toggleExtension($extensionId, $enabled) { - return $this->_toggleExtension($extensionId, true); - } + $_toggleExtension = false; - /** - * To disable an extension - */ - public function disableExtension($extensionId) - { - return $this->_toggleExtension($extensionId, false); + // Loads data from DB about the given extension + $result = $this->_ci->ExtensionsModel->load($extensionId); + if (hasData($result)) + { + // If this server is _not_ the same where the extension was installed then exit with a failure + if (getData($result)[0]->server_kurzbz != SERVER_NAME) return false; + + $extensionName = getData($result)[0]->name; // extension name + + // If to be enabled + if ($enabled === true) + { + // Add the symlinks + $_toggleExtension = $this->_addSoftLinks($extensionName); + } + else // If to be disabled + { + // Remove all the symlinks + $_toggleExtension = $this->_delSoftLinks($extensionName); + } + + if ($_toggleExtension) // if is a success + { + // Updates DB + $result = $this->_ci->ExtensionsModel->update($extensionId, array('enabled' => $enabled)); + if (isSuccess($result)) + { + $_toggleExtension = true; + } + else // if DB update fails remove symlinks from file system + { + $this->_delSoftLinks($extensionName); + } + } + } + + return $_toggleExtension; } // ------------------------------------------------------------------------------------------------- @@ -256,7 +289,7 @@ class ExtensionsLib $this->_ci->load->library( 'upload', array( - 'upload_path' => $this->UPLOAD_PATH, + 'upload_path' => $this->_getUploadPath(), 'allowed_types' => '*', 'overwrite' => true ) @@ -320,7 +353,7 @@ class ExtensionsLib // Extracts the uploaded file $pd = new PharData($uploadPath); - $pd->extractTo($this->UPLOAD_PATH, null, true); + $pd->extractTo($this->_getUploadPath(), null, true); } catch (UnexpectedValueException $uva) { @@ -375,18 +408,14 @@ class ExtensionsLib $this->_errorOccurred = true; $this->_printFailure('data base error: '.getData($result)); } - else // otherwise + elseif (hasData($result)) { - if (hasData($result)) // if found - { - $extensionDB = getData($result)[0]; // return it! - } - else - { - $this->_printMessage('not found'); - } + $extensionDB = getData($result)[0]; } + // If no data have been found + if ($extensionDB == null) $this->_printMessage('not found'); + $this->_printSuccess(!$this->_errorOccurred); $this->_printEnd(); @@ -402,10 +431,10 @@ class ExtensionsLib $this->_printStart('Checking extension file system structure'); // Checks if the root directory of this archive has the same name of the extension - if (is_dir($this->UPLOAD_PATH.$extensionName)) + if (is_dir($this->_getUploadPath().$extensionName)) { // Checks if file extension.json exists inside the uploaded archive - if (!file_exists($this->UPLOAD_PATH.$extensionName.'/'.ExtensionsLib::EXTENSION_JSON_NAME)) + if (!file_exists($this->_getUploadPath().$extensionName.DIRECTORY_SEPARATOR.ExtensionsLib::EXTENSION_JSON_NAME)) { $this->_errorOccurred = true; $this->_printFailure('missing extension.json'); @@ -427,11 +456,14 @@ class ExtensionsLib */ private function _chkExtensionJson($extensionName, $extensionDB) { + // Set a default FHComplete version + $fhcomplete_version = 0; + $this->_printStart('Parsing and checking extension.json'); // Decodes extension.json $extensionJson = json_decode( - file_get_contents($this->UPLOAD_PATH.$extensionName.'/'.ExtensionsLib::EXTENSION_JSON_NAME) + file_get_contents($this->_getUploadPath().$extensionName.DIRECTORY_SEPARATOR.ExtensionsLib::EXTENSION_JSON_NAME) ); // Checks if the parameter name of the extension.json has the same value of the extension name @@ -634,8 +666,11 @@ class ExtensionsLib // Loops through the versions for ($sqlDir = $startVersion; $sqlDir <= $extensionJson->version; $sqlDir++) { + // Gets all the SQL files in the directory having the same name of the version + $files = glob($pkgSQLsPath.DIRECTORY_SEPARATOR.$sqlDir.'/*'.ExtensionsLib::SQL_FILE_EXTENSION); + // If a directory with the same value of the version is present in the sql scripts directory - if (($files = glob($pkgSQLsPath.'/'.$sqlDir.'/*'.ExtensionsLib::SQL_FILE_EXTENSION)) != false) + if ($files != false) { // Loads every sql files foreach ($files as $file) @@ -646,7 +681,10 @@ class ExtensionsLib $this->_printMessage($sql); // Try to execute that - if (!isSuccess($result = @$this->_ci->ExtensionsModel->executeQuery($sql))) + $result = @$this->_ci->ExtensionsModel->executeQuery($sql); + + // If was not a success + if (!isSuccess($result)) { $this->_errorOccurred = true; $this->_printFailure(' error occurred while executing the query'); @@ -660,7 +698,7 @@ class ExtensionsLib $this->_ci->eprintflib->printEOL(); } } - } + } } $this->_printSuccess(!$this->_errorOccurred); @@ -675,12 +713,12 @@ class ExtensionsLib { $this->_printStart('Moving the upload extension from upload folder to extension folder'); - $this->_printMessage('Current extension directory: '.$this->UPLOAD_PATH.$extensionName); - $this->_printMessage('Directory where it will be moved: '.$this->EXTENSIONS_PATH.$extensionName); + $this->_printMessage('Current extension directory: '.$this->_getUploadPath().$extensionName); + $this->_printMessage('Directory where it will be moved: '.$this->_getExtensionsPath().$extensionName); - if (!file_exists($this->EXTENSIONS_PATH.$extensionName)) + if (!file_exists($this->_getExtensionsPath().$extensionName)) { - if (rename($this->UPLOAD_PATH.$extensionName.'/', $this->EXTENSIONS_PATH.$extensionName)) + if (rename($this->_getUploadPath().$extensionName.DIRECTORY_SEPARATOR, $this->_getExtensionsPath().$extensionName)) { $this->_printSuccess(true); } @@ -722,13 +760,21 @@ class ExtensionsLib { $_delSoftLinks = false; + // For every set of target directories where: + // rootPath: is the prefix of the absolute path for the target directory + // targetDirectories: is an array of target directories foreach ($this->SOFTLINK_TARGET_DIRECTORIES as $rootPath => $targetDirectories) { - foreach ($targetDirectories as $key => $targetDirectory) + // For every target directory in the current set + foreach ($targetDirectories as $targetDirectory) { - if (file_exists($rootPath.$targetDirectory.'/'.ExtensionsLib::EXTENSIONS_DIR_NAME.'/'.$extensionName)) + // If the symlink exists + if (file_exists($rootPath.$targetDirectory.DIRECTORY_SEPARATOR.ExtensionsLib::EXTENSIONS_DIR_NAME.DIRECTORY_SEPARATOR.$extensionName)) { - $_delSoftLinks = unlink($rootPath.$targetDirectory.'/'.ExtensionsLib::EXTENSIONS_DIR_NAME.'/'.$extensionName); + // Try to delete it + $_delSoftLinks = unlink( + $rootPath.$targetDirectory.DIRECTORY_SEPARATOR.ExtensionsLib::EXTENSIONS_DIR_NAME.DIRECTORY_SEPARATOR.$extensionName + ); } } } @@ -741,29 +787,23 @@ class ExtensionsLib */ private function _rrm($dir) { - if (!file_exists($dir)) + // If the directory does not exist return success + if (!file_exists($dir)) return true; + + // If it is not a directory then delete it and return the result + if (!is_dir($dir)) return unlink($dir); + + // For each subdirectory + foreach (scandir($dir) as $subdir) { - return true; - } - - if (!is_dir($dir)) - { - return unlink($dir); - } - - foreach (scandir($dir) as $item) - { - if ($item == '.' || $item == '..') - { - continue; - } - - if (!$this->_rrm($dir.DIRECTORY_SEPARATOR.$item)) - { - return false; - } + // If it is the same directory or the parent directory skip to the next one + if ($subdir == '.' || $subdir == '..') continue; + + // Try to remove a subdirectory, if it fails then return a failure + if (!$this->_rrm($dir.DIRECTORY_SEPARATOR.$subdir)) return false; } + // Delete the directory and return the result return rmdir($dir); } @@ -773,42 +813,41 @@ class ExtensionsLib private function _addSoftLinks($extensionName) { $_addSoftLinks = false; - $extensionPath = $this->EXTENSIONS_PATH.$extensionName.'/'; + $extensionPath = $this->_getExtensionsPath().$extensionName.DIRECTORY_SEPARATOR; - // For every target directory + // For every set of target directories where: + // rootPath: is the prefix of the absolute path for the target directory + // targetDirectories: is an array of target directories foreach ($this->SOFTLINK_TARGET_DIRECTORIES as $rootPath => $targetDirectories) { - foreach ($targetDirectories as $key => $targetDirectory) + // For every target directory in the current set + foreach ($targetDirectories as $targetDirectory) { - // If destination of the symlink does not exist - if (!file_exists($rootPath.$targetDirectory.'/'.ExtensionsLib::EXTENSIONS_DIR_NAME.'/'.$extensionName)) + // Checks if the link already exists + $_addSoftLinks = file_exists( + $rootPath.$targetDirectory.DIRECTORY_SEPARATOR.ExtensionsLib::EXTENSIONS_DIR_NAME.DIRECTORY_SEPARATOR.$extensionName + ); + + // If the symlink does not exist + if (!$_addSoftLinks) { - // If the target directory does not exist than creates that - if (!is_dir($extensionPath.$targetDirectory)) - { - mkdir($extensionPath.$targetDirectory); - } + // If the target directory does not exist than creates it + if (!is_dir($extensionPath.$targetDirectory)) mkdir($extensionPath.$targetDirectory); - if (!file_exists($rootPath.$targetDirectory.'/'.ExtensionsLib::EXTENSIONS_DIR_NAME.'/'.$extensionName)) - { - // Create the symlink - $_addSoftLinks = symlink( - $extensionPath.$targetDirectory, - $rootPath.$targetDirectory.'/'.ExtensionsLib::EXTENSIONS_DIR_NAME.'/'.$extensionName - ); - }else - { - $_addSoftLinks = true; - } + // Create the symlink + $_addSoftLinks = @symlink( + // Target + $extensionPath.$targetDirectory, + // Link + $rootPath.$targetDirectory.DIRECTORY_SEPARATOR.ExtensionsLib::EXTENSIONS_DIR_NAME.DIRECTORY_SEPARATOR.$extensionName + ); + // On failure if (!$_addSoftLinks) { log_message('error', 'Failed to create Symlink to '.$extensionPath.$targetDirectory); break; } - }else - { - $_addSoftLinks = true; } } } @@ -833,9 +872,9 @@ class ExtensionsLib $this->_printMessage('Removing the extracted data from the upload directory'); if ($uploadData != null && isset($uploadData->extensionName) - && file_exists($this->UPLOAD_PATH.$uploadData->extensionName)) + && file_exists($this->_getUploadPath().$uploadData->extensionName)) { - $this->_rrm($this->UPLOAD_PATH.$uploadData->extensionName); + $this->_rrm($this->_getUploadPath().$uploadData->extensionName); } // If the upload of the file is a success and the extension name is present and no previous installation were found @@ -852,13 +891,10 @@ class ExtensionsLib $this->delExtension(getData($result)[0]->extension_id); } } - else // otherwise + // Otherwise remove them all only from DB + elseif ($extensionJson != null && isset($extensionJson->extension_id)) { - // Remove them all only from DB - if ($extensionJson != null && isset($extensionJson->extension_id)) - { - $this->_ci->ExtensionsModel->delete($extensionJson->extension_id); - } + $this->_ci->ExtensionsModel->delete($extensionJson->extension_id); } $this->_printMessage('Rollback finished'); @@ -867,49 +903,19 @@ class ExtensionsLib } /** - * To enable/disable an extension + * Returns the absolute upload path */ - private function _toggleExtension($extensionId, $enabled) + private function _getUploadPath() { - $_toggleExtension = false; + return APPPATH.self::UPLOAD_PATH; + } - // Loads data from DB about the given extension - $result = $this->_ci->ExtensionsModel->load($extensionId); - if (hasData($result)) - { - // If this server is _not_ the same where the extension was installed then exit with a failure - if (getData($result)[0]->server_kurzbz != SERVER_NAME) return false; - - $extensionName = getData($result)[0]->name; // extension name - - // If to be enabled - if ($enabled === true) - { - // Add the symlinks - $_toggleExtension = $this->_addSoftLinks($extensionName); - } - else // If to be disabled - { - // Remove all the symlinks - $_toggleExtension = $this->_delSoftLinks($extensionName); - } - - if ($_toggleExtension) // if is a success - { - // Updates DB - $result = $this->_ci->ExtensionsModel->update($extensionId, array('enabled' => $enabled)); - if (isSuccess($result)) - { - $_toggleExtension = true; - } - else // if DB update fails remove symlinks from file system - { - $this->_delSoftLinks($extensionName); - } - } - } - - return $_toggleExtension; + /** + * Returns the absolute extensions path + */ + private function _getExtensionsPath() + { + return APPPATH.self::EXTENSIONS_DIR_NAME.DIRECTORY_SEPARATOR; } /** diff --git a/application/views/system/extensions/manager.php b/application/views/system/extensions/manager.php index 43b61267f..e3116fcdb 100644 --- a/application/views/system/extensions/manager.php +++ b/application/views/system/extensions/manager.php @@ -52,10 +52,10 @@
- +
- +
diff --git a/application/views/system/extensions/tableWidget.php b/application/views/system/extensions/tableWidget.php index d2b6fe1aa..e9885bb68 100644 --- a/application/views/system/extensions/tableWidget.php +++ b/application/views/system/extensions/tableWidget.php @@ -32,7 +32,7 @@ 'Dependencies', 'Enabled' ), - 'formatRow' => function($datasetRaw) { + 'formatRow' => function ($datasetRaw) { if ($datasetRaw->{'description'} == null) { @@ -91,5 +91,4 @@ ); echo $this->widgetlib->widget('TableWidget', $tableWidgetArray); -?> diff --git a/application/widgets/TableWidget.php b/application/widgets/TableWidget.php index a0d452747..fca074f0b 100644 --- a/application/widgets/TableWidget.php +++ b/application/widgets/TableWidget.php @@ -213,51 +213,49 @@ class TableWidget extends Widget */ private function _checkParameters($args) { - // If no options are given to this widget... + // If no options are given to this widget then ends the execution if (!is_array($args) || (is_array($args) && count($args) == 0)) { show_error('Second parameter of the widget call must be a NOT empty associative array'); } - else // ...otherwise + + // The unique id parameter is mandatory + if (!isset($args[TableWidgetLib::TABLE_UNIQUE_ID])) { - // The unique id parameter is mandatory - if (!isset($args[TableWidgetLib::TABLE_UNIQUE_ID])) - { - show_error('The parameter "'.TableWidgetLib::TABLE_UNIQUE_ID.'" must be specified'); - } + show_error('The parameter "'.TableWidgetLib::TABLE_UNIQUE_ID.'" must be specified'); + } - // The query parameter is mandatory - if (!isset($args[TableWidgetLib::QUERY])) - { - show_error('The parameter "'.TableWidgetLib::QUERY.'" must be specified'); - } + // The query parameter is mandatory + if (!isset($args[TableWidgetLib::QUERY])) + { + show_error('The parameter "'.TableWidgetLib::QUERY.'" must be specified'); + } - // The dataset representation parameter is mandatory - if (!isset($args[TableWidgetLib::DATASET_REPRESENTATION])) - { - show_error('The parameter "'.TableWidgetLib::DATASET_REPRESENTATION.'" must be specified'); - } + // The dataset representation parameter is mandatory + if (!isset($args[TableWidgetLib::DATASET_REPRESENTATION])) + { + show_error('The parameter "'.TableWidgetLib::DATASET_REPRESENTATION.'" must be specified'); + } - // Checks if the dataset representation parameter is valid - if (isset($args[TableWidgetLib::DATASET_REPRESENTATION]) - && $args[TableWidgetLib::DATASET_REPRESENTATION] != TableWidgetLib::DATASET_REP_TABLESORTER - && $args[TableWidgetLib::DATASET_REPRESENTATION] != TableWidgetLib::DATASET_REP_PIVOTUI - && $args[TableWidgetLib::DATASET_REPRESENTATION] != TableWidgetLib::DATASET_REP_TABULATOR) - { - show_error( - 'The parameter "'.TableWidgetLib::DATASET_REPRESENTATION. - '" must be IN ("' - .TableWidgetLib::DATASET_REP_TABLESORTER.'", "' - .TableWidgetLib::DATASET_REP_PIVOTUI.'", "' - .TableWidgetLib::DATASET_REP_TABULATOR.'")' - ); - } + // Checks if the dataset representation parameter is valid + if (isset($args[TableWidgetLib::DATASET_REPRESENTATION]) + && $args[TableWidgetLib::DATASET_REPRESENTATION] != TableWidgetLib::DATASET_REP_TABLESORTER + && $args[TableWidgetLib::DATASET_REPRESENTATION] != TableWidgetLib::DATASET_REP_PIVOTUI + && $args[TableWidgetLib::DATASET_REPRESENTATION] != TableWidgetLib::DATASET_REP_TABULATOR) + { + show_error( + 'The parameter "'.TableWidgetLib::DATASET_REPRESENTATION. + '" must be IN ("' + .TableWidgetLib::DATASET_REP_TABLESORTER.'", "' + .TableWidgetLib::DATASET_REP_PIVOTUI.'", "' + .TableWidgetLib::DATASET_REP_TABULATOR.'")' + ); + } - // If given the session timeout parameter must be a number - if (isset($args[TableWidgetLib::SESSION_TIMEOUT]) && !is_numeric($args[TableWidgetLib::SESSION_TIMEOUT])) - { - show_error('The parameter "'.TableWidgetLib::SESSION_TIMEOUT.'" must be a number'); - } + // If given the session timeout parameter must be a number + if (isset($args[TableWidgetLib::SESSION_TIMEOUT]) && !is_numeric($args[TableWidgetLib::SESSION_TIMEOUT])) + { + show_error('The parameter "'.TableWidgetLib::SESSION_TIMEOUT.'" must be a number'); } } @@ -330,8 +328,10 @@ class TableWidget extends Widget TableWidgetLib::SESSION_DATASET => $dataset->retval, // the entire dataset TableWidgetLib::SESSION_DATASET_RELOAD => false, // if the dataset must be reloaded, not needed the first time TableWidgetLib::SESSION_DATASET_REPRESENTATION => $this->_datasetRepresentation, // the choosen dataset representation - TableWidgetLib::SESSION_DATASET_REP_OPTIONS => $this->_datasetRepresentationOptions, // the choosen dataset representation options - TableWidgetLib::SESSION_DATASET_REP_FIELDS_DEFS => $this->_datasetRepFieldsDefs // the choosen dataset representation record fields definition + // The choosen dataset representation options + TableWidgetLib::SESSION_DATASET_REP_OPTIONS => $this->_datasetRepresentationOptions, + // The choosen dataset representation record fields definition + TableWidgetLib::SESSION_DATASET_REP_FIELDS_DEFS => $this->_datasetRepFieldsDefs ) ); } @@ -424,24 +424,6 @@ class TableWidget extends Widget return !isset($class) ? '' : $class; } - /** - * Utility method that retrieves the name of the columns present in a table JSON definition - */ - private function _getColumnsNames($columns) - { - $columnsNames = array(); - - foreach ($columns as $key => $obj) - { - if (isset($obj->name)) - { - $columnsNames[] = $obj->name; - } - } - - return $columnsNames; - } - /** * Loads a view using the given viewName and eventually other parameters */ @@ -451,3 +433,4 @@ class TableWidget extends Widget $ci->load->view($viewName, $parameters); } } + From 16d88d9f638be29ba592966e4c6a361fbbc56528 Mon Sep 17 00:00:00 2001 From: Paolo Date: Wed, 13 Apr 2022 14:21:19 +0200 Subject: [PATCH 09/14] Controller system/extensions/Manager->toggleExtension now convert the enabled parameter from string to boolean --- application/controllers/system/extensions/Manager.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/application/controllers/system/extensions/Manager.php b/application/controllers/system/extensions/Manager.php index 62fa70806..e70377994 100644 --- a/application/controllers/system/extensions/Manager.php +++ b/application/controllers/system/extensions/Manager.php @@ -58,11 +58,11 @@ class Manager extends Auth_Controller $enabled = $this->input->post('enabled'); // Clean the parameter - if ($enabled !== true) $enable = false; + $enabled = $enabled == 'true' ? true : false; // Output the enable/disable of the extension $this->outputJsonSuccess( - $this->extensionslib->toggleExtension($extension_id, $enable) + $this->extensionslib->toggleExtension($extension_id, $enabled) ); } From 16f6176d08948f02e145876c71deb8142bb68979 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96sterreicher?= Date: Wed, 13 Apr 2022 19:01:16 +0200 Subject: [PATCH 10/14] Extension Manager - Added missing Phrases --- application/controllers/system/extensions/Manager.php | 5 +++-- application/views/system/extensions/manager.php | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/application/controllers/system/extensions/Manager.php b/application/controllers/system/extensions/Manager.php index e70377994..115fdba29 100644 --- a/application/controllers/system/extensions/Manager.php +++ b/application/controllers/system/extensions/Manager.php @@ -32,7 +32,9 @@ class Manager extends Auth_Controller $this->loadPhrases( array( - 'extensions' + 'extensions', + 'table', + 'ui' ) ); } @@ -98,4 +100,3 @@ class Manager extends Auth_Controller $this->extensionslib->installExtension(null, null, !$notPerformSql); } } - diff --git a/application/views/system/extensions/manager.php b/application/views/system/extensions/manager.php index e3116fcdb..c163c538b 100644 --- a/application/views/system/extensions/manager.php +++ b/application/views/system/extensions/manager.php @@ -21,7 +21,9 @@ 'tabulator' => true, 'tablewidget' => true, 'phrases' => array( - 'extensions' + 'extensions', + 'table', + 'ui' ), 'customJSs' => array('public/js/ExtensionsManager.js') ) @@ -29,7 +31,7 @@ ?> -
+
@@ -63,4 +65,3 @@ load->view('templates/FHC-Footer'); ?> - From 5e799aa6e123f29ee13abe31eee77fff8b1bbb22 Mon Sep 17 00:00:00 2001 From: Paolo Date: Wed, 5 Apr 2023 14:31:00 +0200 Subject: [PATCH 11/14] Moved DB changes from system/dbupdate_3.3.php to system/dbupdate_3.4/13011_installation_on_multiple_servers.php --- system/dbupdate_3.3.php | 34 ++++------------------------------ 1 file changed, 4 insertions(+), 30 deletions(-) diff --git a/system/dbupdate_3.3.php b/system/dbupdate_3.3.php index ba8a72cea..f57b9d172 100644 --- a/system/dbupdate_3.3.php +++ b/system/dbupdate_3.3.php @@ -1012,39 +1012,13 @@ if ($result = @$db->db_query("SELECT conname FROM pg_constraint WHERE conname = // UNIQUE INDEX uidx_extensions_name_version if ($result = $db->db_query("SELECT 0 FROM pg_class WHERE relname = 'uidx_extensions_name_version'")) { - if ($db->db_num_rows($result) == 1) + if ($db->db_num_rows($result) == 0) { - $qry = 'DROP INDEX system.uidx_extensions_name_version'; + $qry = 'CREATE UNIQUE INDEX uidx_extensions_name_version ON system.tbl_extensions USING btree (name, version);'; if (!$db->db_query($qry)) echo 'uidx_extensions_name_version '.$db->db_last_error().'
'; else - echo '
Dropped unique uidx_extensions_name_version'; - } -} - -// stud_selfservice boolean fuer public.tbl_vorlage -if(!@$db->db_query("SELECT server_kurzbz FROM system.tbl_extensions LIMIT 1")) -{ - $qry = "ALTER TABLE system.tbl_extensions ADD COLUMN server_kurzbz varchar(64); - ALTER TABLE system.tbl_extensions ADD CONSTRAINT fk_extensios_server_kurzbz FOREIGN KEY (server_kurzbz) REFERENCES system.tbl_server(server_kurzbz) ON UPDATE CASCADE ON DELETE RESTRICT;"; - - if(!$db->db_query($qry)) - echo 'App: '.$db->db_last_error().'
'; - else - echo '
Neue Spalte server_kurzbz in system.tbl_extensions hinzugefügt'; -} - - -// UNIQUE INDEX uidx_extensions_name_version_server -if ($result = $db->db_query("SELECT 0 FROM pg_class WHERE relname = 'uidx_extensions_name_version_server'")) -{ - if ($db->db_num_rows($result) == 0) - { - $qry = 'CREATE UNIQUE INDEX uidx_extensions_name_version_server ON system.tbl_extensions USING btree (name, version, server_kurzbz);'; - if (!$db->db_query($qry)) - echo 'uidx_extensions_name_version_server '.$db->db_last_error().'
'; - else - echo '
Created unique uidx_extensions_name_version_server'; + echo '
Created unique uidx_extensions_name_version'; } } @@ -7097,7 +7071,7 @@ $tabellen=array( "system.tbl_cronjob" => array("cronjob_id","server_kurzbz","titel","beschreibung","file","last_execute","aktiv","running","jahr","monat","tag","wochentag","stunde","minute","standalone","reihenfolge","updateamum", "updatevon","insertamum","insertvon","variablen"), "system.tbl_benutzerrolle" => array("benutzerberechtigung_id","rolle_kurzbz","berechtigung_kurzbz","uid","funktion_kurzbz","oe_kurzbz","art","studiensemester_kurzbz","start","ende","negativ","updateamum", "updatevon","insertamum","insertvon","kostenstelle_id","anmerkung"), "system.tbl_berechtigung" => array("berechtigung_kurzbz","beschreibung"), - "system.tbl_extensions" => array("extension_id","name","version","description","license","url","core_version","dependencies","enabled", "server_kurzbz"), + "system.tbl_extensions" => array("extension_id","name","version","description","license","url","core_version","dependencies","enabled"), "system.tbl_fehler" => array("fehlercode","fehler_kurzbz","fehlercode_extern","fehlertext","fehlertyp_kurzbz","app"), "system.tbl_fehlertyp" => array("fehlertyp_kurzbz","bezeichnung_mehrsprachig"), "system.tbl_fehler_zustaendigkeiten" => array("fehlerzustaendigkeiten_id","fehlercode","person_id","oe_kurzbz","funktion_kurzbz", "insertamum", "insertvon"), From e60335b635a8cbf4507f4aac6d1bf94292b29781 Mon Sep 17 00:00:00 2001 From: Paolo Date: Wed, 5 Apr 2023 14:33:27 +0200 Subject: [PATCH 12/14] Added new DB file system/dbupdate_3.4/13011_installation_on_multiple_servers.php --- ...13011_installation_on_multiple_servers.php | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 system/dbupdate_3.4/13011_installation_on_multiple_servers.php diff --git a/system/dbupdate_3.4/13011_installation_on_multiple_servers.php b/system/dbupdate_3.4/13011_installation_on_multiple_servers.php new file mode 100644 index 000000000..24c496457 --- /dev/null +++ b/system/dbupdate_3.4/13011_installation_on_multiple_servers.php @@ -0,0 +1,36 @@ +db_query("SELECT server_kurzbz FROM system.tbl_extensions LIMIT 1")) +{ + $qry = "ALTER TABLE system.tbl_extensions ADD COLUMN server_kurzbz varchar(64); + ALTER TABLE system.tbl_extensions ADD CONSTRAINT fk_extensios_server_kurzbz FOREIGN KEY (server_kurzbz) REFERENCES system.tbl_server(server_kurzbz) ON UPDATE CASCADE ON DELETE RESTRICT;"; + + if(!$db->db_query($qry)) + echo 'App: '.$db->db_last_error().'
'; + else + echo '
Neue Spalte server_kurzbz in system.tbl_extensions hinzugefügt'; +} + + +// UNIQUE INDEX uidx_extensions_name_version_server +if ($result = $db->db_query("SELECT 0 FROM pg_class WHERE relname = 'uidx_extensions_name_version_server'")) +{ + if ($db->db_num_rows($result) == 1) + { + $qry = 'DROP INDEX system.uidx_extensions_name_version'; + if (!$db->db_query($qry)) + echo 'uidx_extensions_name_version_server '.$db->db_last_error().'
'; + else + echo '
Dropped unique uidx_extensions_name_version_server'; + } + + $qry = 'CREATE UNIQUE INDEX uidx_extensions_name_version_server ON system.tbl_extensions USING btree (name, version, server_kurzbz);'; + if (!$db->db_query($qry)) + echo 'uidx_extensions_name_version_server '.$db->db_last_error().'
'; + else + echo '
Created unique uidx_extensions_name_version_server'; +} + From 5465f26c804df81af26d3274261d042e427af983 Mon Sep 17 00:00:00 2001 From: Paolo Date: Thu, 6 Apr 2023 11:56:06 +0200 Subject: [PATCH 13/14] - Fixed deletion of the uidx_extensions_name_version index in the system DB update scripts - Fixed creatation of uidx_extensions_name_version_server index in the system DB update scripts --- system/dbupdate_3.4.php | 1 + ...13011_installation_on_multiple_servers.php | 37 +++++++++++++------ 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/system/dbupdate_3.4.php b/system/dbupdate_3.4.php index bc8152a90..2631b64c8 100644 --- a/system/dbupdate_3.4.php +++ b/system/dbupdate_3.4.php @@ -32,6 +32,7 @@ require_once('dbupdate_3.4/26173_index_webservicelog.php'); require_once('dbupdate_3.4/24682_reihungstest_zugangscode_fuer_login.php'); require_once('dbupdate_3.4/17512_fehlercode_constraints.php'); require_once('dbupdate_3.4/19154_beurteilungsformulare_pruefungssenat.php'); +require_once('dbupdate_3.4/13011_installation_on_multiple_servers.php'); // *** Pruefung und hinzufuegen der neuen Attribute und Tabellen echo '

Pruefe Tabellen und Attribute!

'; diff --git a/system/dbupdate_3.4/13011_installation_on_multiple_servers.php b/system/dbupdate_3.4/13011_installation_on_multiple_servers.php index 24c496457..22f8b20f9 100644 --- a/system/dbupdate_3.4/13011_installation_on_multiple_servers.php +++ b/system/dbupdate_3.4/13011_installation_on_multiple_servers.php @@ -3,34 +3,47 @@ if (! defined('DB_NAME')) exit('No direct script access allowed'); // stud_selfservice boolean fuer public.tbl_vorlage -if(!@$db->db_query("SELECT server_kurzbz FROM system.tbl_extensions LIMIT 1")) +if (!@$db->db_query("SELECT server_kurzbz FROM system.tbl_extensions LIMIT 1")) { $qry = "ALTER TABLE system.tbl_extensions ADD COLUMN server_kurzbz varchar(64); ALTER TABLE system.tbl_extensions ADD CONSTRAINT fk_extensios_server_kurzbz FOREIGN KEY (server_kurzbz) REFERENCES system.tbl_server(server_kurzbz) ON UPDATE CASCADE ON DELETE RESTRICT;"; - if(!$db->db_query($qry)) + if (!$db->db_query($qry)) echo 'App: '.$db->db_last_error().'
'; else echo '
Neue Spalte server_kurzbz in system.tbl_extensions hinzugefügt'; } -// UNIQUE INDEX uidx_extensions_name_version_server -if ($result = $db->db_query("SELECT 0 FROM pg_class WHERE relname = 'uidx_extensions_name_version_server'")) +// UNIQUE INDEX uidx_extensions_name_version +if ($result = $db->db_query("SELECT COUNT(*) FROM pg_class WHERE relname = 'uidx_extensions_name_version'")) { - if ($db->db_num_rows($result) == 1) + $countObj = $db->db_fetch_object($result); + + // If exists then drop it + if ($countObj->count == '1') { $qry = 'DROP INDEX system.uidx_extensions_name_version'; if (!$db->db_query($qry)) - echo 'uidx_extensions_name_version_server '.$db->db_last_error().'
'; + echo 'uidx_extensions_name_version '.$db->db_last_error().'
'; else - echo '
Dropped unique uidx_extensions_name_version_server'; + echo '
Dropped unique uidx_extensions_name_version'; } - $qry = 'CREATE UNIQUE INDEX uidx_extensions_name_version_server ON system.tbl_extensions USING btree (name, version, server_kurzbz);'; - if (!$db->db_query($qry)) - echo 'uidx_extensions_name_version_server '.$db->db_last_error().'
'; - else - echo '
Created unique uidx_extensions_name_version_server'; + // UNIQUE INDEX uidx_extensions_name_version_server + if ($result = $db->db_query("SELECT COUNT(*) FROM pg_class WHERE relname = 'uidx_extensions_name_version_server'")) + { + $countObj = $db->db_fetch_object($result); + + // If does not exist then create it + if ($countObj->count == '0') + { + $qry = 'CREATE UNIQUE INDEX uidx_extensions_name_version_server ON system.tbl_extensions USING btree (name, version, server_kurzbz);'; + if (!$db->db_query($qry)) + echo 'uidx_extensions_name_version_server '.$db->db_last_error().'
'; + else + echo '
Created unique uidx_extensions_name_version_server'; + } + } } From 4944a13bfc88b93752c9bb6e21c0db0fb8f51f8e Mon Sep 17 00:00:00 2001 From: Paolo Date: Thu, 6 Apr 2023 12:21:17 +0200 Subject: [PATCH 14/14] Fixed JS & CSS includes for the Extensions manager --- application/views/system/extensions/manager.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/application/views/system/extensions/manager.php b/application/views/system/extensions/manager.php index c163c538b..afe93942f 100644 --- a/application/views/system/extensions/manager.php +++ b/application/views/system/extensions/manager.php @@ -6,19 +6,19 @@ 'title' => 'Extensions manager', // JS & CSS includes - 'jquery' => true, - 'jqueryui' => true, - 'jquerycheckboxes' => true, - 'bootstrap' => true, + 'jquery3' => true, + 'jqueryui1' => true, + 'jquerycheckboxes1' => true, + 'bootstrap3' => true, + 'tabulator4' => true, // Styles includes - 'fontawesome' => true, - 'sbadmintemplate' => true, + 'fontawesome4' => true, + 'sbadmintemplate3' => true, // FHC JS & CSS includes 'ajaxlib' => true, 'dialoglib' => true, - 'tabulator' => true, 'tablewidget' => true, 'phrases' => array( 'extensions',