mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-07-16 22:42:16 +00:00
Merge branch 'feature-13011/installation_on_multiple_servers' into merge-6237-13011
This commit is contained in:
@@ -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');
|
||||
@@ -28,9 +28,19 @@ 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 installExtension($extensionName, $filename)
|
||||
{
|
||||
$this->extensionslib->installExtension($extensionName, urldecode($filename));
|
||||
$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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,22 @@ 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',
|
||||
'table',
|
||||
'ui'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -45,23 +56,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
|
||||
$enabled = $enabled == 'true' ? true : false;
|
||||
|
||||
$this->output
|
||||
->set_content_type('application/json')
|
||||
->set_output(json_encode($toggleExtension));
|
||||
// Output the enable/disable of the extension
|
||||
$this->outputJsonSuccess(
|
||||
$this->extensionslib->toggleExtension($extension_id, $enabled)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,15 +73,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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,9 +87,16 @@ 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()
|
||||
{
|
||||
$this->extensionslib->installExtension($extensionName, urldecode($filename));
|
||||
$notPerformSql = $this->input->post('notPerformSql');
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,11 +36,18 @@ class ExtensionsLib
|
||||
|
||||
const PHRASES_DIRECTORY = 'phrases/'; // directory name where phrases files are
|
||||
|
||||
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(
|
||||
@@ -48,17 +55,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();
|
||||
|
||||
@@ -76,6 +77,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();
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
@@ -88,32 +96,40 @@ 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, $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
|
||||
}
|
||||
|
||||
if ($uploadData != null) // if no error occurred
|
||||
// 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 the no error occurred
|
||||
if ($uploadData != null)
|
||||
{
|
||||
$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
|
||||
// Retrieves data about any previous installation of this extension on this server
|
||||
$extensionDB = $this->_loadPreviousInstallation($uploadData->extensionName);
|
||||
}
|
||||
|
||||
@@ -134,15 +150,17 @@ 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); // records extension data in DB
|
||||
// Records extension data in DB
|
||||
$this->_installExtension($extensionJson);
|
||||
|
||||
if (!$this->_errorOccurred) // if no error occurred
|
||||
if (!$this->_errorOccurred && $perform_sql === true) // if no error occurred
|
||||
{
|
||||
// Loads and executes the needed SQL scripts
|
||||
$this->_loadSQLs(
|
||||
$this->UPLOAD_PATH.$extensionJson->name.'/'.ExtensionsLib::SQL_DIRECTORY,
|
||||
$this->_getUploadPath().$extensionJson->name.DIRECTORY_SEPARATOR.ExtensionsLib::SQL_DIRECTORY,
|
||||
$extensionJson
|
||||
);
|
||||
}
|
||||
@@ -165,14 +183,6 @@ class ExtensionsLib
|
||||
$this->_installPhrases($extensionJson->name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->_errorOccurred = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->_errorOccurred = true;
|
||||
}
|
||||
|
||||
if ($this->_errorOccurred === false) // if no errors occurred
|
||||
@@ -203,19 +213,26 @@ class ExtensionsLib
|
||||
$result = $this->_ci->ExtensionsModel->load($extensionId);
|
||||
if (hasData($result)) // if something was found
|
||||
{
|
||||
$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
|
||||
$delExtension = $this->_rrm($this->EXTENSIONS_PATH.$extensionName);
|
||||
// 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
|
||||
|
||||
// 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));
|
||||
|
||||
$result = $this->_ci->ExtensionsModel->loadWhere(array('name' => $extensionName, 'server_kurzbz' => SERVER_NAME));
|
||||
|
||||
// If something was found
|
||||
if (hasData($result))
|
||||
{
|
||||
// Loops on them
|
||||
foreach ($result->retval as $extension)
|
||||
foreach (getData($result) as $extension) // loops on them
|
||||
{
|
||||
// Remove them all
|
||||
$result = $this->_ci->ExtensionsModel->delete($extension->extension_id);
|
||||
@@ -232,23 +249,57 @@ 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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
@@ -262,7 +313,7 @@ class ExtensionsLib
|
||||
$this->_ci->load->library(
|
||||
'upload',
|
||||
array(
|
||||
'upload_path' => $this->UPLOAD_PATH,
|
||||
'upload_path' => $this->_getUploadPath(),
|
||||
'allowed_types' => '*',
|
||||
'overwrite' => true
|
||||
)
|
||||
@@ -326,7 +377,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)
|
||||
{
|
||||
@@ -334,6 +385,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');
|
||||
@@ -356,24 +417,29 @@ 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));
|
||||
|
||||
// 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
|
||||
elseif (hasData($result))
|
||||
{
|
||||
if (hasData($result)) // if found
|
||||
{
|
||||
$extensionDB = $result->retval[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();
|
||||
@@ -389,10 +455,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');
|
||||
@@ -414,12 +480,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
|
||||
@@ -429,36 +497,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)
|
||||
{
|
||||
// Default value
|
||||
@@ -467,7 +540,7 @@ class ExtensionsLib
|
||||
require_once('version.php'); // get the core version
|
||||
|
||||
// Checks if the required core version of the extension is the same of this system
|
||||
if (isset($extensionJson->core_version) && version_compare($extensionJson->core_version, $fhcomplete_version,'<='))
|
||||
if (isset($extensionJson->core_version) && version_compare($extensionJson->core_version, $fhcomplete_version, '<='))
|
||||
{
|
||||
$this->_printMessage('Required core version: '.$extensionJson->core_version);
|
||||
$this->_printMessage('Current core version: '.$fhcomplete_version);
|
||||
@@ -480,7 +553,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))
|
||||
{
|
||||
@@ -575,6 +648,7 @@ class ExtensionsLib
|
||||
{
|
||||
$this->_printStart('Adding new entry in the DB');
|
||||
|
||||
// Insert into database the extension information
|
||||
$result = $this->_ci->ExtensionsModel->insert(
|
||||
array(
|
||||
'name' => $extensionJson->name,
|
||||
@@ -583,7 +657,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))
|
||||
@@ -619,17 +694,16 @@ class ExtensionsLib
|
||||
// Loops through the versions
|
||||
for ($sqlDir = $startVersion; $sqlDir <= $extensionJson->version; $sqlDir++)
|
||||
{
|
||||
// Search for a directory with the same value of the version in the sql scripts directory
|
||||
$files = glob($pkgSQLsPath.'/'.$sqlDir.'/*'.ExtensionsLib::SQL_FILE_EXTENSION);
|
||||
// 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 found
|
||||
$files = glob($pkgSQLsPath.'/'.$sqlDir.'/*'.ExtensionsLib::SQL_FILE_EXTENSION);
|
||||
// If a directory with the same value of the version is present in the sql scripts directory
|
||||
if ($files != false)
|
||||
{
|
||||
{
|
||||
// Loads every sql files
|
||||
foreach ($files as $file)
|
||||
{
|
||||
$sql = file_get_contents($file); // gets the entire content of the file
|
||||
$sql = file_get_contents($file); // gets the entire content of the file
|
||||
|
||||
$this->_printMessage('Executing query:');
|
||||
$this->_printMessage($sql);
|
||||
@@ -667,17 +741,20 @@ 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 (rename($this->UPLOAD_PATH.$extensionName.'/', $this->EXTENSIONS_PATH.$extensionName))
|
||||
if (!file_exists($this->_getExtensionsPath().$extensionName))
|
||||
{
|
||||
$this->_printSuccess(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->_errorOccurred = true;
|
||||
$this->_printFailure('error while moving');
|
||||
if (rename($this->_getUploadPath().$extensionName.DIRECTORY_SEPARATOR, $this->_getExtensionsPath().$extensionName))
|
||||
{
|
||||
$this->_printSuccess(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->_errorOccurred = true;
|
||||
$this->_printFailure('error while moving');
|
||||
}
|
||||
}
|
||||
|
||||
$this->_printEnd();
|
||||
@@ -711,13 +788,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)
|
||||
{
|
||||
// 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
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -730,29 +815,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);
|
||||
}
|
||||
|
||||
@@ -762,27 +841,36 @@ 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)
|
||||
{
|
||||
// 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);
|
||||
|
||||
// Create the symlink
|
||||
$_addSoftLinks = symlink(
|
||||
$_addSoftLinks = @symlink(
|
||||
// Target
|
||||
$extensionPath.$targetDirectory,
|
||||
$rootPath.$targetDirectory.'/'.ExtensionsLib::EXTENSIONS_DIR_NAME.'/'.$extensionName
|
||||
// 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);
|
||||
@@ -812,9 +900,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
|
||||
@@ -828,16 +916,13 @@ 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
|
||||
// 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');
|
||||
@@ -846,46 +931,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))
|
||||
{
|
||||
$extensionName = $result->retval[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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -953,7 +1011,7 @@ class ExtensionsLib
|
||||
*/
|
||||
private function _installPhrases($extensionName)
|
||||
{
|
||||
$this->_ci->phraseslib->installFrom($this->EXTENSIONS_PATH.$extensionName.'/'.self::PHRASES_DIRECTORY);
|
||||
$this->_ci->phraseslib->installFrom($this->_getExtensionsPath().$extensionName.'/'.self::PHRASES_DIRECTORY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,168 +1,67 @@
|
||||
<?php $this->load->view('templates/header', array('title' => 'Extensions manager', 'jqueryV1' => true, 'tablesort' => true)); ?>
|
||||
<?php
|
||||
$this->load->view(
|
||||
'templates/FHC-Header',
|
||||
array(
|
||||
// Title
|
||||
'title' => 'Extensions manager',
|
||||
|
||||
<script type="text/javascript">
|
||||
// JS & CSS includes
|
||||
'jquery3' => true,
|
||||
'jqueryui1' => true,
|
||||
'jquerycheckboxes1' => true,
|
||||
'bootstrap3' => true,
|
||||
'tabulator4' => true,
|
||||
|
||||
$(document).ready(function() {
|
||||
// Styles includes
|
||||
'fontawesome4' => true,
|
||||
'sbadmintemplate3' => true,
|
||||
|
||||
$(".tablesorter").each(function(i, v) {
|
||||
|
||||
$("#" + v.id).tablesorter({
|
||||
widgets: ["zebra"],
|
||||
sortList: [[0, 0]],
|
||||
headers: {7: {sorter: false}}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
$(".chkbox").change(function() {
|
||||
|
||||
var chkId = $(this).context.name;
|
||||
var checked = $(this).prop("checked");
|
||||
|
||||
$.ajax({
|
||||
url: "<?php echo current_url(); ?>/toggleExtension",
|
||||
dataType: "json",
|
||||
type: "POST",
|
||||
data: {
|
||||
extension_id: chkId,
|
||||
enabled: checked
|
||||
},
|
||||
error: function(jqXHR, textStatus, errorThrown) {
|
||||
|
||||
alert("Error while saving data");
|
||||
},
|
||||
success: function(response, textStatus, jqXHR) {
|
||||
if (response != true)
|
||||
{
|
||||
alert("Error while saving data");
|
||||
}
|
||||
},
|
||||
complete: function() {
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
$(".lnkrm").click(function() {
|
||||
|
||||
var lnkId = $(this).context.name;
|
||||
|
||||
if (window.confirm('Are you really shure???') == true)
|
||||
{
|
||||
$.ajax({
|
||||
url: "<?php echo current_url(); ?>/delExtension",
|
||||
dataType: "json",
|
||||
type: "POST",
|
||||
data: {
|
||||
extension_id: lnkId
|
||||
},
|
||||
error: function(jqXHR, textStatus, errorThrown) {
|
||||
alert("Error while saving data");
|
||||
},
|
||||
success: function(response, textStatus, jqXHR) {
|
||||
if (response != true)
|
||||
{
|
||||
alert("Error while saving data");
|
||||
}
|
||||
},
|
||||
complete: function() {
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
// FHC JS & CSS includes
|
||||
'ajaxlib' => true,
|
||||
'dialoglib' => true,
|
||||
'tablewidget' => true,
|
||||
'phrases' => array(
|
||||
'extensions',
|
||||
'table',
|
||||
'ui'
|
||||
),
|
||||
'customJSs' => array('public/js/ExtensionsManager.js')
|
||||
)
|
||||
);
|
||||
?>
|
||||
|
||||
<body>
|
||||
<div class="container-fluid">
|
||||
<h3 class="page-header">
|
||||
<?php echo $this->p->t('extensions', 'title'); ?>
|
||||
</h3>
|
||||
|
||||
<?php
|
||||
if (!hasData($extensions))
|
||||
{
|
||||
echo 'No extension installed!<br>';
|
||||
}
|
||||
elseif (isError($extensions))
|
||||
{
|
||||
echo 'An error occurred while retriving extenions list.';
|
||||
}
|
||||
elseif (hasData($extensions))
|
||||
{
|
||||
?>
|
||||
<div>
|
||||
List of installed extensions
|
||||
<div>
|
||||
<?php $this->load->view('system/extensions/tableWidget.php'); ?>
|
||||
</div>
|
||||
|
||||
<?php echo form_open_multipart(current_url().'/uploadExtension'); ?>
|
||||
<div class="row">
|
||||
<div class="col-xs-2">
|
||||
<input type="file" name="extension" />
|
||||
</div>
|
||||
<div>
|
||||
<input type="button" id="uploadExtension" value="<?php echo $this->p->t('extensions', 'uploadExtension'); ?>" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<table class="tablesorter" id="t0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Description</th>
|
||||
<th>Version</th>
|
||||
<th>Licence</th>
|
||||
<th>URL</th>
|
||||
<th>Minimum required Core version</th>
|
||||
<th>Dependes on (extensions)</th>
|
||||
<th>Enabled</th>
|
||||
<th> </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<?php
|
||||
$tableRow = '
|
||||
<tr>
|
||||
<td>%s</td>
|
||||
<td>%s</td>
|
||||
<td>%s</td>
|
||||
<td>%s</td>
|
||||
<td>%s</td>
|
||||
<td>%s</td>
|
||||
<td>%s</td>
|
||||
<td>
|
||||
<input type="checkbox" class="chkbox" name="%s" %s>
|
||||
</td>
|
||||
<td>
|
||||
<a href="#" name="%s" class="lnkrm" >Remove</a>
|
||||
</td>
|
||||
</tr>';
|
||||
|
||||
foreach ($extensions->retval as $key => $extension)
|
||||
{
|
||||
echo sprintf(
|
||||
$tableRow,
|
||||
$extension->name,
|
||||
$extension->description,
|
||||
$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
|
||||
);
|
||||
}
|
||||
?>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
<br>
|
||||
|
||||
<?php echo form_open_multipart(current_url().'/uploadExtension'); ?>
|
||||
<input type="file" name="extension" />
|
||||
<input type="submit" value="Install/Update extension" />
|
||||
</form>
|
||||
<br/>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-2">
|
||||
<label for="notPerformSql"><?php echo $this->p->t('extensions', 'performSql'); ?></label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="checkbox" class="checkbox" id="notPerformSql" name="notPerformSql"/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<?php $this->load->view('templates/footer'); ?>
|
||||
<?php $this->load->view('templates/FHC-Footer'); ?>
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
$tableWidgetArray = array(
|
||||
'query' => '
|
||||
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);
|
||||
|
||||
@@ -251,51 +251,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');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -370,8 +368,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
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -421,6 +421,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));
|
||||
|
||||
@@ -101,7 +101,8 @@ var FHC_AjaxClient = {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -985,3 +985,4 @@ $(document).ready(function() {
|
||||
FHC_TableWidget.display();
|
||||
|
||||
});
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ require_once('dbupdate_3.4/17512_fehlercode_constraints.php');
|
||||
require_once('dbupdate_3.4/28260_vertraege.php');
|
||||
require_once('dbupdate_3.4/27388_anrechnungen_zeitfenster_pflegen.php');
|
||||
require_once('dbupdate_3.4/19154_beurteilungsformulare_pruefungssenat.php');
|
||||
require_once('dbupdate_3.4/13011_installation_on_multiple_servers.php');
|
||||
require_once('dbupdate_3.4/10001_tempus_mitarbeiter_kurzbz_bei_reservierungen_anzeigen.php');
|
||||
require_once('dbupdate_3.4/27949_infocenter_zurueckstellen_mit_grund.php');
|
||||
require_once('dbupdate_3.4/27107_vilesci_erfassung_abwesenheiten_reinigung.php');
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
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"))
|
||||
{
|
||||
$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 '<strong>App: '.$db->db_last_error().'</strong><br>';
|
||||
else
|
||||
echo '<br>Neue Spalte server_kurzbz in system.tbl_extensions hinzugefügt';
|
||||
}
|
||||
|
||||
|
||||
// UNIQUE INDEX uidx_extensions_name_version
|
||||
if ($result = $db->db_query("SELECT COUNT(*) FROM pg_class WHERE relname = 'uidx_extensions_name_version'"))
|
||||
{
|
||||
$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 '<strong>uidx_extensions_name_version '.$db->db_last_error().'</strong><br>';
|
||||
else
|
||||
echo '<br>Dropped unique uidx_extensions_name_version';
|
||||
}
|
||||
|
||||
// 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 '<strong>uidx_extensions_name_version_server '.$db->db_last_error().'</strong><br>';
|
||||
else
|
||||
echo '<br>Created unique uidx_extensions_name_version_server';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user