From 7bf6cd9530986e11d46f9316bbd6d076938a9dc8 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Thu, 10 Jul 2025 11:25:36 +0200 Subject: [PATCH 001/109] fix: announcements cannot be saved --- src/UI/Presenter/AnnouncementsPresenter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/UI/Presenter/AnnouncementsPresenter.php b/src/UI/Presenter/AnnouncementsPresenter.php index 8a962d3986..e0c59fd01e 100644 --- a/src/UI/Presenter/AnnouncementsPresenter.php +++ b/src/UI/Presenter/AnnouncementsPresenter.php @@ -230,7 +230,7 @@ public function createEditForm(string $announcementUUID, bool $copy): void $form = new FormPresenter( 'adm_announcements_edit_form', 'modules/announcements.edit.tpl', - SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/announcements.php', array('mode' => 'edit', 'announcement_uuid' => $announcementUUID)), + SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/announcements.php', array('mode' => 'save', 'announcement_uuid' => $announcementUUID)), $this ); $form->addInput( From 2b1a817af218dbc57e15b0e964c6145d8de974a3 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Mon, 21 Jul 2025 22:13:46 +0200 Subject: [PATCH 002/109] initial implementation of plugin management functionality (PluginManager) --- install/db_scripts/update_5_0.xml | 6 + install/install_steps/start_installation.php | 6 +- modules/plugins.php | 115 +++++ src/Components/Entity/Component.php | 1 + src/Components/Entity/ComponentUpdate.php | 96 +++- src/Infrastructure/Plugins/PluginAbstract.php | 481 ++++++++++++++++++ .../Plugins/PluginInterface.php | 114 +++++ src/Infrastructure/Plugins/PluginManager.php | 147 ++++++ src/UI/Presenter/PluginsPresenter.php | 149 ++++++ .../simple/templates/modules/plugins.list.tpl | 28 + 10 files changed, 1140 insertions(+), 3 deletions(-) create mode 100644 modules/plugins.php create mode 100644 src/Infrastructure/Plugins/PluginAbstract.php create mode 100644 src/Infrastructure/Plugins/PluginInterface.php create mode 100644 src/Infrastructure/Plugins/PluginManager.php create mode 100644 src/UI/Presenter/PluginsPresenter.php create mode 100644 themes/simple/templates/modules/plugins.list.tpl diff --git a/install/db_scripts/update_5_0.xml b/install/db_scripts/update_5_0.xml index 5dd0867508..7327a7f20f 100644 --- a/install/db_scripts/update_5_0.xml +++ b/install/db_scripts/update_5_0.xml @@ -502,5 +502,11 @@ WHERE usf_fn.usf_name_intern = 'FIRST_NAME' AND usf_ln.usf_name_intern = 'LAST_N COLLATE = utf8_unicode_ci; ALTER TABLE %PREFIX%_inventory_field_select_options ADD CONSTRAINT %PREFIX%_fk_ifo_inf FOREIGN KEY (ifo_inf_id) REFERENCES %PREFIX%_inventory_fields (inf_id) ON DELETE CASCADE ON UPDATE RESTRICT; + INSERT INTO %PREFIX%_components (com_type, com_name, com_name_intern, com_version, com_beta) + VALUES ('MODULE', 'SYS_PLUGIN_MANAGER', 'PLUGINS', '5.0.0', 0) + ALTER TABLE %PREFIX%_components + ADD com_status VARCHAR(36) NOT NULL AFTER com_update_completed; + INSERT INTO %PREFIX%_menu (men_com_id, men_men_id_parent, men_uuid, men_node, men_order, men_standard, men_name_intern, men_url, men_icon, men_name, men_description) + VALUES ((SELECT com_id FROM %PREFIX%_components WHERE com_name_intern = 'PLUGINS'), 2, %UUID%, false, 5, true, 'plugins', '/modules/plugins.php', 'puzzle', 'SYS_PLUGIN_MANAGER', 'SYS_PLUGIN_MANAGER_DESC') stop diff --git a/install/install_steps/start_installation.php b/install/install_steps/start_installation.php index a534a76aee..c778c8eaf7 100644 --- a/install/install_steps/start_installation.php +++ b/install/install_steps/start_installation.php @@ -89,7 +89,8 @@ , (\'MODULE\', \'SYS_SETTINGS\', \'PREFERENCES\', \''.ADMIDIO_VERSION.'\', '.ADMIDIO_VERSION_BETA.') , (\'MODULE\', \'SYS_PROFILE\', \'PROFILE\', \''.ADMIDIO_VERSION.'\', '.ADMIDIO_VERSION_BETA.') , (\'MODULE\', \'SYS_REGISTRATION\', \'REGISTRATION\', \''.ADMIDIO_VERSION.'\', '.ADMIDIO_VERSION_BETA.') - , (\'MODULE\', \'SYS_ROOM_MANAGEMENT\', \'ROOMS\', \''.ADMIDIO_VERSION.'\', '.ADMIDIO_VERSION_BETA.')'; + , (\'MODULE\', \'SYS_ROOM_MANAGEMENT\', \'ROOMS\', \''.ADMIDIO_VERSION.'\', '.ADMIDIO_VERSION_BETA.') + , (\'MODULE\', \'SYS_PLUGIN_MANAGER\', \'PLUGINS\', \''.ADMIDIO_VERSION.'\', '.ADMIDIO_VERSION_BETA.')'; $db->query($sql); // TODO add more params // create organization independent categories @@ -279,7 +280,8 @@ , ((SELECT com_id FROM '.TBL_COMPONENTS.' WHERE com_name_intern = \'PREFERENCES\'), 2, \'' . Uuid::uuid4() . '\', false, 1, true, \'orgprop\', \''.FOLDER_MODULES.'/preferences.php\', \'gear-fill\', \'SYS_SETTINGS\', \'ORG_ORGANIZATION_PROPERTIES_DESC\') , ((SELECT com_id FROM '.TBL_COMPONENTS.' WHERE com_name_intern = \'REGISTRATION\'), 2, \'' . Uuid::uuid4() . '\', false, 2, true, \'registration\', \''.FOLDER_MODULES.'/registration.php\', \'card-checklist\', \'SYS_REGISTRATIONS\', \'SYS_MANAGE_NEW_REGISTRATIONS_DESC\') , ((SELECT com_id FROM '.TBL_COMPONENTS.' WHERE com_name_intern = \'MENU\'), 2, \'' . Uuid::uuid4() . '\', false, 3, true, \'menu\', \''.FOLDER_MODULES.'/menu.php\', \'menu-button-wide-fill\', \'SYS_MENU\', \'SYS_MENU_DESC\') - , ((SELECT com_id FROM '.TBL_COMPONENTS.' WHERE com_name_intern = \'ORGANIZATIONS\'), 2, \'' . Uuid::uuid4() . '\', false, 4, true, \'organization\', \''.FOLDER_MODULES.'/organizations.php\', \'diagram-3-fill\', \'SYS_ORGANIZATION\', \'SYS_ORGANIZATION_DESC\')'; + , ((SELECT com_id FROM '.TBL_COMPONENTS.' WHERE com_name_intern = \'ORGANIZATIONS\'), 2, \'' . Uuid::uuid4() . '\', false, 4, true, \'organization\', \''.FOLDER_MODULES.'/organizations.php\', \'diagram-3-fill\', \'SYS_ORGANIZATION\', \'SYS_ORGANIZATION_DESC\') + , ((SELECT com_id FROM '.TBL_COMPONENTS.' WHERE com_name_intern = \'PLUGINS\'), 2, \'' . Uuid::uuid4() . '\', false, 5, true, \'plugins\', \''.FOLDER_MODULES.'/plugins.php\', \'puzzle\', \'SYS_PLUGIN_MANAGER\', \SYS_PLUGIN_MANAGER_DESC\')'; $db->query($sql); // delete session data diff --git a/modules/plugins.php b/modules/plugins.php new file mode 100644 index 0000000000..d1bb49686a --- /dev/null +++ b/modules/plugins.php @@ -0,0 +1,115 @@ + 'list', 'validValues' => array('list', 'install', 'uninstall', 'update'))); + $getPluginName = admFuncVariableIsValid($_GET, 'name', 'string', array('defaultValue' => '')); + + // check rights to use this module + if (!$gCurrentUser->isAdministrator()) { + throw new Exception('SYS_NO_RIGHTS'); + } + + switch ($getMode) { + case 'list': + // create html page object + $page = new PluginsPresenter(); + $page->createList(); + $gNavigation->addStartUrl(CURRENT_URL, $page->getHeadline(), 'bi-puzzle-fill'); + $page->show(); + break; + + case 'install': + // install plugin + if (!empty($getPluginName)) { + $pluginManager = new PluginManager(); + $plugin = $pluginManager->getPluginByName($getPluginName); + if ($plugin) { + $interface = $plugin instanceof PluginAbstract ? $plugin : null; + + if ($interface != null) { + $interface->doInstall(); + } + } + $gNavigation->deleteLastUrl(); + admRedirect(SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/plugins.php')); + } else { + throw new Exception('SYS_PLUGIN_NAME_MISSING'); + } + break; + + case 'uninstall': + // uninstall plugin + if (!empty($getPluginName)) { + $pluginManager = new PluginManager(); + $plugin = $pluginManager->getPluginByName($getPluginName); + if ($plugin) { + $interface = $plugin instanceof PluginAbstract ? $plugin : null; + + if ($interface != null) { + $interface->doUninstall(); + } + } + $gNavigation->deleteLastUrl(); + admRedirect(SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/plugins.php')); + } else { + throw new Exception('SYS_PLUGIN_NAME_MISSING'); + } + break; + + case 'update': + // update plugin + if (!empty($getPluginName)) { + $pluginManager = new PluginManager(); + $plugin = $pluginManager->getPluginByName($getPluginName); + if ($plugin) { + $interface = $plugin instanceof PluginAbstract ? $plugin : null; + + if ($interface != null) { + $interface->doUpdate(); + } + } + $gNavigation->deleteLastUrl(); + admRedirect(SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/plugins.php')); + } else { + throw new Exception('SYS_PLUGIN_NAME_MISSING'); + } + break; + + default: + throw new Exception('SYS_UNKNOWN_MODE'); + break; + } +} catch (Throwable $e) { + if (in_array($getMode, array('save', 'delete'))) { + echo json_encode(array('status' => 'error', 'message' => $e->getMessage())); + } else { + $gMessage->show($e->getMessage()); + } +} diff --git a/src/Components/Entity/Component.php b/src/Components/Entity/Component.php index aca2f3acd5..c31172fa41 100644 --- a/src/Components/Entity/Component.php +++ b/src/Components/Entity/Component.php @@ -318,6 +318,7 @@ public static function isVisible(string $componentName): bool case 'MENU': // fallthrough case 'ORGANIZATIONS': // fallthrough case 'PREFERENCES': // fallthrough + case 'PLUGINS': // fallthrough case 'ROOMS': if ($gCurrentUser->isAdministrator()) { return true; diff --git a/src/Components/Entity/ComponentUpdate.php b/src/Components/Entity/ComponentUpdate.php index 00c1d8f715..1aef47f4a8 100644 --- a/src/Components/Entity/ComponentUpdate.php +++ b/src/Components/Entity/ComponentUpdate.php @@ -83,10 +83,25 @@ private function getXmlObject(int $mainVersion, int $minorVersion): SimpleXMLEle $message = 'XML-Update file not found!'; $gLogger->warning($message, array('filePath' => $updateFile)); + throw new UnexpectedValueException($message); + } elseif ($this->getValue('com_type') === 'PLUGIN') { + $updateFile = ADMIDIO_PATH . FOLDER_PLUGINS . '/' . $this->getValue('com_name_intern') . '/db_scripts/update_'.$mainVersion.'_'.$minorVersion.'.xml'; + + if (is_file($updateFile)) { + try { + return new SimpleXMLElement($updateFile, 0, true); + } catch (\Exception $e) { + throw new Exception($e->getMessage()); + } + } + + $message = 'XML-Update file not found!'; + $gLogger->warning($message, array('filePath' => $updateFile)); + throw new UnexpectedValueException($message); } - throw new UnexpectedValueException('No System update!'); + throw new UnexpectedValueException('No System or Plugin update!'); } /** @@ -299,4 +314,83 @@ public function update(string $targetVersion) WHERE com_type IN (\'SYSTEM\', \'MODULE\')'; $this->db->queryPrepared($sql, array(ADMIDIO_VERSION, ADMIDIO_VERSION_BETA)); } + + /** + * Do a loop through all versions start with the last installed version and end with the current version of the + * file system (**$targetVersion**). Within every subversion the method will search for an update xml file and + * execute all steps in this file until the end of file is reached. If an error occurred then the update will + * be stopped and the system will be marked with update not completed so that it's possible to continue the + * update later if the problem was fixed. + * @param string $targetVersion The target version to update. + * @throws Exception + */ + public function updatePlugin(string $targetVersion) + { + global $gLogger; + + if (empty($this->getValue('com_version'))) { + $currentVersionArray = array(0, 0, 0); + } else { + $currentVersionArray = self::getVersionArrayFromVersion($this->getValue('com_version')); + } + $targetVersionArray = self::getVersionArrayFromVersion($targetVersion); + $initialMinorVersion = $currentVersionArray[1]; + + // if the update is from a version lower than 4.2.0 than the field com_update_complete doesn't exist + // otherwise set the status to incomplete update + if(version_compare($this->getValue('com_update_version'), '4.2.0', '>')) { + $this->setValue('com_update_completed', false); + $this->save(); + } + + for ($mainVersion = $currentVersionArray[0]; $mainVersion <= $targetVersionArray[0]; ++$mainVersion) { + // Set max subversion for iteration. If we are in the loop of the target main version + // then set target minor-version to the max version + $maxMinorVersion = 20; + if ($mainVersion === $targetVersionArray[0]) { + $maxMinorVersion = $targetVersionArray[1]; + } + + for ($minorVersion = $initialMinorVersion; $minorVersion <= $maxMinorVersion; ++$minorVersion) { + // if version is not equal to current version then start update step with 0 + if ($mainVersion !== $currentVersionArray[0] || $minorVersion !== $currentVersionArray[1]) { + $this->setValue('com_update_step', 0); + $this->save(); + } + + // save current version to system component + $this->setValue('com_version', $mainVersion . '.' . $minorVersion . '.0'); + $this->save(); + + // output of the version number for better debugging + $gLogger->notice('UPDATE: Start executing update steps to version ' . $mainVersion . '.' . $minorVersion); + + // open xml file for this version + try { + $xmlObject = $this->getXmlObject($mainVersion, $minorVersion); + + // go step by step through the SQL statements and execute them + foreach ($xmlObject->children() as $updateStep) { + if ((string)$updateStep === self::UPDATE_STEP_STOP) { + break; + } + if ((int)$updateStep['id'] > (int)$this->getValue('com_update_step')) { + $this->executeStep($updateStep, $mainVersion . '.' . $minorVersion . '.0'); + } else { + $gLogger->info('UPDATE: Skip update step Nr: ' . (int)$updateStep['id']); + } + } + } catch (Exception $exception) { + throw new Exception($exception->getMessage()); + } catch (UnexpectedValueException|\Exception $exception) { + // TODO + } + + $gLogger->notice('UPDATE: Finish executing update steps to version '.$mainVersion.'.'.$minorVersion); + } + + // reset subversion because we want to start update for next main version with subversion 0 + $initialMinorVersion = 0; + } + } } diff --git a/src/Infrastructure/Plugins/PluginAbstract.php b/src/Infrastructure/Plugins/PluginAbstract.php new file mode 100644 index 0000000000..c439c0335e --- /dev/null +++ b/src/Infrastructure/Plugins/PluginAbstract.php @@ -0,0 +1,481 @@ +getFileName(), 2); + } + + /** + * Singleton Class! Stop cloning this class! + */ + private function __clone() + { + + } + + /** + * Singleton Class! Stop unserializing this class! + */ + public function __wakeup() + { + + } + + public static function initPreferencePanelCallback(): void + { + // find a preference panel for this plugin + $preferencesFile = self::getPluginPath() . '/classes/Presenter/' . basename(self::getPluginPath()) . 'PreferencesPresenter.php'; + $preferencesClass = is_file($preferencesFile) ? self::getClassNameFromFile($preferencesFile) : null; + if (isset($preferencesClass) && class_exists($preferencesClass)) { + // get the function name for the preferences panel + $functionName = 'create' . basename(self::getPluginPath()) . 'Form'; + if (!method_exists($preferencesClass, $functionName)) { + throw new Exception('The preferences class ' . $preferencesClass . ' does not have a method ' . $functionName . '().'); + } + // register the preferences presenter for this plugin + PreferencesService::addPluginPreferencesPresenter( + self::getComponentId(), + [ $preferencesClass, $functionName ] + ); + } + } + + /** + * Parse a PHP file and return the first class name found. + */ + private static function getClassNameFromFile(string $file): ?string + { + $src = file_get_contents($file); + $tokens = token_get_all($src); + $namespace = ''; + $class = null; + for ($i = 0, $count = count($tokens); $i < $count; $i++) { + if ($tokens[$i][0] === T_NAMESPACE) { + $i++; + while ($tokens[$i][0] === T_WHITESPACE) $i++; + while (in_array($tokens[$i][0], [T_STRING, T_NAME_QUALIFIED, T_NS_SEPARATOR])) { + $namespace .= $tokens[$i++][1]; + } + } + if ($tokens[$i][0] === T_CLASS) { + // skip whitespace + $i++; + while ($tokens[$i][0] === T_WHITESPACE) $i++; + $class = $tokens[$i][1]; + break; + } + } + if ($class) { + return $namespace ? "$namespace\\$class" : $class; + } + return null; + } + + /** + * Reads the plugin metadata from the plugin file. + * + * @param string $class + * @throws Exception + */ + private function readPluginMetadata() : void + { + // get the plugin name, version and metadata from the plugin file + $configFiles = self::getStaticFiles('json'); + if (!isset($configFiles) || count($configFiles) === 0) { + //throw new Exception('Plugin configuration file not found.'); + return; + } else { + $configFile = $configFiles[0]; + } + $configData = json_decode(file_get_contents($configFile), true); + if ($configData === null) { + throw new Exception('Plugin configuration file is not valid JSON.'); + } else { + self::$name = $configData['name'] ?? ''; + self::$dependencies = $configData['dependencies'] ?? array(); + self::$defaultConfig = $configData['defaultConfig'] ?? array(); + self::$metadata = $configData; + } + } + + /** + * @return PluginAbstract + */ + public static function getInstance() : PluginAbstract + { + $class = get_called_class(); + if (!array_key_exists($class, self::$instances)) + { + self::$instances[$class] = new $class(); + self::$instances[$class]->doClassAutoload(); + self::$instances[$class]->readPluginMetadata(); + + // check if the plugin is installed + if (self::$instances[$class]->isInstalled()) { + global $gDb; + // get the component id of the plugin + $sql = 'SELECT com_id FROM ' . TBL_COMPONENTS . ' WHERE com_name = ? AND com_type = ?'; + $statement = $gDb->queryPrepared($sql, array(self::getName(), 'PLUGIN')); + self::$pluginComId = (int)$statement->fetchColumn(); + + // get the installed version of the plugin + $sql = 'SELECT com_version FROM ' . TBL_COMPONENTS . ' WHERE com_name = ? AND com_type = ?'; + $statement = $gDb->queryPrepared($sql, array(self::getName(), 'PLUGIN')); + self::$version = (string)$statement->fetchColumn(); + } + } + + return self::$instances[$class]; + } + + /** + * @return string + */ + public static function getName() : string + { + return self::$name; + } + + /** + * @return string + */ + public static function getVersion() : string + { + return self::$version; + } + + /** + * @return array + */ + public static function getMetadata() : array + { + + return self::$metadata; + } + + /** + * @return array + */ + public static function getDependencies() : array + { + return self::$dependencies; + } + + /** + * @return array + */ + public static function getSupportedLanguages() : array + { + $dir = __DIR__ . DIRECTORY_SEPARATOR . 'languages'; + + $langFiles = array(); + foreach (scandir($dir) as $entry) + { + $entryPath = $dir . DIRECTORY_SEPARATOR . $entry; + $entryInfo = pathinfo($entryPath); + if (is_file($entryPath) && $entryInfo['extension'] === 'xml') + { + $langFiles[] = $entryInfo['filename']; + } + } + + return $langFiles; + } + + /** + * @param string $type + * @throws InvalidArgumentException + * @throws Exception + * @return array + */ + public static function getStaticFiles($type = null) : array + { + if ($type !== null && !is_string($type)) + { + throw new InvalidArgumentException('Type must be "null" or a "string".'); + } + + if (!is_dir(self::$pluginPath)) + { + throw new Exception('Plugin path does not exist: ' . self::$pluginPath); + } + + $files = array(); + foreach (scandir(self::$pluginPath) as $entry) + { + $entryPath = self::$pluginPath . DIRECTORY_SEPARATOR . $entry; + if (is_file($entryPath)) + { + $entryInfo = pathinfo($entryPath); + + if (!array_key_exists($entryInfo['extension'], $files)) + { + $files[$entryInfo['extension']] = array(); + } + + $files[$entryInfo['extension']][] = $entryPath; + } + } + + if ($type === null) + { + return $files; + } + else + { + return $files[$type]; + } + } + + public static function getPluginConfigValues() : array + { + global $gSettingsManager; + $config = array(); + + // loop over all default config keys and get their values from the database if the key exists + foreach (self::$defaultConfig as $key => $value) { + if ($gSettingsManager->has($key)) { + switch ($value['type']) { + case 'integer': + $config[$key] = $gSettingsManager->getInt($key); + break; + case 'boolean': + $config[$key] = $gSettingsManager->getBool($key); + break; + case 'array': + $valueString = $gSettingsManager->get($key); + $config[$key] = $valueString === "" ? array() : explode(',', $valueString); + break; + case 'string': + default: + $config[$key] = $gSettingsManager->get($key); + break; + } + } else { + $config[$key] = $value['value']; + } + } + + return $config; + } + + public static function getPluginConfig() : array + { + $config = self::$defaultConfig; + // get the plugin config values from the database + $values = self::getPluginConfigValues(); + // loop over all default config keys and set their current values + foreach ($config as $key => $value) { + $config[$key]['value'] = $values[$key]; + } + return $config; + } + + public static function getPluginPath() : string + { + return self::$pluginPath; + } + + /** + * @throws Exception + * @return int + */ + public static function getComponentId() : int + { + return self::$pluginComId; + } + + /** + * @throws Exception + * @return bool + */ + public static function isInstalled() : bool + { + global $gDb; + // check if the plugin exists in components database table + $sql = 'SELECT COUNT(*) AS count FROM ' . TBL_COMPONENTS . ' WHERE com_name = ? AND com_type = ?'; + $statement = $gDb->queryPrepared($sql, array(self::getName(), 'PLUGIN')); + $columns = (int)$statement->fetchColumn(); + + return $columns > 0; + } + + /** + * @throws Exception + * @return bool + */ + public static function isActivated() : bool + { + return self::isInstalled() && (self::getComponentId() > 0); + } + + /** + * @throws Exception + * @return bool + */ + public static function isUpdateAvailable() : bool + { + global $gDb; + // check if the plugin exists in components database table + $sql = 'SELECT com_version FROM ' . TBL_COMPONENTS . ' WHERE com_name = ? AND com_type = ?'; + $statement = $gDb->queryPrepared($sql, array(self::getName(), 'PLUGIN')); + $currentVersion = $statement->fetchColumn(); + + return version_compare($currentVersion, self::getVersion(), '<'); + } + + /** + * @throws Exception + * @return bool + */ + public static function doClassAutoload() : bool + { + $autoloadPath = ADMIDIO_PATH . '/vendor/autoload.php'; + + if (is_file($autoloadPath)) + { + require_once($autoloadPath); + + return true; + } + + return false; + } + + /** + * @throws Exception + * @return bool + */ + public static function doInstall() : bool + { + global $gDb, $gSettingsManager; + + // check if the plugin is already installed + if (self::isInstalled()) { + return false; + } + + // insert default plugin config values into the database + $gSettingsManager->setMulti(self::getPluginConfigValues()); + + // install the plugin + $componentUpdateHandle = new ComponentUpdate($gDb); + $componentUpdateHandle->readDataByColumns(array('com_type' => 'PLUGIN', 'com_name' => self::getName(), 'com_name_intern' => basename(self::$pluginPath))); + $componentUpdateHandle->updatePlugin(self::$metadata['version']); + + // set the new component id of the plugin + self::$pluginComId = $componentUpdateHandle->getValue('com_id'); + + // set the installed version of the plugin + self::$version = self::$metadata['version']; + + // perform additional installation tasks + // TODO: implement function to perform updateSteps for the plugin + // e.g.: $componentUpdateHandle->doUpdateSteps(); + + return true; + } + + /** + * @param array $options + * @throws InvalidArgumentException + * @throws Exception + * @return bool + */ + public static function doUninstall(array $options = array()) : bool + { + if (!is_array($options)) + { + throw new InvalidArgumentException('Options must be an "array".'); + } + + // check if the plugin is installed + if (!self::isInstalled()) { + return false; + } + + global $gDb, $gSettingsManager; + + // delete the plugin config values from the database + foreach (self::getPluginConfigValues() as $key => $value) { + if ($gSettingsManager->has($key)) { + $gSettingsManager->del($key); + } + } + + // update $gSettingsManager to remove the plugin config values + $gSettingsManager->resetAll(); + + // delete the plugin from the components table + $plugin = new Component($gDb, self::$pluginComId); + $plugin->delete(); + + // reset the plugin component id + self::$pluginComId = 0; + + // reset the installed version of the plugin + self::$version = '0.0.0'; + + // perform additional uninstallation tasks + // TODO: implement function to perform additional uninstallation tasks for the plugin + return true; + } + + /** + * @throws Exception + * @return bool + */ + public static function doUpdate() : bool + { + global $gDb, $gSettingsManager; + + // check if the plugin is installed + if (!self::isInstalled()) { + return false; + } + + // add new plugin config values to the database + $gSettingsManager->setMulti(self::getPluginConfigValues(), false); + + // update the plugin + $componentUpdateHandle = new ComponentUpdate($gDb); + $componentUpdateHandle->readDataByColumns(array('com_type' => 'PLUGIN', 'com_name' => self::getName(), 'com_name_intern' => basename(self::$pluginPath))); + $componentUpdateHandle->updatePlugin(self::$metadata['version']); + + // set the installed version of the plugin + self::$version = self::$metadata['version']; + + // perform additional update tasks + // TODO: implement function to perform updateSteps for the plugin + // e.g.: $componentUpdateHandle->doUpdateSteps(); + return true; + } +} \ No newline at end of file diff --git a/src/Infrastructure/Plugins/PluginInterface.php b/src/Infrastructure/Plugins/PluginInterface.php new file mode 100644 index 0000000000..44cd23433d --- /dev/null +++ b/src/Infrastructure/Plugins/PluginInterface.php @@ -0,0 +1,114 @@ +pluginsPath = realpath(ADMIDIO_PATH . FOLDER_PLUGINS); + } + + /** + * + */ + public function getAvailablePlugins() : array|object + { + $plugins = array(); + foreach (scandir($this->pluginsPath) as $entry) { + // skip dot and dotdot entries + if ($entry === '.' || $entry === '..') { + continue; + } + + $pluginFolder = $this->pluginsPath . DIRECTORY_SEPARATOR . $entry; + if (is_dir($pluginFolder)) { + $pluginClassFile = $pluginFolder . DIRECTORY_SEPARATOR . 'classes' . DIRECTORY_SEPARATOR . $entry . '.php'; + $className = is_file($pluginClassFile) ? $this->getClassNameFromFile($pluginClassFile) : null; + $instance = $className != null ? $className::getInstance() : null; + + // find the main plugin file + $this->getMainPluginFile($pluginFolder, $entry, $instance); + $plugins[$entry] = array( + 'fullPath' => $this->pluginMainFile, + 'relativePath' => str_replace(realpath(ADMIDIO_PATH), '', $this->pluginMainFile), + 'interface' => $instance + ); + } + } + + return $plugins; + } + + public function getPluginById(int $pluginId): ?PluginAbstract + { + $plugins = $this->getAvailablePlugins(); + foreach ($plugins as $plugin) { + if ($plugin['interface'] instanceof PluginAbstract && $plugin['interface']->getComponentId() === $pluginId) { + return $plugin['interface']; + } + } + return null; + } + + public function getPluginByName(string $pluginName): ?PluginAbstract + { + $plugins = $this->getAvailablePlugins(); + if (isset($plugins[$pluginName]) && $plugins[$pluginName]['interface'] instanceof PluginAbstract) { + return $plugins[$pluginName]['interface']; + } + return null; + } + + public function getMetadataByComponentId(int $componentId): ?array + { + $plugin = $this->getPluginById($componentId); + return $plugin ? $plugin->getMetadata() : null; + } + + private function getMainPluginFile(string $pluginFolder, string $pluginName, ?PluginAbstract $instance) : void + { + $pluginFileName = $instance != null ? $instance->getMetadata()['mainFile'] : 'index.php'; + $pluginFile = $pluginFolder . DIRECTORY_SEPARATOR . $pluginFileName; + if (is_file($pluginFile)) { + $this->pluginMainFile = $pluginFile; + } else { + $pluginFileName = $pluginName . '.php'; + $pluginFile = $pluginFolder . DIRECTORY_SEPARATOR . $pluginFileName; + if (is_file($pluginFile)) { + $this->pluginMainFile = $pluginFile; + } + } + return; + } + + /** + * Parse a PHP file and return the first class name found. + */ + private function getClassNameFromFile(string $file): ?string + { + $src = file_get_contents($file); + $tokens = token_get_all($src); + $namespace = ''; + $class = null; + for ($i = 0, $count = count($tokens); $i < $count; $i++) { + if ($tokens[$i][0] === T_NAMESPACE) { + $i++; + while ($tokens[$i][0] === T_WHITESPACE) $i++; + while (in_array($tokens[$i][0], [T_STRING, T_NAME_QUALIFIED, T_NS_SEPARATOR])) { + $namespace .= $tokens[$i++][1]; + } + } + if ($tokens[$i][0] === T_CLASS) { + // skip whitespace + $i++; + while ($tokens[$i][0] === T_WHITESPACE) $i++; + $class = $tokens[$i][1]; + break; + } + } + if ($class) { + return $namespace ? "$namespace\\$class" : $class; + } + return null; + } + + /** + * + */ + public function getInstalledPlugins() : array + { + $availablePlugins = $this->getAvailablePlugins(); + $installedPlugins = array(); + foreach ($availablePlugins as $plugin) { + if ($plugin['interface'] instanceof PluginAbstract && $plugin['interface']->isInstalled()) { + $installedPlugins[] = $plugin['interface']; + } + } + return $installedPlugins; + } + + /** + * + */ + public function getActivePlugins() + { + + } +} \ No newline at end of file diff --git a/src/UI/Presenter/PluginsPresenter.php b/src/UI/Presenter/PluginsPresenter.php new file mode 100644 index 0000000000..974318a4ad --- /dev/null +++ b/src/UI/Presenter/PluginsPresenter.php @@ -0,0 +1,149 @@ +createEditForm(); + * $page->show(); + * ``` + * @copyright The Admidio Team + * @see https://www.admidio.org/ + * @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License v2.0 only + */ +class PluginsPresenter extends PagePresenter +{ + protected array $templateData = array(); + + /** + * Create the list of plugins. + * @throws Exception + */ + public function createList(): void + { + global $gL10n; + + $this->setHtmlID('adm_plugins'); + $this->setHeadline($gL10n->get('SYS_PLUGIN_MANAGER')); + + $this->prepareData(); + + $this->smarty->assign('list', $this->templateData); + $this->smarty->assign('l10n', $gL10n); + try { + $this->pageContent .= $this->smarty->fetch('modules/plugins.list.tpl'); + } catch (\Smarty\Exception $e) { + throw new Exception($e->getMessage()); + } + } + + /** + * Read all available forum topics from the database and create a Bootstrap card for each topic. + * @param int $offset Offset of the first record that should be returned. + * @throws Exception + * @throws \DateMalformedStringException + */ + public function createCards(): void + { + global $gL10n; + + $baseUrl = SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/plugins.php', array('mode' => 'cards')); + + $this->setHtmlID('adm_plugins'); + $this->setHeadline($gL10n->get('SYS_PLUGIN_MANAGER')); + + $this->prepareData(); + + $this->smarty->assign('cards', $this->templateData); + $this->smarty->assign('l10n', $gL10n); + $this->smarty->assign('pagination', admFuncGeneratePagination($baseUrl, count($this->templateData), 10, 0)); + + try { + $this->pageContent .= $this->smarty->fetch('modules/plugins.cards.tpl'); + } catch (\Smarty\Exception $e) { + throw new Exception($e->getMessage()); + } + } + + /** + * @param int $offset Offset of the first record that should be returned. + * @throws \DateMalformedStringException + * @throws Exception + */ + public function prepareData(): void + { + global $gL10n; + $pluginManager = new PluginManager(); + $plugins = $pluginManager->getAvailablePlugins(); + + foreach($plugins as $pluginName => $values) { + $templateRow = array(); + $interface = $values['interface'] instanceof PluginAbstract ? $values['interface'] : null; + + if ($interface != null) { + $templateRow['id'] = ($interface->getComponentId() !== 0) ? $interface->getComponentId() : $pluginName; + $templateRow['name'] = Language::translateIfTranslationStrId($interface->getName()); + $templateRow['description'] = Language::translateIfTranslationStrId($interface->getMetadata()['description'] ?? ''); + $templateRow['icon'] = $interface->getMetadata()['icon'] ?? ''; + $templateRow['author'] = $interface->getMetadata()['author'] ?? ''; + $templateRow['version'] = $interface->getMetadata()['version'] ?? ''; + $templateRow['installedVersion'] = $interface->getVersion() !== '0.0.0' ? $interface->getVersion() : ''; + + // add actions for the plugin + if ($interface->isInstalled()) { + // add showPreferences action + $templateRow['actions'][] = array( + 'url' => SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/preferences.php', array('panel' => str_replace(' ', '_',strtolower(Language::translateIfTranslationStrId($interface->getName()))))), + 'icon' => 'bi bi-gear', + 'tooltip' => $gL10n->get('SYS_PLUGIN_PREFERENCES') + ); + // add update action if an update is available + if ($interface->isUpdateAvailable()) { + $templateRow['actions'][] = array( + 'url' => SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/plugins.php', array('mode' => 'update', 'name' => $pluginName)), + 'icon' => 'bi bi-arrow-clockwise', + 'tooltip' => $gL10n->get('SYS_PLUGIN_UPDATE') + ); + } + // add uninstall action + $templateRow['actions'][] = array( + 'url' => SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/plugins.php', array('mode' => 'uninstall', 'name' => $pluginName)), + 'icon' => 'bi bi-trash', + 'tooltip' => $gL10n->get('SYS_PLUGIN_UNINSTALL') + ); + } else { + // add install action + $templateRow['actions'][] = array( + 'url' => SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/plugins.php', array('mode' => 'install', 'name' => $pluginName)), + 'icon' => 'bi bi-download', + 'tooltip' => $gL10n->get('SYS_PLUGIN_INSTALL') + ); + } + } else { + // if the plugin does not implement the PluginInterface then we cannot show it + $templateRow['id'] = $pluginName; + $templateRow['name'] = $pluginName; + $templateRow['description'] = $gL10n->get('SYS_PLUGIN_NO_INTERFACE'); + $templateRow['icon'] = ''; + $templateRow['author'] = ''; + $templateRow['version'] = ''; + $templateRow['installedVersion'] = ''; + } + $this->templateData[] = $templateRow; + } + } +} \ No newline at end of file diff --git a/themes/simple/templates/modules/plugins.list.tpl b/themes/simple/templates/modules/plugins.list.tpl new file mode 100644 index 0000000000..b1a7b28f66 --- /dev/null +++ b/themes/simple/templates/modules/plugins.list.tpl @@ -0,0 +1,28 @@ +
+ + + + + + + + + + + + + {foreach $list as $pluginEntry} + + + + + + + + + {/foreach} + +
{$l10n->get('SYS_NAME')}{$l10n->get('SYS_DESCRIPTION')}{$l10n->get('SYS_AUTHOR')}{$l10n->get('SYS_PLUGIN_VERSION')}{$l10n->get('SYS_INSTALLED_VERSION')} 
{if isset($pluginEntry.icon)}{/if} {$pluginEntry.name}{$pluginEntry.description}{$pluginEntry.author}{$pluginEntry.version}{$pluginEntry.installedVersion} + {include 'sys-template-parts/list.functions.tpl' data=$pluginEntry} +
+
\ No newline at end of file From 68dc6f86c6c48e4f386d1fd10107c796cdd32142 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Mon, 21 Jul 2025 22:15:11 +0200 Subject: [PATCH 003/109] fix: convert array values to string when multiple settings should be set --- src/Preferences/ValueObject/SettingsManager.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Preferences/ValueObject/SettingsManager.php b/src/Preferences/ValueObject/SettingsManager.php index 1f0ba32cb9..3e7eba489b 100644 --- a/src/Preferences/ValueObject/SettingsManager.php +++ b/src/Preferences/ValueObject/SettingsManager.php @@ -346,6 +346,13 @@ public function setMulti(array $settings, bool $update = true) if (!self::isValidName($name)) { throw new Exception('Settings name "' . $name . '" is an invalid string!'); } + + // if array is given as value, convert to string + if (is_array($value)) { + $value = implode(',', $value); + $settings[$name] = $value; + } + if (!self::isValidValue($value) && $this->throwExceptions) { throw new Exception('Settings value "' . $value . '" is an invalid value!'); } From 84dca49b35c9dce8f37d14746cf67cd2ebb3ad53 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Mon, 21 Jul 2025 22:16:55 +0200 Subject: [PATCH 004/109] implement plugin preferences callback management in PreferencesService and PreferencesPresenter --- .../Service/PreferencesService.php | 60 ++++++++++++++++ src/UI/Presenter/PreferencesPresenter.php | 68 +++++++++++++++++-- 2 files changed, 123 insertions(+), 5 deletions(-) diff --git a/src/Preferences/Service/PreferencesService.php b/src/Preferences/Service/PreferencesService.php index 5f00eba499..d6d5a035e1 100644 --- a/src/Preferences/Service/PreferencesService.php +++ b/src/Preferences/Service/PreferencesService.php @@ -8,6 +8,8 @@ use Admidio\Infrastructure\Utils\StringUtils; use Admidio\Infrastructure\Entity\Text; use Admidio\Infrastructure\Email; +use Admidio\Infrastructure\Plugins\PluginManager; +use Admidio\Infrastructure\Language; /** * @brief Class with methods to display the module pages. @@ -21,6 +23,64 @@ */ class PreferencesService { + /** + * Registered presenter callbacks by component ID. + * @var array + */ + private static array $pluginPresenters = array(); + + /** + * Register a preferences presenter for a plugin. + * + * @param int $componentId The component ID of the plugin. + * @param callable $presenterCallback A callable that renders the plugin's preferences panel. + */ + public static function addPluginPreferencesPresenter(int $componentId, callable $presenterCallback): void + { + if (!isset(self::$pluginPresenters[$componentId])) { + self::$pluginPresenters[$componentId] = array(); + } + self::$pluginPresenters[$componentId][] = $presenterCallback; + } + + /** + * Get all registered presenter callbacks, grouped by component ID. + * + * @return array + */ + public static function getPluginPresenters(): array + { + return self::$pluginPresenters; + } + + /** + * Build the panel definitions for the "Plugins" tab. + * + * This method gathers metadata from each plugin and prepares + * the structure used by the PreferencesPresenter to render the accordion. + * + * @return array + */ + public static function getPluginPanels(): array + { + $panels = array(); + + foreach (self::$pluginPresenters as $comId => $callbacks) { + // Retrieve plugin metadata by component ID (you may need to implement this lookup) + $pluginManager = new PluginManager(); + $metadata = $pluginManager->getMetadataByComponentId($comId); + + $panels[] = array( + 'id' => str_replace(' ', '_',strtolower(Language::translateIfTranslationStrId($metadata['name']))), + 'title' => Language::translateIfTranslationStrId($metadata['name']), + 'icon' => $metadata['icon'] ?? 'bi-puzzle', + 'subcards' => $metadata['hasSubcards'] ?? false, + ); + } + + return $panels; + } + /** * Function to check an update * @param string $currentVersion diff --git a/src/UI/Presenter/PreferencesPresenter.php b/src/UI/Presenter/PreferencesPresenter.php index 438365ba2a..a02f9a3cfc 100644 --- a/src/UI/Presenter/PreferencesPresenter.php +++ b/src/UI/Presenter/PreferencesPresenter.php @@ -12,6 +12,9 @@ use Admidio\Inventory\ValueObjects\ItemsData; use Admidio\Preferences\Service\PreferencesService; use Admidio\SSO\Service\KeyService; + +use Admidio\Infrastructure\Plugins\PluginManager; + use RuntimeException; /** @@ -67,12 +70,46 @@ public function __construct(string $panel = '') parent::__construct(); } + public function __call(string $name, array $arguments) + { + // check if the method exists in the PreferencePresanter class + if (method_exists($this, $name)) { + return call_user_func_array([$this, $name], $arguments); + } else { + // Look through every plugin you registered during init() + foreach (PreferencesService::getPluginPresenters() as $comId => $callbacks) { + foreach ($callbacks as $callback) { + // We only stored array callbacks for static methods + if (is_array($callback) + && isset($callback[1]) + && $callback[1] === $name + && is_callable($callback) + ) { + // forward all args (usually none) to the real presenter + $arguments = array_merge(array($this->getSmartyTemplate()), $arguments); + return call_user_func_array($callback, $arguments); + } + } + } + } + + // If we get here, there was no presenter registered under that name: + throw new \BadMethodCallException( + "Call to undefined method " . static::class . "::$name()" + ); + } + /** * @throws Exception */ private function initialize(): void { global $gL10n; + $pluginManager = new PluginManager(); + foreach ($pluginManager->getInstalledPlugins() as $pluginClass) { + $pluginClass::initPreferencePanelCallback(); + } + $this->preferenceTabs = array( // === 1) System === array( @@ -84,7 +121,7 @@ private function initialize(): void array('id'=>'regional_settings', 'title'=>$gL10n->get('ORG_REGIONAL_SETTINGS'), 'icon'=>'bi-globe2', 'subcards'=>false), array('id'=>'changelog', 'title'=>$gL10n->get('SYS_CHANGE_HISTORY'), 'icon'=>'bi-clock-history', 'subcards'=>false), array('id'=>'system_information', 'title'=>$gL10n->get('SYS_INFORMATIONS'), 'icon'=>'bi-info-circle-fill', 'subcards'=>true), - ), + ) ), // === 2) Login and Security === @@ -96,7 +133,7 @@ private function initialize(): void array('id'=>'registration', 'title'=>$gL10n->get('SYS_REGISTRATION'), 'icon'=>'bi-card-checklist', 'subcards'=>false), array('id'=>'captcha', 'title'=>$gL10n->get('SYS_CAPTCHA'), 'icon'=>'bi-fonts', 'subcards'=>false), array('id'=>'sso', 'title'=>$gL10n->get('SYS_SSO'), 'icon'=>'bi-key', 'subcards'=>false), - ), + ) ), // === 3) User Management === @@ -108,7 +145,7 @@ private function initialize(): void array('id'=>'profile', 'title'=>$gL10n->get('SYS_PROFILE'), 'icon'=>'bi-person-fill', 'subcards'=>false), array('id'=>'groups_roles', 'title'=>$gL10n->get('SYS_GROUPS_ROLES'), 'icon'=>'bi-people-fill', 'subcards'=>false), array('id'=>'category_report', 'title'=>$gL10n->get('SYS_CATEGORY_REPORT'), 'icon'=>'bi-list-stars', 'subcards'=>false), - ), + ) ), // === 4) Communication === @@ -121,7 +158,7 @@ private function initialize(): void array('id'=>'messages', 'title'=>$gL10n->get('SYS_MESSAGES'), 'icon'=>'bi-envelope-fill', 'subcards'=>false), array('id'=>'announcements', 'title'=>$gL10n->get('SYS_ANNOUNCEMENTS'), 'icon'=>'bi-newspaper', 'subcards'=>false), array('id'=>'forum', 'title'=>$gL10n->get('SYS_FORUM'), 'icon'=>'bi-chat-dots-fill', 'subcards'=>false), - ), + ) ), // === 5) Contents === @@ -134,8 +171,24 @@ private function initialize(): void array('id'=>'inventory', 'title'=>$gL10n->get('SYS_INVENTORY'), 'icon'=>'bi-box-seam-fill', 'subcards'=>false), array('id'=>'photos', 'title'=>$gL10n->get('SYS_PHOTOS'), 'icon'=>'bi-image-fill', 'subcards'=>false), array('id'=>'links', 'title'=>$gL10n->get('SYS_WEBLINKS'), 'icon'=>'bi-link-45deg', 'subcards'=>false), - ), + ) ), + + // === 6) Extensions === + array( + 'key' => 'extensions', + 'label' => $gL10n->get('SYS_EXTENSIONS'), + // load in all plugin panels that are registered in the PreferencesService + 'panels' => array_map( + fn(array $entry) => [ + 'id' => $entry['id'], + 'title' => $entry['title'], + 'icon' => $entry['icon'] ?? 'bi-puzzle', + 'subcards' => $entry['subcards'] ?? false, + ], + \Admidio\Preferences\Service\PreferencesService::getPluginPanels() + ) + ) ); } @@ -2731,6 +2784,11 @@ function initializePanelInteractions(panelId) { $this->addCssFile(ADMIDIO_URL . FOLDER_LIBS . '/bootstrap-tabs-x/css/bootstrap-tabs-x-admidio.css'); $this->addJavascriptFile(ADMIDIO_URL . FOLDER_LIBS . '/bootstrap-tabs-x/js/bootstrap-tabs-x-admidio.js'); + // remove the plugins array from preferenceTabs if there are no panels defined + $this->preferenceTabs = array_filter($this->preferenceTabs, function ($tab) { + return !empty($tab['panels']); + }); + $this->assignSmartyVariable('preferenceTabs', $this->preferenceTabs); $this->addTemplateFile('preferences/preferences.tpl'); From c17bd32039c0e686934147b5e30c803f2923deb2 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Mon, 21 Jul 2025 22:21:25 +0200 Subject: [PATCH 005/109] rebase announcement-list overview-plugin to use PluginManager --- .gitignore | 2 +- .../AnnouncementList/AnnouncementList.json | 48 ++++++ .../classes/AnnouncementList.php | 160 ++++++++++++++++++ .../AnnouncementListPreferencesPresenter.php | 108 ++++++++++++ .../db_scripts/update_1_0.xml | 4 + adm_plugins/AnnouncementList/index.php | 24 +++ .../languages/bg.xml | 0 .../languages/da.xml | 0 .../languages/de-DE.xml | 0 .../languages/de.xml | 0 .../languages/el.xml | 0 adm_plugins/AnnouncementList/languages/en.xml | 19 +++ .../languages/es.xml | 0 .../languages/et.xml | 0 .../languages/fi.xml | 0 .../languages/fr.xml | 0 .../languages/hu.xml | 0 .../languages/nb.xml | 0 .../languages/nl.xml | 0 .../languages/pl.xml | 0 .../languages/pt-BR.xml | 0 .../languages/pt.xml | 0 .../languages/ru.xml | 0 .../languages/sv.xml | 0 .../languages/uk.xml | 0 .../templates/plugin.announcement-list.tpl | 0 .../preferences.plugin.announcement-list.tpl | 15 ++ .../announcement-list/config_sample.php | 36 ---- adm_plugins/announcement-list/index.php | 142 ---------------- .../announcement-list/languages/en.xml | 6 - composer.json | 5 +- themes/simple/templates/system/overview.tpl | 2 +- 32 files changed, 383 insertions(+), 188 deletions(-) create mode 100644 adm_plugins/AnnouncementList/AnnouncementList.json create mode 100644 adm_plugins/AnnouncementList/classes/AnnouncementList.php create mode 100644 adm_plugins/AnnouncementList/classes/Presenter/AnnouncementListPreferencesPresenter.php create mode 100644 adm_plugins/AnnouncementList/db_scripts/update_1_0.xml create mode 100644 adm_plugins/AnnouncementList/index.php rename adm_plugins/{announcement-list => AnnouncementList}/languages/bg.xml (100%) rename adm_plugins/{announcement-list => AnnouncementList}/languages/da.xml (100%) rename adm_plugins/{announcement-list => AnnouncementList}/languages/de-DE.xml (100%) rename adm_plugins/{announcement-list => AnnouncementList}/languages/de.xml (100%) rename adm_plugins/{announcement-list => AnnouncementList}/languages/el.xml (100%) create mode 100644 adm_plugins/AnnouncementList/languages/en.xml rename adm_plugins/{announcement-list => AnnouncementList}/languages/es.xml (100%) rename adm_plugins/{announcement-list => AnnouncementList}/languages/et.xml (100%) rename adm_plugins/{announcement-list => AnnouncementList}/languages/fi.xml (100%) mode change 100755 => 100644 rename adm_plugins/{announcement-list => AnnouncementList}/languages/fr.xml (100%) rename adm_plugins/{announcement-list => AnnouncementList}/languages/hu.xml (100%) rename adm_plugins/{announcement-list => AnnouncementList}/languages/nb.xml (100%) rename adm_plugins/{announcement-list => AnnouncementList}/languages/nl.xml (100%) rename adm_plugins/{announcement-list => AnnouncementList}/languages/pl.xml (100%) rename adm_plugins/{announcement-list => AnnouncementList}/languages/pt-BR.xml (100%) rename adm_plugins/{announcement-list => AnnouncementList}/languages/pt.xml (100%) rename adm_plugins/{announcement-list => AnnouncementList}/languages/ru.xml (100%) rename adm_plugins/{announcement-list => AnnouncementList}/languages/sv.xml (100%) rename adm_plugins/{announcement-list => AnnouncementList}/languages/uk.xml (100%) rename adm_plugins/{announcement-list => AnnouncementList}/templates/plugin.announcement-list.tpl (100%) create mode 100644 adm_plugins/AnnouncementList/templates/preferences.plugin.announcement-list.tpl delete mode 100644 adm_plugins/announcement-list/config_sample.php delete mode 100644 adm_plugins/announcement-list/index.php delete mode 100644 adm_plugins/announcement-list/languages/en.xml diff --git a/.gitignore b/.gitignore index 9cddf76521..1b5d377fc2 100644 --- a/.gitignore +++ b/.gitignore @@ -15,7 +15,7 @@ !/adm_plugins/calendar/ !/adm_plugins/login_form/ !/adm_plugins/random_photo/ -!/adm_plugins/announcement-list/ +!/adm_plugins/AnnouncementList/ !/adm_plugins/event-list/ !/adm_plugins/latest-documents-files/ !/adm_plugins/who-is-online/ diff --git a/adm_plugins/AnnouncementList/AnnouncementList.json b/adm_plugins/AnnouncementList/AnnouncementList.json new file mode 100644 index 0000000000..cea88ce906 --- /dev/null +++ b/adm_plugins/AnnouncementList/AnnouncementList.json @@ -0,0 +1,48 @@ +{ + "name": "PLG_ANNOUNCEMENT_LIST_PLUGIN_NAME", + "description": "PLG_ANNOUNCEMENT_LIST_PLUGIN_DESCRIPTION", + "version": "1.0.0", + "author": "Admidio Team", + "url": "https://www.admidio.org", + "icon": "bi-newspaper", + "mainFile": "index.php", + "dependencies": [], + "defaultConfig": { + "announcement_list_plugin_enabled": { + "name": "ORG_ACCESS_TO_PLUGIN", + "description": "ORG_ACCESS_TO_PLUGIN_DESC", + "type": "integer", + "value" : 1 + }, + "announcement_list_announcements_count": { + "name": "PLG_ANNOUNCEMENT_LIST_PREFERENCES_ANNOUNCEMENTS_COUNT", + "description": "PLG_ANNOUNCEMENT_LIST_PREFERENCES_ANNOUNCEMENTS_COUNT_DESC", + "type": "integer", + "value" : 2 + }, + "announcement_list_show_preview_chars": { + "name": "PLG_ANNOUNCEMENT_LIST_PREFERENCES_SHOW_PREVIEW_CHARS", + "description": "PLG_ANNOUNCEMENT_LIST_PREFERENCES_SHOW_PREVIEW_CHARS_DESC", + "type": "integer", + "value" : 70 + }, + "announcement_list_show_full_description": { + "name": "PLG_ANNOUNCEMENT_LIST_PREFERENCES_SHOW_FULL_DESCRIPTION", + "description": "PLG_ANNOUNCEMENT_LIST_PREFERENCES_SHOW_FULL_DESCRIPTION_DESC", + "type": "boolean", + "value" : false + }, + "announcement_list_chars_before_linebreak": { + "name": "PLG_ANNOUNCEMENT_LIST_PREFERENCES_CHARS_BEFORE_LINEBREAK", + "description": "PLG_ANNOUNCEMENT_LIST_PREFERENCES_CHARS_BEFORE_LINEBREAK_DESC", + "type": "integer", + "value" : 0 + }, + "announcement_list_displayed_categories": { + "name": "PLG_ANNOUNCEMENT_LIST_PREFERENCES_DISPLAYED_CATEGORIES", + "description": "PLG_ANNOUNCEMENT_LIST_PREFERENCES_DISPLAYED_CATEGORIES_DESC", + "type": "array", + "value" : [] + } + } +} \ No newline at end of file diff --git a/adm_plugins/AnnouncementList/classes/AnnouncementList.php b/adm_plugins/AnnouncementList/classes/AnnouncementList.php new file mode 100644 index 0000000000..1a17e3b271 --- /dev/null +++ b/adm_plugins/AnnouncementList/classes/AnnouncementList.php @@ -0,0 +1,160 @@ +getAllVisibleCategories('ANN')); + + $sql = 'SELECT cat.*, ann.* + FROM ' . TBL_ANNOUNCEMENTS . ' AS ann + INNER JOIN ' . TBL_CATEGORIES . ' AS cat + ON cat_id = ann_cat_id + WHERE cat_id IN (' . Database::getQmForValues($catIdParams) . ') + ' . $plgSqlCategories . ' + ORDER BY ann_timestamp_create DESC + LIMIT ' . $config['announcement_list_announcements_count']; + + $pdoStatement = $gDb->queryPrepared($sql, array_merge($catIdParams, $config['announcement_list_displayed_categories'])); + $plgAnnouncementsList = $pdoStatement->fetchAll(); + + $announcementArray = array(); + + if ($pdoStatement->rowCount() > 0) { + // get announcements data + $plgAnnouncement = new Announcement($gDb); + + foreach ($plgAnnouncementsList as $plgRow) { + $plgAnnouncement->clear(); + $plgAnnouncement->setArray($plgRow); + + if ($config['announcement_list_chars_before_linebreak'] > 0) { + // Interrupt words of headline if they are too long + $plgNewHeadline = ''; + + $plgWords = explode(' ', $plgAnnouncement->getValue('ann_headline')); + + foreach ($plgWords as $plgValue) { + if (strlen($plgValue) > $config['announcement_list_chars_before_linebreak']) { + $plgNewHeadline .= ' ' . substr($plgValue, 0, $config['announcement_list_chars_before_linebreak']) . '-
' . + substr($plgValue, $config['announcement_list_chars_before_linebreak']); + } else { + $plgNewHeadline .= ' ' . $plgValue; + } + } + } else { + $plgNewHeadline = $plgAnnouncement->getValue('ann_headline'); + } + + // show preview text + if ($config['announcement_list_show_full_description'] === 1) { + $plgNewDescription = $plgAnnouncement->getValue('ann_description'); + } elseif ($config['announcement_list_show_preview_chars'] > 0) { + // remove all html tags except some format tags + $plgNewDescription = strip_tags($plgAnnouncement->getValue('ann_description')); + + // read first x chars of text and additional 15 chars. Then search for last space and cut the text there + $plgNewDescription = substr($plgNewDescription, 0, $config['announcement_list_show_preview_chars'] + 15); + $plgNewDescription = substr($plgNewDescription, 0, strrpos($plgNewDescription, ' ')) . ' + »'; + } + + $announcementArray[] = array( + 'uuid' => $plgAnnouncement->getValue('ann_uuid'), + 'headline' => $plgNewHeadline, + 'description' => $plgNewDescription, + 'creationDate' => $plgAnnouncement->getValue('ann_timestamp_create', $gSettingsManager->getString('system_date')) + ); + } + } + return $announcementArray; + } + + /** + * @param array $config + * @throws InvalidArgumentException + * @throws Exception + * @return bool + */ + public static function doRender(array $config = array()) + { + global $gSettingsManager, $gL10n; + + if (!is_array($config)) + { + throw new InvalidArgumentException('Config must be an "array".'); + } + + // show the announcement list + try { + $rootPath = dirname(__DIR__, 3); + $pluginFolder = basename(self::$pluginPath); + + require_once($rootPath . '/system/common.php'); + + $announcementListPlugin = new Overview($pluginFolder); + + if ($gSettingsManager->getInt('announcements_module_enabled') > 0) { + if ($gSettingsManager->getInt('announcements_module_enabled') === 1 + || ($gSettingsManager->getInt('announcements_module_enabled') === 2 && $gValidLogin)) { + $announcementArray = self::getAnnouncementsData(); + if (!empty($announcementArray)) { + $announcementListPlugin->assignTemplateVariable('announcements', $announcementArray); + } else { + $announcementListPlugin->assignTemplateVariable('message',$gL10n->get('SYS_NO_ENTRIES')); + } + } else { + $announcementListPlugin->assignTemplateVariable('message',$gL10n->get('PLG_ANNOUNCEMENT_LIST_NO_ENTRIES_VISITORS')); + } + if (isset($page)) { + echo $announcementListPlugin->html('plugin.announcement-list.tpl'); + } else { + $announcementListPlugin->showHtmlPage('plugin.announcement-list.tpl'); + } + } + } catch (Throwable $e) { + echo $e->getMessage(); + } + + return true; + } +} \ No newline at end of file diff --git a/adm_plugins/AnnouncementList/classes/Presenter/AnnouncementListPreferencesPresenter.php b/adm_plugins/AnnouncementList/classes/Presenter/AnnouncementListPreferencesPresenter.php new file mode 100644 index 0000000000..e86f50e582 --- /dev/null +++ b/adm_plugins/AnnouncementList/classes/Presenter/AnnouncementListPreferencesPresenter.php @@ -0,0 +1,108 @@ + 'save', 'panel' => 'announcement_list')), + null, + array('class' => 'form-preferences') + ); + $selectBoxEntries = array( + '0' => $gL10n->get('SYS_DISABLED'), + '1' => $gL10n->get('SYS_ENABLED'), + '2' => $gL10n->get('ORG_ONLY_FOR_REGISTERED_USER') + ); + $formAnnouncementList->addSelectBox( + 'announcement_list_plugin_enabled', + Language::translateIfTranslationStrId($formValues['announcement_list_plugin_enabled']['name']), + $selectBoxEntries, + array('defaultValue' => $formValues['announcement_list_plugin_enabled']['value'], 'showContextDependentFirstEntry' => false, 'helpTextId' => $formValues['announcement_list_plugin_enabled']['description']) + ); + $formAnnouncementList->addInput( + 'announcement_list_announcements_count', + Language::translateIfTranslationStrId($formValues['announcement_list_announcements_count']['name']), + $formValues['announcement_list_announcements_count']['value'], + array('type' => 'number', 'minNumber' => 0, 'maxNumber' => 20, 'step' => 1, 'helpTextId' => $formValues['announcement_list_announcements_count']['description']) + ); + $formAnnouncementList->addInput( + 'announcement_list_show_preview_chars', + Language::translateIfTranslationStrId($formValues['announcement_list_show_preview_chars']['name']), + $formValues['announcement_list_show_preview_chars']['value'], + array('type' => 'number', 'minNumber' => 0, 'step' => 1, 'helpTextId' => $formValues['announcement_list_show_preview_chars']['description']) + ); + $formAnnouncementList->addCheckbox( + 'announcement_list_show_full_description', + Language::translateIfTranslationStrId($formValues['announcement_list_show_full_description']['name']), + $formValues['announcement_list_show_full_description']['value'], + array('helpTextId' => $formValues['announcement_list_show_full_description']['description']) + ); + $formAnnouncementList->addInput( + 'announcement_list_chars_before_linebreak', + Language::translateIfTranslationStrId($formValues['announcement_list_chars_before_linebreak']['name']), + $formValues['announcement_list_chars_before_linebreak']['value'], + array('type' => 'number', 'minNumber' => 0, 'step' => 1, 'helpTextId' => $formValues['announcement_list_chars_before_linebreak']['description']) + ); + + $catIdParams = array_merge(array(0), $gCurrentUser->getAllVisibleCategories('ANN')); + $sql = 'SELECT cat.cat_id, cat.cat_name + FROM ' . TBL_ANNOUNCEMENTS . ' AS ann + INNER JOIN ' . TBL_CATEGORIES . ' AS cat + ON cat_id = ann_cat_id + WHERE cat_id IN (' . $gDb->getQmForValues($catIdParams) . ') + ORDER BY ann_timestamp_create DESC'; + $sqlData = array( + 'query' => $sql, + 'params' => $catIdParams + ); + + $formAnnouncementList->addSelectBoxFromSql( + 'announcement_list_displayed_categories', + Language::translateIfTranslationStrId($formValues['announcement_list_displayed_categories']['name']), + $gDb, + $sqlData, + array('defaultValue' => $formValues['announcement_list_displayed_categories']['value'], 'showContextDependentFirstEntry' => false, 'helpTextId' => $formValues['announcement_list_displayed_categories']['description'], 'multiselect' => true, 'maximumSelectionNumber' => count($gCurrentUser->getAllVisibleCategories('ANN'))) + ); + $formAnnouncementList->addSubmitButton( + 'adm_button_save_announcement_list', + $gL10n->get('SYS_SAVE'), + array('icon' => 'bi-check-lg', 'class' => 'offset-sm-3') + ); + + $formAnnouncementList->addToSmarty($smarty); + $gCurrentSession->addFormObject($formAnnouncementList); + return $smarty->fetch($pluginAnnouncementList::getPluginPath() . '/templates/preferences.plugin.announcement-list.tpl'); + } +} \ No newline at end of file diff --git a/adm_plugins/AnnouncementList/db_scripts/update_1_0.xml b/adm_plugins/AnnouncementList/db_scripts/update_1_0.xml new file mode 100644 index 0000000000..c297b05c32 --- /dev/null +++ b/adm_plugins/AnnouncementList/db_scripts/update_1_0.xml @@ -0,0 +1,4 @@ + + + stop + diff --git a/adm_plugins/AnnouncementList/index.php b/adm_plugins/AnnouncementList/index.php new file mode 100644 index 0000000000..fd43b0d76e --- /dev/null +++ b/adm_plugins/AnnouncementList/index.php @@ -0,0 +1,24 @@ +doRender(); + +} catch (Throwable $e) { + echo $e->getMessage(); +} diff --git a/adm_plugins/announcement-list/languages/bg.xml b/adm_plugins/AnnouncementList/languages/bg.xml similarity index 100% rename from adm_plugins/announcement-list/languages/bg.xml rename to adm_plugins/AnnouncementList/languages/bg.xml diff --git a/adm_plugins/announcement-list/languages/da.xml b/adm_plugins/AnnouncementList/languages/da.xml similarity index 100% rename from adm_plugins/announcement-list/languages/da.xml rename to adm_plugins/AnnouncementList/languages/da.xml diff --git a/adm_plugins/announcement-list/languages/de-DE.xml b/adm_plugins/AnnouncementList/languages/de-DE.xml similarity index 100% rename from adm_plugins/announcement-list/languages/de-DE.xml rename to adm_plugins/AnnouncementList/languages/de-DE.xml diff --git a/adm_plugins/announcement-list/languages/de.xml b/adm_plugins/AnnouncementList/languages/de.xml similarity index 100% rename from adm_plugins/announcement-list/languages/de.xml rename to adm_plugins/AnnouncementList/languages/de.xml diff --git a/adm_plugins/announcement-list/languages/el.xml b/adm_plugins/AnnouncementList/languages/el.xml similarity index 100% rename from adm_plugins/announcement-list/languages/el.xml rename to adm_plugins/AnnouncementList/languages/el.xml diff --git a/adm_plugins/AnnouncementList/languages/en.xml b/adm_plugins/AnnouncementList/languages/en.xml new file mode 100644 index 0000000000..fb2de9b4dc --- /dev/null +++ b/adm_plugins/AnnouncementList/languages/en.xml @@ -0,0 +1,19 @@ + + + All entries + Announcements + There are no announcements available for visitors. Log in to see the announcements. + This plugin displays a preview list of the latest announcements on the Overview page. + Announcement List + + Number of announcements + Number of announcements to be displayed. (Default = 2) + Characters before line break + Maximum number of characters in a word before a line break should be performed. (0: deactivates line break, default: 0) + Displayed categories + If you only want to show announcements of a special category you can select the categories here. (default: All) + Show full description + If set to true (1) the full content of the description will be shown. (0: only show text preview, default: 0) + Preview text + Number of characters of the preview text. (0: no short preview, default: 70) + diff --git a/adm_plugins/announcement-list/languages/es.xml b/adm_plugins/AnnouncementList/languages/es.xml similarity index 100% rename from adm_plugins/announcement-list/languages/es.xml rename to adm_plugins/AnnouncementList/languages/es.xml diff --git a/adm_plugins/announcement-list/languages/et.xml b/adm_plugins/AnnouncementList/languages/et.xml similarity index 100% rename from adm_plugins/announcement-list/languages/et.xml rename to adm_plugins/AnnouncementList/languages/et.xml diff --git a/adm_plugins/announcement-list/languages/fi.xml b/adm_plugins/AnnouncementList/languages/fi.xml old mode 100755 new mode 100644 similarity index 100% rename from adm_plugins/announcement-list/languages/fi.xml rename to adm_plugins/AnnouncementList/languages/fi.xml diff --git a/adm_plugins/announcement-list/languages/fr.xml b/adm_plugins/AnnouncementList/languages/fr.xml similarity index 100% rename from adm_plugins/announcement-list/languages/fr.xml rename to adm_plugins/AnnouncementList/languages/fr.xml diff --git a/adm_plugins/announcement-list/languages/hu.xml b/adm_plugins/AnnouncementList/languages/hu.xml similarity index 100% rename from adm_plugins/announcement-list/languages/hu.xml rename to adm_plugins/AnnouncementList/languages/hu.xml diff --git a/adm_plugins/announcement-list/languages/nb.xml b/adm_plugins/AnnouncementList/languages/nb.xml similarity index 100% rename from adm_plugins/announcement-list/languages/nb.xml rename to adm_plugins/AnnouncementList/languages/nb.xml diff --git a/adm_plugins/announcement-list/languages/nl.xml b/adm_plugins/AnnouncementList/languages/nl.xml similarity index 100% rename from adm_plugins/announcement-list/languages/nl.xml rename to adm_plugins/AnnouncementList/languages/nl.xml diff --git a/adm_plugins/announcement-list/languages/pl.xml b/adm_plugins/AnnouncementList/languages/pl.xml similarity index 100% rename from adm_plugins/announcement-list/languages/pl.xml rename to adm_plugins/AnnouncementList/languages/pl.xml diff --git a/adm_plugins/announcement-list/languages/pt-BR.xml b/adm_plugins/AnnouncementList/languages/pt-BR.xml similarity index 100% rename from adm_plugins/announcement-list/languages/pt-BR.xml rename to adm_plugins/AnnouncementList/languages/pt-BR.xml diff --git a/adm_plugins/announcement-list/languages/pt.xml b/adm_plugins/AnnouncementList/languages/pt.xml similarity index 100% rename from adm_plugins/announcement-list/languages/pt.xml rename to adm_plugins/AnnouncementList/languages/pt.xml diff --git a/adm_plugins/announcement-list/languages/ru.xml b/adm_plugins/AnnouncementList/languages/ru.xml similarity index 100% rename from adm_plugins/announcement-list/languages/ru.xml rename to adm_plugins/AnnouncementList/languages/ru.xml diff --git a/adm_plugins/announcement-list/languages/sv.xml b/adm_plugins/AnnouncementList/languages/sv.xml similarity index 100% rename from adm_plugins/announcement-list/languages/sv.xml rename to adm_plugins/AnnouncementList/languages/sv.xml diff --git a/adm_plugins/announcement-list/languages/uk.xml b/adm_plugins/AnnouncementList/languages/uk.xml similarity index 100% rename from adm_plugins/announcement-list/languages/uk.xml rename to adm_plugins/AnnouncementList/languages/uk.xml diff --git a/adm_plugins/announcement-list/templates/plugin.announcement-list.tpl b/adm_plugins/AnnouncementList/templates/plugin.announcement-list.tpl similarity index 100% rename from adm_plugins/announcement-list/templates/plugin.announcement-list.tpl rename to adm_plugins/AnnouncementList/templates/plugin.announcement-list.tpl diff --git a/adm_plugins/AnnouncementList/templates/preferences.plugin.announcement-list.tpl b/adm_plugins/AnnouncementList/templates/preferences.plugin.announcement-list.tpl new file mode 100644 index 0000000000..3688514ee4 --- /dev/null +++ b/adm_plugins/AnnouncementList/templates/preferences.plugin.announcement-list.tpl @@ -0,0 +1,15 @@ +
+ + {include 'sys-template-parts/form.input.tpl' data=$elements['adm_csrf_token']} + {include 'sys-template-parts/form.select.tpl' data=$elements['announcement_list_plugin_enabled']} + {include 'sys-template-parts/form.input.tpl' data=$elements['announcement_list_announcements_count']} + {include 'sys-template-parts/form.input.tpl' data=$elements['announcement_list_show_preview_chars']} + {include 'sys-template-parts/form.checkbox.tpl' data=$elements['announcement_list_show_full_description']} + {include 'sys-template-parts/form.input.tpl' data=$elements['announcement_list_chars_before_linebreak']} + {include 'sys-template-parts/form.select.tpl' data=$elements['announcement_list_displayed_categories']} + {include 'sys-template-parts/form.button.tpl' data=$elements['adm_button_save_announcement_list']} + +
+{$javascript} \ No newline at end of file diff --git a/adm_plugins/announcement-list/config_sample.php b/adm_plugins/announcement-list/config_sample.php deleted file mode 100644 index a648a170f4..0000000000 --- a/adm_plugins/announcement-list/config_sample.php +++ /dev/null @@ -1,36 +0,0 @@ -getInt('announcements_module_enabled') > 0) { - // read announcements from database - $catIdParams = array_merge(array(0), $gCurrentUser->getAllVisibleCategories('ANN')); - - $sql = 'SELECT cat.*, ann.* - FROM ' . TBL_ANNOUNCEMENTS . ' AS ann - INNER JOIN ' . TBL_CATEGORIES . ' AS cat - ON cat_id = ann_cat_id - WHERE cat_id IN (' . Database::getQmForValues($catIdParams) . ') - ' . $plgSqlCategories . ' - ORDER BY ann_timestamp_create DESC - LIMIT ' . $plg_announcements_count; - - $pdoStatement = $gDb->queryPrepared($sql, array_merge($catIdParams, $plg_categories)); - $plgAnnouncementsList = $pdoStatement->fetchAll(); - - if ($gSettingsManager->getInt('announcements_module_enabled') === 1 - || ($gSettingsManager->getInt('announcements_module_enabled') === 2 && $gValidLogin)) { - if ($pdoStatement->rowCount() > 0) { - // get announcements data - $plgAnnouncement = new Announcement($gDb); - $announcementArray = array(); - - foreach ($plgAnnouncementsList as $plgRow) { - $plgAnnouncement->clear(); - $plgAnnouncement->setArray($plgRow); - - if ($plg_max_char_per_word > 0) { - // Interrupt words of headline if they are too long - $plgNewHeadline = ''; - - $plgWords = explode(' ', $plgAnnouncement->getValue('ann_headline')); - - foreach ($plgWords as $plgValue) { - if (strlen($plgValue) > $plg_max_char_per_word) { - $plgNewHeadline .= ' ' . substr($plgValue, 0, $plg_max_char_per_word) . '-
' . - substr($plgValue, $plg_max_char_per_word); - } else { - $plgNewHeadline .= ' ' . $plgValue; - } - } - } else { - $plgNewHeadline = $plgAnnouncement->getValue('ann_headline'); - } - - // show preview text - if ($plgShowFullDescription === 1) { - $plgNewDescription = $plgAnnouncement->getValue('ann_description'); - } elseif ($plg_show_preview > 0) { - // remove all html tags except some format tags - $plgNewDescription = strip_tags($plgAnnouncement->getValue('ann_description')); - - // read first x chars of text and additional 15 chars. Then search for last space and cut the text there - $plgNewDescription = substr($plgNewDescription, 0, $plg_show_preview + 15); - $plgNewDescription = substr($plgNewDescription, 0, strrpos($plgNewDescription, ' ')) . ' - »'; - } - - $announcementArray[] = array( - 'uuid' => $plgAnnouncement->getValue('ann_uuid'), - 'headline' => $plgNewHeadline, - 'description' => $plgNewDescription, - 'creationDate' => $plgAnnouncement->getValue('ann_timestamp_create', $gSettingsManager->getString('system_date')) - ); - } - - $announcementListPlugin->assignTemplateVariable('announcements', $announcementArray); - } else { - $announcementListPlugin->assignTemplateVariable('message',$gL10n->get('SYS_NO_ENTRIES')); - } - } else { - $announcementListPlugin->assignTemplateVariable('message',$gL10n->get('PLG_ANNOUNCEMENT_LIST_NO_ENTRIES_VISITORS')); - } - if (isset($page)) { - echo $announcementListPlugin->html('plugin.announcement-list.tpl'); - } else { - $announcementListPlugin->showHtmlPage('plugin.announcement-list.tpl'); - } - } -} catch (Throwable $e) { - echo $e->getMessage(); -} diff --git a/adm_plugins/announcement-list/languages/en.xml b/adm_plugins/announcement-list/languages/en.xml deleted file mode 100644 index ec8cf6313f..0000000000 --- a/adm_plugins/announcement-list/languages/en.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - All entries - Announcements - There are no announcements available for visitors. Log in to see the announcements. - diff --git a/composer.json b/composer.json index 4bd2cff612..e7d3e6f3c7 100644 --- a/composer.json +++ b/composer.json @@ -50,7 +50,8 @@ }, "autoload": { "psr-4": { - "Admidio\\": "src/" + "Admidio\\": "src/", + "Plugins\\": "adm_plugins/" }, "classmap": [ "system/classes/", @@ -67,7 +68,7 @@ "!adm_my_files/ecard_templates", "!adm_my_files/mail_templates", "adm_plugins/*", - "!adm_plugins/announcement-list", + "!adm_plugins/AnnouncementList", "!adm_plugins/birthday", "!adm_plugins/calendar", "!adm_plugins/event-list", diff --git a/themes/simple/templates/system/overview.tpl b/themes/simple/templates/system/overview.tpl index be5b6a0cfd..d27a6d6271 100644 --- a/themes/simple/templates/system/overview.tpl +++ b/themes/simple/templates/system/overview.tpl @@ -38,7 +38,7 @@
- {load_admidio_plugin plugin="announcement-list" file="index.php"} + {load_admidio_plugin plugin="AnnouncementList" file="index.php"}
From 122a67011bb55473972d6a1c4d95c0b4a7d61122 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Tue, 22 Jul 2025 00:31:51 +0200 Subject: [PATCH 006/109] - add custom plugin configuration retrieval to AccouncementList and update displayed categories logic - fix: doRender() needs $page to only return the Html content for overview page --- .../AnnouncementList/AnnouncementList.json | 2 +- .../classes/AnnouncementList.php | 41 ++++++++++++++++++- .../AnnouncementListPreferencesPresenter.php | 1 - adm_plugins/AnnouncementList/index.php | 2 +- 4 files changed, 42 insertions(+), 4 deletions(-) diff --git a/adm_plugins/AnnouncementList/AnnouncementList.json b/adm_plugins/AnnouncementList/AnnouncementList.json index cea88ce906..75e4c08fb5 100644 --- a/adm_plugins/AnnouncementList/AnnouncementList.json +++ b/adm_plugins/AnnouncementList/AnnouncementList.json @@ -42,7 +42,7 @@ "name": "PLG_ANNOUNCEMENT_LIST_PREFERENCES_DISPLAYED_CATEGORIES", "description": "PLG_ANNOUNCEMENT_LIST_PREFERENCES_DISPLAYED_CATEGORIES_DESC", "type": "array", - "value" : [] + "value" : ["All"] } } } \ No newline at end of file diff --git a/adm_plugins/AnnouncementList/classes/AnnouncementList.php b/adm_plugins/AnnouncementList/classes/AnnouncementList.php index 1a17e3b271..2b6f6d40a4 100644 --- a/adm_plugins/AnnouncementList/classes/AnnouncementList.php +++ b/adm_plugins/AnnouncementList/classes/AnnouncementList.php @@ -26,6 +26,45 @@ */ class AnnouncementList extends PluginAbstract { + /** + * Get the plugin configuration + * @return array Returns the plugin configuration + */ + public static function getPluginConfig() : array + { + global $gCurrentUser; + + // get the plugin config from the parent class + $config = parent::getPluginConfig(); + + // if the key equals 'announcement_list_displayed_categories' and the value is still the default value, retrieve the categories from the database + if (array_key_exists('announcement_list_displayed_categories', $config) && $config['announcement_list_displayed_categories']['value'] === self::$defaultConfig['announcement_list_displayed_categories']['value']) { + $config['announcement_list_displayed_categories']['value'] = $gCurrentUser->getAllVisibleCategories('ANN'); + } + return $config; + + } + + /** + * Get the plugin configuration values + * @return array Returns the plugin configuration values + */ + public static function getPluginConfigValues() : array + { + global $gCurrentUser; + + // get the plugin config values from the parent class + $config = parent::getPluginConfigValues(); + + // if the key equals 'announcement_list_displayed_categories' and the value is still the default value, retrieve the categories from the database + if (array_key_exists('announcement_list_displayed_categories', $config) && $config['announcement_list_displayed_categories'] === self::$defaultConfig['announcement_list_displayed_categories']['value']) { + $config['announcement_list_displayed_categories'] = $gCurrentUser->getAllVisibleCategories('ANN'); + } + + return $config; + + } + private static function getAnnouncementsData() : array { global $gSettingsManager, $gCurrentUser, $gDb, $gL10n; @@ -115,7 +154,7 @@ private static function getAnnouncementsData() : array * @throws Exception * @return bool */ - public static function doRender(array $config = array()) + public static function doRender($page = null, array $config = array()) : bool { global $gSettingsManager, $gL10n; diff --git a/adm_plugins/AnnouncementList/classes/Presenter/AnnouncementListPreferencesPresenter.php b/adm_plugins/AnnouncementList/classes/Presenter/AnnouncementListPreferencesPresenter.php index e86f50e582..09c6aa679c 100644 --- a/adm_plugins/AnnouncementList/classes/Presenter/AnnouncementListPreferencesPresenter.php +++ b/adm_plugins/AnnouncementList/classes/Presenter/AnnouncementListPreferencesPresenter.php @@ -80,7 +80,6 @@ public static function createAnnouncementListForm(Smarty $smarty): string $sql = 'SELECT cat.cat_id, cat.cat_name FROM ' . TBL_ANNOUNCEMENTS . ' AS ann INNER JOIN ' . TBL_CATEGORIES . ' AS cat - ON cat_id = ann_cat_id WHERE cat_id IN (' . $gDb->getQmForValues($catIdParams) . ') ORDER BY ann_timestamp_create DESC'; $sqlData = array( diff --git a/adm_plugins/AnnouncementList/index.php b/adm_plugins/AnnouncementList/index.php index fd43b0d76e..19b392c4ad 100644 --- a/adm_plugins/AnnouncementList/index.php +++ b/adm_plugins/AnnouncementList/index.php @@ -17,7 +17,7 @@ require_once(__DIR__ . '/../../system/common.php'); $pluginAnnouncementList = AnnouncementList::getInstance(); - $pluginAnnouncementList->doRender(); + $pluginAnnouncementList->doRender($page); } catch (Throwable $e) { echo $e->getMessage(); From 5b3e1889bdd173f27750e8294aa9d1928d55cdbc Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Tue, 22 Jul 2025 00:33:34 +0200 Subject: [PATCH 007/109] update method signatures for type hinting and add function to retrieve overview plugins --- src/Infrastructure/Plugins/PluginAbstract.php | 31 ++++++++++++- .../Plugins/PluginInterface.php | 40 +++++++++++------ src/Infrastructure/Plugins/PluginManager.php | 44 ++++++++++++++++--- 3 files changed, 93 insertions(+), 22 deletions(-) diff --git a/src/Infrastructure/Plugins/PluginAbstract.php b/src/Infrastructure/Plugins/PluginAbstract.php index c439c0335e..82d045a772 100644 --- a/src/Infrastructure/Plugins/PluginAbstract.php +++ b/src/Infrastructure/Plugins/PluginAbstract.php @@ -216,7 +216,7 @@ public static function getSupportedLanguages() : array * @throws Exception * @return array */ - public static function getStaticFiles($type = null) : array + public static function getStaticFiles(?string $type = null) : array { if ($type !== null && !is_string($type)) { @@ -287,6 +287,10 @@ public static function getPluginConfigValues() : array return $config; } + /** + * Get the plugin configuration + * @return array Returns the plugin configuration + */ public static function getPluginConfig() : array { $config = self::$defaultConfig; @@ -313,6 +317,15 @@ public static function getComponentId() : int return self::$pluginComId; } + /** + * @throws Exception + * @return string + */ + public static function getComponentName() : string + { + return basename(self::$pluginPath); + } + /** * @throws Exception * @return bool @@ -337,6 +350,22 @@ public static function isActivated() : bool return self::isInstalled() && (self::getComponentId() > 0); } + /** + * @throws Exception + * @return bool + */ + public static function isOverviewPlugin() : bool + { +/* global $gDb; + // check if the plugin exists in components database table + $sql = 'SELECT COUNT(*) AS count FROM ' . TBL_COMPONENTS . ' WHERE com_name = ? AND com_type = ?'; + $statement = $gDb->queryPrepared($sql, array(self::getName(), 'OVERVIEW_PLUGIN')); + $columns = (int)$statement->fetchColumn(); + + return $columns > 0; */ + return true; + } + /** * @throws Exception * @return bool diff --git a/src/Infrastructure/Plugins/PluginInterface.php b/src/Infrastructure/Plugins/PluginInterface.php index 44cd23433d..687ece2506 100644 --- a/src/Infrastructure/Plugins/PluginInterface.php +++ b/src/Infrastructure/Plugins/PluginInterface.php @@ -2,6 +2,7 @@ namespace Admidio\Infrastructure\Plugins; +use Admidio\UI\Presenter\PagePresenter; use InvalidArgumentException; use Exception; /** @@ -12,32 +13,32 @@ interface PluginInterface /** * @return PluginInterface */ - public static function getInstance(); + public static function getInstance() : PluginInterface; /** * @return string */ - public static function getName(); + public static function getName() : string; /** * @return string */ - public static function getVersion(); + public static function getVersion() : string; /** * @return array */ - public static function getMetadata(); + public static function getMetadata() : array; /** * @return array */ - public static function getDependencies(); + public static function getDependencies() : array; /** * @return array */ - public static function getSupportedLanguages(); + public static function getSupportedLanguages() : array; /** * @param string $type @@ -45,7 +46,7 @@ public static function getSupportedLanguages(); * @throws Exception * @return array */ - public static function getStaticFiles($type = null); + public static function getStaticFiles(?string $type = null) : array; /** * @throws InvalidArgumentException @@ -60,17 +61,28 @@ public static function getPluginConfig() : array; */ public static function getComponentId() : int; + /** + * @throws Exception + * @return string + */ + public static function getComponentName() : string; + /** + * @throws Exception + * @return bool + */ + public static function isInstalled() : bool; + /** * @throws Exception * @return bool */ - public static function isInstalled(); + public static function isActivated() : bool; /** * @throws Exception * @return bool */ - public static function isActivated(); + public static function isOverviewPlugin() : bool; /** * @throws Exception @@ -82,13 +94,13 @@ public static function isUpdateAvailable() : bool; * @throws Exception * @return bool */ - public static function doClassAutoload(); + public static function doClassAutoload() : bool; /** * @throws Exception * @return bool */ - public static function doInstall(); + public static function doInstall() : bool; /** * @param array $options @@ -96,13 +108,13 @@ public static function doInstall(); * @throws Exception * @return bool */ - public static function doUninstall(array $options = array()); + public static function doUninstall(array $options = array()) : bool; /** * @throws Exception * @return bool */ - public static function doUpdate(); + public static function doUpdate() : bool; /** * @param array $config @@ -110,5 +122,5 @@ public static function doUpdate(); * @throws Exception * @return bool */ - public static function doRender(array $config = array()); + public static function doRender(PagePresenter $page, array $config = array()) : bool; } \ No newline at end of file diff --git a/src/Infrastructure/Plugins/PluginManager.php b/src/Infrastructure/Plugins/PluginManager.php index 8fb0f7d460..892597d473 100644 --- a/src/Infrastructure/Plugins/PluginManager.php +++ b/src/Infrastructure/Plugins/PluginManager.php @@ -49,7 +49,7 @@ public function getAvailablePlugins() : array|object return $plugins; } - public function getPluginById(int $pluginId): ?PluginAbstract + public function getPluginById(int $pluginId) : ?PluginAbstract { $plugins = $this->getAvailablePlugins(); foreach ($plugins as $plugin) { @@ -60,7 +60,7 @@ public function getPluginById(int $pluginId): ?PluginAbstract return null; } - public function getPluginByName(string $pluginName): ?PluginAbstract + public function getPluginByName(string $pluginName) : ?PluginAbstract { $plugins = $this->getAvailablePlugins(); if (isset($plugins[$pluginName]) && $plugins[$pluginName]['interface'] instanceof PluginAbstract) { @@ -69,7 +69,7 @@ public function getPluginByName(string $pluginName): ?PluginAbstract return null; } - public function getMetadataByComponentId(int $componentId): ?array + public function getMetadataByComponentId(int $componentId) : ?array { $plugin = $this->getPluginById($componentId); return $plugin ? $plugin->getMetadata() : null; @@ -88,13 +88,12 @@ private function getMainPluginFile(string $pluginFolder, string $pluginName, ?Pl $this->pluginMainFile = $pluginFile; } } - return; } /** * Parse a PHP file and return the first class name found. */ - private function getClassNameFromFile(string $file): ?string + private function getClassNameFromFile(string $file) : ?string { $src = file_get_contents($file); $tokens = token_get_all($src); @@ -138,10 +137,41 @@ public function getInstalledPlugins() : array } /** - * + * Get all plugins that are used on the overview page. + * @return array */ - public function getActivePlugins() + public function getOverviewPlugins() : array { + $availablePlugins = $this->getAvailablePlugins(); + $overviewPlugins = array(); + foreach ($availablePlugins as $plugin) { + if ($plugin['interface'] instanceof PluginAbstract && $plugin['interface']->isInstalled() && $plugin['interface']->isOverviewPlugin()) { + $overviewPlugins[] = array( + 'id' => $plugin['interface']->getComponentId(), + 'name' => $plugin['interface']->getComponentName(), + 'file' => basename($plugin['relativePath']), + 'interface' => $plugin['interface'] + ); + } + } + return $overviewPlugins; + } + /** + * Get all active plugins. + * @return array + */ + public function getActivePlugins() : array + { + $availablePlugins = $this->getAvailablePlugins(); + $activePlugins = array(); + // TODO: Check if the plugin is activated + // For now, we assume all installed plugins are active. + foreach ($availablePlugins as $plugin) { + if ($plugin['interface'] instanceof PluginAbstract && $plugin['interface']->isInstalled()) { + $activePlugins[] = $plugin['interface']; + } + } + return $activePlugins; } } \ No newline at end of file From d98525f2bb1e92f374040fe8ca96dc9b4c0ec351 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Tue, 22 Jul 2025 01:01:58 +0200 Subject: [PATCH 008/109] small improvements --- .../AnnouncementList/classes/AnnouncementList.php | 6 +++--- adm_plugins/AnnouncementList/index.php | 2 +- src/Infrastructure/Plugins/PluginInterface.php | 4 ++-- src/Infrastructure/Plugins/PluginManager.php | 13 ++++++++++++- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/adm_plugins/AnnouncementList/classes/AnnouncementList.php b/adm_plugins/AnnouncementList/classes/AnnouncementList.php index 2b6f6d40a4..5f04ce80e5 100644 --- a/adm_plugins/AnnouncementList/classes/AnnouncementList.php +++ b/adm_plugins/AnnouncementList/classes/AnnouncementList.php @@ -156,7 +156,7 @@ private static function getAnnouncementsData() : array */ public static function doRender($page = null, array $config = array()) : bool { - global $gSettingsManager, $gL10n; + global $gSettingsManager, $gL10n, $gValidLogin; if (!is_array($config)) { @@ -173,8 +173,8 @@ public static function doRender($page = null, array $config = array()) : bool $announcementListPlugin = new Overview($pluginFolder); if ($gSettingsManager->getInt('announcements_module_enabled') > 0) { - if ($gSettingsManager->getInt('announcements_module_enabled') === 1 - || ($gSettingsManager->getInt('announcements_module_enabled') === 2 && $gValidLogin)) { + if (($gSettingsManager->getInt('announcements_module_enabled') === 1 || ($gSettingsManager->getInt('announcements_module_enabled') === 2 && $gValidLogin)) && + ($gSettingsManager->getInt('announcement_list_plugin_enabled') === 1 || ($gSettingsManager->getInt('announcement_list_plugin_enabled') === 2 && $gValidLogin))) { $announcementArray = self::getAnnouncementsData(); if (!empty($announcementArray)) { $announcementListPlugin->assignTemplateVariable('announcements', $announcementArray); diff --git a/adm_plugins/AnnouncementList/index.php b/adm_plugins/AnnouncementList/index.php index 19b392c4ad..babcc2c13a 100644 --- a/adm_plugins/AnnouncementList/index.php +++ b/adm_plugins/AnnouncementList/index.php @@ -17,7 +17,7 @@ require_once(__DIR__ . '/../../system/common.php'); $pluginAnnouncementList = AnnouncementList::getInstance(); - $pluginAnnouncementList->doRender($page); + $pluginAnnouncementList->doRender(isset($page) ? $page : null); } catch (Throwable $e) { echo $e->getMessage(); diff --git a/src/Infrastructure/Plugins/PluginInterface.php b/src/Infrastructure/Plugins/PluginInterface.php index 687ece2506..10477e6cb8 100644 --- a/src/Infrastructure/Plugins/PluginInterface.php +++ b/src/Infrastructure/Plugins/PluginInterface.php @@ -13,7 +13,7 @@ interface PluginInterface /** * @return PluginInterface */ - public static function getInstance() : PluginInterface; + public static function getInstance() ; /** * @return string @@ -122,5 +122,5 @@ public static function doUpdate() : bool; * @throws Exception * @return bool */ - public static function doRender(PagePresenter $page, array $config = array()) : bool; + public static function doRender(?PagePresenter $page = null, array $config = array()) : bool; } \ No newline at end of file diff --git a/src/Infrastructure/Plugins/PluginManager.php b/src/Infrastructure/Plugins/PluginManager.php index 892597d473..581353313c 100644 --- a/src/Infrastructure/Plugins/PluginManager.php +++ b/src/Infrastructure/Plugins/PluginManager.php @@ -146,6 +146,17 @@ public function getOverviewPlugins() : array $overviewPlugins = array(); foreach ($availablePlugins as $plugin) { if ($plugin['interface'] instanceof PluginAbstract && $plugin['interface']->isInstalled() && $plugin['interface']->isOverviewPlugin()) { + $configValues = $plugin['interface']->getPluginConfigValues(); + $enabled = false; + foreach ($configValues as $key => $value) { + if (preg_match('/_enabled$/', $key) && $value > 0) { + $enabled = true; + break; + } + } + if (!$enabled) { + continue; + } $overviewPlugins[] = array( 'id' => $plugin['interface']->getComponentId(), 'name' => $plugin['interface']->getComponentName(), @@ -168,7 +179,7 @@ public function getActivePlugins() : array // TODO: Check if the plugin is activated // For now, we assume all installed plugins are active. foreach ($availablePlugins as $plugin) { - if ($plugin['interface'] instanceof PluginAbstract && $plugin['interface']->isInstalled()) { + if ($plugin['interface'] instanceof PluginAbstract && $plugin['interface']->isActivated()) { $activePlugins[] = $plugin['interface']; } } From b53cec3111a2d4e903d7295ba7a480885a41afba Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Tue, 22 Jul 2025 10:31:05 +0200 Subject: [PATCH 009/109] implement component tye ADM_PLUGIN for overview plugins and implement grouping of available plugins in PluginsPresener --- .../db_scripts/update_1_0.xml | 1 + src/Components/Entity/Component.php | 1 + src/Components/Entity/ComponentUpdate.php | 2 +- src/Infrastructure/Plugins/PluginAbstract.php | 27 +++++++------- src/UI/Presenter/PluginsPresenter.php | 34 +++++++++++++---- .../simple/templates/modules/plugins.list.tpl | 37 +++++++++++++------ 6 files changed, 67 insertions(+), 35 deletions(-) diff --git a/adm_plugins/AnnouncementList/db_scripts/update_1_0.xml b/adm_plugins/AnnouncementList/db_scripts/update_1_0.xml index c297b05c32..1439532f43 100644 --- a/adm_plugins/AnnouncementList/db_scripts/update_1_0.xml +++ b/adm_plugins/AnnouncementList/db_scripts/update_1_0.xml @@ -1,4 +1,5 @@ + UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'AnnouncementList' stop diff --git a/src/Components/Entity/Component.php b/src/Components/Entity/Component.php index c31172fa41..a1c4cd66de 100644 --- a/src/Components/Entity/Component.php +++ b/src/Components/Entity/Component.php @@ -196,6 +196,7 @@ public static function isAdministrable(string $componentName): bool case 'MESSAGES': // fallthrough case 'ORGANIZATIONS': // fallthrough case 'PREFERENCES': // fallthrough + case 'PLUGINS': // fallthrough case 'ROOMS': if ($gCurrentUser->isAdministrator()) { return true; diff --git a/src/Components/Entity/ComponentUpdate.php b/src/Components/Entity/ComponentUpdate.php index 1aef47f4a8..73142cd149 100644 --- a/src/Components/Entity/ComponentUpdate.php +++ b/src/Components/Entity/ComponentUpdate.php @@ -84,7 +84,7 @@ private function getXmlObject(int $mainVersion, int $minorVersion): SimpleXMLEle $gLogger->warning($message, array('filePath' => $updateFile)); throw new UnexpectedValueException($message); - } elseif ($this->getValue('com_type') === 'PLUGIN') { + } elseif ($this->getValue('com_type') === 'PLUGIN' || $this->getValue('com_type') === 'ADM_PLUGIN') { $updateFile = ADMIDIO_PATH . FOLDER_PLUGINS . '/' . $this->getValue('com_name_intern') . '/db_scripts/update_'.$mainVersion.'_'.$minorVersion.'.xml'; if (is_file($updateFile)) { diff --git a/src/Infrastructure/Plugins/PluginAbstract.php b/src/Infrastructure/Plugins/PluginAbstract.php index 82d045a772..dcd1caf339 100644 --- a/src/Infrastructure/Plugins/PluginAbstract.php +++ b/src/Infrastructure/Plugins/PluginAbstract.php @@ -142,13 +142,13 @@ public static function getInstance() : PluginAbstract if (self::$instances[$class]->isInstalled()) { global $gDb; // get the component id of the plugin - $sql = 'SELECT com_id FROM ' . TBL_COMPONENTS . ' WHERE com_name = ? AND com_type = ?'; - $statement = $gDb->queryPrepared($sql, array(self::getName(), 'PLUGIN')); + $sql = 'SELECT com_id FROM ' . TBL_COMPONENTS . ' WHERE com_name = ? AND (com_type = ? OR com_type = ?)'; + $statement = $gDb->queryPrepared($sql, array(self::getName(), 'PLUGIN', 'ADM_PLUGIN')); self::$pluginComId = (int)$statement->fetchColumn(); // get the installed version of the plugin - $sql = 'SELECT com_version FROM ' . TBL_COMPONENTS . ' WHERE com_name = ? AND com_type = ?'; - $statement = $gDb->queryPrepared($sql, array(self::getName(), 'PLUGIN')); + $sql = 'SELECT com_version FROM ' . TBL_COMPONENTS . ' WHERE com_name = ? AND (com_type = ? OR com_type = ?)'; + $statement = $gDb->queryPrepared($sql, array(self::getName(), 'PLUGIN', 'ADM_PLUGIN')); self::$version = (string)$statement->fetchColumn(); } } @@ -334,8 +334,8 @@ public static function isInstalled() : bool { global $gDb; // check if the plugin exists in components database table - $sql = 'SELECT COUNT(*) AS count FROM ' . TBL_COMPONENTS . ' WHERE com_name = ? AND com_type = ?'; - $statement = $gDb->queryPrepared($sql, array(self::getName(), 'PLUGIN')); + $sql = 'SELECT COUNT(*) AS count FROM ' . TBL_COMPONENTS . ' WHERE com_name = ? AND (com_type = ? OR com_type = ?)'; + $statement = $gDb->queryPrepared($sql, array(self::getName(), 'PLUGIN', 'ADM_PLUGIN')); $columns = (int)$statement->fetchColumn(); return $columns > 0; @@ -356,14 +356,13 @@ public static function isActivated() : bool */ public static function isOverviewPlugin() : bool { -/* global $gDb; - // check if the plugin exists in components database table + global $gDb; + // check if the plugin exists in components database table and is of type 'ADM_PLUGIN' $sql = 'SELECT COUNT(*) AS count FROM ' . TBL_COMPONENTS . ' WHERE com_name = ? AND com_type = ?'; - $statement = $gDb->queryPrepared($sql, array(self::getName(), 'OVERVIEW_PLUGIN')); + $statement = $gDb->queryPrepared($sql, array(self::getName(), 'ADM_PLUGIN')); $columns = (int)$statement->fetchColumn(); - return $columns > 0; */ - return true; + return $columns > 0; } /** @@ -374,8 +373,8 @@ public static function isUpdateAvailable() : bool { global $gDb; // check if the plugin exists in components database table - $sql = 'SELECT com_version FROM ' . TBL_COMPONENTS . ' WHERE com_name = ? AND com_type = ?'; - $statement = $gDb->queryPrepared($sql, array(self::getName(), 'PLUGIN')); + $sql = 'SELECT com_version FROM ' . TBL_COMPONENTS . ' WHERE com_name = ? AND (com_type = ? OR com_type = ?)'; + $statement = $gDb->queryPrepared($sql, array(self::getName(), 'PLUGIN', 'ADM_PLUGIN')); $currentVersion = $statement->fetchColumn(); return version_compare($currentVersion, self::getVersion(), '<'); @@ -496,7 +495,7 @@ public static function doUpdate() : bool // update the plugin $componentUpdateHandle = new ComponentUpdate($gDb); - $componentUpdateHandle->readDataByColumns(array('com_type' => 'PLUGIN', 'com_name' => self::getName(), 'com_name_intern' => basename(self::$pluginPath))); + $componentUpdateHandle->readDataByColumns(array('com_name' => self::getName(), 'com_name_intern' => basename(self::$pluginPath))); $componentUpdateHandle->updatePlugin(self::$metadata['version']); // set the installed version of the plugin diff --git a/src/UI/Presenter/PluginsPresenter.php b/src/UI/Presenter/PluginsPresenter.php index 974318a4ad..8a24910ae9 100644 --- a/src/UI/Presenter/PluginsPresenter.php +++ b/src/UI/Presenter/PluginsPresenter.php @@ -42,6 +42,13 @@ public function createList(): void $this->prepareData(); + $this->addJavascript(' + $(".admidio-open-close-caret").click(function() { + showHideBlock($(this)); + }); + ', true + ); + $this->smarty->assign('list', $this->templateData); $this->smarty->assign('l10n', $gL10n); try { @@ -89,7 +96,8 @@ public function prepareData(): void global $gL10n; $pluginManager = new PluginManager(); $plugins = $pluginManager->getAvailablePlugins(); - + $templateRowPluginParent[] = array('id' => 'overview_plugins', 'name' => $gL10n->get('SYS_OVERVIEW_EXTENSIONS'), 'entries' => array()); + $templateRowPluginParent[] = array('id' => 'plugins', 'name' => $gL10n->get('SYS_EXTENSIONS'), 'entries' => array()); foreach($plugins as $pluginName => $values) { $templateRow = array(); $interface = $values['interface'] instanceof PluginAbstract ? $values['interface'] : null; @@ -119,12 +127,14 @@ public function prepareData(): void 'tooltip' => $gL10n->get('SYS_PLUGIN_UPDATE') ); } - // add uninstall action - $templateRow['actions'][] = array( - 'url' => SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/plugins.php', array('mode' => 'uninstall', 'name' => $pluginName)), - 'icon' => 'bi bi-trash', - 'tooltip' => $gL10n->get('SYS_PLUGIN_UNINSTALL') - ); + if (!$interface->isOverviewPlugin()) { + // add uninstall action + $templateRow['actions'][] = array( + 'url' => SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/plugins.php', array('mode' => 'uninstall', 'name' => $pluginName)), + 'icon' => 'bi bi-trash', + 'tooltip' => $gL10n->get('SYS_PLUGIN_UNINSTALL') + ); + } } else { // add install action $templateRow['actions'][] = array( @@ -143,7 +153,15 @@ public function prepareData(): void $templateRow['version'] = ''; $templateRow['installedVersion'] = ''; } - $this->templateData[] = $templateRow; + + if ($interface !== null && $interface->isOverviewPlugin()) { + // add the plugin to the overview plugins + $templateRowPluginParent[0]['entries'][] = $templateRow; + } else { + // add the plugin to the normal plugins + $templateRowPluginParent[1]['entries'][] = $templateRow; + } } + $this->templateData = $templateRowPluginParent; } } \ No newline at end of file diff --git a/themes/simple/templates/modules/plugins.list.tpl b/themes/simple/templates/modules/plugins.list.tpl index b1a7b28f66..e2485e27d7 100644 --- a/themes/simple/templates/modules/plugins.list.tpl +++ b/themes/simple/templates/modules/plugins.list.tpl @@ -10,19 +10,32 @@   - - {foreach $list as $pluginEntry} - - {if isset($pluginEntry.icon)}{/if} {$pluginEntry.name} - {$pluginEntry.description} - {$pluginEntry.author} - {$pluginEntry.version} - {$pluginEntry.installedVersion} - - {include 'sys-template-parts/list.functions.tpl' data=$pluginEntry} + {foreach $list as $pluginNode} + + + + + + {$pluginNode.name} - {/foreach} - + + {if isset($pluginNode.entries)} + + {foreach $pluginNode.entries as $pluginEntry} + + {if isset($pluginEntry.icon)}{/if} {$pluginEntry.name} + {$pluginEntry.description} + {$pluginEntry.author} + {$pluginEntry.version} + {$pluginEntry.installedVersion} + + {include 'sys-template-parts/list.functions.tpl' data=$pluginEntry} + + + {/foreach} + + {/if} + {/foreach} \ No newline at end of file From 561c0c65923e928067cc8b64970fe7c352416033 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Tue, 22 Jul 2025 14:41:08 +0200 Subject: [PATCH 010/109] small fixes AnnouncementList --- adm_plugins/AnnouncementList/classes/AnnouncementList.php | 2 -- adm_plugins/AnnouncementList/languages/en.xml | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/adm_plugins/AnnouncementList/classes/AnnouncementList.php b/adm_plugins/AnnouncementList/classes/AnnouncementList.php index 5f04ce80e5..f307816daf 100644 --- a/adm_plugins/AnnouncementList/classes/AnnouncementList.php +++ b/adm_plugins/AnnouncementList/classes/AnnouncementList.php @@ -42,7 +42,6 @@ public static function getPluginConfig() : array $config['announcement_list_displayed_categories']['value'] = $gCurrentUser->getAllVisibleCategories('ANN'); } return $config; - } /** @@ -62,7 +61,6 @@ public static function getPluginConfigValues() : array } return $config; - } private static function getAnnouncementsData() : array diff --git a/adm_plugins/AnnouncementList/languages/en.xml b/adm_plugins/AnnouncementList/languages/en.xml index fb2de9b4dc..e02039f428 100644 --- a/adm_plugins/AnnouncementList/languages/en.xml +++ b/adm_plugins/AnnouncementList/languages/en.xml @@ -7,13 +7,13 @@ Announcement List Number of announcements - Number of announcements to be displayed. (Default = 2) + Number of announcements to be displayed. (default: 2) Characters before line break Maximum number of characters in a word before a line break should be performed. (0: deactivates line break, default: 0) Displayed categories If you only want to show announcements of a special category you can select the categories here. (default: All) Show full description - If set to true (1) the full content of the description will be shown. (0: only show text preview, default: 0) + If this setting is enabled the full content of the description will be shown. Otherwise only a text preview will be displayed. (default: false) Preview text Number of characters of the preview text. (0: no short preview, default: 70) From 91f4d6097d57fa0c7b66601fe2a9905d8cc63105 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Tue, 22 Jul 2025 14:47:08 +0200 Subject: [PATCH 011/109] fix: when multiple plugin instances are defined the correct instance must be retrieved again by geInstance() --- modules/plugins.php | 6 +-- src/Infrastructure/Plugins/PluginAbstract.php | 40 ++++++++++--------- src/Infrastructure/Plugins/PluginManager.php | 11 ++++- src/UI/Presenter/PluginsPresenter.php | 2 +- src/UI/Presenter/PreferencesPresenter.php | 1 + 5 files changed, 36 insertions(+), 24 deletions(-) diff --git a/modules/plugins.php b/modules/plugins.php index d1bb49686a..4b79125a7f 100644 --- a/modules/plugins.php +++ b/modules/plugins.php @@ -51,7 +51,7 @@ $pluginManager = new PluginManager(); $plugin = $pluginManager->getPluginByName($getPluginName); if ($plugin) { - $interface = $plugin instanceof PluginAbstract ? $plugin : null; + $interface = $plugin instanceof PluginAbstract ? $plugin::getInstance() : null; if ($interface != null) { $interface->doInstall(); @@ -70,7 +70,7 @@ $pluginManager = new PluginManager(); $plugin = $pluginManager->getPluginByName($getPluginName); if ($plugin) { - $interface = $plugin instanceof PluginAbstract ? $plugin : null; + $interface = $plugin instanceof PluginAbstract ? $plugin::getInstance() : null; if ($interface != null) { $interface->doUninstall(); @@ -89,7 +89,7 @@ $pluginManager = new PluginManager(); $plugin = $pluginManager->getPluginByName($getPluginName); if ($plugin) { - $interface = $plugin instanceof PluginAbstract ? $plugin : null; + $interface = $plugin instanceof PluginAbstract ? $plugin::getInstance() : null; if ($interface != null) { $interface->doUpdate(); diff --git a/src/Infrastructure/Plugins/PluginAbstract.php b/src/Infrastructure/Plugins/PluginAbstract.php index dcd1caf339..9d553222bb 100644 --- a/src/Infrastructure/Plugins/PluginAbstract.php +++ b/src/Infrastructure/Plugins/PluginAbstract.php @@ -28,9 +28,7 @@ abstract class PluginAbstract implements PluginInterface */ protected function __construct() { - // set the plugin path to the folder of this class - $reflection = new \ReflectionClass($this); - self::$pluginPath = dirname($reflection->getFileName(), 2); + } /** @@ -136,21 +134,27 @@ public static function getInstance() : PluginAbstract { self::$instances[$class] = new $class(); self::$instances[$class]->doClassAutoload(); - self::$instances[$class]->readPluginMetadata(); - - // check if the plugin is installed - if (self::$instances[$class]->isInstalled()) { - global $gDb; - // get the component id of the plugin - $sql = 'SELECT com_id FROM ' . TBL_COMPONENTS . ' WHERE com_name = ? AND (com_type = ? OR com_type = ?)'; - $statement = $gDb->queryPrepared($sql, array(self::getName(), 'PLUGIN', 'ADM_PLUGIN')); - self::$pluginComId = (int)$statement->fetchColumn(); - - // get the installed version of the plugin - $sql = 'SELECT com_version FROM ' . TBL_COMPONENTS . ' WHERE com_name = ? AND (com_type = ? OR com_type = ?)'; - $statement = $gDb->queryPrepared($sql, array(self::getName(), 'PLUGIN', 'ADM_PLUGIN')); - self::$version = (string)$statement->fetchColumn(); - } + } + + // set the plugin path to the folder of this class + $reflection = new \ReflectionClass(self::$instances[$class]); + self::$pluginPath = dirname($reflection->getFileName(), 2); + + // read the plugin metadata + self::$instances[$class]->readPluginMetadata(); + + // check if the plugin is installed + if (self::$instances[$class]->isInstalled()) { + global $gDb; + // get the component id of the plugin + $sql = 'SELECT com_id FROM ' . TBL_COMPONENTS . ' WHERE com_name = ? AND (com_type = ? OR com_type = ?)'; + $statement = $gDb->queryPrepared($sql, array(self::getName(), 'PLUGIN', 'ADM_PLUGIN')); + self::$pluginComId = (int)$statement->fetchColumn(); + + // get the installed version of the plugin + $sql = 'SELECT com_version FROM ' . TBL_COMPONENTS . ' WHERE com_name = ? AND (com_type = ? OR com_type = ?)'; + $statement = $gDb->queryPrepared($sql, array(self::getName(), 'PLUGIN', 'ADM_PLUGIN')); + self::$version = (string)$statement->fetchColumn(); } return self::$instances[$class]; diff --git a/src/Infrastructure/Plugins/PluginManager.php b/src/Infrastructure/Plugins/PluginManager.php index 581353313c..629573cf9f 100644 --- a/src/Infrastructure/Plugins/PluginManager.php +++ b/src/Infrastructure/Plugins/PluginManager.php @@ -53,6 +53,7 @@ public function getPluginById(int $pluginId) : ?PluginAbstract { $plugins = $this->getAvailablePlugins(); foreach ($plugins as $plugin) { + $plugin['interface'] = $plugin['interface'] !== null ? $plugin['interface']::getInstance() : null; if ($plugin['interface'] instanceof PluginAbstract && $plugin['interface']->getComponentId() === $pluginId) { return $plugin['interface']; } @@ -63,8 +64,11 @@ public function getPluginById(int $pluginId) : ?PluginAbstract public function getPluginByName(string $pluginName) : ?PluginAbstract { $plugins = $this->getAvailablePlugins(); - if (isset($plugins[$pluginName]) && $plugins[$pluginName]['interface'] instanceof PluginAbstract) { - return $plugins[$pluginName]['interface']; + if (isset($plugins[$pluginName])) { + $plugin = $plugins[$pluginName]['interface'] !== null ? $plugins[$pluginName]['interface']::getInstance() : null; + if ($plugin instanceof PluginAbstract) { + return $plugin; + } } return null; } @@ -129,6 +133,7 @@ public function getInstalledPlugins() : array $availablePlugins = $this->getAvailablePlugins(); $installedPlugins = array(); foreach ($availablePlugins as $plugin) { + $plugin['interface'] = $plugin['interface'] !== null ? $plugin['interface']::getInstance() : null; if ($plugin['interface'] instanceof PluginAbstract && $plugin['interface']->isInstalled()) { $installedPlugins[] = $plugin['interface']; } @@ -145,6 +150,7 @@ public function getOverviewPlugins() : array $availablePlugins = $this->getAvailablePlugins(); $overviewPlugins = array(); foreach ($availablePlugins as $plugin) { + $plugin['interface'] = $plugin['interface'] !== null ? $plugin['interface']::getInstance() : null; if ($plugin['interface'] instanceof PluginAbstract && $plugin['interface']->isInstalled() && $plugin['interface']->isOverviewPlugin()) { $configValues = $plugin['interface']->getPluginConfigValues(); $enabled = false; @@ -179,6 +185,7 @@ public function getActivePlugins() : array // TODO: Check if the plugin is activated // For now, we assume all installed plugins are active. foreach ($availablePlugins as $plugin) { + $plugin['interface'] = $plugin['interface'] !== null ? $plugin['interface']::getInstance() : null; if ($plugin['interface'] instanceof PluginAbstract && $plugin['interface']->isActivated()) { $activePlugins[] = $plugin['interface']; } diff --git a/src/UI/Presenter/PluginsPresenter.php b/src/UI/Presenter/PluginsPresenter.php index 8a24910ae9..c35c6e8995 100644 --- a/src/UI/Presenter/PluginsPresenter.php +++ b/src/UI/Presenter/PluginsPresenter.php @@ -100,7 +100,7 @@ public function prepareData(): void $templateRowPluginParent[] = array('id' => 'plugins', 'name' => $gL10n->get('SYS_EXTENSIONS'), 'entries' => array()); foreach($plugins as $pluginName => $values) { $templateRow = array(); - $interface = $values['interface'] instanceof PluginAbstract ? $values['interface'] : null; + $interface = $values['interface'] instanceof PluginAbstract ? $values['interface']::getInstance() : null; if ($interface != null) { $templateRow['id'] = ($interface->getComponentId() !== 0) ? $interface->getComponentId() : $pluginName; diff --git a/src/UI/Presenter/PreferencesPresenter.php b/src/UI/Presenter/PreferencesPresenter.php index a02f9a3cfc..5508837ce8 100644 --- a/src/UI/Presenter/PreferencesPresenter.php +++ b/src/UI/Presenter/PreferencesPresenter.php @@ -107,6 +107,7 @@ private function initialize(): void global $gL10n; $pluginManager = new PluginManager(); foreach ($pluginManager->getInstalledPlugins() as $pluginClass) { + $pluginClass::getInstance(); $pluginClass::initPreferencePanelCallback(); } From b1d3bf8903041831f5feaf28a4d3ff5ab68cda07 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Tue, 22 Jul 2025 14:48:50 +0200 Subject: [PATCH 012/109] rebase birthday overview-plugin to use PluginManager --- adm_plugins/birthday/Birthday.json | 90 ++++ adm_plugins/birthday/classes/Birthday.php | 424 ++++++++++++++++++ .../BirthdayPreferencesPresenter.php | 155 +++++++ adm_plugins/birthday/config_sample.php | 72 --- .../birthday/db_scripts/update_1_0.xml | 5 + adm_plugins/birthday/index.php | 339 +------------- adm_plugins/birthday/languages/en.xml | 28 ++ .../templates/preferences.plugin.birthday.tpl | 23 + 8 files changed, 730 insertions(+), 406 deletions(-) create mode 100644 adm_plugins/birthday/Birthday.json create mode 100644 adm_plugins/birthday/classes/Birthday.php create mode 100644 adm_plugins/birthday/classes/Presenter/BirthdayPreferencesPresenter.php delete mode 100644 adm_plugins/birthday/config_sample.php create mode 100644 adm_plugins/birthday/db_scripts/update_1_0.xml create mode 100644 adm_plugins/birthday/templates/preferences.plugin.birthday.tpl diff --git a/adm_plugins/birthday/Birthday.json b/adm_plugins/birthday/Birthday.json new file mode 100644 index 0000000000..1965085edd --- /dev/null +++ b/adm_plugins/birthday/Birthday.json @@ -0,0 +1,90 @@ +{ + "name": "PLG_BIRTHDAY_PLUGIN_NAME", + "description": "PLG_BIRTHDAY_PLUGIN_DESCRIPTION", + "version": "1.0.0", + "author": "Admidio Team", + "url": "https://www.admidio.org", + "icon": "bi-cake2", + "mainFile": "index.php", + "dependencies": [], + "defaultConfig": { + "birthday_plugin_enabled": { + "name": "ORG_ACCESS_TO_PLUGIN", + "description": "ORG_ACCESS_TO_PLUGIN_DESC", + "type": "integer", + "value" : 1 + }, + "birthday_show_names_extern": { + "name": "PLG_BIRTHDAY_PREFERENCES_SHOW_NAMES_EXTERN", + "description": "PLG_BIRTHDAY_PREFERENCES_SHOW_NAMES_EXTERN_DESC", + "type": "boolean", + "value" : false + }, + "birthday_show_names": { + "name": "PLG_BIRTHDAY_PREFERENCES_SHOW_NAMES", + "description": "PLG_BIRTHDAY_PREFERENCES_SHOW_NAMES_DESC", + "type": "integer", + "value" : 0 + }, + "birthday_show_age": { + "name": "PLG_BIRTHDAY_PREFERENCES_SHOW_AGE", + "description": "PLG_BIRTHDAY_PREFERENCES_SHOW_AGE_DESC", + "type": "boolean", + "value" : false + }, + "birthday_show_age_salutation": { + "name": "PLG_BIRTHDAY_PREFERENCES_SHOW_AGE_SALUTATION", + "description": "PLG_BIRTHDAY_PREFERENCES_SHOW_AGE_SALUTATION_DESC", + "type": "integer", + "value" : 18 + }, + "birthday_show_notice_none": { + "name": "PLG_BIRTHDAY_PREFERENCES_SHOW_NOTICE_NONE", + "description": "PLG_BIRTHDAY_PREFERENCES_SHOW_NOTICE_NONE_DESC", + "type": "boolean", + "value" : true + }, + "birthday_show_past": { + "name": "PLG_BIRTHDAY_PREFERENCES_SHOW_PAST", + "description": "PLG_BIRTHDAY_PREFERENCES_SHOW_PAST_DESC", + "type": "integer", + "value" : 1 + }, + "birthday_show_future": { + "name": "PLG_BIRTHDAY_PREFERENCES_SHOW_FUTURE", + "description": "PLG_BIRTHDAY_PREFERENCES_SHOW_FUTURE_DESC", + "type": "integer", + "value" : 2 + }, + "birthday_show_display_limit": { + "name": "PLG_BIRTHDAY_PREFERENCES_SHOW_DISPLAY_LIMIT", + "description": "PLG_BIRTHDAY_PREFERENCES_SHOW_DISPLAY_LIMIT_DESC", + "type": "integer", + "value" : 200 + }, + "birthday_show_email_extern": { + "name": "PLG_BIRTHDAY_PREFERENCES_SHOW_EMAIL_EXTERN", + "description": "PLG_BIRTHDAY_PREFERENCES_SHOW_EMAIL_EXTERN_DESC", + "type": "integer", + "value" : 0 + }, + "birthday_roles_view_plugin": { + "name": "PLG_BIRTHDAY_PREFERENCES_ROLES_VIEW_PLUGIN", + "description": "PLG_BIRTHDAY_PREFERENCES_ROLES_VIEW_PLUGIN_DESC", + "type": "array", + "value" : ["All"] + }, + "birthday_roles_sql": { + "name": "PLG_BIRTHDAY_PREFERENCES_ROLES_SQL", + "description": "PLG_BIRTHDAY_PREFERENCES_ROLES_SQL_DESC", + "type": "array", + "value" : ["All"] + }, + "birthday_sort_sql": { + "name": "PLG_BIRTHDAY_PREFERENCES_SORT_SQL", + "description": "PLG_BIRTHDAY_PREFERENCES_SORT_SQL_DESC", + "type": "string", + "value" : "DESC" + } + } +} \ No newline at end of file diff --git a/adm_plugins/birthday/classes/Birthday.php b/adm_plugins/birthday/classes/Birthday.php new file mode 100644 index 0000000000..da8d3cd0ce --- /dev/null +++ b/adm_plugins/birthday/classes/Birthday.php @@ -0,0 +1,424 @@ +findAll($roleType); + + foreach ($data as $rowViewRoles) { + if ($onlyIds) { + // If only the IDs are requested, return an array with the role IDs + $allRolesSet[] = $rowViewRoles['rol_id']; + } else { + // Each role is now added to this array + $allRolesSet[] = array( + $rowViewRoles['rol_id'], // ID + $rowViewRoles['rol_name'] + ); + } + } + return $allRolesSet; + } + + private static function getBirthdaysData() : array + { + global $gSettingsManager, $gCurrentUser, $gDb, $gL10n, $gProfileFields, $gValidLogin, $gDbType, $gCurrentOrgId; + + $config = self::getPluginConfigValues(); + + // check if only members of configured roles could view birthday + if ($gValidLogin) { + if (isset($config['birthday_roles_view_plugin']) && count($config['birthday_roles_view_plugin']) > 0) { + // current user must be member of at least one listed role + if (count(array_intersect($config['birthday_roles_view_plugin'], $gCurrentUser->getRoleMemberships())) > 0) { + self::$birthdayShowNames = true; + } + } + } else { + if ($config['birthday_show_names_extern'] === 1) { + // every visitor is allowed to view birthdays + self::$birthdayShowNames = true; + } + } + + // Check if the role condition has been set + if (isset($config['birthday_rolle_sql']) && is_array($config['birthday_rolle_sql']) && count($config['birthday_rolle_sql']) > 0) { + $sqlRol = 'IN (' . implode(',', $config['birthday_rolle_sql']) . ')'; + } else { + $sqlRol = 'IS NOT NULL'; + } + + // Check if the sort condition has been set + if (!isset($config['birthday_sort_sql']) || $config['birthday_sort_sql'] === '') { + $sqlSort = 'DESC'; + } else { + $sqlSort = $config['birthday_sort_sql']; + } + + // if no birthdays should be shown than disable future and former birthday periods + if (!self::$birthdayShowNames) { + $config['birthday_show_past'] = 0; + $config['birthday_show_future'] = 0; + } + + $fieldBirthday = $gProfileFields->getProperty('BIRTHDAY', 'usf_id'); + + if ($gDbType === 'pgsql') { + $sql = 'SELECT DISTINCT usr_id, usr_uuid, usr_login_name, + last_name.usd_value AS last_name, first_name.usd_value AS first_name, + birthday.bday AS birthday, birthday.bdate, + EXTRACT(DAY FROM TO_TIMESTAMP(?, \'YYYY-MM-DD\') - birthday.bdate) * (-1) AS days_to_bdate, -- DATE_NOW + EXTRACT(YEAR FROM bdate) - EXTRACT(YEAR FROM TO_TIMESTAMP(bday, \'YYYY-MM-DD\')) AS age, + email.usd_value AS email, gender.usd_value AS gender + FROM ' . TBL_USERS . ' AS users + INNER JOIN ( (SELECT usd_usr_id, usd_value AS bday, + TO_DATE(EXTRACT(YEAR FROM TO_TIMESTAMP(?, \'YYYY-MM-DD\')) || TO_CHAR(TO_TIMESTAMP(bd1.usd_value, \'YYYY-MM-DD\'), \'-MM-DD\'), \'YYYY-MM-DD\') AS bdate -- DATE_NOW + FROM ' . TBL_USER_DATA . ' AS bd1 + WHERE EXTRACT(DAY FROM TO_TIMESTAMP(?, \'YYYY-MM-DD\') - TO_TIMESTAMP(EXTRACT(YEAR FROM TO_TIMESTAMP(?, \'YYYY-MM-DD\')) || TO_CHAR(TO_TIMESTAMP(bd1.usd_value, \'YYYY-MM-DD\'), \'-MM-DD\'), \'YYYY-MM-DD\')) -- DATE_NOW,DATE_NOW + BETWEEN ? AND ? -- -$config[\'birthday_show_past\'] AND $config[\'birthday_show_future\'] + AND usd_usf_id = ?) -- $fieldBirthday + UNION + (SELECT usd_usr_id, usd_value AS bday, + TO_DATE(EXTRACT(YEAR FROM TO_TIMESTAMP(?, \'YYYY-MM-DD\'))-1 || TO_CHAR(TO_TIMESTAMP(bd2.usd_value, \'YYYY-MM-DD\'), \'-MM-DD\'), \'YYYY-MM-DD\') AS bdate -- DATE_NOW + FROM ' . TBL_USER_DATA . ' AS bd2 + WHERE EXTRACT(DAY FROM TO_TIMESTAMP(?, \'YYYY-MM-DD\') - TO_TIMESTAMP(EXTRACT(YEAR FROM TO_TIMESTAMP(?, \'YYYY-MM-DD\')- INTERVAL \'1 year\') || TO_CHAR(TO_TIMESTAMP(bd2.usd_value, \'YYYY-MM-DD\'), \'-MM-DD\'), \'YYYY-MM-DD\')) -- DATE_NOW,DATE_NOW + BETWEEN ? AND ? -- -$config[\'birthday_show_past\'] AND $config[\'birthday_show_future\'] + AND usd_usf_id = ?) -- $fieldBirthday + UNION + (SELECT usd_usr_id, usd_value AS bday, + TO_DATE(EXTRACT(YEAR FROM TO_TIMESTAMP(?, \'YYYY-MM-DD\'))+1 || TO_CHAR(TO_TIMESTAMP(bd3.usd_value, \'YYYY-MM-DD\'), \'-MM-DD\'), \'YYYY-MM-DD\') AS bdate -- DATE_NOW + FROM ' . TBL_USER_DATA . ' AS bd3 + WHERE EXTRACT(DAY FROM TO_TIMESTAMP(?, \'YYYY-MM-DD\') - TO_TIMESTAMP(EXTRACT(YEAR FROM TO_TIMESTAMP(?, \'YYYY-MM-DD\')+ INTERVAL \'1 year\') || TO_CHAR(TO_TIMESTAMP(bd3.usd_value, \'YYYY-MM-DD\'), \'-MM-DD\'), \'YYYY-MM-DD\')) -- DATE_NOW,DATE_NOW + BETWEEN ? AND ? -- -$config[\'birthday_show_past\'] AND $config[\'birthday_show_future\'] + AND usd_usf_id = ?) -- $fieldBirthday + ) AS birthday + ON birthday.usd_usr_id = usr_id + LEFT JOIN ' . TBL_USER_DATA . ' AS last_name + ON last_name.usd_usr_id = usr_id + AND last_name.usd_usf_id = ? -- $gProfileFields->getProperty(\'LAST_NAME\', \'usf_id\') + LEFT JOIN ' . TBL_USER_DATA . ' AS first_name + ON first_name.usd_usr_id = usr_id + AND first_name.usd_usf_id = ? -- $gProfileFields->getProperty(\'FIRST_NAME\', \'usf_id\') + LEFT JOIN ' . TBL_USER_DATA . ' AS email + ON email.usd_usr_id = usr_id + AND email.usd_usf_id = ? -- $gProfileFields->getProperty(\'EMAIL\', \'usf_id\') + LEFT JOIN ' . TBL_USER_DATA . ' AS gender + ON gender.usd_usr_id = usr_id + AND gender.usd_usf_id = ? -- $gProfileFields->getProperty(\'GENDER\', \'usf_id\') + LEFT JOIN ' . TBL_MEMBERS . ' + ON mem_usr_id = usr_id + AND mem_begin <= ? -- DATE_NOW + AND mem_end > ? -- DATE_NOW + INNER JOIN ' . TBL_ROLES . ' + ON mem_rol_id = rol_id + AND rol_valid = true + INNER JOIN ' . TBL_CATEGORIES . ' + ON rol_cat_id = cat_id + AND cat_org_id = ? -- $gCurrentOrgId + WHERE usr_valid = true + AND mem_rol_id ' . $sqlRol . ' + ORDER BY days_to_bdate ' . $sqlSort . ', last_name, first_name'; + } else { + $sql = 'SELECT DISTINCT usr_id, usr_uuid, usr_login_name, + last_name.usd_value AS last_name, first_name.usd_value AS first_name, + birthday.bday AS birthday, birthday.bdate, + DATEDIFF(birthday.bdate, ?) AS days_to_bdate, -- DATE_NOW + YEAR(bdate) - YEAR(bday) AS age, + email.usd_value AS email, gender.usd_value AS gender + FROM ' . TBL_USERS . ' AS users + INNER JOIN ( (SELECT usd_usr_id, usd_value AS bday, + CONCAT(YEAR(?), DATE_FORMAT(bd1.usd_value, \'-%m-%d\')) AS bdate -- DATE_NOW + FROM ' . TBL_USER_DATA . ' AS bd1 + WHERE DATEDIFF(CONCAT(YEAR(?), DATE_FORMAT(bd1.usd_value, \'-%m-%d\')), ?) -- DATE_NOW,DATE_NOW + BETWEEN ? AND ? -- -$config[\'birthday_show_past\'] AND $config[\'birthday_show_future\'] + AND usd_usf_id = ?) -- $fieldBirthday + UNION + (SELECT usd_usr_id, usd_value AS bday, + CONCAT(YEAR(?)-1, DATE_FORMAT(bd2.usd_value, \'-%m-%d\')) AS bdate -- DATE_NOW + FROM ' . TBL_USER_DATA . ' AS bd2 + WHERE DATEDIFF(CONCAT(YEAR(?)-1, DATE_FORMAT(bd2.usd_value, \'-%m-%d\')), ?) -- DATE_NOW,DATE_NOW + BETWEEN ? AND ? -- -$config[\'birthday_show_past\'] AND $config[\'birthday_show_future\'] + AND usd_usf_id = ?) -- $fieldBirthday + UNION + (SELECT usd_usr_id, usd_value AS bday, + CONCAT(YEAR(?)+1, DATE_FORMAT(bd3.usd_value, \'-%m-%d\')) AS bdate -- DATE_NOW + FROM ' . TBL_USER_DATA . ' AS bd3 + WHERE DATEDIFF(CONCAT(YEAR(?)+1, DATE_FORMAT(bd3.usd_value, \'-%m-%d\')), ?) -- DATE_NOW,DATE_NOW + BETWEEN ? AND ? -- -$config[\'birthday_show_past\'] AND $config[\'birthday_show_future\'] + AND usd_usf_id = ?) -- $fieldBirthday + ) AS birthday + ON birthday.usd_usr_id = usr_id + LEFT JOIN ' . TBL_USER_DATA . ' AS last_name + ON last_name.usd_usr_id = usr_id + AND last_name.usd_usf_id = ? -- $gProfileFields->getProperty(\'LAST_NAME\', \'usf_id\') + LEFT JOIN ' . TBL_USER_DATA . ' AS first_name + ON first_name.usd_usr_id = usr_id + AND first_name.usd_usf_id = ? -- $gProfileFields->getProperty(\'FIRST_NAME\', \'usf_id\') + LEFT JOIN ' . TBL_USER_DATA . ' AS email + ON email.usd_usr_id = usr_id + AND email.usd_usf_id = ? -- $gProfileFields->getProperty(\'EMAIL\', \'usf_id\') + LEFT JOIN ' . TBL_USER_DATA . ' AS gender + ON gender.usd_usr_id = usr_id + AND gender.usd_usf_id = ? -- $gProfileFields->getProperty(\'GENDER\', \'usf_id\') + LEFT JOIN ' . TBL_MEMBERS . ' + ON mem_usr_id = usr_id + AND mem_begin <= ? -- DATE_NOW + AND mem_end > ? -- DATE_NOW + INNER JOIN ' . TBL_ROLES . ' + ON mem_rol_id = rol_id + AND rol_valid = true + INNER JOIN ' . TBL_CATEGORIES . ' + ON rol_cat_id = cat_id + AND cat_org_id = ? -- $gCurrentOrgId + WHERE usr_valid = true + AND mem_rol_id ' . $sqlRol . ' + ORDER BY days_to_bdate ' . $sqlSort . ', last_name, first_name'; + } + + $queryParams = array( + DATE_NOW, + DATE_NOW, DATE_NOW, DATE_NOW, -$config['birthday_show_past'], $config['birthday_show_future'], $fieldBirthday, + DATE_NOW, DATE_NOW, DATE_NOW, -$config['birthday_show_past'], $config['birthday_show_future'], $fieldBirthday, + DATE_NOW, DATE_NOW, DATE_NOW, -$config['birthday_show_past'], $config['birthday_show_future'], $fieldBirthday, + $gProfileFields->getProperty('LAST_NAME', 'usf_id'), + $gProfileFields->getProperty('FIRST_NAME', 'usf_id'), + $gProfileFields->getProperty('EMAIL', 'usf_id'), + $gProfileFields->getProperty('GENDER', 'usf_id'), + DATE_NOW, + DATE_NOW, + $gCurrentOrgId + // TODO add more params + ); + $birthdayStatement = $gDb->queryPrepared($sql, $queryParams); + + $numberBirthdays = $birthdayStatement->rowCount(); + + $birthdayArray = array(); + + if ($numberBirthdays > 0) { + if (self::$birthdayShowNames) { + // how many birthdays should be displayed (as a maximum) + $birthdayCount = null; + + while (($row = $birthdayStatement->fetch()) && $birthdayCount < $config['birthday_show_display_limit']) { + // the display type of the name + switch ($config['birthday_show_names']) { + case 1: // first name, last name + $plgShowName = $row['first_name'] . ' ' . $row['last_name']; + break; + case 2: // last name, first name + $plgShowName = $row['last_name'] . ', ' . $row['first_name']; + break; + case 3: // first name + $plgShowName = $row['first_name']; + break; + case 4: // Loginname + $plgShowName = $row['usr_login_name']; + break; + default: // first name, last name + $plgShowName = $row['first_name'] . ' ' . $row['last_name']; + } + + // from a specified age, only the last name with salutation is displayed for logged out visitors + if ($config['birthday_show_age_salutation'] > -1) { + if (!$gValidLogin && $config['birthday_show_age_salutation'] <= $row['age']) { + if ($row['gender'] > 1) { + $plgShowName = $gL10n->get('PLG_BIRTHDAY_WOMAN_VAR', array($row['last_name'])); + } else { + $plgShowName = $gL10n->get('PLG_BIRTHDAY_MAN_VAR', array($row['last_name'])); + } + } + } + + // show name and e-mail link for registered users + if ($gValidLogin) { + $plgShowName = '' . $plgShowName . ''; + + // E-Mail-Adresse ist hinterlegt und soll auch bei eingeloggten Benutzern verlinkt werden + if ((string)$row['email'] !== '' && $config['birthday_show_email_extern'] < 2) { + $plgShowName .= ' + ' . + ''; + } + } elseif ($config['birthday_show_email_extern'] === 1 && strlen($row['email']) > 0) { + $plgShowName .= ' + ' . + ''; + } + + // set css class and string for birthday today, in the future or in the past + $birthdayDate = DateTime::createFromFormat('Y-m-d', $row['birthday']); + + if ($row['days_to_bdate'] < 0) { + $plgCssClass = 'plgBirthdayNameHighlightAgo'; + if ($row['days_to_bdate'] == -1) { + $birthdayText = 'PLG_BIRTHDAY_YESTERDAY'; + $plgDays = ' '; + } else { + $birthdayText = 'PLG_BIRTHDAY_PAST'; + $plgDays = -$row['days_to_bdate']; + } + } elseif ($row['days_to_bdate'] > 0) { + $plgCssClass = 'plgBirthdayNameHighlightFuture'; + if ($row['days_to_bdate'] == 1) { + $birthdayText = 'PLG_BIRTHDAY_TOMORROW'; + $plgDays = ' '; + } else { + $birthdayText = 'PLG_BIRTHDAY_FUTURE'; + $plgDays = $row['days_to_bdate']; + } + } else { + $plgCssClass = 'plgBirthdayNameHighlight'; + $birthdayText = 'PLG_BIRTHDAY_TODAY'; + $plgDays = $row['age']; + } + + // don't show age of birthday person if preference is set + if ($config['birthday_show_age'] === 0 || !$gValidLogin) { + $birthdayText .= '_NO_AGE'; + } + + $birthdayArray[] = array( + 'userText' => $gL10n->get($birthdayText, array($plgShowName, $plgDays, $row['age'], $birthdayDate->format($gSettingsManager->getString('system_date')))) + ); + + // counting displayed birthdays + $birthdayCount++; + } + } + } + + return $birthdayArray; + } + + /** + * @param array $config + * @throws InvalidArgumentException + * @throws Exception + * @return bool + */ + public static function doRender($page = null, array $config = array()) : bool + { + global $gSettingsManager, $gL10n, $gValidLogin; + + if (!is_array($config)) + { + throw new InvalidArgumentException('Config must be an "array".'); + } + + // show the announcement list + try { + $rootPath = dirname(__DIR__, 3); + $pluginFolder = basename(self::$pluginPath); + + require_once($rootPath . '/system/common.php'); + + $birthdayPlugin = new Overview($pluginFolder); + + if ($gSettingsManager->getInt('birthday_plugin_enabled') === 1 || ($gSettingsManager->getInt('birthday_plugin_enabled') === 2 && $gValidLogin)) { + $birthdaysArray = self::getBirthdaysData(); + + if (!empty($birthdaysArray)) { + if (self::$birthdayShowNames) { + $birthdayPlugin->assignTemplateVariable('birthdays', $birthdaysArray); + } else { + if (count($birthdaysArray) === 1) { + $birthdayPlugin->assignTemplateVariable('message',$gL10n->get('PLG_BIRTHDAY_ONE_MEMBER')); + } else { + $birthdayPlugin->assignTemplateVariable('message',$gL10n->get('PLG_BIRTHDAY_MORE_MEMBERS', array(count($birthdaysArray)))); + } + } + } else { + // If the configuration is set accordingly, a message is output if no member has a birthday today + if ($config['birthday_show_notice_none']) { + $birthdayPlugin->assignTemplateVariable('message',$gL10n->get('PLG_BIRTHDAY_NO_MEMBERS')); + } + } + } else { + $birthdayPlugin->assignTemplateVariable('message',$gL10n->get('PLG_BIRTHDAY_NO_ENTRIES_VISITORS')); + } + if (isset($page)) { + echo $birthdayPlugin->html('plugin.birthday.tpl'); + } else { + $birthdayPlugin->showHtmlPage('plugin.birthday.tpl'); + } + } catch (Throwable $e) { + echo $e->getMessage(); + } + + return true; + } +} \ No newline at end of file diff --git a/adm_plugins/birthday/classes/Presenter/BirthdayPreferencesPresenter.php b/adm_plugins/birthday/classes/Presenter/BirthdayPreferencesPresenter.php new file mode 100644 index 0000000000..59003bc18c --- /dev/null +++ b/adm_plugins/birthday/classes/Presenter/BirthdayPreferencesPresenter.php @@ -0,0 +1,155 @@ + 'save', 'panel' => 'birthday')), + null, + array('class' => 'form-preferences') + ); + $selectBoxEntries = array( + '0' => $gL10n->get('SYS_DISABLED'), + '1' => $gL10n->get('SYS_ENABLED'), + '2' => $gL10n->get('ORG_ONLY_FOR_REGISTERED_USER') + ); + $formBirthday->addSelectBox( + 'birthday_plugin_enabled', + Language::translateIfTranslationStrId($formValues['birthday_plugin_enabled']['name']), + $selectBoxEntries, + array('defaultValue' => $formValues['birthday_plugin_enabled']['value'], 'showContextDependentFirstEntry' => false, 'helpTextId' => $formValues['birthday_plugin_enabled']['description']) + ); + $formBirthday->addCheckbox( + 'birthday_show_names_extern', + Language::translateIfTranslationStrId($formValues['birthday_show_names_extern']['name']), + $formValues['birthday_show_names_extern']['value'], + array('helpTextId' => $formValues['birthday_show_names_extern']['description']) + ); + $selectBoxEntries = array( + '0' => $gL10n->get('SYS_FIRSTNAME') . ' ' . $gL10n->get('SYS_LASTNAME'), + '1' => $gL10n->get('SYS_LASTNAME') . ', ' . $gL10n->get('SYS_FIRSTNAME'), + '2' => $gL10n->get('SYS_FIRSTNAME'), + '3' => $gL10n->get('SYS_USERNAME') + ); + $formBirthday->addSelectBox( + 'birthday_show_names', + Language::translateIfTranslationStrId($formValues['birthday_show_names']['name']), + $selectBoxEntries, + array('defaultValue' => $formValues['birthday_show_names']['value'], 'showContextDependentFirstEntry' => false, 'helpTextId' => $formValues['birthday_show_names']['description']) + ); + $formBirthday->addCheckbox( + 'birthday_show_age', + Language::translateIfTranslationStrId($formValues['birthday_show_age']['name']), + $formValues['birthday_show_age']['value'], + array('helpTextId' => $formValues['birthday_show_age']['description']) + ); + $formBirthday->addInput( + 'birthday_show_age_salutation', + Language::translateIfTranslationStrId($formValues['birthday_show_age_salutation']['name']), + $formValues['birthday_show_age_salutation']['value'], + array('type' => 'number', 'minNumber' => -1, 'step' => 1, 'helpTextId' => $formValues['birthday_show_age_salutation']['description']) + ); + $formBirthday->addCheckbox( + 'birthday_show_notice_none', + Language::translateIfTranslationStrId($formValues['birthday_show_notice_none']['name']), + $formValues['birthday_show_notice_none']['value'], + array('helpTextId' => $formValues['birthday_show_notice_none']['description']) + ); + $formBirthday->addInput( + 'birthday_show_past', + Language::translateIfTranslationStrId($formValues['birthday_show_past']['name']), + $formValues['birthday_show_past']['value'], + array('type' => 'number', 'minNumber' => 0, 'step' => 1, 'helpTextId' => $formValues['birthday_show_past']['description']) + ); + $formBirthday->addInput( + 'birthday_show_future', + Language::translateIfTranslationStrId($formValues['birthday_show_future']['name']), + $formValues['birthday_show_future']['value'], + array('type' => 'number', 'minNumber' => 0, 'step' => 1, 'helpTextId' => $formValues['birthday_show_future']['description']) + ); + $formBirthday->addInput( + 'birthday_show_display_limit', + Language::translateIfTranslationStrId($formValues['birthday_show_display_limit']['name']), + $formValues['birthday_show_display_limit']['value'], + array('type' => 'number', 'minNumber' => 0, 'step' => 1, 'helpTextId' => $formValues['birthday_show_display_limit']['description']) + ); + $selectBoxEntries = array( + '0' => $gL10n->get('SYS_NAME') . ' (' . $gL10n->get('SYS_VISITORS') . ')', + '1' => $gL10n->get('SYS_NAME') . ' + ' . $gL10n->get('SYS_EMAIL'), + '2' => $gL10n->get('SYS_NAME') . ' (' . $gL10n->get('SYS_VISITORS') . ' + ' . $gL10n->get('SYS_USERS') . ')' + ); + $formBirthday->addSelectBox( + 'birthday_show_email_extern', + Language::translateIfTranslationStrId($formValues['birthday_show_email_extern']['name']), + $selectBoxEntries, + array('defaultValue' => $formValues['birthday_show_email_extern']['value'], 'showContextDependentFirstEntry' => false, 'helpTextId' => $formValues['birthday_show_email_extern']['description']) + ); + + $selectBoxEntries = $pluginBirthday instanceof Birthday ? $pluginBirthday::getAvailableRoles() : array(); + + $formBirthday->addSelectBox( + 'birthday_roles_view_plugin', + Language::translateIfTranslationStrId($formValues['birthday_roles_view_plugin']['name']), + $selectBoxEntries, + array('defaultValue' => $formValues['birthday_roles_view_plugin']['value'], 'showContextDependentFirstEntry' => false, 'helpTextId' => $formValues['birthday_roles_view_plugin']['description'], 'multiselect' => true, 'maximumSelectionNumber' => count($selectBoxEntries)) + ); + $formBirthday->addSelectBox( + 'birthday_roles_sql', + Language::translateIfTranslationStrId($formValues['birthday_roles_sql']['name']), + $selectBoxEntries, + array('defaultValue' => $formValues['birthday_roles_sql']['value'], 'showContextDependentFirstEntry' => false, 'helpTextId' => $formValues['birthday_roles_sql']['description'], 'multiselect' => true, 'maximumSelectionNumber' => count($selectBoxEntries)) + ); + + $selectBoxEntries = array( + 'ASC' => 'ASC', + 'DESC' => 'DESC' + ); + $formBirthday->addSelectBox( + 'birthday_sort_sql', + Language::translateIfTranslationStrId($formValues['birthday_sort_sql']['name']), + $selectBoxEntries, + array('defaultValue' => $formValues['birthday_sort_sql']['value'], 'showContextDependentFirstEntry' => false, 'helpTextId' => $formValues['birthday_sort_sql']['description']) + ); + $formBirthday->addSubmitButton( + 'adm_button_save_birthday', + $gL10n->get('SYS_SAVE'), + array('icon' => 'bi-check-lg', 'class' => 'offset-sm-3') + ); + + $formBirthday->addToSmarty($smarty); + $gCurrentSession->addFormObject($formBirthday); + return $smarty->fetch($pluginBirthday::getPluginPath() . '/templates/preferences.plugin.birthday.tpl'); + } +} \ No newline at end of file diff --git a/adm_plugins/birthday/config_sample.php b/adm_plugins/birthday/config_sample.php deleted file mode 100644 index c13e4d9e2f..0000000000 --- a/adm_plugins/birthday/config_sample.php +++ /dev/null @@ -1,72 +0,0 @@ - + + UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'Birthday' + stop + diff --git a/adm_plugins/birthday/index.php b/adm_plugins/birthday/index.php index 30cdd1fcb7..d56ce2e5a0 100644 --- a/adm_plugins/birthday/index.php +++ b/adm_plugins/birthday/index.php @@ -1,13 +1,11 @@ doRender(isset($page) ? $page : null); - // only include config file if it exists - if (is_file(__DIR__ . '/config.php')) { - require_once(__DIR__ . '/config.php'); - } - - $birthdayPlugin = new Overview($pluginFolder); - - // global variable to show names of the members who have birthday - $plgBirthdayShowNames = false; - - // set default values if there is no value has been stored in the config.php - if (!isset($plg_show_names_extern) || !is_numeric($plg_show_names_extern) || $plg_show_names_extern !== 1) { - $plg_show_names_extern = 0; - } - - if (!isset($plg_show_email_extern) || !is_numeric($plg_show_email_extern)) { - $plg_show_email_extern = 0; - } - - if (!isset($plg_show_names) || !is_numeric($plg_show_names)) { - $plg_show_names = 1; - } - - if (!isset($plg_show_age) || !is_numeric($plg_show_age)) { - $plg_show_age = 0; - } - - if (!isset($plg_show_hinweis_keiner) || !is_numeric($plg_show_hinweis_keiner)) { - $plg_show_hinweis_keiner = 0; - } - - if (!isset($plg_show_alter_anrede) || !is_numeric($plg_show_alter_anrede)) { - $plg_show_alter_anrede = 18; - } - - if (!isset($plg_show_zeitraum) || !is_numeric($plg_show_zeitraum)) { - $plg_show_zeitraum = 1; - } - - if (!isset($plg_show_future) || !is_numeric($plg_show_future)) { - $plg_show_future = 2; - } - if (!isset($plg_show_display_limit) || !is_numeric($plg_show_display_limit)) { - $plg_show_display_limit = 200; - } - - // check if only members of configured roles could view birthday - if ($gValidLogin) { - if (isset($plg_birthday_roles_view_plugin) && count($plg_birthday_roles_view_plugin) > 0) { - // current user must be member of at least one listed role - if (count(array_intersect($plg_birthday_roles_view_plugin, $gCurrentUser->getRoleMemberships())) > 0) { - $plgBirthdayShowNames = true; - } - } else { - // every member could view birthdays - $plgBirthdayShowNames = true; - } - } else { - if ($plg_show_names_extern === 1) { - // every visitor is allowed to view birthdays - $plgBirthdayShowNames = true; - } - } - - // Check if the role condition has been set - if (isset($plg_rolle_sql) && is_array($plg_rolle_sql) && count($plg_rolle_sql) > 0) { - $sqlRol = 'IN (' . implode(',', $plg_rolle_sql) . ')'; - } else { - $sqlRol = 'IS NOT NULL'; - } - - // Check if the sort condition has been set - if (!isset($plg_sort_sql) || $plg_sort_sql === '') { - $sqlSort = 'DESC'; - } else { - $sqlSort = $plg_sort_sql; - } - - // if no birthdays should be shown than disable future and former birthday periods - if (!$plgBirthdayShowNames) { - $plg_show_zeitraum = 0; - $plg_show_future = 0; - } - - $fieldBirthday = $gProfileFields->getProperty('BIRTHDAY', 'usf_id'); - - if ($gDbType === 'pgsql') { - $sql = 'SELECT DISTINCT usr_id, usr_uuid, usr_login_name, - last_name.usd_value AS last_name, first_name.usd_value AS first_name, - birthday.bday AS birthday, birthday.bdate, - EXTRACT(DAY FROM TO_TIMESTAMP(?, \'YYYY-MM-DD\') - birthday.bdate) * (-1) AS days_to_bdate, -- DATE_NOW - EXTRACT(YEAR FROM bdate) - EXTRACT(YEAR FROM TO_TIMESTAMP(bday, \'YYYY-MM-DD\')) AS age, - email.usd_value AS email, gender.usd_value AS gender - FROM ' . TBL_USERS . ' AS users - INNER JOIN ( (SELECT usd_usr_id, usd_value AS bday, - TO_DATE(EXTRACT(YEAR FROM TO_TIMESTAMP(?, \'YYYY-MM-DD\')) || TO_CHAR(TO_TIMESTAMP(bd1.usd_value, \'YYYY-MM-DD\'), \'-MM-DD\'), \'YYYY-MM-DD\') AS bdate -- DATE_NOW - FROM ' . TBL_USER_DATA . ' AS bd1 - WHERE EXTRACT(DAY FROM TO_TIMESTAMP(?, \'YYYY-MM-DD\') - TO_TIMESTAMP(EXTRACT(YEAR FROM TO_TIMESTAMP(?, \'YYYY-MM-DD\')) || TO_CHAR(TO_TIMESTAMP(bd1.usd_value, \'YYYY-MM-DD\'), \'-MM-DD\'), \'YYYY-MM-DD\')) -- DATE_NOW,DATE_NOW - BETWEEN ? AND ? -- -$plg_show_zeitraum AND $plg_show_future - AND usd_usf_id = ?) -- $fieldBirthday - UNION - (SELECT usd_usr_id, usd_value AS bday, - TO_DATE(EXTRACT(YEAR FROM TO_TIMESTAMP(?, \'YYYY-MM-DD\'))-1 || TO_CHAR(TO_TIMESTAMP(bd2.usd_value, \'YYYY-MM-DD\'), \'-MM-DD\'), \'YYYY-MM-DD\') AS bdate -- DATE_NOW - FROM ' . TBL_USER_DATA . ' AS bd2 - WHERE EXTRACT(DAY FROM TO_TIMESTAMP(?, \'YYYY-MM-DD\') - TO_TIMESTAMP(EXTRACT(YEAR FROM TO_TIMESTAMP(?, \'YYYY-MM-DD\')- INTERVAL \'1 year\') || TO_CHAR(TO_TIMESTAMP(bd2.usd_value, \'YYYY-MM-DD\'), \'-MM-DD\'), \'YYYY-MM-DD\')) -- DATE_NOW,DATE_NOW - BETWEEN ? AND ? -- -$plg_show_zeitraum AND $plg_show_future - AND usd_usf_id = ?) -- $fieldBirthday - UNION - (SELECT usd_usr_id, usd_value AS bday, - TO_DATE(EXTRACT(YEAR FROM TO_TIMESTAMP(?, \'YYYY-MM-DD\'))+1 || TO_CHAR(TO_TIMESTAMP(bd3.usd_value, \'YYYY-MM-DD\'), \'-MM-DD\'), \'YYYY-MM-DD\') AS bdate -- DATE_NOW - FROM ' . TBL_USER_DATA . ' AS bd3 - WHERE EXTRACT(DAY FROM TO_TIMESTAMP(?, \'YYYY-MM-DD\') - TO_TIMESTAMP(EXTRACT(YEAR FROM TO_TIMESTAMP(?, \'YYYY-MM-DD\')+ INTERVAL \'1 year\') || TO_CHAR(TO_TIMESTAMP(bd3.usd_value, \'YYYY-MM-DD\'), \'-MM-DD\'), \'YYYY-MM-DD\')) -- DATE_NOW,DATE_NOW - BETWEEN ? AND ? -- -$plg_show_zeitraum AND $plg_show_future - AND usd_usf_id = ?) -- $fieldBirthday - ) AS birthday - ON birthday.usd_usr_id = usr_id - LEFT JOIN ' . TBL_USER_DATA . ' AS last_name - ON last_name.usd_usr_id = usr_id - AND last_name.usd_usf_id = ? -- $gProfileFields->getProperty(\'LAST_NAME\', \'usf_id\') - LEFT JOIN ' . TBL_USER_DATA . ' AS first_name - ON first_name.usd_usr_id = usr_id - AND first_name.usd_usf_id = ? -- $gProfileFields->getProperty(\'FIRST_NAME\', \'usf_id\') - LEFT JOIN ' . TBL_USER_DATA . ' AS email - ON email.usd_usr_id = usr_id - AND email.usd_usf_id = ? -- $gProfileFields->getProperty(\'EMAIL\', \'usf_id\') - LEFT JOIN ' . TBL_USER_DATA . ' AS gender - ON gender.usd_usr_id = usr_id - AND gender.usd_usf_id = ? -- $gProfileFields->getProperty(\'GENDER\', \'usf_id\') - LEFT JOIN ' . TBL_MEMBERS . ' - ON mem_usr_id = usr_id - AND mem_begin <= ? -- DATE_NOW - AND mem_end > ? -- DATE_NOW - INNER JOIN ' . TBL_ROLES . ' - ON mem_rol_id = rol_id - AND rol_valid = true - INNER JOIN ' . TBL_CATEGORIES . ' - ON rol_cat_id = cat_id - AND cat_org_id = ? -- $gCurrentOrgId - WHERE usr_valid = true - AND mem_rol_id ' . $sqlRol . ' - ORDER BY days_to_bdate ' . $sqlSort . ', last_name, first_name'; - } else { - $sql = 'SELECT DISTINCT usr_id, usr_uuid, usr_login_name, - last_name.usd_value AS last_name, first_name.usd_value AS first_name, - birthday.bday AS birthday, birthday.bdate, - DATEDIFF(birthday.bdate, ?) AS days_to_bdate, -- DATE_NOW - YEAR(bdate) - YEAR(bday) AS age, - email.usd_value AS email, gender.usd_value AS gender - FROM ' . TBL_USERS . ' AS users - INNER JOIN ( (SELECT usd_usr_id, usd_value AS bday, - CONCAT(YEAR(?), DATE_FORMAT(bd1.usd_value, \'-%m-%d\')) AS bdate -- DATE_NOW - FROM ' . TBL_USER_DATA . ' AS bd1 - WHERE DATEDIFF(CONCAT(YEAR(?), DATE_FORMAT(bd1.usd_value, \'-%m-%d\')), ?) -- DATE_NOW,DATE_NOW - BETWEEN ? AND ? -- -$plg_show_zeitraum AND $plg_show_future - AND usd_usf_id = ?) -- $fieldBirthday - UNION - (SELECT usd_usr_id, usd_value AS bday, - CONCAT(YEAR(?)-1, DATE_FORMAT(bd2.usd_value, \'-%m-%d\')) AS bdate -- DATE_NOW - FROM ' . TBL_USER_DATA . ' AS bd2 - WHERE DATEDIFF(CONCAT(YEAR(?)-1, DATE_FORMAT(bd2.usd_value, \'-%m-%d\')), ?) -- DATE_NOW,DATE_NOW - BETWEEN ? AND ? -- -$plg_show_zeitraum AND $plg_show_future - AND usd_usf_id = ?) -- $fieldBirthday - UNION - (SELECT usd_usr_id, usd_value AS bday, - CONCAT(YEAR(?)+1, DATE_FORMAT(bd3.usd_value, \'-%m-%d\')) AS bdate -- DATE_NOW - FROM ' . TBL_USER_DATA . ' AS bd3 - WHERE DATEDIFF(CONCAT(YEAR(?)+1, DATE_FORMAT(bd3.usd_value, \'-%m-%d\')), ?) -- DATE_NOW,DATE_NOW - BETWEEN ? AND ? -- -$plg_show_zeitraum AND $plg_show_future - AND usd_usf_id = ?) -- $fieldBirthday - ) AS birthday - ON birthday.usd_usr_id = usr_id - LEFT JOIN ' . TBL_USER_DATA . ' AS last_name - ON last_name.usd_usr_id = usr_id - AND last_name.usd_usf_id = ? -- $gProfileFields->getProperty(\'LAST_NAME\', \'usf_id\') - LEFT JOIN ' . TBL_USER_DATA . ' AS first_name - ON first_name.usd_usr_id = usr_id - AND first_name.usd_usf_id = ? -- $gProfileFields->getProperty(\'FIRST_NAME\', \'usf_id\') - LEFT JOIN ' . TBL_USER_DATA . ' AS email - ON email.usd_usr_id = usr_id - AND email.usd_usf_id = ? -- $gProfileFields->getProperty(\'EMAIL\', \'usf_id\') - LEFT JOIN ' . TBL_USER_DATA . ' AS gender - ON gender.usd_usr_id = usr_id - AND gender.usd_usf_id = ? -- $gProfileFields->getProperty(\'GENDER\', \'usf_id\') - LEFT JOIN ' . TBL_MEMBERS . ' - ON mem_usr_id = usr_id - AND mem_begin <= ? -- DATE_NOW - AND mem_end > ? -- DATE_NOW - INNER JOIN ' . TBL_ROLES . ' - ON mem_rol_id = rol_id - AND rol_valid = true - INNER JOIN ' . TBL_CATEGORIES . ' - ON rol_cat_id = cat_id - AND cat_org_id = ? -- $gCurrentOrgId - WHERE usr_valid = true - AND mem_rol_id ' . $sqlRol . ' - ORDER BY days_to_bdate ' . $sqlSort . ', last_name, first_name'; - } - - $queryParams = array( - DATE_NOW, - DATE_NOW, DATE_NOW, DATE_NOW, -$plg_show_zeitraum, $plg_show_future, $fieldBirthday, - DATE_NOW, DATE_NOW, DATE_NOW, -$plg_show_zeitraum, $plg_show_future, $fieldBirthday, - DATE_NOW, DATE_NOW, DATE_NOW, -$plg_show_zeitraum, $plg_show_future, $fieldBirthday, - $gProfileFields->getProperty('LAST_NAME', 'usf_id'), - $gProfileFields->getProperty('FIRST_NAME', 'usf_id'), - $gProfileFields->getProperty('EMAIL', 'usf_id'), - $gProfileFields->getProperty('GENDER', 'usf_id'), - DATE_NOW, - DATE_NOW, - $gCurrentOrgId - // TODO add more params - ); - $birthdayStatement = $gDb->queryPrepared($sql, $queryParams); - - $numberBirthdays = $birthdayStatement->rowCount(); - - if ($numberBirthdays > 0) { - if ($plgBirthdayShowNames) { - // how many birthdays should be displayed (as a maximum) - $birthdayCount = null; - $birthdayArray = array(); - - while (($row = $birthdayStatement->fetch()) && $birthdayCount < $plg_show_display_limit) { - // the display type of the name - switch ($plg_show_names) { - case 1: // first name, last name - $plgShowName = $row['first_name'] . ' ' . $row['last_name']; - break; - case 2: // last name, first name - $plgShowName = $row['last_name'] . ', ' . $row['first_name']; - break; - case 3: // first name - $plgShowName = $row['first_name']; - break; - case 4: // Loginname - $plgShowName = $row['usr_login_name']; - break; - default: // first name, last name - $plgShowName = $row['first_name'] . ' ' . $row['last_name']; - } - - // from a specified age, only the last name with salutation is displayed for logged out visitors - if (!$gValidLogin && $plg_show_alter_anrede <= $row['age']) { - if ($row['gender'] > 1) { - $plgShowName = $gL10n->get('PLG_BIRTHDAY_WOMAN_VAR', array($row['last_name'])); - } else { - $plgShowName = $gL10n->get('PLG_BIRTHDAY_MAN_VAR', array($row['last_name'])); - } - } - - // show name and e-mail link for registered users - if ($gValidLogin) { - $plgShowName = '' . $plgShowName . ''; - - // E-Mail-Adresse ist hinterlegt und soll auch bei eingeloggten Benutzern verlinkt werden - if ((string)$row['email'] !== '' && $plg_show_email_extern < 2) { - $plgShowName .= ' - ' . - ''; - } - } elseif ($plg_show_email_extern === 1 && strlen($row['email']) > 0) { - $plgShowName .= ' - ' . - ''; - } - - // set css class and string for birthday today, in the future or in the past - $birthdayDate = DateTime::createFromFormat('Y-m-d', $row['birthday']); - - if ($row['days_to_bdate'] < 0) { - $plgCssClass = 'plgBirthdayNameHighlightAgo'; - if ($row['days_to_bdate'] == -1) { - $birthdayText = 'PLG_BIRTHDAY_YESTERDAY'; - $plgDays = ' '; - } else { - $birthdayText = 'PLG_BIRTHDAY_PAST'; - $plgDays = -$row['days_to_bdate']; - } - } elseif ($row['days_to_bdate'] > 0) { - $plgCssClass = 'plgBirthdayNameHighlightFuture'; - if ($row['days_to_bdate'] == 1) { - $birthdayText = 'PLG_BIRTHDAY_TOMORROW'; - $plgDays = ' '; - } else { - $birthdayText = 'PLG_BIRTHDAY_FUTURE'; - $plgDays = $row['days_to_bdate']; - } - } else { - $plgCssClass = 'plgBirthdayNameHighlight'; - $birthdayText = 'PLG_BIRTHDAY_TODAY'; - $plgDays = $row['age']; - } - - // don't show age of birthday person if preference is set - if ($plg_show_age === 0 || !$gValidLogin) { - $birthdayText .= '_NO_AGE'; - } - - $birthdayArray[] = array( - 'userText' => $gL10n->get($birthdayText, array($plgShowName, $plgDays, $row['age'], $birthdayDate->format($gSettingsManager->getString('system_date')))) - ); - - // counting displayed birthdays - $birthdayCount++; - } - - $birthdayPlugin->assignTemplateVariable('birthdays', $birthdayArray); - } else { - if ($numberBirthdays === 1) { - $birthdayPlugin->assignTemplateVariable('message',$gL10n->get('PLG_BIRTHDAY_ONE_MEMBER')); - } else { - $birthdayPlugin->assignTemplateVariable('message',$gL10n->get('PLG_BIRTHDAY_MORE_MEMBERS', array($numberBirthdays))); - } - } - } else { - // If the configuration is set accordingly, a message is output if no member has a birthday today - if (!$plg_show_hinweis_keiner) { - $birthdayPlugin->assignTemplateVariable('message',$gL10n->get('PLG_BIRTHDAY_NO_MEMBERS')); - } - } - - if (isset($page)) { - echo $birthdayPlugin->html('plugin.birthday.tpl'); - } else { - $birthdayPlugin->showHtmlPage('plugin.birthday.tpl'); - } } catch (Throwable $e) { echo $e->getMessage(); } diff --git a/adm_plugins/birthday/languages/en.xml b/adm_plugins/birthday/languages/en.xml index ee2ee0db0a..3770558be8 100644 --- a/adm_plugins/birthday/languages/en.xml +++ b/adm_plugins/birthday/languages/en.xml @@ -5,10 +5,13 @@ Birthdays Mr. #VAR1# Today #VAR1# members have birthday. + There are no member's birthdays available for visitors. Log in to see the member's birthdays. Today is not a member's birthday. Today is a member's birthday. #VAR1# became #VAR3# years old #VAR2# days before, on the #VAR4# #VAR1# had their birthday #VAR2# days ago + This plugin displays a preview of the latest birthdays on the Overview page. + Birthday #VAR1# will be today #VAR2# #VAR1# has their birthday today #VAR1# will be tomorrow #VAR3# years old, on the #VAR4# @@ -16,4 +19,29 @@ Mrs. #VAR1# #VAR1# became #VAR3# years old yesterday on the #VAR4# #VAR1# had their birthday yesterday + + Show names for visitors + If this setting is enabled visitors will see all names (not the age) of birthday persons today, in the future and in the past. Otherwise visitors will only see the number of persons who have birthday today, nothing more. (default: false) + Display style for birthday person name + This setting allows you to choose how the names of birthday persons are displayed. (default: First name Last name) + Show age + If this setting is enabled logged in users will see the ages of birthday persons. (default: false) + Show name with salutation + Defines the age from which the first name of a birthday person will be replaced by the salutation for visitors. (disable: -1, default: 18) + Show no birthday persons notice + If this setting is enabled a notice will be shown if no member has birthday in the selected time span. (default: true) + Show past birthday days + With this setting you can define how many days in the past birthdays should be shown. (default: 1) + Show future birthday days + With this setting you can define how many days in the future birthdays should be shown. (default: 2) + Limit the number of birthday persons + With this setting you can define the maximum number of birthday persons to be displayed. (default: 200) + Show email address for visitors + This setting allows you to choose if the email address of birthday persons should be displayed. (default: only name (visitors)) + Allowed roles for content + Here you can select the roles that are allowed to see the content of this plugin. If a user is not part of any selected role only the number of birthdays are shown. (default: all roles) + Allowed roles for birthdays + Here you can select the roles which users must have whose birthdays should be shown. (default: all roles) + Sort order of birthday persons + This setting allows you to choose the sort order of birthday persons. (default: DESC) diff --git a/adm_plugins/birthday/templates/preferences.plugin.birthday.tpl b/adm_plugins/birthday/templates/preferences.plugin.birthday.tpl new file mode 100644 index 0000000000..74aec2db77 --- /dev/null +++ b/adm_plugins/birthday/templates/preferences.plugin.birthday.tpl @@ -0,0 +1,23 @@ +
+ + {include 'sys-template-parts/form.input.tpl' data=$elements['adm_csrf_token']} + {include 'sys-template-parts/form.select.tpl' data=$elements['birthday_plugin_enabled']} + {include 'sys-template-parts/form.checkbox.tpl' data=$elements['birthday_show_names_extern']} + {include 'sys-template-parts/form.select.tpl' data=$elements['birthday_show_names']} + {include 'sys-template-parts/form.checkbox.tpl' data=$elements['birthday_show_age']} + {include 'sys-template-parts/form.input.tpl' data=$elements['birthday_show_age_salutation']} + {include 'sys-template-parts/form.checkbox.tpl' data=$elements['birthday_show_notice_none']} + {include 'sys-template-parts/form.input.tpl' data=$elements['birthday_show_past']} + {include 'sys-template-parts/form.input.tpl' data=$elements['birthday_show_future']} + {include 'sys-template-parts/form.input.tpl' data=$elements['birthday_show_display_limit']} + {include 'sys-template-parts/form.select.tpl' data=$elements['birthday_show_email_extern']} + {include 'sys-template-parts/form.select.tpl' data=$elements['birthday_roles_view_plugin']} + {include 'sys-template-parts/form.select.tpl' data=$elements['birthday_roles_sql']} + {include 'sys-template-parts/form.select.tpl' data=$elements['birthday_sort_sql']} + {include 'sys-template-parts/form.button.tpl' data=$elements['adm_button_save_birthday']} + + +
+{$javascript} \ No newline at end of file From 84a98e131725de1de96b957eb2a4896eeb4fa25d Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 23 Jul 2025 10:08:45 +0200 Subject: [PATCH 013/109] refactor: simplify doRender method by removing config parameter --- .../AnnouncementList/classes/AnnouncementList.php | 7 +------ adm_plugins/birthday/classes/Birthday.php | 12 ++++-------- src/Infrastructure/Plugins/PluginInterface.php | 4 ++-- 3 files changed, 7 insertions(+), 16 deletions(-) diff --git a/adm_plugins/AnnouncementList/classes/AnnouncementList.php b/adm_plugins/AnnouncementList/classes/AnnouncementList.php index f307816daf..e2f5e1cc35 100644 --- a/adm_plugins/AnnouncementList/classes/AnnouncementList.php +++ b/adm_plugins/AnnouncementList/classes/AnnouncementList.php @@ -152,15 +152,10 @@ private static function getAnnouncementsData() : array * @throws Exception * @return bool */ - public static function doRender($page = null, array $config = array()) : bool + public static function doRender($page = null) : bool { global $gSettingsManager, $gL10n, $gValidLogin; - if (!is_array($config)) - { - throw new InvalidArgumentException('Config must be an "array".'); - } - // show the announcement list try { $rootPath = dirname(__DIR__, 3); diff --git a/adm_plugins/birthday/classes/Birthday.php b/adm_plugins/birthday/classes/Birthday.php index da8d3cd0ce..403000cfe3 100644 --- a/adm_plugins/birthday/classes/Birthday.php +++ b/adm_plugins/birthday/classes/Birthday.php @@ -74,6 +74,7 @@ public static function getPluginConfigValues() : array public static function getAvailableRoles($roleType = 1, bool $onlyIds = false): array { global $gDb; + $allRolesSet = array(); $rolesService = new RolesService($gDb); $data = $rolesService->findAll($roleType); @@ -370,15 +371,10 @@ private static function getBirthdaysData() : array * @throws Exception * @return bool */ - public static function doRender($page = null, array $config = array()) : bool + public static function doRender($page = null) : bool { global $gSettingsManager, $gL10n, $gValidLogin; - if (!is_array($config)) - { - throw new InvalidArgumentException('Config must be an "array".'); - } - // show the announcement list try { $rootPath = dirname(__DIR__, 3); @@ -401,9 +397,9 @@ public static function doRender($page = null, array $config = array()) : bool $birthdayPlugin->assignTemplateVariable('message',$gL10n->get('PLG_BIRTHDAY_MORE_MEMBERS', array(count($birthdaysArray)))); } } - } else { + } else { // If the configuration is set accordingly, a message is output if no member has a birthday today - if ($config['birthday_show_notice_none']) { + if ($gSettingsManager->getBool('birthday_show_notice_none')) { $birthdayPlugin->assignTemplateVariable('message',$gL10n->get('PLG_BIRTHDAY_NO_MEMBERS')); } } diff --git a/src/Infrastructure/Plugins/PluginInterface.php b/src/Infrastructure/Plugins/PluginInterface.php index 10477e6cb8..171a9d68ee 100644 --- a/src/Infrastructure/Plugins/PluginInterface.php +++ b/src/Infrastructure/Plugins/PluginInterface.php @@ -117,10 +117,10 @@ public static function doUninstall(array $options = array()) : bool; public static function doUpdate() : bool; /** - * @param array $config + * @param PagePresenter $page * @throws InvalidArgumentException * @throws Exception * @return bool */ - public static function doRender(?PagePresenter $page = null, array $config = array()) : bool; + public static function doRender(?PagePresenter $page = null) : bool; } \ No newline at end of file From 3fe94a8bf86b4f5ef4d098d8d06c00e26fe5df18 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 23 Jul 2025 11:33:51 +0200 Subject: [PATCH 014/109] implement plugin sequence management and sorting in the plugin manager --- .../db_scripts/update_1_0.xml | 1 + .../birthday/db_scripts/update_1_0.xml | 1 + install/db_scripts/update_5_0.xml | 5 +- modules/plugins.php | 25 ++++- src/Components/Service/ComponentService.php | 106 ++++++++++++++++++ src/Infrastructure/Plugins/PluginAbstract.php | 14 +++ .../Plugins/PluginInterface.php | 7 ++ src/Infrastructure/Plugins/PluginManager.php | 15 ++- src/UI/Presenter/PluginsPresenter.php | 68 +++++++++-- .../simple/templates/modules/plugins.list.tpl | 17 ++- 10 files changed, 245 insertions(+), 14 deletions(-) create mode 100644 src/Components/Service/ComponentService.php diff --git a/adm_plugins/AnnouncementList/db_scripts/update_1_0.xml b/adm_plugins/AnnouncementList/db_scripts/update_1_0.xml index 1439532f43..16f71024b3 100644 --- a/adm_plugins/AnnouncementList/db_scripts/update_1_0.xml +++ b/adm_plugins/AnnouncementList/db_scripts/update_1_0.xml @@ -1,5 +1,6 @@ UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'AnnouncementList' + UPDATE %PREFIX%_components SET com_plg_sequence = 6 WHERE com_type = 'ADM_PLUGIN' AND com_name_intern = 'AnnouncementList' stop diff --git a/adm_plugins/birthday/db_scripts/update_1_0.xml b/adm_plugins/birthday/db_scripts/update_1_0.xml index 4d88d6c9e7..2cb5a06df2 100644 --- a/adm_plugins/birthday/db_scripts/update_1_0.xml +++ b/adm_plugins/birthday/db_scripts/update_1_0.xml @@ -1,5 +1,6 @@ UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'Birthday' + UPDATE %PREFIX%_components SET com_plg_sequence = 2 WHERE com_type = 'ADM_PLUGIN' AND com_name_intern = 'Birthday' stop diff --git a/install/db_scripts/update_5_0.xml b/install/db_scripts/update_5_0.xml index 7327a7f20f..ae5d8c748a 100644 --- a/install/db_scripts/update_5_0.xml +++ b/install/db_scripts/update_5_0.xml @@ -501,11 +501,10 @@ WHERE usf_fn.usf_name_intern = 'FIRST_NAME' AND usf_ln.usf_name_intern = 'LAST_N DEFAULT character SET = utf8 COLLATE = utf8_unicode_ci; ALTER TABLE %PREFIX%_inventory_field_select_options - ADD CONSTRAINT %PREFIX%_fk_ifo_inf FOREIGN KEY (ifo_inf_id) REFERENCES %PREFIX%_inventory_fields (inf_id) ON DELETE CASCADE ON UPDATE RESTRICT; + ADD CONSTRAINT %PREFIX%_fk_ifo_inf FOREIGN KEY (ifo_inf_id) REFERENCES %PREFIX%_inventory_fields (inf_id) ON DELETE CASCADE ON UPDATE RESTRICT; INSERT INTO %PREFIX%_components (com_type, com_name, com_name_intern, com_version, com_beta) VALUES ('MODULE', 'SYS_PLUGIN_MANAGER', 'PLUGINS', '5.0.0', 0) - ALTER TABLE %PREFIX%_components - ADD com_status VARCHAR(36) NOT NULL AFTER com_update_completed; + ALTER TABLE %PREFIX%_components ADD COLUMN com_plg_sequence smallint NOT NULL DEFAULT 0 AFTER com_update_completed; INSERT INTO %PREFIX%_menu (men_com_id, men_men_id_parent, men_uuid, men_node, men_order, men_standard, men_name_intern, men_url, men_icon, men_name, men_description) VALUES ((SELECT com_id FROM %PREFIX%_components WHERE com_name_intern = 'PLUGINS'), 2, %UUID%, false, 5, true, 'plugins', '/modules/plugins.php', 'puzzle', 'SYS_PLUGIN_MANAGER', 'SYS_PLUGIN_MANAGER_DESC') stop diff --git a/modules/plugins.php b/modules/plugins.php index 4b79125a7f..50981b917f 100644 --- a/modules/plugins.php +++ b/modules/plugins.php @@ -18,7 +18,10 @@ * direction : Direction to change the sequence of the menu entry *********************************************************************************************** */ + +use Admidio\Components\Service\ComponentService; use Admidio\Infrastructure\Exception; +use Admidio\Menu\Entity\MenuEntry; use Admidio\Infrastructure\Utils\SecurityUtils; use Admidio\Infrastructure\Plugins\PluginAbstract; use Admidio\Infrastructure\Plugins\PluginManager; @@ -28,8 +31,9 @@ require_once(__DIR__ . '/../system/common.php'); // Initialize and check the parameters - $getMode = admFuncVariableIsValid($_GET, 'mode', 'string', array('defaultValue' => 'list', 'validValues' => array('list', 'install', 'uninstall', 'update'))); + $getMode = admFuncVariableIsValid($_GET, 'mode', 'string', array('defaultValue' => 'list', 'validValues' => array('list', 'install', 'uninstall', 'update', 'sequence'))); $getPluginName = admFuncVariableIsValid($_GET, 'name', 'string', array('defaultValue' => '')); + $getPluginId = admFuncVariableIsValid($_GET, 'uuid', 'int'); // check rights to use this module if (!$gCurrentUser->isAdministrator()) { @@ -101,6 +105,25 @@ throw new Exception('SYS_PLUGIN_NAME_MISSING'); } break; + case 'sequence': + // Update menu entry sequence + $postDirection = admFuncVariableIsValid($_POST, 'direction', 'string', array('validValues' => array(MenuEntry::MOVE_UP, MenuEntry::MOVE_DOWN))); + $getOrder = admFuncVariableIsValid($_GET, 'order', 'array'); + + // check the CSRF token of the form against the session token + SecurityUtils::validateCsrfToken($_POST['adm_csrf_token']); + + $componentService = new ComponentService($gDb, $getPluginId); + + if (!empty($getOrder)) { + // set new order (drag and drop) + $ret = $componentService->setSequence(explode(',', $getOrder)); + } else { + $ret = $componentService->moveSequence($postDirection); + } + + echo json_encode(array('status' => ($ret ? 'success' : 'error'))); + break; default: throw new Exception('SYS_UNKNOWN_MODE'); diff --git a/src/Components/Service/ComponentService.php b/src/Components/Service/ComponentService.php new file mode 100644 index 0000000000..ddbd2ba476 --- /dev/null +++ b/src/Components/Service/ComponentService.php @@ -0,0 +1,106 @@ +db = $database; + $this->comId = $comId; + $this->componentRessource = new Component($database); + $this->componentRessource->readDataById($comId); + } + + /** + * Profile field will change the sequence one step up or one step down. + * @param string $mode mode if the item field move up or down, values are ProfileField::MOVE_UP, ProfileField::MOVE_DOWN + * @return bool Return true if the sequence of the category could be changed, otherwise false. + * @throws Exception + */ + public function moveSequence(string $mode): bool + { + global $gCurrentOrgId; + + $plgSequence = (int)$this->componentRessource->getValue('com_plg_sequence'); + $sql = 'UPDATE ' . TBL_COMPONENTS . ' + SET com_plg_sequence = ? -- $usfSequence + WHERE com_type = \'ADM_PLUGIN\' + AND com_plg_sequence = ? -- $usfSequence -/+ 1'; + + // item field will get one number lower and therefore move a position up in the list + if ($mode === self::MOVE_UP) { + $newSequence = $plgSequence - 1; + } // item field will get one number higher and therefore move a position down in the list + elseif ($mode === self::MOVE_DOWN) { + $newSequence = $plgSequence + 1; + } + + // update the existing entry with the sequence of the field that should get the new sequence + $this->db->queryPrepared($sql, array($plgSequence, $newSequence)); + + $this->componentRessource->setValue('com_plg_sequence', $newSequence); + return $this->componentRessource->save(); + } + + /** + * Iem field will change the complete sequence. + * @param array $sequence the new sequence of item fields (field IDs) + * @return bool Return true if the sequence of the category could be changed, otherwise false. + * @throws Exception + */ + public function setSequence(array $sequence): bool + { + global $gCurrentOrgId; + $comId = $this->componentRessource->getValue('com_id'); + + $sql = 'UPDATE ' . TBL_COMPONENTS . ' + SET com_plg_sequence = ? -- new order sequence + WHERE com_id = ? -- field uuid; + AND com_type = \'ADM_PLUGIN\' + '; + + $newSequence = -1; + foreach ($sequence as $pos => $id) { + if ($id == $comId) { + // Store position for later update + $newSequence = $pos; + } else { + $this->db->queryPrepared($sql, array($pos, $id)); + } + } + + if ($newSequence >= 0) { + $this->componentRessource->setValue('com_plg_sequence', $newSequence); + } + + return $this->componentRessource->save(); + } +} \ No newline at end of file diff --git a/src/Infrastructure/Plugins/PluginAbstract.php b/src/Infrastructure/Plugins/PluginAbstract.php index 9d553222bb..6789543810 100644 --- a/src/Infrastructure/Plugins/PluginAbstract.php +++ b/src/Infrastructure/Plugins/PluginAbstract.php @@ -330,6 +330,20 @@ public static function getComponentName() : string return basename(self::$pluginPath); } + /** + * Get the sequence of the plugin in the components table. + * @throws Exception + * @return int Returns the sequence of the plugin. + */ + public static function getPluginSequence() : int + { + global $gDb; + // get the plugin sequence from the database + $sql = 'SELECT com_plg_sequence FROM ' . TBL_COMPONENTS . ' WHERE com_id = ?'; + $statement = $gDb->queryPrepared($sql, array(self::getComponentId())); + return (int)$statement->fetchColumn(); + } + /** * @throws Exception * @return bool diff --git a/src/Infrastructure/Plugins/PluginInterface.php b/src/Infrastructure/Plugins/PluginInterface.php index 171a9d68ee..7ad8fe9f3a 100644 --- a/src/Infrastructure/Plugins/PluginInterface.php +++ b/src/Infrastructure/Plugins/PluginInterface.php @@ -66,6 +66,13 @@ public static function getComponentId() : int; * @return string */ public static function getComponentName() : string; + + /** + * @throws Exception + * @return int + */ + public static function getPluginSequence() : int; + /** * @throws Exception * @return bool diff --git a/src/Infrastructure/Plugins/PluginManager.php b/src/Infrastructure/Plugins/PluginManager.php index 629573cf9f..134584e9c5 100644 --- a/src/Infrastructure/Plugins/PluginManager.php +++ b/src/Infrastructure/Plugins/PluginManager.php @@ -163,12 +163,25 @@ public function getOverviewPlugins() : array if (!$enabled) { continue; } - $overviewPlugins[] = array( + + $templateRow = array( 'id' => $plugin['interface']->getComponentId(), 'name' => $plugin['interface']->getComponentName(), 'file' => basename($plugin['relativePath']), 'interface' => $plugin['interface'] ); + + // Get the sequence of the plugin + $sequence = $plugin['interface']->getPluginSequence(); + $desiredSequence = $sequence; + if (isset($overviewPlugins[$desiredSequence])) { + $desiredSequence++; + while (isset($overviewPlugins[$desiredSequence])) { + $desiredSequence++; + } + } + $overviewPlugins[$desiredSequence] = $templateRow; + ksort($overviewPlugins); } } return $overviewPlugins; diff --git a/src/UI/Presenter/PluginsPresenter.php b/src/UI/Presenter/PluginsPresenter.php index c35c6e8995..7123ed203b 100644 --- a/src/UI/Presenter/PluginsPresenter.php +++ b/src/UI/Presenter/PluginsPresenter.php @@ -35,17 +35,49 @@ class PluginsPresenter extends PagePresenter */ public function createList(): void { - global $gL10n; + global $gL10n, $gCurrentSession; $this->setHtmlID('adm_plugins'); $this->setHeadline($gL10n->get('SYS_PLUGIN_MANAGER')); - + $this->setContentFullWidth(); + $this->prepareData(); $this->addJavascript(' $(".admidio-open-close-caret").click(function() { showHideBlock($(this)); }); + $("tbody.admidio-sortable").sortable({ + axis: "y", + handle: ".handle", + stop: function(event, ui) { + const order = $(this).sortable("toArray", {attribute: "data-uuid"}); + const uid = ui.item.attr("data-uuid"); + $.post("' . ADMIDIO_URL . FOLDER_MODULES . '/plugins.php?mode=sequence&uuid=" + uid + "&order=" + order, + {"adm_csrf_token": "' . $gCurrentSession->getCsrfToken() . '"} + ); + updateMoveActions("tbody.admidio-sortable", "adm_plugin_entry", "admidio-plugin-move"); + } + }); + $(".admidio-plugin-move").click(function() { + moveTableRow( + $(this), + "' . ADMIDIO_URL . FOLDER_MODULES . '/plugins.php", + "' . $gCurrentSession->getCsrfToken() . '" + ); + }); + $(document).ajaxComplete(function(event, xhr, settings) { + if (settings.url.indexOf("mode=delete") !== -1) { + // wait for callUrlHideElement to finish hiding the element + setTimeout(function() { + updateMoveActions("tbody.admidio-sortable", "adm_plugin_entry", "admidio-plugin-move"); + }, 1000); + } else { + updateMoveActions("tbody.admidio-sortable", "adm_plugin_entry", "admidio-plugin-move"); + } + }); + + updateMoveActions("tbody.admidio-sortable", "adm_plugin_entry", "admidio-plugin-move"); ', true ); @@ -96,8 +128,9 @@ public function prepareData(): void global $gL10n; $pluginManager = new PluginManager(); $plugins = $pluginManager->getAvailablePlugins(); - $templateRowPluginParent[] = array('id' => 'overview_plugins', 'name' => $gL10n->get('SYS_OVERVIEW_EXTENSIONS'), 'entries' => array()); - $templateRowPluginParent[] = array('id' => 'plugins', 'name' => $gL10n->get('SYS_EXTENSIONS'), 'entries' => array()); + $templateRowPluginParent['overview'] = array('id' => 'overview_plugins', 'name' => $gL10n->get('SYS_OVERVIEW_EXTENSIONS'), 'entries' => array()); + $templateRowPluginParent['plugins'] = array('id' => 'plugins', 'name' => $gL10n->get('SYS_EXTENSIONS'), 'entries' => array()); + $templateRowPluginParent['available'] = array('id' => 'plugins_available', 'name' => $gL10n->get('SYS_EXTENSIONS_AVAILABLE'), 'entries' => array()); foreach($plugins as $pluginName => $values) { $templateRow = array(); $interface = $values['interface'] instanceof PluginAbstract ? $values['interface']::getInstance() : null; @@ -156,12 +189,33 @@ public function prepareData(): void if ($interface !== null && $interface->isOverviewPlugin()) { // add the plugin to the overview plugins - $templateRowPluginParent[0]['entries'][] = $templateRow; - } else { + // for overview plugins here is a sequence number that is used to sort the plugins on the overview page + $sequence = $interface->getPluginSequence(); + $desiredSequence = $sequence; + if (isset($templateRowPluginParent['overview']['entries'][$desiredSequence])) { + $desiredSequence++; + while (isset($templateRowPluginParent['overview']['entries'][$desiredSequence])) { + $desiredSequence++; + } + } + $templateRowPluginParent['overview']['entries'][$desiredSequence] = $templateRow; + ksort($templateRowPluginParent['overview']['entries']); + } elseif ($interface !== null && $interface->isInstalled()) { // add the plugin to the normal plugins - $templateRowPluginParent[1]['entries'][] = $templateRow; + $templateRowPluginParent['plugins']['entries'][] = $templateRow; + } else { + // add the plugin to the available plugins + $templateRowPluginParent['available']['entries'][] = $templateRow; } } + + // remove empty categories + foreach ($templateRowPluginParent as $key => $value) { + if (empty($value['entries'])) { + unset($templateRowPluginParent[$key]); + } + } + $this->templateData = $templateRowPluginParent; } } \ No newline at end of file diff --git a/themes/simple/templates/modules/plugins.list.tpl b/themes/simple/templates/modules/plugins.list.tpl index e2485e27d7..ee86f33aaf 100644 --- a/themes/simple/templates/modules/plugins.list.tpl +++ b/themes/simple/templates/modules/plugins.list.tpl @@ -3,11 +3,12 @@ {$l10n->get('SYS_NAME')} +   {* sort *} {$l10n->get('SYS_DESCRIPTION')} {$l10n->get('SYS_AUTHOR')} {$l10n->get('SYS_PLUGIN_VERSION')} {$l10n->get('SYS_INSTALLED_VERSION')} -   +   {* actions *} {foreach $list as $pluginNode} @@ -23,8 +24,20 @@ {if isset($pluginNode.entries)} {foreach $pluginNode.entries as $pluginEntry} - + {if isset($pluginEntry.icon)}{/if} {$pluginEntry.name} + + {if {string_contains haystack=$pluginNode.id needle='overview'}} + + + + + + + {/if} + {$pluginEntry.description} {$pluginEntry.author} {$pluginEntry.version} From e0eca011c12ba86b08a4913a7e61545fb2dc4b8d Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 23 Jul 2025 13:03:22 +0200 Subject: [PATCH 015/109] small fixes --- .../AnnouncementList/classes/AnnouncementList.php | 7 ++++++- adm_plugins/birthday/classes/Birthday.php | 11 ++++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/adm_plugins/AnnouncementList/classes/AnnouncementList.php b/adm_plugins/AnnouncementList/classes/AnnouncementList.php index e2f5e1cc35..0423097734 100644 --- a/adm_plugins/AnnouncementList/classes/AnnouncementList.php +++ b/adm_plugins/AnnouncementList/classes/AnnouncementList.php @@ -147,7 +147,7 @@ private static function getAnnouncementsData() : array } /** - * @param array $config + * @param PagePresenter $page * @throws InvalidArgumentException * @throws Exception * @return bool @@ -165,6 +165,11 @@ public static function doRender($page = null) : bool $announcementListPlugin = new Overview($pluginFolder); + // check if the plugin is installed + if (!self::isInstalled()) { + throw new InvalidArgumentException($gL10n->get('SYS_PLUGIN_NOT_INSTALLED')); + } + if ($gSettingsManager->getInt('announcements_module_enabled') > 0) { if (($gSettingsManager->getInt('announcements_module_enabled') === 1 || ($gSettingsManager->getInt('announcements_module_enabled') === 2 && $gValidLogin)) && ($gSettingsManager->getInt('announcement_list_plugin_enabled') === 1 || ($gSettingsManager->getInt('announcement_list_plugin_enabled') === 2 && $gValidLogin))) { diff --git a/adm_plugins/birthday/classes/Birthday.php b/adm_plugins/birthday/classes/Birthday.php index 403000cfe3..774e7d7f8c 100644 --- a/adm_plugins/birthday/classes/Birthday.php +++ b/adm_plugins/birthday/classes/Birthday.php @@ -115,8 +115,8 @@ private static function getBirthdaysData() : array } // Check if the role condition has been set - if (isset($config['birthday_rolle_sql']) && is_array($config['birthday_rolle_sql']) && count($config['birthday_rolle_sql']) > 0) { - $sqlRol = 'IN (' . implode(',', $config['birthday_rolle_sql']) . ')'; + if (isset($config['birthday_roles_sql']) && is_array($config['birthday_roles_sql']) && count($config['birthday_roles_sql']) > 0) { + $sqlRol = 'IN (' . implode(',', $config['birthday_roles_sql']) . ')'; } else { $sqlRol = 'IS NOT NULL'; } @@ -366,7 +366,7 @@ private static function getBirthdaysData() : array } /** - * @param array $config + * @param PagePresenter $page * @throws InvalidArgumentException * @throws Exception * @return bool @@ -384,6 +384,11 @@ public static function doRender($page = null) : bool $birthdayPlugin = new Overview($pluginFolder); + // check if the plugin is installed + if (!self::isInstalled()) { + throw new InvalidArgumentException($gL10n->get('SYS_PLUGIN_NOT_INSTALLED')); + } + if ($gSettingsManager->getInt('birthday_plugin_enabled') === 1 || ($gSettingsManager->getInt('birthday_plugin_enabled') === 2 && $gValidLogin)) { $birthdaysArray = self::getBirthdaysData(); From 07b3dd1514e85228eaeda70daeeb43d8ca117d2e Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 23 Jul 2025 15:16:14 +0200 Subject: [PATCH 016/109] rebase calendar overview-plugin to use PluginManager --- adm_plugins/birthday/languages/en.xml | 2 +- adm_plugins/calendar/Calendar.json | 72 +++ adm_plugins/calendar/classes/Calendar.php | 584 ++++++++++++++++++ .../CalendarPreferencesPresenter.php | 141 +++++ adm_plugins/calendar/config_sample.php | 65 -- .../calendar/db_scripts/update_1_0.xml | 6 + adm_plugins/calendar/index.php | 453 +------------- adm_plugins/calendar/languages/en.xml | 21 + .../templates/preferences.plugin.calendar.tpl | 20 + src/Infrastructure/Plugins/PluginAbstract.php | 10 + .../Plugins/PluginInterface.php | 6 + .../simple/templates/modules/plugins.list.tpl | 2 +- 12 files changed, 869 insertions(+), 513 deletions(-) create mode 100644 adm_plugins/calendar/Calendar.json create mode 100644 adm_plugins/calendar/classes/Calendar.php create mode 100644 adm_plugins/calendar/classes/Presenter/CalendarPreferencesPresenter.php delete mode 100644 adm_plugins/calendar/config_sample.php create mode 100644 adm_plugins/calendar/db_scripts/update_1_0.xml create mode 100644 adm_plugins/calendar/templates/preferences.plugin.calendar.tpl diff --git a/adm_plugins/birthday/languages/en.xml b/adm_plugins/birthday/languages/en.xml index 3770558be8..b5cfbbae4a 100644 --- a/adm_plugins/birthday/languages/en.xml +++ b/adm_plugins/birthday/languages/en.xml @@ -23,7 +23,7 @@ Show names for visitors If this setting is enabled visitors will see all names (not the age) of birthday persons today, in the future and in the past. Otherwise visitors will only see the number of persons who have birthday today, nothing more. (default: false) Display style for birthday person name - This setting allows you to choose how the names of birthday persons are displayed. (default: First name Last name) + This setting allows you to choose how the names of birthday persons are displayed. (default: First name Surname) Show age If this setting is enabled logged in users will see the ages of birthday persons. (default: false) Show name with salutation diff --git a/adm_plugins/calendar/Calendar.json b/adm_plugins/calendar/Calendar.json new file mode 100644 index 0000000000..a18309913b --- /dev/null +++ b/adm_plugins/calendar/Calendar.json @@ -0,0 +1,72 @@ +{ + "name": "PLG_CALENDAR_PLUGIN_NAME", + "description": "PLG_CALENDAR_PLUGIN_DESCRIPTION", + "version": "1.0.0", + "author": "Admidio Team", + "url": "https://www.admidio.org", + "icon": "bi-calendar-week-fill", + "mainFile": "index.php", + "dependencies": [], + "defaultConfig": { + "calendar_plugin_enabled": { + "name": "ORG_ACCESS_TO_PLUGIN", + "description": "ORG_ACCESS_TO_PLUGIN_DESC", + "type": "integer", + "value" : 1 + }, + "calendar_show_events": { + "name": "PLG_CALENDAR_PREFERENCES_SHOW_EVENTS", + "description": "PLG_CALENDAR_PREFERENCES_SHOW_EVENTS_DESC", + "type": "boolean", + "value" : true + }, + "calendar_show_birthdays": { + "name": "PLG_CALENDAR_PREFERENCES_SHOW_BIRTHDAYS", + "description": "PLG_CALENDAR_PREFERENCES_SHOW_BIRTHDAYS_DESC", + "type": "boolean", + "value" : true + }, + "calendar_show_birthdays_to_guests": { + "name": "PLG_CALENDAR_PREFERENCES_SHOW_BIRTHDAYS_TO_GUESTS", + "description": "PLG_CALENDAR_PREFERENCES_SHOW_BIRTHDAYS_TO_GUESTS_DESC", + "type": "boolean", + "value" : false + }, + "calendar_show_birthday_icon": { + "name": "PLG_CALENDAR_PREFERENCES_SHOW_BIRTHDAY_ICON", + "description": "PLG_CALENDAR_PREFERENCES_SHOW_BIRTHDAY_ICON_DESC", + "type": "boolean", + "value" : true + }, + "calendar_show_birthday_names": { + "name": "PLG_CALENDAR_PREFERENCES_SHOW_BIRTHDAY_NAMES", + "description": "PLG_CALENDAR_PREFERENCES_SHOW_BIRTHDAY_NAMES_DESC", + "type": "integer", + "value" : 1 + }, + "calendar_show_categories": { + "name": "PLG_CALENDAR_PREFERENCES_SHOW_CATEGORIES", + "description": "PLG_CALENDAR_PREFERENCES_SHOW_CATEGORIES_DESC", + "type": "array", + "value" : ["All"] + }, + "calendar_show_categories_names": { + "name": "PLG_CALENDAR_PREFERENCES_SHOW_CATEGORIES_NAMES", + "description": "PLG_CALENDAR_PREFERENCES_SHOW_CATEGORIES_NAMES_DESC", + "type": "boolean", + "value" : false + }, + "calendar_roles_view_plugin": { + "name": "PLG_CALENDAR_PREFERENCES_ROLES_VIEW_PLUGIN", + "description": "PLG_CALENDAR_PREFERENCES_ROLES_VIEW_PLUGIN_DESC", + "type": "array", + "value" : ["All"] + }, + "calendar_roles_sql": { + "name": "PLG_CALENDAR_PREFERENCES_ROLES_SQL", + "description": "PLG_CALENDAR_PREFERENCES_ROLES_SQL_DESC", + "type": "array", + "value" : ["All"] + } + } +} \ No newline at end of file diff --git a/adm_plugins/calendar/classes/Calendar.php b/adm_plugins/calendar/classes/Calendar.php new file mode 100644 index 0000000000..0491e0341e --- /dev/null +++ b/adm_plugins/calendar/classes/Calendar.php @@ -0,0 +1,584 @@ +getAllVisibleCategories('EVT'); + } + + // if the key equals 'calendar_roles_view_plugin' and the value is still the default value, retrieve the roles from the database + if (array_key_exists('calendar_roles_view_plugin', $config) && $config['calendar_roles_view_plugin']['value'] === self::$defaultConfig['calendar_roles_view_plugin']['value']) { + $config['calendar_roles_view_plugin']['value'] = self::getAvailableRoles(1, true); + } + // if the key equals 'calendar_roles_sql' and the value is still the default value, retrieve the roles from the database + if (array_key_exists('calendar_roles_sql', $config) && $config['calendar_roles_sql']['value'] === self::$defaultConfig['calendar_roles_sql']['value']) { + $config['calendar_roles_sql']['value'] = self::getAvailableRoles(1, true); + } + return $config; + } + + /** + * Get the plugin configuration values + * @return array Returns the plugin configuration values + */ + public static function getPluginConfigValues() : array + { + global $gCurrentUser; + + // get the plugin config values from the parent class + $config = parent::getPluginConfigValues(); + + // if the key equals 'calendar_show_categories' and the value is still the default value, retrieve the roles from the database + if (array_key_exists('calendar_show_categories', $config) && $config['calendar_show_categories'] === self::$defaultConfig['calendar_show_categories']['value']) { + $config['calendar_show_categories'] = $gCurrentUser->getAllVisibleCategories('EVT'); + } + // if the key equals 'calendar_roles_view_plugin' and the value is still the default value, retrieve the roles from the database + if (array_key_exists('calendar_roles_view_plugin', $config) && $config['calendar_roles_view_plugin'] === self::$defaultConfig['calendar_roles_view_plugin']['value']) { + $config['calendar_roles_view_plugin'] = self::getAvailableRoles(1, true); + } + // if the key equals 'calendar_roles_sql' and the value is still the default value, retrieve the roles from the database + if (array_key_exists('calendar_roles_sql', $config) && $config['calendar_roles_sql'] === self::$defaultConfig['calendar_roles_sql']['value']) { + $config['calendar_roles_sql'] = self::getAvailableRoles(1, true); + } + + return $config; + } + + /** + * Get the available roles for the calendar plugin + * @param int $roleType The type of roles to retrieve (0 for inactive, 1 for active, 2 for only event participation roles) + * @param bool $onlyIds If true, only the IDs of the roles are returned + * @return array Returns an array with the available roles + */ + public static function getAvailableRoles($roleType = 1, bool $onlyIds = false): array { + global $gDb; + + $allRolesSet = array(); + $rolesService = new RolesService($gDb); + $data = $rolesService->findAll($roleType); + + foreach ($data as $rowViewRoles) { + if ($onlyIds) { + // If only the IDs are requested, return an array with the role IDs + $allRolesSet[] = $rowViewRoles['rol_id']; + } else { + // Each role is now added to this array + $allRolesSet[] = array( + $rowViewRoles['rol_id'], // ID + $rowViewRoles['rol_name'] + ); + } + } + return $allRolesSet; + } + + private static function createCalendar(array $eventsMonthDayArray, array $birthdaysMonthDayArray) : string + { + global $gSettingsManager, $gL10n, $gValidLogin; + // Kalender erstellen + $firstWeekdayOfMonth = (int)date('w', mktime(0, 0, 0, self::$currentMonth, 1, self::$currentYear)); + self::$months = explode(',', $gL10n->get('PLG_CALENDAR_MONTH')); + + if ($firstWeekdayOfMonth === 0) { + $firstWeekdayOfMonth = 7; + } + + $tableContent = ''; + $i = 1; + while ($i < $firstWeekdayOfMonth) { + $tableContent .= ' '; + ++$i; + } + + $currentDay = 1; + $boolNewStart = false; + + while ($currentDay <= self::$lastDayCurrentMonth) { + $terLink = ''; + $gebLink = ''; + $htmlContent = ''; + $textContent = ''; + $hasEvents = false; + $hasBirthdays = false; + $countEvents = 0; + + $dateObj = DateTime::createFromFormat('Y-m-j', self::$currentYear . '-' . self::$currentMonth . '-' . $currentDay); + + // add events to the calendar + if (self::$pluginConfig['calendar_show_events']) { + // only show events in dependence of the events module view settings + if (array_key_exists($currentDay, $eventsMonthDayArray) + && ($gSettingsManager->getInt('events_module_enabled') === 1 + || ($gSettingsManager->getInt('events_module_enabled') === 2 && $gValidLogin))) { + $hasEvents = true; + + foreach ($eventsMonthDayArray[$currentDay] as $eventArray) { + if ($eventArray['location'] !== '') { + $eventArray['location'] = ', ' . $eventArray['location']; + } + + if ($htmlContent !== '') { + $htmlContent .= '
'; + } + if ($eventArray['all_day'] == 1) { + if ($eventArray['one_day']) { + $htmlContent .= '' . $gL10n->get('SYS_ALL_DAY') . ' ' . $eventArray['headline'] . $eventArray['location']; + $textContent .= $gL10n->get('SYS_ALL_DAY') . ' ' . $eventArray['headline'] . $eventArray['location']; + } else { + $htmlContent .= '' . $gL10n->get('PLG_CALENDAR_SEVERAL_DAYS') . ' ' . $eventArray['headline'] . $eventArray['location']; + $textContent .= $gL10n->get('PLG_CALENDAR_SEVERAL_DAYS') . ' ' . $eventArray['headline'] . $eventArray['location']; + } + } else { + $htmlContent .= '' . $eventArray['time'] . ' ' . $gL10n->get('SYS_CLOCK') . ' ' . $eventArray['headline'] . $eventArray['location']; + $textContent .= $eventArray['time'] . ' ' . $gL10n->get('SYS_CLOCK') . ' ' . $eventArray['headline'] . $eventArray['location']; + } + ++$countEvents; + } + + if ($countEvents > 0) { + $plgLink = SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/events/events.php', array('date_from' => $dateObj->format('Y-m-d'), 'date_to' => $dateObj->format('Y-m-d'))); + } + } + } + + // add users birthdays to the calendar + if (self::$pluginConfig['calendar_show_birthdays']) { + if (array_key_exists($currentDay, $birthdaysMonthDayArray) && self::$calendarShowNames) { + foreach ($birthdaysMonthDayArray[$currentDay] as $birthdayArray) { + $hasBirthdays = true; + + if ($htmlContent !== '') { + $htmlContent .= '
'; + $textContent .= ', '; + } + + if (self::$pluginConfig['calendar_show_birthday_icon']) { + $icon = ''; + } else { + $icon = ''; + } + + $htmlContent .= $icon . $birthdayArray['name'] . ' (' . $birthdayArray['age'] . ')'; + $textContent .= $birthdayArray['name'] . ' (' . $birthdayArray['age'] . ')'; + } + } + } + + // First pre-assignment of the weekday classes + $plgLinkClassSaturday = 'plgCalendarSaturday'; + $plgLinkClassSunday = 'plgCalendarSunday'; + $plgLinkClassWeekday = 'plgCalendarDay'; + + if (!$hasEvents && $hasBirthdays) { // no events but birthdays + $plgLinkClass = 'geb'; + $plgLinkClassSaturday .= ' plgCalendarBirthDay'; + $plgLinkClassSunday .= ' plgCalendarBirthDay'; + $plgLinkClassWeekday .= ' plgCalendarBirthDay'; + } + + if ($hasEvents && !$hasBirthdays) { // events but no birthdays + $plgLinkClass = 'date'; + $plgLinkClassSaturday .= ' plgCalendarDateDay'; + $plgLinkClassSunday .= ' plgCalendarDateDay'; + $plgLinkClassWeekday .= ' plgCalendarDateDay'; + } + + if ($hasEvents && $hasBirthdays) { // events and birthdays + $plgLinkClass = 'merge'; + $plgLinkClassSaturday .= ' plgCalendarMergeDay'; + $plgLinkClassSunday .= ' plgCalendarMergeDay'; + $plgLinkClassWeekday .= ' plgCalendarMergeDay'; + } + + if ($boolNewStart) { + $tableContent .= ''; + $boolNewStart = false; + } + $rest = ($currentDay + $firstWeekdayOfMonth - 1) % 7; + if ($currentDay === self::$today) { + $tableContent .= ''; + } elseif ($rest === 6) { + $tableContent .= ''; + } elseif ($rest === 0) { + $tableContent .= ''; + } else { + $tableContent .= ''; + } + + if ($currentDay === self::$today || $hasEvents || $hasBirthdays) { + if (!$hasEvents && $hasBirthdays) { + // Switch off link URL for birthday by #. + $plgLink = '#'; + } + + if ($hasEvents || $hasBirthdays) { + if ($terLink !== '' && $gebLink !== '') { + $gebLink = '&' . $gebLink; + } + + // plg_link_class bestimmt das Erscheinungsbild des jeweiligen Links + $tableContent .= '' . $currentDay . ''; + } elseif ($currentDay === self::$today) { + $tableContent .= '' . $currentDay . ''; + } + } elseif ($rest === 6) { + $tableContent .= '' . $currentDay . ''; + } elseif ($rest === 0) { + $tableContent .= '' . $currentDay . ''; + } else { + $tableContent .= $currentDay; + } + $tableContent .= ''; + if ($rest === 0 || $currentDay === self::$lastDayCurrentMonth) { + $tableContent .= ''; + $boolNewStart = true; + } + + ++$currentDay; + } + + return $tableContent; + } + + private static function getCalendarsData() : string + { + global $gSettingsManager, $gCurrentUser, $gDb, $gL10n, $gProfileFields, $gValidLogin, $gDbType, $gCurrentOrgId; + + self::$pluginConfig = self::getPluginConfigValues(); + + // check if only members of configured roles could view birthday + if ($gValidLogin) { + if (isset(self::$pluginConfig['calendar_roles_view_plugin']) && count(self::$pluginConfig['calendar_roles_view_plugin']) > 0) { + // current user must be member of at least one listed role + if (count(array_intersect(self::$pluginConfig['calendar_roles_view_plugin'], $gCurrentUser->getRoleMemberships())) > 0) { + self::$calendarShowNames = true; + } + } + } else { + if (self::$pluginConfig['calendar_show_birthdays_to_guests']) { + // every visitor is allowed to view birthdays + self::$calendarShowNames = true; + } + } + + // Check if the role condition has been set + if (isset(self::$pluginConfig['calendar_roles_sql']) && is_array(self::$pluginConfig['calendar_roles_sql']) && count(self::$pluginConfig['calendar_roles_sql']) > 0) { + $sqlRoleIds = 'IN (' . implode(',', self::$pluginConfig['calendar_roles_sql']) . ')'; + } else { + $sqlRoleIds = 'IS NOT NULL'; + } + + $dateMonthStart = self::$currentYear . '-' . self::$currentMonth . '-01 00:00:01'; // add 1 second to ignore all day events that end at 00:00:00 + $dateMonthEnd = self::$currentYear . '-' . self::$currentMonth . '-' . self::$lastDayCurrentMonth . ' 23:59:59'; + $eventsMonthDayArray = array(); + $birthdaysMonthDayArray = array(); + + // query of all events + if (self::$pluginConfig['calendar_show_events']) { + $catIdParams = array_merge(array(0), $gCurrentUser->getAllVisibleCategories('EVT')); + $queryParams = array_merge($catIdParams, array($dateMonthEnd, $dateMonthStart)); + + // check if special calendars should be shown + $allCategories = $gCurrentUser->getAllVisibleCategories('EVT'); + $selectedCategories = self::$pluginConfig['calendar_show_categories']; + + sort($allCategories); + sort($selectedCategories); + + if ($allCategories == $selectedCategories) { + // show all calendars + $sqlSyntax = ''; + } else { + // show only calendars of the parameter calendar_show_categories + $sqlSyntax = ' AND cat_name IN (' . Database::getQmForValues(self::$pluginConfig['calendar_show_categories']) . ')'; + $queryParams = array_merge($queryParams, self::$pluginConfig['calendar_show_categories']); + } + + $sql = 'SELECT DISTINCT dat_id, dat_cat_id, cat_name, dat_begin, dat_end, dat_all_day, dat_location, dat_headline + FROM ' . TBL_EVENTS . ' + INNER JOIN ' . TBL_CATEGORIES . ' + ON cat_id = dat_cat_id + WHERE cat_id IN (' . Database::getQmForValues($catIdParams) . ') + AND dat_begin <= ? -- $dateMonthEnd + AND dat_end >= ? -- $dateMonthStart + ' . $sqlSyntax . ' + ORDER BY dat_begin ASC'; + $datesStatement = $gDb->queryPrepared($sql, $queryParams); + + while ($row = $datesStatement->fetch()) { + $startDate = new DateTime($row['dat_begin']); + $endDate = new DateTime($row['dat_end']); + + // set custom name of plugin for calendar or use default Admidio name + if (self::$pluginConfig['calendar_show_categories_names']) { + if ($row['cat_name'][3] === '_') { + $calendarName = $gL10n->get($row['cat_name']); + } else { + $calendarName = $row['cat_name']; + } + $row['dat_headline'] = $calendarName . ': ' . $row['dat_headline']; + } + + if ($startDate->format('Y-m-d') === $endDate->format('Y-m-d')) { + // event only within one day + $eventsMonthDayArray[$startDate->format('j')][] = array( + 'dat_id' => $row['dat_id'], + 'time' => $startDate->format($gSettingsManager->getString('system_time')), + 'all_day' => $row['dat_all_day'], + 'location' => $row['dat_location'], + 'headline' => $row['dat_headline'], + 'one_day' => true + ); + } else { + // event within several days + + if ($startDate->format('m') !== self::$currentMonth) { + $firstDay = 1; + } else { + $firstDay = $startDate->format('j'); + } + + if ($endDate->format('m') !== self::$currentMonth) { + $lastDay = self::$lastDayCurrentMonth; + } else { + $lastDay = $endDate->format('j'); + } + + // now add event to every relevant day of month + for ($i = $firstDay; $i <= $lastDay; ++$i) { + $eventsMonthDayArray[$i][] = array( + 'dat_id' => $row['dat_id'], + 'time' => $startDate->format($gSettingsManager->getString('system_time')), + 'all_day' => $row['dat_all_day'], + 'location' => $row['dat_location'], + 'headline' => $row['dat_headline'], + 'one_day' => false + ); + } + } + } + } + + // query of all birthdays + if (self::$pluginConfig['calendar_show_birthdays']) { + if (DB_ENGINE === Database::PDO_ENGINE_PGSQL) { + $sqlYearOfBirthday = ' EXTRACT(YEAR FROM TO_TIMESTAMP(birthday.usd_value, \'YYYY-MM-DD\')) '; + $sqlMonthOfBirthday = ' EXTRACT(MONTH FROM TO_TIMESTAMP(birthday.usd_value, \'YYYY-MM-DD\')) '; + $sqlDayOfBirthday = ' EXTRACT(DAY FROM TO_TIMESTAMP(birthday.usd_value, \'YYYY-MM-DD\')) '; + } else { + $sqlYearOfBirthday = ' YEAR(birthday.usd_value) '; + $sqlMonthOfBirthday = ' MONTH(birthday.usd_value) '; + $sqlDayOfBirthday = ' DayOfMonth(birthday.usd_value) '; + } + + switch (self::$pluginConfig['calendar_show_birthday_names']) { + case 1: + $sqlOrderName = 'first_name'; + break; + case 2: + $sqlOrderName = 'last_name'; + break; + case 0: // fallthrough + default: + $sqlOrderName = 'last_name, first_name'; + } + + // database query for all birthdays of this month + $sql = 'SELECT DISTINCT + usr_id, last_name.usd_value AS last_name, first_name.usd_value AS first_name, birthday.usd_value AS birthday, + ' . $sqlYearOfBirthday . ' AS birthday_year, ' . $sqlMonthOfBirthday . ' AS birthday_month, + ' . $sqlDayOfBirthday . ' AS birthday_day + FROM ' . TBL_MEMBERS . ' + INNER JOIN ' . TBL_ROLES . ' + ON rol_id = mem_rol_id + INNER JOIN ' . TBL_CATEGORIES . ' + ON cat_id = rol_cat_id + INNER JOIN ' . TBL_USERS . ' + ON usr_id = mem_usr_id + INNER JOIN ' . TBL_USER_DATA . ' AS birthday + ON birthday.usd_usr_id = usr_id + AND birthday.usd_usf_id = ? -- $gProfileFields->getProperty(\'BIRTHDAY\', \'usf_id\') + AND ' . $sqlMonthOfBirthday . ' = ? -- $currentMonth + LEFT JOIN ' . TBL_USER_DATA . ' AS last_name + ON last_name.usd_usr_id = usr_id + AND last_name.usd_usf_id = ? -- $gProfileFields->getProperty(\'LAST_NAME\', \'usf_id\') + LEFT JOIN ' . TBL_USER_DATA . ' AS first_name + ON first_name.usd_usr_id = usr_id + AND first_name.usd_usf_id = ? -- $gProfileFields->getProperty(\'FIRST_NAME\', \'usf_id\') + WHERE usr_valid = true + AND cat_org_id = ? -- $gCurrentOrgId + AND rol_id ' . $sqlRoleIds . ' + AND mem_begin <= ? -- DATE_NOW + AND mem_end > ? -- DATE_NOW + ORDER BY birthday_year DESC, birthday_month DESC, birthday_day DESC, ' . $sqlOrderName; + + $queryParams = array( + $gProfileFields->getProperty('BIRTHDAY', 'usf_id'), + self::$currentMonth, + $gProfileFields->getProperty('LAST_NAME', 'usf_id'), + $gProfileFields->getProperty('FIRST_NAME', 'usf_id'), + $gCurrentOrgId, + DATE_NOW, + DATE_NOW + ); + $birthdayStatement = $gDb->queryPrepared($sql, $queryParams); + + while ($row = $birthdayStatement->fetch()) { + $birthdayDate = new DateTime($row['birthday']); + + switch (self::$pluginConfig['calendar_show_birthday_names']) { + case 1: + $name = $row['first_name']; + break; + case 2: + $name = $row['last_name']; + break; + case 0: // fallthrough + default: + $name = $row['last_name'] . ($row['last_name'] ? ', ' : '') . $row['first_name']; + } + + $birthdaysMonthDayArray[$birthdayDate->format('j')][] = array( + 'year' => $birthdayDate->format('Y'), + 'age' => self::$currentYear - $birthdayDate->format('Y'), + 'name' => $name + ); + } + } + + return self::createCalendar($eventsMonthDayArray, $birthdaysMonthDayArray); + } + + public static function initParams(array $params = array()) : bool + { + // check if params is an array + if (!is_array($params)) + { + throw new InvalidArgumentException('Config must be an "array".'); + } + + // init parameters + if (isset($params['date_id']) && $params['date_id'] !== '') { + // Read Date ID or generate current month and year + self::$currentMonth = substr($params['date_id'], 0, 2); + self::$currentYear = substr($params['date_id'], 2, 4); + $_SESSION['plugin_calendar_last_month'] = self::$currentMonth . self::$currentYear; + } elseif (isset($_SESSION['plugin_calendar_last_month'])) { + // Show last selected month + self::$currentMonth = substr($_SESSION['plugin_calendar_last_month'], 0, 2); + self::$currentYear = substr($_SESSION['plugin_calendar_last_month'], 2, 4); + } else { + // show current month + self::$currentMonth = date('m'); + self::$currentYear = date('Y'); + } + + if (self::$currentMonth === date('m') && self::$currentYear === date('Y')) { + self::$today = (int)date('d'); + } + + self::$lastDayCurrentMonth = (int)date('t', mktime(0, 0, 0, self::$currentMonth, 1, self::$currentYear)); + + return true; + } + + /** + * @param PagePresenter $page + * @throws InvalidArgumentException + * @throws Exception + * @return bool + */ + public static function doRender($page = null) : bool + { + global $gSettingsManager, $gL10n, $gValidLogin; + + // show the announcement list + try { + $rootPath = dirname(__DIR__, 3); + $pluginFolder = basename(self::$pluginPath); + + require_once($rootPath . '/system/common.php'); + + $calendarPlugin = new Overview($pluginFolder); + // check if the plugin is installed + if (!self::isInstalled()) { + throw new InvalidArgumentException($gL10n->get('SYS_PLUGIN_NOT_INSTALLED')); + } + + if ($gSettingsManager->getInt('calendar_plugin_enabled') === 1 || ($gSettingsManager->getInt('calendar_plugin_enabled') === 2 && $gValidLogin)) { + + $tableContent = self::getCalendarsData(); + + header('Content-Type: text/html; charset=utf-8'); + + $calendarPlugin->assignTemplateVariable('pluginFolder', $pluginFolder); + $calendarPlugin->assignTemplateVariable('monthYearHeadline', self::$months[(int) self::$currentMonth - 1] . ' ' . self::$currentYear); + $calendarPlugin->assignTemplateVariable('monthYear', self::$currentMonth . self::$currentYear); + $calendarPlugin->assignTemplateVariable('currentMonthYear', date('mY')); + $calendarPlugin->assignTemplateVariable('dateIdLastMonth', date('mY', mktime(0, 0, 0, self::$currentMonth - 1, 1, self::$currentYear))); + $calendarPlugin->assignTemplateVariable('dateIdNextMonth', date('mY', mktime(0, 0, 0, self::$currentMonth + 1, 1, self::$currentYear))); + $calendarPlugin->assignTemplateVariable('tableContent', $tableContent); + } else { + $calendarPlugin->assignTemplateVariable('message',$gL10n->get('PLG_BIRTHDAY_NO_ENTRIES_VISITORS')); + } + + if (isset($page)) { + echo $calendarPlugin->html('plugin.calendar.tpl'); + } else { + $calendarPlugin->showHtmlPage('plugin.calendar.tpl'); + } + } catch (Throwable $e) { + echo $e->getMessage(); + } + + return true; + } +} \ No newline at end of file diff --git a/adm_plugins/calendar/classes/Presenter/CalendarPreferencesPresenter.php b/adm_plugins/calendar/classes/Presenter/CalendarPreferencesPresenter.php new file mode 100644 index 0000000000..eef0554876 --- /dev/null +++ b/adm_plugins/calendar/classes/Presenter/CalendarPreferencesPresenter.php @@ -0,0 +1,141 @@ + 'save', 'panel' => 'calendar')), + null, + array('class' => 'form-preferences') + ); + $selectBoxEntries = array( + '0' => $gL10n->get('SYS_DISABLED'), + '1' => $gL10n->get('SYS_ENABLED'), + '2' => $gL10n->get('ORG_ONLY_FOR_REGISTERED_USER') + ); + $formCalendar->addSelectBox( + 'calendar_plugin_enabled', + Language::translateIfTranslationStrId($formValues['calendar_plugin_enabled']['name']), + $selectBoxEntries, + array('defaultValue' => $formValues['calendar_plugin_enabled']['value'], 'showContextDependentFirstEntry' => false, 'helpTextId' => $formValues['calendar_plugin_enabled']['description']) + ); + $formCalendar->addCheckbox( + 'calendar_show_events', + Language::translateIfTranslationStrId($formValues['calendar_show_events']['name']), + $formValues['calendar_show_events']['value'], + array('helpTextId' => $formValues['calendar_show_events']['description']) + ); + $formCalendar->addCheckbox( + 'calendar_show_birthdays', + Language::translateIfTranslationStrId($formValues['calendar_show_birthdays']['name']), + $formValues['calendar_show_birthdays']['value'], + array('helpTextId' => $formValues['calendar_show_birthdays']['description']) + ); + $formCalendar->addCheckbox( + 'calendar_show_birthdays_to_guests', + Language::translateIfTranslationStrId($formValues['calendar_show_birthdays_to_guests']['name']), + $formValues['calendar_show_birthdays_to_guests']['value'], + array('helpTextId' => $formValues['calendar_show_birthdays_to_guests']['description']) + ); + $formCalendar->addCheckbox( + 'calendar_show_birthday_icon', + Language::translateIfTranslationStrId($formValues['calendar_show_birthday_icon']['name']), + $formValues['calendar_show_birthday_icon']['value'], + array('helpTextId' => $formValues['calendar_show_birthday_icon']['description']) + ); + $selectBoxEntries = array( + '0' => $gL10n->get('SYS_LASTNAME') . ', ' . $gL10n->get('SYS_FIRSTNAME'), + '1' => $gL10n->get('SYS_FIRSTNAME'), + '2' => $gL10n->get('SYS_LASTNAME') + ); + $formCalendar->addSelectBox( + 'calendar_show_birthday_names', + Language::translateIfTranslationStrId($formValues['calendar_show_birthday_names']['name']), + $selectBoxEntries, + array('defaultValue' => $formValues['calendar_show_birthday_names']['value'], 'showContextDependentFirstEntry' => false, 'helpTextId' => $formValues['calendar_show_birthday_names']['description']) + ); + + $catIdParams = array_merge(array(0), $gCurrentUser->getAllVisibleCategories('EVT')); + $sql = 'SELECT cat.cat_id, cat.cat_name + FROM ' . TBL_EVENTS . ' AS evt + INNER JOIN ' . TBL_CATEGORIES . ' AS cat + WHERE cat_id IN (' . $gDb->getQmForValues($catIdParams) . ') + ORDER BY evt.dat_timestamp_create DESC'; + $sqlData = array( + 'query' => $sql, + 'params' => $catIdParams + ); + + $formCalendar->addSelectBoxFromSql( + 'calendar_show_categories', + Language::translateIfTranslationStrId($formValues['calendar_show_categories']['name']), + $gDb, + $sqlData, + array('defaultValue' => $formValues['calendar_show_categories']['value'], 'showContextDependentFirstEntry' => false, 'helpTextId' => $formValues['calendar_show_categories']['description'], 'multiselect' => true, 'maximumSelectionNumber' => count($gCurrentUser->getAllVisibleCategories('EVT'))) + ); + + $formCalendar->addCheckbox( + 'calendar_show_categories_names', + Language::translateIfTranslationStrId($formValues['calendar_show_categories_names']['name']), + $formValues['calendar_show_categories_names']['value'], + array('helpTextId' => $formValues['calendar_show_categories_names']['description']) + ); + + $selectBoxEntries = $pluginCalendar instanceof Calendar ? $pluginCalendar::getAvailableRoles() : array(); + + $formCalendar->addSelectBox( + 'calendar_roles_view_plugin', + Language::translateIfTranslationStrId($formValues['calendar_roles_view_plugin']['name']), + $selectBoxEntries, + array('defaultValue' => $formValues['calendar_roles_view_plugin']['value'], 'showContextDependentFirstEntry' => false, 'helpTextId' => $formValues['calendar_roles_view_plugin']['description'], 'multiselect' => true, 'maximumSelectionNumber' => count($selectBoxEntries)) + ); + $formCalendar->addSelectBox( + 'calendar_roles_sql', + Language::translateIfTranslationStrId($formValues['calendar_roles_sql']['name']), + $selectBoxEntries, + array('defaultValue' => $formValues['calendar_roles_sql']['value'], 'showContextDependentFirstEntry' => false, 'helpTextId' => $formValues['calendar_roles_sql']['description'], 'multiselect' => true, 'maximumSelectionNumber' => count($selectBoxEntries)) + ); + + $formCalendar->addSubmitButton( + 'adm_button_save_calendar', + $gL10n->get('SYS_SAVE'), + array('icon' => 'bi-check-lg', 'class' => 'offset-sm-3') + ); + + $formCalendar->addToSmarty($smarty); + $gCurrentSession->addFormObject($formCalendar); + return $smarty->fetch($pluginCalendar::getPluginPath() . '/templates/preferences.plugin.calendar.tpl'); + } +} \ No newline at end of file diff --git a/adm_plugins/calendar/config_sample.php b/adm_plugins/calendar/config_sample.php deleted file mode 100644 index 64dbdb9b71..0000000000 --- a/adm_plugins/calendar/config_sample.php +++ /dev/null @@ -1,65 +0,0 @@ - + + UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'Calendar' + UPDATE %PREFIX%_components SET com_plg_sequence = 3 WHERE com_type = 'ADM_PLUGIN' AND com_name_intern = 'Calendar' + stop + diff --git a/adm_plugins/calendar/index.php b/adm_plugins/calendar/index.php index 2f75af25ad..9f6adfa1e8 100644 --- a/adm_plugins/calendar/index.php +++ b/adm_plugins/calendar/index.php @@ -1,16 +1,11 @@ 0) { - // current user must be member of at least one listed role - if (count(array_intersect($plg_calendar_roles_view_plugin, $gCurrentUser->getRoleMemberships())) > 0) { - $plgCalendarShowNames = true; - } - } else { - // every member could view birthdays - $plgCalendarShowNames = true; - } - } else { - if ($plg_geb_login === 0) { - // every visitor is allowed to view birthdays - $plgCalendarShowNames = true; - } - } - - // check if role conditions where set - if (isset($plg_rolle_sql) && is_array($plg_rolle_sql) && count($plg_rolle_sql) > 0) { - $sqlRoleIds = 'IN (' . implode(',', $plg_rolle_sql) . ')'; - } else { - $sqlRoleIds = 'IS NOT NULL'; - } - - header('Content-Type: text/html; charset=utf-8'); - - // initialize some variables - $gebLink = ''; - $plgLink = ''; - $currentMonth = ''; - $currentYear = ''; - $today = 0; - - if ($getDateId !== '') { - // Read Date ID or generate current month and year - $currentMonth = substr($getDateId, 0, 2); - $currentYear = substr($getDateId, 2, 4); - $_SESSION['plugin_calendar_last_month'] = $currentMonth . $currentYear; - } elseif (isset($_SESSION['plugin_calendar_last_month'])) { - // Show last selected month - $currentMonth = substr($_SESSION['plugin_calendar_last_month'], 0, 2); - $currentYear = substr($_SESSION['plugin_calendar_last_month'], 2, 4); - } else { - // show current month - $currentMonth = date('m'); - $currentYear = date('Y'); - } - - if ($currentMonth === date('m') && $currentYear === date('Y')) { - $today = (int)date('d'); - } - - $lastDayCurrentMonth = (int)date('t', mktime(0, 0, 0, $currentMonth, 1, $currentYear)); - $dateMonthStart = $currentYear . '-' . $currentMonth . '-01 00:00:01'; // add 1 second to ignore all day events that end at 00:00:00 - $dateMonthEnd = $currentYear . '-' . $currentMonth . '-' . $lastDayCurrentMonth . ' 23:59:59'; - $eventsMonthDayArray = array(); - $birthdaysMonthDayArray = array(); - - // query of all events - if ($plg_ter_aktiv) { - $catIdParams = array_merge(array(0), $gCurrentUser->getAllVisibleCategories('EVT')); - $queryParams = array_merge($catIdParams, array($dateMonthEnd, $dateMonthStart)); - - // check if special calendars should be shown - if (in_array('all', $plg_kal_cat, true)) { - // show all calendars - $sqlSyntax = ''; - } else { - // show only calendars of the parameter $plg_kal_cat - $sqlSyntax = ' AND cat_name IN (' . Database::getQmForValues($plg_kal_cat) . ')'; - $queryParams = array_merge($queryParams, $plg_kal_cat); - } - - $sql = 'SELECT DISTINCT dat_id, dat_cat_id, cat_name, dat_begin, dat_end, dat_all_day, dat_location, dat_headline - FROM ' . TBL_EVENTS . ' - INNER JOIN ' . TBL_CATEGORIES . ' - ON cat_id = dat_cat_id - WHERE cat_id IN (' . Database::getQmForValues($catIdParams) . ') - AND dat_begin <= ? -- $dateMonthEnd - AND dat_end >= ? -- $dateMonthStart - ' . $sqlSyntax . ' - ORDER BY dat_begin ASC'; - $datesStatement = $gDb->queryPrepared($sql, $queryParams); - - while ($row = $datesStatement->fetch()) { - $startDate = new DateTime($row['dat_begin']); - $endDate = new DateTime($row['dat_end']); - - // set custom name of plugin for calendar or use default Admidio name - if ($plg_kal_cat_show) { - if ($row['cat_name'][3] === '_') { - $calendarName = $gL10n->get($row['cat_name']); - } else { - $calendarName = $row['cat_name']; - } - $row['dat_headline'] = $calendarName . ': ' . $row['dat_headline']; - } - - if ($startDate->format('Y-m-d') === $endDate->format('Y-m-d')) { - // event only within one day - $eventsMonthDayArray[$startDate->format('j')][] = array( - 'dat_id' => $row['dat_id'], - 'time' => $startDate->format($gSettingsManager->getString('system_time')), - 'all_day' => $row['dat_all_day'], - 'location' => $row['dat_location'], - 'headline' => $row['dat_headline'], - 'one_day' => true - ); - } else { - // event within several days - - if ($startDate->format('m') !== $currentMonth) { - $firstDay = 1; - } else { - $firstDay = $startDate->format('j'); - } - - if ($endDate->format('m') !== $currentMonth) { - $lastDay = $lastDayCurrentMonth; - } else { - $lastDay = $endDate->format('j'); - } - - // now add event to every relevant day of month - for ($i = $firstDay; $i <= $lastDay; ++$i) { - $eventsMonthDayArray[$i][] = array( - 'dat_id' => $row['dat_id'], - 'time' => $startDate->format($gSettingsManager->getString('system_time')), - 'all_day' => $row['dat_all_day'], - 'location' => $row['dat_location'], - 'headline' => $row['dat_headline'], - 'one_day' => false - ); - } - } - } - } - - // query of all birthdays - if ($plg_geb_aktiv) { - if (DB_ENGINE === Database::PDO_ENGINE_PGSQL) { - $sqlYearOfBirthday = ' EXTRACT(YEAR FROM TO_TIMESTAMP(birthday.usd_value, \'YYYY-MM-DD\')) '; - $sqlMonthOfBirthday = ' EXTRACT(MONTH FROM TO_TIMESTAMP(birthday.usd_value, \'YYYY-MM-DD\')) '; - $sqlDayOfBirthday = ' EXTRACT(DAY FROM TO_TIMESTAMP(birthday.usd_value, \'YYYY-MM-DD\')) '; - } else { - $sqlYearOfBirthday = ' YEAR(birthday.usd_value) '; - $sqlMonthOfBirthday = ' MONTH(birthday.usd_value) '; - $sqlDayOfBirthday = ' DayOfMonth(birthday.usd_value) '; - } - - switch ($plg_geb_displayNames) { - case 1: - $sqlOrderName = 'first_name'; - break; - case 2: - $sqlOrderName = 'last_name'; - break; - case 0: // fallthrough - default: - $sqlOrderName = 'last_name, first_name'; - } - - // database query for all birthdays of this month - $sql = 'SELECT DISTINCT - usr_id, last_name.usd_value AS last_name, first_name.usd_value AS first_name, birthday.usd_value AS birthday, - ' . $sqlYearOfBirthday . ' AS birthday_year, ' . $sqlMonthOfBirthday . ' AS birthday_month, - ' . $sqlDayOfBirthday . ' AS birthday_day - FROM ' . TBL_MEMBERS . ' - INNER JOIN ' . TBL_ROLES . ' - ON rol_id = mem_rol_id - INNER JOIN ' . TBL_CATEGORIES . ' - ON cat_id = rol_cat_id - INNER JOIN ' . TBL_USERS . ' - ON usr_id = mem_usr_id - INNER JOIN ' . TBL_USER_DATA . ' AS birthday - ON birthday.usd_usr_id = usr_id - AND birthday.usd_usf_id = ? -- $gProfileFields->getProperty(\'BIRTHDAY\', \'usf_id\') - AND ' . $sqlMonthOfBirthday . ' = ? -- $currentMonth - LEFT JOIN ' . TBL_USER_DATA . ' AS last_name - ON last_name.usd_usr_id = usr_id - AND last_name.usd_usf_id = ? -- $gProfileFields->getProperty(\'LAST_NAME\', \'usf_id\') - LEFT JOIN ' . TBL_USER_DATA . ' AS first_name - ON first_name.usd_usr_id = usr_id - AND first_name.usd_usf_id = ? -- $gProfileFields->getProperty(\'FIRST_NAME\', \'usf_id\') - WHERE usr_valid = true - AND cat_org_id = ? -- $gCurrentOrgId - AND rol_id ' . $sqlRoleIds . ' - AND mem_begin <= ? -- DATE_NOW - AND mem_end > ? -- DATE_NOW - ORDER BY birthday_year DESC, birthday_month DESC, birthday_day DESC, ' . $sqlOrderName; - - $queryParams = array( - $gProfileFields->getProperty('BIRTHDAY', 'usf_id'), - $currentMonth, - $gProfileFields->getProperty('LAST_NAME', 'usf_id'), - $gProfileFields->getProperty('FIRST_NAME', 'usf_id'), - $gCurrentOrgId, - DATE_NOW, - DATE_NOW - ); - $birthdayStatement = $gDb->queryPrepared($sql, $queryParams); - - while ($row = $birthdayStatement->fetch()) { - $birthdayDate = new DateTime($row['birthday']); - - switch ($plg_geb_displayNames) { - case 1: - $name = $row['first_name']; - break; - case 2: - $name = $row['last_name']; - break; - case 0: // fallthrough - default: - $name = $row['last_name'] . ($row['last_name'] ? ', ' : '') . $row['first_name']; - } - - $birthdaysMonthDayArray[$birthdayDate->format('j')][] = array( - 'year' => $birthdayDate->format('Y'), - 'age' => $currentYear - $birthdayDate->format('Y'), - 'name' => $name - ); - } - } - - // Kalender erstellen - $firstWeekdayOfMonth = (int)date('w', mktime(0, 0, 0, $currentMonth, 1, $currentYear)); - $months = explode(',', $gL10n->get('PLG_CALENDAR_MONTH')); - - if ($firstWeekdayOfMonth === 0) { - $firstWeekdayOfMonth = 7; - } - - $tableContent = ''; - $i = 1; - while ($i < $firstWeekdayOfMonth) { - $tableContent .= ' '; - ++$i; - } - - $currentDay = 1; - $boolNewStart = false; - - while ($currentDay <= $lastDayCurrentMonth) { - $terLink = ''; - $gebLink = ''; - $htmlContent = ''; - $textContent = ''; - $hasEvents = false; - $hasBirthdays = false; - $countEvents = 0; - - $dateObj = DateTime::createFromFormat('Y-m-j', $currentYear . '-' . $currentMonth . '-' . $currentDay); - - // add events to the calendar - if ($plg_ter_aktiv) { - // only show events in dependence of the events module view settings - if (array_key_exists($currentDay, $eventsMonthDayArray) - && ($gSettingsManager->getInt('events_module_enabled') === 1 - || ($gSettingsManager->getInt('events_module_enabled') === 2 && $gValidLogin))) { - $hasEvents = true; - - foreach ($eventsMonthDayArray[$currentDay] as $eventArray) { - if ($eventArray['location'] !== '') { - $eventArray['location'] = ', ' . $eventArray['location']; - } - - if ($htmlContent !== '') { - $htmlContent .= '
'; - } - if ($eventArray['all_day'] == 1) { - if ($eventArray['one_day']) { - $htmlContent .= '' . $gL10n->get('SYS_ALL_DAY') . ' ' . $eventArray['headline'] . $eventArray['location']; - $textContent .= $gL10n->get('SYS_ALL_DAY') . ' ' . $eventArray['headline'] . $eventArray['location']; - } else { - $htmlContent .= '' . $gL10n->get('PLG_CALENDAR_SEVERAL_DAYS') . ' ' . $eventArray['headline'] . $eventArray['location']; - $textContent .= $gL10n->get('PLG_CALENDAR_SEVERAL_DAYS') . ' ' . $eventArray['headline'] . $eventArray['location']; - } - } else { - $htmlContent .= '' . $eventArray['time'] . ' ' . $gL10n->get('SYS_CLOCK') . ' ' . $eventArray['headline'] . $eventArray['location']; - $textContent .= $eventArray['time'] . ' ' . $gL10n->get('SYS_CLOCK') . ' ' . $eventArray['headline'] . $eventArray['location']; - } - ++$countEvents; - } - - if ($countEvents > 0) { - $plgLink = SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/events/events.php', array('date_from' => $dateObj->format('Y-m-d'), 'date_to' => $dateObj->format('Y-m-d'))); - } - } - } - - // add users birthdays to the calendar - if ($plg_geb_aktiv) { - if (array_key_exists($currentDay, $birthdaysMonthDayArray) && $plgCalendarShowNames) { - foreach ($birthdaysMonthDayArray[$currentDay] as $birthdayArray) { - $hasBirthdays = true; - - if ($htmlContent !== '') { - $htmlContent .= '
'; - $textContent .= ', '; - } - - if ($plg_geb_icon) { - $icon = ''; - } else { - $icon = ''; - } - - $htmlContent .= $icon . $birthdayArray['name'] . ' (' . $birthdayArray['age'] . ')'; - $textContent .= $birthdayArray['name'] . ' (' . $birthdayArray['age'] . ')'; - } - } - } - - // First pre-assignment of the weekday classes - $plgLinkClassSaturday = 'plgCalendarSaturday'; - $plgLinkClassSunday = 'plgCalendarSunday'; - $plgLinkClassWeekday = 'plgCalendarDay'; - - if (!$hasEvents && $hasBirthdays) { // no events but birthdays - $plgLinkClass = 'geb'; - $plgLinkClassSaturday .= ' plgCalendarBirthDay'; - $plgLinkClassSunday .= ' plgCalendarBirthDay'; - $plgLinkClassWeekday .= ' plgCalendarBirthDay'; - } - - if ($hasEvents && !$hasBirthdays) { // events but no birthdays - $plgLinkClass = 'date'; - $plgLinkClassSaturday .= ' plgCalendarDateDay'; - $plgLinkClassSunday .= ' plgCalendarDateDay'; - $plgLinkClassWeekday .= ' plgCalendarDateDay'; - } - - if ($hasEvents && $hasBirthdays) { // events and birthdays - $plgLinkClass = 'merge'; - $plgLinkClassSaturday .= ' plgCalendarMergeDay'; - $plgLinkClassSunday .= ' plgCalendarMergeDay'; - $plgLinkClassWeekday .= ' plgCalendarMergeDay'; - } - - if ($boolNewStart) { - $tableContent .= ''; - $boolNewStart = false; - } - $rest = ($currentDay + $firstWeekdayOfMonth - 1) % 7; - if ($currentDay === $today) { - $tableContent .= ''; - } elseif ($rest === 6) { - $tableContent .= ''; - } elseif ($rest === 0) { - $tableContent .= ''; - } else { - $tableContent .= ''; - } - - if ($currentDay === $today || $hasEvents || $hasBirthdays) { - if (!$hasEvents && $hasBirthdays) { - // Switch off link URL for birthday by #. - $plgLink = '#'; - } - - if ($hasEvents || $hasBirthdays) { - if ($terLink !== '' && $gebLink !== '') { - $gebLink = '&' . $gebLink; - } - - // plg_link_class bestimmt das Erscheinungsbild des jeweiligen Links - $tableContent .= '' . $currentDay . ''; - } elseif ($currentDay === $today) { - $tableContent .= '' . $currentDay . ''; - } - } elseif ($rest === 6) { - $tableContent .= '' . $currentDay . ''; - } elseif ($rest === 0) { - $tableContent .= '' . $currentDay . ''; - } else { - $tableContent .= $currentDay; - } - $tableContent .= ''; - if ($rest === 0 || $currentDay === $lastDayCurrentMonth) { - $tableContent .= ''; - $boolNewStart = true; - } - - ++$currentDay; - } - - $calendarPlugin->assignTemplateVariable('pluginFolder', $pluginFolder); - $calendarPlugin->assignTemplateVariable('monthYearHeadline', $months[(int) $currentMonth - 1] . ' ' . $currentYear); - $calendarPlugin->assignTemplateVariable('monthYear', $currentMonth . $currentYear); - $calendarPlugin->assignTemplateVariable('currentMonthYear', date('mY')); - $calendarPlugin->assignTemplateVariable('dateIdLastMonth', date('mY', mktime(0, 0, 0, $currentMonth - 1, 1, $currentYear))); - $calendarPlugin->assignTemplateVariable('dateIdNextMonth', date('mY', mktime(0, 0, 0, $currentMonth + 1, 1, $currentYear))); - $calendarPlugin->assignTemplateVariable('tableContent', $tableContent); + $pluginCalendar = Calendar::getInstance(); + $pluginCalendar->initParams(array('date_id' => $getDateId)); + $pluginCalendar->doRender(isset($page) ? $page : null); - if (isset($page)) { - echo $calendarPlugin->html('plugin.calendar.tpl'); - } else { - $calendarPlugin->showHtmlPage('plugin.calendar.tpl'); - } } catch (Throwable $e) { echo $e->getMessage(); } diff --git a/adm_plugins/calendar/languages/en.xml b/adm_plugins/calendar/languages/en.xml index bfa4ded60b..360f86d758 100644 --- a/adm_plugins/calendar/languages/en.xml +++ b/adm_plugins/calendar/languages/en.xml @@ -10,4 +10,25 @@ Sa Su Several days + This plugin displays a calendar with all events of the current month. + Calendar + + Show events + If this setting is enabled, events will be displayed in the calendar. (default: true) + Show birthdays + If this setting is enabled, the birthdays of members will be displayed in the calendar. (default: true) + Show birthdays for visitors + If this setting is enabled, the birthdays of members will be displayed for visitors. (default: false) + Show birthday icon + If this setting is enabled, a birthday icon will be displayed in the calendar. (default: true) + Display style for birthday person name + This setting allows you to choose how the names of birthday persons are displayed. (default: First name) + Considered categories + This setting allows you to choose which categories should be considered for events in the calendar. (default: all categories) + Display calendar names + If this setting is enabled, the names of the calendars will be displayed for each event. (default: false) + Allowed roles for content + Here you can select the roles that are allowed to see the content of this plugin. If a user is not part of any selected role only the number of events and birthdays are shown. (default: all roles) + Allowed roles for birhdays + Here you can select the roles which users must have whose birthdays should be shown. (default: all roles) diff --git a/adm_plugins/calendar/templates/preferences.plugin.calendar.tpl b/adm_plugins/calendar/templates/preferences.plugin.calendar.tpl new file mode 100644 index 0000000000..96062629d5 --- /dev/null +++ b/adm_plugins/calendar/templates/preferences.plugin.calendar.tpl @@ -0,0 +1,20 @@ +
+ + {include 'sys-template-parts/form.input.tpl' data=$elements['adm_csrf_token']} + {include 'sys-template-parts/form.select.tpl' data=$elements['calendar_plugin_enabled']} + {include 'sys-template-parts/form.checkbox.tpl' data=$elements['calendar_show_events']} + {include 'sys-template-parts/form.checkbox.tpl' data=$elements['calendar_show_birthdays']} + {include 'sys-template-parts/form.checkbox.tpl' data=$elements['calendar_show_birthdays_to_guests']} + {include 'sys-template-parts/form.checkbox.tpl' data=$elements['calendar_show_birthday_icon']} + {include 'sys-template-parts/form.select.tpl' data=$elements['calendar_show_birthday_names']} + {include 'sys-template-parts/form.select.tpl' data=$elements['calendar_show_categories']} + {include 'sys-template-parts/form.checkbox.tpl' data=$elements['calendar_show_categories_names']} + {include 'sys-template-parts/form.select.tpl' data=$elements['calendar_roles_view_plugin']} + {include 'sys-template-parts/form.select.tpl' data=$elements['calendar_roles_sql']} + {include 'sys-template-parts/form.button.tpl' data=$elements['adm_button_save_calendar']} + + +
+{$javascript} \ No newline at end of file diff --git a/src/Infrastructure/Plugins/PluginAbstract.php b/src/Infrastructure/Plugins/PluginAbstract.php index 6789543810..4093f890e8 100644 --- a/src/Infrastructure/Plugins/PluginAbstract.php +++ b/src/Infrastructure/Plugins/PluginAbstract.php @@ -524,4 +524,14 @@ public static function doUpdate() : bool // e.g.: $componentUpdateHandle->doUpdateSteps(); return true; } + + public static function initParams(array $params = array()) : bool + { + if (!is_array($params)) + { + throw new InvalidArgumentException('Params must be an "array".'); + } + + return true; + } } \ No newline at end of file diff --git a/src/Infrastructure/Plugins/PluginInterface.php b/src/Infrastructure/Plugins/PluginInterface.php index 7ad8fe9f3a..f9c09da8e5 100644 --- a/src/Infrastructure/Plugins/PluginInterface.php +++ b/src/Infrastructure/Plugins/PluginInterface.php @@ -123,6 +123,12 @@ public static function doUninstall(array $options = array()) : bool; */ public static function doUpdate() : bool; + /** + * @throws Exception + * @return void + */ + public static function initParams(array $params = array()) : bool; + /** * @param PagePresenter $page * @throws InvalidArgumentException diff --git a/themes/simple/templates/modules/plugins.list.tpl b/themes/simple/templates/modules/plugins.list.tpl index ee86f33aaf..0d773cf771 100644 --- a/themes/simple/templates/modules/plugins.list.tpl +++ b/themes/simple/templates/modules/plugins.list.tpl @@ -14,7 +14,7 @@ {foreach $list as $pluginNode} - + {$pluginNode.name} From 88c25ad1062eb5983ad41faccc7c847a284dbe88 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 23 Jul 2025 16:15:22 +0200 Subject: [PATCH 017/109] rebase event-list overview-plugin to use PluginManager --- adm_plugins/AnnouncementList/languages/en.xml | 2 +- adm_plugins/EventList/EventList.json | 54 +++++ adm_plugins/EventList/classes/EventList.php | 198 ++++++++++++++++++ .../EventListPreferencesPresenter.php | 114 ++++++++++ .../EventList/db_scripts/update_1_0.xml | 6 + adm_plugins/EventList/index.php | 24 +++ .../languages/bg.xml | 0 .../languages/da.xml | 0 .../languages/de-DE.xml | 0 .../languages/de.xml | 0 .../languages/el.xml | 0 adm_plugins/EventList/languages/en.xml | 21 ++ .../languages/es.xml | 0 .../languages/et.xml | 0 .../languages/fi.xml | 0 .../languages/fr.xml | 0 .../languages/hu.xml | 0 .../languages/nb.xml | 0 .../languages/nl.xml | 0 .../languages/pl.xml | 0 .../languages/pt-BR.xml | 0 .../languages/pt.xml | 0 .../languages/ru.xml | 0 .../languages/sv.xml | 0 .../languages/uk.xml | 0 .../languages/zh.xml | 0 .../templates/plugin.event-list.tpl | 0 .../preferences.plugin.event-list.tpl | 17 ++ adm_plugins/event-list/config_sample.php | 41 ---- adm_plugins/event-list/index.php | 148 ------------- adm_plugins/event-list/languages/en.xml | 6 - src/Infrastructure/Plugins/PluginAbstract.php | 10 + 32 files changed, 445 insertions(+), 196 deletions(-) create mode 100644 adm_plugins/EventList/EventList.json create mode 100644 adm_plugins/EventList/classes/EventList.php create mode 100644 adm_plugins/EventList/classes/Presenter/EventListPreferencesPresenter.php create mode 100644 adm_plugins/EventList/db_scripts/update_1_0.xml create mode 100644 adm_plugins/EventList/index.php rename adm_plugins/{event-list => EventList}/languages/bg.xml (100%) rename adm_plugins/{event-list => EventList}/languages/da.xml (100%) rename adm_plugins/{event-list => EventList}/languages/de-DE.xml (100%) rename adm_plugins/{event-list => EventList}/languages/de.xml (100%) rename adm_plugins/{event-list => EventList}/languages/el.xml (100%) create mode 100644 adm_plugins/EventList/languages/en.xml rename adm_plugins/{event-list => EventList}/languages/es.xml (100%) rename adm_plugins/{event-list => EventList}/languages/et.xml (100%) rename adm_plugins/{event-list => EventList}/languages/fi.xml (100%) mode change 100755 => 100644 rename adm_plugins/{event-list => EventList}/languages/fr.xml (100%) rename adm_plugins/{event-list => EventList}/languages/hu.xml (100%) rename adm_plugins/{event-list => EventList}/languages/nb.xml (100%) rename adm_plugins/{event-list => EventList}/languages/nl.xml (100%) rename adm_plugins/{event-list => EventList}/languages/pl.xml (100%) rename adm_plugins/{event-list => EventList}/languages/pt-BR.xml (100%) rename adm_plugins/{event-list => EventList}/languages/pt.xml (100%) rename adm_plugins/{event-list => EventList}/languages/ru.xml (100%) rename adm_plugins/{event-list => EventList}/languages/sv.xml (100%) rename adm_plugins/{event-list => EventList}/languages/uk.xml (100%) rename adm_plugins/{event-list => EventList}/languages/zh.xml (100%) rename adm_plugins/{event-list => EventList}/templates/plugin.event-list.tpl (100%) create mode 100644 adm_plugins/EventList/templates/preferences.plugin.event-list.tpl delete mode 100644 adm_plugins/event-list/config_sample.php delete mode 100644 adm_plugins/event-list/index.php delete mode 100644 adm_plugins/event-list/languages/en.xml diff --git a/adm_plugins/AnnouncementList/languages/en.xml b/adm_plugins/AnnouncementList/languages/en.xml index e02039f428..1bf9ad93ca 100644 --- a/adm_plugins/AnnouncementList/languages/en.xml +++ b/adm_plugins/AnnouncementList/languages/en.xml @@ -11,7 +11,7 @@ Characters before line break Maximum number of characters in a word before a line break should be performed. (0: deactivates line break, default: 0) Displayed categories - If you only want to show announcements of a special category you can select the categories here. (default: All) + If you only want to show announcements of a special category you can select the categories here. (default: all categories) Show full description If this setting is enabled the full content of the description will be shown. Otherwise only a text preview will be displayed. (default: false) Preview text diff --git a/adm_plugins/EventList/EventList.json b/adm_plugins/EventList/EventList.json new file mode 100644 index 0000000000..7350c294c7 --- /dev/null +++ b/adm_plugins/EventList/EventList.json @@ -0,0 +1,54 @@ +{ + "name": "PLG_EVENT_LIST_PLUGIN_NAME", + "description": "PLG_EVENT_LIST_PLUGIN_DESCRIPTION", + "version": "1.0.0", + "author": "Admidio Team", + "url": "https://www.admidio.org", + "icon": "bi-calendar-week-fill", + "mainFile": "index.php", + "dependencies": [], + "defaultConfig": { + "event_list_plugin_enabled": { + "name": "ORG_ACCESS_TO_PLUGIN", + "description": "ORG_ACCESS_TO_PLUGIN_DESC", + "type": "integer", + "value" : 1 + }, + "event_list_events_count": { + "name": "PLG_EVENT_LIST_PREFERENCES_EVENTS_COUNT", + "description": "PLG_EVENT_LIST_PREFERENCES_EVENTS_COUNT_DESC", + "type": "integer", + "value" : 2 + }, + "event_list_show_event_date_end": { + "name": "PLG_EVENT_LIST_PREFERENCES_SHOW_EVENT_DATE_END", + "description": "PLG_EVENT_LIST_PREFERENCES_SHOW_EVENT_DATE_END_DESC", + "type": "boolean", + "value" : true + }, + "event_list_show_preview_chars": { + "name": "PLG_EVENT_LIST_PREFERENCES_SHOW_PREVIEW_CHARS", + "description": "PLG_EVENT_LIST_PREFERENCES_SHOW_PREVIEW_CHARS_DESC", + "type": "integer", + "value" : 70 + }, + "event_list_show_full_description": { + "name": "PLG_EVENT_LIST_PREFERENCES_SHOW_FULL_DESCRIPTION", + "description": "PLG_EVENT_LIST_PREFERENCES_SHOW_FULL_DESCRIPTION_DESC", + "type": "boolean", + "value" : false + }, + "event_list_chars_before_linebreak": { + "name": "PLG_EVENT_LIST_PREFERENCES_CHARS_BEFORE_LINEBREAK", + "description": "PLG_EVENT_LIST_PREFERENCES_CHARS_BEFORE_LINEBREAK_DESC", + "type": "integer", + "value" : 0 + }, + "event_list_displayed_categories": { + "name": "PLG_EVENT_LIST_PREFERENCES_DISPLAYED_CATEGORIES", + "description": "PLG_EVENT_LIST_PREFERENCES_DISPLAYED_CATEGORIES_DESC", + "type": "array", + "value" : ["All"] + } + } +} \ No newline at end of file diff --git a/adm_plugins/EventList/classes/EventList.php b/adm_plugins/EventList/classes/EventList.php new file mode 100644 index 0000000000..5e85722234 --- /dev/null +++ b/adm_plugins/EventList/classes/EventList.php @@ -0,0 +1,198 @@ +getAllVisibleCategories('EVT'); + } + return $config; + } + + /** + * Get the plugin configuration values + * @return array Returns the plugin configuration values + */ + public static function getPluginConfigValues() : array + { + global $gCurrentUser; + + // get the plugin config values from the parent class + $config = parent::getPluginConfigValues(); + + // if the key equals 'event_list_displayed_categories' and the value is still the default value, retrieve the categories from the database + if (array_key_exists('event_list_displayed_categories', $config) && $config['event_list_displayed_categories'] === self::$defaultConfig['event_list_displayed_categories']['value']) { + $config['event_list_displayed_categories'] = $gCurrentUser->getAllVisibleCategories('EVT'); + } + + return $config; + } + + private static function getEventsData() : array + { + global $gSettingsManager, $gCurrentUser, $gDb, $gL10n; + + $config = self::getPluginConfigValues(); + + if (!is_array($config['event_list_displayed_categories']) || empty($config['event_list_displayed_categories'])) { + $plgSqlCategories = ''; + } else { + $plgSqlCategories = ' AND cat_id IN (' . Database::getQmForValues($config['event_list_displayed_categories']) . ') '; + } + + // read events from database + $catIdParams = array_merge(array(0), $gCurrentUser->getAllVisibleCategories('EVT')); + + $sql = 'SELECT cat.*, evt.* + FROM ' . TBL_EVENTS . ' AS evt + INNER JOIN ' . TBL_CATEGORIES . ' AS cat + ON cat_id = dat_cat_id + WHERE cat_id IN (' . Database::getQmForValues($catIdParams) . ') + AND dat_begin >= ? -- DATETIME_NOW + ' . $plgSqlCategories . ' + ORDER BY dat_begin + LIMIT ' . $config['event_list_events_count']; + + $pdoStatement = $gDb->queryPrepared($sql, array_merge($catIdParams, array(DATETIME_NOW), $config['event_list_displayed_categories'])); + $plgEventsList = $pdoStatement->fetchAll(); + + $eventsArray = array(); + + if ($pdoStatement->rowCount() > 0) { + // get events data + $plgEvent = new Event($gDb); + + foreach ($plgEventsList as $plgRow) { + $plgEvent->clear(); + $plgEvent->setArray($plgRow); + + if ($config['event_list_chars_before_linebreak'] > 0) { + // Interrupt words of headline if they are too long + $plgNewHeadline = ''; + + $plgWords = explode(' ', $plgEvent->getValue('dat_headline')); + + foreach ($plgWords as $plgValue) { + if (strlen($plgValue) > $config['event_list_chars_before_linebreak']) { + $plgNewHeadline .= ' ' . substr($plgValue, 0, $config['event_list_chars_before_linebreak']) . '-
' . + substr($plgValue, $config['event_list_chars_before_linebreak']); + } else { + $plgNewHeadline .= ' ' . $plgValue; + } + } + } else { + $plgNewHeadline = $plgEvent->getValue('dat_headline'); + } + + // show preview text + if ($config['event_list_show_full_description'] === 1) { + $plgNewDescription = $plgEvent->getValue('dat_description'); + } elseif ($config['event_list_show_preview_chars'] > 0) { + // remove all html tags except some format tags + $plgNewDescription = strip_tags($plgEvent->getValue('dat_description')); + + // read first x chars of text and additional 15 chars. Then search for last space and cut the text there + $plgNewDescription = substr($plgNewDescription, 0, $config['event_list_show_preview_chars'] + 15); + $plgNewDescription = substr($plgNewDescription, 0, strrpos($plgNewDescription, ' ')) . ' + »'; + } + + $eventsArray[] = array( + 'uuid' => $plgEvent->getValue('dat_uuid'), + 'dateTimePeriod' => $plgEvent->getDateTimePeriod($config['event_list_show_event_date_end']), + 'headline' => $plgNewHeadline, + 'description' => $plgNewDescription + ); + } + } + return $eventsArray; + } + + /** + * @param PagePresenter $page + * @throws InvalidArgumentException + * @throws Exception + * @return bool + */ + public static function doRender($page = null) : bool + { + global $gSettingsManager, $gL10n, $gValidLogin; + + // show the event list + try { + $rootPath = dirname(__DIR__, 3); + $pluginFolder = basename(self::$pluginPath); + + require_once($rootPath . '/system/common.php'); + + $eventListPlugin = new Overview($pluginFolder); + + // check if the plugin is installed + if (!self::isInstalled()) { + throw new InvalidArgumentException($gL10n->get('SYS_PLUGIN_NOT_INSTALLED')); + } + + if ($gSettingsManager->getInt('events_module_enabled') > 0) { + if (($gSettingsManager->getInt('events_module_enabled') === 1 || ($gSettingsManager->getInt('events_module_enabled') === 2 && $gValidLogin)) && + ($gSettingsManager->getInt('event_list_plugin_enabled') === 1 || ($gSettingsManager->getInt('event_list_plugin_enabled') === 2 && $gValidLogin))) { + $eventsArray = self::getEventsData(); + if (!empty($eventsArray)) { + $eventListPlugin->assignTemplateVariable('events', $eventsArray); + } else { + $eventListPlugin->assignTemplateVariable('message',$gL10n->get('SYS_NO_ENTRIES')); + } + } else { + $eventListPlugin->assignTemplateVariable('message',$gL10n->get('PLG_EVENT_LIST_NO_ENTRIES_VISITORS')); + } + if (isset($page)) { + echo $eventListPlugin->html('plugin.event-list.tpl'); + } else { + $eventListPlugin->showHtmlPage('plugin.event-list.tpl'); + } + } + } catch (Throwable $e) { + echo $e->getMessage(); + } + + return true; + } +} \ No newline at end of file diff --git a/adm_plugins/EventList/classes/Presenter/EventListPreferencesPresenter.php b/adm_plugins/EventList/classes/Presenter/EventListPreferencesPresenter.php new file mode 100644 index 0000000000..d7277ccf29 --- /dev/null +++ b/adm_plugins/EventList/classes/Presenter/EventListPreferencesPresenter.php @@ -0,0 +1,114 @@ + 'save', 'panel' => 'event_list')), + null, + array('class' => 'form-preferences') + ); + $selectBoxEntries = array( + '0' => $gL10n->get('SYS_DISABLED'), + '1' => $gL10n->get('SYS_ENABLED'), + '2' => $gL10n->get('ORG_ONLY_FOR_REGISTERED_USER') + ); + $formEventList->addSelectBox( + 'event_list_plugin_enabled', + Language::translateIfTranslationStrId($formValues['event_list_plugin_enabled']['name']), + $selectBoxEntries, + array('defaultValue' => $formValues['event_list_plugin_enabled']['value'], 'showContextDependentFirstEntry' => false, 'helpTextId' => $formValues['event_list_plugin_enabled']['description']) + ); + $formEventList->addInput( + 'event_list_events_count', + Language::translateIfTranslationStrId($formValues['event_list_events_count']['name']), + $formValues['event_list_events_count']['value'], + array('type' => 'number', 'minNumber' => 0, 'maxNumber' => 20, 'step' => 1, 'helpTextId' => $formValues['event_list_events_count']['description']) + ); + $formEventList->addCheckbox( + 'event_list_show_event_date_end', + Language::translateIfTranslationStrId($formValues['event_list_show_event_date_end']['name']), + $formValues['event_list_show_event_date_end']['value'], + array('helpTextId' => $formValues['event_list_show_event_date_end']['description']) + ); + $formEventList->addInput( + 'event_list_show_preview_chars', + Language::translateIfTranslationStrId($formValues['event_list_show_preview_chars']['name']), + $formValues['event_list_show_preview_chars']['value'], + array('type' => 'number', 'minNumber' => 0, 'step' => 1, 'helpTextId' => $formValues['event_list_show_preview_chars']['description']) + ); + $formEventList->addCheckbox( + 'event_list_show_full_description', + Language::translateIfTranslationStrId($formValues['event_list_show_full_description']['name']), + $formValues['event_list_show_full_description']['value'], + array('helpTextId' => $formValues['event_list_show_full_description']['description']) + ); + $formEventList->addInput( + 'event_list_chars_before_linebreak', + Language::translateIfTranslationStrId($formValues['event_list_chars_before_linebreak']['name']), + $formValues['event_list_chars_before_linebreak']['value'], + array('type' => 'number', 'minNumber' => 0, 'step' => 1, 'helpTextId' => $formValues['event_list_chars_before_linebreak']['description']) + ); + + $catIdParams = array_merge(array(0), $gCurrentUser->getAllVisibleCategories('EVT')); + $sql = 'SELECT cat.cat_id, cat.cat_name + FROM ' . TBL_EVENTS . ' AS evt + INNER JOIN ' . TBL_CATEGORIES . ' AS cat + WHERE cat_id IN (' . $gDb->getQmForValues($catIdParams) . ') + AND dat_begin >= ? -- DATETIME_NOW + ORDER BY dat_timestamp_create DESC'; + $sqlData = array( + 'query' => $sql, + 'params' => array_merge($catIdParams, array(DATETIME_NOW)) + ); + + $formEventList->addSelectBoxFromSql( + 'event_list_displayed_categories', + Language::translateIfTranslationStrId($formValues['event_list_displayed_categories']['name']), + $gDb, + $sqlData, + array('defaultValue' => $formValues['event_list_displayed_categories']['value'], 'showContextDependentFirstEntry' => false, 'helpTextId' => $formValues['event_list_displayed_categories']['description'], 'multiselect' => true, 'maximumSelectionNumber' => count($gCurrentUser->getAllVisibleCategories('ANN'))) + ); + $formEventList->addSubmitButton( + 'adm_button_save_event_list', + $gL10n->get('SYS_SAVE'), + array('icon' => 'bi-check-lg', 'class' => 'offset-sm-3') + ); + + $formEventList->addToSmarty($smarty); + $gCurrentSession->addFormObject($formEventList); + return $smarty->fetch($pluginEventList::getPluginPath() . '/templates/preferences.plugin.event-list.tpl'); + } +} \ No newline at end of file diff --git a/adm_plugins/EventList/db_scripts/update_1_0.xml b/adm_plugins/EventList/db_scripts/update_1_0.xml new file mode 100644 index 0000000000..2b3aa609bc --- /dev/null +++ b/adm_plugins/EventList/db_scripts/update_1_0.xml @@ -0,0 +1,6 @@ + + + UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'EventList' + UPDATE %PREFIX%_components SET com_plg_sequence = 7 WHERE com_type = 'ADM_PLUGIN' AND com_name_intern = 'EventList' + stop + diff --git a/adm_plugins/EventList/index.php b/adm_plugins/EventList/index.php new file mode 100644 index 0000000000..7a0feb32a8 --- /dev/null +++ b/adm_plugins/EventList/index.php @@ -0,0 +1,24 @@ +doRender(isset($page) ? $page : null); + +} catch (Throwable $e) { + echo $e->getMessage(); +} diff --git a/adm_plugins/event-list/languages/bg.xml b/adm_plugins/EventList/languages/bg.xml similarity index 100% rename from adm_plugins/event-list/languages/bg.xml rename to adm_plugins/EventList/languages/bg.xml diff --git a/adm_plugins/event-list/languages/da.xml b/adm_plugins/EventList/languages/da.xml similarity index 100% rename from adm_plugins/event-list/languages/da.xml rename to adm_plugins/EventList/languages/da.xml diff --git a/adm_plugins/event-list/languages/de-DE.xml b/adm_plugins/EventList/languages/de-DE.xml similarity index 100% rename from adm_plugins/event-list/languages/de-DE.xml rename to adm_plugins/EventList/languages/de-DE.xml diff --git a/adm_plugins/event-list/languages/de.xml b/adm_plugins/EventList/languages/de.xml similarity index 100% rename from adm_plugins/event-list/languages/de.xml rename to adm_plugins/EventList/languages/de.xml diff --git a/adm_plugins/event-list/languages/el.xml b/adm_plugins/EventList/languages/el.xml similarity index 100% rename from adm_plugins/event-list/languages/el.xml rename to adm_plugins/EventList/languages/el.xml diff --git a/adm_plugins/EventList/languages/en.xml b/adm_plugins/EventList/languages/en.xml new file mode 100644 index 0000000000..ec1f6278dc --- /dev/null +++ b/adm_plugins/EventList/languages/en.xml @@ -0,0 +1,21 @@ + + + All events + Events + There are no events available for visitors. Log in to see the events. + This plugin displays a preview list of the latest events on the Overview page. + Event List + + Number of events + Number of events to be displayed. (default: 2) + Show end date + If this setting is enabled the end date and end time of the event will be shown. Otherwise only the start date and start time will be displayed. (default: true) + Characters before line break + Maximum number of characters in a word before a line break should be performed. (0: deactivates line break, default: 0) + Displayed categories + If you only want to show events of a special category you can select the categories here. (default: all categories) + Show full description + If this setting is enabled the full content of the description will be shown. Otherwise only a text preview will be displayed. (default: false) + Preview text + Number of characters of the preview text. (0: no short preview, default: 70) + diff --git a/adm_plugins/event-list/languages/es.xml b/adm_plugins/EventList/languages/es.xml similarity index 100% rename from adm_plugins/event-list/languages/es.xml rename to adm_plugins/EventList/languages/es.xml diff --git a/adm_plugins/event-list/languages/et.xml b/adm_plugins/EventList/languages/et.xml similarity index 100% rename from adm_plugins/event-list/languages/et.xml rename to adm_plugins/EventList/languages/et.xml diff --git a/adm_plugins/event-list/languages/fi.xml b/adm_plugins/EventList/languages/fi.xml old mode 100755 new mode 100644 similarity index 100% rename from adm_plugins/event-list/languages/fi.xml rename to adm_plugins/EventList/languages/fi.xml diff --git a/adm_plugins/event-list/languages/fr.xml b/adm_plugins/EventList/languages/fr.xml similarity index 100% rename from adm_plugins/event-list/languages/fr.xml rename to adm_plugins/EventList/languages/fr.xml diff --git a/adm_plugins/event-list/languages/hu.xml b/adm_plugins/EventList/languages/hu.xml similarity index 100% rename from adm_plugins/event-list/languages/hu.xml rename to adm_plugins/EventList/languages/hu.xml diff --git a/adm_plugins/event-list/languages/nb.xml b/adm_plugins/EventList/languages/nb.xml similarity index 100% rename from adm_plugins/event-list/languages/nb.xml rename to adm_plugins/EventList/languages/nb.xml diff --git a/adm_plugins/event-list/languages/nl.xml b/adm_plugins/EventList/languages/nl.xml similarity index 100% rename from adm_plugins/event-list/languages/nl.xml rename to adm_plugins/EventList/languages/nl.xml diff --git a/adm_plugins/event-list/languages/pl.xml b/adm_plugins/EventList/languages/pl.xml similarity index 100% rename from adm_plugins/event-list/languages/pl.xml rename to adm_plugins/EventList/languages/pl.xml diff --git a/adm_plugins/event-list/languages/pt-BR.xml b/adm_plugins/EventList/languages/pt-BR.xml similarity index 100% rename from adm_plugins/event-list/languages/pt-BR.xml rename to adm_plugins/EventList/languages/pt-BR.xml diff --git a/adm_plugins/event-list/languages/pt.xml b/adm_plugins/EventList/languages/pt.xml similarity index 100% rename from adm_plugins/event-list/languages/pt.xml rename to adm_plugins/EventList/languages/pt.xml diff --git a/adm_plugins/event-list/languages/ru.xml b/adm_plugins/EventList/languages/ru.xml similarity index 100% rename from adm_plugins/event-list/languages/ru.xml rename to adm_plugins/EventList/languages/ru.xml diff --git a/adm_plugins/event-list/languages/sv.xml b/adm_plugins/EventList/languages/sv.xml similarity index 100% rename from adm_plugins/event-list/languages/sv.xml rename to adm_plugins/EventList/languages/sv.xml diff --git a/adm_plugins/event-list/languages/uk.xml b/adm_plugins/EventList/languages/uk.xml similarity index 100% rename from adm_plugins/event-list/languages/uk.xml rename to adm_plugins/EventList/languages/uk.xml diff --git a/adm_plugins/event-list/languages/zh.xml b/adm_plugins/EventList/languages/zh.xml similarity index 100% rename from adm_plugins/event-list/languages/zh.xml rename to adm_plugins/EventList/languages/zh.xml diff --git a/adm_plugins/event-list/templates/plugin.event-list.tpl b/adm_plugins/EventList/templates/plugin.event-list.tpl similarity index 100% rename from adm_plugins/event-list/templates/plugin.event-list.tpl rename to adm_plugins/EventList/templates/plugin.event-list.tpl diff --git a/adm_plugins/EventList/templates/preferences.plugin.event-list.tpl b/adm_plugins/EventList/templates/preferences.plugin.event-list.tpl new file mode 100644 index 0000000000..c3e335c11a --- /dev/null +++ b/adm_plugins/EventList/templates/preferences.plugin.event-list.tpl @@ -0,0 +1,17 @@ +
+ + {include 'sys-template-parts/form.input.tpl' data=$elements['adm_csrf_token']} + {include 'sys-template-parts/form.select.tpl' data=$elements['event_list_plugin_enabled']} + {include 'sys-template-parts/form.input.tpl' data=$elements['event_list_events_count']} + {include 'sys-template-parts/form.checkbox.tpl' data=$elements['event_list_show_event_date_end']} + {include 'sys-template-parts/form.input.tpl' data=$elements['event_list_show_preview_chars']} + {include 'sys-template-parts/form.checkbox.tpl' data=$elements['event_list_show_full_description']} + {include 'sys-template-parts/form.input.tpl' data=$elements['event_list_chars_before_linebreak']} + {include 'sys-template-parts/form.select.tpl' data=$elements['event_list_displayed_categories']} + {include 'sys-template-parts/form.button.tpl' data=$elements['adm_button_save_event_list']} + + +
+{$javascript} \ No newline at end of file diff --git a/adm_plugins/event-list/config_sample.php b/adm_plugins/event-list/config_sample.php deleted file mode 100644 index 184266abaa..0000000000 --- a/adm_plugins/event-list/config_sample.php +++ /dev/null @@ -1,41 +0,0 @@ -getInt('events_module_enabled') > 0) { - // read events from database - $catIdParams = array_merge(array(0), $gCurrentUser->getAllVisibleCategories('EVT')); - - $sql = 'SELECT cat.*, evt.* - FROM ' . TBL_EVENTS . ' AS evt - INNER JOIN ' . TBL_CATEGORIES . ' AS cat - ON cat_id = dat_cat_id - WHERE cat_id IN (' . Database::getQmForValues($catIdParams) . ') - AND dat_begin >= ? -- DATETIME_NOW - ' . $plgSqlCategories . ' - ORDER BY dat_begin - LIMIT ' . $plg_max_number_events_shown; - - $pdoStatement = $gDb->queryPrepared($sql, array_merge($catIdParams, array(DATETIME_NOW), $plg_kal_cat)); - $plgEventList = $pdoStatement->fetchAll(); - - if ($gSettingsManager->getInt('events_module_enabled') === 1 - || ($gSettingsManager->getInt('events_module_enabled') === 2 && $gValidLogin)) { - if ($pdoStatement->rowCount() > 0) { - // get announcements data - $plgEvent = new Event($gDb); - $eventArray = array(); - - foreach ($plgEventList as $plgRow) { - $plgEvent->clear(); - $plgEvent->setArray($plgRow); - - if ($plg_max_char_per_word > 0) { - $plgNewHeadline = ''; - - // Pause words if they are too long - $plgWords = explode(' ', $plgEvent->getValue('dat_headline')); - - foreach ($plgWords as $plgValue) { - if (strlen($plgValue) > $plg_max_char_per_word) { - $plgNewHeadline .= ' ' . substr($plgValue, 0, $plg_max_char_per_word) . '-
' . - substr($plgValue, $plg_max_char_per_word); - } else { - $plgNewHeadline .= ' ' . $plgValue; - } - } - } else { - $plgNewHeadline = $plgEvent->getValue('dat_headline'); - } - - // show preview text - if ($plgShowFullDescription === 1) { - $plgNewDescription = $plgEvent->getValue('dat_description'); - } elseif ($plg_events_show_preview > 0) { - // remove all html tags except some format tags - $plgNewDescription = strip_tags($plgEvent->getValue('dat_description')); - - // read first x chars of text and additional 15 chars. Then search for last space and cut the text there - $plgNewDescription = substr($plgNewDescription, 0, $plg_events_show_preview + 15); - $plgNewDescription = substr($plgNewDescription, 0, strrpos($plgNewDescription, ' ')) . ' - »'; - } - - $eventArray[] = array( - 'uuid' => $plgEvent->getValue('dat_uuid'), - 'dateTimePeriod' => $plgEvent->getDateTimePeriod($plg_show_date_end), - 'headline' => $plgNewHeadline, - 'description' => $plgNewDescription - ); - } - - $eventListPlugin->assignTemplateVariable('events', $eventArray); - } else { - $eventListPlugin->assignTemplateVariable('message',$gL10n->get('SYS_NO_ENTRIES')); - } - } else { - $eventListPlugin->assignTemplateVariable('message',$gL10n->get('PLG_EVENT_LIST_NO_ENTRIES_VISITORS')); - } - - if (isset($page)) { - echo $eventListPlugin->html('plugin.event-list.tpl'); - } else { - $eventListPlugin->showHtmlPage('plugin.event-list.tpl'); - } - } -} catch (Throwable $e) { - echo $e->getMessage(); -} diff --git a/adm_plugins/event-list/languages/en.xml b/adm_plugins/event-list/languages/en.xml deleted file mode 100644 index 1a8d72b8e9..0000000000 --- a/adm_plugins/event-list/languages/en.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - All events - Events - There are no events available for visitors. Log in to see the events. - diff --git a/src/Infrastructure/Plugins/PluginAbstract.php b/src/Infrastructure/Plugins/PluginAbstract.php index 4093f890e8..4b3653b971 100644 --- a/src/Infrastructure/Plugins/PluginAbstract.php +++ b/src/Infrastructure/Plugins/PluginAbstract.php @@ -129,6 +129,16 @@ private function readPluginMetadata() : void */ public static function getInstance() : PluginAbstract { + // reset global variables + self::$pluginComId = 0; + self::$pluginPath = ''; + self::$name = ''; + self::$version = '0.0.0'; + self::$dependencies = array(); + self::$metadata = array(); + self::$defaultConfig = array(); + + // get the class name of the called class $class = get_called_class(); if (!array_key_exists($class, self::$instances)) { From 2e67b35371a0d933a9ffe0222cdc520b57a07362 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 23 Jul 2025 16:16:15 +0200 Subject: [PATCH 018/109] rename official plugin names to match the new folder names --- .gitignore | 16 ++++++++-------- composer.json | 14 +++++++------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index 1b5d377fc2..ef4d661e3b 100644 --- a/.gitignore +++ b/.gitignore @@ -11,15 +11,15 @@ # Only allow commit of official plugins /adm_plugins/* -!/adm_plugins/birthday/ -!/adm_plugins/calendar/ -!/adm_plugins/login_form/ -!/adm_plugins/random_photo/ +!/adm_plugins/Birthday/ +!/adm_plugins/Calendar/ +!/adm_plugins/LoginForm/ +!/adm_plugins/RandomPhoto/ !/adm_plugins/AnnouncementList/ -!/adm_plugins/event-list/ -!/adm_plugins/latest-documents-files/ -!/adm_plugins/who-is-online/ -!/adm_plugins/category_report/ +!/adm_plugins/EventList/ +!/adm_plugins/LatestDocumentsFiles/ +!/adm_plugins/WhoIsOnline/ +!/adm_plugins/CategoryReport/ # Only allow commit of official themes /themes/* diff --git a/composer.json b/composer.json index e7d3e6f3c7..0ee8cdcfb5 100644 --- a/composer.json +++ b/composer.json @@ -69,13 +69,13 @@ "!adm_my_files/mail_templates", "adm_plugins/*", "!adm_plugins/AnnouncementList", - "!adm_plugins/birthday", - "!adm_plugins/calendar", - "!adm_plugins/event-list", - "!adm_plugins/latest-documents-files", - "!adm_plugins/login_form", - "!adm_plugins/random_photo", - "!adm_plugins/who-is-online", + "!adm_plugins/Birthday", + "!adm_plugins/Calendar", + "!adm_plugins/EventList", + "!adm_plugins/LatestDocumentsFiles", + "!adm_plugins/LoginForm", + "!adm_plugins/RandomPhoto", + "!adm_plugins/WhoIsOnline", "demo_data", "!vendor/*", "vendor/maennchen/zipstream-php/test", From dd60f7421112dc2bc37fec236dda575c1e75c15a Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 23 Jul 2025 17:23:08 +0200 Subject: [PATCH 019/109] refactor: improve module status handling and update plugin description --- .../classes/AnnouncementList.php | 13 ++++--- adm_plugins/EventList/classes/EventList.php | 13 ++++--- adm_plugins/birthday/classes/Birthday.php | 35 +++++++++++-------- adm_plugins/calendar/classes/Calendar.php | 27 +++++++------- adm_plugins/calendar/languages/en.xml | 2 +- 5 files changed, 52 insertions(+), 38 deletions(-) diff --git a/adm_plugins/AnnouncementList/classes/AnnouncementList.php b/adm_plugins/AnnouncementList/classes/AnnouncementList.php index 0423097734..0cc9690faf 100644 --- a/adm_plugins/AnnouncementList/classes/AnnouncementList.php +++ b/adm_plugins/AnnouncementList/classes/AnnouncementList.php @@ -182,11 +182,14 @@ public static function doRender($page = null) : bool } else { $announcementListPlugin->assignTemplateVariable('message',$gL10n->get('PLG_ANNOUNCEMENT_LIST_NO_ENTRIES_VISITORS')); } - if (isset($page)) { - echo $announcementListPlugin->html('plugin.announcement-list.tpl'); - } else { - $announcementListPlugin->showHtmlPage('plugin.announcement-list.tpl'); - } + } else { + $announcementListPlugin->assignTemplateVariable('message', $gL10n->get('SYS_MODULE_DISABLED')); + } + + if (isset($page)) { + echo $announcementListPlugin->html('plugin.announcement-list.tpl'); + } else { + $announcementListPlugin->showHtmlPage('plugin.announcement-list.tpl'); } } catch (Throwable $e) { echo $e->getMessage(); diff --git a/adm_plugins/EventList/classes/EventList.php b/adm_plugins/EventList/classes/EventList.php index 5e85722234..63d11371a7 100644 --- a/adm_plugins/EventList/classes/EventList.php +++ b/adm_plugins/EventList/classes/EventList.php @@ -183,11 +183,14 @@ public static function doRender($page = null) : bool } else { $eventListPlugin->assignTemplateVariable('message',$gL10n->get('PLG_EVENT_LIST_NO_ENTRIES_VISITORS')); } - if (isset($page)) { - echo $eventListPlugin->html('plugin.event-list.tpl'); - } else { - $eventListPlugin->showHtmlPage('plugin.event-list.tpl'); - } + } else { + $eventListPlugin->assignTemplateVariable('message', $gL10n->get('SYS_MODULE_DISABLED')); + } + + if (isset($page)) { + echo $eventListPlugin->html('plugin.event-list.tpl'); + } else { + $eventListPlugin->showHtmlPage('plugin.event-list.tpl'); } } catch (Throwable $e) { echo $e->getMessage(); diff --git a/adm_plugins/birthday/classes/Birthday.php b/adm_plugins/birthday/classes/Birthday.php index 774e7d7f8c..a0c327e684 100644 --- a/adm_plugins/birthday/classes/Birthday.php +++ b/adm_plugins/birthday/classes/Birthday.php @@ -389,28 +389,33 @@ public static function doRender($page = null) : bool throw new InvalidArgumentException($gL10n->get('SYS_PLUGIN_NOT_INSTALLED')); } - if ($gSettingsManager->getInt('birthday_plugin_enabled') === 1 || ($gSettingsManager->getInt('birthday_plugin_enabled') === 2 && $gValidLogin)) { - $birthdaysArray = self::getBirthdaysData(); + if ($gSettingsManager->getInt('events_module_enabled') > 0) { + if ($gSettingsManager->getInt('birthday_plugin_enabled') === 1 || ($gSettingsManager->getInt('birthday_plugin_enabled') === 2 && $gValidLogin)) { + $birthdaysArray = self::getBirthdaysData(); - if (!empty($birthdaysArray)) { - if (self::$birthdayShowNames) { - $birthdayPlugin->assignTemplateVariable('birthdays', $birthdaysArray); - } else { - if (count($birthdaysArray) === 1) { - $birthdayPlugin->assignTemplateVariable('message',$gL10n->get('PLG_BIRTHDAY_ONE_MEMBER')); + if (!empty($birthdaysArray)) { + if (self::$birthdayShowNames) { + $birthdayPlugin->assignTemplateVariable('birthdays', $birthdaysArray); } else { - $birthdayPlugin->assignTemplateVariable('message',$gL10n->get('PLG_BIRTHDAY_MORE_MEMBERS', array(count($birthdaysArray)))); + if (count($birthdaysArray) === 1) { + $birthdayPlugin->assignTemplateVariable('message',$gL10n->get('PLG_BIRTHDAY_ONE_MEMBER')); + } else { + $birthdayPlugin->assignTemplateVariable('message',$gL10n->get('PLG_BIRTHDAY_MORE_MEMBERS', array(count($birthdaysArray)))); + } + } + } else { + // If the configuration is set accordingly, a message is output if no member has a birthday today + if ($gSettingsManager->getBool('birthday_show_notice_none')) { + $birthdayPlugin->assignTemplateVariable('message',$gL10n->get('PLG_BIRTHDAY_NO_MEMBERS')); } } - } else { - // If the configuration is set accordingly, a message is output if no member has a birthday today - if ($gSettingsManager->getBool('birthday_show_notice_none')) { - $birthdayPlugin->assignTemplateVariable('message',$gL10n->get('PLG_BIRTHDAY_NO_MEMBERS')); - } + } else { + $birthdayPlugin->assignTemplateVariable('message',$gL10n->get('PLG_BIRTHDAY_NO_ENTRIES_VISITORS')); } } else { - $birthdayPlugin->assignTemplateVariable('message',$gL10n->get('PLG_BIRTHDAY_NO_ENTRIES_VISITORS')); + $birthdayPlugin->assignTemplateVariable('message', $gL10n->get('SYS_MODULE_DISABLED')); } + if (isset($page)) { echo $birthdayPlugin->html('plugin.birthday.tpl'); } else { diff --git a/adm_plugins/calendar/classes/Calendar.php b/adm_plugins/calendar/classes/Calendar.php index 0491e0341e..7bf2ea4e7d 100644 --- a/adm_plugins/calendar/classes/Calendar.php +++ b/adm_plugins/calendar/classes/Calendar.php @@ -552,22 +552,25 @@ public static function doRender($page = null) : bool if (!self::isInstalled()) { throw new InvalidArgumentException($gL10n->get('SYS_PLUGIN_NOT_INSTALLED')); } + if ($gSettingsManager->getInt('events_module_enabled') > 0 && $gSettingsManager->getInt('announcements_module_enabled') > 0) { + if ($gSettingsManager->getInt('calendar_plugin_enabled') === 1 || ($gSettingsManager->getInt('calendar_plugin_enabled') === 2 && $gValidLogin)) { - if ($gSettingsManager->getInt('calendar_plugin_enabled') === 1 || ($gSettingsManager->getInt('calendar_plugin_enabled') === 2 && $gValidLogin)) { + $tableContent = self::getCalendarsData(); - $tableContent = self::getCalendarsData(); + header('Content-Type: text/html; charset=utf-8'); - header('Content-Type: text/html; charset=utf-8'); - - $calendarPlugin->assignTemplateVariable('pluginFolder', $pluginFolder); - $calendarPlugin->assignTemplateVariable('monthYearHeadline', self::$months[(int) self::$currentMonth - 1] . ' ' . self::$currentYear); - $calendarPlugin->assignTemplateVariable('monthYear', self::$currentMonth . self::$currentYear); - $calendarPlugin->assignTemplateVariable('currentMonthYear', date('mY')); - $calendarPlugin->assignTemplateVariable('dateIdLastMonth', date('mY', mktime(0, 0, 0, self::$currentMonth - 1, 1, self::$currentYear))); - $calendarPlugin->assignTemplateVariable('dateIdNextMonth', date('mY', mktime(0, 0, 0, self::$currentMonth + 1, 1, self::$currentYear))); - $calendarPlugin->assignTemplateVariable('tableContent', $tableContent); + $calendarPlugin->assignTemplateVariable('pluginFolder', $pluginFolder); + $calendarPlugin->assignTemplateVariable('monthYearHeadline', self::$months[(int) self::$currentMonth - 1] . ' ' . self::$currentYear); + $calendarPlugin->assignTemplateVariable('monthYear', self::$currentMonth . self::$currentYear); + $calendarPlugin->assignTemplateVariable('currentMonthYear', date('mY')); + $calendarPlugin->assignTemplateVariable('dateIdLastMonth', date('mY', mktime(0, 0, 0, self::$currentMonth - 1, 1, self::$currentYear))); + $calendarPlugin->assignTemplateVariable('dateIdNextMonth', date('mY', mktime(0, 0, 0, self::$currentMonth + 1, 1, self::$currentYear))); + $calendarPlugin->assignTemplateVariable('tableContent', $tableContent); + } else { + $calendarPlugin->assignTemplateVariable('message',$gL10n->get('PLG_BIRTHDAY_NO_ENTRIES_VISITORS')); + } } else { - $calendarPlugin->assignTemplateVariable('message',$gL10n->get('PLG_BIRTHDAY_NO_ENTRIES_VISITORS')); + $calendarPlugin->assignTemplateVariable('message', $gL10n->get('SYS_MODULE_DISABLED')); } if (isset($page)) { diff --git a/adm_plugins/calendar/languages/en.xml b/adm_plugins/calendar/languages/en.xml index 360f86d758..1bd3671e4b 100644 --- a/adm_plugins/calendar/languages/en.xml +++ b/adm_plugins/calendar/languages/en.xml @@ -10,7 +10,7 @@ Sa Su Several days - This plugin displays a calendar with all events of the current month. + This plugin displays a calendar with all events of the current month on the Overview page. Calendar Show events From 3cb3a2c2de05606111037c91436c504908dfbf26 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 23 Jul 2025 17:23:22 +0200 Subject: [PATCH 020/109] fix: sanitize plugin name formatting in preferences and plugins presenters --- src/Preferences/Service/PreferencesService.php | 2 +- src/UI/Presenter/PluginsPresenter.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Preferences/Service/PreferencesService.php b/src/Preferences/Service/PreferencesService.php index d6d5a035e1..a30d091482 100644 --- a/src/Preferences/Service/PreferencesService.php +++ b/src/Preferences/Service/PreferencesService.php @@ -71,7 +71,7 @@ public static function getPluginPanels(): array $metadata = $pluginManager->getMetadataByComponentId($comId); $panels[] = array( - 'id' => str_replace(' ', '_',strtolower(Language::translateIfTranslationStrId($metadata['name']))), + 'id' => preg_replace('/\s+/', '_', preg_replace('/[^a-z0-9_ ]/', '', strtolower(Language::translateIfTranslationStrId($metadata['name'])))), 'title' => Language::translateIfTranslationStrId($metadata['name']), 'icon' => $metadata['icon'] ?? 'bi-puzzle', 'subcards' => $metadata['hasSubcards'] ?? false, diff --git a/src/UI/Presenter/PluginsPresenter.php b/src/UI/Presenter/PluginsPresenter.php index 7123ed203b..8a9b91f5b5 100644 --- a/src/UI/Presenter/PluginsPresenter.php +++ b/src/UI/Presenter/PluginsPresenter.php @@ -148,7 +148,7 @@ public function prepareData(): void if ($interface->isInstalled()) { // add showPreferences action $templateRow['actions'][] = array( - 'url' => SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/preferences.php', array('panel' => str_replace(' ', '_',strtolower(Language::translateIfTranslationStrId($interface->getName()))))), + 'url' => SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/preferences.php', array('panel' => preg_replace('/\s+/', '_', preg_replace('/[^a-z0-9_ ]/', '', strtolower(Language::translateIfTranslationStrId($interface->getName())))))), 'icon' => 'bi bi-gear', 'tooltip' => $gL10n->get('SYS_PLUGIN_PREFERENCES') ); From 3f84613e0db17e4efb15b3512de08a9ebb6c92e5 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 23 Jul 2025 17:24:46 +0200 Subject: [PATCH 021/109] rebase latest-documents-files overview-plugin to use PluginManager --- .../LatestDocumentsFiles.json | 36 ++++ .../classes/LatestDocumentsFiles.php | 163 ++++++++++++++++++ ...testDocumentsFilesPreferencesPresenter.php | 82 +++++++++ .../db_scripts/update_1_0.xml | 6 + adm_plugins/LatestDocumentsFiles/index.php | 23 +++ .../LatestDocumentsFiles/languages/bg.xml | 7 + .../LatestDocumentsFiles/languages/da.xml | 7 + .../LatestDocumentsFiles/languages/de-DE.xml | 7 + .../LatestDocumentsFiles/languages/de.xml | 7 + .../LatestDocumentsFiles/languages/el.xml | 7 + .../LatestDocumentsFiles/languages/en.xml | 16 ++ .../LatestDocumentsFiles/languages/es.xml | 7 + .../LatestDocumentsFiles/languages/et.xml | 7 + .../LatestDocumentsFiles/languages/fi.xml | 7 + .../LatestDocumentsFiles/languages/fr.xml | 7 + .../LatestDocumentsFiles/languages/hu.xml | 7 + .../LatestDocumentsFiles/languages/nb.xml | 7 + .../LatestDocumentsFiles/languages/nl.xml | 7 + .../LatestDocumentsFiles/languages/pl.xml | 7 + .../LatestDocumentsFiles/languages/pt-BR.xml | 7 + .../LatestDocumentsFiles/languages/pt.xml | 7 + .../LatestDocumentsFiles/languages/ru.xml | 7 + .../LatestDocumentsFiles/languages/sv.xml | 7 + .../LatestDocumentsFiles/languages/uk.xml | 7 + .../LatestDocumentsFiles/languages/zh.xml | 7 + .../plugin.latest-documents-files.tpl | 4 +- ...ferences.plugin.latest-documents-files.tpl | 14 ++ .../latest-documents-files/config_sample.php | 24 --- adm_plugins/latest-documents-files/index.php | 134 -------------- .../latest-documents-files/languages/bg.xml | 7 - .../latest-documents-files/languages/da.xml | 7 - .../languages/de-DE.xml | 7 - .../latest-documents-files/languages/de.xml | 7 - .../latest-documents-files/languages/el.xml | 7 - .../latest-documents-files/languages/en.xml | 7 - .../latest-documents-files/languages/es.xml | 7 - .../latest-documents-files/languages/et.xml | 7 - .../latest-documents-files/languages/fi.xml | 7 - .../latest-documents-files/languages/fr.xml | 7 - .../latest-documents-files/languages/hu.xml | 7 - .../latest-documents-files/languages/nb.xml | 7 - .../latest-documents-files/languages/nl.xml | 7 - .../latest-documents-files/languages/pl.xml | 7 - .../languages/pt-BR.xml | 7 - .../latest-documents-files/languages/pt.xml | 7 - .../latest-documents-files/languages/ru.xml | 7 - .../latest-documents-files/languages/sv.xml | 7 - .../latest-documents-files/languages/uk.xml | 7 - .../latest-documents-files/languages/zh.xml | 7 - 49 files changed, 475 insertions(+), 300 deletions(-) create mode 100644 adm_plugins/LatestDocumentsFiles/LatestDocumentsFiles.json create mode 100644 adm_plugins/LatestDocumentsFiles/classes/LatestDocumentsFiles.php create mode 100644 adm_plugins/LatestDocumentsFiles/classes/Presenter/LatestDocumentsFilesPreferencesPresenter.php create mode 100644 adm_plugins/LatestDocumentsFiles/db_scripts/update_1_0.xml create mode 100644 adm_plugins/LatestDocumentsFiles/index.php create mode 100644 adm_plugins/LatestDocumentsFiles/languages/bg.xml create mode 100644 adm_plugins/LatestDocumentsFiles/languages/da.xml create mode 100644 adm_plugins/LatestDocumentsFiles/languages/de-DE.xml create mode 100644 adm_plugins/LatestDocumentsFiles/languages/de.xml create mode 100644 adm_plugins/LatestDocumentsFiles/languages/el.xml create mode 100644 adm_plugins/LatestDocumentsFiles/languages/en.xml create mode 100644 adm_plugins/LatestDocumentsFiles/languages/es.xml create mode 100644 adm_plugins/LatestDocumentsFiles/languages/et.xml create mode 100644 adm_plugins/LatestDocumentsFiles/languages/fi.xml create mode 100644 adm_plugins/LatestDocumentsFiles/languages/fr.xml create mode 100644 adm_plugins/LatestDocumentsFiles/languages/hu.xml create mode 100644 adm_plugins/LatestDocumentsFiles/languages/nb.xml create mode 100644 adm_plugins/LatestDocumentsFiles/languages/nl.xml create mode 100644 adm_plugins/LatestDocumentsFiles/languages/pl.xml create mode 100644 adm_plugins/LatestDocumentsFiles/languages/pt-BR.xml create mode 100644 adm_plugins/LatestDocumentsFiles/languages/pt.xml create mode 100644 adm_plugins/LatestDocumentsFiles/languages/ru.xml create mode 100644 adm_plugins/LatestDocumentsFiles/languages/sv.xml create mode 100644 adm_plugins/LatestDocumentsFiles/languages/uk.xml create mode 100644 adm_plugins/LatestDocumentsFiles/languages/zh.xml rename adm_plugins/{latest-documents-files => LatestDocumentsFiles}/templates/plugin.latest-documents-files.tpl (86%) create mode 100644 adm_plugins/LatestDocumentsFiles/templates/preferences.plugin.latest-documents-files.tpl delete mode 100644 adm_plugins/latest-documents-files/config_sample.php delete mode 100644 adm_plugins/latest-documents-files/index.php delete mode 100644 adm_plugins/latest-documents-files/languages/bg.xml delete mode 100644 adm_plugins/latest-documents-files/languages/da.xml delete mode 100644 adm_plugins/latest-documents-files/languages/de-DE.xml delete mode 100644 adm_plugins/latest-documents-files/languages/de.xml delete mode 100644 adm_plugins/latest-documents-files/languages/el.xml delete mode 100644 adm_plugins/latest-documents-files/languages/en.xml delete mode 100644 adm_plugins/latest-documents-files/languages/es.xml delete mode 100644 adm_plugins/latest-documents-files/languages/et.xml delete mode 100755 adm_plugins/latest-documents-files/languages/fi.xml delete mode 100644 adm_plugins/latest-documents-files/languages/fr.xml delete mode 100644 adm_plugins/latest-documents-files/languages/hu.xml delete mode 100644 adm_plugins/latest-documents-files/languages/nb.xml delete mode 100644 adm_plugins/latest-documents-files/languages/nl.xml delete mode 100644 adm_plugins/latest-documents-files/languages/pl.xml delete mode 100644 adm_plugins/latest-documents-files/languages/pt-BR.xml delete mode 100644 adm_plugins/latest-documents-files/languages/pt.xml delete mode 100644 adm_plugins/latest-documents-files/languages/ru.xml delete mode 100644 adm_plugins/latest-documents-files/languages/sv.xml delete mode 100644 adm_plugins/latest-documents-files/languages/uk.xml delete mode 100644 adm_plugins/latest-documents-files/languages/zh.xml diff --git a/adm_plugins/LatestDocumentsFiles/LatestDocumentsFiles.json b/adm_plugins/LatestDocumentsFiles/LatestDocumentsFiles.json new file mode 100644 index 0000000000..d98cc85e63 --- /dev/null +++ b/adm_plugins/LatestDocumentsFiles/LatestDocumentsFiles.json @@ -0,0 +1,36 @@ +{ + "name": "PLG_LATEST_DOCUMENTS_FILES_PLUGIN_NAME", + "description": "PLG_LATEST_DOCUMENTS_FILES_PLUGIN_DESCRIPTION", + "version": "1.0.0", + "author": "Admidio Team", + "url": "https://www.admidio.org", + "icon": "bi-file-earmark-arrow-down-fill", + "mainFile": "index.php", + "dependencies": [], + "defaultConfig": { + "latest_documents_files_plugin_enabled": { + "name": "ORG_ACCESS_TO_PLUGIN", + "description": "ORG_ACCESS_TO_PLUGIN_DESC", + "type": "integer", + "value" : 1 + }, + "latest_documents_files_files_count": { + "name": "PLG_LATEST_DOCUMENTS_FILES_PREFERENCES_FILES_COUNT", + "description": "PLG_LATEST_DOCUMENTS_FILES_PREFERENCES_FILES_COUNT_DESC", + "type": "integer", + "value" : 5 + }, + "latest_documents_files_show_upload_timestamp": { + "name": "PLG_LATEST_DOCUMENTS_FILES_PREFERENCES_SHOW_UPLOAD_TIMESTAMP", + "description": "PLG_LATEST_DOCUMENTS_FILES_PREFERENCES_SHOW_UPLOAD_TIMESTAMP_DESC", + "type": "boolean", + "value" : true + }, + "latest_documents_files_max_chars_filename": { + "name": "PLG_LATEST_DOCUMENTS_FILES_PREFERENCES_MAX_CHARS_FILENAME", + "description": "PLG_LATEST_DOCUMENTS_FILES_PREFERENCES_MAX_CHARS_FILENAME_DESC", + "type": "integer", + "value" : 0 + } + } +} \ No newline at end of file diff --git a/adm_plugins/LatestDocumentsFiles/classes/LatestDocumentsFiles.php b/adm_plugins/LatestDocumentsFiles/classes/LatestDocumentsFiles.php new file mode 100644 index 0000000000..a8c4fce11a --- /dev/null +++ b/adm_plugins/LatestDocumentsFiles/classes/LatestDocumentsFiles.php @@ -0,0 +1,163 @@ +readDataByColumns(array('fol_org_id' => $gCurrentOrgId, + 'fol_fol_id_parent' => 'NULL', + 'fol_type' => 'DOCUMENTS')); + $downloadFolder = $rootFolder->getValue('fol_path') . '/' . $rootFolder->getValue('fol_name'); + + // read all downloads from database and then check the rights for each download + $sql = 'SELECT fil_timestamp, fil_name, fil_usr_id, fol_name, fol_path, fil_id, fil_fol_id, fil_uuid + FROM ' . TBL_FILES . ' + INNER JOIN ' . TBL_FOLDERS . ' + ON fol_id = fil_fol_id + WHERE fol_org_id = ? -- $gCurrentOrgId + ' . $sqlCondition . ' + ORDER BY fil_timestamp DESC'; + + $filesStatement = $gDb->queryPrepared($sql, array($gCurrentOrgId)); + + if ($filesStatement->rowCount() > 0) { + while ($rowFile = $filesStatement->fetch()) { + try { + // get recordset of current file from database + $file = new File($gDb); + $file->getFileForDownload($rowFile['fil_uuid']); + + // get filename without extension and extension separately + $fileName = pathinfo($rowFile['fil_name'], PATHINFO_FILENAME); + $fullFolderFileName = $rowFile['fol_path'] . '/' . $rowFile['fol_name'] . '/' . $rowFile['fil_name']; + $tooltip = str_replace($downloadFolder, $gL10n->get('SYS_DOCUMENTS_FILES'), $fullFolderFileName); + ++$countVisibleDownloads; + + // if max chars are set then limit characters of shown filename + if ($config['latest_documents_files_max_chars_filename'] > 0 && strlen($fileName) > $config['latest_documents_files_max_chars_filename']) { + $fileName = substr($fileName, 0, $config['latest_documents_files_max_chars_filename']) . '...'; + } + + // if set in config file then show timestamp of file upload + if ($config['latest_documents_files_show_upload_timestamp']) { + // Vorname und Nachname abfragen (Upload der Datei) + $user = new User($gDb, $gProfileFields, $rowFile['fil_usr_id']); + + $tooltip .= '
' . $gL10n->get('PLG_LATEST_DOCUMENTS_FILES_UPLOAD_FROM_AT', array($user->getValue('FIRST_NAME') . ' ' . $user->getValue('LAST_NAME'), $file->getValue('fil_timestamp'))); + } + + $documentsFilesArray[] = array( + 'uuid' => $rowFile['fil_uuid'], + 'icon' => $file->getIcon(), + 'fileName' => $fileName, + 'fileExtension' => $file->getFileExtension(), + 'tooltip' => $tooltip + ); + + if ($countVisibleDownloads === $config['latest_documents_files_files_count']) { + break; + } + } catch (Exception $e) { + // do nothing and go to next file + } + } + } + + return $documentsFilesArray; + } + + /** + * @param PagePresenter $page + * @throws InvalidArgumentException + * @throws Exception + * @return bool + */ + public static function doRender($page = null) : bool + { + global $gSettingsManager, $gL10n, $gValidLogin; + + // show the latest documents & files list + try { + $rootPath = dirname(__DIR__, 3); + $pluginFolder = basename(self::$pluginPath); + + require_once($rootPath . '/system/common.php'); + + $latestDocumentsFilesPlugin = new Overview($pluginFolder); + + // check if the plugin is installed + if (!self::isInstalled()) { + throw new InvalidArgumentException($gL10n->get('SYS_PLUGIN_NOT_INSTALLED')); + } + + if ($gSettingsManager->getInt('documents_files_module_enabled') > 0) { + if (($gSettingsManager->getInt('documents_files_module_enabled') === 1 || ($gSettingsManager->getInt('documents_files_module_enabled') === 2 && $gValidLogin)) && + ($gSettingsManager->getInt('latest_documents_files_plugin_enabled') === 1 || ($gSettingsManager->getInt('latest_documents_files_plugin_enabled') === 2 && $gValidLogin))) { + $documentsFilesArray = self::getDocumentsFilesData(); + if (!empty($documentsFilesArray)) { + $latestDocumentsFilesPlugin->assignTemplateVariable('documentsFiles', $documentsFilesArray); + } else { + if ($gValidLogin) { + $latestDocumentsFilesPlugin->assignTemplateVariable('message', $gL10n->get('PLG_LATEST_DOCUMENTS_FILES_NO_DOWNLOADS_AVAILABLE')); + } else { + $latestDocumentsFilesPlugin->assignTemplateVariable('message', $gL10n->get('SYS_FOLDER_NO_FILES_VISITOR')); + } + } + } else { + $latestDocumentsFilesPlugin->assignTemplateVariable('message',$gL10n->get('SYS_FOLDER_NO_FILES_VISITOR')); + } + } else { + $latestDocumentsFilesPlugin->assignTemplateVariable('message', $gL10n->get('SYS_MODULE_DISABLED')); + } + + if (isset($page)) { + echo $latestDocumentsFilesPlugin->html('plugin.latest-documents-files.tpl'); + } else { + $latestDocumentsFilesPlugin->showHtmlPage('plugin.latest-documents-files.tpl'); + } + } catch (Throwable $e) { + echo $e->getMessage(); + } + + return true; + } +} \ No newline at end of file diff --git a/adm_plugins/LatestDocumentsFiles/classes/Presenter/LatestDocumentsFilesPreferencesPresenter.php b/adm_plugins/LatestDocumentsFiles/classes/Presenter/LatestDocumentsFilesPreferencesPresenter.php new file mode 100644 index 0000000000..636a32c182 --- /dev/null +++ b/adm_plugins/LatestDocumentsFiles/classes/Presenter/LatestDocumentsFilesPreferencesPresenter.php @@ -0,0 +1,82 @@ + 'save', 'panel' => 'latest_documents_files')), + null, + array('class' => 'form-preferences') + ); + $selectBoxEntries = array( + '0' => $gL10n->get('SYS_DISABLED'), + '1' => $gL10n->get('SYS_ENABLED'), + '2' => $gL10n->get('ORG_ONLY_FOR_REGISTERED_USER') + ); + $formLatestDocumentsFiles->addSelectBox( + 'latest_documents_files_plugin_enabled', + Language::translateIfTranslationStrId($formValues['latest_documents_files_plugin_enabled']['name']), + $selectBoxEntries, + array('defaultValue' => $formValues['latest_documents_files_plugin_enabled']['value'], 'showContextDependentFirstEntry' => false, 'helpTextId' => $formValues['latest_documents_files_plugin_enabled']['description']) + ); + $formLatestDocumentsFiles->addInput( + 'latest_documents_files_files_count', + Language::translateIfTranslationStrId($formValues['latest_documents_files_files_count']['name']), + $formValues['latest_documents_files_files_count']['value'], + array('type' => 'number', 'minNumber' => 0, 'maxNumber' => 20, 'step' => 1, 'helpTextId' => $formValues['latest_documents_files_files_count']['description']) + ); + $formLatestDocumentsFiles->addCheckbox( + 'latest_documents_files_show_upload_timestamp', + Language::translateIfTranslationStrId($formValues['latest_documents_files_show_upload_timestamp']['name']), + $formValues['latest_documents_files_show_upload_timestamp']['value'], + array('helpTextId' => $formValues['latest_documents_files_show_upload_timestamp']['description']) + ); + $formLatestDocumentsFiles->addInput( + 'latest_documents_files_max_chars_filename', + Language::translateIfTranslationStrId($formValues['latest_documents_files_max_chars_filename']['name']), + $formValues['latest_documents_files_max_chars_filename']['value'], + array('type' => 'number', 'minNumber' => 0, 'step' => 1, 'helpTextId' => $formValues['latest_documents_files_max_chars_filename']['description']) + ); + $formLatestDocumentsFiles->addSubmitButton( + 'adm_button_save_latest_documents_files', + $gL10n->get('SYS_SAVE'), + array('icon' => 'bi-check-lg', 'class' => 'offset-sm-3') + ); + + $formLatestDocumentsFiles->addToSmarty($smarty); + $gCurrentSession->addFormObject($formLatestDocumentsFiles); + return $smarty->fetch($pluginLatestDocumentsFiles::getPluginPath() . '/templates/preferences.plugin.latest-documents-files.tpl'); + } +} \ No newline at end of file diff --git a/adm_plugins/LatestDocumentsFiles/db_scripts/update_1_0.xml b/adm_plugins/LatestDocumentsFiles/db_scripts/update_1_0.xml new file mode 100644 index 0000000000..20b0e676ee --- /dev/null +++ b/adm_plugins/LatestDocumentsFiles/db_scripts/update_1_0.xml @@ -0,0 +1,6 @@ + + + UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'LatestDocumentsFiles' + UPDATE %PREFIX%_components SET com_plg_sequence = 5 WHERE com_type = 'ADM_PLUGIN' AND com_name_intern = 'LatestDocumentsFiles' + stop + diff --git a/adm_plugins/LatestDocumentsFiles/index.php b/adm_plugins/LatestDocumentsFiles/index.php new file mode 100644 index 0000000000..1878f830dd --- /dev/null +++ b/adm_plugins/LatestDocumentsFiles/index.php @@ -0,0 +1,23 @@ +doRender(isset($page) ? $page : null); + +} catch (Throwable $e) { + echo $e->getMessage(); +} diff --git a/adm_plugins/LatestDocumentsFiles/languages/bg.xml b/adm_plugins/LatestDocumentsFiles/languages/bg.xml new file mode 100644 index 0000000000..7d0a5abce4 --- /dev/null +++ b/adm_plugins/LatestDocumentsFiles/languages/bg.xml @@ -0,0 +1,7 @@ + + + Документи и файлове + Още документи и файлове + Няма налични документи и файлове. + Качен от #VAR1# на #VAR2# + diff --git a/adm_plugins/LatestDocumentsFiles/languages/da.xml b/adm_plugins/LatestDocumentsFiles/languages/da.xml new file mode 100644 index 0000000000..dae40c7b4e --- /dev/null +++ b/adm_plugins/LatestDocumentsFiles/languages/da.xml @@ -0,0 +1,7 @@ + + + Dokumenter & filer + Flere dokumenter & filer + Der er ikke nogen dokumenter eller filer tilgængelige. + Uploadet af #VAR1# den #VAR2# + diff --git a/adm_plugins/LatestDocumentsFiles/languages/de-DE.xml b/adm_plugins/LatestDocumentsFiles/languages/de-DE.xml new file mode 100644 index 0000000000..abcc8b8e8b --- /dev/null +++ b/adm_plugins/LatestDocumentsFiles/languages/de-DE.xml @@ -0,0 +1,7 @@ + + + Dokumente & Dateien + Weitere Dokumente & Dateien + Es stehen keine Dateien zum Download zur Verfügung. + Hochgeladen von #VAR1# am #VAR2# + diff --git a/adm_plugins/LatestDocumentsFiles/languages/de.xml b/adm_plugins/LatestDocumentsFiles/languages/de.xml new file mode 100644 index 0000000000..cab6aa211e --- /dev/null +++ b/adm_plugins/LatestDocumentsFiles/languages/de.xml @@ -0,0 +1,7 @@ + + + Dokumente & Dateien + Weitere Dokumente & Dateien + Es stehen keine Dokumente oder Dateien zur Verfügung. + Hochgeladen von #VAR1# am #VAR2# + diff --git a/adm_plugins/LatestDocumentsFiles/languages/el.xml b/adm_plugins/LatestDocumentsFiles/languages/el.xml new file mode 100644 index 0000000000..f67e21045d --- /dev/null +++ b/adm_plugins/LatestDocumentsFiles/languages/el.xml @@ -0,0 +1,7 @@ + + + Έγγραφα & αρχεία + Περισσότερα Έγγραφα & αρχεία + Δεν υπάρχουν διαθέσιμα έγγραφα ή αρχεία. + Ανέβηκε από #VAR1# στις #VAR2# + diff --git a/adm_plugins/LatestDocumentsFiles/languages/en.xml b/adm_plugins/LatestDocumentsFiles/languages/en.xml new file mode 100644 index 0000000000..66ffd6c612 --- /dev/null +++ b/adm_plugins/LatestDocumentsFiles/languages/en.xml @@ -0,0 +1,16 @@ + + + Documents & files + More documents & files + There are no documents or files available. + Uploaded by #VAR1# on #VAR2# + This plugin lists the latest documents and files uploaded by users on the Overview page. + Latest Documents & Files + + Number of files + Number of files to be displayed. (default: 2) + Show upload timestamp + If this setting is enabled the upload timestamp of the file will be shown. Otherwise it will be hidden. (default: true) + Maximum characters in filename + Maximum number of characters in a filename before it is truncated. (0: deactivates truncation, default: 0) + diff --git a/adm_plugins/LatestDocumentsFiles/languages/es.xml b/adm_plugins/LatestDocumentsFiles/languages/es.xml new file mode 100644 index 0000000000..80e01a9503 --- /dev/null +++ b/adm_plugins/LatestDocumentsFiles/languages/es.xml @@ -0,0 +1,7 @@ + + + Descargas + Más descargas + No hay archivos disponibles para descargar. + Subido de #VAR1# el #VAR2# + diff --git a/adm_plugins/LatestDocumentsFiles/languages/et.xml b/adm_plugins/LatestDocumentsFiles/languages/et.xml new file mode 100644 index 0000000000..a0f236a8a1 --- /dev/null +++ b/adm_plugins/LatestDocumentsFiles/languages/et.xml @@ -0,0 +1,7 @@ + + + Dokumendid & failid + Rohkem dokumente & failid + Dokumente ega faile pole saadaval. + #VAR1# laadis üles #VAR2# + diff --git a/adm_plugins/LatestDocumentsFiles/languages/fi.xml b/adm_plugins/LatestDocumentsFiles/languages/fi.xml new file mode 100644 index 0000000000..ddf877aff5 --- /dev/null +++ b/adm_plugins/LatestDocumentsFiles/languages/fi.xml @@ -0,0 +1,7 @@ + + + Dokumentteja & tiedostoja + Lisää dokumentteja & tiedostoja + Asiakirjoja tai tiedostoja ei ole saatavilla. + Lataaja #VAR1# pävämäärällä #VAR2# + diff --git a/adm_plugins/LatestDocumentsFiles/languages/fr.xml b/adm_plugins/LatestDocumentsFiles/languages/fr.xml new file mode 100644 index 0000000000..76961e92f9 --- /dev/null +++ b/adm_plugins/LatestDocumentsFiles/languages/fr.xml @@ -0,0 +1,7 @@ + + + Documents & des dossiers + Plus de documents & des dossiers + Il n\'y a pas de documents ou fichiers disponibles. + Téléchargé de #VAR1# le #VAR2# + diff --git a/adm_plugins/LatestDocumentsFiles/languages/hu.xml b/adm_plugins/LatestDocumentsFiles/languages/hu.xml new file mode 100644 index 0000000000..bd79adf45f --- /dev/null +++ b/adm_plugins/LatestDocumentsFiles/languages/hu.xml @@ -0,0 +1,7 @@ + + + Dokumentumok és fájlok + További dokumentumok és fájlok + Nincsenek dokumentumok vagy fájlok. + Feltöltötte #VAR1# a #VAR2# időpontban + diff --git a/adm_plugins/LatestDocumentsFiles/languages/nb.xml b/adm_plugins/LatestDocumentsFiles/languages/nb.xml new file mode 100644 index 0000000000..4a48cae5db --- /dev/null +++ b/adm_plugins/LatestDocumentsFiles/languages/nb.xml @@ -0,0 +1,7 @@ + + + Dokumenter og filer + Flere dokumenter og filer + Ingen dokumenter tilgjengelig + Lastet opp av #VAR1# den #VAR2# + diff --git a/adm_plugins/LatestDocumentsFiles/languages/nl.xml b/adm_plugins/LatestDocumentsFiles/languages/nl.xml new file mode 100644 index 0000000000..7273b92401 --- /dev/null +++ b/adm_plugins/LatestDocumentsFiles/languages/nl.xml @@ -0,0 +1,7 @@ + + + Documenten & bestanden + Meer documenten & bestanden + Er zijn geen documenten of bestanden beschikbaar. + Geüpload door #VAR1# op #VAR2# + diff --git a/adm_plugins/LatestDocumentsFiles/languages/pl.xml b/adm_plugins/LatestDocumentsFiles/languages/pl.xml new file mode 100644 index 0000000000..3df4d471a2 --- /dev/null +++ b/adm_plugins/LatestDocumentsFiles/languages/pl.xml @@ -0,0 +1,7 @@ + + + Dokumenty i pliki + Więcej dokumentów i plików + Brak dostępnych dokumentów i plików. + Przesłane przez #VAR1# w dniu #VAR2# + diff --git a/adm_plugins/LatestDocumentsFiles/languages/pt-BR.xml b/adm_plugins/LatestDocumentsFiles/languages/pt-BR.xml new file mode 100644 index 0000000000..b07831b8ff --- /dev/null +++ b/adm_plugins/LatestDocumentsFiles/languages/pt-BR.xml @@ -0,0 +1,7 @@ + + + Downloads + Mais downloads + Não há arquivos disponíveis para baixar. + Enviado por #VAR1# em #VAR2# + diff --git a/adm_plugins/LatestDocumentsFiles/languages/pt.xml b/adm_plugins/LatestDocumentsFiles/languages/pt.xml new file mode 100644 index 0000000000..18c266580f --- /dev/null +++ b/adm_plugins/LatestDocumentsFiles/languages/pt.xml @@ -0,0 +1,7 @@ + + + Documentos e Ficheiros + Mais documentos e ficheiros + Não existem documentos ou ficheiros disponíveis + Enviado por #VAR1# em #VAR2# + diff --git a/adm_plugins/LatestDocumentsFiles/languages/ru.xml b/adm_plugins/LatestDocumentsFiles/languages/ru.xml new file mode 100644 index 0000000000..6749dee010 --- /dev/null +++ b/adm_plugins/LatestDocumentsFiles/languages/ru.xml @@ -0,0 +1,7 @@ + + + Документы и файлы + Больше документов и файлов + Нет документов или файлов. + Загружено #VAR1# #VAR2# + diff --git a/adm_plugins/LatestDocumentsFiles/languages/sv.xml b/adm_plugins/LatestDocumentsFiles/languages/sv.xml new file mode 100644 index 0000000000..aec79cd9f6 --- /dev/null +++ b/adm_plugins/LatestDocumentsFiles/languages/sv.xml @@ -0,0 +1,7 @@ + + + Dokument & filer + Fler dokument & filer + Det finns inga dokument eller filer tillgängliga. + Uppladdat av #VAR1# på #VAR2# + diff --git a/adm_plugins/LatestDocumentsFiles/languages/uk.xml b/adm_plugins/LatestDocumentsFiles/languages/uk.xml new file mode 100644 index 0000000000..cfe30cb36a --- /dev/null +++ b/adm_plugins/LatestDocumentsFiles/languages/uk.xml @@ -0,0 +1,7 @@ + + + Документи & файли + Більше документів & файлів + Немає доступних документів чи файлів. + Завантажено #VAR1# #VAR2# + diff --git a/adm_plugins/LatestDocumentsFiles/languages/zh.xml b/adm_plugins/LatestDocumentsFiles/languages/zh.xml new file mode 100644 index 0000000000..a2a48761a8 --- /dev/null +++ b/adm_plugins/LatestDocumentsFiles/languages/zh.xml @@ -0,0 +1,7 @@ + + + 下载 + 更多下载 + 没有可供下载的文件。 + 上传者: #VAR1# 在 #VAR2# + diff --git a/adm_plugins/latest-documents-files/templates/plugin.latest-documents-files.tpl b/adm_plugins/LatestDocumentsFiles/templates/plugin.latest-documents-files.tpl similarity index 86% rename from adm_plugins/latest-documents-files/templates/plugin.latest-documents-files.tpl rename to adm_plugins/LatestDocumentsFiles/templates/plugin.latest-documents-files.tpl index 0facad36a0..15ab0cbad6 100644 --- a/adm_plugins/latest-documents-files/templates/plugin.latest-documents-files.tpl +++ b/adm_plugins/LatestDocumentsFiles/templates/plugin.latest-documents-files.tpl @@ -1,5 +1,5 @@
-

{$l10n->get('PLG_LATEST_FILES_HEADLINE')}

+

{$l10n->get('PLG_LATEST_DOCUMENTS_FILES_HEADLINE')}

{if count($documentsFiles) > 0} {else} diff --git a/adm_plugins/LatestDocumentsFiles/templates/preferences.plugin.latest-documents-files.tpl b/adm_plugins/LatestDocumentsFiles/templates/preferences.plugin.latest-documents-files.tpl new file mode 100644 index 0000000000..f242898a26 --- /dev/null +++ b/adm_plugins/LatestDocumentsFiles/templates/preferences.plugin.latest-documents-files.tpl @@ -0,0 +1,14 @@ +
+ + {include 'sys-template-parts/form.input.tpl' data=$elements['adm_csrf_token']} + {include 'sys-template-parts/form.select.tpl' data=$elements['latest_documents_files_plugin_enabled']} + {include 'sys-template-parts/form.input.tpl' data=$elements['latest_documents_files_files_count']} + {include 'sys-template-parts/form.checkbox.tpl' data=$elements['latest_documents_files_show_upload_timestamp']} + {include 'sys-template-parts/form.input.tpl' data=$elements['latest_documents_files_max_chars_filename']} + {include 'sys-template-parts/form.button.tpl' data=$elements['adm_button_save_latest_documents_files']} + + +
+{$javascript} \ No newline at end of file diff --git a/adm_plugins/latest-documents-files/config_sample.php b/adm_plugins/latest-documents-files/config_sample.php deleted file mode 100644 index 1141e77f71..0000000000 --- a/adm_plugins/latest-documents-files/config_sample.php +++ /dev/null @@ -1,24 +0,0 @@ -readDataByColumns(array('fol_org_id' => $gCurrentOrgId, - 'fol_fol_id_parent' => 'NULL', - 'fol_type' => 'DOCUMENTS')); - $downloadFolder = $rootFolder->getValue('fol_path') . '/' . $rootFolder->getValue('fol_name'); - - // read all downloads from database and then check the rights for each download - $sql = 'SELECT fil_timestamp, fil_name, fil_usr_id, fol_name, fol_path, fil_id, fil_fol_id, fil_uuid - FROM ' . TBL_FILES . ' - INNER JOIN ' . TBL_FOLDERS . ' - ON fol_id = fil_fol_id - WHERE fol_org_id = ? -- $gCurrentOrgId - ' . $sqlCondition . ' - ORDER BY fil_timestamp DESC'; - - $filesStatement = $gDb->queryPrepared($sql, array($gCurrentOrgId)); - - if ($filesStatement->rowCount() > 0) { - $documentsFilesArray = array(); - - while ($rowFile = $filesStatement->fetch()) { - try { - // get recordset of current file from database - $file = new File($gDb); - $file->getFileForDownload($rowFile['fil_uuid']); - - // get filename without extension and extension separately - $fileName = pathinfo($rowFile['fil_name'], PATHINFO_FILENAME); - $fullFolderFileName = $rowFile['fol_path'] . '/' . $rowFile['fol_name'] . '/' . $rowFile['fil_name']; - $tooltip = str_replace($downloadFolder, $gL10n->get('SYS_DOCUMENTS_FILES'), $fullFolderFileName); - ++$countVisibleDownloads; - - // if max chars are set then limit characters of shown filename - if ($plgMaxCharsFilename > 0 && strlen($fileName) > $plgMaxCharsFilename) { - $fileName = substr($fileName, 0, $plgMaxCharsFilename) . '...'; - } - - // if set in config file then show timestamp of file upload - if ($plg_show_upload_timestamp) { - // Vorname und Nachname abfragen (Upload der Datei) - $user = new User($gDb, $gProfileFields, $rowFile['fil_usr_id']); - - $tooltip .= '
' . $gL10n->get('PLG_LATEST_FILES_UPLOAD_FROM_AT', array($user->getValue('FIRST_NAME') . ' ' . $user->getValue('LAST_NAME'), $file->getValue('fil_timestamp'))); - } - - $documentsFilesArray[] = array( - 'uuid' => $rowFile['fil_uuid'], - 'icon' => $file->getIcon(), - 'fileName' => $fileName, - 'fileExtension' => $file->getFileExtension(), - 'tooltip' => $tooltip - ); - - if ($countVisibleDownloads === $plgCountFiles) { - break; - } - } catch (Exception $e) { - // do nothing and go to next file - } - } - $latestDocumentsFilesPlugin->assignTemplateVariable('documentsFiles', $documentsFilesArray); - } - } - - if ($countVisibleDownloads === 0) { - if ($gValidLogin) { - $latestDocumentsFilesPlugin->assignTemplateVariable('message',$gL10n->get('PLG_LATEST_FILES_NO_DOWNLOADS_AVAILABLE')); - } else { - $latestDocumentsFilesPlugin->assignTemplateVariable('message',$gL10n->get('SYS_FOLDER_NO_FILES_VISITOR')); - } - } - - if (isset($page)) { - echo $latestDocumentsFilesPlugin->html('plugin.latest-documents-files.tpl'); - } else { - $latestDocumentsFilesPlugin->showHtmlPage('plugin.latest-documents-files.tpl'); - } -} catch (Throwable $e) { - echo $e->getMessage(); -} diff --git a/adm_plugins/latest-documents-files/languages/bg.xml b/adm_plugins/latest-documents-files/languages/bg.xml deleted file mode 100644 index f18963078b..0000000000 --- a/adm_plugins/latest-documents-files/languages/bg.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - Документи и файлове - Още документи и файлове - Няма налични документи и файлове. - Качен от #VAR1# на #VAR2# - diff --git a/adm_plugins/latest-documents-files/languages/da.xml b/adm_plugins/latest-documents-files/languages/da.xml deleted file mode 100644 index 784994447b..0000000000 --- a/adm_plugins/latest-documents-files/languages/da.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - Dokumenter & filer - Flere dokumenter & filer - Der er ikke nogen dokumenter eller filer tilgængelige. - Uploadet af #VAR1# den #VAR2# - diff --git a/adm_plugins/latest-documents-files/languages/de-DE.xml b/adm_plugins/latest-documents-files/languages/de-DE.xml deleted file mode 100644 index e20097be4d..0000000000 --- a/adm_plugins/latest-documents-files/languages/de-DE.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - Dokumente & Dateien - Weitere Dokumente & Dateien - Es stehen keine Dateien zum Download zur Verfügung. - Hochgeladen von #VAR1# am #VAR2# - diff --git a/adm_plugins/latest-documents-files/languages/de.xml b/adm_plugins/latest-documents-files/languages/de.xml deleted file mode 100644 index 6283f1ba24..0000000000 --- a/adm_plugins/latest-documents-files/languages/de.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - Dokumente & Dateien - Weitere Dokumente & Dateien - Es stehen keine Dokumente oder Dateien zur Verfügung. - Hochgeladen von #VAR1# am #VAR2# - diff --git a/adm_plugins/latest-documents-files/languages/el.xml b/adm_plugins/latest-documents-files/languages/el.xml deleted file mode 100644 index 57ab958fa3..0000000000 --- a/adm_plugins/latest-documents-files/languages/el.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - Έγγραφα & αρχεία - Περισσότερα Έγγραφα & αρχεία - Δεν υπάρχουν διαθέσιμα έγγραφα ή αρχεία. - Ανέβηκε από #VAR1# στις #VAR2# - diff --git a/adm_plugins/latest-documents-files/languages/en.xml b/adm_plugins/latest-documents-files/languages/en.xml deleted file mode 100644 index 38719db6b8..0000000000 --- a/adm_plugins/latest-documents-files/languages/en.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - Documents & files - More documents & files - There are no documents or files available. - Uploaded by #VAR1# on #VAR2# - diff --git a/adm_plugins/latest-documents-files/languages/es.xml b/adm_plugins/latest-documents-files/languages/es.xml deleted file mode 100644 index af71a5e0c2..0000000000 --- a/adm_plugins/latest-documents-files/languages/es.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - Descargas - Más descargas - No hay archivos disponibles para descargar. - Subido de #VAR1# el #VAR2# - diff --git a/adm_plugins/latest-documents-files/languages/et.xml b/adm_plugins/latest-documents-files/languages/et.xml deleted file mode 100644 index 3df1d13559..0000000000 --- a/adm_plugins/latest-documents-files/languages/et.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - Dokumendid & failid - Rohkem dokumente & failid - Dokumente ega faile pole saadaval. - #VAR1# laadis üles #VAR2# - diff --git a/adm_plugins/latest-documents-files/languages/fi.xml b/adm_plugins/latest-documents-files/languages/fi.xml deleted file mode 100755 index 5ce2f7b916..0000000000 --- a/adm_plugins/latest-documents-files/languages/fi.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - Dokumentteja & tiedostoja - Lisää dokumentteja & tiedostoja - Asiakirjoja tai tiedostoja ei ole saatavilla. - Lataaja #VAR1# pävämäärällä #VAR2# - diff --git a/adm_plugins/latest-documents-files/languages/fr.xml b/adm_plugins/latest-documents-files/languages/fr.xml deleted file mode 100644 index 3069f2a750..0000000000 --- a/adm_plugins/latest-documents-files/languages/fr.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - Documents & des dossiers - Plus de documents & des dossiers - Il n\'y a pas de documents ou fichiers disponibles. - Téléchargé de #VAR1# le #VAR2# - diff --git a/adm_plugins/latest-documents-files/languages/hu.xml b/adm_plugins/latest-documents-files/languages/hu.xml deleted file mode 100644 index b57ee49cbe..0000000000 --- a/adm_plugins/latest-documents-files/languages/hu.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - Dokumentumok és fájlok - További dokumentumok és fájlok - Nincsenek dokumentumok vagy fájlok. - Feltöltötte #VAR1# a #VAR2# időpontban - diff --git a/adm_plugins/latest-documents-files/languages/nb.xml b/adm_plugins/latest-documents-files/languages/nb.xml deleted file mode 100644 index 2ca7641776..0000000000 --- a/adm_plugins/latest-documents-files/languages/nb.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - Dokumenter og filer - Flere dokumenter og filer - Ingen dokumenter tilgjengelig - Lastet opp av #VAR1# den #VAR2# - diff --git a/adm_plugins/latest-documents-files/languages/nl.xml b/adm_plugins/latest-documents-files/languages/nl.xml deleted file mode 100644 index 29015d8bff..0000000000 --- a/adm_plugins/latest-documents-files/languages/nl.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - Documenten & bestanden - Meer documenten & bestanden - Er zijn geen documenten of bestanden beschikbaar. - Geüpload door #VAR1# op #VAR2# - diff --git a/adm_plugins/latest-documents-files/languages/pl.xml b/adm_plugins/latest-documents-files/languages/pl.xml deleted file mode 100644 index 115a59a23a..0000000000 --- a/adm_plugins/latest-documents-files/languages/pl.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - Dokumenty i pliki - Więcej dokumentów i plików - Brak dostępnych dokumentów i plików. - Przesłane przez #VAR1# w dniu #VAR2# - diff --git a/adm_plugins/latest-documents-files/languages/pt-BR.xml b/adm_plugins/latest-documents-files/languages/pt-BR.xml deleted file mode 100644 index 1226537142..0000000000 --- a/adm_plugins/latest-documents-files/languages/pt-BR.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - Downloads - Mais downloads - Não há arquivos disponíveis para baixar. - Enviado por #VAR1# em #VAR2# - diff --git a/adm_plugins/latest-documents-files/languages/pt.xml b/adm_plugins/latest-documents-files/languages/pt.xml deleted file mode 100644 index 0cad719a7d..0000000000 --- a/adm_plugins/latest-documents-files/languages/pt.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - Documentos e Ficheiros - Mais documentos e ficheiros - Não existem documentos ou ficheiros disponíveis - Enviado por #VAR1# em #VAR2# - diff --git a/adm_plugins/latest-documents-files/languages/ru.xml b/adm_plugins/latest-documents-files/languages/ru.xml deleted file mode 100644 index 9a01807cc3..0000000000 --- a/adm_plugins/latest-documents-files/languages/ru.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - Документы и файлы - Больше документов и файлов - Нет документов или файлов. - Загружено #VAR1# #VAR2# - diff --git a/adm_plugins/latest-documents-files/languages/sv.xml b/adm_plugins/latest-documents-files/languages/sv.xml deleted file mode 100644 index 101584f029..0000000000 --- a/adm_plugins/latest-documents-files/languages/sv.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - Dokument & filer - Fler dokument & filer - Det finns inga dokument eller filer tillgängliga. - Uppladdat av #VAR1# på #VAR2# - diff --git a/adm_plugins/latest-documents-files/languages/uk.xml b/adm_plugins/latest-documents-files/languages/uk.xml deleted file mode 100644 index 73a4672495..0000000000 --- a/adm_plugins/latest-documents-files/languages/uk.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - Документи & файли - Більше документів & файлів - Немає доступних документів чи файлів. - Завантажено #VAR1# #VAR2# - diff --git a/adm_plugins/latest-documents-files/languages/zh.xml b/adm_plugins/latest-documents-files/languages/zh.xml deleted file mode 100644 index f66c1319b7..0000000000 --- a/adm_plugins/latest-documents-files/languages/zh.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - 下载 - 更多下载 - 没有可供下载的文件。 - 上传者: #VAR1# 在 #VAR2# - From 0ae5854945dfc5aa778c7fe6634cced039476a5a Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 23 Jul 2025 19:07:12 +0200 Subject: [PATCH 022/109] rebase login-form overview-plugin to use PluginManager --- adm_plugins/LoginForm/LoginForm.json | 53 ++++++ .../classes/LoginForm.php} | 158 +++++++++++------- .../LoginFormPreferencesPresenter.php | 107 ++++++++++++ .../LoginForm/db_scripts/update_1_0.xml | 6 + adm_plugins/LoginForm/index.php | 25 +++ adm_plugins/LoginForm/languages/bg.xml | 10 ++ adm_plugins/LoginForm/languages/da.xml | 10 ++ adm_plugins/LoginForm/languages/de-DE.xml | 10 ++ adm_plugins/LoginForm/languages/de.xml | 10 ++ adm_plugins/LoginForm/languages/el.xml | 10 ++ adm_plugins/LoginForm/languages/en.xml | 24 +++ adm_plugins/LoginForm/languages/es.xml | 10 ++ adm_plugins/LoginForm/languages/et.xml | 10 ++ adm_plugins/LoginForm/languages/fi.xml | 10 ++ adm_plugins/LoginForm/languages/fr.xml | 10 ++ adm_plugins/LoginForm/languages/hu.xml | 10 ++ adm_plugins/LoginForm/languages/it.xml | 10 ++ adm_plugins/LoginForm/languages/nb.xml | 10 ++ adm_plugins/LoginForm/languages/nl.xml | 10 ++ adm_plugins/LoginForm/languages/pl.xml | 10 ++ adm_plugins/LoginForm/languages/pt-BR.xml | 10 ++ adm_plugins/LoginForm/languages/pt.xml | 10 ++ adm_plugins/LoginForm/languages/ru.xml | 10 ++ adm_plugins/LoginForm/languages/sv.xml | 10 ++ adm_plugins/LoginForm/languages/uk.xml | 10 ++ adm_plugins/LoginForm/languages/zh.xml | 10 ++ .../templates/plugin.login-form.edit.tpl | 0 .../templates/plugin.login-form.view.tpl | 6 +- .../preferences.plugin.login-form.tpl | 16 ++ adm_plugins/login_form/config_sample.php | 38 ----- adm_plugins/login_form/languages/bg.xml | 10 -- adm_plugins/login_form/languages/da.xml | 10 -- adm_plugins/login_form/languages/de-DE.xml | 10 -- adm_plugins/login_form/languages/de.xml | 10 -- adm_plugins/login_form/languages/el.xml | 10 -- adm_plugins/login_form/languages/en.xml | 10 -- adm_plugins/login_form/languages/es.xml | 10 -- adm_plugins/login_form/languages/et.xml | 10 -- adm_plugins/login_form/languages/fi.xml | 10 -- adm_plugins/login_form/languages/fr.xml | 10 -- adm_plugins/login_form/languages/hu.xml | 10 -- adm_plugins/login_form/languages/it.xml | 10 -- adm_plugins/login_form/languages/nb.xml | 10 -- adm_plugins/login_form/languages/nl.xml | 10 -- adm_plugins/login_form/languages/pl.xml | 10 -- adm_plugins/login_form/languages/pt-BR.xml | 10 -- adm_plugins/login_form/languages/pt.xml | 10 -- adm_plugins/login_form/languages/ru.xml | 10 -- adm_plugins/login_form/languages/sv.xml | 10 -- adm_plugins/login_form/languages/uk.xml | 10 -- adm_plugins/login_form/languages/zh.xml | 10 -- 51 files changed, 529 insertions(+), 314 deletions(-) create mode 100644 adm_plugins/LoginForm/LoginForm.json rename adm_plugins/{login_form/index.php => LoginForm/classes/LoginForm.php} (56%) create mode 100644 adm_plugins/LoginForm/classes/Presenter/LoginFormPreferencesPresenter.php create mode 100644 adm_plugins/LoginForm/db_scripts/update_1_0.xml create mode 100644 adm_plugins/LoginForm/index.php create mode 100644 adm_plugins/LoginForm/languages/bg.xml create mode 100644 adm_plugins/LoginForm/languages/da.xml create mode 100644 adm_plugins/LoginForm/languages/de-DE.xml create mode 100644 adm_plugins/LoginForm/languages/de.xml create mode 100644 adm_plugins/LoginForm/languages/el.xml create mode 100644 adm_plugins/LoginForm/languages/en.xml create mode 100644 adm_plugins/LoginForm/languages/es.xml create mode 100644 adm_plugins/LoginForm/languages/et.xml create mode 100644 adm_plugins/LoginForm/languages/fi.xml create mode 100644 adm_plugins/LoginForm/languages/fr.xml create mode 100644 adm_plugins/LoginForm/languages/hu.xml create mode 100644 adm_plugins/LoginForm/languages/it.xml create mode 100644 adm_plugins/LoginForm/languages/nb.xml create mode 100644 adm_plugins/LoginForm/languages/nl.xml create mode 100644 adm_plugins/LoginForm/languages/pl.xml create mode 100644 adm_plugins/LoginForm/languages/pt-BR.xml create mode 100644 adm_plugins/LoginForm/languages/pt.xml create mode 100644 adm_plugins/LoginForm/languages/ru.xml create mode 100644 adm_plugins/LoginForm/languages/sv.xml create mode 100644 adm_plugins/LoginForm/languages/uk.xml create mode 100644 adm_plugins/LoginForm/languages/zh.xml rename adm_plugins/{login_form => LoginForm}/templates/plugin.login-form.edit.tpl (100%) rename adm_plugins/{login_form => LoginForm}/templates/plugin.login-form.view.tpl (86%) create mode 100644 adm_plugins/LoginForm/templates/preferences.plugin.login-form.tpl delete mode 100644 adm_plugins/login_form/config_sample.php delete mode 100644 adm_plugins/login_form/languages/bg.xml delete mode 100644 adm_plugins/login_form/languages/da.xml delete mode 100644 adm_plugins/login_form/languages/de-DE.xml delete mode 100644 adm_plugins/login_form/languages/de.xml delete mode 100644 adm_plugins/login_form/languages/el.xml delete mode 100644 adm_plugins/login_form/languages/en.xml delete mode 100644 adm_plugins/login_form/languages/es.xml delete mode 100644 adm_plugins/login_form/languages/et.xml delete mode 100755 adm_plugins/login_form/languages/fi.xml delete mode 100644 adm_plugins/login_form/languages/fr.xml delete mode 100644 adm_plugins/login_form/languages/hu.xml delete mode 100644 adm_plugins/login_form/languages/it.xml delete mode 100644 adm_plugins/login_form/languages/nb.xml delete mode 100644 adm_plugins/login_form/languages/nl.xml delete mode 100644 adm_plugins/login_form/languages/pl.xml delete mode 100644 adm_plugins/login_form/languages/pt-BR.xml delete mode 100644 adm_plugins/login_form/languages/pt.xml delete mode 100644 adm_plugins/login_form/languages/ru.xml delete mode 100644 adm_plugins/login_form/languages/sv.xml delete mode 100644 adm_plugins/login_form/languages/uk.xml delete mode 100644 adm_plugins/login_form/languages/zh.xml diff --git a/adm_plugins/LoginForm/LoginForm.json b/adm_plugins/LoginForm/LoginForm.json new file mode 100644 index 0000000000..e5af107773 --- /dev/null +++ b/adm_plugins/LoginForm/LoginForm.json @@ -0,0 +1,53 @@ +{ + "name": "PLG_LOGIN_FORM_PLUGIN_NAME", + "description": "PLG_LOGIN_FORM_PLUGIN_DESCRIPTION", + "version": "1.0.0", + "author": "Admidio Team", + "url": "https://www.admidio.org", + "icon": "bi-box-arrow-in-right", + "mainFile": "index.php", + "dependencies": [], + "defaultConfig": { + "login_form_plugin_enabled": { + "name": "ORG_ACCESS_TO_PLUGIN", + "description": "ORG_ACCESS_TO_PLUGIN_DESC", + "type": "integer", + "value" : 1 + }, + "login_form_plugin_show_register_link": { + "name": "PLG_LOGIN_FORM_PREFERENCES_SHOW_REGISTER_LINK", + "description": "PLG_LOGIN_FORM_PREFERENCES_SHOW_REGISTER_LINK_DESC", + "type": "boolean", + "value" : false + }, + "login_form_plugin_show_email_link": { + "name": "PLG_LOGIN_FORM_PREFERENCES_SHOW_EMAIL_LINK", + "description": "PLG_LOGIN_FORM_PREFERENCES_SHOW_EMAIL_LINK_DESC", + "type": "boolean", + "value" : true + }, + "login_form_plugin_show_logout_link": { + "name": "PLG_LOGIN_FORM_PREFERENCES_SHOW_LOGOUT_LINK", + "description": "PLG_LOGIN_FORM_PREFERENCES_SHOW_LOGOUT_LINK_DESC", + "type": "boolean", + "value" : false + }, + "login_form_plugin_enable_ranks": { + "name": "PLG_LOGIN_FORM_PREFERENCES_ENABLE_RANKS", + "description": "PLG_LOGIN_FORM_PREFERENCES_ENABLE_RANKS_DESC", + "type": "boolean", + "value" : true + }, + "login_form_plugin_ranks": { + "name": "PLG_LOGIN_FORM_PREFERENCES_RANKS", + "description": "PLG_LOGIN_FORM_PREFERENCES_RANKS_DESC", + "type": "array", + "value" : { + "0": "PLG_LOGIN_FORM_NEW_ONLINE_MEMBER", + "50": "PLG_LOGIN_FORM_ONLINE_MEMBER", + "100": "PLG_LOGIN_FORM_SENIOR_ONLINE_MEMBER", + "200": "PLG_LOGIN_FORM_HONORARY_MEMBER" + } + } + } +} \ No newline at end of file diff --git a/adm_plugins/login_form/index.php b/adm_plugins/LoginForm/classes/LoginForm.php similarity index 56% rename from adm_plugins/login_form/index.php rename to adm_plugins/LoginForm/classes/LoginForm.php index d2fa55ee96..e4bda665d3 100644 --- a/adm_plugins/login_form/index.php +++ b/adm_plugins/LoginForm/classes/LoginForm.php @@ -1,8 +1,17 @@ 0) { + if (self::$pluginConfig['login_form_plugin_enable_ranks']) { $currentUserRankTitle = ''; - $rankTitle = reset($plg_rank); + $rankTitle = reset(self::$pluginConfig['login_form_plugin_ranks']); while ($rankTitle !== false) { - $rankAssessment = key($plg_rank); + $rankAssessment = key(self::$pluginConfig['login_form_plugin_ranks']); if ($rankAssessment < $gCurrentUser->getValue('usr_number_login')) { $currentUserRankTitle = $rankTitle; } - $rankTitle = next($plg_rank); + $rankTitle = next(self::$pluginConfig['login_form_plugin_ranks']); } if ($currentUserRankTitle !== '') { - $htmlUserRank = ' (' . $currentUserRankTitle . ')'; + $loginData['htmlUserRank'] = ' (' . Language::translateIfTranslationStrId($currentUserRankTitle) . ')'; } } if ($gCurrentUser->getValue('usr_last_login') === '') { - $lastLogin = '---'; + $loginData['lastLogin'] = '---'; } else { - $lastLogin = $gCurrentUser->getValue('usr_last_login'); + $loginData['lastLogin'] = $gCurrentUser->getValue('usr_last_login'); } - $loginFormPlugin->assignTemplateVariable('userUUID', $gCurrentUser->getValue('usr_uuid')); - $loginFormPlugin->assignTemplateVariable('userName', $gCurrentUser->getValue('FIRST_NAME') . ' ' . $gCurrentUser->getValue('LAST_NAME')); - $loginFormPlugin->assignTemplateVariable('loginActiveSince', $gCurrentSession->getValue('ses_begin', $gSettingsManager->getString('system_time'))); - $loginFormPlugin->assignTemplateVariable('lastLogin', $lastLogin); - $loginFormPlugin->assignTemplateVariable('numberOfLogins', $gCurrentUser->getValue('usr_number_login') . $htmlUserRank); - $loginFormPlugin->assignTemplateVariable('showLogoutLink', $plg_show_logout_link); - - if (isset($page)) { - echo $loginFormPlugin->html('plugin.login-form.view.tpl'); - } else { - $loginFormPlugin->showHtmlPage('plugin.login-form.view.tpl'); - } - } else { - // create and show the login form + return $loginData; + } + /** + * @brief Creates the login form + * @return FormPresenter Returns the login form presenter + */ + private static function createLoginForm() : FormPresenter + { + global $gL10n, $gDb, $gCurrentOrgId, $gSettingsManager, $gCurrentOrganization; + // preselected organization should be set by query parameter $getOrganizationShortName = admFuncVariableIsValid($_GET, 'organization_short_name', 'string'); if ($getOrganizationShortName === '') { $getOrganizationShortName = $gCurrentOrganization->getValue('org_shortname'); } - if ($plg_show_email_link) { + if (self::$pluginConfig['login_form_plugin_show_email_link']) { // read id of administrator role $sql = 'SELECT MIN(rol_id) as rol_id FROM ' . TBL_ROLES . ' @@ -123,7 +106,7 @@ // show link to send mail with local mail-client to administrator $linkUrl = SecurityUtils::encodeUrl('mailto:' . $gCurrentOrganization->getValue('org_email_administrator'), array('subject' => $gL10n->get('SYS_LOGIN_PROBLEMS'))); } - $forgotPasswordLink = '' . $gL10n->get('SYS_PASSWORD_FORGOTTEN') . ''; + $forgotPasswordLink = '' . $linkText . ''; } else { $forgotPasswordLink = ''; } @@ -180,13 +163,62 @@ } $form->addSubmitButton('plg_btn_login', $gL10n->get('SYS_LOGIN'), array('icon' => 'bi-box-arrow-in-right')); - $smarty = $loginFormPlugin->createSmartyObject(); - $smarty->assign('settings', $gSettingsManager); - $smarty->assign('showRegisterLink', $plg_show_register_link); - $form->addToSmarty($smarty); - $gCurrentSession->addFormObject($form); - echo $smarty->fetch('plugin.login-form.edit.tpl'); + return $form; + } + + /** + * @param PagePresenter $page + * @throws InvalidArgumentException + * @throws Exception + * @return bool + */ + public static function doRender($page = null) : bool + { + global $gSettingsManager, $gCurrentUser, $gCurrentSession, $gValidLogin, $gL10n; + + // show the latest documents & files list + try { + $rootPath = dirname(__DIR__, 3); + $pluginFolder = basename(self::$pluginPath); + + require_once($rootPath . '/system/common.php'); + + $loginFormPlugin = new Overview($pluginFolder); + self::$pluginConfig = self::getPluginConfigValues(); + + // check if the plugin is enabled + if (self::$pluginConfig['login_form_plugin_enabled'] === 1 || ($gValidLogin && self::$pluginConfig['login_form_plugin_enabled'] === 2 && $gValidLogin)) { + if ($gValidLogin) { + $loginData = self::getLoginData(); + $loginFormPlugin->assignTemplateVariable('userUUID', $gCurrentUser->getValue('usr_uuid')); + $loginFormPlugin->assignTemplateVariable('userName', $gCurrentUser->getValue('FIRST_NAME') . ' ' . $gCurrentUser->getValue('LAST_NAME')); + $loginFormPlugin->assignTemplateVariable('loginActiveSince', $gCurrentSession->getValue('ses_begin', $gSettingsManager->getString('system_time'))); + $loginFormPlugin->assignTemplateVariable('lastLogin', $loginData['lastLogin']); + $loginFormPlugin->assignTemplateVariable('numberOfLogins', $gCurrentUser->getValue('usr_number_login') . $loginData['htmlUserRank']); + $loginFormPlugin->assignTemplateVariable('showLogoutLink', self::$pluginConfig['login_form_plugin_show_logout_link']); + + if (isset($page)) { + echo $loginFormPlugin->html('plugin.login-form.view.tpl'); + } else { + $loginFormPlugin->showHtmlPage('plugin.login-form.view.tpl'); + } + } else { + $form = self::createLoginForm(); + $smarty = $loginFormPlugin->createSmartyObject(); + $smarty->assign('settings', $gSettingsManager); + $smarty->assign('showRegisterLink', self::$pluginConfig['login_form_plugin_show_register_link']); + $form->addToSmarty($smarty); + $gCurrentSession->addFormObject($form); + echo $smarty->fetch('plugin.login-form.edit.tpl'); + } + } else { + throw new InvalidArgumentException($gL10n->get('SYS_INVALID_PAGE_VIEW')); + } + + } catch (Throwable $e) { + echo $e->getMessage(); + } + + return true; } -} catch (Throwable $e) { - echo $e->getMessage(); -} +} \ No newline at end of file diff --git a/adm_plugins/LoginForm/classes/Presenter/LoginFormPreferencesPresenter.php b/adm_plugins/LoginForm/classes/Presenter/LoginFormPreferencesPresenter.php new file mode 100644 index 0000000000..f100cb3280 --- /dev/null +++ b/adm_plugins/LoginForm/classes/Presenter/LoginFormPreferencesPresenter.php @@ -0,0 +1,107 @@ + 'save', 'panel' => 'login_form')), + null, + array('class' => 'form-preferences') + ); + $selectBoxEntries = array( + '0' => $gL10n->get('SYS_DISABLED'), + '1' => $gL10n->get('SYS_ENABLED'), + '2' => $gL10n->get('ORG_ONLY_FOR_REGISTERED_USER') + ); + $formLoginForm->addSelectBox( + 'login_form_plugin_enabled', + Language::translateIfTranslationStrId($formValues['login_form_plugin_enabled']['name']), + $selectBoxEntries, + array('defaultValue' => $formValues['login_form_plugin_enabled']['value'], 'showContextDependentFirstEntry' => false, 'helpTextId' => $formValues['login_form_plugin_enabled']['description']) + ); + $formLoginForm->addCheckbox( + 'login_form_plugin_show_register_link', + Language::translateIfTranslationStrId($formValues['login_form_plugin_show_register_link']['name']), + $formValues['login_form_plugin_show_register_link']['value'], + array('helpTextId' => $formValues['login_form_plugin_show_register_link']['description']) + ); + $formLoginForm->addCheckbox( + 'login_form_plugin_show_email_link', + Language::translateIfTranslationStrId($formValues['login_form_plugin_show_email_link']['name']), + $formValues['login_form_plugin_show_email_link']['value'], + array('helpTextId' => $formValues['login_form_plugin_show_email_link']['description']) + ); + $formLoginForm->addCheckbox( + 'login_form_plugin_show_logout_link', + Language::translateIfTranslationStrId($formValues['login_form_plugin_show_logout_link']['name']), + $formValues['login_form_plugin_show_logout_link']['value'], + array('helpTextId' => $formValues['login_form_plugin_show_logout_link']['description']) + ); + $formLoginForm->addCheckbox( + 'login_form_plugin_enable_ranks', + Language::translateIfTranslationStrId($formValues['login_form_plugin_enable_ranks']['name']), + $formValues['login_form_plugin_enable_ranks']['value'], + array('helpTextId' => $formValues['login_form_plugin_enable_ranks']['description']) + ); + $content = ''; + // create a table with the ranks + $content .= ''; + $content .= ''; + $content .= ''; + foreach ($formValues['login_form_plugin_ranks']['value'] as $numLogins => $rankName) { + $content .= ''; + $content .= ''; + $content .= ''; + $content .= ''; + } + $content .= '
' . $gL10n->get('PLG_LOGIN_FORM_NUMBER_OF_LOGINS') . '' . $gL10n->get('PLG_LOGIN_FORM_MEMBERRANK') . '
' . htmlspecialchars($numLogins) . '' . Language::translateIfTranslationStrId($rankName) . '
'; + $formLoginForm->addCustomContent( + 'login_form_plugin_ranks', + Language::translateIfTranslationStrId($formValues['login_form_plugin_ranks']['name']), + $content, + array('helpTextId' => $formValues['login_form_plugin_ranks']['description']) + ); + + $formLoginForm->addSubmitButton( + 'adm_button_save_login_form', + $gL10n->get('SYS_SAVE'), + array('icon' => 'bi-check-lg', 'class' => 'offset-sm-3') + ); + + $formLoginForm->addToSmarty($smarty); + $gCurrentSession->addFormObject($formLoginForm); + return $smarty->fetch($pluginLoginForm::getPluginPath() . '/templates/preferences.plugin.login-form.tpl'); + } +} \ No newline at end of file diff --git a/adm_plugins/LoginForm/db_scripts/update_1_0.xml b/adm_plugins/LoginForm/db_scripts/update_1_0.xml new file mode 100644 index 0000000000..dfd925e361 --- /dev/null +++ b/adm_plugins/LoginForm/db_scripts/update_1_0.xml @@ -0,0 +1,6 @@ + + + UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'LoginForm' + UPDATE %PREFIX%_components SET com_plg_sequence = 1 WHERE com_type = 'ADM_PLUGIN' AND com_name_intern = 'LoginForm' + stop + diff --git a/adm_plugins/LoginForm/index.php b/adm_plugins/LoginForm/index.php new file mode 100644 index 0000000000..5a89d8a0d2 --- /dev/null +++ b/adm_plugins/LoginForm/index.php @@ -0,0 +1,25 @@ +doRender(isset($page) ? $page : null); + +} catch (Throwable $e) { + echo $e->getMessage(); +} diff --git a/adm_plugins/LoginForm/languages/bg.xml b/adm_plugins/LoginForm/languages/bg.xml new file mode 100644 index 0000000000..8e6acb2c6d --- /dev/null +++ b/adm_plugins/LoginForm/languages/bg.xml @@ -0,0 +1,10 @@ + + + Активен от + Хоноруван участник + Последно влизане + Нов онлайн участник + Брой влизания + Онлайн участник + Старши онлайн участник + diff --git a/adm_plugins/LoginForm/languages/da.xml b/adm_plugins/LoginForm/languages/da.xml new file mode 100644 index 0000000000..905e00da6b --- /dev/null +++ b/adm_plugins/LoginForm/languages/da.xml @@ -0,0 +1,10 @@ + + + Aktiv siden + Æresmedlem + Sidste login + Nyt online medlem + Antal logins + Online medlem + Senior online medlem + diff --git a/adm_plugins/LoginForm/languages/de-DE.xml b/adm_plugins/LoginForm/languages/de-DE.xml new file mode 100644 index 0000000000..3f495923a8 --- /dev/null +++ b/adm_plugins/LoginForm/languages/de-DE.xml @@ -0,0 +1,10 @@ + + + Aktiv seit + Ehrenmitglied + Letzter Login + Neues Onlinemitglied + Anzahl Logins + Onlinemitglied + Senior Onlinemitglied + diff --git a/adm_plugins/LoginForm/languages/de.xml b/adm_plugins/LoginForm/languages/de.xml new file mode 100644 index 0000000000..3f495923a8 --- /dev/null +++ b/adm_plugins/LoginForm/languages/de.xml @@ -0,0 +1,10 @@ + + + Aktiv seit + Ehrenmitglied + Letzter Login + Neues Onlinemitglied + Anzahl Logins + Onlinemitglied + Senior Onlinemitglied + diff --git a/adm_plugins/LoginForm/languages/el.xml b/adm_plugins/LoginForm/languages/el.xml new file mode 100644 index 0000000000..aa2ff7b90c --- /dev/null +++ b/adm_plugins/LoginForm/languages/el.xml @@ -0,0 +1,10 @@ + + + Ενεργός από + Επίτιμο μέλος + Τελευταία είσοδος + Νέο online μέλος + Αριθμός εισόδων + Online μέλος + Παλαιότερο online μέλος + diff --git a/adm_plugins/LoginForm/languages/en.xml b/adm_plugins/LoginForm/languages/en.xml new file mode 100644 index 0000000000..9f965f2a16 --- /dev/null +++ b/adm_plugins/LoginForm/languages/en.xml @@ -0,0 +1,24 @@ + + + Active since + Honorary member + Last login + New online member + Number of logins + Online member + Senior online member + This plugin displays a login form for a user to log in on the Overview page. If the user is logged in, useful information of the user is now displayed in the place of the fields. + Login Form + Member rank + + Show registration link + If this option is enabled, a link to the registration form will be displayed in the login form. (default: false) + Show email link + If this option is enabled, a link to send an email to the administrator if you have login problems will be displayed in the login form. (default: true) + Show logout link + If this option is enabled, a link to log out will be displayed after login. (default: false) + Show ranks + If this option is enabled, a rank depending on the number of logins will be displayed after the username. (default: true) + Ranks + Here you can define the ranks that will be displayed after the username if \'Show ranks\' is enabled. The key is the number of logins and the value is the name of the rank. + diff --git a/adm_plugins/LoginForm/languages/es.xml b/adm_plugins/LoginForm/languages/es.xml new file mode 100644 index 0000000000..b60537166c --- /dev/null +++ b/adm_plugins/LoginForm/languages/es.xml @@ -0,0 +1,10 @@ + + + Activo desde + Miembro honorario + Última sesión + Nuevo miembro en línea + Número de sesiónes + Miembro en línea + Miembro mayor en línea + diff --git a/adm_plugins/LoginForm/languages/et.xml b/adm_plugins/LoginForm/languages/et.xml new file mode 100644 index 0000000000..73b35e6865 --- /dev/null +++ b/adm_plugins/LoginForm/languages/et.xml @@ -0,0 +1,10 @@ + + + Aktiivne alates + Auliige + Viimane sisselogimine + Uus võrguliige + Sisselogimiste arv + Online liige + Vanem võrguliige + diff --git a/adm_plugins/LoginForm/languages/fi.xml b/adm_plugins/LoginForm/languages/fi.xml new file mode 100644 index 0000000000..47402f8aa2 --- /dev/null +++ b/adm_plugins/LoginForm/languages/fi.xml @@ -0,0 +1,10 @@ + + + Aktiivinen + Kunniajäsen + Viime kirjautuminen + uusi on-line jäsen + Kirjautumisia + On-line jäsen + Vanhempi on-line jäsen + diff --git a/adm_plugins/LoginForm/languages/fr.xml b/adm_plugins/LoginForm/languages/fr.xml new file mode 100644 index 0000000000..02e9ebf6b4 --- /dev/null +++ b/adm_plugins/LoginForm/languages/fr.xml @@ -0,0 +1,10 @@ + + + Actif depuis + Membre honoraire + Dernière connexion + Nouveau membre en ligne + Nombre de connexions + Membre en ligne + Membre senior en ligne + diff --git a/adm_plugins/LoginForm/languages/hu.xml b/adm_plugins/LoginForm/languages/hu.xml new file mode 100644 index 0000000000..d1ce901aab --- /dev/null +++ b/adm_plugins/LoginForm/languages/hu.xml @@ -0,0 +1,10 @@ + + + Aktív + Tiszteletbeli tag + Utolsó bejelentkezés + Új online tag + Bejelentkezések száma + Online tag + Rangidős online tag + diff --git a/adm_plugins/LoginForm/languages/it.xml b/adm_plugins/LoginForm/languages/it.xml new file mode 100644 index 0000000000..cd5a886772 --- /dev/null +++ b/adm_plugins/LoginForm/languages/it.xml @@ -0,0 +1,10 @@ + + + Attivo da + Membro onorario + Ultimo accesso + Nuovo membro online + Numero di accessi + Membro online + Senior membro online + diff --git a/adm_plugins/LoginForm/languages/nb.xml b/adm_plugins/LoginForm/languages/nb.xml new file mode 100644 index 0000000000..281868a58e --- /dev/null +++ b/adm_plugins/LoginForm/languages/nb.xml @@ -0,0 +1,10 @@ + + + Aktiv siden + Æresmedlem + Siste innlogging + Nytt onlinemedlem + Antall pålogginger + Onlinemedlem + Senior onlinemedlem + diff --git a/adm_plugins/LoginForm/languages/nl.xml b/adm_plugins/LoginForm/languages/nl.xml new file mode 100644 index 0000000000..d9d4a0063d --- /dev/null +++ b/adm_plugins/LoginForm/languages/nl.xml @@ -0,0 +1,10 @@ + + + Actief sinds + Erelid + Laatst ingelogd + Nieuw lid online + Aantal keer ingelogd + Online lid + Online senior lid + diff --git a/adm_plugins/LoginForm/languages/pl.xml b/adm_plugins/LoginForm/languages/pl.xml new file mode 100644 index 0000000000..71e02ad2e4 --- /dev/null +++ b/adm_plugins/LoginForm/languages/pl.xml @@ -0,0 +1,10 @@ + + + Aktywny/a od + Honorowy członek + Ostatnie logowanie + Nowy członek online + Ilość logowań + Członek online + Przełożony online + diff --git a/adm_plugins/LoginForm/languages/pt-BR.xml b/adm_plugins/LoginForm/languages/pt-BR.xml new file mode 100644 index 0000000000..d03761bd91 --- /dev/null +++ b/adm_plugins/LoginForm/languages/pt-BR.xml @@ -0,0 +1,10 @@ + + + Ativo desde + Membro honorário + Última Sessão + Novo Membro Ativo + Número de Sessões + Membro Ativo + Membro Sénior Ativo + diff --git a/adm_plugins/LoginForm/languages/pt.xml b/adm_plugins/LoginForm/languages/pt.xml new file mode 100644 index 0000000000..185edb7f00 --- /dev/null +++ b/adm_plugins/LoginForm/languages/pt.xml @@ -0,0 +1,10 @@ + + + Ativo desde + Membro honorário + Última sessão + Novo membro on-line + Número de sessões + Membro on-line + Membro sénior on-line + diff --git a/adm_plugins/LoginForm/languages/ru.xml b/adm_plugins/LoginForm/languages/ru.xml new file mode 100644 index 0000000000..256895fbe0 --- /dev/null +++ b/adm_plugins/LoginForm/languages/ru.xml @@ -0,0 +1,10 @@ + + + Активен с + Почетный участник + Последний вход + Новый участник + Количество входов + Участник + Старший участник + diff --git a/adm_plugins/LoginForm/languages/sv.xml b/adm_plugins/LoginForm/languages/sv.xml new file mode 100644 index 0000000000..425aa48bb5 --- /dev/null +++ b/adm_plugins/LoginForm/languages/sv.xml @@ -0,0 +1,10 @@ + + + Aktiv från + Hedersmedlem + Senaste login + Ny online-medlem + Antal logins + Online-medlem + Senior online-medlem + diff --git a/adm_plugins/LoginForm/languages/uk.xml b/adm_plugins/LoginForm/languages/uk.xml new file mode 100644 index 0000000000..df3bad6b65 --- /dev/null +++ b/adm_plugins/LoginForm/languages/uk.xml @@ -0,0 +1,10 @@ + + + Активний з + Почесний член + Останній вхід + Новий онлайн-учасник + Кількість логінів + Онлайн-учасник + Старший онлайн-учасник + diff --git a/adm_plugins/LoginForm/languages/zh.xml b/adm_plugins/LoginForm/languages/zh.xml new file mode 100644 index 0000000000..be8b4c6ae8 --- /dev/null +++ b/adm_plugins/LoginForm/languages/zh.xml @@ -0,0 +1,10 @@ + + + 活跃至今 + 荣誉会员 + 上次登录 + 新的在线会员 + 登录次数 + 在线会员 + 高级在线会员 + diff --git a/adm_plugins/login_form/templates/plugin.login-form.edit.tpl b/adm_plugins/LoginForm/templates/plugin.login-form.edit.tpl similarity index 100% rename from adm_plugins/login_form/templates/plugin.login-form.edit.tpl rename to adm_plugins/LoginForm/templates/plugin.login-form.edit.tpl diff --git a/adm_plugins/login_form/templates/plugin.login-form.view.tpl b/adm_plugins/LoginForm/templates/plugin.login-form.view.tpl similarity index 86% rename from adm_plugins/login_form/templates/plugin.login-form.view.tpl rename to adm_plugins/LoginForm/templates/plugin.login-form.view.tpl index 282d943b09..639b5cd45d 100644 --- a/adm_plugins/login_form/templates/plugin.login-form.view.tpl +++ b/adm_plugins/LoginForm/templates/plugin.login-form.view.tpl @@ -13,7 +13,7 @@
- {$l10n->get('PLG_LOGIN_ACTIVE_SINCE')} + {$l10n->get('PLG_LOGIN_FORM_ACTIVE_SINCE')}
{$loginActiveSince} @@ -21,7 +21,7 @@
- {$l10n->get('PLG_LOGIN_LAST_LOGIN')} + {$l10n->get('PLG_LOGIN_FORM_LAST_LOGIN')}
{$lastLogin} @@ -29,7 +29,7 @@
- {$l10n->get('PLG_LOGIN_NUMBER_OF_LOGINS')} + {$l10n->get('PLG_LOGIN_FORM_NUMBER_OF_LOGINS')}
{$numberOfLogins} diff --git a/adm_plugins/LoginForm/templates/preferences.plugin.login-form.tpl b/adm_plugins/LoginForm/templates/preferences.plugin.login-form.tpl new file mode 100644 index 0000000000..6876560259 --- /dev/null +++ b/adm_plugins/LoginForm/templates/preferences.plugin.login-form.tpl @@ -0,0 +1,16 @@ +
+ + {include 'sys-template-parts/form.input.tpl' data=$elements['adm_csrf_token']} + {include 'sys-template-parts/form.select.tpl' data=$elements['login_form_plugin_enabled']} + {include 'sys-template-parts/form.checkbox.tpl' data=$elements['login_form_plugin_show_register_link']} + {include 'sys-template-parts/form.checkbox.tpl' data=$elements['login_form_plugin_show_email_link']} + {include 'sys-template-parts/form.checkbox.tpl' data=$elements['login_form_plugin_show_logout_link']} + {include 'sys-template-parts/form.checkbox.tpl' data=$elements['login_form_plugin_enable_ranks']} + {include 'sys-template-parts/form.custom-content.tpl' data=$elements['login_form_plugin_ranks']} + {include 'sys-template-parts/form.button.tpl' data=$elements['adm_button_save_login_form']} + + +
+{$javascript} \ No newline at end of file diff --git a/adm_plugins/login_form/config_sample.php b/adm_plugins/login_form/config_sample.php deleted file mode 100644 index a724e42eae..0000000000 --- a/adm_plugins/login_form/config_sample.php +++ /dev/null @@ -1,38 +0,0 @@ - $gL10n->get('PLG_LOGIN_NEW_ONLINE_MEMBER'), - '50' => $gL10n->get('PLG_LOGIN_ONLINE_MEMBER'), - '100' => $gL10n->get('PLG_LOGIN_SENIOR_ONLINE_MEMBER'), - '200' => $gL10n->get('PLG_LOGIN_HONORARY_MEMBER') - ); diff --git a/adm_plugins/login_form/languages/bg.xml b/adm_plugins/login_form/languages/bg.xml deleted file mode 100644 index 7f07d30bbd..0000000000 --- a/adm_plugins/login_form/languages/bg.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Активен от - Хоноруван участник - Последно влизане - Нов онлайн участник - Брой влизания - Онлайн участник - Старши онлайн участник - diff --git a/adm_plugins/login_form/languages/da.xml b/adm_plugins/login_form/languages/da.xml deleted file mode 100644 index 51526f8023..0000000000 --- a/adm_plugins/login_form/languages/da.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Aktiv siden - Æresmedlem - Sidste login - Nyt online medlem - Antal logins - Online medlem - Senior online medlem - diff --git a/adm_plugins/login_form/languages/de-DE.xml b/adm_plugins/login_form/languages/de-DE.xml deleted file mode 100644 index 2d979f05c2..0000000000 --- a/adm_plugins/login_form/languages/de-DE.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Aktiv seit - Ehrenmitglied - Letzter Login - Neues Onlinemitglied - Anzahl Logins - Onlinemitglied - Senior Onlinemitglied - diff --git a/adm_plugins/login_form/languages/de.xml b/adm_plugins/login_form/languages/de.xml deleted file mode 100644 index 2d979f05c2..0000000000 --- a/adm_plugins/login_form/languages/de.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Aktiv seit - Ehrenmitglied - Letzter Login - Neues Onlinemitglied - Anzahl Logins - Onlinemitglied - Senior Onlinemitglied - diff --git a/adm_plugins/login_form/languages/el.xml b/adm_plugins/login_form/languages/el.xml deleted file mode 100644 index 7f68b8dd43..0000000000 --- a/adm_plugins/login_form/languages/el.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Ενεργός από - Επίτιμο μέλος - Τελευταία είσοδος - Νέο online μέλος - Αριθμός εισόδων - Online μέλος - Παλαιότερο online μέλος - diff --git a/adm_plugins/login_form/languages/en.xml b/adm_plugins/login_form/languages/en.xml deleted file mode 100644 index c84d77c370..0000000000 --- a/adm_plugins/login_form/languages/en.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Active since - Honorary member - Last login - New online member - Number of logins - Online member - Senior online member - diff --git a/adm_plugins/login_form/languages/es.xml b/adm_plugins/login_form/languages/es.xml deleted file mode 100644 index 53f2483a74..0000000000 --- a/adm_plugins/login_form/languages/es.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Activo desde - Miembro honorario - Última sesión - Nuevo miembro en línea - Número de sesiónes - Miembro en línea - Miembro mayor en línea - diff --git a/adm_plugins/login_form/languages/et.xml b/adm_plugins/login_form/languages/et.xml deleted file mode 100644 index b2ec6f219a..0000000000 --- a/adm_plugins/login_form/languages/et.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Aktiivne alates - Auliige - Viimane sisselogimine - Uus võrguliige - Sisselogimiste arv - Online liige - Vanem võrguliige - diff --git a/adm_plugins/login_form/languages/fi.xml b/adm_plugins/login_form/languages/fi.xml deleted file mode 100755 index 903c167c68..0000000000 --- a/adm_plugins/login_form/languages/fi.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Aktiivinen - Kunniajäsen - Viime kirjautuminen - uusi on-line jäsen - Kirjautumisia - On-line jäsen - Vanhempi on-line jäsen - diff --git a/adm_plugins/login_form/languages/fr.xml b/adm_plugins/login_form/languages/fr.xml deleted file mode 100644 index 6903ebc2c3..0000000000 --- a/adm_plugins/login_form/languages/fr.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Actif depuis - Membre honoraire - Dernière connexion - Nouveau membre en ligne - Nombre de connexions - Membre en ligne - Membre senior en ligne - diff --git a/adm_plugins/login_form/languages/hu.xml b/adm_plugins/login_form/languages/hu.xml deleted file mode 100644 index bb58ab8a77..0000000000 --- a/adm_plugins/login_form/languages/hu.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Aktív - Tiszteletbeli tag - Utolsó bejelentkezés - Új online tag - Bejelentkezések száma - Online tag - Rangidős online tag - diff --git a/adm_plugins/login_form/languages/it.xml b/adm_plugins/login_form/languages/it.xml deleted file mode 100644 index 2ae9f6ee3d..0000000000 --- a/adm_plugins/login_form/languages/it.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Attivo da - Membro onorario - Ultimo accesso - Nuovo membro online - Numero di accessi - Membro online - Senior membro online - diff --git a/adm_plugins/login_form/languages/nb.xml b/adm_plugins/login_form/languages/nb.xml deleted file mode 100644 index 0f97241d24..0000000000 --- a/adm_plugins/login_form/languages/nb.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Aktiv siden - Æresmedlem - Siste innlogging - Nytt onlinemedlem - Antall pålogginger - Onlinemedlem - Senior onlinemedlem - diff --git a/adm_plugins/login_form/languages/nl.xml b/adm_plugins/login_form/languages/nl.xml deleted file mode 100644 index 53a00e356a..0000000000 --- a/adm_plugins/login_form/languages/nl.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Actief sinds - Erelid - Laatst ingelogd - Nieuw lid online - Aantal keer ingelogd - Online lid - Online senior lid - diff --git a/adm_plugins/login_form/languages/pl.xml b/adm_plugins/login_form/languages/pl.xml deleted file mode 100644 index c79c0b5e22..0000000000 --- a/adm_plugins/login_form/languages/pl.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Aktywny/a od - Honorowy członek - Ostatnie logowanie - Nowy członek online - Ilość logowań - Członek online - Przełożony online - diff --git a/adm_plugins/login_form/languages/pt-BR.xml b/adm_plugins/login_form/languages/pt-BR.xml deleted file mode 100644 index b3263cdb08..0000000000 --- a/adm_plugins/login_form/languages/pt-BR.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Ativo desde - Membro honorário - Última Sessão - Novo Membro Ativo - Número de Sessões - Membro Ativo - Membro Sénior Ativo - diff --git a/adm_plugins/login_form/languages/pt.xml b/adm_plugins/login_form/languages/pt.xml deleted file mode 100644 index f4337829b1..0000000000 --- a/adm_plugins/login_form/languages/pt.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Ativo desde - Membro honorário - Última sessão - Novo membro on-line - Número de sessões - Membro on-line - Membro sénior on-line - diff --git a/adm_plugins/login_form/languages/ru.xml b/adm_plugins/login_form/languages/ru.xml deleted file mode 100644 index 3697229b65..0000000000 --- a/adm_plugins/login_form/languages/ru.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Активен с - Почетный участник - Последний вход - Новый участник - Количество входов - Участник - Старший участник - diff --git a/adm_plugins/login_form/languages/sv.xml b/adm_plugins/login_form/languages/sv.xml deleted file mode 100644 index cd2810720f..0000000000 --- a/adm_plugins/login_form/languages/sv.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Aktiv från - Hedersmedlem - Senaste login - Ny online-medlem - Antal logins - Online-medlem - Senior online-medlem - diff --git a/adm_plugins/login_form/languages/uk.xml b/adm_plugins/login_form/languages/uk.xml deleted file mode 100644 index 632bcdc5df..0000000000 --- a/adm_plugins/login_form/languages/uk.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Активний з - Почесний член - Останній вхід - Новий онлайн-учасник - Кількість логінів - Онлайн-учасник - Старший онлайн-учасник - diff --git a/adm_plugins/login_form/languages/zh.xml b/adm_plugins/login_form/languages/zh.xml deleted file mode 100644 index 14e4a47b2b..0000000000 --- a/adm_plugins/login_form/languages/zh.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - 活跃至今 - 荣誉会员 - 上次登录 - 新的在线会员 - 登录次数 - 在线会员 - 高级在线会员 - From 5e471aede03cb2dcdcb2459f4d5ba23dc4391929 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 23 Jul 2025 19:08:09 +0200 Subject: [PATCH 023/109] feat: enhance plugin configuration handling and improve login validation for overview plugins --- src/Infrastructure/Plugins/PluginAbstract.php | 19 +++++++++++++++++-- src/Infrastructure/Plugins/PluginManager.php | 4 +++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/Infrastructure/Plugins/PluginAbstract.php b/src/Infrastructure/Plugins/PluginAbstract.php index 4b3653b971..ead8249b34 100644 --- a/src/Infrastructure/Plugins/PluginAbstract.php +++ b/src/Infrastructure/Plugins/PluginAbstract.php @@ -286,7 +286,14 @@ public static function getPluginConfigValues() : array break; case 'array': $valueString = $gSettingsManager->get($key); - $config[$key] = $valueString === "" ? array() : explode(',', $valueString); + if ($gSettingsManager->has($key . '_keys')) { + // if the keys are stored separately, use them to create the array + $keyString = $gSettingsManager->get($key . '_keys'); + $config[$key] = $valueString === "" ? array() : array_combine(explode(',', $keyString), explode(',', $valueString)); + } else { + // if no keys are stored, use the value string as the value + $config[$key] = $valueString === "" ? array() : explode(',', $valueString); + } break; case 'string': default: @@ -440,7 +447,15 @@ public static function doInstall() : bool } // insert default plugin config values into the database - $gSettingsManager->setMulti(self::getPluginConfigValues()); + $configValues = self::getPluginConfigValues(); + foreach ($configValues as $key => $value) { + if (is_array($value)) { + $gSettingsManager->set($key, implode(',', $value)); + $gSettingsManager->set($key . '_keys', implode(',', array_keys($value))); + } else { + $gSettingsManager->set($key, $value); + } + } // install the plugin $componentUpdateHandle = new ComponentUpdate($gDb); diff --git a/src/Infrastructure/Plugins/PluginManager.php b/src/Infrastructure/Plugins/PluginManager.php index 134584e9c5..cadea57594 100644 --- a/src/Infrastructure/Plugins/PluginManager.php +++ b/src/Infrastructure/Plugins/PluginManager.php @@ -147,6 +147,8 @@ public function getInstalledPlugins() : array */ public function getOverviewPlugins() : array { + global $gValidLogin; + $availablePlugins = $this->getAvailablePlugins(); $overviewPlugins = array(); foreach ($availablePlugins as $plugin) { @@ -155,7 +157,7 @@ public function getOverviewPlugins() : array $configValues = $plugin['interface']->getPluginConfigValues(); $enabled = false; foreach ($configValues as $key => $value) { - if (preg_match('/_enabled$/', $key) && $value > 0) { + if (preg_match('/_enabled$/', $key) && $value === 1 || ($value === 2 && $gValidLogin)) { $enabled = true; break; } From abaf2b7e9797e56af5ac5fda840e840961c03ed6 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 23 Jul 2025 19:55:25 +0200 Subject: [PATCH 024/109] rebase random-photo overview-plugin to use PluginManager --- adm_plugins/RandomPhoto/RandomPhoto.json | 54 +++++++ .../RandomPhotoPreferencesPresenter.php | 100 ++++++++++++ .../RandomPhoto/classes/RandomPhoto.php | 150 ++++++++++++++++++ .../RandomPhoto/db_scripts/update_1_0.xml | 6 + adm_plugins/RandomPhoto/index.php | 24 +++ .../languages/bg.xml | 0 .../languages/da.xml | 0 .../languages/de-DE.xml | 0 .../languages/de.xml | 0 .../languages/el.xml | 0 adm_plugins/RandomPhoto/languages/en.xml | 19 +++ .../languages/et.xml | 0 .../languages/fi.xml | 0 .../languages/fr.xml | 0 .../languages/hu.xml | 0 .../languages/nb.xml | 0 .../languages/nl.xml | 0 .../languages/pl.xml | 0 .../languages/pt.xml | 0 .../languages/ru.xml | 0 .../languages/sv.xml | 0 .../languages/uk.xml | 0 .../templates/plugin.random-photo.tpl | 0 .../preferences.plugin.random-photo.tpl | 17 ++ adm_plugins/random_photo/config_sample.php | 43 ----- adm_plugins/random_photo/index.php | 127 --------------- adm_plugins/random_photo/languages/en.xml | 4 - 27 files changed, 370 insertions(+), 174 deletions(-) create mode 100644 adm_plugins/RandomPhoto/RandomPhoto.json create mode 100644 adm_plugins/RandomPhoto/classes/Presenter/RandomPhotoPreferencesPresenter.php create mode 100644 adm_plugins/RandomPhoto/classes/RandomPhoto.php create mode 100644 adm_plugins/RandomPhoto/db_scripts/update_1_0.xml create mode 100644 adm_plugins/RandomPhoto/index.php rename adm_plugins/{random_photo => RandomPhoto}/languages/bg.xml (100%) rename adm_plugins/{random_photo => RandomPhoto}/languages/da.xml (100%) rename adm_plugins/{random_photo => RandomPhoto}/languages/de-DE.xml (100%) rename adm_plugins/{random_photo => RandomPhoto}/languages/de.xml (100%) rename adm_plugins/{random_photo => RandomPhoto}/languages/el.xml (100%) create mode 100644 adm_plugins/RandomPhoto/languages/en.xml rename adm_plugins/{random_photo => RandomPhoto}/languages/et.xml (100%) rename adm_plugins/{random_photo => RandomPhoto}/languages/fi.xml (100%) mode change 100755 => 100644 rename adm_plugins/{random_photo => RandomPhoto}/languages/fr.xml (100%) rename adm_plugins/{random_photo => RandomPhoto}/languages/hu.xml (100%) rename adm_plugins/{random_photo => RandomPhoto}/languages/nb.xml (100%) rename adm_plugins/{random_photo => RandomPhoto}/languages/nl.xml (100%) rename adm_plugins/{random_photo => RandomPhoto}/languages/pl.xml (100%) rename adm_plugins/{random_photo => RandomPhoto}/languages/pt.xml (100%) rename adm_plugins/{random_photo => RandomPhoto}/languages/ru.xml (100%) rename adm_plugins/{random_photo => RandomPhoto}/languages/sv.xml (100%) rename adm_plugins/{random_photo => RandomPhoto}/languages/uk.xml (100%) rename adm_plugins/{random_photo => RandomPhoto}/templates/plugin.random-photo.tpl (100%) create mode 100644 adm_plugins/RandomPhoto/templates/preferences.plugin.random-photo.tpl delete mode 100644 adm_plugins/random_photo/config_sample.php delete mode 100644 adm_plugins/random_photo/index.php delete mode 100644 adm_plugins/random_photo/languages/en.xml diff --git a/adm_plugins/RandomPhoto/RandomPhoto.json b/adm_plugins/RandomPhoto/RandomPhoto.json new file mode 100644 index 0000000000..d37f3f618e --- /dev/null +++ b/adm_plugins/RandomPhoto/RandomPhoto.json @@ -0,0 +1,54 @@ +{ + "name": "PLG_RANDOM_PHOTO_PLUGIN_NAME", + "description": "PLG_RANDOM_PHOTO_PLUGIN_DESCRIPTION", + "version": "1.0.0", + "author": "Admidio Team", + "url": "https://www.admidio.org", + "icon": "bi-image-fill", + "mainFile": "index.php", + "dependencies": [], + "defaultConfig": { + "random_photo_plugin_enabled": { + "name": "ORG_ACCESS_TO_PLUGIN", + "description": "ORG_ACCESS_TO_PLUGIN_DESC", + "type": "integer", + "value" : 1 + }, + "random_photo_plugin_max_char_per_word": { + "name": "PLG_RANDOM_PHOTO_PREFERENCES_MAX_CHAR_PER_WORD", + "description": "PLG_RANDOM_PHOTO_PREFERENCES_MAX_CHAR_PER_WORD_DESC", + "type": "integer", + "value" : 0 + }, + "random_photo_plugin_max_width": { + "name": "PLG_RANDOM_PHOTO_PREFERENCES_MAX_WIDTH", + "description": "PLG_RANDOM_PHOTO_PREFERENCES_MAX_WIDTH_DESC", + "type": "integer", + "value" : 0 + }, + "random_photo_plugin_max_height": { + "name": "PLG_RANDOM_PHOTO_PREFERENCES_MAX_HEIGHT", + "description": "PLG_RANDOM_PHOTO_PREFERENCES_MAX_HEIGHT_DESC", + "type": "integer", + "value" : 0 + }, + "random_photo_plugin_albums": { + "name": "PLG_RANDOM_PHOTO_PREFERENCES_ALBUMS", + "description": "PLG_RANDOM_PHOTO_PREFERENCES_ALBUMS_DESC", + "type": "integer", + "value" : 0 + }, + "random_photo_plugin_album_photo_number": { + "name": "PLG_RANDOM_PHOTO_PREFERENCES_ALBUM_PHOTO_NUMBER", + "description": "PLG_RANDOM_PHOTO_PREFERENCES_ALBUM_PHOTO_NUMBER_DESC", + "type": "integer", + "value" : 0 + }, + "random_photo_plugin_show_album_link": { + "name": "PLG_RANDOM_PHOTO_PREFERENCES_SHOW_ALBUM_LINK", + "description": "PLG_RANDOM_PHOTO_PREFERENCES_SHOW_ALBUM_LINK_DESC", + "type": "boolean", + "value" : true + } + } +} \ No newline at end of file diff --git a/adm_plugins/RandomPhoto/classes/Presenter/RandomPhotoPreferencesPresenter.php b/adm_plugins/RandomPhoto/classes/Presenter/RandomPhotoPreferencesPresenter.php new file mode 100644 index 0000000000..d04d7cc084 --- /dev/null +++ b/adm_plugins/RandomPhoto/classes/Presenter/RandomPhotoPreferencesPresenter.php @@ -0,0 +1,100 @@ + 'save', 'panel' => 'random_photo')), + null, + array('class' => 'form-preferences') + ); + $selectBoxEntries = array( + '0' => $gL10n->get('SYS_DISABLED'), + '1' => $gL10n->get('SYS_ENABLED'), + '2' => $gL10n->get('ORG_ONLY_FOR_REGISTERED_USER') + ); + $formRandomPhoto->addSelectBox( + 'random_photo_plugin_enabled', + Language::translateIfTranslationStrId($formValues['random_photo_plugin_enabled']['name']), + $selectBoxEntries, + array('defaultValue' => $formValues['random_photo_plugin_enabled']['value'], 'showContextDependentFirstEntry' => false, 'helpTextId' => $formValues['random_photo_plugin_enabled']['description']) + ); + $formRandomPhoto->addInput( + 'random_photo_plugin_max_char_per_word', + Language::translateIfTranslationStrId($formValues['random_photo_plugin_max_char_per_word']['name']), + $formValues['random_photo_plugin_max_char_per_word']['value'], + array('type' => 'number', 'minNumber' => 0, 'step' => 1, 'helpTextId' => $formValues['random_photo_plugin_max_char_per_word']['description']) + ); + $formRandomPhoto->addInput( + 'random_photo_plugin_max_width', + Language::translateIfTranslationStrId($formValues['random_photo_plugin_max_width']['name']), + $formValues['random_photo_plugin_max_width']['value'], + array('type' => 'number', 'minNumber' => 0, 'step' => 1, 'helpTextId' => $formValues['random_photo_plugin_max_width']['description']) + ); + $formRandomPhoto->addInput( + 'random_photo_plugin_max_height', + Language::translateIfTranslationStrId($formValues['random_photo_plugin_max_height']['name']), + $formValues['random_photo_plugin_max_height']['value'], + array('type' => 'number', 'minNumber' => 0, 'step' => 1, 'helpTextId' => $formValues['random_photo_plugin_max_height']['description']) + ); + $formRandomPhoto->addInput( + 'random_photo_plugin_albums', + Language::translateIfTranslationStrId($formValues['random_photo_plugin_albums']['name']), + $formValues['random_photo_plugin_albums']['value'], + array('type' => 'number', 'minNumber' => 0, 'step' => 1, 'helpTextId' => $formValues['random_photo_plugin_albums']['description']) + ); + $formRandomPhoto->addInput( + 'random_photo_plugin_album_photo_number', + Language::translateIfTranslationStrId($formValues['random_photo_plugin_album_photo_number']['name']), + $formValues['random_photo_plugin_album_photo_number']['value'], + array('type' => 'number', 'minNumber' => 0, 'step' => 1, 'helpTextId' => $formValues['random_photo_plugin_album_photo_number']['description']) + ); + $formRandomPhoto->addCheckbox( + 'random_photo_plugin_show_album_link', + Language::translateIfTranslationStrId($formValues['random_photo_plugin_show_album_link']['name']), + $formValues['random_photo_plugin_show_album_link']['value'], + array('helpTextId' => $formValues['random_photo_plugin_show_album_link']['description']) + ); + $formRandomPhoto->addSubmitButton( + 'adm_button_save_random_photo', + $gL10n->get('SYS_SAVE'), + array('icon' => 'bi-check-lg', 'class' => 'offset-sm-3') + ); + + $formRandomPhoto->addToSmarty($smarty); + $gCurrentSession->addFormObject($formRandomPhoto); + return $smarty->fetch($pluginRandomPhoto::getPluginPath() . '/templates/preferences.plugin.random-photo.tpl'); + } +} \ No newline at end of file diff --git a/adm_plugins/RandomPhoto/classes/RandomPhoto.php b/adm_plugins/RandomPhoto/classes/RandomPhoto.php new file mode 100644 index 0000000000..ab25f3c594 --- /dev/null +++ b/adm_plugins/RandomPhoto/classes/RandomPhoto.php @@ -0,0 +1,150 @@ + 0 + ORDER BY pho_begin DESC'; + + // optional set a limit which albums should be scanned + if (self::$pluginConfig['random_photo_plugin_albums'] > 0) { + $sql .= ' LIMIT ' . self::$pluginConfig['random_photo_plugin_albums']; + } + + $albumStatement = $gDb->queryPrepared($sql, array($gCurrentOrgId)); + $albumList = $albumStatement->fetchAll(); + + $i = 0; + $photoNr = 0; + $photoServerPath = ''; + $linkText = ''; + $album = new Album($gDb); + + // loop, if an image is not found directly, but limit to 20 passes + while (!is_file($photoServerPath) && $i < 20 && $albumStatement->rowCount() > 0) { + $album->setArray($albumList[mt_rand(0, $albumStatement->rowCount() - 1)]); + + // optionally select an image randomly + if (self::$pluginConfig['random_photo_plugin_album_photo_number'] === 0) { + $photoNr = mt_rand(1, (int)$album->getValue('pho_quantity')); + } else { + $photoNr = self::$pluginConfig['random_photo_plugin_album_photo_number']; + } + + // Compose image path + $photoServerPath = ADMIDIO_PATH . FOLDER_DATA . '/photos/' . $album->getValue('pho_begin', 'Y-m-d') . '_' . (int)$album->getValue('pho_id') . '/' . $photoNr . '.jpg'; + ++$i; + } + + if (self::$pluginConfig['random_photo_plugin_show_album_link'] && self::$pluginConfig['random_photo_plugin_max_char_per_word'] > 0) { + // Wrap link text if necessary + $words = explode(' ', $album->getValue('pho_name')); + + foreach ($words as $word) { + if (strlen($word) > self::$pluginConfig['random_photo_plugin_max_char_per_word']) { + $linkText .= substr($word, 0, self::$pluginConfig['random_photo_plugin_max_char_per_word']) . '-
' . + substr($word, self::$pluginConfig['random_photo_plugin_max_char_per_word']) . ' '; + } else { + $linkText .= $word . ' '; + } + } + } else { + $linkText = $album->getValue('pho_name'); + } + $photoData['photoNr'] = $photoNr; + $photoData['uuid'] = $album->getValue('pho_uuid'); + $photoData['linkText'] = $linkText; + return $photoData; + } + + /** + * @param PagePresenter $page + * @throws InvalidArgumentException + * @throws Exception + * @return bool + */ + public static function doRender($page = null) : bool + { + global $gSettingsManager, $gL10n, $gValidLogin; + + // show random photo + try { + $rootPath = dirname(__DIR__, 3); + $pluginFolder = basename(self::$pluginPath); + + require_once($rootPath . '/system/common.php'); + + $randomPhotoPlugin = new Overview($pluginFolder); + + // check if the plugin is installed + if (!self::isInstalled()) { + throw new InvalidArgumentException($gL10n->get('SYS_PLUGIN_NOT_INSTALLED')); + } + + if ($gSettingsManager->getInt('photo_module_enabled') > 0) { + if (($gSettingsManager->getInt('photo_module_enabled') === 1 || ($gSettingsManager->getInt('photo_module_enabled') === 2 && $gValidLogin)) && + ($gSettingsManager->getInt('random_photo_plugin_enabled') === 1 || ($gSettingsManager->getInt('random_photo_plugin_enabled') === 2 && $gValidLogin))) { + $photoData = self::getPhotoData(); + $randomPhotoPlugin->assignTemplateVariable('photoUUID', $photoData['uuid']); + $randomPhotoPlugin->assignTemplateVariable('photoNr', $photoData['photoNr']); + $randomPhotoPlugin->assignTemplateVariable('photoTitle', $photoData['linkText']); + $randomPhotoPlugin->assignTemplateVariable('photoMaxWidth', self::$pluginConfig['random_photo_plugin_max_width']); + $randomPhotoPlugin->assignTemplateVariable('photoMaxHeight', self::$pluginConfig['random_photo_plugin_max_height']); + $randomPhotoPlugin->assignTemplateVariable('photoShowLink', self::$pluginConfig['random_photo_plugin_show_album_link']); + } else { + $randomPhotoPlugin->assignTemplateVariable('message',$gL10n->get('PLG_RANDOM_PHOTO_NO_ENTRIES_VISITORS')); + } + } else { + $randomPhotoPlugin->assignTemplateVariable('message', $gL10n->get('SYS_MODULE_DISABLED')); + } + + if (isset($page)) { + echo $randomPhotoPlugin->html('plugin.random-photo.tpl'); + } else { + $randomPhotoPlugin->showHtmlPage('plugin.random-photo.tpl'); + } + } catch (Throwable $e) { + echo $e->getMessage(); + } + + return true; + } +} \ No newline at end of file diff --git a/adm_plugins/RandomPhoto/db_scripts/update_1_0.xml b/adm_plugins/RandomPhoto/db_scripts/update_1_0.xml new file mode 100644 index 0000000000..5fdda08474 --- /dev/null +++ b/adm_plugins/RandomPhoto/db_scripts/update_1_0.xml @@ -0,0 +1,6 @@ + + + UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'RandomPhoto' + UPDATE %PREFIX%_components SET com_plg_sequence = 4 WHERE com_type = 'ADM_PLUGIN' AND com_name_intern = 'RandomPhoto' + stop + diff --git a/adm_plugins/RandomPhoto/index.php b/adm_plugins/RandomPhoto/index.php new file mode 100644 index 0000000000..8caa3001d8 --- /dev/null +++ b/adm_plugins/RandomPhoto/index.php @@ -0,0 +1,24 @@ +doRender(isset($page) ? $page : null); + +} catch (Throwable $e) { + echo $e->getMessage(); +} diff --git a/adm_plugins/random_photo/languages/bg.xml b/adm_plugins/RandomPhoto/languages/bg.xml similarity index 100% rename from adm_plugins/random_photo/languages/bg.xml rename to adm_plugins/RandomPhoto/languages/bg.xml diff --git a/adm_plugins/random_photo/languages/da.xml b/adm_plugins/RandomPhoto/languages/da.xml similarity index 100% rename from adm_plugins/random_photo/languages/da.xml rename to adm_plugins/RandomPhoto/languages/da.xml diff --git a/adm_plugins/random_photo/languages/de-DE.xml b/adm_plugins/RandomPhoto/languages/de-DE.xml similarity index 100% rename from adm_plugins/random_photo/languages/de-DE.xml rename to adm_plugins/RandomPhoto/languages/de-DE.xml diff --git a/adm_plugins/random_photo/languages/de.xml b/adm_plugins/RandomPhoto/languages/de.xml similarity index 100% rename from adm_plugins/random_photo/languages/de.xml rename to adm_plugins/RandomPhoto/languages/de.xml diff --git a/adm_plugins/random_photo/languages/el.xml b/adm_plugins/RandomPhoto/languages/el.xml similarity index 100% rename from adm_plugins/random_photo/languages/el.xml rename to adm_plugins/RandomPhoto/languages/el.xml diff --git a/adm_plugins/RandomPhoto/languages/en.xml b/adm_plugins/RandomPhoto/languages/en.xml new file mode 100644 index 0000000000..2de8c45de2 --- /dev/null +++ b/adm_plugins/RandomPhoto/languages/en.xml @@ -0,0 +1,19 @@ + + + There are no photos available for visitors. Log in to see the photos. + This plugin displays a randomly selected photo from the photo module. + Random Photo + + Number of characters per word + Maximum number of characters in a word before a line break should be performed. If it's set to 0 then no line break will be performed. (default: 0) + Maximum photo width + Maximum width of the photo in pixels. If it's set to 0 then the image will be dynamically scaled by the html container in which this plugin is placed. (default: 0) + Maximum photo height + Maximum height of the photo in pixels. If it's set to 0 then the image will be dynamically scaled by the html container in which this plugin is placed. (default: 0) + Considered albums + Number of albums the photo may come from. Counts from the most recent album in descending order. If it's set to 0 then all albums will be considered. (default: 0) + Photo number + Number of the photo from the album to be displayed. If it's set to 0 then a random photo from the album will be displayed, if it's set to a specific number then that photo will be displayed. (default: 0) + Show album link + If this setting is enabled a link to the album with the album name below the photo will be displayed. (default: true) + diff --git a/adm_plugins/random_photo/languages/et.xml b/adm_plugins/RandomPhoto/languages/et.xml similarity index 100% rename from adm_plugins/random_photo/languages/et.xml rename to adm_plugins/RandomPhoto/languages/et.xml diff --git a/adm_plugins/random_photo/languages/fi.xml b/adm_plugins/RandomPhoto/languages/fi.xml old mode 100755 new mode 100644 similarity index 100% rename from adm_plugins/random_photo/languages/fi.xml rename to adm_plugins/RandomPhoto/languages/fi.xml diff --git a/adm_plugins/random_photo/languages/fr.xml b/adm_plugins/RandomPhoto/languages/fr.xml similarity index 100% rename from adm_plugins/random_photo/languages/fr.xml rename to adm_plugins/RandomPhoto/languages/fr.xml diff --git a/adm_plugins/random_photo/languages/hu.xml b/adm_plugins/RandomPhoto/languages/hu.xml similarity index 100% rename from adm_plugins/random_photo/languages/hu.xml rename to adm_plugins/RandomPhoto/languages/hu.xml diff --git a/adm_plugins/random_photo/languages/nb.xml b/adm_plugins/RandomPhoto/languages/nb.xml similarity index 100% rename from adm_plugins/random_photo/languages/nb.xml rename to adm_plugins/RandomPhoto/languages/nb.xml diff --git a/adm_plugins/random_photo/languages/nl.xml b/adm_plugins/RandomPhoto/languages/nl.xml similarity index 100% rename from adm_plugins/random_photo/languages/nl.xml rename to adm_plugins/RandomPhoto/languages/nl.xml diff --git a/adm_plugins/random_photo/languages/pl.xml b/adm_plugins/RandomPhoto/languages/pl.xml similarity index 100% rename from adm_plugins/random_photo/languages/pl.xml rename to adm_plugins/RandomPhoto/languages/pl.xml diff --git a/adm_plugins/random_photo/languages/pt.xml b/adm_plugins/RandomPhoto/languages/pt.xml similarity index 100% rename from adm_plugins/random_photo/languages/pt.xml rename to adm_plugins/RandomPhoto/languages/pt.xml diff --git a/adm_plugins/random_photo/languages/ru.xml b/adm_plugins/RandomPhoto/languages/ru.xml similarity index 100% rename from adm_plugins/random_photo/languages/ru.xml rename to adm_plugins/RandomPhoto/languages/ru.xml diff --git a/adm_plugins/random_photo/languages/sv.xml b/adm_plugins/RandomPhoto/languages/sv.xml similarity index 100% rename from adm_plugins/random_photo/languages/sv.xml rename to adm_plugins/RandomPhoto/languages/sv.xml diff --git a/adm_plugins/random_photo/languages/uk.xml b/adm_plugins/RandomPhoto/languages/uk.xml similarity index 100% rename from adm_plugins/random_photo/languages/uk.xml rename to adm_plugins/RandomPhoto/languages/uk.xml diff --git a/adm_plugins/random_photo/templates/plugin.random-photo.tpl b/adm_plugins/RandomPhoto/templates/plugin.random-photo.tpl similarity index 100% rename from adm_plugins/random_photo/templates/plugin.random-photo.tpl rename to adm_plugins/RandomPhoto/templates/plugin.random-photo.tpl diff --git a/adm_plugins/RandomPhoto/templates/preferences.plugin.random-photo.tpl b/adm_plugins/RandomPhoto/templates/preferences.plugin.random-photo.tpl new file mode 100644 index 0000000000..6f96571bdb --- /dev/null +++ b/adm_plugins/RandomPhoto/templates/preferences.plugin.random-photo.tpl @@ -0,0 +1,17 @@ +
+ + {include 'sys-template-parts/form.input.tpl' data=$elements['adm_csrf_token']} + {include 'sys-template-parts/form.select.tpl' data=$elements['random_photo_plugin_enabled']} + {include 'sys-template-parts/form.input.tpl' data=$elements['random_photo_plugin_max_char_per_word']} + {include 'sys-template-parts/form.input.tpl' data=$elements['random_photo_plugin_max_width']} + {include 'sys-template-parts/form.input.tpl' data=$elements['random_photo_plugin_max_height']} + {include 'sys-template-parts/form.input.tpl' data=$elements['random_photo_plugin_albums']} + {include 'sys-template-parts/form.input.tpl' data=$elements['random_photo_plugin_album_photo_number']} + {include 'sys-template-parts/form.checkbox.tpl' data=$elements['random_photo_plugin_show_album_link']} + {include 'sys-template-parts/form.button.tpl' data=$elements['adm_button_save_random_photo']} + + +
+{$javascript} \ No newline at end of file diff --git a/adm_plugins/random_photo/config_sample.php b/adm_plugins/random_photo/config_sample.php deleted file mode 100644 index 686b2e1fd1..0000000000 --- a/adm_plugins/random_photo/config_sample.php +++ /dev/null @@ -1,43 +0,0 @@ -getInt('photo_module_enabled') > 0) { - if ($gSettingsManager->getInt('photo_module_enabled') === 1 - || ($gSettingsManager->getInt('photo_module_enabled') === 2 && $gValidLogin)) { - // call photo albums - $sql = 'SELECT * - FROM ' . TBL_PHOTOS . ' - WHERE pho_org_id = ? -- $gCurrentOrgId - AND pho_locked = false - AND pho_quantity > 0 - ORDER BY pho_begin DESC'; - - // optional set a limit which albums should be scanned - if ($plg_photos_albums > 0) { - $sql .= ' LIMIT ' . $plg_photos_albums; - } - - $albumStatement = $gDb->queryPrepared($sql, array($gCurrentOrgId)); - $albumList = $albumStatement->fetchAll(); - - $i = 0; - $photoNr = 0; - $photoServerPath = ''; - $linkText = ''; - $album = new Album($gDb); - - // loop, if an image is not found directly, but limit to 20 passes - while (!is_file($photoServerPath) && $i < 20 && $albumStatement->rowCount() > 0) { - $album->setArray($albumList[mt_rand(0, $albumStatement->rowCount() - 1)]); - - // optionally select an image randomly - if ($plg_photos_picnr === 0) { - $photoNr = mt_rand(1, (int)$album->getValue('pho_quantity')); - } else { - $photoNr = $plg_photos_picnr; - } - - // Compose image path - $photoServerPath = ADMIDIO_PATH . FOLDER_DATA . '/photos/' . $album->getValue('pho_begin', 'Y-m-d') . '_' . (int)$album->getValue('pho_id') . '/' . $photoNr . '.jpg'; - ++$i; - } - - if ($plg_photos_show_link && $plg_max_char_per_word > 0) { - // Wrap link text if necessary - $words = explode(' ', $album->getValue('pho_name')); - - foreach ($words as $word) { - if (strlen($word) > $plg_max_char_per_word) { - $linkText .= substr($word, 0, $plg_max_char_per_word) . '-
' . - substr($word, $plg_max_char_per_word) . ' '; - } else { - $linkText .= $word . ' '; - } - } - } else { - $linkText = $album->getValue('pho_name'); - } - - $randomPhotoPlugin->assignTemplateVariable('photoUUID', $album->getValue('pho_uuid')); - $randomPhotoPlugin->assignTemplateVariable('photoNr', $photoNr); - $randomPhotoPlugin->assignTemplateVariable('photoTitle', $linkText); - $randomPhotoPlugin->assignTemplateVariable('photoMaxWidth', $plg_photos_max_width); - $randomPhotoPlugin->assignTemplateVariable('photoMaxHeight', $plg_photos_max_height); - $randomPhotoPlugin->assignTemplateVariable('photoShowLink', $plg_photos_show_link); - } else { - $randomPhotoPlugin->assignTemplateVariable('message',$gL10n->get('PLG_RANDOM_PHOTO_NO_ENTRIES_VISITORS')); - } - - if (isset($page)) { - echo $randomPhotoPlugin->html('plugin.random-photo.tpl'); - } else { - $randomPhotoPlugin->showHtmlPage('plugin.random-photo.tpl'); - } - } -} catch (Throwable $e) { - echo $e->getMessage(); -} diff --git a/adm_plugins/random_photo/languages/en.xml b/adm_plugins/random_photo/languages/en.xml deleted file mode 100644 index 42557cbcb1..0000000000 --- a/adm_plugins/random_photo/languages/en.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - There are no photos available for visitors. Log in to see the photos. - From 7f1bf4b99696e0ee2693c226448d704bde0b8026 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 23 Jul 2025 20:48:42 +0200 Subject: [PATCH 025/109] rebase who-is-online overview-plugin to use PluginManager --- adm_plugins/WhoIsOnline/WhoIsOnline.json | 48 ++++++ .../WhoIsOnlinePreferencesPresenter.php | 99 +++++++++++ .../WhoIsOnline/classes/WhoIsOnline.php | 158 ++++++++++++++++++ .../WhoIsOnline/db_scripts/update_1_0.xml | 6 + adm_plugins/WhoIsOnline/index.php | 23 +++ adm_plugins/WhoIsOnline/languages/bg.xml | 10 ++ adm_plugins/WhoIsOnline/languages/da.xml | 10 ++ adm_plugins/WhoIsOnline/languages/de-DE.xml | 10 ++ adm_plugins/WhoIsOnline/languages/de.xml | 10 ++ adm_plugins/WhoIsOnline/languages/el.xml | 10 ++ adm_plugins/WhoIsOnline/languages/en.xml | 27 +++ adm_plugins/WhoIsOnline/languages/es.xml | 8 + adm_plugins/WhoIsOnline/languages/et.xml | 10 ++ adm_plugins/WhoIsOnline/languages/fi.xml | 10 ++ adm_plugins/WhoIsOnline/languages/fr.xml | 10 ++ adm_plugins/WhoIsOnline/languages/hu.xml | 10 ++ adm_plugins/WhoIsOnline/languages/nb.xml | 10 ++ adm_plugins/WhoIsOnline/languages/nl.xml | 10 ++ adm_plugins/WhoIsOnline/languages/pl.xml | 10 ++ adm_plugins/WhoIsOnline/languages/pt-BR.xml | 10 ++ adm_plugins/WhoIsOnline/languages/pt.xml | 10 ++ adm_plugins/WhoIsOnline/languages/ru.xml | 10 ++ adm_plugins/WhoIsOnline/languages/sv.xml | 10 ++ adm_plugins/WhoIsOnline/languages/uk.xml | 10 ++ adm_plugins/WhoIsOnline/languages/zh.xml | 8 + .../templates/plugin.who-is-online.tpl | 2 +- .../preferences.plugin.who-is-online.tpl | 16 ++ adm_plugins/who-is-online/config_sample.php | 37 ---- adm_plugins/who-is-online/index.php | 131 --------------- adm_plugins/who-is-online/languages/bg.xml | 10 -- adm_plugins/who-is-online/languages/da.xml | 10 -- adm_plugins/who-is-online/languages/de-DE.xml | 10 -- adm_plugins/who-is-online/languages/de.xml | 10 -- adm_plugins/who-is-online/languages/el.xml | 10 -- adm_plugins/who-is-online/languages/en.xml | 10 -- adm_plugins/who-is-online/languages/es.xml | 8 - adm_plugins/who-is-online/languages/et.xml | 10 -- adm_plugins/who-is-online/languages/fi.xml | 10 -- adm_plugins/who-is-online/languages/fr.xml | 10 -- adm_plugins/who-is-online/languages/hu.xml | 10 -- adm_plugins/who-is-online/languages/nb.xml | 10 -- adm_plugins/who-is-online/languages/nl.xml | 10 -- adm_plugins/who-is-online/languages/pl.xml | 10 -- adm_plugins/who-is-online/languages/pt-BR.xml | 10 -- adm_plugins/who-is-online/languages/pt.xml | 10 -- adm_plugins/who-is-online/languages/ru.xml | 10 -- adm_plugins/who-is-online/languages/sv.xml | 10 -- adm_plugins/who-is-online/languages/uk.xml | 10 -- adm_plugins/who-is-online/languages/zh.xml | 8 - 49 files changed, 564 insertions(+), 365 deletions(-) create mode 100644 adm_plugins/WhoIsOnline/WhoIsOnline.json create mode 100644 adm_plugins/WhoIsOnline/classes/Presenter/WhoIsOnlinePreferencesPresenter.php create mode 100644 adm_plugins/WhoIsOnline/classes/WhoIsOnline.php create mode 100644 adm_plugins/WhoIsOnline/db_scripts/update_1_0.xml create mode 100644 adm_plugins/WhoIsOnline/index.php create mode 100644 adm_plugins/WhoIsOnline/languages/bg.xml create mode 100644 adm_plugins/WhoIsOnline/languages/da.xml create mode 100644 adm_plugins/WhoIsOnline/languages/de-DE.xml create mode 100644 adm_plugins/WhoIsOnline/languages/de.xml create mode 100644 adm_plugins/WhoIsOnline/languages/el.xml create mode 100644 adm_plugins/WhoIsOnline/languages/en.xml create mode 100644 adm_plugins/WhoIsOnline/languages/es.xml create mode 100644 adm_plugins/WhoIsOnline/languages/et.xml create mode 100644 adm_plugins/WhoIsOnline/languages/fi.xml create mode 100644 adm_plugins/WhoIsOnline/languages/fr.xml create mode 100644 adm_plugins/WhoIsOnline/languages/hu.xml create mode 100644 adm_plugins/WhoIsOnline/languages/nb.xml create mode 100644 adm_plugins/WhoIsOnline/languages/nl.xml create mode 100644 adm_plugins/WhoIsOnline/languages/pl.xml create mode 100644 adm_plugins/WhoIsOnline/languages/pt-BR.xml create mode 100644 adm_plugins/WhoIsOnline/languages/pt.xml create mode 100644 adm_plugins/WhoIsOnline/languages/ru.xml create mode 100644 adm_plugins/WhoIsOnline/languages/sv.xml create mode 100644 adm_plugins/WhoIsOnline/languages/uk.xml create mode 100644 adm_plugins/WhoIsOnline/languages/zh.xml rename adm_plugins/{who-is-online => WhoIsOnline}/templates/plugin.who-is-online.tpl (58%) create mode 100644 adm_plugins/WhoIsOnline/templates/preferences.plugin.who-is-online.tpl delete mode 100644 adm_plugins/who-is-online/config_sample.php delete mode 100644 adm_plugins/who-is-online/index.php delete mode 100644 adm_plugins/who-is-online/languages/bg.xml delete mode 100644 adm_plugins/who-is-online/languages/da.xml delete mode 100644 adm_plugins/who-is-online/languages/de-DE.xml delete mode 100644 adm_plugins/who-is-online/languages/de.xml delete mode 100644 adm_plugins/who-is-online/languages/el.xml delete mode 100644 adm_plugins/who-is-online/languages/en.xml delete mode 100644 adm_plugins/who-is-online/languages/es.xml delete mode 100644 adm_plugins/who-is-online/languages/et.xml delete mode 100755 adm_plugins/who-is-online/languages/fi.xml delete mode 100644 adm_plugins/who-is-online/languages/fr.xml delete mode 100644 adm_plugins/who-is-online/languages/hu.xml delete mode 100644 adm_plugins/who-is-online/languages/nb.xml delete mode 100644 adm_plugins/who-is-online/languages/nl.xml delete mode 100644 adm_plugins/who-is-online/languages/pl.xml delete mode 100644 adm_plugins/who-is-online/languages/pt-BR.xml delete mode 100644 adm_plugins/who-is-online/languages/pt.xml delete mode 100644 adm_plugins/who-is-online/languages/ru.xml delete mode 100644 adm_plugins/who-is-online/languages/sv.xml delete mode 100644 adm_plugins/who-is-online/languages/uk.xml delete mode 100644 adm_plugins/who-is-online/languages/zh.xml diff --git a/adm_plugins/WhoIsOnline/WhoIsOnline.json b/adm_plugins/WhoIsOnline/WhoIsOnline.json new file mode 100644 index 0000000000..4a476c0679 --- /dev/null +++ b/adm_plugins/WhoIsOnline/WhoIsOnline.json @@ -0,0 +1,48 @@ +{ + "name": "PLG_WHO_IS_ONLINE_PLUGIN_NAME", + "description": "PLG_WHO_IS_ONLINE_PLUGIN_DESCRIPTION", + "version": "1.0.0", + "author": "Admidio Team", + "url": "https://www.admidio.org", + "icon": "bi-building-fill-check", + "mainFile": "index.php", + "dependencies": [], + "defaultConfig": { + "who_is_online_plugin_enabled": { + "name": "ORG_ACCESS_TO_PLUGIN", + "description": "ORG_ACCESS_TO_PLUGIN_DESC", + "type": "integer", + "value" : 1 + }, + "who_is_online_plugin_time_still_active": { + "name": "PLG_WHO_IS_ONLINE_PLUGIN_TIME_STILL_ACTIVE", + "description": "PLG_WHO_IS_ONLINE_PLUGIN_TIME_STILL_ACTIVE_DESC", + "type": "integer", + "value" : 10 + }, + "who_is_online_plugin_show_visitors": { + "name": "PLG_WHO_IS_ONLINE_PREFERENCES_SHOW_VISITORS", + "description": "PLG_WHO_IS_ONLINE_PREFERENCES_SHOW_VISITORS_DESC", + "type": "boolean", + "value" : true + }, + "who_is_online_plugin_show_members_to_visitors": { + "name": "PLG_WHO_IS_ONLINE_PREFERENCES_SHOW_MEMBERS_TO_VISITORS", + "description": "PLG_WHO_IS_ONLINE_PREFERENCES_SHOW_MEMBERS_TO_VISITORS_DESC", + "type": "integer", + "value" : 2 + }, + "who_is_online_plugin_show_self": { + "name": "PLG_WHO_IS_ONLINE_PREFERENCES_SHOW_SELF", + "description": "PLG_WHO_IS_ONLINE_PREFERENCES_SHOW_SELF_DESC", + "type": "boolean", + "value" : true + }, + "who_is_online_plugin_show_users_side_by_side": { + "name": "PLG_WHO_IS_ONLINE_PREFERENCES_SHOW_USERS_SIDE_BY_SIDE", + "description": "PLG_WHO_IS_ONLINE_PREFERENCES_SHOW_USERS_SIDE_BY_SIDE_DESC", + "type": "boolean", + "value" : false + } + } +} \ No newline at end of file diff --git a/adm_plugins/WhoIsOnline/classes/Presenter/WhoIsOnlinePreferencesPresenter.php b/adm_plugins/WhoIsOnline/classes/Presenter/WhoIsOnlinePreferencesPresenter.php new file mode 100644 index 0000000000..4e11900914 --- /dev/null +++ b/adm_plugins/WhoIsOnline/classes/Presenter/WhoIsOnlinePreferencesPresenter.php @@ -0,0 +1,99 @@ + 'save', 'panel' => 'who_is_online')), + null, + array('class' => 'form-preferences') + ); + $selectBoxEntries = array( + '0' => $gL10n->get('SYS_DISABLED'), + '1' => $gL10n->get('SYS_ENABLED'), + '2' => $gL10n->get('ORG_ONLY_FOR_REGISTERED_USER') + ); + $formWhoIsOnline->addSelectBox( + 'who_is_online_plugin_enabled', + Language::translateIfTranslationStrId($formValues['who_is_online_plugin_enabled']['name']), + $selectBoxEntries, + array('defaultValue' => $formValues['who_is_online_plugin_enabled']['value'], 'showContextDependentFirstEntry' => false, 'helpTextId' => $formValues['who_is_online_plugin_enabled']['description']) + ); + $formWhoIsOnline->addInput( + 'who_is_online_plugin_time_still_active', + Language::translateIfTranslationStrId($formValues['who_is_online_plugin_time_still_active']['name']), + $formValues['who_is_online_plugin_time_still_active']['value'], + array('type' => 'number', 'minNumber' => 0, 'step' => 1, 'helpTextId' => $formValues['who_is_online_plugin_time_still_active']['description']) + ); + $formWhoIsOnline->addCheckbox( + 'who_is_online_plugin_show_visitors', + Language::translateIfTranslationStrId($formValues['who_is_online_plugin_show_visitors']['name']), + $formValues['who_is_online_plugin_show_visitors']['value'], + array('helpTextId' => $formValues['who_is_online_plugin_show_visitors']['description']) + ); + $selectBoxEntries = array( + '0' => $gL10n->get('PLG_WHO_IS_ONLINE_PREFERENCES_SHOW_MEMBERS_TO_VISITORS_SELECTION_1'), + '1' => $gL10n->get('PLG_WHO_IS_ONLINE_PREFERENCES_SHOW_MEMBERS_TO_VISITORS_SELECTION_2'), + '2' => $gL10n->get('PLG_WHO_IS_ONLINE_PREFERENCES_SHOW_MEMBERS_TO_VISITORS_SELECTION_3') + ); + $formWhoIsOnline->addSelectBox( + 'who_is_online_plugin_show_members_to_visitors', + Language::translateIfTranslationStrId($formValues['who_is_online_plugin_show_members_to_visitors']['name']), + $selectBoxEntries, + array('defaultValue' => $formValues['who_is_online_plugin_show_members_to_visitors']['value'], 'showContextDependentFirstEntry' => false, 'helpTextId' => $formValues['who_is_online_plugin_show_members_to_visitors']['description']) + ); + $formWhoIsOnline->addCheckbox( + 'who_is_online_plugin_show_self', + Language::translateIfTranslationStrId($formValues['who_is_online_plugin_show_self']['name']), + $formValues['who_is_online_plugin_show_self']['value'], + array('helpTextId' => $formValues['who_is_online_plugin_show_self']['description']) + ); + $formWhoIsOnline->addCheckbox( + 'who_is_online_plugin_show_users_side_by_side', + Language::translateIfTranslationStrId($formValues['who_is_online_plugin_show_users_side_by_side']['name']), + $formValues['who_is_online_plugin_show_users_side_by_side']['value'], + array('helpTextId' => $formValues['who_is_online_plugin_show_users_side_by_side']['description']) + ); + $formWhoIsOnline->addSubmitButton( + 'adm_button_save_who_is_online', + $gL10n->get('SYS_SAVE'), + array('icon' => 'bi-check-lg', 'class' => 'offset-sm-3') + ); + + $formWhoIsOnline->addToSmarty($smarty); + $gCurrentSession->addFormObject($formWhoIsOnline); + return $smarty->fetch($pluginWhoIsOnline::getPluginPath() . '/templates/preferences.plugin.who-is-online.tpl'); + } +} \ No newline at end of file diff --git a/adm_plugins/WhoIsOnline/classes/WhoIsOnline.php b/adm_plugins/WhoIsOnline/classes/WhoIsOnline.php new file mode 100644 index 0000000000..2fe2c92c20 --- /dev/null +++ b/adm_plugins/WhoIsOnline/classes/WhoIsOnline.php @@ -0,0 +1,158 @@ +sub($minutesOffset)->format('Y-m-d H:i:s'); + + // Find user IDs of all sessions that are in the specified current and reference time + $sql = 'SELECT ses_usr_id, usr_uuid, usr_login_name + FROM ' . TBL_SESSIONS . ' + LEFT JOIN ' . TBL_USERS . ' + ON usr_id = ses_usr_id + WHERE ses_timestamp BETWEEN ? AND ? -- $refDate AND DATETIME_NOW + AND ses_org_id = ? -- $gCurrentOrgId'; + $queryParams = array($refDate, DATETIME_NOW, $gCurrentOrgId); + if (!$config['who_is_online_plugin_show_visitors']) { + $sql .= ' + AND ses_usr_id IS NOT NULL'; + } + if (!$config['who_is_online_plugin_show_self'] && $gValidLogin) { + $sql .= ' + AND ses_usr_id <> ? -- $gCurrentUserId'; + $queryParams[] = $gCurrentUserId; + } + $sql .= ' + ORDER BY ses_usr_id'; + $onlineUsersStatement = $gDb->queryPrepared($sql, $queryParams); + + if ($onlineUsersStatement->rowCount() > 0) { + $usrIdMerker = 0; + $countMembers = 0; + $countVisitors = 0; + $allVisibleOnlineUsers = array(); + $textOnlineVisitors = ''; + + while ($row = $onlineUsersStatement->fetch()) { + if ($row['ses_usr_id'] > 0) { + if (((int)$row['ses_usr_id'] !== $usrIdMerker) + && ($config['who_is_online_plugin_show_members_to_visitors'] == 1 || $gValidLogin)) { + $allVisibleOnlineUsers[] = '' . $row['usr_login_name'] . ''; + $usrIdMerker = (int)$row['ses_usr_id']; + } + ++$countMembers; + } else { + ++$countVisitors; + } + } + + if (!$gValidLogin && $config['who_is_online_plugin_show_members_to_visitors'] == 2 && $countMembers > 0) { + if ($countMembers > 1) { + $allVisibleOnlineUsers[] = $gL10n->get('PLG_WHO_IS_ONLINE_VAR_NUM_MEMBERS', array($countMembers)); + } else { + $allVisibleOnlineUsers[] = $gL10n->get('PLG_WHO_IS_ONLINE_VAR_NUM_MEMBER', array($countMembers)); + } + } + + if ($config['who_is_online_plugin_show_visitors'] && $countVisitors > 0) { + $allVisibleOnlineUsers[] = $gL10n->get('PLG_WHO_IS_ONLINE_VAR_NUM_VISITORS', array($countVisitors)); + } + + if ($config['who_is_online_plugin_show_users_side_by_side']) { + $textOnlineVisitors = implode(', ', $allVisibleOnlineUsers); + } else { + $textOnlineVisitors = '
' . implode('
', $allVisibleOnlineUsers); + } + + if ($onlineUsersStatement->rowCount() === 1) { + $text = $gL10n->get('PLG_WHO_IS_ONLINE_VAR_ONLINE_IS', array($textOnlineVisitors)); + } else { + $text = $gL10n->get('PLG_WHO_IS_ONLINE_VAR_ONLINE_ARE', array($textOnlineVisitors)); + } + } else { + $text = $gL10n->get('PLG_WHO_IS_ONLINE_NO_VISITORS_ON_WEBSITE'); + } + + return $text; + } + + /** + * @param PagePresenter $page + * @throws InvalidArgumentException + * @throws Exception + * @return bool + */ + public static function doRender($page = null) : bool + { + global $gSettingsManager, $gL10n, $gValidLogin; + + // show random photo + try { + $rootPath = dirname(__DIR__, 3); + $pluginFolder = basename(self::$pluginPath); + + require_once($rootPath . '/system/common.php'); + + $whoIsOnlinePlugin = new Overview($pluginFolder); + + // check if the plugin is installed + if (!self::isInstalled()) { + throw new InvalidArgumentException($gL10n->get('SYS_PLUGIN_NOT_INSTALLED')); + } + + if ($gSettingsManager->getInt('who_is_online_plugin_enabled') === 1 || ($gSettingsManager->getInt('who_is_online_plugin_enabled') === 2 && $gValidLogin)) { + $text = self::getWhoIsOnlineText(); + $whoIsOnlinePlugin->assignTemplateVariable('message', $text); + } else { + $whoIsOnlinePlugin->assignTemplateVariable('message', $gL10n->get('PLG_WHO_IS_ONLINE_NO_DATA_VISITORS')); + } + + if (isset($page)) { + echo $whoIsOnlinePlugin->html('plugin.who-is-online.tpl'); + } else { + $whoIsOnlinePlugin->showHtmlPage('plugin.who-is-online.tpl'); + } + } catch (Throwable $e) { + echo $e->getMessage(); + } + + return true; + } +} \ No newline at end of file diff --git a/adm_plugins/WhoIsOnline/db_scripts/update_1_0.xml b/adm_plugins/WhoIsOnline/db_scripts/update_1_0.xml new file mode 100644 index 0000000000..34ddc7b5fd --- /dev/null +++ b/adm_plugins/WhoIsOnline/db_scripts/update_1_0.xml @@ -0,0 +1,6 @@ + + + UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'WhoIsOnline' + UPDATE %PREFIX%_components SET com_plg_sequence = 8 WHERE com_type = 'ADM_PLUGIN' AND com_name_intern = 'WhoIsOnline' + stop + diff --git a/adm_plugins/WhoIsOnline/index.php b/adm_plugins/WhoIsOnline/index.php new file mode 100644 index 0000000000..7abb564200 --- /dev/null +++ b/adm_plugins/WhoIsOnline/index.php @@ -0,0 +1,23 @@ +doRender(isset($page) ? $page : null); + +} catch (Throwable $e) { + echo $e->getMessage(); +} diff --git a/adm_plugins/WhoIsOnline/languages/bg.xml b/adm_plugins/WhoIsOnline/languages/bg.xml new file mode 100644 index 0000000000..6a0225b431 --- /dev/null +++ b/adm_plugins/WhoIsOnline/languages/bg.xml @@ -0,0 +1,10 @@ + + + Кой е онлайн? + Няма онлайн потребители.. + #VAR1# посетители + #VAR1# члет + #VAR1# членове + Онлайн има #VAR1# + Онлайн е #VAR1# + diff --git a/adm_plugins/WhoIsOnline/languages/da.xml b/adm_plugins/WhoIsOnline/languages/da.xml new file mode 100644 index 0000000000..c40b6654e7 --- /dev/null +++ b/adm_plugins/WhoIsOnline/languages/da.xml @@ -0,0 +1,10 @@ + + + On-line + Lige nu er der ikke nogen besøgende på hjemmesiden + #VAR1# Gæster + #VAR1# Medlem + #VAR1# Medlemmer + Online er #VAR1# + Online er #VAR1# + diff --git a/adm_plugins/WhoIsOnline/languages/de-DE.xml b/adm_plugins/WhoIsOnline/languages/de-DE.xml new file mode 100644 index 0000000000..e08477a459 --- /dev/null +++ b/adm_plugins/WhoIsOnline/languages/de-DE.xml @@ -0,0 +1,10 @@ + + + Wer ist Online? + Zur Zeit sind keine Besucher auf der Webseite. + #VAR1# Besucher + #VAR1# Mitglied + #VAR1# Mitglieder + Online sind #VAR1# + Online ist #VAR1# + diff --git a/adm_plugins/WhoIsOnline/languages/de.xml b/adm_plugins/WhoIsOnline/languages/de.xml new file mode 100644 index 0000000000..de924a77b3 --- /dev/null +++ b/adm_plugins/WhoIsOnline/languages/de.xml @@ -0,0 +1,10 @@ + + + Wer ist Online? + Zur Zeit sind keine Besucher auf der Webseite. + #VAR1# Besucher + #VAR1# Mitglied + #VAR1# Mitglieder + Online sind #VAR1# + Online ist #VAR1# + diff --git a/adm_plugins/WhoIsOnline/languages/el.xml b/adm_plugins/WhoIsOnline/languages/el.xml new file mode 100644 index 0000000000..189a1aa009 --- /dev/null +++ b/adm_plugins/WhoIsOnline/languages/el.xml @@ -0,0 +1,10 @@ + + + Ποιος είναι online; + Δεν υπάρχουν επισκέπτες αυτή τη στιγμή. + #VAR1# Επισκέπτες + #VAR1# μέλος + #VAR1# μέλη + Online είναι #VAR1# + Online είναι #VAR1# + diff --git a/adm_plugins/WhoIsOnline/languages/en.xml b/adm_plugins/WhoIsOnline/languages/en.xml new file mode 100644 index 0000000000..a9c87d9052 --- /dev/null +++ b/adm_plugins/WhoIsOnline/languages/en.xml @@ -0,0 +1,27 @@ + + + Who is online? + There is no data available for visitors. Log in to see who is online. + No visitors are on the website. + #VAR1# Visitors + #VAR1# member + #VAR1# members + Online are #VAR1# + Online is #VAR1# + This plugin displays visitors and registered members on the Overview page. + Who is Online + + Time still active + The time (in minutes) a user is considered still online after their last action. (default: 10) + Show visitors + If this setting is enabled the number of visitors will be displayed. Otherwise only logged-in users will be shown. (default: true) + Show members to visitors + Here you can select how members are displayed to visitors. (default: number of logged in members) + Don\'t show logged in members + Show logged in members + Number of logged in members + Show self + If this setting is enabled the own status (logged in as well as logged out) will be displayed. (default: true) + Show users side by side + If this setting is enabled the users will be displayed side by side. Otherwise they will be displayed one below the other. (default: false) + diff --git a/adm_plugins/WhoIsOnline/languages/es.xml b/adm_plugins/WhoIsOnline/languages/es.xml new file mode 100644 index 0000000000..6a686a4f83 --- /dev/null +++ b/adm_plugins/WhoIsOnline/languages/es.xml @@ -0,0 +1,8 @@ + + + En línea + En este momento no hay visitantes en el sitio web. + #VAR1# visitantes + #VAR1# Membro + #VAR1# Membros + diff --git a/adm_plugins/WhoIsOnline/languages/et.xml b/adm_plugins/WhoIsOnline/languages/et.xml new file mode 100644 index 0000000000..9da927b44a --- /dev/null +++ b/adm_plugins/WhoIsOnline/languages/et.xml @@ -0,0 +1,10 @@ + + + Kes on Internetis? + Veebisaidil pole külastajaid.. + #VAR1# Külastajad + #VAR1# liige + #VAR1# liikmed + Internetis on #VAR1# + Internetis on #VAR1# + diff --git a/adm_plugins/WhoIsOnline/languages/fi.xml b/adm_plugins/WhoIsOnline/languages/fi.xml new file mode 100644 index 0000000000..10faccb4d1 --- /dev/null +++ b/adm_plugins/WhoIsOnline/languages/fi.xml @@ -0,0 +1,10 @@ + + + Kuka on kirjautuneena? + Ei vieraita sivustolla.. + #VAR1# Vieraita + #VAR1# jäsen + #VAR1# jäsentä + #VAR1# linjoilla + #VAR1# on linjoilla + diff --git a/adm_plugins/WhoIsOnline/languages/fr.xml b/adm_plugins/WhoIsOnline/languages/fr.xml new file mode 100644 index 0000000000..ca2148850e --- /dev/null +++ b/adm_plugins/WhoIsOnline/languages/fr.xml @@ -0,0 +1,10 @@ + + + Qui est en ligne ? + Il n\'y a actuellement aucun visiteur sur le site Web. + #VAR1# visiteurs + #VAR1# Membre + #VAR1# Membres + En ligne sont #VAR1# + En ligne est #VAR1# + diff --git a/adm_plugins/WhoIsOnline/languages/hu.xml b/adm_plugins/WhoIsOnline/languages/hu.xml new file mode 100644 index 0000000000..41934ae6c0 --- /dev/null +++ b/adm_plugins/WhoIsOnline/languages/hu.xml @@ -0,0 +1,10 @@ + + + Kik vannak online? + A honlapon nincsenek látogatók.. + #VAR1# Látogató + #VAR1# tag + #VAR1# tag + Online van #VAR1# + Online van #VAR1# + diff --git a/adm_plugins/WhoIsOnline/languages/nb.xml b/adm_plugins/WhoIsOnline/languages/nb.xml new file mode 100644 index 0000000000..32168364c8 --- /dev/null +++ b/adm_plugins/WhoIsOnline/languages/nb.xml @@ -0,0 +1,10 @@ + + + Online + Foreløpig er det ingen besøkende til nettstedet. + #VAR1# Besøkende + #VAR1# Medlem + #VAR1# Medlemmer + #VAR1# er online + #VAR1# er online + diff --git a/adm_plugins/WhoIsOnline/languages/nl.xml b/adm_plugins/WhoIsOnline/languages/nl.xml new file mode 100644 index 0000000000..0949df4e02 --- /dev/null +++ b/adm_plugins/WhoIsOnline/languages/nl.xml @@ -0,0 +1,10 @@ + + + Wie is online? + Op dit moment zijn geen bezoekers op de website. + #VAR1# bezoekers + #VAR1# lid + #VAR1# leden + Online zijn #VAR1# + Online is #VAR1# + diff --git a/adm_plugins/WhoIsOnline/languages/pl.xml b/adm_plugins/WhoIsOnline/languages/pl.xml new file mode 100644 index 0000000000..32b43a8f82 --- /dev/null +++ b/adm_plugins/WhoIsOnline/languages/pl.xml @@ -0,0 +1,10 @@ + + + Kto jest on-line? + Nie ma odwiedzających na stronie. + #VAR1# Odwiedzających + #VAR1# Członek + #VAR1# Członków + #VAR1# jest On-line + #VAR1# są On-line + diff --git a/adm_plugins/WhoIsOnline/languages/pt-BR.xml b/adm_plugins/WhoIsOnline/languages/pt-BR.xml new file mode 100644 index 0000000000..cb8a47390e --- /dev/null +++ b/adm_plugins/WhoIsOnline/languages/pt-BR.xml @@ -0,0 +1,10 @@ + + + Quem está on-line? + Atualmente, não há nenhum visitante no site da Web. + #VAR1# Visitantes + #VAR1# Membro + #VAR1# Membros + Estão #VAR1# on-line + Está #VAR1# on-line + diff --git a/adm_plugins/WhoIsOnline/languages/pt.xml b/adm_plugins/WhoIsOnline/languages/pt.xml new file mode 100644 index 0000000000..53993e1335 --- /dev/null +++ b/adm_plugins/WhoIsOnline/languages/pt.xml @@ -0,0 +1,10 @@ + + + Quem está on-line? + Sem visitantes no site da Web. + #VAR1# Visitantes + #VAR1# membro + #VAR1# membros + Estão #VAR1# on-line + Está #VAR1# on-line + diff --git a/adm_plugins/WhoIsOnline/languages/ru.xml b/adm_plugins/WhoIsOnline/languages/ru.xml new file mode 100644 index 0000000000..5b948e9d35 --- /dev/null +++ b/adm_plugins/WhoIsOnline/languages/ru.xml @@ -0,0 +1,10 @@ + + + Кто онлайн? + На сайте нет посетителей. + #VAR1# посетителей + #VAR1# участник + #VAR1# участников + Онлайн #VAR1# + Онлайн #VAR1# + diff --git a/adm_plugins/WhoIsOnline/languages/sv.xml b/adm_plugins/WhoIsOnline/languages/sv.xml new file mode 100644 index 0000000000..be694fdd1a --- /dev/null +++ b/adm_plugins/WhoIsOnline/languages/sv.xml @@ -0,0 +1,10 @@ + + + Vem är online? + Inga besökare på webbplatsen .. + #VAR1# besökare + #VAR1# medlem + #VAR1# medlemmar + Online är #VAR1# + Online är #VAR1# + diff --git a/adm_plugins/WhoIsOnline/languages/uk.xml b/adm_plugins/WhoIsOnline/languages/uk.xml new file mode 100644 index 0000000000..c0c09c6df5 --- /dev/null +++ b/adm_plugins/WhoIsOnline/languages/uk.xml @@ -0,0 +1,10 @@ + + + Хто онлайн? + На сайті немає відвідувачів. + #VAR1# Відвідувачів + #VAR1# учасник + #VAR1# учасників + Онлайн #VAR1# + Онлайн #VAR1# + diff --git a/adm_plugins/WhoIsOnline/languages/zh.xml b/adm_plugins/WhoIsOnline/languages/zh.xml new file mode 100644 index 0000000000..68190e7183 --- /dev/null +++ b/adm_plugins/WhoIsOnline/languages/zh.xml @@ -0,0 +1,8 @@ + + + 当前谁在线? + 还没有访客。 + #VAR1# 访客 + #VAR1# 会员 + #VAR1# 会员 + diff --git a/adm_plugins/who-is-online/templates/plugin.who-is-online.tpl b/adm_plugins/WhoIsOnline/templates/plugin.who-is-online.tpl similarity index 58% rename from adm_plugins/who-is-online/templates/plugin.who-is-online.tpl rename to adm_plugins/WhoIsOnline/templates/plugin.who-is-online.tpl index 743cf12580..868b05766a 100644 --- a/adm_plugins/who-is-online/templates/plugin.who-is-online.tpl +++ b/adm_plugins/WhoIsOnline/templates/plugin.who-is-online.tpl @@ -1,5 +1,5 @@
-

{$l10n->get('PLG_ONLINE_HEADLINE')}

+

{$l10n->get('PLG_WHO_IS_ONLINE_HEADLINE')}

{$message}
diff --git a/adm_plugins/WhoIsOnline/templates/preferences.plugin.who-is-online.tpl b/adm_plugins/WhoIsOnline/templates/preferences.plugin.who-is-online.tpl new file mode 100644 index 0000000000..cd18b7ac83 --- /dev/null +++ b/adm_plugins/WhoIsOnline/templates/preferences.plugin.who-is-online.tpl @@ -0,0 +1,16 @@ +
+ + {include 'sys-template-parts/form.input.tpl' data=$elements['adm_csrf_token']} + {include 'sys-template-parts/form.select.tpl' data=$elements['who_is_online_plugin_enabled']} + {include 'sys-template-parts/form.input.tpl' data=$elements['who_is_online_plugin_time_still_active']} + {include 'sys-template-parts/form.checkbox.tpl' data=$elements['who_is_online_plugin_show_visitors']} + {include 'sys-template-parts/form.select.tpl' data=$elements['who_is_online_plugin_show_members_to_visitors']} + {include 'sys-template-parts/form.checkbox.tpl' data=$elements['who_is_online_plugin_show_self']} + {include 'sys-template-parts/form.checkbox.tpl' data=$elements['who_is_online_plugin_show_users_side_by_side']} + {include 'sys-template-parts/form.button.tpl' data=$elements['adm_button_save_who_is_online']} + + +
+{$javascript} \ No newline at end of file diff --git a/adm_plugins/who-is-online/config_sample.php b/adm_plugins/who-is-online/config_sample.php deleted file mode 100644 index 2ffb93cea0..0000000000 --- a/adm_plugins/who-is-online/config_sample.php +++ /dev/null @@ -1,37 +0,0 @@ -sub($minutesOffset)->format('Y-m-d H:i:s'); - - // Find user IDs of all sessions that are in the specified current and reference time - $sql = 'SELECT ses_usr_id, usr_uuid, usr_login_name - FROM ' . TBL_SESSIONS . ' - LEFT JOIN ' . TBL_USERS . ' - ON usr_id = ses_usr_id - WHERE ses_timestamp BETWEEN ? AND ? -- $refDate AND DATETIME_NOW - AND ses_org_id = ? -- $gCurrentOrgId'; - $queryParams = array($refDate, DATETIME_NOW, $gCurrentOrgId); - if (!$plg_show_visitors) { - $sql .= ' - AND ses_usr_id IS NOT NULL'; - } - if (!$plg_show_self && $gValidLogin) { - $sql .= ' - AND ses_usr_id <> ? -- $gCurrentUserId'; - $queryParams[] = $gCurrentUserId; - } - $sql .= ' - ORDER BY ses_usr_id'; - $onlineUsersStatement = $gDb->queryPrepared($sql, $queryParams); - - if ($onlineUsersStatement->rowCount() > 0) { - $usrIdMerker = 0; - $countMembers = 0; - $countVisitors = 0; - $allVisibleOnlineUsers = array(); - $textOnlineVisitors = ''; - - while ($row = $onlineUsersStatement->fetch()) { - if ($row['ses_usr_id'] > 0) { - if (((int)$row['ses_usr_id'] !== $usrIdMerker) - && ($plg_show_members == 1 || $gValidLogin)) { - $allVisibleOnlineUsers[] = '' . $row['usr_login_name'] . ''; - $usrIdMerker = (int)$row['ses_usr_id']; - } - ++$countMembers; - } else { - ++$countVisitors; - } - } - - if (!$gValidLogin && $plg_show_members == 2 && $countMembers > 0) { - if ($countMembers > 1) { - $allVisibleOnlineUsers[] = $gL10n->get('PLG_ONLINE_VAR_NUM_MEMBERS', array($countMembers)); - } else { - $allVisibleOnlineUsers[] = $gL10n->get('PLG_ONLINE_VAR_NUM_MEMBER', array($countMembers)); - } - } - - if ($plg_show_visitors && $countVisitors > 0) { - $allVisibleOnlineUsers[] = $gL10n->get('PLG_ONLINE_VAR_NUM_VISITORS', array($countVisitors)); - } - - if ($plg_show_users_side_by_side) { - $textOnlineVisitors = implode(', ', $allVisibleOnlineUsers); - } else { - $textOnlineVisitors = '
' . implode('
', $allVisibleOnlineUsers); - } - - if ($onlineUsersStatement->rowCount() === 1) { - $whoIsOnlinePlugin->assignTemplateVariable('message', $gL10n->get('PLG_ONLINE_VAR_ONLINE_IS', array($textOnlineVisitors))); - } else { - $whoIsOnlinePlugin->assignTemplateVariable('message', $gL10n->get('PLG_ONLINE_VAR_ONLINE_ARE', array($textOnlineVisitors))); - } - } else { - $whoIsOnlinePlugin->assignTemplateVariable('message', $gL10n->get('PLG_ONLINE_NO_VISITORS_ON_WEBSITE')); - } - - if (isset($page)) { - echo $whoIsOnlinePlugin->html('plugin.who-is-online.tpl'); - } else { - $whoIsOnlinePlugin->showHtmlPage('plugin.who-is-online.tpl'); - } -} catch (Throwable $e) { - echo $e->getMessage(); -} diff --git a/adm_plugins/who-is-online/languages/bg.xml b/adm_plugins/who-is-online/languages/bg.xml deleted file mode 100644 index 0d524f8c8e..0000000000 --- a/adm_plugins/who-is-online/languages/bg.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Кой е онлайн? - Няма онлайн потребители.. - #VAR1# посетители - #VAR1# члет - #VAR1# членове - Онлайн има #VAR1# - Онлайн е #VAR1# - diff --git a/adm_plugins/who-is-online/languages/da.xml b/adm_plugins/who-is-online/languages/da.xml deleted file mode 100644 index e007cf678c..0000000000 --- a/adm_plugins/who-is-online/languages/da.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - On-line - Lige nu er der ikke nogen besøgende på hjemmesiden - #VAR1# Gæster - #VAR1# Medlem - #VAR1# Medlemmer - Online er #VAR1# - Online er #VAR1# - diff --git a/adm_plugins/who-is-online/languages/de-DE.xml b/adm_plugins/who-is-online/languages/de-DE.xml deleted file mode 100644 index 1ef9dd4238..0000000000 --- a/adm_plugins/who-is-online/languages/de-DE.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Wer ist Online? - Zur Zeit sind keine Besucher auf der Webseite. - #VAR1# Besucher - #VAR1# Mitglied - #VAR1# Mitglieder - Online sind #VAR1# - Online ist #VAR1# - diff --git a/adm_plugins/who-is-online/languages/de.xml b/adm_plugins/who-is-online/languages/de.xml deleted file mode 100644 index 45b2250872..0000000000 --- a/adm_plugins/who-is-online/languages/de.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Wer ist Online? - Zur Zeit sind keine Besucher auf der Webseite. - #VAR1# Besucher - #VAR1# Mitglied - #VAR1# Mitglieder - Online sind #VAR1# - Online ist #VAR1# - diff --git a/adm_plugins/who-is-online/languages/el.xml b/adm_plugins/who-is-online/languages/el.xml deleted file mode 100644 index 324cc0f491..0000000000 --- a/adm_plugins/who-is-online/languages/el.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Ποιος είναι online; - Δεν υπάρχουν επισκέπτες αυτή τη στιγμή. - #VAR1# Επισκέπτες - #VAR1# μέλος - #VAR1# μέλη - Online είναι #VAR1# - Online είναι #VAR1# - diff --git a/adm_plugins/who-is-online/languages/en.xml b/adm_plugins/who-is-online/languages/en.xml deleted file mode 100644 index d9faf8ec4e..0000000000 --- a/adm_plugins/who-is-online/languages/en.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Who is online? - No visitors are on the website.. - #VAR1# Visitors - #VAR1# member - #VAR1# members - Online are #VAR1# - Online is #VAR1# - diff --git a/adm_plugins/who-is-online/languages/es.xml b/adm_plugins/who-is-online/languages/es.xml deleted file mode 100644 index 02a5800964..0000000000 --- a/adm_plugins/who-is-online/languages/es.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - En línea - En este momento no hay visitantes en el sitio web. - #VAR1# visitantes - #VAR1# Membro - #VAR1# Membros - diff --git a/adm_plugins/who-is-online/languages/et.xml b/adm_plugins/who-is-online/languages/et.xml deleted file mode 100644 index 8a5dc96d3c..0000000000 --- a/adm_plugins/who-is-online/languages/et.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Kes on Internetis? - Veebisaidil pole külastajaid.. - #VAR1# Külastajad - #VAR1# liige - #VAR1# liikmed - Internetis on #VAR1# - Internetis on #VAR1# - diff --git a/adm_plugins/who-is-online/languages/fi.xml b/adm_plugins/who-is-online/languages/fi.xml deleted file mode 100755 index d6c7f2e16e..0000000000 --- a/adm_plugins/who-is-online/languages/fi.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Kuka on kirjautuneena? - Ei vieraita sivustolla.. - #VAR1# Vieraita - #VAR1# jäsen - #VAR1# jäsentä - #VAR1# linjoilla - #VAR1# on linjoilla - diff --git a/adm_plugins/who-is-online/languages/fr.xml b/adm_plugins/who-is-online/languages/fr.xml deleted file mode 100644 index 06915baed4..0000000000 --- a/adm_plugins/who-is-online/languages/fr.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Qui est en ligne ? - Il n\'y a actuellement aucun visiteur sur le site Web. - #VAR1# visiteurs - #VAR1# Membre - #VAR1# Membres - En ligne sont #VAR1# - En ligne est #VAR1# - diff --git a/adm_plugins/who-is-online/languages/hu.xml b/adm_plugins/who-is-online/languages/hu.xml deleted file mode 100644 index f8179bf6ce..0000000000 --- a/adm_plugins/who-is-online/languages/hu.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Kik vannak online? - A honlapon nincsenek látogatók.. - #VAR1# Látogató - #VAR1# tag - #VAR1# tag - Online van #VAR1# - Online van #VAR1# - diff --git a/adm_plugins/who-is-online/languages/nb.xml b/adm_plugins/who-is-online/languages/nb.xml deleted file mode 100644 index ca96f0d4b7..0000000000 --- a/adm_plugins/who-is-online/languages/nb.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Online - Foreløpig er det ingen besøkende til nettstedet. - #VAR1# Besøkende - #VAR1# Medlem - #VAR1# Medlemmer - #VAR1# er online - #VAR1# er online - diff --git a/adm_plugins/who-is-online/languages/nl.xml b/adm_plugins/who-is-online/languages/nl.xml deleted file mode 100644 index 6119a2b2eb..0000000000 --- a/adm_plugins/who-is-online/languages/nl.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Wie is online? - Op dit moment zijn geen bezoekers op de website. - #VAR1# bezoekers - #VAR1# lid - #VAR1# leden - Online zijn #VAR1# - Online is #VAR1# - diff --git a/adm_plugins/who-is-online/languages/pl.xml b/adm_plugins/who-is-online/languages/pl.xml deleted file mode 100644 index 95a44da52e..0000000000 --- a/adm_plugins/who-is-online/languages/pl.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Kto jest on-line? - Nie ma odwiedzających na stronie. - #VAR1# Odwiedzających - #VAR1# Członek - #VAR1# Członków - #VAR1# jest On-line - #VAR1# są On-line - diff --git a/adm_plugins/who-is-online/languages/pt-BR.xml b/adm_plugins/who-is-online/languages/pt-BR.xml deleted file mode 100644 index b30a1a3508..0000000000 --- a/adm_plugins/who-is-online/languages/pt-BR.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Quem está on-line? - Atualmente, não há nenhum visitante no site da Web. - #VAR1# Visitantes - #VAR1# Membro - #VAR1# Membros - Estão #VAR1# on-line - Está #VAR1# on-line - diff --git a/adm_plugins/who-is-online/languages/pt.xml b/adm_plugins/who-is-online/languages/pt.xml deleted file mode 100644 index f40cc16bb0..0000000000 --- a/adm_plugins/who-is-online/languages/pt.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Quem está on-line? - Sem visitantes no site da Web. - #VAR1# Visitantes - #VAR1# membro - #VAR1# membros - Estão #VAR1# on-line - Está #VAR1# on-line - diff --git a/adm_plugins/who-is-online/languages/ru.xml b/adm_plugins/who-is-online/languages/ru.xml deleted file mode 100644 index ac25133a0b..0000000000 --- a/adm_plugins/who-is-online/languages/ru.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Кто онлайн? - На сайте нет посетителей. - #VAR1# посетителей - #VAR1# участник - #VAR1# участников - Онлайн #VAR1# - Онлайн #VAR1# - diff --git a/adm_plugins/who-is-online/languages/sv.xml b/adm_plugins/who-is-online/languages/sv.xml deleted file mode 100644 index 88ff4907cc..0000000000 --- a/adm_plugins/who-is-online/languages/sv.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Vem är online? - Inga besökare på webbplatsen .. - #VAR1# besökare - #VAR1# medlem - #VAR1# medlemmar - Online är #VAR1# - Online är #VAR1# - diff --git a/adm_plugins/who-is-online/languages/uk.xml b/adm_plugins/who-is-online/languages/uk.xml deleted file mode 100644 index 52b65b489e..0000000000 --- a/adm_plugins/who-is-online/languages/uk.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Хто онлайн? - На сайті немає відвідувачів. - #VAR1# Відвідувачів - #VAR1# учасник - #VAR1# учасників - Онлайн #VAR1# - Онлайн #VAR1# - diff --git a/adm_plugins/who-is-online/languages/zh.xml b/adm_plugins/who-is-online/languages/zh.xml deleted file mode 100644 index bf89610f73..0000000000 --- a/adm_plugins/who-is-online/languages/zh.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - 当前谁在线? - 还没有访客。 - #VAR1# 访客 - #VAR1# 会员 - #VAR1# 会员 - From 1aecc0187566756f54816349d3601416e4708982 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 23 Jul 2025 20:49:22 +0200 Subject: [PATCH 026/109] fix: language string name LoginForm --- adm_plugins/LoginForm/languages/en.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/adm_plugins/LoginForm/languages/en.xml b/adm_plugins/LoginForm/languages/en.xml index 9f965f2a16..4e7d74d1b2 100644 --- a/adm_plugins/LoginForm/languages/en.xml +++ b/adm_plugins/LoginForm/languages/en.xml @@ -17,8 +17,8 @@ If this option is enabled, a link to send an email to the administrator if you have login problems will be displayed in the login form. (default: true) Show logout link If this option is enabled, a link to log out will be displayed after login. (default: false) - Show ranks - If this option is enabled, a rank depending on the number of logins will be displayed after the username. (default: true) + Show ranks + If this option is enabled, a rank depending on the number of logins will be displayed after the username. (default: true) Ranks Here you can define the ranks that will be displayed after the username if \'Show ranks\' is enabled. The key is the number of logins and the value is the name of the rank. From 45981ce214ababb3f495736c74643ba726e89693 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 23 Jul 2025 20:49:48 +0200 Subject: [PATCH 027/109] feat: implement dynamic loading of overview plugins in the template --- modules/overview.php | 15 +++++ themes/simple/templates/system/overview.tpl | 61 +++------------------ 2 files changed, 22 insertions(+), 54 deletions(-) diff --git a/modules/overview.php b/modules/overview.php index 407b12b177..18c4a534cc 100644 --- a/modules/overview.php +++ b/modules/overview.php @@ -10,6 +10,7 @@ */ use Admidio\UI\Presenter\PagePresenter; +use Admidio\Infrastructure\Plugins\PluginManager; try { // if the config file doesn't exist, then show the installation dialog @@ -28,6 +29,20 @@ // create html page object and load template file $page = PagePresenter::withHtmlIDAndHeadline('admidio-overview', $headline); $page->setContentFullWidth(); + + // get all overview plugins and add them to the template + $pluginManager = new PluginManager(); + $plugins = $pluginManager->getOverviewPlugins(); + + $overviewPlugins = array(); + foreach ($plugins as $plugin) { + $overviewPlugins[] = array( + 'id' => $plugin['id'], + 'name' => $plugin['name'], + 'file' => basename($plugin['file']) + ); + } + $page->assignSmartyVariable('overviewPlugins', $overviewPlugins); $page->addTemplateFile('system/overview.tpl'); $page->show(); diff --git a/themes/simple/templates/system/overview.tpl b/themes/simple/templates/system/overview.tpl index d27a6d6271..fd18c5af9e 100644 --- a/themes/simple/templates/system/overview.tpl +++ b/themes/simple/templates/system/overview.tpl @@ -1,59 +1,12 @@
-
-
-
- {load_admidio_plugin plugin="login_form" file="index.php"} + {foreach $overviewPlugins as $plugin} +
+
+
+ {load_admidio_plugin plugin="{$plugin.name}" file="{$plugin.file}"} +
-
-
-
-
- {load_admidio_plugin plugin="birthday" file="index.php"} -
-
-
-
-
-
- {load_admidio_plugin plugin="calendar" file="index.php"} -
-
-
-
-
-
- {load_admidio_plugin plugin="random_photo" file="index.php"} -
-
-
-
-
-
- {load_admidio_plugin plugin="latest-documents-files" file="index.php"} -
-
-
-
-
-
- {load_admidio_plugin plugin="AnnouncementList" file="index.php"} -
-
-
-
-
-
- {load_admidio_plugin plugin="event-list" file="index.php"} -
-
-
-
-
-
- {load_admidio_plugin plugin="who-is-online" file="index.php"} -
-
-
+ {/foreach}
From 7768e3393640532fef3a51dd53090ec060c5461f Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 23 Jul 2025 20:54:38 +0200 Subject: [PATCH 028/109] fix: extend visibility toggling of preference form elements for plugins --- src/UI/Presenter/PreferencesPresenter.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/UI/Presenter/PreferencesPresenter.php b/src/UI/Presenter/PreferencesPresenter.php index 5508837ce8..c18a4bda82 100644 --- a/src/UI/Presenter/PreferencesPresenter.php +++ b/src/UI/Presenter/PreferencesPresenter.php @@ -2694,8 +2694,8 @@ function initializePanelInteractions(panelId) { // define additional ids that should also be considered for visibility toggling var additionalIds = [\'#system_notifications_enabled\']; - // Look for any input whose id ends with "_module_enabled" - var selectors = ["[id$=\'_module_enabled\']"].concat(additionalIds); + // Look for any input whose id ends with "_module_enabled" or "_plugin_enabled" + var selectors = ["[id$=\'_module_enabled\']", "[id$=\'_plugin_enabled\']"].concat(additionalIds); var moduleEnabledField = panelContainer.find(selectors.join(", ")).filter(":visible"); if (moduleEnabledField.length > 0) { From 99205ef1f74d01583031623aa69a1b48c2b891bd Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 23 Jul 2025 22:27:08 +0200 Subject: [PATCH 029/109] add new language strings for PluginManager --- languages/en.xml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/languages/en.xml b/languages/en.xml index 69dee53a42..96cb48965a 100644 --- a/languages/en.xml +++ b/languages/en.xml @@ -90,6 +90,8 @@ Spouse Wife + Plugin access + Plugin can be disabled or enabled for logged in users only. If plugin is only accessible to logged in users, it will be hidden for logged out users and web feed will be completely disabled for both user groups. (default: active) Module access Module can be disabled or enabled for logged in users only. If module is only accessible to logged in users, it will be hidden for logged out users and web feed will be completely disabled for both user groups. (default: active) Additional variables @@ -286,6 +288,7 @@ #VAR1# attachments You signed up for the event #VAR1_BOLD# on #VAR2#. You signed up tentative for the event #VAR1_BOLD# on #VAR2#. + Author Auto-detect Available Available Beta @@ -659,7 +662,9 @@ Export to Export vCard Export vCard of #VAR1# + Extension Extensions + Available extensions Facebook Fade in Favicon File @@ -782,6 +787,7 @@ The Admidio database is now installed and completely set up. The configuration file with the access data to the database has been created and stored. You can now work with Admidio and log in with the administrator data. The installation and setup of the database was successfully completed. Installed + Installed version Internal name The internal name is used to uniquely access this data object. This is not relevant for program use. In development, however, this name must always be used to identify the field, e.g. to address with getValue (). The internal name is automatically filled when creating a data record. Recipients need to be listed in the TO field instead of the BCC field @@ -1141,6 +1147,7 @@ Other tables (third-party modules; only visible to administrators) Overhang Overview + Overview extensions Page Previous Next @@ -1205,6 +1212,16 @@ Pipe (|) Select option Please wait + Install plugin + Plugin Manager + Here you can manage the plugins of Admidio. Plugins are additional modules that can be installed to extend the functionality of Admidio. You can install, update or remove plugins. + No plugin name specified. + The plugin has no interface. + The plugin is not installed. + Plugin preferences + Uninstall plugin + Update plugin + Plugin version Port Portrait Column names for auto detection: #VAR1# From 3bf9eedf8593b7eaabe0bf347301c5ced41bf762 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 23 Jul 2025 22:27:36 +0200 Subject: [PATCH 030/109] implement update step for installing overview plugins on update --- install/db_scripts/update_5_0.xml | 1 + .../Service/UpdateStepsCode.php | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/install/db_scripts/update_5_0.xml b/install/db_scripts/update_5_0.xml index ae5d8c748a..dc39d8cb8a 100644 --- a/install/db_scripts/update_5_0.xml +++ b/install/db_scripts/update_5_0.xml @@ -507,5 +507,6 @@ WHERE usf_fn.usf_name_intern = 'FIRST_NAME' AND usf_ln.usf_name_intern = 'LAST_N ALTER TABLE %PREFIX%_components ADD COLUMN com_plg_sequence smallint NOT NULL DEFAULT 0 AFTER com_update_completed; INSERT INTO %PREFIX%_menu (men_com_id, men_men_id_parent, men_uuid, men_node, men_order, men_standard, men_name_intern, men_url, men_icon, men_name, men_description) VALUES ((SELECT com_id FROM %PREFIX%_components WHERE com_name_intern = 'PLUGINS'), 2, %UUID%, false, 5, true, 'plugins', '/modules/plugins.php', 'puzzle', 'SYS_PLUGIN_MANAGER', 'SYS_PLUGIN_MANAGER_DESC') + UpdateStepsCode::updateStep50InstallOverviewPlugins stop diff --git a/src/InstallationUpdate/Service/UpdateStepsCode.php b/src/InstallationUpdate/Service/UpdateStepsCode.php index 91c13513a5..0c31b95d45 100644 --- a/src/InstallationUpdate/Service/UpdateStepsCode.php +++ b/src/InstallationUpdate/Service/UpdateStepsCode.php @@ -1,6 +1,7 @@ getAvailablePlugins(); + $arrayOverviewPlugins = array(/* 'AnnouncementList', 'Birthday', 'Calendar', 'EventList', 'LatestDocumentsFiles', */ 'LoginForm'/* , 'RandomPhoto', 'WhoIsOnline' */); + + foreach ($plugins as $pluginName => $plugin) { + if (in_array($pluginName, $arrayOverviewPlugins)) { + // Install the overview plugin + $plugin['interface']::getInstance()->doInstall(); + } + } + } + public static function updateStep50MoveFieldListValues() { $sql = 'SELECT usf_id, usf_value_list FROM ' . TBL_USER_FIELDS . ' From 5ae1ca9d770c3ec0c2305b9fc8051be6959b753a Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 23 Jul 2025 22:50:18 +0200 Subject: [PATCH 031/109] fix: installation errors --- install/db_scripts/db.sql | 2 +- install/install_steps/start_installation.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/install/db_scripts/db.sql b/install/db_scripts/db.sql index 3b0b57a2da..45f25a2301 100644 --- a/install/db_scripts/db.sql +++ b/install/db_scripts/db.sql @@ -1345,7 +1345,7 @@ ALTER TABLE %PREFIX%_user_relations ADD CONSTRAINT %PREFIX%_fk_ure_usr_create FOREIGN KEY (ure_usr_id_create) REFERENCES %PREFIX%_users (usr_id) ON DELETE SET NULL ON UPDATE RESTRICT; ALTER TABLE %PREFIX%_user_field_select_options - ADD CONSTRAINT %PREFIX%_fk_ufo_usf FOREIGN KEY (ufo_usf_id) REFERENCES %PREFIX%_user_fields (usf_id) ON DELETE RESTRICT ON UPDATE RESTRICT, + ADD CONSTRAINT %PREFIX%_fk_ufo_usf FOREIGN KEY (ufo_usf_id) REFERENCES %PREFIX%_user_fields (usf_id) ON DELETE RESTRICT ON UPDATE RESTRICT; ALTER TABLE %PREFIX%_inventory_fields ADD CONSTRAINT %PREFIX%_fk_inf_org FOREIGN KEY (inf_org_id) REFERENCES %PREFIX%_organizations (org_id) ON DELETE RESTRICT ON UPDATE RESTRICT, diff --git a/install/install_steps/start_installation.php b/install/install_steps/start_installation.php index c778c8eaf7..b96ecf0740 100644 --- a/install/install_steps/start_installation.php +++ b/install/install_steps/start_installation.php @@ -151,7 +151,7 @@ // add gender options to database $sql = 'INSERT INTO '.TBL_USER_FIELD_OPTIONS.' - (uso_usf_id, uso_value, uso_sequence) + (ufo_usf_id, ufo_value, ufo_sequence) VALUES ((SELECT usf_id FROM '.TBL_USER_FIELDS.' WHERE usf_cat_id = '.$categoryIdMasterData.' AND usf_name_intern = \'GENDER\'), \'gender-male|SYS_MALE\', 1) , ((SELECT usf_id FROM '.TBL_USER_FIELDS.' WHERE usf_cat_id = '.$categoryIdMasterData.' AND usf_name_intern = \'GENDER\'), \'gender-female|SYS_FEMALE\', 2) , ((SELECT usf_id FROM '.TBL_USER_FIELDS.' WHERE usf_cat_id = '.$categoryIdMasterData.' AND usf_name_intern = \'GENDER\'), \'gender-trans|SYS_DIVERSE\', 3)'; From fafbdd23913b4da8292384829382be720bf222d6 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 23 Jul 2025 22:51:17 +0200 Subject: [PATCH 032/109] install overview plugins during installation process --- install/db_scripts/db.sql | 1 + install/install_steps/start_installation.php | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/install/db_scripts/db.sql b/install/db_scripts/db.sql index 45f25a2301..4787753a2c 100644 --- a/install/db_scripts/db.sql +++ b/install/db_scripts/db.sql @@ -159,6 +159,7 @@ CREATE TABLE %PREFIX%_components com_beta smallint NOT NULL DEFAULT 0, com_update_step integer NOT NULL DEFAULT 0, com_update_completed boolean NOT NULL DEFAULT true, + com_plg_sequence smallint NOT NULL DEFAULT 0, com_timestamp_installed timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (com_id) ) diff --git a/install/install_steps/start_installation.php b/install/install_steps/start_installation.php index b96ecf0740..a81f1936ce 100644 --- a/install/install_steps/start_installation.php +++ b/install/install_steps/start_installation.php @@ -9,6 +9,7 @@ *********************************************************************************************** */ +use Admidio\Infrastructure\Plugins\PluginManager; use Admidio\Components\Entity\ComponentUpdate; use Admidio\Infrastructure\Exception; use Admidio\Infrastructure\Utils\PasswordUtils; @@ -281,9 +282,21 @@ , ((SELECT com_id FROM '.TBL_COMPONENTS.' WHERE com_name_intern = \'REGISTRATION\'), 2, \'' . Uuid::uuid4() . '\', false, 2, true, \'registration\', \''.FOLDER_MODULES.'/registration.php\', \'card-checklist\', \'SYS_REGISTRATIONS\', \'SYS_MANAGE_NEW_REGISTRATIONS_DESC\') , ((SELECT com_id FROM '.TBL_COMPONENTS.' WHERE com_name_intern = \'MENU\'), 2, \'' . Uuid::uuid4() . '\', false, 3, true, \'menu\', \''.FOLDER_MODULES.'/menu.php\', \'menu-button-wide-fill\', \'SYS_MENU\', \'SYS_MENU_DESC\') , ((SELECT com_id FROM '.TBL_COMPONENTS.' WHERE com_name_intern = \'ORGANIZATIONS\'), 2, \'' . Uuid::uuid4() . '\', false, 4, true, \'organization\', \''.FOLDER_MODULES.'/organizations.php\', \'diagram-3-fill\', \'SYS_ORGANIZATION\', \'SYS_ORGANIZATION_DESC\') - , ((SELECT com_id FROM '.TBL_COMPONENTS.' WHERE com_name_intern = \'PLUGINS\'), 2, \'' . Uuid::uuid4() . '\', false, 5, true, \'plugins\', \''.FOLDER_MODULES.'/plugins.php\', \'puzzle\', \'SYS_PLUGIN_MANAGER\', \SYS_PLUGIN_MANAGER_DESC\')'; + , ((SELECT com_id FROM '.TBL_COMPONENTS.' WHERE com_name_intern = \'PLUGINS\'), 2, \'' . Uuid::uuid4() . '\', false, 5, true, \'plugins\', \''.FOLDER_MODULES.'/plugins.php\', \'puzzle\', \'SYS_PLUGIN_MANAGER\', \'SYS_PLUGIN_MANAGER_DESC\')'; $db->query($sql); +// install all overview plugins +$pluginManager = new PluginManager(); +$plugins = $pluginManager->getAvailablePlugins(); +$arrayOverviewPlugins = array('AnnouncementList', 'Birthday', 'Calendar', 'EventList', 'LatestDocumentsFiles', 'LoginForm', 'RandomPhoto', 'WhoIsOnline'); + +foreach ($plugins as $pluginName => $plugin) { + if (in_array($pluginName, $arrayOverviewPlugins)) { + // Install the overview plugin + $plugin['interface']::getInstance()->doInstall(); + } +} + // delete session data session_unset(); session_destroy(); From b1a9906d1768a8d4e6ca2f2094cedbf889dccaf3 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Thu, 24 Jul 2025 10:25:27 +0200 Subject: [PATCH 033/109] implement dependency check for plugins during installation --- modules/plugins.php | 4 + src/Infrastructure/Plugins/PluginAbstract.php | 77 +++++++++++++++++++ .../Plugins/PluginInterface.php | 6 ++ 3 files changed, 87 insertions(+) diff --git a/modules/plugins.php b/modules/plugins.php index 50981b917f..ae927cb2ca 100644 --- a/modules/plugins.php +++ b/modules/plugins.php @@ -58,6 +58,10 @@ $interface = $plugin instanceof PluginAbstract ? $plugin::getInstance() : null; if ($interface != null) { + if (!$interface->checkDependencies()) { + throw new RuntimeException('Missing dependencies for ' . $getPluginName . ' plugin'); + } + $interface->doInstall(); } } diff --git a/src/Infrastructure/Plugins/PluginAbstract.php b/src/Infrastructure/Plugins/PluginAbstract.php index ead8249b34..72e563d682 100644 --- a/src/Infrastructure/Plugins/PluginAbstract.php +++ b/src/Infrastructure/Plugins/PluginAbstract.php @@ -361,6 +361,83 @@ public static function getPluginSequence() : int return (int)$statement->fetchColumn(); } + /** + * Check if the plugin has all dependencies installed. + * @throws Exception + * @return bool Returns true if all dependencies are installed, false otherwise. + */ + public static function checkDependencies() : bool + { + // check if the plugin has dependencies + if (empty(self::$dependencies)) { + return true; + } + + // ensure Composer’s PSR‑4 autoloader is registered + if (!self::doClassAutoload()) { + throw new \RuntimeException('Could not load Composer autoloader at ' . ADMIDIO_PATH . '/vendor/autoload.php'); + } + $missing = array(); + + // loop over all dependencies and check if they are available + foreach (self::$dependencies as $dependency) { + // dependencies should be a class name of the admidio core or the final namespace of the class + + // check if the dependency is a fully qualified class name or only a short name + if (class_exists($dependency, true)) { + // if the class exists, continue to the next dependency + continue; + } + + // if the class does not exist, try to find it in the Admidio namespace + if (self::findAdmidioClass($dependency) === null) { + $missing[] = $dependency; + } + } + + if (!empty($missing)) { + // not all dependencies are met + return false; + } + + return true; + } + + /** + * Scan src/ under the Admidio\ namespace for a class named $shortName. + * Returns the fully qualified class name if found, or null otherwise. + * + * @param string $shortName + * @return string|null + */ + private static function findAdmidioClass(string $shortName): ?string + { + // define the path to the src directory + $srcDir = ADMIDIO_PATH . '/src'; + $prefix = 'Admidio\\'; + + $it = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($srcDir)); + + // iterate through the directory structure to find the class file + foreach ($it as $file) { + if (! $file->isFile() || $file->getFilename() !== $shortName . '.php') { + continue; + } + + // if the file is found, construct the full class name + $relPath = substr($file->getPathname(), strlen($srcDir) + 1, -4); + $subNamespaces = str_replace(DIRECTORY_SEPARATOR, '\\', $relPath); + $fullName = $prefix . ($subNamespaces !== '' ? $subNamespaces : $shortName); + + + if (class_exists($fullName, true)) { + return $fullName; + } + } + + return null; + } + /** * @throws Exception * @return bool diff --git a/src/Infrastructure/Plugins/PluginInterface.php b/src/Infrastructure/Plugins/PluginInterface.php index f9c09da8e5..e86b3289be 100644 --- a/src/Infrastructure/Plugins/PluginInterface.php +++ b/src/Infrastructure/Plugins/PluginInterface.php @@ -73,6 +73,12 @@ public static function getComponentName() : string; */ public static function getPluginSequence() : int; + /** + * @throws Exception + * @return bool + */ + public static function checkDependencies() : bool; + /** * @throws Exception * @return bool From 7c929f442a8a9170cf426207b2efd1d01eebbdde Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Thu, 24 Jul 2025 10:33:16 +0200 Subject: [PATCH 034/109] add overview plugins dependencies to config files --- adm_plugins/AnnouncementList/AnnouncementList.json | 8 +++++++- .../AnnouncementList/classes/AnnouncementList.php | 2 +- adm_plugins/EventList/EventList.json | 8 +++++++- adm_plugins/EventList/classes/EventList.php | 2 +- .../LatestDocumentsFiles/LatestDocumentsFiles.json | 8 +++++++- .../classes/LatestDocumentsFiles.php | 2 +- adm_plugins/LoginForm/LoginForm.json | 9 ++++++++- adm_plugins/LoginForm/classes/LoginForm.php | 4 ++-- adm_plugins/RandomPhoto/RandomPhoto.json | 6 +++++- adm_plugins/RandomPhoto/classes/RandomPhoto.php | 2 +- adm_plugins/WhoIsOnline/WhoIsOnline.json | 6 +++++- adm_plugins/birthday/Birthday.json | 7 ++++++- adm_plugins/birthday/classes/Birthday.php | 4 ++-- adm_plugins/calendar/Calendar.json | 8 +++++++- adm_plugins/calendar/classes/Calendar.php | 4 ++-- 15 files changed, 62 insertions(+), 18 deletions(-) diff --git a/adm_plugins/AnnouncementList/AnnouncementList.json b/adm_plugins/AnnouncementList/AnnouncementList.json index 75e4c08fb5..83be863157 100644 --- a/adm_plugins/AnnouncementList/AnnouncementList.json +++ b/adm_plugins/AnnouncementList/AnnouncementList.json @@ -6,7 +6,13 @@ "url": "https://www.admidio.org", "icon": "bi-newspaper", "mainFile": "index.php", - "dependencies": [], + "dependencies": [ + "Admidio\\Announcements\\Entity\\Announcement", + "Admidio\\Infrastructure\\Database", + "Admidio\\Infrastructure\\Plugins\\Overview", + "Admidio\\Infrastructure\\Utils\\SecurityUtils", + "Admidio\\Infrastructure\\Plugins\\PluginAbstract" + ], "defaultConfig": { "announcement_list_plugin_enabled": { "name": "ORG_ACCESS_TO_PLUGIN", diff --git a/adm_plugins/AnnouncementList/classes/AnnouncementList.php b/adm_plugins/AnnouncementList/classes/AnnouncementList.php index 0cc9690faf..60ef8fa063 100644 --- a/adm_plugins/AnnouncementList/classes/AnnouncementList.php +++ b/adm_plugins/AnnouncementList/classes/AnnouncementList.php @@ -5,8 +5,8 @@ use Admidio\Announcements\Entity\Announcement; use Admidio\Infrastructure\Database; use Admidio\Infrastructure\Plugins\Overview; -use Admidio\Infrastructure\Utils\SecurityUtils; use Admidio\Infrastructure\Plugins\PluginAbstract; +use Admidio\Infrastructure\Utils\SecurityUtils; use InvalidArgumentException; use Exception; diff --git a/adm_plugins/EventList/EventList.json b/adm_plugins/EventList/EventList.json index 7350c294c7..ad1e2ef329 100644 --- a/adm_plugins/EventList/EventList.json +++ b/adm_plugins/EventList/EventList.json @@ -6,7 +6,13 @@ "url": "https://www.admidio.org", "icon": "bi-calendar-week-fill", "mainFile": "index.php", - "dependencies": [], + "dependencies": [ + "Admidio\\Events\\Entity\\Event", + "Admidio\\Infrastructure\\Database", + "Admidio\\Infrastructure\\Plugins\\Overview", + "Admidio\\Infrastructure\\Plugins\\PluginAbstract", + "Admidio\\Infrastructure\\Utils\\SecurityUtils" + ], "defaultConfig": { "event_list_plugin_enabled": { "name": "ORG_ACCESS_TO_PLUGIN", diff --git a/adm_plugins/EventList/classes/EventList.php b/adm_plugins/EventList/classes/EventList.php index 63d11371a7..cd58f843a6 100644 --- a/adm_plugins/EventList/classes/EventList.php +++ b/adm_plugins/EventList/classes/EventList.php @@ -5,8 +5,8 @@ use Admidio\Events\Entity\Event; use Admidio\Infrastructure\Database; use Admidio\Infrastructure\Plugins\Overview; -use Admidio\Infrastructure\Utils\SecurityUtils; use Admidio\Infrastructure\Plugins\PluginAbstract; +use Admidio\Infrastructure\Utils\SecurityUtils; use InvalidArgumentException; use Exception; diff --git a/adm_plugins/LatestDocumentsFiles/LatestDocumentsFiles.json b/adm_plugins/LatestDocumentsFiles/LatestDocumentsFiles.json index d98cc85e63..bab8c54245 100644 --- a/adm_plugins/LatestDocumentsFiles/LatestDocumentsFiles.json +++ b/adm_plugins/LatestDocumentsFiles/LatestDocumentsFiles.json @@ -6,7 +6,13 @@ "url": "https://www.admidio.org", "icon": "bi-file-earmark-arrow-down-fill", "mainFile": "index.php", - "dependencies": [], + "dependencies": [ + "Admidio\\Documents\\Entity\\File", + "Admidio\\Documents\\Entity\\Folder", + "Admidio\\Infrastructure\\Plugins\\Overview", + "Admidio\\Infrastructure\\Plugins\\PluginAbstract", + "Admidio\\Users\\Entity\\User" + ], "defaultConfig": { "latest_documents_files_plugin_enabled": { "name": "ORG_ACCESS_TO_PLUGIN", diff --git a/adm_plugins/LatestDocumentsFiles/classes/LatestDocumentsFiles.php b/adm_plugins/LatestDocumentsFiles/classes/LatestDocumentsFiles.php index a8c4fce11a..4bd3a0265b 100644 --- a/adm_plugins/LatestDocumentsFiles/classes/LatestDocumentsFiles.php +++ b/adm_plugins/LatestDocumentsFiles/classes/LatestDocumentsFiles.php @@ -5,8 +5,8 @@ use Admidio\Documents\Entity\File; use Admidio\Documents\Entity\Folder; use Admidio\Infrastructure\Plugins\Overview; -use Admidio\Users\Entity\User; use Admidio\Infrastructure\Plugins\PluginAbstract; +use Admidio\Users\Entity\User; use InvalidArgumentException; use Exception; diff --git a/adm_plugins/LoginForm/LoginForm.json b/adm_plugins/LoginForm/LoginForm.json index e5af107773..ffa2ca3c9b 100644 --- a/adm_plugins/LoginForm/LoginForm.json +++ b/adm_plugins/LoginForm/LoginForm.json @@ -6,7 +6,14 @@ "url": "https://www.admidio.org", "icon": "bi-box-arrow-in-right", "mainFile": "index.php", - "dependencies": [], + "dependencies": [ + "Admidio\\Infrastructure\\Language", + "Admidio\\Infrastructure\\Plugins\\Overview", + "Admidio\\Infrastructure\\Plugins\\PluginAbstract", + "Admidio\\Infrastructure\\Utils\\SecurityUtils", + "Admidio\\Roles\\Entity\\Role", + "Admidio\\UI\\Presenter\\FormPresenter" + ], "defaultConfig": { "login_form_plugin_enabled": { "name": "ORG_ACCESS_TO_PLUGIN", diff --git a/adm_plugins/LoginForm/classes/LoginForm.php b/adm_plugins/LoginForm/classes/LoginForm.php index e4bda665d3..c1f6842a59 100644 --- a/adm_plugins/LoginForm/classes/LoginForm.php +++ b/adm_plugins/LoginForm/classes/LoginForm.php @@ -2,12 +2,12 @@ namespace Plugins\LoginForm\classes; +use Admidio\Infrastructure\Language; use Admidio\Infrastructure\Plugins\Overview; use Admidio\Infrastructure\Plugins\PluginAbstract; -use Admidio\UI\Presenter\FormPresenter; use Admidio\Infrastructure\Utils\SecurityUtils; use Admidio\Roles\Entity\Role; -use Admidio\Infrastructure\Language; +use Admidio\UI\Presenter\FormPresenter; use InvalidArgumentException; use Exception; diff --git a/adm_plugins/RandomPhoto/RandomPhoto.json b/adm_plugins/RandomPhoto/RandomPhoto.json index d37f3f618e..819d4fcafc 100644 --- a/adm_plugins/RandomPhoto/RandomPhoto.json +++ b/adm_plugins/RandomPhoto/RandomPhoto.json @@ -6,7 +6,11 @@ "url": "https://www.admidio.org", "icon": "bi-image-fill", "mainFile": "index.php", - "dependencies": [], + "dependencies": [ + "Admidio\\Infrastructure\\Plugins\\Overview", + "Admidio\\Infrastructure\\Plugins\\PluginAbstract", + "Admidio\\Photos\\Entity\\Album" + ], "defaultConfig": { "random_photo_plugin_enabled": { "name": "ORG_ACCESS_TO_PLUGIN", diff --git a/adm_plugins/RandomPhoto/classes/RandomPhoto.php b/adm_plugins/RandomPhoto/classes/RandomPhoto.php index ab25f3c594..52afe9768b 100644 --- a/adm_plugins/RandomPhoto/classes/RandomPhoto.php +++ b/adm_plugins/RandomPhoto/classes/RandomPhoto.php @@ -2,9 +2,9 @@ namespace Plugins\RandomPhoto\classes; -use Admidio\Photos\Entity\Album; use Admidio\Infrastructure\Plugins\Overview; use Admidio\Infrastructure\Plugins\PluginAbstract; +use Admidio\Photos\Entity\Album; use InvalidArgumentException; use Exception; diff --git a/adm_plugins/WhoIsOnline/WhoIsOnline.json b/adm_plugins/WhoIsOnline/WhoIsOnline.json index 4a476c0679..66359d15f3 100644 --- a/adm_plugins/WhoIsOnline/WhoIsOnline.json +++ b/adm_plugins/WhoIsOnline/WhoIsOnline.json @@ -6,7 +6,11 @@ "url": "https://www.admidio.org", "icon": "bi-building-fill-check", "mainFile": "index.php", - "dependencies": [], + "dependencies": [ + "Admidio\\Infrastructure\\Plugins\\Overview", + "Admidio\\Infrastructure\\Plugins\\PluginAbstract", + "Admidio\\Infrastructure\\Utils\\SecurityUtils" + ], "defaultConfig": { "who_is_online_plugin_enabled": { "name": "ORG_ACCESS_TO_PLUGIN", diff --git a/adm_plugins/birthday/Birthday.json b/adm_plugins/birthday/Birthday.json index 1965085edd..6f7ebb2975 100644 --- a/adm_plugins/birthday/Birthday.json +++ b/adm_plugins/birthday/Birthday.json @@ -6,7 +6,12 @@ "url": "https://www.admidio.org", "icon": "bi-cake2", "mainFile": "index.php", - "dependencies": [], + "dependencies": [ + "Admidio\\Infrastructure\\Plugins\\Overview", + "Admidio\\Infrastructure\\Plugins\\PluginAbstract", + "Admidio\\Infrastructure\\Utils\\SecurityUtils", + "Admidio\\Roles\\Service\\RolesService" + ], "defaultConfig": { "birthday_plugin_enabled": { "name": "ORG_ACCESS_TO_PLUGIN", diff --git a/adm_plugins/birthday/classes/Birthday.php b/adm_plugins/birthday/classes/Birthday.php index a0c327e684..b1e445cf20 100644 --- a/adm_plugins/birthday/classes/Birthday.php +++ b/adm_plugins/birthday/classes/Birthday.php @@ -2,10 +2,10 @@ namespace Plugins\Birthday\classes; -use Admidio\Roles\Service\RolesService; use Admidio\Infrastructure\Plugins\Overview; -use Admidio\Infrastructure\Utils\SecurityUtils; use Admidio\Infrastructure\Plugins\PluginAbstract; +use Admidio\Infrastructure\Utils\SecurityUtils; +use Admidio\Roles\Service\RolesService; use InvalidArgumentException; use Exception; diff --git a/adm_plugins/calendar/Calendar.json b/adm_plugins/calendar/Calendar.json index a18309913b..e644b39a0a 100644 --- a/adm_plugins/calendar/Calendar.json +++ b/adm_plugins/calendar/Calendar.json @@ -6,7 +6,13 @@ "url": "https://www.admidio.org", "icon": "bi-calendar-week-fill", "mainFile": "index.php", - "dependencies": [], + "dependencies": [ + "Admidio\\Infrastructure\\Database", + "Admidio\\Infrastructure\\Plugins\\Overview", + "Admidio\\Infrastructure\\Plugins\\PluginAbstract", + "Admidio\\Infrastructure\\Utils\\SecurityUtils", + "Admidio\\Roles\\Service\\RolesService" + ], "defaultConfig": { "calendar_plugin_enabled": { "name": "ORG_ACCESS_TO_PLUGIN", diff --git a/adm_plugins/calendar/classes/Calendar.php b/adm_plugins/calendar/classes/Calendar.php index 7bf2ea4e7d..b24a869ee1 100644 --- a/adm_plugins/calendar/classes/Calendar.php +++ b/adm_plugins/calendar/classes/Calendar.php @@ -2,11 +2,11 @@ namespace Plugins\Calendar\classes; -use Admidio\Roles\Service\RolesService; use Admidio\Infrastructure\Database; use Admidio\Infrastructure\Plugins\Overview; -use Admidio\Infrastructure\Utils\SecurityUtils; use Admidio\Infrastructure\Plugins\PluginAbstract; +use Admidio\Infrastructure\Utils\SecurityUtils; +use Admidio\Roles\Service\RolesService; use InvalidArgumentException; use Exception; From b3df7dcc995bedec1885d95611100c07c9cd8d7d Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Thu, 24 Jul 2025 19:33:10 +0200 Subject: [PATCH 035/109] fix: use corrext urls for previousMonth, nextMonth and calendarReseLink to enable interacion wih the calendar again and don't create the complete page again just echo the fetched template content when click on any interaction link --- adm_plugins/calendar/classes/Calendar.php | 7 ++++++- adm_plugins/calendar/templates/plugin.calendar.tpl | 10 +++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/adm_plugins/calendar/classes/Calendar.php b/adm_plugins/calendar/classes/Calendar.php index b24a869ee1..b6d85c3137 100644 --- a/adm_plugins/calendar/classes/Calendar.php +++ b/adm_plugins/calendar/classes/Calendar.php @@ -34,6 +34,7 @@ class Calendar extends PluginAbstract private static string $currentYear = ''; private static int $today = 0; private static int $lastDayCurrentMonth = 0; + private static bool $getDatId = false; private static array $pluginConfig = array(); @@ -505,8 +506,12 @@ public static function initParams(array $params = array()) : bool throw new InvalidArgumentException('Config must be an "array".'); } + // reset get date id flag before init + self::$getDatId = false; + // init parameters if (isset($params['date_id']) && $params['date_id'] !== '') { + self::$getDatId = true; // Read Date ID or generate current month and year self::$currentMonth = substr($params['date_id'], 0, 2); self::$currentYear = substr($params['date_id'], 2, 4); @@ -573,7 +578,7 @@ public static function doRender($page = null) : bool $calendarPlugin->assignTemplateVariable('message', $gL10n->get('SYS_MODULE_DISABLED')); } - if (isset($page)) { + if (isset($page) || self::$getDatId) { echo $calendarPlugin->html('plugin.calendar.tpl'); } else { $calendarPlugin->showHtmlPage('plugin.calendar.tpl'); diff --git a/adm_plugins/calendar/templates/plugin.calendar.tpl b/adm_plugins/calendar/templates/plugin.calendar.tpl index 3caff07d9e..45178d0020 100644 --- a/adm_plugins/calendar/templates/plugin.calendar.tpl +++ b/adm_plugins/calendar/templates/plugin.calendar.tpl @@ -29,10 +29,10 @@
{/if} - +
From 20014c41c2fd4f3fa0944a69ba3661faba71fa8e Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Thu, 24 Jul 2025 23:06:26 +0200 Subject: [PATCH 036/109] fix: mobile view spacing --- themes/simple/templates/modules/profile.view.tpl | 2 +- themes/simple/templates/preferences/preferences.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/themes/simple/templates/modules/profile.view.tpl b/themes/simple/templates/modules/profile.view.tpl index 1e3e492ef2..d262b62e71 100644 --- a/themes/simple/templates/modules/profile.view.tpl +++ b/themes/simple/templates/modules/profile.view.tpl @@ -133,7 +133,7 @@
-
+
diff --git a/themes/simple/templates/preferences/preferences.tpl b/themes/simple/templates/preferences/preferences.tpl index 9db38174b5..70c278412b 100644 --- a/themes/simple/templates/preferences/preferences.tpl +++ b/themes/simple/templates/preferences/preferences.tpl @@ -48,7 +48,7 @@
-
+
{foreach $preferenceTabs as $tab name=outer} From 61eaf50ff6d9f01d54e3472c89ecc1436d154d7d Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Thu, 24 Jul 2025 23:08:08 +0200 Subject: [PATCH 037/109] implement mobile view for PluginManager and add website url to Presenter --- src/UI/Presenter/PluginsPresenter.php | 5 + system/js/common_functions.js | 2 +- .../simple/templates/modules/plugins.list.tpl | 180 +++++++++++++----- 3 files changed, 137 insertions(+), 50 deletions(-) diff --git a/src/UI/Presenter/PluginsPresenter.php b/src/UI/Presenter/PluginsPresenter.php index 8a9b91f5b5..1c0263ef71 100644 --- a/src/UI/Presenter/PluginsPresenter.php +++ b/src/UI/Presenter/PluginsPresenter.php @@ -71,13 +71,16 @@ public function createList(): void // wait for callUrlHideElement to finish hiding the element setTimeout(function() { updateMoveActions("tbody.admidio-sortable", "adm_plugin_entry", "admidio-plugin-move"); + updateMoveActions(".accordion", "adm_plugin_card_entry", "admidio-plugin-move"); }, 1000); } else { updateMoveActions("tbody.admidio-sortable", "adm_plugin_entry", "admidio-plugin-move"); + updateMoveActions(".accordion", "adm_plugin_card_entry", "admidio-plugin-move"); } }); updateMoveActions("tbody.admidio-sortable", "adm_plugin_entry", "admidio-plugin-move"); + updateMoveActions(".accordion", "adm_plugin_card_entry", "admidio-plugin-move"); ', true ); @@ -140,6 +143,7 @@ public function prepareData(): void $templateRow['name'] = Language::translateIfTranslationStrId($interface->getName()); $templateRow['description'] = Language::translateIfTranslationStrId($interface->getMetadata()['description'] ?? ''); $templateRow['icon'] = $interface->getMetadata()['icon'] ?? ''; + $templateRow['url'] = $interface->getMetadata()['url'] ? '' . parse_url($interface->getMetadata()['url'])['host'] . '' : ''; $templateRow['author'] = $interface->getMetadata()['author'] ?? ''; $templateRow['version'] = $interface->getMetadata()['version'] ?? ''; $templateRow['installedVersion'] = $interface->getVersion() !== '0.0.0' ? $interface->getVersion() : ''; @@ -182,6 +186,7 @@ public function prepareData(): void $templateRow['name'] = $pluginName; $templateRow['description'] = $gL10n->get('SYS_PLUGIN_NO_INTERFACE'); $templateRow['icon'] = ''; + $templateRow['url'] = ''; $templateRow['author'] = ''; $templateRow['version'] = ''; $templateRow['installedVersion'] = ''; diff --git a/system/js/common_functions.js b/system/js/common_functions.js index f9b8c4e858..cc191c2339 100644 --- a/system/js/common_functions.js +++ b/system/js/common_functions.js @@ -344,7 +344,7 @@ function updateMoveActions($scope, rowIdPrefix, moveActionClass) { $($scope).each(function() { // If the scope is ".card-body", we search for divs with IDs starting with rowIdPrefix. // Otherwise, we search for table rows with IDs starting with rowIdPrefix. - if ($scope === ".card-body") { + if ($scope === ".card-body" || $scope === ".accordion") { var $rows = $(this).find("div[id^=" + rowIdPrefix + "]").has("." + moveActionClass).filter(function() { return $(this).css("display") !== "none"; }); diff --git a/themes/simple/templates/modules/plugins.list.tpl b/themes/simple/templates/modules/plugins.list.tpl index 0d773cf771..a55638e132 100644 --- a/themes/simple/templates/modules/plugins.list.tpl +++ b/themes/simple/templates/modules/plugins.list.tpl @@ -1,54 +1,136 @@ -
- - - - - {* sort *} - - - - - {* actions *} - - - {foreach $list as $pluginNode} - - - + +
+
+
{$l10n->get('SYS_NAME')} {$l10n->get('SYS_DESCRIPTION')}{$l10n->get('SYS_AUTHOR')}{$l10n->get('SYS_PLUGIN_VERSION')}{$l10n->get('SYS_INSTALLED_VERSION')} 
- - - {$pluginNode.name} -
+ + + + {* sort *} + + + + + + {* actions *} - - {if isset($pluginNode.entries)} - - {foreach $pluginNode.entries as $pluginEntry} - - - - - - - - + + + + {if isset($pluginNode.entries)} + + {foreach $pluginNode.entries as $pluginEntry} + + + + + + + + + + + {/foreach} + + {/if} + {/foreach} +
{$l10n->get('SYS_NAME')} {$l10n->get('SYS_DESCRIPTION')}{$l10n->get('SYS_AUTHOR')}{$l10n->get('SYS_WEBSITE')}{$l10n->get('SYS_PLUGIN_VERSION')}{$l10n->get('SYS_INSTALLED_VERSION')} 
{if isset($pluginEntry.icon)}{/if} {$pluginEntry.name} - {if {string_contains haystack=$pluginNode.id needle='overview'}} - - - - - - - {/if} - {$pluginEntry.description}{$pluginEntry.author}{$pluginEntry.version}{$pluginEntry.installedVersion} - {include 'sys-template-parts/list.functions.tpl' data=$pluginEntry} + + {foreach $list as $pluginNode} +
+ + + {$pluginNode.name}
{if isset($pluginEntry.icon)}{/if} {$pluginEntry.name} + {if {string_contains haystack=$pluginNode.id needle='overview'}} +
+ + + + + + +
+ {/if} +
{$pluginEntry.description}{$pluginEntry.author}{$pluginEntry.url}{$pluginEntry.version}{$pluginEntry.installedVersion} + {include 'sys-template-parts/list.functions.tpl' data=$pluginEntry} +
+
+
+ + +
+
+ {foreach $list as $pluginNode name=outer} +
+

+ +

+
+
+ {foreach $pluginNode.entries as $pluginEntry} +
+
+ {if isset($pluginEntry.icon)}{/if} {$pluginEntry.name} + +
+
+
+ {$l10n->get('SYS_DESCRIPTION')}: +

{$pluginEntry.description}

+
+
+ {$l10n->get('SYS_AUTHOR')}: +

{$pluginEntry.author}

+
+
+ {$l10n->get('SYS_PLUGIN_VERSION')}: +

{$pluginEntry.version}

+
+
+ {$l10n->get('SYS_INSTALLED_VERSION')}: +

{$pluginEntry.installedVersion}

+
+
+
{/foreach} - - {/if} - {/foreach} - +
+
+
+ {/foreach} +
\ No newline at end of file From e75d53ef6bad8a39dc962ab19db053c6d8d961ca Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Fri, 25 Jul 2025 01:20:13 +0200 Subject: [PATCH 038/109] feat: differentiate between overview plugin and normal plugin preferences for PreferencePresenter and add functionality to add menu entry for a plugin with update steps (doInstall() needs to add the sequence and the UUID to the MenuEntry) --- src/Infrastructure/Plugins/PluginAbstract.php | 25 ++++++++-- .../Service/PreferencesService.php | 49 ++++++++++++++++++- src/UI/Presenter/PreferencesPresenter.php | 18 ++++++- 3 files changed, 85 insertions(+), 7 deletions(-) diff --git a/src/Infrastructure/Plugins/PluginAbstract.php b/src/Infrastructure/Plugins/PluginAbstract.php index 72e563d682..e3e877c823 100644 --- a/src/Infrastructure/Plugins/PluginAbstract.php +++ b/src/Infrastructure/Plugins/PluginAbstract.php @@ -4,9 +4,12 @@ use Admidio\Preferences\Service\PreferencesService; use Admidio\Components\Entity\Component; use Admidio\Components\Entity\ComponentUpdate; +use Admidio\Menu\Entity\MenuEntry; +use Admidio\Menu\ValueObject\MenuNode; use InvalidArgumentException; use Exception; +use Ramsey\Uuid\Uuid; /** * Class PluginAbstract @@ -58,11 +61,13 @@ public static function initPreferencePanelCallback(): void if (!method_exists($preferencesClass, $functionName)) { throw new Exception('The preferences class ' . $preferencesClass . ' does not have a method ' . $functionName . '().'); } - // register the preferences presenter for this plugin - PreferencesService::addPluginPreferencesPresenter( - self::getComponentId(), - [ $preferencesClass, $functionName ] - ); + if (self::isOverviewPlugin()) { + // register the overview preferences presenter for this plugin + PreferencesService::addOverviewPluginPreferencesPresenter(self::getComponentId(), [ $preferencesClass, $functionName ]); + } else { + // register the preferences presenter for this plugin + PreferencesService::addPluginPreferencesPresenter(self::getComponentId(), [ $preferencesClass, $functionName ]); + } } } @@ -549,6 +554,16 @@ public static function doInstall() : bool // TODO: implement function to perform updateSteps for the plugin // e.g.: $componentUpdateHandle->doUpdateSteps(); + // check if plugin has a menu entry generated with SQL if so add a vaild UUID + $pluginMenuEntry = new MenuEntry($gDb); + if ($pluginMenuEntry->readDataByColumns(array('men_name_intern' => basename(self::$pluginPath)))) { + $menuNode = new MenuNode('extensions', 'SYS_EXTENSIONS'); + $menuNode->loadFromDatabase(3); // extensions node has the id of 3 by default + $pluginMenuEntry->setValue('men_order', ($menuNode->count())); // set the order to the element. count includes the new entry + $pluginMenuEntry->setValue('men_uuid', (string)Uuid::uuid4()); + $pluginMenuEntry->save(); + } + return true; } diff --git a/src/Preferences/Service/PreferencesService.php b/src/Preferences/Service/PreferencesService.php index a30d091482..31cf57b221 100644 --- a/src/Preferences/Service/PreferencesService.php +++ b/src/Preferences/Service/PreferencesService.php @@ -28,6 +28,11 @@ class PreferencesService * @var array */ private static array $pluginPresenters = array(); + /** + * Registered presenter callbacks by component ID. + * @var array + */ + private static array $overviewPluginPresenters = array(); /** * Register a preferences presenter for a plugin. @@ -50,7 +55,7 @@ public static function addPluginPreferencesPresenter(int $componentId, callable */ public static function getPluginPresenters(): array { - return self::$pluginPresenters; + return array_merge(self::$overviewPluginPresenters, self::$pluginPresenters); } /** @@ -81,6 +86,48 @@ public static function getPluginPanels(): array return $panels; } + /** + * Register a preferences presenter for a plugin. + * + * @param int $componentId The component ID of the plugin. + * @param callable $presenterCallback A callable that renders the plugin's preferences panel. + */ + public static function addOverviewPluginPreferencesPresenter(int $componentId, callable $presenterCallback): void + { + if (!isset(self::$overviewPluginPresenters[$componentId])) { + self::$overviewPluginPresenters[$componentId] = array(); + } + self::$overviewPluginPresenters[$componentId][] = $presenterCallback; + } + + /** + * Build the panel definitions for the "Plugins" tab. + * + * This method gathers metadata from each plugin and prepares + * the structure used by the PreferencesPresenter to render the accordion. + * + * @return array + */ + public static function getOverviewPluginPanels(): array + { + $panels = array(); + + foreach (self::$overviewPluginPresenters as $comId => $callbacks) { + // Retrieve plugin metadata by component ID (you may need to implement this lookup) + $pluginManager = new PluginManager(); + $metadata = $pluginManager->getMetadataByComponentId($comId); + + $panels[] = array( + 'id' => preg_replace('/\s+/', '_', preg_replace('/[^a-z0-9_ ]/', '', strtolower(Language::translateIfTranslationStrId($metadata['name'])))), + 'title' => Language::translateIfTranslationStrId($metadata['name']), + 'icon' => $metadata['icon'] ?? 'bi-puzzle', + 'subcards' => $metadata['hasSubcards'] ?? false, + ); + } + + return $panels; + } + /** * Function to check an update * @param string $currentVersion diff --git a/src/UI/Presenter/PreferencesPresenter.php b/src/UI/Presenter/PreferencesPresenter.php index c18a4bda82..77092037ce 100644 --- a/src/UI/Presenter/PreferencesPresenter.php +++ b/src/UI/Presenter/PreferencesPresenter.php @@ -175,7 +175,23 @@ private function initialize(): void ) ), - // === 6) Extensions === + // === 6) Overview Extensions === + array( + 'key' => 'overview_extensions', + 'label' => $gL10n->get('SYS_OVERVIEW_EXTENSIONS'), + // load in all plugin panels that are registered in the PreferencesService + 'panels' => array_map( + fn(array $entry) => [ + 'id' => $entry['id'], + 'title' => $entry['title'], + 'icon' => $entry['icon'] ?? 'bi-puzzle', + 'subcards' => $entry['subcards'] ?? false, + ], + \Admidio\Preferences\Service\PreferencesService::getOverviewPluginPanels() + ) + ), + + // === 7) Extensions === array( 'key' => 'extensions', 'label' => $gL10n->get('SYS_EXTENSIONS'), From 08b46446ecb32b5ea62f9cc7804a96ff9e5f2f09 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Fri, 25 Jul 2025 11:43:19 +0200 Subject: [PATCH 039/109] feat: add visibility check for plugins in Component and update PluginInterface --- src/Components/Entity/Component.php | 11 +++++++++++ src/Infrastructure/Plugins/PluginInterface.php | 6 ++++++ 2 files changed, 17 insertions(+) diff --git a/src/Components/Entity/Component.php b/src/Components/Entity/Component.php index a1c4cd66de..6964110fdd 100644 --- a/src/Components/Entity/Component.php +++ b/src/Components/Entity/Component.php @@ -5,6 +5,8 @@ use Admidio\Infrastructure\Exception; use Admidio\Infrastructure\Database; use Admidio\Infrastructure\Entity\Entity; +use Admidio\Infrastructure\Plugins\PluginAbstract; +use Admidio\Infrastructure\Plugins\PluginManager; /** * @brief Handle different components of Admidio (e.g. system, plugins or modules) and manage them in the database @@ -325,6 +327,15 @@ public static function isVisible(string $componentName): bool return true; } break; + + default: + // check if the component is a plugin and it is visible + $pluginManager = new PluginManager(); + $plugin = $pluginManager->getPluginByName($componentName); + if ($plugin) { + return ($plugin instanceof PluginAbstract) ? $plugin::getInstance()->isVisible() : false; + } + break; } return false; diff --git a/src/Infrastructure/Plugins/PluginInterface.php b/src/Infrastructure/Plugins/PluginInterface.php index e86b3289be..a0ab3df542 100644 --- a/src/Infrastructure/Plugins/PluginInterface.php +++ b/src/Infrastructure/Plugins/PluginInterface.php @@ -91,6 +91,12 @@ public static function isInstalled() : bool; */ public static function isActivated() : bool; + /** + * @throws Exception + * @return bool + */ + public static function isVisible() : bool; + /** * @throws Exception * @return bool From e0b8a226aef0f92cedb8c35f3d00ab1b1f6f4824 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Fri, 25 Jul 2025 11:43:52 +0200 Subject: [PATCH 040/109] feat: implement menu entry management for plugins during installation and uninstallation and implement isVisible method --- src/Infrastructure/Plugins/PluginAbstract.php | 94 ++++++++++++++++--- 1 file changed, 82 insertions(+), 12 deletions(-) diff --git a/src/Infrastructure/Plugins/PluginAbstract.php b/src/Infrastructure/Plugins/PluginAbstract.php index e3e877c823..b1bf92e66b 100644 --- a/src/Infrastructure/Plugins/PluginAbstract.php +++ b/src/Infrastructure/Plugins/PluginAbstract.php @@ -5,11 +5,9 @@ use Admidio\Components\Entity\Component; use Admidio\Components\Entity\ComponentUpdate; use Admidio\Menu\Entity\MenuEntry; -use Admidio\Menu\ValueObject\MenuNode; use InvalidArgumentException; use Exception; -use Ramsey\Uuid\Uuid; /** * Class PluginAbstract @@ -50,6 +48,57 @@ public function __wakeup() } + /** + * Add the plugin menu entry to the database. + * This method is called during the installation of the plugin. + * @throws Exception + */ + private static function addMenuEntry() : void + { + global $gDb; + + $className = basename(self::$pluginPath); + + $pluginMenuEntry = new MenuEntry($gDb); + $pluginMenuEntry->setValue('men_men_id_parent', 3); // extensions node has the id of 3 by default + $pluginMenuEntry->setValue('men_name', self::$name); + $pluginMenuEntry->setValue('men_com_id', self::$pluginComId); + $pluginMenuEntry->setValue('men_description', self::$metadata['description']); + $pluginMenuEntry->setValue('men_url', FOLDER_PLUGINS . '/' . $className . '/' . $className . '.php'); + $pluginMenuEntry->setValue('men_icon', self::$metadata['icon']); + $pluginMenuEntry->save(); + + // rename the menu entry internal name to the class name + $pluginMenuEntry->readDataById($pluginMenuEntry->getValue('men_id')); + $pluginMenuEntry->setValue('men_name_intern', $className); + $pluginMenuEntry->save(); + } + + /** + * Remove the plugin menu entry from the database. + * This method is called during the uninstallation of the plugin. + * @throws Exception + */ + private static function removeMenuEntry() : bool + { + global $gDb; + + $className = basename(self::$pluginPath); + + // delete the plugin menu entry + $pluginMenuEntry = new MenuEntry($gDb); + if ($pluginMenuEntry->readDataByColumns(array('men_name_intern' => $className))) { + $pluginMenuEntry->delete(); + } + + return true; + } + + /** + * Initialize the preferences panel for this plugin. + * This method will be called automatically when the plugin is activated. + * It will register the preferences panel for this plugin in the PreferencesService. + */ public static function initPreferencePanelCallback(): void { // find a preference panel for this plugin @@ -467,6 +516,31 @@ public static function isActivated() : bool return self::isInstalled() && (self::getComponentId() > 0); } + /** + * @throws Exception + * @return bool + */ + public static function isVisible() : bool + { + global $gValidLogin, $gCurrentUser; + + // check if the plugin is activated + if (!self::isActivated()) { + return false; + } + + // check if the plugin has setting ending with '_enabled' + $pluginConfig = self::getPluginConfig(); + foreach ($pluginConfig as $key => $value) { + if (str_ends_with($key, '_enabled') && isset($value['value'])) { + if (($value['value'] === 1 || ($value['value'] === 2 && $gValidLogin))) { + return true; + } + } + } + return false; + } + /** * @throws Exception * @return bool @@ -550,20 +624,13 @@ public static function doInstall() : bool // set the installed version of the plugin self::$version = self::$metadata['version']; + // add the plugin menu entry to the database + self::addMenuEntry(); + // perform additional installation tasks // TODO: implement function to perform updateSteps for the plugin // e.g.: $componentUpdateHandle->doUpdateSteps(); - // check if plugin has a menu entry generated with SQL if so add a vaild UUID - $pluginMenuEntry = new MenuEntry($gDb); - if ($pluginMenuEntry->readDataByColumns(array('men_name_intern' => basename(self::$pluginPath)))) { - $menuNode = new MenuNode('extensions', 'SYS_EXTENSIONS'); - $menuNode->loadFromDatabase(3); // extensions node has the id of 3 by default - $pluginMenuEntry->setValue('men_order', ($menuNode->count())); // set the order to the element. count includes the new entry - $pluginMenuEntry->setValue('men_uuid', (string)Uuid::uuid4()); - $pluginMenuEntry->save(); - } - return true; } @@ -597,6 +664,9 @@ public static function doUninstall(array $options = array()) : bool // update $gSettingsManager to remove the plugin config values $gSettingsManager->resetAll(); + // remove the plugin menu entry + self::removeMenuEntry(); + // delete the plugin from the components table $plugin = new Component($gDb, self::$pluginComId); $plugin->delete(); From 069432af31424ed655ed79a98bec4e0bf53dd774 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Fri, 25 Jul 2025 13:12:52 +0200 Subject: [PATCH 041/109] rename adm_plugins folder to plugins --- .gitignore | 20 +++++++++---------- composer.json | 20 +++++++++---------- install/db_scripts/update_5_0.xml | 3 ++- .../AnnouncementList/AnnouncementList.json | 0 .../classes/AnnouncementList.php | 0 .../AnnouncementListPreferencesPresenter.php | 0 .../db_scripts/update_1_0.xml | 0 .../AnnouncementList/index.php | 0 .../AnnouncementList/languages/bg.xml | 0 .../AnnouncementList/languages/da.xml | 0 .../AnnouncementList/languages/de-DE.xml | 0 .../AnnouncementList/languages/de.xml | 0 .../AnnouncementList/languages/el.xml | 0 .../AnnouncementList/languages/en.xml | 0 .../AnnouncementList/languages/es.xml | 0 .../AnnouncementList/languages/et.xml | 0 .../AnnouncementList/languages/fi.xml | 0 .../AnnouncementList/languages/fr.xml | 0 .../AnnouncementList/languages/hu.xml | 0 .../AnnouncementList/languages/nb.xml | 0 .../AnnouncementList/languages/nl.xml | 0 .../AnnouncementList/languages/pl.xml | 0 .../AnnouncementList/languages/pt-BR.xml | 0 .../AnnouncementList/languages/pt.xml | 0 .../AnnouncementList/languages/ru.xml | 0 .../AnnouncementList/languages/sv.xml | 0 .../AnnouncementList/languages/uk.xml | 0 .../templates/plugin.announcement-list.tpl | 0 .../preferences.plugin.announcement-list.tpl | 0 .../Birthday}/Birthday.json | 0 .../Birthday}/classes/Birthday.php | 0 .../BirthdayPreferencesPresenter.php | 0 .../Birthday}/db_scripts/update_1_0.xml | 0 .../birthday => plugins/Birthday}/index.php | 0 .../Birthday}/languages/bg.xml | 0 .../Birthday}/languages/da.xml | 0 .../Birthday}/languages/de-DE.xml | 0 .../Birthday}/languages/de.xml | 0 .../Birthday}/languages/el.xml | 0 .../Birthday}/languages/en.xml | 0 .../Birthday}/languages/es.xml | 0 .../Birthday}/languages/et.xml | 0 .../Birthday}/languages/fi.xml | 0 .../Birthday}/languages/fr.xml | 0 .../Birthday}/languages/hu.xml | 0 .../Birthday}/languages/nb.xml | 0 .../Birthday}/languages/nl.xml | 0 .../Birthday}/languages/pl.xml | 0 .../Birthday}/languages/pt-BR.xml | 0 .../Birthday}/languages/pt.xml | 0 .../Birthday}/languages/ru.xml | 0 .../Birthday}/languages/sv.xml | 0 .../Birthday}/languages/uk.xml | 0 .../Birthday}/languages/zh.xml | 0 .../Birthday}/templates/plugin.birthday.tpl | 0 .../templates/preferences.plugin.birthday.tpl | 0 .../Calendar}/Calendar.json | 0 .../Calendar}/classes/Calendar.php | 0 .../CalendarPreferencesPresenter.php | 0 .../Calendar}/db_scripts/update_1_0.xml | 0 .../calendar => plugins/Calendar}/index.php | 0 .../Calendar}/languages/bg.xml | 0 .../Calendar}/languages/da.xml | 0 .../Calendar}/languages/de-DE.xml | 0 .../Calendar}/languages/de.xml | 0 .../Calendar}/languages/el.xml | 0 .../Calendar}/languages/en.xml | 0 .../Calendar}/languages/es.xml | 0 .../Calendar}/languages/et.xml | 0 .../Calendar}/languages/fi.xml | 0 .../Calendar}/languages/fr.xml | 0 .../Calendar}/languages/hu.xml | 0 .../Calendar}/languages/nb.xml | 0 .../Calendar}/languages/nl.xml | 0 .../Calendar}/languages/pl.xml | 0 .../Calendar}/languages/pt-BR.xml | 0 .../Calendar}/languages/pt.xml | 0 .../Calendar}/languages/ru.xml | 0 .../Calendar}/languages/sv.xml | 0 .../Calendar}/languages/uk.xml | 0 .../Calendar}/languages/zh.xml | 0 .../Calendar}/templates/plugin.calendar.tpl | 6 +++--- .../templates/preferences.plugin.calendar.tpl | 0 .../EventList/EventList.json | 0 .../EventList/classes/EventList.php | 0 .../EventListPreferencesPresenter.php | 0 .../EventList/db_scripts/update_1_0.xml | 0 {adm_plugins => plugins}/EventList/index.php | 0 .../EventList/languages/bg.xml | 0 .../EventList/languages/da.xml | 0 .../EventList/languages/de-DE.xml | 0 .../EventList/languages/de.xml | 0 .../EventList/languages/el.xml | 0 .../EventList/languages/en.xml | 0 .../EventList/languages/es.xml | 0 .../EventList/languages/et.xml | 0 .../EventList/languages/fi.xml | 0 .../EventList/languages/fr.xml | 0 .../EventList/languages/hu.xml | 0 .../EventList/languages/nb.xml | 0 .../EventList/languages/nl.xml | 0 .../EventList/languages/pl.xml | 0 .../EventList/languages/pt-BR.xml | 0 .../EventList/languages/pt.xml | 0 .../EventList/languages/ru.xml | 0 .../EventList/languages/sv.xml | 0 .../EventList/languages/uk.xml | 0 .../EventList/languages/zh.xml | 0 .../EventList/templates/plugin.event-list.tpl | 0 .../preferences.plugin.event-list.tpl | 0 .../LatestDocumentsFiles.json | 0 .../classes/LatestDocumentsFiles.php | 0 ...testDocumentsFilesPreferencesPresenter.php | 0 .../db_scripts/update_1_0.xml | 0 .../LatestDocumentsFiles/index.php | 0 .../LatestDocumentsFiles/languages/bg.xml | 0 .../LatestDocumentsFiles/languages/da.xml | 0 .../LatestDocumentsFiles/languages/de-DE.xml | 0 .../LatestDocumentsFiles/languages/de.xml | 0 .../LatestDocumentsFiles/languages/el.xml | 0 .../LatestDocumentsFiles/languages/en.xml | 0 .../LatestDocumentsFiles/languages/es.xml | 0 .../LatestDocumentsFiles/languages/et.xml | 0 .../LatestDocumentsFiles/languages/fi.xml | 0 .../LatestDocumentsFiles/languages/fr.xml | 0 .../LatestDocumentsFiles/languages/hu.xml | 0 .../LatestDocumentsFiles/languages/nb.xml | 0 .../LatestDocumentsFiles/languages/nl.xml | 0 .../LatestDocumentsFiles/languages/pl.xml | 0 .../LatestDocumentsFiles/languages/pt-BR.xml | 0 .../LatestDocumentsFiles/languages/pt.xml | 0 .../LatestDocumentsFiles/languages/ru.xml | 0 .../LatestDocumentsFiles/languages/sv.xml | 0 .../LatestDocumentsFiles/languages/uk.xml | 0 .../LatestDocumentsFiles/languages/zh.xml | 0 .../plugin.latest-documents-files.tpl | 0 ...ferences.plugin.latest-documents-files.tpl | 0 .../LoginForm/LoginForm.json | 0 .../LoginForm/classes/LoginForm.php | 0 .../LoginFormPreferencesPresenter.php | 0 .../LoginForm/db_scripts/update_1_0.xml | 0 {adm_plugins => plugins}/LoginForm/index.php | 0 .../LoginForm/languages/bg.xml | 0 .../LoginForm/languages/da.xml | 0 .../LoginForm/languages/de-DE.xml | 0 .../LoginForm/languages/de.xml | 0 .../LoginForm/languages/el.xml | 0 .../LoginForm/languages/en.xml | 0 .../LoginForm/languages/es.xml | 0 .../LoginForm/languages/et.xml | 0 .../LoginForm/languages/fi.xml | 0 .../LoginForm/languages/fr.xml | 0 .../LoginForm/languages/hu.xml | 0 .../LoginForm/languages/it.xml | 0 .../LoginForm/languages/nb.xml | 0 .../LoginForm/languages/nl.xml | 0 .../LoginForm/languages/pl.xml | 0 .../LoginForm/languages/pt-BR.xml | 0 .../LoginForm/languages/pt.xml | 0 .../LoginForm/languages/ru.xml | 0 .../LoginForm/languages/sv.xml | 0 .../LoginForm/languages/uk.xml | 0 .../LoginForm/languages/zh.xml | 0 .../templates/plugin.login-form.edit.tpl | 0 .../templates/plugin.login-form.view.tpl | 0 .../preferences.plugin.login-form.tpl | 0 .../RandomPhoto/RandomPhoto.json | 0 .../RandomPhotoPreferencesPresenter.php | 0 .../RandomPhoto/classes/RandomPhoto.php | 0 .../RandomPhoto/db_scripts/update_1_0.xml | 0 .../RandomPhoto/index.php | 0 .../RandomPhoto/languages/bg.xml | 0 .../RandomPhoto/languages/da.xml | 0 .../RandomPhoto/languages/de-DE.xml | 0 .../RandomPhoto/languages/de.xml | 0 .../RandomPhoto/languages/el.xml | 0 .../RandomPhoto/languages/en.xml | 0 .../RandomPhoto/languages/et.xml | 0 .../RandomPhoto/languages/fi.xml | 0 .../RandomPhoto/languages/fr.xml | 0 .../RandomPhoto/languages/hu.xml | 0 .../RandomPhoto/languages/nb.xml | 0 .../RandomPhoto/languages/nl.xml | 0 .../RandomPhoto/languages/pl.xml | 0 .../RandomPhoto/languages/pt.xml | 0 .../RandomPhoto/languages/ru.xml | 0 .../RandomPhoto/languages/sv.xml | 0 .../RandomPhoto/languages/uk.xml | 0 .../templates/plugin.random-photo.tpl | 0 .../preferences.plugin.random-photo.tpl | 0 .../WhoIsOnline/WhoIsOnline.json | 0 .../WhoIsOnlinePreferencesPresenter.php | 0 .../WhoIsOnline/classes/WhoIsOnline.php | 0 .../WhoIsOnline/db_scripts/update_1_0.xml | 0 .../WhoIsOnline/index.php | 0 .../WhoIsOnline/languages/bg.xml | 0 .../WhoIsOnline/languages/da.xml | 0 .../WhoIsOnline/languages/de-DE.xml | 0 .../WhoIsOnline/languages/de.xml | 0 .../WhoIsOnline/languages/el.xml | 0 .../WhoIsOnline/languages/en.xml | 0 .../WhoIsOnline/languages/es.xml | 0 .../WhoIsOnline/languages/et.xml | 0 .../WhoIsOnline/languages/fi.xml | 0 .../WhoIsOnline/languages/fr.xml | 0 .../WhoIsOnline/languages/hu.xml | 0 .../WhoIsOnline/languages/nb.xml | 0 .../WhoIsOnline/languages/nl.xml | 0 .../WhoIsOnline/languages/pl.xml | 0 .../WhoIsOnline/languages/pt-BR.xml | 0 .../WhoIsOnline/languages/pt.xml | 0 .../WhoIsOnline/languages/ru.xml | 0 .../WhoIsOnline/languages/sv.xml | 0 .../WhoIsOnline/languages/uk.xml | 0 .../WhoIsOnline/languages/zh.xml | 0 .../templates/plugin.who-is-online.tpl | 0 .../preferences.plugin.who-is-online.tpl | 0 src/Infrastructure/Language.php | 2 +- system/bootstrap/constants.php | 2 +- 219 files changed, 27 insertions(+), 26 deletions(-) rename {adm_plugins => plugins}/AnnouncementList/AnnouncementList.json (100%) rename {adm_plugins => plugins}/AnnouncementList/classes/AnnouncementList.php (100%) rename {adm_plugins => plugins}/AnnouncementList/classes/Presenter/AnnouncementListPreferencesPresenter.php (100%) rename {adm_plugins => plugins}/AnnouncementList/db_scripts/update_1_0.xml (100%) rename {adm_plugins => plugins}/AnnouncementList/index.php (100%) rename {adm_plugins => plugins}/AnnouncementList/languages/bg.xml (100%) rename {adm_plugins => plugins}/AnnouncementList/languages/da.xml (100%) rename {adm_plugins => plugins}/AnnouncementList/languages/de-DE.xml (100%) rename {adm_plugins => plugins}/AnnouncementList/languages/de.xml (100%) rename {adm_plugins => plugins}/AnnouncementList/languages/el.xml (100%) rename {adm_plugins => plugins}/AnnouncementList/languages/en.xml (100%) rename {adm_plugins => plugins}/AnnouncementList/languages/es.xml (100%) rename {adm_plugins => plugins}/AnnouncementList/languages/et.xml (100%) rename {adm_plugins => plugins}/AnnouncementList/languages/fi.xml (100%) rename {adm_plugins => plugins}/AnnouncementList/languages/fr.xml (100%) rename {adm_plugins => plugins}/AnnouncementList/languages/hu.xml (100%) rename {adm_plugins => plugins}/AnnouncementList/languages/nb.xml (100%) rename {adm_plugins => plugins}/AnnouncementList/languages/nl.xml (100%) rename {adm_plugins => plugins}/AnnouncementList/languages/pl.xml (100%) rename {adm_plugins => plugins}/AnnouncementList/languages/pt-BR.xml (100%) rename {adm_plugins => plugins}/AnnouncementList/languages/pt.xml (100%) rename {adm_plugins => plugins}/AnnouncementList/languages/ru.xml (100%) rename {adm_plugins => plugins}/AnnouncementList/languages/sv.xml (100%) rename {adm_plugins => plugins}/AnnouncementList/languages/uk.xml (100%) rename {adm_plugins => plugins}/AnnouncementList/templates/plugin.announcement-list.tpl (100%) rename {adm_plugins => plugins}/AnnouncementList/templates/preferences.plugin.announcement-list.tpl (100%) rename {adm_plugins/birthday => plugins/Birthday}/Birthday.json (100%) rename {adm_plugins/birthday => plugins/Birthday}/classes/Birthday.php (100%) rename {adm_plugins/birthday => plugins/Birthday}/classes/Presenter/BirthdayPreferencesPresenter.php (100%) rename {adm_plugins/birthday => plugins/Birthday}/db_scripts/update_1_0.xml (100%) rename {adm_plugins/birthday => plugins/Birthday}/index.php (100%) rename {adm_plugins/birthday => plugins/Birthday}/languages/bg.xml (100%) rename {adm_plugins/birthday => plugins/Birthday}/languages/da.xml (100%) rename {adm_plugins/birthday => plugins/Birthday}/languages/de-DE.xml (100%) rename {adm_plugins/birthday => plugins/Birthday}/languages/de.xml (100%) rename {adm_plugins/birthday => plugins/Birthday}/languages/el.xml (100%) rename {adm_plugins/birthday => plugins/Birthday}/languages/en.xml (100%) rename {adm_plugins/birthday => plugins/Birthday}/languages/es.xml (100%) rename {adm_plugins/birthday => plugins/Birthday}/languages/et.xml (100%) rename {adm_plugins/birthday => plugins/Birthday}/languages/fi.xml (100%) rename {adm_plugins/birthday => plugins/Birthday}/languages/fr.xml (100%) rename {adm_plugins/birthday => plugins/Birthday}/languages/hu.xml (100%) rename {adm_plugins/birthday => plugins/Birthday}/languages/nb.xml (100%) rename {adm_plugins/birthday => plugins/Birthday}/languages/nl.xml (100%) rename {adm_plugins/birthday => plugins/Birthday}/languages/pl.xml (100%) rename {adm_plugins/birthday => plugins/Birthday}/languages/pt-BR.xml (100%) rename {adm_plugins/birthday => plugins/Birthday}/languages/pt.xml (100%) rename {adm_plugins/birthday => plugins/Birthday}/languages/ru.xml (100%) rename {adm_plugins/birthday => plugins/Birthday}/languages/sv.xml (100%) rename {adm_plugins/birthday => plugins/Birthday}/languages/uk.xml (100%) rename {adm_plugins/birthday => plugins/Birthday}/languages/zh.xml (100%) rename {adm_plugins/birthday => plugins/Birthday}/templates/plugin.birthday.tpl (100%) rename {adm_plugins/birthday => plugins/Birthday}/templates/preferences.plugin.birthday.tpl (100%) rename {adm_plugins/calendar => plugins/Calendar}/Calendar.json (100%) rename {adm_plugins/calendar => plugins/Calendar}/classes/Calendar.php (100%) rename {adm_plugins/calendar => plugins/Calendar}/classes/Presenter/CalendarPreferencesPresenter.php (100%) rename {adm_plugins/calendar => plugins/Calendar}/db_scripts/update_1_0.xml (100%) rename {adm_plugins/calendar => plugins/Calendar}/index.php (100%) rename {adm_plugins/calendar => plugins/Calendar}/languages/bg.xml (100%) rename {adm_plugins/calendar => plugins/Calendar}/languages/da.xml (100%) rename {adm_plugins/calendar => plugins/Calendar}/languages/de-DE.xml (100%) rename {adm_plugins/calendar => plugins/Calendar}/languages/de.xml (100%) rename {adm_plugins/calendar => plugins/Calendar}/languages/el.xml (100%) rename {adm_plugins/calendar => plugins/Calendar}/languages/en.xml (100%) rename {adm_plugins/calendar => plugins/Calendar}/languages/es.xml (100%) rename {adm_plugins/calendar => plugins/Calendar}/languages/et.xml (100%) rename {adm_plugins/calendar => plugins/Calendar}/languages/fi.xml (100%) mode change 100755 => 100644 rename {adm_plugins/calendar => plugins/Calendar}/languages/fr.xml (100%) rename {adm_plugins/calendar => plugins/Calendar}/languages/hu.xml (100%) rename {adm_plugins/calendar => plugins/Calendar}/languages/nb.xml (100%) rename {adm_plugins/calendar => plugins/Calendar}/languages/nl.xml (100%) rename {adm_plugins/calendar => plugins/Calendar}/languages/pl.xml (100%) rename {adm_plugins/calendar => plugins/Calendar}/languages/pt-BR.xml (100%) rename {adm_plugins/calendar => plugins/Calendar}/languages/pt.xml (100%) rename {adm_plugins/calendar => plugins/Calendar}/languages/ru.xml (100%) rename {adm_plugins/calendar => plugins/Calendar}/languages/sv.xml (100%) rename {adm_plugins/calendar => plugins/Calendar}/languages/uk.xml (100%) rename {adm_plugins/calendar => plugins/Calendar}/languages/zh.xml (100%) rename {adm_plugins/calendar => plugins/Calendar}/templates/plugin.calendar.tpl (92%) rename {adm_plugins/calendar => plugins/Calendar}/templates/preferences.plugin.calendar.tpl (100%) rename {adm_plugins => plugins}/EventList/EventList.json (100%) rename {adm_plugins => plugins}/EventList/classes/EventList.php (100%) rename {adm_plugins => plugins}/EventList/classes/Presenter/EventListPreferencesPresenter.php (100%) rename {adm_plugins => plugins}/EventList/db_scripts/update_1_0.xml (100%) rename {adm_plugins => plugins}/EventList/index.php (100%) rename {adm_plugins => plugins}/EventList/languages/bg.xml (100%) rename {adm_plugins => plugins}/EventList/languages/da.xml (100%) rename {adm_plugins => plugins}/EventList/languages/de-DE.xml (100%) rename {adm_plugins => plugins}/EventList/languages/de.xml (100%) rename {adm_plugins => plugins}/EventList/languages/el.xml (100%) rename {adm_plugins => plugins}/EventList/languages/en.xml (100%) rename {adm_plugins => plugins}/EventList/languages/es.xml (100%) rename {adm_plugins => plugins}/EventList/languages/et.xml (100%) rename {adm_plugins => plugins}/EventList/languages/fi.xml (100%) rename {adm_plugins => plugins}/EventList/languages/fr.xml (100%) rename {adm_plugins => plugins}/EventList/languages/hu.xml (100%) rename {adm_plugins => plugins}/EventList/languages/nb.xml (100%) rename {adm_plugins => plugins}/EventList/languages/nl.xml (100%) rename {adm_plugins => plugins}/EventList/languages/pl.xml (100%) rename {adm_plugins => plugins}/EventList/languages/pt-BR.xml (100%) rename {adm_plugins => plugins}/EventList/languages/pt.xml (100%) rename {adm_plugins => plugins}/EventList/languages/ru.xml (100%) rename {adm_plugins => plugins}/EventList/languages/sv.xml (100%) rename {adm_plugins => plugins}/EventList/languages/uk.xml (100%) rename {adm_plugins => plugins}/EventList/languages/zh.xml (100%) rename {adm_plugins => plugins}/EventList/templates/plugin.event-list.tpl (100%) rename {adm_plugins => plugins}/EventList/templates/preferences.plugin.event-list.tpl (100%) rename {adm_plugins => plugins}/LatestDocumentsFiles/LatestDocumentsFiles.json (100%) rename {adm_plugins => plugins}/LatestDocumentsFiles/classes/LatestDocumentsFiles.php (100%) rename {adm_plugins => plugins}/LatestDocumentsFiles/classes/Presenter/LatestDocumentsFilesPreferencesPresenter.php (100%) rename {adm_plugins => plugins}/LatestDocumentsFiles/db_scripts/update_1_0.xml (100%) rename {adm_plugins => plugins}/LatestDocumentsFiles/index.php (100%) rename {adm_plugins => plugins}/LatestDocumentsFiles/languages/bg.xml (100%) rename {adm_plugins => plugins}/LatestDocumentsFiles/languages/da.xml (100%) rename {adm_plugins => plugins}/LatestDocumentsFiles/languages/de-DE.xml (100%) rename {adm_plugins => plugins}/LatestDocumentsFiles/languages/de.xml (100%) rename {adm_plugins => plugins}/LatestDocumentsFiles/languages/el.xml (100%) rename {adm_plugins => plugins}/LatestDocumentsFiles/languages/en.xml (100%) rename {adm_plugins => plugins}/LatestDocumentsFiles/languages/es.xml (100%) rename {adm_plugins => plugins}/LatestDocumentsFiles/languages/et.xml (100%) rename {adm_plugins => plugins}/LatestDocumentsFiles/languages/fi.xml (100%) rename {adm_plugins => plugins}/LatestDocumentsFiles/languages/fr.xml (100%) rename {adm_plugins => plugins}/LatestDocumentsFiles/languages/hu.xml (100%) rename {adm_plugins => plugins}/LatestDocumentsFiles/languages/nb.xml (100%) rename {adm_plugins => plugins}/LatestDocumentsFiles/languages/nl.xml (100%) rename {adm_plugins => plugins}/LatestDocumentsFiles/languages/pl.xml (100%) rename {adm_plugins => plugins}/LatestDocumentsFiles/languages/pt-BR.xml (100%) rename {adm_plugins => plugins}/LatestDocumentsFiles/languages/pt.xml (100%) rename {adm_plugins => plugins}/LatestDocumentsFiles/languages/ru.xml (100%) rename {adm_plugins => plugins}/LatestDocumentsFiles/languages/sv.xml (100%) rename {adm_plugins => plugins}/LatestDocumentsFiles/languages/uk.xml (100%) rename {adm_plugins => plugins}/LatestDocumentsFiles/languages/zh.xml (100%) rename {adm_plugins => plugins}/LatestDocumentsFiles/templates/plugin.latest-documents-files.tpl (100%) rename {adm_plugins => plugins}/LatestDocumentsFiles/templates/preferences.plugin.latest-documents-files.tpl (100%) rename {adm_plugins => plugins}/LoginForm/LoginForm.json (100%) rename {adm_plugins => plugins}/LoginForm/classes/LoginForm.php (100%) rename {adm_plugins => plugins}/LoginForm/classes/Presenter/LoginFormPreferencesPresenter.php (100%) rename {adm_plugins => plugins}/LoginForm/db_scripts/update_1_0.xml (100%) rename {adm_plugins => plugins}/LoginForm/index.php (100%) rename {adm_plugins => plugins}/LoginForm/languages/bg.xml (100%) rename {adm_plugins => plugins}/LoginForm/languages/da.xml (100%) rename {adm_plugins => plugins}/LoginForm/languages/de-DE.xml (100%) rename {adm_plugins => plugins}/LoginForm/languages/de.xml (100%) rename {adm_plugins => plugins}/LoginForm/languages/el.xml (100%) rename {adm_plugins => plugins}/LoginForm/languages/en.xml (100%) rename {adm_plugins => plugins}/LoginForm/languages/es.xml (100%) rename {adm_plugins => plugins}/LoginForm/languages/et.xml (100%) rename {adm_plugins => plugins}/LoginForm/languages/fi.xml (100%) rename {adm_plugins => plugins}/LoginForm/languages/fr.xml (100%) rename {adm_plugins => plugins}/LoginForm/languages/hu.xml (100%) rename {adm_plugins => plugins}/LoginForm/languages/it.xml (100%) rename {adm_plugins => plugins}/LoginForm/languages/nb.xml (100%) rename {adm_plugins => plugins}/LoginForm/languages/nl.xml (100%) rename {adm_plugins => plugins}/LoginForm/languages/pl.xml (100%) rename {adm_plugins => plugins}/LoginForm/languages/pt-BR.xml (100%) rename {adm_plugins => plugins}/LoginForm/languages/pt.xml (100%) rename {adm_plugins => plugins}/LoginForm/languages/ru.xml (100%) rename {adm_plugins => plugins}/LoginForm/languages/sv.xml (100%) rename {adm_plugins => plugins}/LoginForm/languages/uk.xml (100%) rename {adm_plugins => plugins}/LoginForm/languages/zh.xml (100%) rename {adm_plugins => plugins}/LoginForm/templates/plugin.login-form.edit.tpl (100%) rename {adm_plugins => plugins}/LoginForm/templates/plugin.login-form.view.tpl (100%) rename {adm_plugins => plugins}/LoginForm/templates/preferences.plugin.login-form.tpl (100%) rename {adm_plugins => plugins}/RandomPhoto/RandomPhoto.json (100%) rename {adm_plugins => plugins}/RandomPhoto/classes/Presenter/RandomPhotoPreferencesPresenter.php (100%) rename {adm_plugins => plugins}/RandomPhoto/classes/RandomPhoto.php (100%) rename {adm_plugins => plugins}/RandomPhoto/db_scripts/update_1_0.xml (100%) rename {adm_plugins => plugins}/RandomPhoto/index.php (100%) rename {adm_plugins => plugins}/RandomPhoto/languages/bg.xml (100%) rename {adm_plugins => plugins}/RandomPhoto/languages/da.xml (100%) rename {adm_plugins => plugins}/RandomPhoto/languages/de-DE.xml (100%) rename {adm_plugins => plugins}/RandomPhoto/languages/de.xml (100%) rename {adm_plugins => plugins}/RandomPhoto/languages/el.xml (100%) rename {adm_plugins => plugins}/RandomPhoto/languages/en.xml (100%) rename {adm_plugins => plugins}/RandomPhoto/languages/et.xml (100%) rename {adm_plugins => plugins}/RandomPhoto/languages/fi.xml (100%) rename {adm_plugins => plugins}/RandomPhoto/languages/fr.xml (100%) rename {adm_plugins => plugins}/RandomPhoto/languages/hu.xml (100%) rename {adm_plugins => plugins}/RandomPhoto/languages/nb.xml (100%) rename {adm_plugins => plugins}/RandomPhoto/languages/nl.xml (100%) rename {adm_plugins => plugins}/RandomPhoto/languages/pl.xml (100%) rename {adm_plugins => plugins}/RandomPhoto/languages/pt.xml (100%) rename {adm_plugins => plugins}/RandomPhoto/languages/ru.xml (100%) rename {adm_plugins => plugins}/RandomPhoto/languages/sv.xml (100%) rename {adm_plugins => plugins}/RandomPhoto/languages/uk.xml (100%) rename {adm_plugins => plugins}/RandomPhoto/templates/plugin.random-photo.tpl (100%) rename {adm_plugins => plugins}/RandomPhoto/templates/preferences.plugin.random-photo.tpl (100%) rename {adm_plugins => plugins}/WhoIsOnline/WhoIsOnline.json (100%) rename {adm_plugins => plugins}/WhoIsOnline/classes/Presenter/WhoIsOnlinePreferencesPresenter.php (100%) rename {adm_plugins => plugins}/WhoIsOnline/classes/WhoIsOnline.php (100%) rename {adm_plugins => plugins}/WhoIsOnline/db_scripts/update_1_0.xml (100%) rename {adm_plugins => plugins}/WhoIsOnline/index.php (100%) rename {adm_plugins => plugins}/WhoIsOnline/languages/bg.xml (100%) rename {adm_plugins => plugins}/WhoIsOnline/languages/da.xml (100%) rename {adm_plugins => plugins}/WhoIsOnline/languages/de-DE.xml (100%) rename {adm_plugins => plugins}/WhoIsOnline/languages/de.xml (100%) rename {adm_plugins => plugins}/WhoIsOnline/languages/el.xml (100%) rename {adm_plugins => plugins}/WhoIsOnline/languages/en.xml (100%) rename {adm_plugins => plugins}/WhoIsOnline/languages/es.xml (100%) rename {adm_plugins => plugins}/WhoIsOnline/languages/et.xml (100%) rename {adm_plugins => plugins}/WhoIsOnline/languages/fi.xml (100%) rename {adm_plugins => plugins}/WhoIsOnline/languages/fr.xml (100%) rename {adm_plugins => plugins}/WhoIsOnline/languages/hu.xml (100%) rename {adm_plugins => plugins}/WhoIsOnline/languages/nb.xml (100%) rename {adm_plugins => plugins}/WhoIsOnline/languages/nl.xml (100%) rename {adm_plugins => plugins}/WhoIsOnline/languages/pl.xml (100%) rename {adm_plugins => plugins}/WhoIsOnline/languages/pt-BR.xml (100%) rename {adm_plugins => plugins}/WhoIsOnline/languages/pt.xml (100%) rename {adm_plugins => plugins}/WhoIsOnline/languages/ru.xml (100%) rename {adm_plugins => plugins}/WhoIsOnline/languages/sv.xml (100%) rename {adm_plugins => plugins}/WhoIsOnline/languages/uk.xml (100%) rename {adm_plugins => plugins}/WhoIsOnline/languages/zh.xml (100%) rename {adm_plugins => plugins}/WhoIsOnline/templates/plugin.who-is-online.tpl (100%) rename {adm_plugins => plugins}/WhoIsOnline/templates/preferences.plugin.who-is-online.tpl (100%) diff --git a/.gitignore b/.gitignore index ef4d661e3b..79dde60897 100644 --- a/.gitignore +++ b/.gitignore @@ -10,16 +10,16 @@ !/adm_my_files/index.html # Only allow commit of official plugins -/adm_plugins/* -!/adm_plugins/Birthday/ -!/adm_plugins/Calendar/ -!/adm_plugins/LoginForm/ -!/adm_plugins/RandomPhoto/ -!/adm_plugins/AnnouncementList/ -!/adm_plugins/EventList/ -!/adm_plugins/LatestDocumentsFiles/ -!/adm_plugins/WhoIsOnline/ -!/adm_plugins/CategoryReport/ +/plugins/* +!/plugins/Birthday/ +!/plugins/Calendar/ +!/plugins/LoginForm/ +!/plugins/RandomPhoto/ +!/plugins/AnnouncementList/ +!/plugins/EventList/ +!/plugins/LatestDocumentsFiles/ +!/plugins/WhoIsOnline/ +!/plugins/CategoryReport/ # Only allow commit of official themes /themes/* diff --git a/composer.json b/composer.json index 0ee8cdcfb5..57f75184b8 100644 --- a/composer.json +++ b/composer.json @@ -51,7 +51,7 @@ "autoload": { "psr-4": { "Admidio\\": "src/", - "Plugins\\": "adm_plugins/" + "Plugins\\": "plugins/" }, "classmap": [ "system/classes/", @@ -67,15 +67,15 @@ "!adm_my_files/config_example.php", "!adm_my_files/ecard_templates", "!adm_my_files/mail_templates", - "adm_plugins/*", - "!adm_plugins/AnnouncementList", - "!adm_plugins/Birthday", - "!adm_plugins/Calendar", - "!adm_plugins/EventList", - "!adm_plugins/LatestDocumentsFiles", - "!adm_plugins/LoginForm", - "!adm_plugins/RandomPhoto", - "!adm_plugins/WhoIsOnline", + "plugins/*", + "!plugins/AnnouncementList", + "!plugins/Birthday", + "!plugins/Calendar", + "!plugins/EventList", + "!plugins/LatestDocumentsFiles", + "!plugins/LoginForm", + "!plugins/RandomPhoto", + "!plugins/WhoIsOnline", "demo_data", "!vendor/*", "vendor/maennchen/zipstream-php/test", diff --git a/install/db_scripts/update_5_0.xml b/install/db_scripts/update_5_0.xml index dc39d8cb8a..5b5a10d318 100644 --- a/install/db_scripts/update_5_0.xml +++ b/install/db_scripts/update_5_0.xml @@ -507,6 +507,7 @@ WHERE usf_fn.usf_name_intern = 'FIRST_NAME' AND usf_ln.usf_name_intern = 'LAST_N ALTER TABLE %PREFIX%_components ADD COLUMN com_plg_sequence smallint NOT NULL DEFAULT 0 AFTER com_update_completed; INSERT INTO %PREFIX%_menu (men_com_id, men_men_id_parent, men_uuid, men_node, men_order, men_standard, men_name_intern, men_url, men_icon, men_name, men_description) VALUES ((SELECT com_id FROM %PREFIX%_components WHERE com_name_intern = 'PLUGINS'), 2, %UUID%, false, 5, true, 'plugins', '/modules/plugins.php', 'puzzle', 'SYS_PLUGIN_MANAGER', 'SYS_PLUGIN_MANAGER_DESC') - UpdateStepsCode::updateStep50InstallOverviewPlugins + UPDATE %PREFIX%_menu SET men_url = REPLACE(men_url, '/adm_plugins', 'plugins') WHERE men_url LIKE '%/adm_plugins%' + UpdateStepsCode::updateStep50InstallOverviewPlugins stop diff --git a/adm_plugins/AnnouncementList/AnnouncementList.json b/plugins/AnnouncementList/AnnouncementList.json similarity index 100% rename from adm_plugins/AnnouncementList/AnnouncementList.json rename to plugins/AnnouncementList/AnnouncementList.json diff --git a/adm_plugins/AnnouncementList/classes/AnnouncementList.php b/plugins/AnnouncementList/classes/AnnouncementList.php similarity index 100% rename from adm_plugins/AnnouncementList/classes/AnnouncementList.php rename to plugins/AnnouncementList/classes/AnnouncementList.php diff --git a/adm_plugins/AnnouncementList/classes/Presenter/AnnouncementListPreferencesPresenter.php b/plugins/AnnouncementList/classes/Presenter/AnnouncementListPreferencesPresenter.php similarity index 100% rename from adm_plugins/AnnouncementList/classes/Presenter/AnnouncementListPreferencesPresenter.php rename to plugins/AnnouncementList/classes/Presenter/AnnouncementListPreferencesPresenter.php diff --git a/adm_plugins/AnnouncementList/db_scripts/update_1_0.xml b/plugins/AnnouncementList/db_scripts/update_1_0.xml similarity index 100% rename from adm_plugins/AnnouncementList/db_scripts/update_1_0.xml rename to plugins/AnnouncementList/db_scripts/update_1_0.xml diff --git a/adm_plugins/AnnouncementList/index.php b/plugins/AnnouncementList/index.php similarity index 100% rename from adm_plugins/AnnouncementList/index.php rename to plugins/AnnouncementList/index.php diff --git a/adm_plugins/AnnouncementList/languages/bg.xml b/plugins/AnnouncementList/languages/bg.xml similarity index 100% rename from adm_plugins/AnnouncementList/languages/bg.xml rename to plugins/AnnouncementList/languages/bg.xml diff --git a/adm_plugins/AnnouncementList/languages/da.xml b/plugins/AnnouncementList/languages/da.xml similarity index 100% rename from adm_plugins/AnnouncementList/languages/da.xml rename to plugins/AnnouncementList/languages/da.xml diff --git a/adm_plugins/AnnouncementList/languages/de-DE.xml b/plugins/AnnouncementList/languages/de-DE.xml similarity index 100% rename from adm_plugins/AnnouncementList/languages/de-DE.xml rename to plugins/AnnouncementList/languages/de-DE.xml diff --git a/adm_plugins/AnnouncementList/languages/de.xml b/plugins/AnnouncementList/languages/de.xml similarity index 100% rename from adm_plugins/AnnouncementList/languages/de.xml rename to plugins/AnnouncementList/languages/de.xml diff --git a/adm_plugins/AnnouncementList/languages/el.xml b/plugins/AnnouncementList/languages/el.xml similarity index 100% rename from adm_plugins/AnnouncementList/languages/el.xml rename to plugins/AnnouncementList/languages/el.xml diff --git a/adm_plugins/AnnouncementList/languages/en.xml b/plugins/AnnouncementList/languages/en.xml similarity index 100% rename from adm_plugins/AnnouncementList/languages/en.xml rename to plugins/AnnouncementList/languages/en.xml diff --git a/adm_plugins/AnnouncementList/languages/es.xml b/plugins/AnnouncementList/languages/es.xml similarity index 100% rename from adm_plugins/AnnouncementList/languages/es.xml rename to plugins/AnnouncementList/languages/es.xml diff --git a/adm_plugins/AnnouncementList/languages/et.xml b/plugins/AnnouncementList/languages/et.xml similarity index 100% rename from adm_plugins/AnnouncementList/languages/et.xml rename to plugins/AnnouncementList/languages/et.xml diff --git a/adm_plugins/AnnouncementList/languages/fi.xml b/plugins/AnnouncementList/languages/fi.xml similarity index 100% rename from adm_plugins/AnnouncementList/languages/fi.xml rename to plugins/AnnouncementList/languages/fi.xml diff --git a/adm_plugins/AnnouncementList/languages/fr.xml b/plugins/AnnouncementList/languages/fr.xml similarity index 100% rename from adm_plugins/AnnouncementList/languages/fr.xml rename to plugins/AnnouncementList/languages/fr.xml diff --git a/adm_plugins/AnnouncementList/languages/hu.xml b/plugins/AnnouncementList/languages/hu.xml similarity index 100% rename from adm_plugins/AnnouncementList/languages/hu.xml rename to plugins/AnnouncementList/languages/hu.xml diff --git a/adm_plugins/AnnouncementList/languages/nb.xml b/plugins/AnnouncementList/languages/nb.xml similarity index 100% rename from adm_plugins/AnnouncementList/languages/nb.xml rename to plugins/AnnouncementList/languages/nb.xml diff --git a/adm_plugins/AnnouncementList/languages/nl.xml b/plugins/AnnouncementList/languages/nl.xml similarity index 100% rename from adm_plugins/AnnouncementList/languages/nl.xml rename to plugins/AnnouncementList/languages/nl.xml diff --git a/adm_plugins/AnnouncementList/languages/pl.xml b/plugins/AnnouncementList/languages/pl.xml similarity index 100% rename from adm_plugins/AnnouncementList/languages/pl.xml rename to plugins/AnnouncementList/languages/pl.xml diff --git a/adm_plugins/AnnouncementList/languages/pt-BR.xml b/plugins/AnnouncementList/languages/pt-BR.xml similarity index 100% rename from adm_plugins/AnnouncementList/languages/pt-BR.xml rename to plugins/AnnouncementList/languages/pt-BR.xml diff --git a/adm_plugins/AnnouncementList/languages/pt.xml b/plugins/AnnouncementList/languages/pt.xml similarity index 100% rename from adm_plugins/AnnouncementList/languages/pt.xml rename to plugins/AnnouncementList/languages/pt.xml diff --git a/adm_plugins/AnnouncementList/languages/ru.xml b/plugins/AnnouncementList/languages/ru.xml similarity index 100% rename from adm_plugins/AnnouncementList/languages/ru.xml rename to plugins/AnnouncementList/languages/ru.xml diff --git a/adm_plugins/AnnouncementList/languages/sv.xml b/plugins/AnnouncementList/languages/sv.xml similarity index 100% rename from adm_plugins/AnnouncementList/languages/sv.xml rename to plugins/AnnouncementList/languages/sv.xml diff --git a/adm_plugins/AnnouncementList/languages/uk.xml b/plugins/AnnouncementList/languages/uk.xml similarity index 100% rename from adm_plugins/AnnouncementList/languages/uk.xml rename to plugins/AnnouncementList/languages/uk.xml diff --git a/adm_plugins/AnnouncementList/templates/plugin.announcement-list.tpl b/plugins/AnnouncementList/templates/plugin.announcement-list.tpl similarity index 100% rename from adm_plugins/AnnouncementList/templates/plugin.announcement-list.tpl rename to plugins/AnnouncementList/templates/plugin.announcement-list.tpl diff --git a/adm_plugins/AnnouncementList/templates/preferences.plugin.announcement-list.tpl b/plugins/AnnouncementList/templates/preferences.plugin.announcement-list.tpl similarity index 100% rename from adm_plugins/AnnouncementList/templates/preferences.plugin.announcement-list.tpl rename to plugins/AnnouncementList/templates/preferences.plugin.announcement-list.tpl diff --git a/adm_plugins/birthday/Birthday.json b/plugins/Birthday/Birthday.json similarity index 100% rename from adm_plugins/birthday/Birthday.json rename to plugins/Birthday/Birthday.json diff --git a/adm_plugins/birthday/classes/Birthday.php b/plugins/Birthday/classes/Birthday.php similarity index 100% rename from adm_plugins/birthday/classes/Birthday.php rename to plugins/Birthday/classes/Birthday.php diff --git a/adm_plugins/birthday/classes/Presenter/BirthdayPreferencesPresenter.php b/plugins/Birthday/classes/Presenter/BirthdayPreferencesPresenter.php similarity index 100% rename from adm_plugins/birthday/classes/Presenter/BirthdayPreferencesPresenter.php rename to plugins/Birthday/classes/Presenter/BirthdayPreferencesPresenter.php diff --git a/adm_plugins/birthday/db_scripts/update_1_0.xml b/plugins/Birthday/db_scripts/update_1_0.xml similarity index 100% rename from adm_plugins/birthday/db_scripts/update_1_0.xml rename to plugins/Birthday/db_scripts/update_1_0.xml diff --git a/adm_plugins/birthday/index.php b/plugins/Birthday/index.php similarity index 100% rename from adm_plugins/birthday/index.php rename to plugins/Birthday/index.php diff --git a/adm_plugins/birthday/languages/bg.xml b/plugins/Birthday/languages/bg.xml similarity index 100% rename from adm_plugins/birthday/languages/bg.xml rename to plugins/Birthday/languages/bg.xml diff --git a/adm_plugins/birthday/languages/da.xml b/plugins/Birthday/languages/da.xml similarity index 100% rename from adm_plugins/birthday/languages/da.xml rename to plugins/Birthday/languages/da.xml diff --git a/adm_plugins/birthday/languages/de-DE.xml b/plugins/Birthday/languages/de-DE.xml similarity index 100% rename from adm_plugins/birthday/languages/de-DE.xml rename to plugins/Birthday/languages/de-DE.xml diff --git a/adm_plugins/birthday/languages/de.xml b/plugins/Birthday/languages/de.xml similarity index 100% rename from adm_plugins/birthday/languages/de.xml rename to plugins/Birthday/languages/de.xml diff --git a/adm_plugins/birthday/languages/el.xml b/plugins/Birthday/languages/el.xml similarity index 100% rename from adm_plugins/birthday/languages/el.xml rename to plugins/Birthday/languages/el.xml diff --git a/adm_plugins/birthday/languages/en.xml b/plugins/Birthday/languages/en.xml similarity index 100% rename from adm_plugins/birthday/languages/en.xml rename to plugins/Birthday/languages/en.xml diff --git a/adm_plugins/birthday/languages/es.xml b/plugins/Birthday/languages/es.xml similarity index 100% rename from adm_plugins/birthday/languages/es.xml rename to plugins/Birthday/languages/es.xml diff --git a/adm_plugins/birthday/languages/et.xml b/plugins/Birthday/languages/et.xml similarity index 100% rename from adm_plugins/birthday/languages/et.xml rename to plugins/Birthday/languages/et.xml diff --git a/adm_plugins/birthday/languages/fi.xml b/plugins/Birthday/languages/fi.xml similarity index 100% rename from adm_plugins/birthday/languages/fi.xml rename to plugins/Birthday/languages/fi.xml diff --git a/adm_plugins/birthday/languages/fr.xml b/plugins/Birthday/languages/fr.xml similarity index 100% rename from adm_plugins/birthday/languages/fr.xml rename to plugins/Birthday/languages/fr.xml diff --git a/adm_plugins/birthday/languages/hu.xml b/plugins/Birthday/languages/hu.xml similarity index 100% rename from adm_plugins/birthday/languages/hu.xml rename to plugins/Birthday/languages/hu.xml diff --git a/adm_plugins/birthday/languages/nb.xml b/plugins/Birthday/languages/nb.xml similarity index 100% rename from adm_plugins/birthday/languages/nb.xml rename to plugins/Birthday/languages/nb.xml diff --git a/adm_plugins/birthday/languages/nl.xml b/plugins/Birthday/languages/nl.xml similarity index 100% rename from adm_plugins/birthday/languages/nl.xml rename to plugins/Birthday/languages/nl.xml diff --git a/adm_plugins/birthday/languages/pl.xml b/plugins/Birthday/languages/pl.xml similarity index 100% rename from adm_plugins/birthday/languages/pl.xml rename to plugins/Birthday/languages/pl.xml diff --git a/adm_plugins/birthday/languages/pt-BR.xml b/plugins/Birthday/languages/pt-BR.xml similarity index 100% rename from adm_plugins/birthday/languages/pt-BR.xml rename to plugins/Birthday/languages/pt-BR.xml diff --git a/adm_plugins/birthday/languages/pt.xml b/plugins/Birthday/languages/pt.xml similarity index 100% rename from adm_plugins/birthday/languages/pt.xml rename to plugins/Birthday/languages/pt.xml diff --git a/adm_plugins/birthday/languages/ru.xml b/plugins/Birthday/languages/ru.xml similarity index 100% rename from adm_plugins/birthday/languages/ru.xml rename to plugins/Birthday/languages/ru.xml diff --git a/adm_plugins/birthday/languages/sv.xml b/plugins/Birthday/languages/sv.xml similarity index 100% rename from adm_plugins/birthday/languages/sv.xml rename to plugins/Birthday/languages/sv.xml diff --git a/adm_plugins/birthday/languages/uk.xml b/plugins/Birthday/languages/uk.xml similarity index 100% rename from adm_plugins/birthday/languages/uk.xml rename to plugins/Birthday/languages/uk.xml diff --git a/adm_plugins/birthday/languages/zh.xml b/plugins/Birthday/languages/zh.xml similarity index 100% rename from adm_plugins/birthday/languages/zh.xml rename to plugins/Birthday/languages/zh.xml diff --git a/adm_plugins/birthday/templates/plugin.birthday.tpl b/plugins/Birthday/templates/plugin.birthday.tpl similarity index 100% rename from adm_plugins/birthday/templates/plugin.birthday.tpl rename to plugins/Birthday/templates/plugin.birthday.tpl diff --git a/adm_plugins/birthday/templates/preferences.plugin.birthday.tpl b/plugins/Birthday/templates/preferences.plugin.birthday.tpl similarity index 100% rename from adm_plugins/birthday/templates/preferences.plugin.birthday.tpl rename to plugins/Birthday/templates/preferences.plugin.birthday.tpl diff --git a/adm_plugins/calendar/Calendar.json b/plugins/Calendar/Calendar.json similarity index 100% rename from adm_plugins/calendar/Calendar.json rename to plugins/Calendar/Calendar.json diff --git a/adm_plugins/calendar/classes/Calendar.php b/plugins/Calendar/classes/Calendar.php similarity index 100% rename from adm_plugins/calendar/classes/Calendar.php rename to plugins/Calendar/classes/Calendar.php diff --git a/adm_plugins/calendar/classes/Presenter/CalendarPreferencesPresenter.php b/plugins/Calendar/classes/Presenter/CalendarPreferencesPresenter.php similarity index 100% rename from adm_plugins/calendar/classes/Presenter/CalendarPreferencesPresenter.php rename to plugins/Calendar/classes/Presenter/CalendarPreferencesPresenter.php diff --git a/adm_plugins/calendar/db_scripts/update_1_0.xml b/plugins/Calendar/db_scripts/update_1_0.xml similarity index 100% rename from adm_plugins/calendar/db_scripts/update_1_0.xml rename to plugins/Calendar/db_scripts/update_1_0.xml diff --git a/adm_plugins/calendar/index.php b/plugins/Calendar/index.php similarity index 100% rename from adm_plugins/calendar/index.php rename to plugins/Calendar/index.php diff --git a/adm_plugins/calendar/languages/bg.xml b/plugins/Calendar/languages/bg.xml similarity index 100% rename from adm_plugins/calendar/languages/bg.xml rename to plugins/Calendar/languages/bg.xml diff --git a/adm_plugins/calendar/languages/da.xml b/plugins/Calendar/languages/da.xml similarity index 100% rename from adm_plugins/calendar/languages/da.xml rename to plugins/Calendar/languages/da.xml diff --git a/adm_plugins/calendar/languages/de-DE.xml b/plugins/Calendar/languages/de-DE.xml similarity index 100% rename from adm_plugins/calendar/languages/de-DE.xml rename to plugins/Calendar/languages/de-DE.xml diff --git a/adm_plugins/calendar/languages/de.xml b/plugins/Calendar/languages/de.xml similarity index 100% rename from adm_plugins/calendar/languages/de.xml rename to plugins/Calendar/languages/de.xml diff --git a/adm_plugins/calendar/languages/el.xml b/plugins/Calendar/languages/el.xml similarity index 100% rename from adm_plugins/calendar/languages/el.xml rename to plugins/Calendar/languages/el.xml diff --git a/adm_plugins/calendar/languages/en.xml b/plugins/Calendar/languages/en.xml similarity index 100% rename from adm_plugins/calendar/languages/en.xml rename to plugins/Calendar/languages/en.xml diff --git a/adm_plugins/calendar/languages/es.xml b/plugins/Calendar/languages/es.xml similarity index 100% rename from adm_plugins/calendar/languages/es.xml rename to plugins/Calendar/languages/es.xml diff --git a/adm_plugins/calendar/languages/et.xml b/plugins/Calendar/languages/et.xml similarity index 100% rename from adm_plugins/calendar/languages/et.xml rename to plugins/Calendar/languages/et.xml diff --git a/adm_plugins/calendar/languages/fi.xml b/plugins/Calendar/languages/fi.xml old mode 100755 new mode 100644 similarity index 100% rename from adm_plugins/calendar/languages/fi.xml rename to plugins/Calendar/languages/fi.xml diff --git a/adm_plugins/calendar/languages/fr.xml b/plugins/Calendar/languages/fr.xml similarity index 100% rename from adm_plugins/calendar/languages/fr.xml rename to plugins/Calendar/languages/fr.xml diff --git a/adm_plugins/calendar/languages/hu.xml b/plugins/Calendar/languages/hu.xml similarity index 100% rename from adm_plugins/calendar/languages/hu.xml rename to plugins/Calendar/languages/hu.xml diff --git a/adm_plugins/calendar/languages/nb.xml b/plugins/Calendar/languages/nb.xml similarity index 100% rename from adm_plugins/calendar/languages/nb.xml rename to plugins/Calendar/languages/nb.xml diff --git a/adm_plugins/calendar/languages/nl.xml b/plugins/Calendar/languages/nl.xml similarity index 100% rename from adm_plugins/calendar/languages/nl.xml rename to plugins/Calendar/languages/nl.xml diff --git a/adm_plugins/calendar/languages/pl.xml b/plugins/Calendar/languages/pl.xml similarity index 100% rename from adm_plugins/calendar/languages/pl.xml rename to plugins/Calendar/languages/pl.xml diff --git a/adm_plugins/calendar/languages/pt-BR.xml b/plugins/Calendar/languages/pt-BR.xml similarity index 100% rename from adm_plugins/calendar/languages/pt-BR.xml rename to plugins/Calendar/languages/pt-BR.xml diff --git a/adm_plugins/calendar/languages/pt.xml b/plugins/Calendar/languages/pt.xml similarity index 100% rename from adm_plugins/calendar/languages/pt.xml rename to plugins/Calendar/languages/pt.xml diff --git a/adm_plugins/calendar/languages/ru.xml b/plugins/Calendar/languages/ru.xml similarity index 100% rename from adm_plugins/calendar/languages/ru.xml rename to plugins/Calendar/languages/ru.xml diff --git a/adm_plugins/calendar/languages/sv.xml b/plugins/Calendar/languages/sv.xml similarity index 100% rename from adm_plugins/calendar/languages/sv.xml rename to plugins/Calendar/languages/sv.xml diff --git a/adm_plugins/calendar/languages/uk.xml b/plugins/Calendar/languages/uk.xml similarity index 100% rename from adm_plugins/calendar/languages/uk.xml rename to plugins/Calendar/languages/uk.xml diff --git a/adm_plugins/calendar/languages/zh.xml b/plugins/Calendar/languages/zh.xml similarity index 100% rename from adm_plugins/calendar/languages/zh.xml rename to plugins/Calendar/languages/zh.xml diff --git a/adm_plugins/calendar/templates/plugin.calendar.tpl b/plugins/Calendar/templates/plugin.calendar.tpl similarity index 92% rename from adm_plugins/calendar/templates/plugin.calendar.tpl rename to plugins/Calendar/templates/plugin.calendar.tpl index 45178d0020..52cefa739b 100644 --- a/adm_plugins/calendar/templates/plugin.calendar.tpl +++ b/plugins/Calendar/templates/plugin.calendar.tpl @@ -32,7 +32,7 @@ + +
+ + {include 'sys-template-parts/form.input.tpl' data=$elements['adm_csrf_token']} + {* include input elements for all $elements ending with _overview_sequence *} + {foreach $elements as $key => $element} + {if {string_contains haystack=$key needle="_overview_sequence"}} + {include 'sys-template-parts/form.input.tpl' data=$element} + {/if} + {/foreach} + + {* show the description *} + {include 'sys-template-parts/form.description.tpl' data=$elements['adm_overview_description']} + + {* Display the overview plugins container *} +
+ {foreach $overviewPlugins as $overviewPlugin} +
+
+
+
+ {if isset($overviewPlugin.icon)}{/if} {$overviewPlugin.name} + {if !$overviewPlugin.enabled} + {$l10n->get('SYS_DISABLED')} + {/if} +
+
+
+
+
+ {if isset($overviewPlugin.icon)}{/if} {$overviewPlugin.name} + {if !$overviewPlugin.enabled} + {$l10n->get('SYS_DISABLED')} + {/if} +
+
+ +
+
+
+ {/foreach} +
+ + {* Include the save button *} + {include 'sys-template-parts/form.button.tpl' data=$elements['adm_button_save_overview']} + +
\ No newline at end of file From 6016a717b1804d2b1fb1cabad05889fecd9f4f0b Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 20 Aug 2025 18:57:39 +0200 Subject: [PATCH 052/109] refactor: rename plugin configuration keys for consistency and clarity and implement new overview sequence configuration key --- plugins/WhoIsOnline/WhoIsOnline.json | 20 ++++++---- .../WhoIsOnlinePreferencesPresenter.php | 38 +++++++++---------- plugins/WhoIsOnline/classes/WhoIsOnline.php | 14 +++---- plugins/WhoIsOnline/db_scripts/update_1_0.xml | 1 - 4 files changed, 39 insertions(+), 34 deletions(-) diff --git a/plugins/WhoIsOnline/WhoIsOnline.json b/plugins/WhoIsOnline/WhoIsOnline.json index 66359d15f3..657c7b2511 100644 --- a/plugins/WhoIsOnline/WhoIsOnline.json +++ b/plugins/WhoIsOnline/WhoIsOnline.json @@ -18,31 +18,37 @@ "type": "integer", "value" : 1 }, - "who_is_online_plugin_time_still_active": { - "name": "PLG_WHO_IS_ONLINE_PLUGIN_TIME_STILL_ACTIVE", - "description": "PLG_WHO_IS_ONLINE_PLUGIN_TIME_STILL_ACTIVE_DESC", + "who_is_online_overview_sequence": { + "name": "SYS_OVERVIEW_SEQUENCE", + "description": "SYS_OVERVIEW_SEQUENCE_DESC", + "type": "integer", + "value" : 8 + }, + "who_is_online_time_still_active": { + "name": "PLG_WHO_IS_ONLINE_PREFERENCES_TIME_STILL_ACTIVE", + "description": "PLG_WHO_IS_ONLINE_PREFERENCES_TIME_STILL_ACTIVE_DESC", "type": "integer", "value" : 10 }, - "who_is_online_plugin_show_visitors": { + "who_is_online_show_visitors": { "name": "PLG_WHO_IS_ONLINE_PREFERENCES_SHOW_VISITORS", "description": "PLG_WHO_IS_ONLINE_PREFERENCES_SHOW_VISITORS_DESC", "type": "boolean", "value" : true }, - "who_is_online_plugin_show_members_to_visitors": { + "who_is_online_show_members_to_visitors": { "name": "PLG_WHO_IS_ONLINE_PREFERENCES_SHOW_MEMBERS_TO_VISITORS", "description": "PLG_WHO_IS_ONLINE_PREFERENCES_SHOW_MEMBERS_TO_VISITORS_DESC", "type": "integer", "value" : 2 }, - "who_is_online_plugin_show_self": { + "who_is_online_show_self": { "name": "PLG_WHO_IS_ONLINE_PREFERENCES_SHOW_SELF", "description": "PLG_WHO_IS_ONLINE_PREFERENCES_SHOW_SELF_DESC", "type": "boolean", "value" : true }, - "who_is_online_plugin_show_users_side_by_side": { + "who_is_online_show_users_side_by_side": { "name": "PLG_WHO_IS_ONLINE_PREFERENCES_SHOW_USERS_SIDE_BY_SIDE", "description": "PLG_WHO_IS_ONLINE_PREFERENCES_SHOW_USERS_SIDE_BY_SIDE_DESC", "type": "boolean", diff --git a/plugins/WhoIsOnline/classes/Presenter/WhoIsOnlinePreferencesPresenter.php b/plugins/WhoIsOnline/classes/Presenter/WhoIsOnlinePreferencesPresenter.php index 4e11900914..14080d5e8d 100644 --- a/plugins/WhoIsOnline/classes/Presenter/WhoIsOnlinePreferencesPresenter.php +++ b/plugins/WhoIsOnline/classes/Presenter/WhoIsOnlinePreferencesPresenter.php @@ -52,16 +52,16 @@ public static function createWhoIsOnlineForm(Smarty $smarty): string array('defaultValue' => $formValues['who_is_online_plugin_enabled']['value'], 'showContextDependentFirstEntry' => false, 'helpTextId' => $formValues['who_is_online_plugin_enabled']['description']) ); $formWhoIsOnline->addInput( - 'who_is_online_plugin_time_still_active', - Language::translateIfTranslationStrId($formValues['who_is_online_plugin_time_still_active']['name']), - $formValues['who_is_online_plugin_time_still_active']['value'], - array('type' => 'number', 'minNumber' => 0, 'step' => 1, 'helpTextId' => $formValues['who_is_online_plugin_time_still_active']['description']) + 'who_is_online_time_still_active', + Language::translateIfTranslationStrId($formValues['who_is_online_time_still_active']['name']), + $formValues['who_is_online_time_still_active']['value'], + array('type' => 'number', 'minNumber' => 0, 'step' => 1, 'helpTextId' => $formValues['who_is_online_time_still_active']['description']) ); $formWhoIsOnline->addCheckbox( - 'who_is_online_plugin_show_visitors', - Language::translateIfTranslationStrId($formValues['who_is_online_plugin_show_visitors']['name']), - $formValues['who_is_online_plugin_show_visitors']['value'], - array('helpTextId' => $formValues['who_is_online_plugin_show_visitors']['description']) + 'who_is_online_show_visitors', + Language::translateIfTranslationStrId($formValues['who_is_online_show_visitors']['name']), + $formValues['who_is_online_show_visitors']['value'], + array('helpTextId' => $formValues['who_is_online_show_visitors']['description']) ); $selectBoxEntries = array( '0' => $gL10n->get('PLG_WHO_IS_ONLINE_PREFERENCES_SHOW_MEMBERS_TO_VISITORS_SELECTION_1'), @@ -69,22 +69,22 @@ public static function createWhoIsOnlineForm(Smarty $smarty): string '2' => $gL10n->get('PLG_WHO_IS_ONLINE_PREFERENCES_SHOW_MEMBERS_TO_VISITORS_SELECTION_3') ); $formWhoIsOnline->addSelectBox( - 'who_is_online_plugin_show_members_to_visitors', - Language::translateIfTranslationStrId($formValues['who_is_online_plugin_show_members_to_visitors']['name']), + 'who_is_online_show_members_to_visitors', + Language::translateIfTranslationStrId($formValues['who_is_online_show_members_to_visitors']['name']), $selectBoxEntries, - array('defaultValue' => $formValues['who_is_online_plugin_show_members_to_visitors']['value'], 'showContextDependentFirstEntry' => false, 'helpTextId' => $formValues['who_is_online_plugin_show_members_to_visitors']['description']) + array('defaultValue' => $formValues['who_is_online_show_members_to_visitors']['value'], 'showContextDependentFirstEntry' => false, 'helpTextId' => $formValues['who_is_online_show_members_to_visitors']['description']) ); $formWhoIsOnline->addCheckbox( - 'who_is_online_plugin_show_self', - Language::translateIfTranslationStrId($formValues['who_is_online_plugin_show_self']['name']), - $formValues['who_is_online_plugin_show_self']['value'], - array('helpTextId' => $formValues['who_is_online_plugin_show_self']['description']) + 'who_is_online_show_self', + Language::translateIfTranslationStrId($formValues['who_is_online_show_self']['name']), + $formValues['who_is_online_show_self']['value'], + array('helpTextId' => $formValues['who_is_online_show_self']['description']) ); $formWhoIsOnline->addCheckbox( - 'who_is_online_plugin_show_users_side_by_side', - Language::translateIfTranslationStrId($formValues['who_is_online_plugin_show_users_side_by_side']['name']), - $formValues['who_is_online_plugin_show_users_side_by_side']['value'], - array('helpTextId' => $formValues['who_is_online_plugin_show_users_side_by_side']['description']) + 'who_is_online_show_users_side_by_side', + Language::translateIfTranslationStrId($formValues['who_is_online_show_users_side_by_side']['name']), + $formValues['who_is_online_show_users_side_by_side']['value'], + array('helpTextId' => $formValues['who_is_online_show_users_side_by_side']['description']) ); $formWhoIsOnline->addSubmitButton( 'adm_button_save_who_is_online', diff --git a/plugins/WhoIsOnline/classes/WhoIsOnline.php b/plugins/WhoIsOnline/classes/WhoIsOnline.php index 2fe2c92c20..4c5facd004 100644 --- a/plugins/WhoIsOnline/classes/WhoIsOnline.php +++ b/plugins/WhoIsOnline/classes/WhoIsOnline.php @@ -38,7 +38,7 @@ private static function getWhoIsOnlineText() : string // Set reference time $now = new DateTime(); - $minutesOffset = new DateInterval('PT' . $config['who_is_online_plugin_time_still_active'] . 'M'); + $minutesOffset = new DateInterval('PT' . $config['who_is_online_time_still_active'] . 'M'); $refDate = $now->sub($minutesOffset)->format('Y-m-d H:i:s'); // Find user IDs of all sessions that are in the specified current and reference time @@ -49,11 +49,11 @@ private static function getWhoIsOnlineText() : string WHERE ses_timestamp BETWEEN ? AND ? -- $refDate AND DATETIME_NOW AND ses_org_id = ? -- $gCurrentOrgId'; $queryParams = array($refDate, DATETIME_NOW, $gCurrentOrgId); - if (!$config['who_is_online_plugin_show_visitors']) { + if (!$config['who_is_online_show_visitors']) { $sql .= ' AND ses_usr_id IS NOT NULL'; } - if (!$config['who_is_online_plugin_show_self'] && $gValidLogin) { + if (!$config['who_is_online_show_self'] && $gValidLogin) { $sql .= ' AND ses_usr_id <> ? -- $gCurrentUserId'; $queryParams[] = $gCurrentUserId; @@ -72,7 +72,7 @@ private static function getWhoIsOnlineText() : string while ($row = $onlineUsersStatement->fetch()) { if ($row['ses_usr_id'] > 0) { if (((int)$row['ses_usr_id'] !== $usrIdMerker) - && ($config['who_is_online_plugin_show_members_to_visitors'] == 1 || $gValidLogin)) { + && ($config['who_is_online_show_members_to_visitors'] == 1 || $gValidLogin)) { $allVisibleOnlineUsers[] = '' . $row['usr_login_name'] . ''; $usrIdMerker = (int)$row['ses_usr_id']; @@ -83,7 +83,7 @@ private static function getWhoIsOnlineText() : string } } - if (!$gValidLogin && $config['who_is_online_plugin_show_members_to_visitors'] == 2 && $countMembers > 0) { + if (!$gValidLogin && $config['who_is_online_show_members_to_visitors'] == 2 && $countMembers > 0) { if ($countMembers > 1) { $allVisibleOnlineUsers[] = $gL10n->get('PLG_WHO_IS_ONLINE_VAR_NUM_MEMBERS', array($countMembers)); } else { @@ -91,11 +91,11 @@ private static function getWhoIsOnlineText() : string } } - if ($config['who_is_online_plugin_show_visitors'] && $countVisitors > 0) { + if ($config['who_is_online_show_visitors'] && $countVisitors > 0) { $allVisibleOnlineUsers[] = $gL10n->get('PLG_WHO_IS_ONLINE_VAR_NUM_VISITORS', array($countVisitors)); } - if ($config['who_is_online_plugin_show_users_side_by_side']) { + if ($config['who_is_online_show_users_side_by_side']) { $textOnlineVisitors = implode(', ', $allVisibleOnlineUsers); } else { $textOnlineVisitors = '
' . implode('
', $allVisibleOnlineUsers); diff --git a/plugins/WhoIsOnline/db_scripts/update_1_0.xml b/plugins/WhoIsOnline/db_scripts/update_1_0.xml index 34ddc7b5fd..dba8467f50 100644 --- a/plugins/WhoIsOnline/db_scripts/update_1_0.xml +++ b/plugins/WhoIsOnline/db_scripts/update_1_0.xml @@ -1,6 +1,5 @@ UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'WhoIsOnline' - UPDATE %PREFIX%_components SET com_plg_sequence = 8 WHERE com_type = 'ADM_PLUGIN' AND com_name_intern = 'WhoIsOnline' stop From 2126e6f38e0464dec3498c9eca7ed92b1bda30ef Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 20 Aug 2025 18:57:39 +0200 Subject: [PATCH 053/109] refactor: rename plugin configuration keys for consistency and clarity and implement new overview sequence configuration key --- plugins/WhoIsOnline/WhoIsOnline.json | 20 ++++++---- .../WhoIsOnlinePreferencesPresenter.php | 38 +++++++++---------- plugins/WhoIsOnline/classes/WhoIsOnline.php | 14 +++---- plugins/WhoIsOnline/db_scripts/update_1_0.xml | 1 - .../preferences.plugin.who-is-online.tpl | 10 ++--- 5 files changed, 44 insertions(+), 39 deletions(-) diff --git a/plugins/WhoIsOnline/WhoIsOnline.json b/plugins/WhoIsOnline/WhoIsOnline.json index 66359d15f3..657c7b2511 100644 --- a/plugins/WhoIsOnline/WhoIsOnline.json +++ b/plugins/WhoIsOnline/WhoIsOnline.json @@ -18,31 +18,37 @@ "type": "integer", "value" : 1 }, - "who_is_online_plugin_time_still_active": { - "name": "PLG_WHO_IS_ONLINE_PLUGIN_TIME_STILL_ACTIVE", - "description": "PLG_WHO_IS_ONLINE_PLUGIN_TIME_STILL_ACTIVE_DESC", + "who_is_online_overview_sequence": { + "name": "SYS_OVERVIEW_SEQUENCE", + "description": "SYS_OVERVIEW_SEQUENCE_DESC", + "type": "integer", + "value" : 8 + }, + "who_is_online_time_still_active": { + "name": "PLG_WHO_IS_ONLINE_PREFERENCES_TIME_STILL_ACTIVE", + "description": "PLG_WHO_IS_ONLINE_PREFERENCES_TIME_STILL_ACTIVE_DESC", "type": "integer", "value" : 10 }, - "who_is_online_plugin_show_visitors": { + "who_is_online_show_visitors": { "name": "PLG_WHO_IS_ONLINE_PREFERENCES_SHOW_VISITORS", "description": "PLG_WHO_IS_ONLINE_PREFERENCES_SHOW_VISITORS_DESC", "type": "boolean", "value" : true }, - "who_is_online_plugin_show_members_to_visitors": { + "who_is_online_show_members_to_visitors": { "name": "PLG_WHO_IS_ONLINE_PREFERENCES_SHOW_MEMBERS_TO_VISITORS", "description": "PLG_WHO_IS_ONLINE_PREFERENCES_SHOW_MEMBERS_TO_VISITORS_DESC", "type": "integer", "value" : 2 }, - "who_is_online_plugin_show_self": { + "who_is_online_show_self": { "name": "PLG_WHO_IS_ONLINE_PREFERENCES_SHOW_SELF", "description": "PLG_WHO_IS_ONLINE_PREFERENCES_SHOW_SELF_DESC", "type": "boolean", "value" : true }, - "who_is_online_plugin_show_users_side_by_side": { + "who_is_online_show_users_side_by_side": { "name": "PLG_WHO_IS_ONLINE_PREFERENCES_SHOW_USERS_SIDE_BY_SIDE", "description": "PLG_WHO_IS_ONLINE_PREFERENCES_SHOW_USERS_SIDE_BY_SIDE_DESC", "type": "boolean", diff --git a/plugins/WhoIsOnline/classes/Presenter/WhoIsOnlinePreferencesPresenter.php b/plugins/WhoIsOnline/classes/Presenter/WhoIsOnlinePreferencesPresenter.php index 4e11900914..14080d5e8d 100644 --- a/plugins/WhoIsOnline/classes/Presenter/WhoIsOnlinePreferencesPresenter.php +++ b/plugins/WhoIsOnline/classes/Presenter/WhoIsOnlinePreferencesPresenter.php @@ -52,16 +52,16 @@ public static function createWhoIsOnlineForm(Smarty $smarty): string array('defaultValue' => $formValues['who_is_online_plugin_enabled']['value'], 'showContextDependentFirstEntry' => false, 'helpTextId' => $formValues['who_is_online_plugin_enabled']['description']) ); $formWhoIsOnline->addInput( - 'who_is_online_plugin_time_still_active', - Language::translateIfTranslationStrId($formValues['who_is_online_plugin_time_still_active']['name']), - $formValues['who_is_online_plugin_time_still_active']['value'], - array('type' => 'number', 'minNumber' => 0, 'step' => 1, 'helpTextId' => $formValues['who_is_online_plugin_time_still_active']['description']) + 'who_is_online_time_still_active', + Language::translateIfTranslationStrId($formValues['who_is_online_time_still_active']['name']), + $formValues['who_is_online_time_still_active']['value'], + array('type' => 'number', 'minNumber' => 0, 'step' => 1, 'helpTextId' => $formValues['who_is_online_time_still_active']['description']) ); $formWhoIsOnline->addCheckbox( - 'who_is_online_plugin_show_visitors', - Language::translateIfTranslationStrId($formValues['who_is_online_plugin_show_visitors']['name']), - $formValues['who_is_online_plugin_show_visitors']['value'], - array('helpTextId' => $formValues['who_is_online_plugin_show_visitors']['description']) + 'who_is_online_show_visitors', + Language::translateIfTranslationStrId($formValues['who_is_online_show_visitors']['name']), + $formValues['who_is_online_show_visitors']['value'], + array('helpTextId' => $formValues['who_is_online_show_visitors']['description']) ); $selectBoxEntries = array( '0' => $gL10n->get('PLG_WHO_IS_ONLINE_PREFERENCES_SHOW_MEMBERS_TO_VISITORS_SELECTION_1'), @@ -69,22 +69,22 @@ public static function createWhoIsOnlineForm(Smarty $smarty): string '2' => $gL10n->get('PLG_WHO_IS_ONLINE_PREFERENCES_SHOW_MEMBERS_TO_VISITORS_SELECTION_3') ); $formWhoIsOnline->addSelectBox( - 'who_is_online_plugin_show_members_to_visitors', - Language::translateIfTranslationStrId($formValues['who_is_online_plugin_show_members_to_visitors']['name']), + 'who_is_online_show_members_to_visitors', + Language::translateIfTranslationStrId($formValues['who_is_online_show_members_to_visitors']['name']), $selectBoxEntries, - array('defaultValue' => $formValues['who_is_online_plugin_show_members_to_visitors']['value'], 'showContextDependentFirstEntry' => false, 'helpTextId' => $formValues['who_is_online_plugin_show_members_to_visitors']['description']) + array('defaultValue' => $formValues['who_is_online_show_members_to_visitors']['value'], 'showContextDependentFirstEntry' => false, 'helpTextId' => $formValues['who_is_online_show_members_to_visitors']['description']) ); $formWhoIsOnline->addCheckbox( - 'who_is_online_plugin_show_self', - Language::translateIfTranslationStrId($formValues['who_is_online_plugin_show_self']['name']), - $formValues['who_is_online_plugin_show_self']['value'], - array('helpTextId' => $formValues['who_is_online_plugin_show_self']['description']) + 'who_is_online_show_self', + Language::translateIfTranslationStrId($formValues['who_is_online_show_self']['name']), + $formValues['who_is_online_show_self']['value'], + array('helpTextId' => $formValues['who_is_online_show_self']['description']) ); $formWhoIsOnline->addCheckbox( - 'who_is_online_plugin_show_users_side_by_side', - Language::translateIfTranslationStrId($formValues['who_is_online_plugin_show_users_side_by_side']['name']), - $formValues['who_is_online_plugin_show_users_side_by_side']['value'], - array('helpTextId' => $formValues['who_is_online_plugin_show_users_side_by_side']['description']) + 'who_is_online_show_users_side_by_side', + Language::translateIfTranslationStrId($formValues['who_is_online_show_users_side_by_side']['name']), + $formValues['who_is_online_show_users_side_by_side']['value'], + array('helpTextId' => $formValues['who_is_online_show_users_side_by_side']['description']) ); $formWhoIsOnline->addSubmitButton( 'adm_button_save_who_is_online', diff --git a/plugins/WhoIsOnline/classes/WhoIsOnline.php b/plugins/WhoIsOnline/classes/WhoIsOnline.php index 2fe2c92c20..4c5facd004 100644 --- a/plugins/WhoIsOnline/classes/WhoIsOnline.php +++ b/plugins/WhoIsOnline/classes/WhoIsOnline.php @@ -38,7 +38,7 @@ private static function getWhoIsOnlineText() : string // Set reference time $now = new DateTime(); - $minutesOffset = new DateInterval('PT' . $config['who_is_online_plugin_time_still_active'] . 'M'); + $minutesOffset = new DateInterval('PT' . $config['who_is_online_time_still_active'] . 'M'); $refDate = $now->sub($minutesOffset)->format('Y-m-d H:i:s'); // Find user IDs of all sessions that are in the specified current and reference time @@ -49,11 +49,11 @@ private static function getWhoIsOnlineText() : string WHERE ses_timestamp BETWEEN ? AND ? -- $refDate AND DATETIME_NOW AND ses_org_id = ? -- $gCurrentOrgId'; $queryParams = array($refDate, DATETIME_NOW, $gCurrentOrgId); - if (!$config['who_is_online_plugin_show_visitors']) { + if (!$config['who_is_online_show_visitors']) { $sql .= ' AND ses_usr_id IS NOT NULL'; } - if (!$config['who_is_online_plugin_show_self'] && $gValidLogin) { + if (!$config['who_is_online_show_self'] && $gValidLogin) { $sql .= ' AND ses_usr_id <> ? -- $gCurrentUserId'; $queryParams[] = $gCurrentUserId; @@ -72,7 +72,7 @@ private static function getWhoIsOnlineText() : string while ($row = $onlineUsersStatement->fetch()) { if ($row['ses_usr_id'] > 0) { if (((int)$row['ses_usr_id'] !== $usrIdMerker) - && ($config['who_is_online_plugin_show_members_to_visitors'] == 1 || $gValidLogin)) { + && ($config['who_is_online_show_members_to_visitors'] == 1 || $gValidLogin)) { $allVisibleOnlineUsers[] = '' . $row['usr_login_name'] . ''; $usrIdMerker = (int)$row['ses_usr_id']; @@ -83,7 +83,7 @@ private static function getWhoIsOnlineText() : string } } - if (!$gValidLogin && $config['who_is_online_plugin_show_members_to_visitors'] == 2 && $countMembers > 0) { + if (!$gValidLogin && $config['who_is_online_show_members_to_visitors'] == 2 && $countMembers > 0) { if ($countMembers > 1) { $allVisibleOnlineUsers[] = $gL10n->get('PLG_WHO_IS_ONLINE_VAR_NUM_MEMBERS', array($countMembers)); } else { @@ -91,11 +91,11 @@ private static function getWhoIsOnlineText() : string } } - if ($config['who_is_online_plugin_show_visitors'] && $countVisitors > 0) { + if ($config['who_is_online_show_visitors'] && $countVisitors > 0) { $allVisibleOnlineUsers[] = $gL10n->get('PLG_WHO_IS_ONLINE_VAR_NUM_VISITORS', array($countVisitors)); } - if ($config['who_is_online_plugin_show_users_side_by_side']) { + if ($config['who_is_online_show_users_side_by_side']) { $textOnlineVisitors = implode(', ', $allVisibleOnlineUsers); } else { $textOnlineVisitors = '
' . implode('
', $allVisibleOnlineUsers); diff --git a/plugins/WhoIsOnline/db_scripts/update_1_0.xml b/plugins/WhoIsOnline/db_scripts/update_1_0.xml index 34ddc7b5fd..dba8467f50 100644 --- a/plugins/WhoIsOnline/db_scripts/update_1_0.xml +++ b/plugins/WhoIsOnline/db_scripts/update_1_0.xml @@ -1,6 +1,5 @@ UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'WhoIsOnline' - UPDATE %PREFIX%_components SET com_plg_sequence = 8 WHERE com_type = 'ADM_PLUGIN' AND com_name_intern = 'WhoIsOnline' stop diff --git a/plugins/WhoIsOnline/templates/preferences.plugin.who-is-online.tpl b/plugins/WhoIsOnline/templates/preferences.plugin.who-is-online.tpl index cd18b7ac83..f14e70a5f6 100644 --- a/plugins/WhoIsOnline/templates/preferences.plugin.who-is-online.tpl +++ b/plugins/WhoIsOnline/templates/preferences.plugin.who-is-online.tpl @@ -4,11 +4,11 @@ {include 'sys-template-parts/form.input.tpl' data=$elements['adm_csrf_token']} {include 'sys-template-parts/form.select.tpl' data=$elements['who_is_online_plugin_enabled']} - {include 'sys-template-parts/form.input.tpl' data=$elements['who_is_online_plugin_time_still_active']} - {include 'sys-template-parts/form.checkbox.tpl' data=$elements['who_is_online_plugin_show_visitors']} - {include 'sys-template-parts/form.select.tpl' data=$elements['who_is_online_plugin_show_members_to_visitors']} - {include 'sys-template-parts/form.checkbox.tpl' data=$elements['who_is_online_plugin_show_self']} - {include 'sys-template-parts/form.checkbox.tpl' data=$elements['who_is_online_plugin_show_users_side_by_side']} + {include 'sys-template-parts/form.input.tpl' data=$elements['who_is_online_time_still_active']} + {include 'sys-template-parts/form.checkbox.tpl' data=$elements['who_is_online_show_visitors']} + {include 'sys-template-parts/form.select.tpl' data=$elements['who_is_online_show_members_to_visitors']} + {include 'sys-template-parts/form.checkbox.tpl' data=$elements['who_is_online_show_self']} + {include 'sys-template-parts/form.checkbox.tpl' data=$elements['who_is_online_show_users_side_by_side']} {include 'sys-template-parts/form.button.tpl' data=$elements['adm_button_save_who_is_online']} From b52f0071472e60a4e18c17d5385dc8e59d9b7508 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 20 Aug 2025 19:00:17 +0200 Subject: [PATCH 054/109] refactor: update random photo plugin configuration keys for consistency and implement new overview sequence configuration key --- plugins/RandomPhoto/RandomPhoto.json | 18 ++++--- .../RandomPhotoPreferencesPresenter.php | 48 +++++++++---------- plugins/RandomPhoto/classes/RandomPhoto.php | 22 ++++----- plugins/RandomPhoto/db_scripts/update_1_0.xml | 1 - .../preferences.plugin.random-photo.tpl | 12 ++--- 5 files changed, 53 insertions(+), 48 deletions(-) diff --git a/plugins/RandomPhoto/RandomPhoto.json b/plugins/RandomPhoto/RandomPhoto.json index 819d4fcafc..eceffda84a 100644 --- a/plugins/RandomPhoto/RandomPhoto.json +++ b/plugins/RandomPhoto/RandomPhoto.json @@ -18,37 +18,43 @@ "type": "integer", "value" : 1 }, - "random_photo_plugin_max_char_per_word": { + "random_photo_overview_sequence": { + "name": "SYS_OVERVIEW_SEQUENCE", + "description": "SYS_OVERVIEW_SEQUENCE_DESC", + "type": "integer", + "value" : 4 + }, + "random_photo_max_char_per_word": { "name": "PLG_RANDOM_PHOTO_PREFERENCES_MAX_CHAR_PER_WORD", "description": "PLG_RANDOM_PHOTO_PREFERENCES_MAX_CHAR_PER_WORD_DESC", "type": "integer", "value" : 0 }, - "random_photo_plugin_max_width": { + "random_photo_max_width": { "name": "PLG_RANDOM_PHOTO_PREFERENCES_MAX_WIDTH", "description": "PLG_RANDOM_PHOTO_PREFERENCES_MAX_WIDTH_DESC", "type": "integer", "value" : 0 }, - "random_photo_plugin_max_height": { + "random_photo_max_height": { "name": "PLG_RANDOM_PHOTO_PREFERENCES_MAX_HEIGHT", "description": "PLG_RANDOM_PHOTO_PREFERENCES_MAX_HEIGHT_DESC", "type": "integer", "value" : 0 }, - "random_photo_plugin_albums": { + "random_photo_albums": { "name": "PLG_RANDOM_PHOTO_PREFERENCES_ALBUMS", "description": "PLG_RANDOM_PHOTO_PREFERENCES_ALBUMS_DESC", "type": "integer", "value" : 0 }, - "random_photo_plugin_album_photo_number": { + "random_photo_album_photo_number": { "name": "PLG_RANDOM_PHOTO_PREFERENCES_ALBUM_PHOTO_NUMBER", "description": "PLG_RANDOM_PHOTO_PREFERENCES_ALBUM_PHOTO_NUMBER_DESC", "type": "integer", "value" : 0 }, - "random_photo_plugin_show_album_link": { + "random_photo_show_album_link": { "name": "PLG_RANDOM_PHOTO_PREFERENCES_SHOW_ALBUM_LINK", "description": "PLG_RANDOM_PHOTO_PREFERENCES_SHOW_ALBUM_LINK_DESC", "type": "boolean", diff --git a/plugins/RandomPhoto/classes/Presenter/RandomPhotoPreferencesPresenter.php b/plugins/RandomPhoto/classes/Presenter/RandomPhotoPreferencesPresenter.php index d04d7cc084..e7190da8af 100644 --- a/plugins/RandomPhoto/classes/Presenter/RandomPhotoPreferencesPresenter.php +++ b/plugins/RandomPhoto/classes/Presenter/RandomPhotoPreferencesPresenter.php @@ -52,40 +52,40 @@ public static function createRandomPhotoForm(Smarty $smarty): string array('defaultValue' => $formValues['random_photo_plugin_enabled']['value'], 'showContextDependentFirstEntry' => false, 'helpTextId' => $formValues['random_photo_plugin_enabled']['description']) ); $formRandomPhoto->addInput( - 'random_photo_plugin_max_char_per_word', - Language::translateIfTranslationStrId($formValues['random_photo_plugin_max_char_per_word']['name']), - $formValues['random_photo_plugin_max_char_per_word']['value'], - array('type' => 'number', 'minNumber' => 0, 'step' => 1, 'helpTextId' => $formValues['random_photo_plugin_max_char_per_word']['description']) + 'random_photo_max_char_per_word', + Language::translateIfTranslationStrId($formValues['random_photo_max_char_per_word']['name']), + $formValues['random_photo_max_char_per_word']['value'], + array('type' => 'number', 'minNumber' => 0, 'step' => 1, 'helpTextId' => $formValues['random_photo_max_char_per_word']['description']) ); $formRandomPhoto->addInput( - 'random_photo_plugin_max_width', - Language::translateIfTranslationStrId($formValues['random_photo_plugin_max_width']['name']), - $formValues['random_photo_plugin_max_width']['value'], - array('type' => 'number', 'minNumber' => 0, 'step' => 1, 'helpTextId' => $formValues['random_photo_plugin_max_width']['description']) + 'random_photo_max_width', + Language::translateIfTranslationStrId($formValues['random_photo_max_width']['name']), + $formValues['random_photo_max_width']['value'], + array('type' => 'number', 'minNumber' => 0, 'step' => 1, 'helpTextId' => $formValues['random_photo_max_width']['description']) ); $formRandomPhoto->addInput( - 'random_photo_plugin_max_height', - Language::translateIfTranslationStrId($formValues['random_photo_plugin_max_height']['name']), - $formValues['random_photo_plugin_max_height']['value'], - array('type' => 'number', 'minNumber' => 0, 'step' => 1, 'helpTextId' => $formValues['random_photo_plugin_max_height']['description']) + 'random_photo_max_height', + Language::translateIfTranslationStrId($formValues['random_photo_max_height']['name']), + $formValues['random_photo_max_height']['value'], + array('type' => 'number', 'minNumber' => 0, 'step' => 1, 'helpTextId' => $formValues['random_photo_max_height']['description']) ); $formRandomPhoto->addInput( - 'random_photo_plugin_albums', - Language::translateIfTranslationStrId($formValues['random_photo_plugin_albums']['name']), - $formValues['random_photo_plugin_albums']['value'], - array('type' => 'number', 'minNumber' => 0, 'step' => 1, 'helpTextId' => $formValues['random_photo_plugin_albums']['description']) + 'random_photo_albums', + Language::translateIfTranslationStrId($formValues['random_photo_albums']['name']), + $formValues['random_photo_albums']['value'], + array('type' => 'number', 'minNumber' => 0, 'step' => 1, 'helpTextId' => $formValues['random_photo_albums']['description']) ); $formRandomPhoto->addInput( - 'random_photo_plugin_album_photo_number', - Language::translateIfTranslationStrId($formValues['random_photo_plugin_album_photo_number']['name']), - $formValues['random_photo_plugin_album_photo_number']['value'], - array('type' => 'number', 'minNumber' => 0, 'step' => 1, 'helpTextId' => $formValues['random_photo_plugin_album_photo_number']['description']) + 'random_photo_album_photo_number', + Language::translateIfTranslationStrId($formValues['random_photo_album_photo_number']['name']), + $formValues['random_photo_album_photo_number']['value'], + array('type' => 'number', 'minNumber' => 0, 'step' => 1, 'helpTextId' => $formValues['random_photo_album_photo_number']['description']) ); $formRandomPhoto->addCheckbox( - 'random_photo_plugin_show_album_link', - Language::translateIfTranslationStrId($formValues['random_photo_plugin_show_album_link']['name']), - $formValues['random_photo_plugin_show_album_link']['value'], - array('helpTextId' => $formValues['random_photo_plugin_show_album_link']['description']) + 'random_photo_show_album_link', + Language::translateIfTranslationStrId($formValues['random_photo_show_album_link']['name']), + $formValues['random_photo_show_album_link']['value'], + array('helpTextId' => $formValues['random_photo_show_album_link']['description']) ); $formRandomPhoto->addSubmitButton( 'adm_button_save_random_photo', diff --git a/plugins/RandomPhoto/classes/RandomPhoto.php b/plugins/RandomPhoto/classes/RandomPhoto.php index 52afe9768b..08b2d6a20f 100644 --- a/plugins/RandomPhoto/classes/RandomPhoto.php +++ b/plugins/RandomPhoto/classes/RandomPhoto.php @@ -45,8 +45,8 @@ private static function getPhotoData() : array ORDER BY pho_begin DESC'; // optional set a limit which albums should be scanned - if (self::$pluginConfig['random_photo_plugin_albums'] > 0) { - $sql .= ' LIMIT ' . self::$pluginConfig['random_photo_plugin_albums']; + if (self::$pluginConfig['random_photo_albums'] > 0) { + $sql .= ' LIMIT ' . self::$pluginConfig['random_photo_albums']; } $albumStatement = $gDb->queryPrepared($sql, array($gCurrentOrgId)); @@ -63,10 +63,10 @@ private static function getPhotoData() : array $album->setArray($albumList[mt_rand(0, $albumStatement->rowCount() - 1)]); // optionally select an image randomly - if (self::$pluginConfig['random_photo_plugin_album_photo_number'] === 0) { + if (self::$pluginConfig['random_photo_album_photo_number'] === 0) { $photoNr = mt_rand(1, (int)$album->getValue('pho_quantity')); } else { - $photoNr = self::$pluginConfig['random_photo_plugin_album_photo_number']; + $photoNr = self::$pluginConfig['random_photo_album_photo_number']; } // Compose image path @@ -74,14 +74,14 @@ private static function getPhotoData() : array ++$i; } - if (self::$pluginConfig['random_photo_plugin_show_album_link'] && self::$pluginConfig['random_photo_plugin_max_char_per_word'] > 0) { + if (self::$pluginConfig['random_photo_show_album_link'] && self::$pluginConfig['random_photo_max_char_per_word'] > 0) { // Wrap link text if necessary $words = explode(' ', $album->getValue('pho_name')); foreach ($words as $word) { - if (strlen($word) > self::$pluginConfig['random_photo_plugin_max_char_per_word']) { - $linkText .= substr($word, 0, self::$pluginConfig['random_photo_plugin_max_char_per_word']) . '-
' . - substr($word, self::$pluginConfig['random_photo_plugin_max_char_per_word']) . ' '; + if (strlen($word) > self::$pluginConfig['random_photo_max_char_per_word']) { + $linkText .= substr($word, 0, self::$pluginConfig['random_photo_max_char_per_word']) . '-
' . + substr($word, self::$pluginConfig['random_photo_max_char_per_word']) . ' '; } else { $linkText .= $word . ' '; } @@ -126,9 +126,9 @@ public static function doRender($page = null) : bool $randomPhotoPlugin->assignTemplateVariable('photoUUID', $photoData['uuid']); $randomPhotoPlugin->assignTemplateVariable('photoNr', $photoData['photoNr']); $randomPhotoPlugin->assignTemplateVariable('photoTitle', $photoData['linkText']); - $randomPhotoPlugin->assignTemplateVariable('photoMaxWidth', self::$pluginConfig['random_photo_plugin_max_width']); - $randomPhotoPlugin->assignTemplateVariable('photoMaxHeight', self::$pluginConfig['random_photo_plugin_max_height']); - $randomPhotoPlugin->assignTemplateVariable('photoShowLink', self::$pluginConfig['random_photo_plugin_show_album_link']); + $randomPhotoPlugin->assignTemplateVariable('photoMaxWidth', self::$pluginConfig['random_photo_max_width']); + $randomPhotoPlugin->assignTemplateVariable('photoMaxHeight', self::$pluginConfig['random_photo_max_height']); + $randomPhotoPlugin->assignTemplateVariable('photoShowLink', self::$pluginConfig['random_photo_show_album_link']); } else { $randomPhotoPlugin->assignTemplateVariable('message',$gL10n->get('PLG_RANDOM_PHOTO_NO_ENTRIES_VISITORS')); } diff --git a/plugins/RandomPhoto/db_scripts/update_1_0.xml b/plugins/RandomPhoto/db_scripts/update_1_0.xml index 5fdda08474..e3e4fed3e5 100644 --- a/plugins/RandomPhoto/db_scripts/update_1_0.xml +++ b/plugins/RandomPhoto/db_scripts/update_1_0.xml @@ -1,6 +1,5 @@ UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'RandomPhoto' - UPDATE %PREFIX%_components SET com_plg_sequence = 4 WHERE com_type = 'ADM_PLUGIN' AND com_name_intern = 'RandomPhoto' stop diff --git a/plugins/RandomPhoto/templates/preferences.plugin.random-photo.tpl b/plugins/RandomPhoto/templates/preferences.plugin.random-photo.tpl index 6f96571bdb..b2ef185107 100644 --- a/plugins/RandomPhoto/templates/preferences.plugin.random-photo.tpl +++ b/plugins/RandomPhoto/templates/preferences.plugin.random-photo.tpl @@ -4,12 +4,12 @@ {include 'sys-template-parts/form.input.tpl' data=$elements['adm_csrf_token']} {include 'sys-template-parts/form.select.tpl' data=$elements['random_photo_plugin_enabled']} - {include 'sys-template-parts/form.input.tpl' data=$elements['random_photo_plugin_max_char_per_word']} - {include 'sys-template-parts/form.input.tpl' data=$elements['random_photo_plugin_max_width']} - {include 'sys-template-parts/form.input.tpl' data=$elements['random_photo_plugin_max_height']} - {include 'sys-template-parts/form.input.tpl' data=$elements['random_photo_plugin_albums']} - {include 'sys-template-parts/form.input.tpl' data=$elements['random_photo_plugin_album_photo_number']} - {include 'sys-template-parts/form.checkbox.tpl' data=$elements['random_photo_plugin_show_album_link']} + {include 'sys-template-parts/form.input.tpl' data=$elements['random_photo_max_char_per_word']} + {include 'sys-template-parts/form.input.tpl' data=$elements['random_photo_max_width']} + {include 'sys-template-parts/form.input.tpl' data=$elements['random_photo_max_height']} + {include 'sys-template-parts/form.input.tpl' data=$elements['random_photo_albums']} + {include 'sys-template-parts/form.input.tpl' data=$elements['random_photo_album_photo_number']} + {include 'sys-template-parts/form.checkbox.tpl' data=$elements['random_photo_show_album_link']} {include 'sys-template-parts/form.button.tpl' data=$elements['adm_button_save_random_photo']} From f1fb500b61702fd45e19ca3ef6d942e3342dceb9 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 20 Aug 2025 19:00:51 +0200 Subject: [PATCH 055/109] refactor: rename login form plugin configuration keys for consistency and implement new overview sequence key --- plugins/LoginForm/LoginForm.json | 16 +++++--- plugins/LoginForm/classes/LoginForm.php | 14 +++---- .../LoginFormPreferencesPresenter.php | 40 +++++++++---------- plugins/LoginForm/db_scripts/update_1_0.xml | 1 - 4 files changed, 38 insertions(+), 33 deletions(-) diff --git a/plugins/LoginForm/LoginForm.json b/plugins/LoginForm/LoginForm.json index ffa2ca3c9b..3095668548 100644 --- a/plugins/LoginForm/LoginForm.json +++ b/plugins/LoginForm/LoginForm.json @@ -21,31 +21,37 @@ "type": "integer", "value" : 1 }, - "login_form_plugin_show_register_link": { + "login_form_overview_sequence": { + "name": "SYS_OVERVIEW_SEQUENCE", + "description": "SYS_OVERVIEW_SEQUENCE_DESC", + "type": "integer", + "value" : 1 + }, + "login_form_show_register_link": { "name": "PLG_LOGIN_FORM_PREFERENCES_SHOW_REGISTER_LINK", "description": "PLG_LOGIN_FORM_PREFERENCES_SHOW_REGISTER_LINK_DESC", "type": "boolean", "value" : false }, - "login_form_plugin_show_email_link": { + "login_form_show_email_link": { "name": "PLG_LOGIN_FORM_PREFERENCES_SHOW_EMAIL_LINK", "description": "PLG_LOGIN_FORM_PREFERENCES_SHOW_EMAIL_LINK_DESC", "type": "boolean", "value" : true }, - "login_form_plugin_show_logout_link": { + "login_form_show_logout_link": { "name": "PLG_LOGIN_FORM_PREFERENCES_SHOW_LOGOUT_LINK", "description": "PLG_LOGIN_FORM_PREFERENCES_SHOW_LOGOUT_LINK_DESC", "type": "boolean", "value" : false }, - "login_form_plugin_enable_ranks": { + "login_form_enable_ranks": { "name": "PLG_LOGIN_FORM_PREFERENCES_ENABLE_RANKS", "description": "PLG_LOGIN_FORM_PREFERENCES_ENABLE_RANKS_DESC", "type": "boolean", "value" : true }, - "login_form_plugin_ranks": { + "login_form_ranks": { "name": "PLG_LOGIN_FORM_PREFERENCES_RANKS", "description": "PLG_LOGIN_FORM_PREFERENCES_RANKS_DESC", "type": "array", diff --git a/plugins/LoginForm/classes/LoginForm.php b/plugins/LoginForm/classes/LoginForm.php index c1f6842a59..79e7112e75 100644 --- a/plugins/LoginForm/classes/LoginForm.php +++ b/plugins/LoginForm/classes/LoginForm.php @@ -38,16 +38,16 @@ private static function getLoginData() : array // show the rank of the user if this is configured in the config.php $loginData['htmlUserRank'] = ''; - if (self::$pluginConfig['login_form_plugin_enable_ranks']) { + if (self::$pluginConfig['login_form_enable_ranks']) { $currentUserRankTitle = ''; - $rankTitle = reset(self::$pluginConfig['login_form_plugin_ranks']); + $rankTitle = reset(self::$pluginConfig['login_form_ranks']); while ($rankTitle !== false) { - $rankAssessment = key(self::$pluginConfig['login_form_plugin_ranks']); + $rankAssessment = key(self::$pluginConfig['login_form_ranks']); if ($rankAssessment < $gCurrentUser->getValue('usr_number_login')) { $currentUserRankTitle = $rankTitle; } - $rankTitle = next(self::$pluginConfig['login_form_plugin_ranks']); + $rankTitle = next(self::$pluginConfig['login_form_ranks']); } if ($currentUserRankTitle !== '') { @@ -78,7 +78,7 @@ private static function createLoginForm() : FormPresenter $getOrganizationShortName = $gCurrentOrganization->getValue('org_shortname'); } - if (self::$pluginConfig['login_form_plugin_show_email_link']) { + if (self::$pluginConfig['login_form_show_email_link']) { // read id of administrator role $sql = 'SELECT MIN(rol_id) as rol_id FROM ' . TBL_ROLES . ' @@ -195,7 +195,7 @@ public static function doRender($page = null) : bool $loginFormPlugin->assignTemplateVariable('loginActiveSince', $gCurrentSession->getValue('ses_begin', $gSettingsManager->getString('system_time'))); $loginFormPlugin->assignTemplateVariable('lastLogin', $loginData['lastLogin']); $loginFormPlugin->assignTemplateVariable('numberOfLogins', $gCurrentUser->getValue('usr_number_login') . $loginData['htmlUserRank']); - $loginFormPlugin->assignTemplateVariable('showLogoutLink', self::$pluginConfig['login_form_plugin_show_logout_link']); + $loginFormPlugin->assignTemplateVariable('showLogoutLink', self::$pluginConfig['login_form_show_logout_link']); if (isset($page)) { echo $loginFormPlugin->html('plugin.login-form.view.tpl'); @@ -206,7 +206,7 @@ public static function doRender($page = null) : bool $form = self::createLoginForm(); $smarty = $loginFormPlugin->createSmartyObject(); $smarty->assign('settings', $gSettingsManager); - $smarty->assign('showRegisterLink', self::$pluginConfig['login_form_plugin_show_register_link']); + $smarty->assign('showRegisterLink', self::$pluginConfig['login_form_show_register_link']); $form->addToSmarty($smarty); $gCurrentSession->addFormObject($form); echo $smarty->fetch('plugin.login-form.edit.tpl'); diff --git a/plugins/LoginForm/classes/Presenter/LoginFormPreferencesPresenter.php b/plugins/LoginForm/classes/Presenter/LoginFormPreferencesPresenter.php index f100cb3280..bc8b8b6979 100644 --- a/plugins/LoginForm/classes/Presenter/LoginFormPreferencesPresenter.php +++ b/plugins/LoginForm/classes/Presenter/LoginFormPreferencesPresenter.php @@ -52,35 +52,35 @@ public static function createLoginFormForm(Smarty $smarty): string array('defaultValue' => $formValues['login_form_plugin_enabled']['value'], 'showContextDependentFirstEntry' => false, 'helpTextId' => $formValues['login_form_plugin_enabled']['description']) ); $formLoginForm->addCheckbox( - 'login_form_plugin_show_register_link', - Language::translateIfTranslationStrId($formValues['login_form_plugin_show_register_link']['name']), - $formValues['login_form_plugin_show_register_link']['value'], - array('helpTextId' => $formValues['login_form_plugin_show_register_link']['description']) + 'login_form_show_register_link', + Language::translateIfTranslationStrId($formValues['login_form_show_register_link']['name']), + $formValues['login_form_show_register_link']['value'], + array('helpTextId' => $formValues['login_form_show_register_link']['description']) ); $formLoginForm->addCheckbox( - 'login_form_plugin_show_email_link', - Language::translateIfTranslationStrId($formValues['login_form_plugin_show_email_link']['name']), - $formValues['login_form_plugin_show_email_link']['value'], - array('helpTextId' => $formValues['login_form_plugin_show_email_link']['description']) + 'login_form_show_email_link', + Language::translateIfTranslationStrId($formValues['login_form_show_email_link']['name']), + $formValues['login_form_show_email_link']['value'], + array('helpTextId' => $formValues['login_form_show_email_link']['description']) ); $formLoginForm->addCheckbox( - 'login_form_plugin_show_logout_link', - Language::translateIfTranslationStrId($formValues['login_form_plugin_show_logout_link']['name']), - $formValues['login_form_plugin_show_logout_link']['value'], - array('helpTextId' => $formValues['login_form_plugin_show_logout_link']['description']) + 'login_form_show_logout_link', + Language::translateIfTranslationStrId($formValues['login_form_show_logout_link']['name']), + $formValues['login_form_show_logout_link']['value'], + array('helpTextId' => $formValues['login_form_show_logout_link']['description']) ); $formLoginForm->addCheckbox( - 'login_form_plugin_enable_ranks', - Language::translateIfTranslationStrId($formValues['login_form_plugin_enable_ranks']['name']), - $formValues['login_form_plugin_enable_ranks']['value'], - array('helpTextId' => $formValues['login_form_plugin_enable_ranks']['description']) + 'login_form_enable_ranks', + Language::translateIfTranslationStrId($formValues['login_form_enable_ranks']['name']), + $formValues['login_form_enable_ranks']['value'], + array('helpTextId' => $formValues['login_form_enable_ranks']['description']) ); $content = ''; // create a table with the ranks $content .= ''; $content .= ''; $content .= ''; - foreach ($formValues['login_form_plugin_ranks']['value'] as $numLogins => $rankName) { + foreach ($formValues['login_form_ranks']['value'] as $numLogins => $rankName) { $content .= ''; $content .= ''; $content .= ''; @@ -88,10 +88,10 @@ public static function createLoginFormForm(Smarty $smarty): string } $content .= '
' . $gL10n->get('PLG_LOGIN_FORM_NUMBER_OF_LOGINS') . '' . $gL10n->get('PLG_LOGIN_FORM_MEMBERRANK') . '
' . htmlspecialchars($numLogins) . '' . Language::translateIfTranslationStrId($rankName) . '
'; $formLoginForm->addCustomContent( - 'login_form_plugin_ranks', - Language::translateIfTranslationStrId($formValues['login_form_plugin_ranks']['name']), + 'login_form_ranks', + Language::translateIfTranslationStrId($formValues['login_form_ranks']['name']), $content, - array('helpTextId' => $formValues['login_form_plugin_ranks']['description']) + array('helpTextId' => $formValues['login_form_ranks']['description']) ); $formLoginForm->addSubmitButton( diff --git a/plugins/LoginForm/db_scripts/update_1_0.xml b/plugins/LoginForm/db_scripts/update_1_0.xml index dfd925e361..e6f2b56015 100644 --- a/plugins/LoginForm/db_scripts/update_1_0.xml +++ b/plugins/LoginForm/db_scripts/update_1_0.xml @@ -1,6 +1,5 @@ UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'LoginForm' - UPDATE %PREFIX%_components SET com_plg_sequence = 1 WHERE com_type = 'ADM_PLUGIN' AND com_name_intern = 'LoginForm' stop From 15509c441bb61d8c4e847dc4366c15eb5682f4f8 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 20 Aug 2025 19:00:51 +0200 Subject: [PATCH 056/109] refactor: rename login form plugin configuration keys for consistency and implement new overview sequence key --- plugins/LoginForm/LoginForm.json | 16 +++++--- plugins/LoginForm/classes/LoginForm.php | 14 +++---- .../LoginFormPreferencesPresenter.php | 40 +++++++++---------- plugins/LoginForm/db_scripts/update_1_0.xml | 1 - .../preferences.plugin.login-form.tpl | 10 ++--- 5 files changed, 43 insertions(+), 38 deletions(-) diff --git a/plugins/LoginForm/LoginForm.json b/plugins/LoginForm/LoginForm.json index ffa2ca3c9b..3095668548 100644 --- a/plugins/LoginForm/LoginForm.json +++ b/plugins/LoginForm/LoginForm.json @@ -21,31 +21,37 @@ "type": "integer", "value" : 1 }, - "login_form_plugin_show_register_link": { + "login_form_overview_sequence": { + "name": "SYS_OVERVIEW_SEQUENCE", + "description": "SYS_OVERVIEW_SEQUENCE_DESC", + "type": "integer", + "value" : 1 + }, + "login_form_show_register_link": { "name": "PLG_LOGIN_FORM_PREFERENCES_SHOW_REGISTER_LINK", "description": "PLG_LOGIN_FORM_PREFERENCES_SHOW_REGISTER_LINK_DESC", "type": "boolean", "value" : false }, - "login_form_plugin_show_email_link": { + "login_form_show_email_link": { "name": "PLG_LOGIN_FORM_PREFERENCES_SHOW_EMAIL_LINK", "description": "PLG_LOGIN_FORM_PREFERENCES_SHOW_EMAIL_LINK_DESC", "type": "boolean", "value" : true }, - "login_form_plugin_show_logout_link": { + "login_form_show_logout_link": { "name": "PLG_LOGIN_FORM_PREFERENCES_SHOW_LOGOUT_LINK", "description": "PLG_LOGIN_FORM_PREFERENCES_SHOW_LOGOUT_LINK_DESC", "type": "boolean", "value" : false }, - "login_form_plugin_enable_ranks": { + "login_form_enable_ranks": { "name": "PLG_LOGIN_FORM_PREFERENCES_ENABLE_RANKS", "description": "PLG_LOGIN_FORM_PREFERENCES_ENABLE_RANKS_DESC", "type": "boolean", "value" : true }, - "login_form_plugin_ranks": { + "login_form_ranks": { "name": "PLG_LOGIN_FORM_PREFERENCES_RANKS", "description": "PLG_LOGIN_FORM_PREFERENCES_RANKS_DESC", "type": "array", diff --git a/plugins/LoginForm/classes/LoginForm.php b/plugins/LoginForm/classes/LoginForm.php index c1f6842a59..79e7112e75 100644 --- a/plugins/LoginForm/classes/LoginForm.php +++ b/plugins/LoginForm/classes/LoginForm.php @@ -38,16 +38,16 @@ private static function getLoginData() : array // show the rank of the user if this is configured in the config.php $loginData['htmlUserRank'] = ''; - if (self::$pluginConfig['login_form_plugin_enable_ranks']) { + if (self::$pluginConfig['login_form_enable_ranks']) { $currentUserRankTitle = ''; - $rankTitle = reset(self::$pluginConfig['login_form_plugin_ranks']); + $rankTitle = reset(self::$pluginConfig['login_form_ranks']); while ($rankTitle !== false) { - $rankAssessment = key(self::$pluginConfig['login_form_plugin_ranks']); + $rankAssessment = key(self::$pluginConfig['login_form_ranks']); if ($rankAssessment < $gCurrentUser->getValue('usr_number_login')) { $currentUserRankTitle = $rankTitle; } - $rankTitle = next(self::$pluginConfig['login_form_plugin_ranks']); + $rankTitle = next(self::$pluginConfig['login_form_ranks']); } if ($currentUserRankTitle !== '') { @@ -78,7 +78,7 @@ private static function createLoginForm() : FormPresenter $getOrganizationShortName = $gCurrentOrganization->getValue('org_shortname'); } - if (self::$pluginConfig['login_form_plugin_show_email_link']) { + if (self::$pluginConfig['login_form_show_email_link']) { // read id of administrator role $sql = 'SELECT MIN(rol_id) as rol_id FROM ' . TBL_ROLES . ' @@ -195,7 +195,7 @@ public static function doRender($page = null) : bool $loginFormPlugin->assignTemplateVariable('loginActiveSince', $gCurrentSession->getValue('ses_begin', $gSettingsManager->getString('system_time'))); $loginFormPlugin->assignTemplateVariable('lastLogin', $loginData['lastLogin']); $loginFormPlugin->assignTemplateVariable('numberOfLogins', $gCurrentUser->getValue('usr_number_login') . $loginData['htmlUserRank']); - $loginFormPlugin->assignTemplateVariable('showLogoutLink', self::$pluginConfig['login_form_plugin_show_logout_link']); + $loginFormPlugin->assignTemplateVariable('showLogoutLink', self::$pluginConfig['login_form_show_logout_link']); if (isset($page)) { echo $loginFormPlugin->html('plugin.login-form.view.tpl'); @@ -206,7 +206,7 @@ public static function doRender($page = null) : bool $form = self::createLoginForm(); $smarty = $loginFormPlugin->createSmartyObject(); $smarty->assign('settings', $gSettingsManager); - $smarty->assign('showRegisterLink', self::$pluginConfig['login_form_plugin_show_register_link']); + $smarty->assign('showRegisterLink', self::$pluginConfig['login_form_show_register_link']); $form->addToSmarty($smarty); $gCurrentSession->addFormObject($form); echo $smarty->fetch('plugin.login-form.edit.tpl'); diff --git a/plugins/LoginForm/classes/Presenter/LoginFormPreferencesPresenter.php b/plugins/LoginForm/classes/Presenter/LoginFormPreferencesPresenter.php index f100cb3280..bc8b8b6979 100644 --- a/plugins/LoginForm/classes/Presenter/LoginFormPreferencesPresenter.php +++ b/plugins/LoginForm/classes/Presenter/LoginFormPreferencesPresenter.php @@ -52,35 +52,35 @@ public static function createLoginFormForm(Smarty $smarty): string array('defaultValue' => $formValues['login_form_plugin_enabled']['value'], 'showContextDependentFirstEntry' => false, 'helpTextId' => $formValues['login_form_plugin_enabled']['description']) ); $formLoginForm->addCheckbox( - 'login_form_plugin_show_register_link', - Language::translateIfTranslationStrId($formValues['login_form_plugin_show_register_link']['name']), - $formValues['login_form_plugin_show_register_link']['value'], - array('helpTextId' => $formValues['login_form_plugin_show_register_link']['description']) + 'login_form_show_register_link', + Language::translateIfTranslationStrId($formValues['login_form_show_register_link']['name']), + $formValues['login_form_show_register_link']['value'], + array('helpTextId' => $formValues['login_form_show_register_link']['description']) ); $formLoginForm->addCheckbox( - 'login_form_plugin_show_email_link', - Language::translateIfTranslationStrId($formValues['login_form_plugin_show_email_link']['name']), - $formValues['login_form_plugin_show_email_link']['value'], - array('helpTextId' => $formValues['login_form_plugin_show_email_link']['description']) + 'login_form_show_email_link', + Language::translateIfTranslationStrId($formValues['login_form_show_email_link']['name']), + $formValues['login_form_show_email_link']['value'], + array('helpTextId' => $formValues['login_form_show_email_link']['description']) ); $formLoginForm->addCheckbox( - 'login_form_plugin_show_logout_link', - Language::translateIfTranslationStrId($formValues['login_form_plugin_show_logout_link']['name']), - $formValues['login_form_plugin_show_logout_link']['value'], - array('helpTextId' => $formValues['login_form_plugin_show_logout_link']['description']) + 'login_form_show_logout_link', + Language::translateIfTranslationStrId($formValues['login_form_show_logout_link']['name']), + $formValues['login_form_show_logout_link']['value'], + array('helpTextId' => $formValues['login_form_show_logout_link']['description']) ); $formLoginForm->addCheckbox( - 'login_form_plugin_enable_ranks', - Language::translateIfTranslationStrId($formValues['login_form_plugin_enable_ranks']['name']), - $formValues['login_form_plugin_enable_ranks']['value'], - array('helpTextId' => $formValues['login_form_plugin_enable_ranks']['description']) + 'login_form_enable_ranks', + Language::translateIfTranslationStrId($formValues['login_form_enable_ranks']['name']), + $formValues['login_form_enable_ranks']['value'], + array('helpTextId' => $formValues['login_form_enable_ranks']['description']) ); $content = ''; // create a table with the ranks $content .= ''; $content .= ''; $content .= ''; - foreach ($formValues['login_form_plugin_ranks']['value'] as $numLogins => $rankName) { + foreach ($formValues['login_form_ranks']['value'] as $numLogins => $rankName) { $content .= ''; $content .= ''; $content .= ''; @@ -88,10 +88,10 @@ public static function createLoginFormForm(Smarty $smarty): string } $content .= '
' . $gL10n->get('PLG_LOGIN_FORM_NUMBER_OF_LOGINS') . '' . $gL10n->get('PLG_LOGIN_FORM_MEMBERRANK') . '
' . htmlspecialchars($numLogins) . '' . Language::translateIfTranslationStrId($rankName) . '
'; $formLoginForm->addCustomContent( - 'login_form_plugin_ranks', - Language::translateIfTranslationStrId($formValues['login_form_plugin_ranks']['name']), + 'login_form_ranks', + Language::translateIfTranslationStrId($formValues['login_form_ranks']['name']), $content, - array('helpTextId' => $formValues['login_form_plugin_ranks']['description']) + array('helpTextId' => $formValues['login_form_ranks']['description']) ); $formLoginForm->addSubmitButton( diff --git a/plugins/LoginForm/db_scripts/update_1_0.xml b/plugins/LoginForm/db_scripts/update_1_0.xml index dfd925e361..e6f2b56015 100644 --- a/plugins/LoginForm/db_scripts/update_1_0.xml +++ b/plugins/LoginForm/db_scripts/update_1_0.xml @@ -1,6 +1,5 @@ UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'LoginForm' - UPDATE %PREFIX%_components SET com_plg_sequence = 1 WHERE com_type = 'ADM_PLUGIN' AND com_name_intern = 'LoginForm' stop diff --git a/plugins/LoginForm/templates/preferences.plugin.login-form.tpl b/plugins/LoginForm/templates/preferences.plugin.login-form.tpl index 6876560259..8eeac2a4f6 100644 --- a/plugins/LoginForm/templates/preferences.plugin.login-form.tpl +++ b/plugins/LoginForm/templates/preferences.plugin.login-form.tpl @@ -4,11 +4,11 @@ {include 'sys-template-parts/form.input.tpl' data=$elements['adm_csrf_token']} {include 'sys-template-parts/form.select.tpl' data=$elements['login_form_plugin_enabled']} - {include 'sys-template-parts/form.checkbox.tpl' data=$elements['login_form_plugin_show_register_link']} - {include 'sys-template-parts/form.checkbox.tpl' data=$elements['login_form_plugin_show_email_link']} - {include 'sys-template-parts/form.checkbox.tpl' data=$elements['login_form_plugin_show_logout_link']} - {include 'sys-template-parts/form.checkbox.tpl' data=$elements['login_form_plugin_enable_ranks']} - {include 'sys-template-parts/form.custom-content.tpl' data=$elements['login_form_plugin_ranks']} + {include 'sys-template-parts/form.checkbox.tpl' data=$elements['login_form_show_register_link']} + {include 'sys-template-parts/form.checkbox.tpl' data=$elements['login_form_show_email_link']} + {include 'sys-template-parts/form.checkbox.tpl' data=$elements['login_form_show_logout_link']} + {include 'sys-template-parts/form.checkbox.tpl' data=$elements['login_form_enable_ranks']} + {include 'sys-template-parts/form.custom-content.tpl' data=$elements['login_form_ranks']} {include 'sys-template-parts/form.button.tpl' data=$elements['adm_button_save_login_form']} From 81f63caedfecfdb59dad9d2e886eb601f6795948 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 20 Aug 2025 19:05:06 +0200 Subject: [PATCH 057/109] refactor: implement new overview sequence configuration key and remove redundant update step --- plugins/LatestDocumentsFiles/LatestDocumentsFiles.json | 6 ++++++ plugins/LatestDocumentsFiles/db_scripts/update_1_0.xml | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/plugins/LatestDocumentsFiles/LatestDocumentsFiles.json b/plugins/LatestDocumentsFiles/LatestDocumentsFiles.json index bab8c54245..0b3117ad09 100644 --- a/plugins/LatestDocumentsFiles/LatestDocumentsFiles.json +++ b/plugins/LatestDocumentsFiles/LatestDocumentsFiles.json @@ -20,6 +20,12 @@ "type": "integer", "value" : 1 }, + "latest_documents_overview_sequence": { + "name": "SYS_OVERVIEW_SEQUENCE", + "description": "SYS_OVERVIEW_SEQUENCE_DESC", + "type": "integer", + "value" : 5 + }, "latest_documents_files_files_count": { "name": "PLG_LATEST_DOCUMENTS_FILES_PREFERENCES_FILES_COUNT", "description": "PLG_LATEST_DOCUMENTS_FILES_PREFERENCES_FILES_COUNT_DESC", diff --git a/plugins/LatestDocumentsFiles/db_scripts/update_1_0.xml b/plugins/LatestDocumentsFiles/db_scripts/update_1_0.xml index 20b0e676ee..ead909f55d 100644 --- a/plugins/LatestDocumentsFiles/db_scripts/update_1_0.xml +++ b/plugins/LatestDocumentsFiles/db_scripts/update_1_0.xml @@ -1,6 +1,5 @@ UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'LatestDocumentsFiles' - UPDATE %PREFIX%_components SET com_plg_sequence = 5 WHERE com_type = 'ADM_PLUGIN' AND com_name_intern = 'LatestDocumentsFiles' stop From 72b00445461e4d8753960c4479c7bd63eb9368c3 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 20 Aug 2025 19:05:30 +0200 Subject: [PATCH 058/109] refactor: implement new overview sequence configuration key and remove redundant update step --- plugins/EventList/EventList.json | 6 ++++++ plugins/EventList/db_scripts/update_1_0.xml | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/plugins/EventList/EventList.json b/plugins/EventList/EventList.json index ad1e2ef329..f5e8164e86 100644 --- a/plugins/EventList/EventList.json +++ b/plugins/EventList/EventList.json @@ -20,6 +20,12 @@ "type": "integer", "value" : 1 }, + "event_list_overview_sequence": { + "name": "SYS_OVERVIEW_SEQUENCE", + "description": "SYS_OVERVIEW_SEQUENCE_DESC", + "type": "integer", + "value" : 7 + }, "event_list_events_count": { "name": "PLG_EVENT_LIST_PREFERENCES_EVENTS_COUNT", "description": "PLG_EVENT_LIST_PREFERENCES_EVENTS_COUNT_DESC", diff --git a/plugins/EventList/db_scripts/update_1_0.xml b/plugins/EventList/db_scripts/update_1_0.xml index 2b3aa609bc..dd125cc3ca 100644 --- a/plugins/EventList/db_scripts/update_1_0.xml +++ b/plugins/EventList/db_scripts/update_1_0.xml @@ -1,6 +1,5 @@ UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'EventList' - UPDATE %PREFIX%_components SET com_plg_sequence = 7 WHERE com_type = 'ADM_PLUGIN' AND com_name_intern = 'EventList' stop From 7bd80db197a66f22b64924723935363e2eefba6b Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 20 Aug 2025 19:05:42 +0200 Subject: [PATCH 059/109] refactor: implement new overview sequence configuration key and remove redundant update step --- plugins/Calendar/Calendar.json | 6 ++++++ plugins/Calendar/db_scripts/update_1_0.xml | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/plugins/Calendar/Calendar.json b/plugins/Calendar/Calendar.json index e644b39a0a..f2d96c4523 100644 --- a/plugins/Calendar/Calendar.json +++ b/plugins/Calendar/Calendar.json @@ -20,6 +20,12 @@ "type": "integer", "value" : 1 }, + "calendar_overview_sequence": { + "name": "SYS_OVERVIEW_SEQUENCE", + "description": "SYS_OVERVIEW_SEQUENCE_DESC", + "type": "integer", + "value" : 3 + }, "calendar_show_events": { "name": "PLG_CALENDAR_PREFERENCES_SHOW_EVENTS", "description": "PLG_CALENDAR_PREFERENCES_SHOW_EVENTS_DESC", diff --git a/plugins/Calendar/db_scripts/update_1_0.xml b/plugins/Calendar/db_scripts/update_1_0.xml index 91654a1538..c9452879db 100644 --- a/plugins/Calendar/db_scripts/update_1_0.xml +++ b/plugins/Calendar/db_scripts/update_1_0.xml @@ -1,6 +1,5 @@ UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'Calendar' - UPDATE %PREFIX%_components SET com_plg_sequence = 3 WHERE com_type = 'ADM_PLUGIN' AND com_name_intern = 'Calendar' stop From 80ded846a81f5aa4b19b1169dae19f552c677ac4 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 20 Aug 2025 19:05:56 +0200 Subject: [PATCH 060/109] refactor: implement new overview sequence configuration key and remove redundant update step --- plugins/Birthday/Birthday.json | 6 ++++++ plugins/Birthday/db_scripts/update_1_0.xml | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/plugins/Birthday/Birthday.json b/plugins/Birthday/Birthday.json index 6f7ebb2975..94265a1796 100644 --- a/plugins/Birthday/Birthday.json +++ b/plugins/Birthday/Birthday.json @@ -19,6 +19,12 @@ "type": "integer", "value" : 1 }, + "birthday_overview_sequence": { + "name": "SYS_OVERVIEW_SEQUENCE", + "description": "SYS_OVERVIEW_SEQUENCE_DESC", + "type": "integer", + "value" : 2 + }, "birthday_show_names_extern": { "name": "PLG_BIRTHDAY_PREFERENCES_SHOW_NAMES_EXTERN", "description": "PLG_BIRTHDAY_PREFERENCES_SHOW_NAMES_EXTERN_DESC", diff --git a/plugins/Birthday/db_scripts/update_1_0.xml b/plugins/Birthday/db_scripts/update_1_0.xml index 2cb5a06df2..4d88d6c9e7 100644 --- a/plugins/Birthday/db_scripts/update_1_0.xml +++ b/plugins/Birthday/db_scripts/update_1_0.xml @@ -1,6 +1,5 @@ UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'Birthday' - UPDATE %PREFIX%_components SET com_plg_sequence = 2 WHERE com_type = 'ADM_PLUGIN' AND com_name_intern = 'Birthday' stop From 8f4f6d61d8f955ddd71b367bdb3918809be1cefc Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 20 Aug 2025 19:06:09 +0200 Subject: [PATCH 061/109] refactor: implement new overview sequence configuration key and remove redundant update step --- plugins/AnnouncementList/AnnouncementList.json | 6 ++++++ plugins/AnnouncementList/db_scripts/update_1_0.xml | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/plugins/AnnouncementList/AnnouncementList.json b/plugins/AnnouncementList/AnnouncementList.json index 83be863157..04bc39d02d 100644 --- a/plugins/AnnouncementList/AnnouncementList.json +++ b/plugins/AnnouncementList/AnnouncementList.json @@ -20,6 +20,12 @@ "type": "integer", "value" : 1 }, + "announcement_list_overview_sequence": { + "name": "SYS_OVERVIEW_SEQUENCE", + "description": "SYS_OVERVIEW_SEQUENCE_DESC", + "type": "integer", + "value" : 6 + }, "announcement_list_announcements_count": { "name": "PLG_ANNOUNCEMENT_LIST_PREFERENCES_ANNOUNCEMENTS_COUNT", "description": "PLG_ANNOUNCEMENT_LIST_PREFERENCES_ANNOUNCEMENTS_COUNT_DESC", diff --git a/plugins/AnnouncementList/db_scripts/update_1_0.xml b/plugins/AnnouncementList/db_scripts/update_1_0.xml index 16f71024b3..1439532f43 100644 --- a/plugins/AnnouncementList/db_scripts/update_1_0.xml +++ b/plugins/AnnouncementList/db_scripts/update_1_0.xml @@ -1,6 +1,5 @@ UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'AnnouncementList' - UPDATE %PREFIX%_components SET com_plg_sequence = 6 WHERE com_type = 'ADM_PLUGIN' AND com_name_intern = 'AnnouncementList' stop From 7b20af6ee9ae3fd93276e9e84bb0ed43b2527ee3 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 20 Aug 2025 19:07:06 +0200 Subject: [PATCH 062/109] refactor: update translation keys in who is online plugin --- plugins/WhoIsOnline/languages/en.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/WhoIsOnline/languages/en.xml b/plugins/WhoIsOnline/languages/en.xml index a9c87d9052..5d61db2a8a 100644 --- a/plugins/WhoIsOnline/languages/en.xml +++ b/plugins/WhoIsOnline/languages/en.xml @@ -11,8 +11,8 @@ This plugin displays visitors and registered members on the Overview page. Who is Online - Time still active - The time (in minutes) a user is considered still online after their last action. (default: 10) + Time still active + The time (in minutes) a user is considered still online after their last action. (default: 10) Show visitors If this setting is enabled the number of visitors will be displayed. Otherwise only logged-in users will be shown. (default: true) Show members to visitors From 95f8dd6a53025dafdc80cfad508cefc909208522 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 20 Aug 2025 21:04:11 +0200 Subject: [PATCH 063/109] fix: handle boolean values by storing them as integers in preferences --- src/Infrastructure/Plugins/PluginAbstract.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Infrastructure/Plugins/PluginAbstract.php b/src/Infrastructure/Plugins/PluginAbstract.php index ea23e1d550..7cb57c53a0 100644 --- a/src/Infrastructure/Plugins/PluginAbstract.php +++ b/src/Infrastructure/Plugins/PluginAbstract.php @@ -642,6 +642,9 @@ public static function doInstall(): bool // if the value is an associative array, store the keys separately $gSettingsManager->set($key . '_keys', implode(',', array_keys($value))); } + } elseif (is_bool($value)) { + // if the value is a boolean, store it as an integer + $gSettingsManager->set($key, (int)$value); } else { $gSettingsManager->set($key, $value); } From 1bdf61887fcc12cd71be2f940d7e4e6abc5c1b57 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 20 Aug 2025 21:10:10 +0200 Subject: [PATCH 064/109] fix: remove unnecessary name and description fields from overview sequences in JSON files --- plugins/AnnouncementList/AnnouncementList.json | 2 -- plugins/Birthday/Birthday.json | 2 -- plugins/Calendar/Calendar.json | 2 -- plugins/EventList/EventList.json | 2 -- plugins/LatestDocumentsFiles/LatestDocumentsFiles.json | 2 -- plugins/LoginForm/LoginForm.json | 2 -- plugins/RandomPhoto/RandomPhoto.json | 2 -- plugins/WhoIsOnline/WhoIsOnline.json | 2 -- 8 files changed, 16 deletions(-) diff --git a/plugins/AnnouncementList/AnnouncementList.json b/plugins/AnnouncementList/AnnouncementList.json index 04bc39d02d..25091c1a2e 100644 --- a/plugins/AnnouncementList/AnnouncementList.json +++ b/plugins/AnnouncementList/AnnouncementList.json @@ -21,8 +21,6 @@ "value" : 1 }, "announcement_list_overview_sequence": { - "name": "SYS_OVERVIEW_SEQUENCE", - "description": "SYS_OVERVIEW_SEQUENCE_DESC", "type": "integer", "value" : 6 }, diff --git a/plugins/Birthday/Birthday.json b/plugins/Birthday/Birthday.json index 94265a1796..24f3b65ec2 100644 --- a/plugins/Birthday/Birthday.json +++ b/plugins/Birthday/Birthday.json @@ -20,8 +20,6 @@ "value" : 1 }, "birthday_overview_sequence": { - "name": "SYS_OVERVIEW_SEQUENCE", - "description": "SYS_OVERVIEW_SEQUENCE_DESC", "type": "integer", "value" : 2 }, diff --git a/plugins/Calendar/Calendar.json b/plugins/Calendar/Calendar.json index f2d96c4523..4d87e87758 100644 --- a/plugins/Calendar/Calendar.json +++ b/plugins/Calendar/Calendar.json @@ -21,8 +21,6 @@ "value" : 1 }, "calendar_overview_sequence": { - "name": "SYS_OVERVIEW_SEQUENCE", - "description": "SYS_OVERVIEW_SEQUENCE_DESC", "type": "integer", "value" : 3 }, diff --git a/plugins/EventList/EventList.json b/plugins/EventList/EventList.json index f5e8164e86..69e4b68824 100644 --- a/plugins/EventList/EventList.json +++ b/plugins/EventList/EventList.json @@ -21,8 +21,6 @@ "value" : 1 }, "event_list_overview_sequence": { - "name": "SYS_OVERVIEW_SEQUENCE", - "description": "SYS_OVERVIEW_SEQUENCE_DESC", "type": "integer", "value" : 7 }, diff --git a/plugins/LatestDocumentsFiles/LatestDocumentsFiles.json b/plugins/LatestDocumentsFiles/LatestDocumentsFiles.json index 0b3117ad09..9165e97732 100644 --- a/plugins/LatestDocumentsFiles/LatestDocumentsFiles.json +++ b/plugins/LatestDocumentsFiles/LatestDocumentsFiles.json @@ -21,8 +21,6 @@ "value" : 1 }, "latest_documents_overview_sequence": { - "name": "SYS_OVERVIEW_SEQUENCE", - "description": "SYS_OVERVIEW_SEQUENCE_DESC", "type": "integer", "value" : 5 }, diff --git a/plugins/LoginForm/LoginForm.json b/plugins/LoginForm/LoginForm.json index 3095668548..7fe700a4ca 100644 --- a/plugins/LoginForm/LoginForm.json +++ b/plugins/LoginForm/LoginForm.json @@ -22,8 +22,6 @@ "value" : 1 }, "login_form_overview_sequence": { - "name": "SYS_OVERVIEW_SEQUENCE", - "description": "SYS_OVERVIEW_SEQUENCE_DESC", "type": "integer", "value" : 1 }, diff --git a/plugins/RandomPhoto/RandomPhoto.json b/plugins/RandomPhoto/RandomPhoto.json index eceffda84a..e409fab0b2 100644 --- a/plugins/RandomPhoto/RandomPhoto.json +++ b/plugins/RandomPhoto/RandomPhoto.json @@ -19,8 +19,6 @@ "value" : 1 }, "random_photo_overview_sequence": { - "name": "SYS_OVERVIEW_SEQUENCE", - "description": "SYS_OVERVIEW_SEQUENCE_DESC", "type": "integer", "value" : 4 }, diff --git a/plugins/WhoIsOnline/WhoIsOnline.json b/plugins/WhoIsOnline/WhoIsOnline.json index 657c7b2511..3845159059 100644 --- a/plugins/WhoIsOnline/WhoIsOnline.json +++ b/plugins/WhoIsOnline/WhoIsOnline.json @@ -19,8 +19,6 @@ "value" : 1 }, "who_is_online_overview_sequence": { - "name": "SYS_OVERVIEW_SEQUENCE", - "description": "SYS_OVERVIEW_SEQUENCE_DESC", "type": "integer", "value" : 8 }, From d289be26c4596c3cb5111ff82acc84feb7896202 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Wed, 20 Aug 2025 21:47:49 +0200 Subject: [PATCH 065/109] feat: enhance login form ranks management with dynamic input fields and JSON handling --- .../LoginFormPreferencesPresenter.php | 38 +++++++++-- plugins/LoginForm/languages/en.xml | 2 +- .../preferences.plugin.login-form.tpl | 68 ++++++++++++++++++- .../Service/PreferencesService.php | 4 ++ 4 files changed, 104 insertions(+), 8 deletions(-) diff --git a/plugins/LoginForm/classes/Presenter/LoginFormPreferencesPresenter.php b/plugins/LoginForm/classes/Presenter/LoginFormPreferencesPresenter.php index bc8b8b6979..0ca8f47470 100644 --- a/plugins/LoginForm/classes/Presenter/LoginFormPreferencesPresenter.php +++ b/plugins/LoginForm/classes/Presenter/LoginFormPreferencesPresenter.php @@ -75,20 +75,46 @@ public static function createLoginFormForm(Smarty $smarty): string $formValues['login_form_enable_ranks']['value'], array('helpTextId' => $formValues['login_form_enable_ranks']['description']) ); + // these inputs will never be displayed, but they are used to save the values later + // register an input filed for the ranks array and add the values from the plugin config + $formLoginForm->addInput( + 'login_form_ranks_keys', + '', + implode(',', array_keys($formValues['login_form_ranks']['value'])), + array('type' => 'text', 'property' => FormPresenter::FIELD_HIDDEN) + ); + // register an input filed for the ranks keys array and add the values from the plugin config + $formLoginForm->addInput( + 'login_form_ranks', + '', + implode(',', $formValues['login_form_ranks']['value']), + array('type' => 'text', 'property' => FormPresenter::FIELD_HIDDEN) + ); $content = ''; // create a table with the ranks $content .= ''; - $content .= ''; + $content .= ''; $content .= ''; + $id = 0; foreach ($formValues['login_form_ranks']['value'] as $numLogins => $rankName) { - $content .= ''; - $content .= ''; - $content .= ''; + $content .= ''; + $content .= ''; + $content .= ''; $content .= ''; + $id++; } - $content .= '
' . $gL10n->get('PLG_LOGIN_FORM_NUMBER_OF_LOGINS') . '' . $gL10n->get('PLG_LOGIN_FORM_MEMBERRANK') . '
' . $gL10n->get('PLG_LOGIN_FORM_NUMBER_OF_LOGINS') . '' . $gL10n->get('PLG_LOGIN_FORM_MEMBERRANK') . '
' . htmlspecialchars($numLogins) . '' . Language::translateIfTranslationStrId($rankName) . '
'; + $content .= ''; + $content .= ' + + + + ' . $gL10n->get('SYS_ADD_ENTRY') . ' + + + '; + $content .= ''; $formLoginForm->addCustomContent( - 'login_form_ranks', + 'login_form_ranks_table', Language::translateIfTranslationStrId($formValues['login_form_ranks']['name']), $content, array('helpTextId' => $formValues['login_form_ranks']['description']) diff --git a/plugins/LoginForm/languages/en.xml b/plugins/LoginForm/languages/en.xml index 4e7d74d1b2..05fa1170cf 100644 --- a/plugins/LoginForm/languages/en.xml +++ b/plugins/LoginForm/languages/en.xml @@ -20,5 +20,5 @@ Show ranks If this option is enabled, a rank depending on the number of logins will be displayed after the username. (default: true) Ranks - Here you can define the ranks that will be displayed after the username if \'Show ranks\' is enabled. The key is the number of logins and the value is the name of the rank. + Here you can define the ranks that will be displayed after the username if \'Show ranks\' is enabled. The key is the number of logins and the value is the name of the rank.\n To delete a rank just clear the \'Number of logins\' and \'Member rank\' inputs in the table. diff --git a/plugins/LoginForm/templates/preferences.plugin.login-form.tpl b/plugins/LoginForm/templates/preferences.plugin.login-form.tpl index 8eeac2a4f6..185dd7608d 100644 --- a/plugins/LoginForm/templates/preferences.plugin.login-form.tpl +++ b/plugins/LoginForm/templates/preferences.plugin.login-form.tpl @@ -1,3 +1,67 @@ +
@@ -8,7 +72,9 @@ {include 'sys-template-parts/form.checkbox.tpl' data=$elements['login_form_show_email_link']} {include 'sys-template-parts/form.checkbox.tpl' data=$elements['login_form_show_logout_link']} {include 'sys-template-parts/form.checkbox.tpl' data=$elements['login_form_enable_ranks']} - {include 'sys-template-parts/form.custom-content.tpl' data=$elements['login_form_ranks']} + {include 'sys-template-parts/form.input.tpl' data=$elements['login_form_ranks']} + {include 'sys-template-parts/form.input.tpl' data=$elements['login_form_ranks_keys']} + {include 'sys-template-parts/form.custom-content.tpl' data=$elements['login_form_ranks_table']} {include 'sys-template-parts/form.button.tpl' data=$elements['adm_button_save_login_form']} diff --git a/src/Preferences/Service/PreferencesService.php b/src/Preferences/Service/PreferencesService.php index 31cf57b221..e2c8c4452f 100644 --- a/src/Preferences/Service/PreferencesService.php +++ b/src/Preferences/Service/PreferencesService.php @@ -397,6 +397,10 @@ public function save(string $panel, array $formData) $sql = 'DELETE FROM ' . TBL_AUTO_LOGIN; $gDb->queryPrepared($sql); $gSettingsManager->set($key, $value); + } elseif (str_starts_with($value, '["') && str_ends_with($value, '"]')) { // check if the value is a JSON array + // decode JSON array and save it as an array + $value = implode(',', json_decode($value, true)); + $gSettingsManager->set($key, $value); } else { $gSettingsManager->set($key, $value); } From b5dbc411fe0e82f5b314609051508c7698a6d3e2 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Thu, 21 Aug 2025 16:29:09 +0200 Subject: [PATCH 066/109] fix: ensure value is a string before checking for JSON array format in PreferencesService --- src/Preferences/Service/PreferencesService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Preferences/Service/PreferencesService.php b/src/Preferences/Service/PreferencesService.php index e2c8c4452f..8b337d378c 100644 --- a/src/Preferences/Service/PreferencesService.php +++ b/src/Preferences/Service/PreferencesService.php @@ -397,7 +397,7 @@ public function save(string $panel, array $formData) $sql = 'DELETE FROM ' . TBL_AUTO_LOGIN; $gDb->queryPrepared($sql); $gSettingsManager->set($key, $value); - } elseif (str_starts_with($value, '["') && str_ends_with($value, '"]')) { // check if the value is a JSON array + } elseif (is_string($value) && str_starts_with($value, '["') && str_ends_with($value, '"]')) { // check if the value is a JSON array // decode JSON array and save it as an array $value = implode(',', json_decode($value, true)); $gSettingsManager->set($key, $value); From d875315243bf8eed60eddb56570a3176117c4ac9 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Thu, 21 Aug 2025 18:26:44 +0200 Subject: [PATCH 067/109] feat: add appendToSmarty method to allow adding multiple form elements to one smarty object --- src/UI/Presenter/FormPresenter.php | 95 ++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/src/UI/Presenter/FormPresenter.php b/src/UI/Presenter/FormPresenter.php index 2e02f912df..c29774ca1f 100644 --- a/src/UI/Presenter/FormPresenter.php +++ b/src/UI/Presenter/FormPresenter.php @@ -1917,6 +1917,101 @@ public function addToSmarty(Smarty $smarty): void $smarty->assign('hasRequiredFields', ($this->flagRequiredFields && $this->showRequiredFields ? true : false)); } + /** + * This method appends the form attributes and all form elements to the Smarty object. + * It also assigns the template file of the form to the Smarty object. + * After this method is called the whole form could be rendered through the Smarty object. + * + * Important: This method creates an array of the form type, elements, attributes, javascript code and hasRequiredFields variables if they already exist in the Smarty object. + * If the variables do not exist, they will be assigned as normal. + * The variables urlAdmidio, l10n, and settings are only one time assigned to the Smarty object. + * This results in the following structure for the zero-based array variables: + * [variableName] => [ + * 0 => first form element values, + * 1 => second form element values, + * 2 => ..., + * ] + * + * + * @param Smarty $smarty The Smarty object where the form data should be appended. + * @return void + */ + public function appendToSmarty(Smarty $smarty): void + { + global $gL10n, $gSettingsManager; + + if (!isset($smarty->tpl_vars['urlAdmidio'])) { + $smarty->assign('urlAdmidio', ADMIDIO_URL); + } + if (!isset($smarty->tpl_vars['l10n'])) { + $smarty->assign('l10n', $gL10n); + } + if (!isset($smarty->tpl_vars['settings'])) { + $smarty->assign('settings', $gSettingsManager); + } + if (!isset($smarty->tpl_vars['formType'])) { + $smarty->assign('formType', $this->type); + } else { + $curType = $smarty->getTemplateVars('formType'); + if (is_array($curType) && array_key_first($curType) === 0) { + // if type is already an array then append the new type to the existing ones + $smarty->assign('formType', array_merge($curType, array($this->type))); + } else { + // if type is not an array then create a new array with the current and new type + $smarty->assign('formType', array($curType, $this->type)); + } + } + if (!isset($smarty->tpl_vars['attributes'])) { + $smarty->assign('attributes', $this->attributes); + } else { + $curAttributes = $smarty->getTemplateVars('attributes'); + if (is_array($curAttributes) && count(array_filter($curAttributes, 'is_array')) > 0 && array_key_first($curAttributes) === 0) { + // if attributes are already an array then append the new attributes to the existing ones + $smarty->assign('attributes', array_merge($curAttributes, array($this->attributes))); + } else { + // if attributes are not an array then create a new array with the current and new attributes + $smarty->assign('attributes', array($curAttributes, $this->attributes)); + } + } + if (!isset($smarty->tpl_vars['elements'])) { + $smarty->assign('elements', $this->elements); + } else { + $curElements = $smarty->getTemplateVars('elements'); + if (is_array($curElements) && count(array_filter($curElements, 'is_array')) > 0 && array_key_first($curElements) === 0) { + // if elements are already an array then append the new elements to the existing ones + $smarty->assign('elements', array_merge($curElements, array($this->elements))); + } else { + // if elements are not an array then create a new array with the current and new elements + $smarty->assign('elements', array($curElements, $this->elements)); + } + } + if (!isset($smarty->tpl_vars['javascript'])) { + $smarty->assign('javascript', $this->javascript); + } else { + $curJavascript = $smarty->getTemplateVars('javascript'); + if (is_array($curJavascript) && array_key_first($curJavascript) === 0) { + // if javascript is already an array then append the new javascript to the existing ones + $smarty->assign('javascript', array_merge($curJavascript, array($this->javascript))); + } else { + // if javascript is not an array then create a new array with the current and new javascript + $smarty->assign('javascript', array($curJavascript, $this->javascript)); + } + } + if (!isset($smarty->tpl_vars['hasRequiredFields'])) { + $smarty->assign('hasRequiredFields', ($this->flagRequiredFields && $this->showRequiredFields ? true : false)); + } else { + $curRequiredFields = $smarty->getTemplateVars('hasRequiredFields'); + $newRequiredFields = ($this->flagRequiredFields && $this->showRequiredFields ? true : false); + if (is_array($curRequiredFields) && array_key_first($curRequiredFields) === 0) { + // if hasRequiredFields is already an array then append the new hasRequiredFields to the existing ones + $smarty->assign('hasRequiredFields', array_merge($curRequiredFields, array($newRequiredFields))); + } else { + // if hasRequiredFields is not an array then create a new array with the current and new hasRequiredFields + $smarty->assign('hasRequiredFields', array($curRequiredFields, $newRequiredFields)); + } + } + } + /** * This method returns the attributes array. * @return array Returns all attributes of the form. From 9f2b009a5f958d6f4f44895eee115268e2247686 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Fa=C3=9Fbender?= Date: Fri, 9 Jan 2026 17:52:38 +0100 Subject: [PATCH 068/109] fix loading of plugin classes --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 84e2d5c1f1..056869f541 100644 --- a/composer.json +++ b/composer.json @@ -50,7 +50,8 @@ }, "autoload": { "psr-4": { - "Admidio\\": "src/" + "Admidio\\": "src/", + "Plugins\\": "plugins/" }, "classmap": [ "system/classes/", From a998d92d4e391e651c51bdebbeea200bd2516734 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sun, 11 Jan 2026 16:40:06 +0100 Subject: [PATCH 069/109] feat: install all overview plugins when updating --- src/InstallationUpdate/Service/UpdateStepsCode.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/InstallationUpdate/Service/UpdateStepsCode.php b/src/InstallationUpdate/Service/UpdateStepsCode.php index a41966b936..580e8b7b14 100644 --- a/src/InstallationUpdate/Service/UpdateStepsCode.php +++ b/src/InstallationUpdate/Service/UpdateStepsCode.php @@ -44,11 +44,11 @@ public static function setDatabase(Database $database) self::$db = $database; } - public static function updateStep50InstallOverviewPlugins() + public static function updateStep51InstallOverviewPlugins() { $pluginManager = new PluginManager(); $plugins = $pluginManager->getAvailablePlugins(); - $arrayOverviewPlugins = array(/* 'AnnouncementList', 'Birthday', 'Calendar', 'EventList', 'LatestDocumentsFiles', */ 'LoginForm'/* , 'RandomPhoto', 'WhoIsOnline' */); + $arrayOverviewPlugins = array('AnnouncementList', 'Birthday', 'Calendar', 'EventList', 'LatestDocumentsFiles', 'LoginForm', 'RandomPhoto', 'WhoIsOnline'); foreach ($plugins as $pluginName => $plugin) { if (in_array($pluginName, $arrayOverviewPlugins)) { From 2d1ebae62d41274bd170bdecb80fba175ac63380 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sun, 11 Jan 2026 16:41:11 +0100 Subject: [PATCH 070/109] create new admidio update xml-file for version 5.1 --- install/db_scripts/update_5_0.xml | 9 --------- install/db_scripts/update_5_1.xml | 13 +++++++++++++ 2 files changed, 13 insertions(+), 9 deletions(-) create mode 100644 install/db_scripts/update_5_1.xml diff --git a/install/db_scripts/update_5_0.xml b/install/db_scripts/update_5_0.xml index 7ee536496b..6943e55d26 100644 --- a/install/db_scripts/update_5_0.xml +++ b/install/db_scripts/update_5_0.xml @@ -530,14 +530,5 @@ WHERE usf_fn.usf_name_intern = 'FIRST_NAME' AND usf_ln.usf_name_intern = 'LAST_N UPDATE %PREFIX%_user_fields SET usf_name = 'ICQ' WHERE usf_name = 'SYS_ICQ' UPDATE %PREFIX%_user_fields SET usf_name = 'X' WHERE usf_name = 'SYS_TWITTER' UPDATE %PREFIX%_user_fields SET usf_description = 'SYS_SOCIAL_NETWORK_FIELD_URL_DESC' WHERE usf_description = 'SYS_SOCIAL_NETWORK_FIELD_DESC' - INSERT INTO %PREFIX%_components (com_type, com_name, com_name_intern, com_version, com_beta) - VALUES ('MODULE', 'SYS_PLUGIN_MANAGER', 'PLUGINS', '5.0.0', 0) - INSERT INTO %PREFIX%_menu (men_com_id, men_men_id_parent, men_uuid, men_node, men_order, men_standard, men_name_intern, men_url, men_icon, men_name, men_description) - VALUES ((SELECT com_id FROM %PREFIX%_components WHERE com_name_intern = 'PLUGINS'), 2, %UUID%, false, 5, true, 'plugins', '/modules/plugins.php', 'puzzle', 'SYS_PLUGIN_MANAGER', 'SYS_PLUGIN_MANAGER_DESC') - UPDATE %PREFIX%_menu SET men_url = REPLACE(men_url, '/adm_plugins', 'plugins') WHERE men_url LIKE '%/adm_plugins%' - UpdateStepsCode::updateStep50InstallOverviewPlugins - ALTER TABLE %PREFIX%_preferences MODIFY COLUMN prf_name varchar(100) NOT NULL - ALTER TABLE %PREFIX%_preferences ALTER COLUMN prf_name TYPE varchar(100) - ALTER TABLE %PREFIX%_preferences ALTER COLUMN prf_name SET NOT NULL stop diff --git a/install/db_scripts/update_5_1.xml b/install/db_scripts/update_5_1.xml new file mode 100644 index 0000000000..6bc887e37d --- /dev/null +++ b/install/db_scripts/update_5_1.xml @@ -0,0 +1,13 @@ + + + INSERT INTO %PREFIX%_components (com_type, com_name, com_name_intern, com_version, com_beta) + VALUES ('MODULE', 'SYS_PLUGIN_MANAGER', 'PLUGINS', '5.0.0', 0) + INSERT INTO %PREFIX%_menu (men_com_id, men_men_id_parent, men_uuid, men_node, men_order, men_standard, men_name_intern, men_url, men_icon, men_name, men_description) + VALUES ((SELECT com_id FROM %PREFIX%_components WHERE com_name_intern = 'PLUGINS'), 2, %UUID%, false, 5, true, 'plugins', '/modules/plugins.php', 'puzzle', 'SYS_PLUGIN_MANAGER', 'SYS_PLUGIN_MANAGER_DESC') + UPDATE %PREFIX%_menu SET men_url = REPLACE(men_url, '/adm_plugins', 'plugins') WHERE men_url LIKE '%/adm_plugins%' + UpdateStepsCode::updateStep51InstallOverviewPlugins + ALTER TABLE %PREFIX%_preferences MODIFY COLUMN prf_name varchar(100) NOT NULL + ALTER TABLE %PREFIX%_preferences ALTER COLUMN prf_name TYPE varchar(100) + ALTER TABLE %PREFIX%_preferences ALTER COLUMN prf_name SET NOT NULL + stop + From d1f23ffa0a84be325f383e49db90f370c2090c69 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sun, 11 Jan 2026 16:49:34 +0100 Subject: [PATCH 071/109] fix: exclude of plugin classes --- composer.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/composer.json b/composer.json index 056869f541..d85dc42235 100644 --- a/composer.json +++ b/composer.json @@ -67,15 +67,15 @@ "!adm_my_files/config_example.php", "!adm_my_files/ecard_templates", "!adm_my_files/mail_templates", - "adm_plugins/*", - "!adm_plugins/announcement-list", - "!adm_plugins/birthday", - "!adm_plugins/calendar", - "!adm_plugins/event-list", - "!adm_plugins/latest-documents-files", - "!adm_plugins/login_form", - "!adm_plugins/random_photo", - "!adm_plugins/who-is-online", + "plugins/*", + "!plugins/announcement-list", + "!plugins/birthday", + "!plugins/calendar", + "!plugins/event-list", + "!plugins/latest-documents-files", + "!plugins/login_form", + "!plugins/random_photo", + "!plugins/who-is-online", "demo", "!vendor/*", "vendor/maennchen/zipstream-php/test", From 86929b201a76cac8d966bc9b6da7750d3c1f7fa7 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sun, 11 Jan 2026 16:50:59 +0100 Subject: [PATCH 072/109] feat: add update steps for retrieving previous settings in overview plugins --- .../classes/Service/UpdateStepsCode.php | 95 ++++++++++++++ .../db_scripts/update_1_0.xml | 1 + .../classes/Service/UpdateStepsCode.php | 103 +++++++++++++++ plugins/Birthday/db_scripts/update_1_0.xml | 1 + .../classes/Service/UpdateStepsCode.php | 118 ++++++++++++++++++ plugins/Calendar/db_scripts/update_1_0.xml | 1 + .../classes/Service/UpdateStepsCode.php | 100 +++++++++++++++ plugins/EventList/db_scripts/update_1_0.xml | 1 + .../classes/Service/UpdateStepsCode.php | 63 ++++++++++ .../db_scripts/update_1_0.xml | 1 + .../classes/Service/UpdateStepsCode.php | 86 +++++++++++++ plugins/LoginForm/db_scripts/update_1_0.xml | 1 + .../classes/Service/UpdateStepsCode.php | 76 +++++++++++ plugins/RandomPhoto/db_scripts/update_1_0.xml | 1 + .../classes/Service/UpdateStepsCode.php | 72 +++++++++++ plugins/WhoIsOnline/db_scripts/update_1_0.xml | 1 + 16 files changed, 721 insertions(+) create mode 100644 plugins/AnnouncementList/classes/Service/UpdateStepsCode.php create mode 100644 plugins/Birthday/classes/Service/UpdateStepsCode.php create mode 100644 plugins/Calendar/classes/Service/UpdateStepsCode.php create mode 100644 plugins/EventList/classes/Service/UpdateStepsCode.php create mode 100644 plugins/LatestDocumentsFiles/classes/Service/UpdateStepsCode.php create mode 100644 plugins/LoginForm/classes/Service/UpdateStepsCode.php create mode 100644 plugins/RandomPhoto/classes/Service/UpdateStepsCode.php create mode 100644 plugins/WhoIsOnline/classes/Service/UpdateStepsCode.php diff --git a/plugins/AnnouncementList/classes/Service/UpdateStepsCode.php b/plugins/AnnouncementList/classes/Service/UpdateStepsCode.php new file mode 100644 index 0000000000..2318e1f378 --- /dev/null +++ b/plugins/AnnouncementList/classes/Service/UpdateStepsCode.php @@ -0,0 +1,95 @@ + $varValue) { + if ($varName === 'plg_announcements_count') { + if ($gSettingsManager->getInt('announcement_list_announcements_count') !== (int)$varValue) { + $gSettingsManager->set('announcement_list_announcements_count', (int)$varValue); + } + } elseif ($varName === 'plg_show_preview') { + if ($gSettingsManager->getInt('announcement_list_show_preview_chars') !== (int)$varValue) { + $gSettingsManager->set('announcement_list_show_preview_chars', (int)$varValue); + } + } elseif ($varName === 'plgShowFullDescription') { + if ($gSettingsManager->getBool('announcement_list_show_full_description') !== (bool)$varValue) { + $gSettingsManager->set('announcement_list_show_full_description', (bool)$varValue); + } + } elseif ($varName === 'plg_max_char_per_word') { + if ($gSettingsManager->getInt('announcement_list_chars_before_linebreak') !== (int)$varValue) { + $gSettingsManager->set('announcement_list_chars_before_linebreak', (int)$varValue); + } + } elseif ($varName === 'plg_categories') { + $categories = (is_array($varValue) && !empty($varValue)) ? $varValue : array('All'); + if ($categories !== array('All')) { + $categoryIds = array(); + foreach ($categories as $category) { + // check if the category name exists and get the category id + $sql = 'SELECT cat_id + FROM ' . TBL_CATEGORIES . ' + WHERE cat_name = ? + AND cat_type = \'ANN\''; + $pdoStatement = $gDb->queryPrepared($sql, array($category)); + $row = $pdoStatement->fetch(); + if ($row !== false) { + $categoryIds[] = (int)$row['cat_id']; + } + } + // if there are no valid category ids found, get all visible categories for the current user + if (empty($categoryIds)) { + $categoryIds = array('All'); + } + } else { + $categoryIds = array('All'); + } + + $categoriesString = implode(',', $categoryIds); + if ($gSettingsManager->get('announcement_list_displayed_categories') !== $categoriesString) { + $gSettingsManager->set('announcement_list_displayed_categories', $categoriesString); + } + } + } + } + } +} \ No newline at end of file diff --git a/plugins/AnnouncementList/db_scripts/update_1_0.xml b/plugins/AnnouncementList/db_scripts/update_1_0.xml index 1439532f43..6032748a4f 100644 --- a/plugins/AnnouncementList/db_scripts/update_1_0.xml +++ b/plugins/AnnouncementList/db_scripts/update_1_0.xml @@ -1,5 +1,6 @@ UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'AnnouncementList' + UpdateStepsCode::updateStep10RetrievePreviousSettings stop diff --git a/plugins/Birthday/classes/Service/UpdateStepsCode.php b/plugins/Birthday/classes/Service/UpdateStepsCode.php new file mode 100644 index 0000000000..565bc9eebb --- /dev/null +++ b/plugins/Birthday/classes/Service/UpdateStepsCode.php @@ -0,0 +1,103 @@ + $varValue) { + if ($varName === 'plg_show_names_extern') { + if ($gSettingsManager->getBool('birthday_show_names_extern') !== (bool)$varValue) { + $gSettingsManager->set('birthday_show_names_extern', (bool)$varValue); + } + } elseif ($varName === 'birthday_show_names') { + if ($gSettingsManager->getInt('birthday_show_names') !== (int)$varValue) { + $gSettingsManager->set('birthday_show_names', (int)$varValue); + } + } elseif ($varName === 'plg_show_age') { + if ($gSettingsManager->getBool('birthday_show_age') !== (bool)$varValue) { + $gSettingsManager->set('birthday_show_age', (bool)$varValue); + } + } elseif ($varName === 'plg_show_alter_anrede') { + if ($gSettingsManager->getInt('birthday_show_age_salutation') !== (int)$varValue) { + $gSettingsManager->set('birthday_show_age_salutation', (int)$varValue); + } + } elseif ($varName === 'plg_show_hinweis_keiner') { + if ($gSettingsManager->getBool('birthday_show_notice_none') !== (bool)$varValue) { + $gSettingsManager->set('birthday_show_notice_none', (bool)$varValue); + } + } elseif ($varName === 'plg_show_zeitraum') { + if ($gSettingsManager->getInt('birthday_show_past') !== (int)$varValue) { + $gSettingsManager->set('birthday_show_past', (int)$varValue); + } + } elseif ($varName === 'plg_show_future') { + if ($gSettingsManager->getInt('birthday_show_future') !== (int)$varValue) { + $gSettingsManager->set('birthday_show_future', (int)$varValue); + } + } elseif ($varName === 'plg_show_display_limit') { + if ($gSettingsManager->getInt('birthday_show_display_limit') !== (int)$varValue) { + $gSettingsManager->set('birthday_show_display_limit', (int)$varValue); + } + } elseif ($varName === 'plg_show_email_extern') { + if ($gSettingsManager->getInt('birthday_show_email_extern') !== (int)$varValue) { + $gSettingsManager->set('birthday_show_email_extern', (int)$varValue); + } + } elseif ($varName === 'plg_birthday_roles_view_plugin') { + $categories = (is_array($varValue) && !empty($varValue)) ? $varValue : array('All'); + $categoriesString = implode(',', $categories); + if ($gSettingsManager->get('birthday_roles_view_plugin') !== $categoriesString) { + $gSettingsManager->set('birthday_roles_view_plugin', $categoriesString); + } + } elseif ($varName === 'plg_rolle_sql') { + $categories = (is_array($varValue) && !empty($varValue)) ? $varValue : array('All'); + $categoriesString = implode(',', $categories); + if ($gSettingsManager->get('birthday_roles_sql') !== $categoriesString) { + $gSettingsManager->set('birthday_roles_sql', $categoriesString); + } + } elseif ($varName === 'plg_sort_sql') { + if (strtolower($gSettingsManager->getString('birthday_sort_sql')) !== strtolower((string)$varValue)) { + $gSettingsManager->set('birthday_sort_sql', (string)$varValue); + } + } + } + } + } +} \ No newline at end of file diff --git a/plugins/Birthday/db_scripts/update_1_0.xml b/plugins/Birthday/db_scripts/update_1_0.xml index 4d88d6c9e7..883001a52a 100644 --- a/plugins/Birthday/db_scripts/update_1_0.xml +++ b/plugins/Birthday/db_scripts/update_1_0.xml @@ -1,5 +1,6 @@ UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'Birthday' + UpdateStepsCode::updateStep10RetrievePreviousSettings stop diff --git a/plugins/Calendar/classes/Service/UpdateStepsCode.php b/plugins/Calendar/classes/Service/UpdateStepsCode.php new file mode 100644 index 0000000000..7124f882f0 --- /dev/null +++ b/plugins/Calendar/classes/Service/UpdateStepsCode.php @@ -0,0 +1,118 @@ + $varValue) { + if ($varName === 'plg_ter_aktiv') { + if ($gSettingsManager->getBool('calendar_show_events') !== (bool)$varValue) { + $gSettingsManager->set('calendar_show_events', (bool)$varValue); + } + } elseif ($varName === 'plg_geb_aktiv') { + if ($gSettingsManager->getBool('calendar_show_birthdays') !== (bool)$varValue) { + $gSettingsManager->set('calendar_show_birthdays', (bool)$varValue); + } + } elseif ($varName === 'plg_geb_login') { + if ($gSettingsManager->getBool('calendar_show_birthdays_to_guests') !== (bool)$varValue) { + $gSettingsManager->set('calendar_show_birthdays_to_guests', (bool)$varValue); + } + } elseif ($varName === 'plg_geb_icon') { + if ($gSettingsManager->getBool('calendar_show_birthday_icon') !== (bool)$varValue) { + $gSettingsManager->set('calendar_show_birthday_icon', (bool)$varValue); + } + }elseif ($varName === 'plg_geb_displayNames') { + if ($gSettingsManager->getInt('calendar_show_birthday_names') !== (int)$varValue) { + $gSettingsManager->set('calendar_show_birthday_names', (int)$varValue); + } + } elseif ($varName === 'plg_kal_cat_show') { + if ($gSettingsManager->getBool('calendar_show_categories_names') !== (bool)$varValue) { + $gSettingsManager->set('calendar_show_categories_names', (bool)$varValue); + } + } elseif ($varName === 'plg_kal_cat') { + $categories = (is_array($varValue) && !empty($varValue)) ? $varValue : array('All'); + if ($categories !== array('All')) { + $categoryIds = array(); + foreach ($categories as $category) { + // check if the category name exists and get the category id + $sql = 'SELECT cat_id + FROM ' . TBL_CATEGORIES . ' + WHERE cat_name = ? + AND cat_type = \'EVT\''; + $pdoStatement = $gDb->queryPrepared($sql, array($category)); + $row = $pdoStatement->fetch(); + if ($row !== false) { + $categoryIds[] = (int)$row['cat_id']; + } + } + // if there are no valid category ids found, get all visible categories for the current user + if (empty($categoryIds)) { + $categoryIds = array('All'); + } + } else { + $categoryIds = array('All'); + } + + $categoriesString = implode(',', $categoryIds); + // make sure to use 'All' instead of 'all' for consistency + $categoriesString = str_ireplace('all', 'All', $categoriesString); + + if ($gSettingsManager->get('calendar_show_categories') !== $categoriesString) { + $gSettingsManager->set('calendar_show_categories', $categoriesString); + } + } elseif ($varName === 'plg_calendar_roles_view_plugin') { + $categories = (is_array($varValue) && !empty($varValue)) ? $varValue : array('All'); + $categoriesString = implode(',', $categories); + if ($gSettingsManager->get('calendar_roles_view_plugin') !== $categoriesString) { + $gSettingsManager->set('calendar_roles_view_plugin', $categoriesString); + } + } elseif ($varName === 'plg_rolle_sql') { + $categories = (is_array($varValue) && !empty($varValue)) ? $varValue : array('All'); + $categoriesString = implode(',', $categories); + if ($gSettingsManager->get('calendar_roles_sql') !== $categoriesString) { + $gSettingsManager->set('calendar_roles_sql', $categoriesString); + } + } + } + } + } +} \ No newline at end of file diff --git a/plugins/Calendar/db_scripts/update_1_0.xml b/plugins/Calendar/db_scripts/update_1_0.xml index c9452879db..5b6691e742 100644 --- a/plugins/Calendar/db_scripts/update_1_0.xml +++ b/plugins/Calendar/db_scripts/update_1_0.xml @@ -1,5 +1,6 @@ UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'Calendar' + UpdateStepsCode::updateStep10RetrievePreviousSettings stop diff --git a/plugins/EventList/classes/Service/UpdateStepsCode.php b/plugins/EventList/classes/Service/UpdateStepsCode.php new file mode 100644 index 0000000000..8530ff32bb --- /dev/null +++ b/plugins/EventList/classes/Service/UpdateStepsCode.php @@ -0,0 +1,100 @@ + $varValue) { + if ($varName === 'plg_max_number_events_shown') { + if ($gSettingsManager->getInt('event_list_events_count') !== (int)$varValue) { + $gSettingsManager->set('event_list_events_count', (int)$varValue); + } + } elseif ($varName === 'plg_show_date_end') { + if ($gSettingsManager->getBool('event_list_show_event_date_end') !== (bool)$varValue) { + $gSettingsManager->set('event_list_show_event_date_end', (bool)$varValue); + } + } elseif ($varName === 'plg_events_show_preview') { + if ($gSettingsManager->getInt('event_list_show_preview_chars') !== (int)$varValue) { + $gSettingsManager->set('event_list_show_preview_chars', (int)$varValue); + } + } elseif ($varName === 'plgShowFullDescription') { + if ($gSettingsManager->getBool('event_list_show_full_description') !== (bool)$varValue) { + $gSettingsManager->set('event_list_show_full_description', (bool)$varValue); + } + }elseif ($varName === 'plg_max_char_per_word') { + if ($gSettingsManager->getInt('event_list_chars_before_linebreak') !== (int)$varValue) { + $gSettingsManager->set('event_list_chars_before_linebreak', (int)$varValue); + } + } elseif ($varName === 'plg_kal_cat') { + $categories = (is_array($varValue) && !empty($varValue)) ? $varValue : array('All'); + + if ($categories !== array('All')) { + $categoryIds = array(); + foreach ($categories as $category) { + // check if the category name exists and get the category id + $sql = 'SELECT cat_id + FROM ' . TBL_CATEGORIES . ' + WHERE cat_name = ? + AND cat_type = \'EVT\''; + $pdoStatement = $gDb->queryPrepared($sql, array($category)); + $row = $pdoStatement->fetch(); + if ($row !== false) { + $categoryIds[] = (int)$row['cat_id']; + } + } + // if there are no valid category ids found, get all visible categories for the current user + if (empty($categoryIds)) { + $categoryIds = array('All'); + } + } else { + $categoryIds = array('All'); + } + + $categoriesString = implode(',', $categoryIds); + if ($gSettingsManager->get('event_list_displayed_categories') !== $categoriesString) { + $gSettingsManager->set('event_list_displayed_categories', $categoriesString); + } + } + } + } + } +} \ No newline at end of file diff --git a/plugins/EventList/db_scripts/update_1_0.xml b/plugins/EventList/db_scripts/update_1_0.xml index dd125cc3ca..250ea8f3df 100644 --- a/plugins/EventList/db_scripts/update_1_0.xml +++ b/plugins/EventList/db_scripts/update_1_0.xml @@ -1,5 +1,6 @@ UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'EventList' + UpdateStepsCode::updateStep10RetrievePreviousSettings stop diff --git a/plugins/LatestDocumentsFiles/classes/Service/UpdateStepsCode.php b/plugins/LatestDocumentsFiles/classes/Service/UpdateStepsCode.php new file mode 100644 index 0000000000..1f4ab856db --- /dev/null +++ b/plugins/LatestDocumentsFiles/classes/Service/UpdateStepsCode.php @@ -0,0 +1,63 @@ + $varValue) { + if ($varName === 'plgCountFiles') { + if ($gSettingsManager->getInt('latest_documents_files_files_count') !== (int)$varValue) { + $gSettingsManager->set('latest_documents_files_files_count', (int)$varValue); + } + } elseif ($varName === 'plgMaxCharsFilename') { + if ($gSettingsManager->getInt('latest_documents_files_max_chars_filename') !== (int)$varValue) { + $gSettingsManager->set('latest_documents_files_max_chars_filename', (int)$varValue); + } + } elseif ($varName === 'plg_show_upload_timestamp') { + if ($gSettingsManager->getBool('latest_documents_files_show_upload_timestamp') !== (bool)$varValue) { + $gSettingsManager->set('latest_documents_files_show_upload_timestamp', (bool)$varValue); + } + } + } + } + } +} \ No newline at end of file diff --git a/plugins/LatestDocumentsFiles/db_scripts/update_1_0.xml b/plugins/LatestDocumentsFiles/db_scripts/update_1_0.xml index ead909f55d..56dfaffe72 100644 --- a/plugins/LatestDocumentsFiles/db_scripts/update_1_0.xml +++ b/plugins/LatestDocumentsFiles/db_scripts/update_1_0.xml @@ -1,5 +1,6 @@ UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'LatestDocumentsFiles' + UpdateStepsCode::updateStep10RetrievePreviousSettings stop diff --git a/plugins/LoginForm/classes/Service/UpdateStepsCode.php b/plugins/LoginForm/classes/Service/UpdateStepsCode.php new file mode 100644 index 0000000000..2788507b96 --- /dev/null +++ b/plugins/LoginForm/classes/Service/UpdateStepsCode.php @@ -0,0 +1,86 @@ + $varValue) { + if ($varName === 'plg_show_register_link') { + if ($gSettingsManager->getBool('login_form_show_register_link') !== (bool)$varValue) { + $gSettingsManager->set('login_form_show_register_link', (bool)$varValue); + } + } elseif ($varName === 'plg_show_email_link') { + if ($gSettingsManager->getBool('login_form_show_email_link') !== (bool)$varValue) { + $gSettingsManager->set('login_form_show_email_link', (bool)$varValue); + } + } elseif ($varName === 'plg_show_logout_link') { + if ($gSettingsManager->getBool('login_form_show_logout_link') !== (bool)$varValue) { + $gSettingsManager->set('login_form_show_logout_link', (bool)$varValue); + } + } elseif ($varName === 'plg_rank') { + $ranks = (is_array($varValue) && !empty($varValue)) ? $varValue : array(); + // if there are no ranks defined disable the rank feature + // in previous versions this was done by defining an empty array + if (empty($ranks)) { + $gSettingsManager->set('login_form_enable_ranks', false); + } else { + $gSettingsManager->set('login_form_enable_ranks', true); + + // normally we would also use the defined rank titles from the config file but because they are + // not translatable and will be different to the new translation strings we don't update them here + /* + foreach ($ranks as $key => $rank) { + $gSettingsManager->set($key, implode(',', $value)); + // check if the value contains keys + if (array_keys($value) !== range(0, count($value) - 1)) { + // if the value is an associative array, store the keys separately + $gSettingsManager->set($key . '_keys', implode(',', array_keys($value))); + } + } + */ + } + } + } + } + } +} \ No newline at end of file diff --git a/plugins/LoginForm/db_scripts/update_1_0.xml b/plugins/LoginForm/db_scripts/update_1_0.xml index e6f2b56015..aae5dfb5c4 100644 --- a/plugins/LoginForm/db_scripts/update_1_0.xml +++ b/plugins/LoginForm/db_scripts/update_1_0.xml @@ -1,5 +1,6 @@ UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'LoginForm' + UpdateStepsCode::updateStep10RetrievePreviousSettings stop diff --git a/plugins/RandomPhoto/classes/Service/UpdateStepsCode.php b/plugins/RandomPhoto/classes/Service/UpdateStepsCode.php new file mode 100644 index 0000000000..326cb684c0 --- /dev/null +++ b/plugins/RandomPhoto/classes/Service/UpdateStepsCode.php @@ -0,0 +1,76 @@ + $varValue) { + if ($varName === 'plg_max_char_per_word') { + if ($gSettingsManager->getInt('random_photo_max_char_per_word') !== (int)$varValue) { + $gSettingsManager->set('random_photo_max_char_per_word', (int)$varValue); + } + } elseif ($varName === 'plg_photos_max_width') { + if ($gSettingsManager->getInt('random_photo_max_width') !== (int)$varValue) { + $gSettingsManager->set('random_photo_max_width', (int)$varValue); + } + } elseif ($varName === 'plg_photos_max_height') { + if ($gSettingsManager->getInt('random_photo_max_height') !== (int)$varValue) { + $gSettingsManager->set('random_photo_max_height', (int)$varValue); + } + } elseif ($varName === 'plg_photos_albums') { + if ($gSettingsManager->getInt('random_photo_albums') !== (int)$varValue) { + $gSettingsManager->set('random_photo_albums', (int)$varValue); + } + } elseif ($varName === 'plg_photos_picnr') { + if ($gSettingsManager->getInt('random_photo_album_photo_number') !== (int)$varValue) { + $gSettingsManager->set('random_photo_album_photo_number', (int)$varValue); + } + } elseif ($varName === 'plg_photos_show_link') { + if ($gSettingsManager->getBool('random_photo_show_album_link') !== (bool)$varValue) { + $gSettingsManager->set('random_photo_show_album_link', (bool)$varValue); + } + } + } + } + } +} \ No newline at end of file diff --git a/plugins/RandomPhoto/db_scripts/update_1_0.xml b/plugins/RandomPhoto/db_scripts/update_1_0.xml index e3e4fed3e5..366b5fec99 100644 --- a/plugins/RandomPhoto/db_scripts/update_1_0.xml +++ b/plugins/RandomPhoto/db_scripts/update_1_0.xml @@ -1,5 +1,6 @@ UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'RandomPhoto' + UpdateStepsCode::updateStep10RetrievePreviousSettings stop diff --git a/plugins/WhoIsOnline/classes/Service/UpdateStepsCode.php b/plugins/WhoIsOnline/classes/Service/UpdateStepsCode.php new file mode 100644 index 0000000000..e69ed5ab6b --- /dev/null +++ b/plugins/WhoIsOnline/classes/Service/UpdateStepsCode.php @@ -0,0 +1,72 @@ + $varValue) { + if ($varName === 'plg_time_online') { + if ($gSettingsManager->getInt('who_is_online_time_still_active') !== (int)$varValue) { + $gSettingsManager->set('who_is_online_time_still_active', (int)$varValue); + } + } elseif ($varName === 'plg_show_visitors') { + if ($gSettingsManager->getBool('who_is_online_show_visitors') !== (bool)$varValue) { + $gSettingsManager->set('who_is_online_show_visitors', (bool)$varValue); + } + } elseif ($varName === 'plg_show_members') { + if ($gSettingsManager->getInt('who_is_online_show_members_to_visitors') !== (int)$varValue) { + $gSettingsManager->set('who_is_online_show_members_to_visitors', (int)$varValue); + } + } elseif ($varName === 'plg_show_self') { + if ($gSettingsManager->getBool('who_is_online_show_self') !== (bool)$varValue) { + $gSettingsManager->set('who_is_online_show_self', (bool)$varValue); + } + } elseif ($varName === 'plg_show_users_side_by_side') { + if ($gSettingsManager->getBool('who_is_online_show_users_side_by_side') !== (bool)$varValue) { + $gSettingsManager->set('who_is_online_show_users_side_by_side', (bool)$varValue); + } + } + } + } + } +} \ No newline at end of file diff --git a/plugins/WhoIsOnline/db_scripts/update_1_0.xml b/plugins/WhoIsOnline/db_scripts/update_1_0.xml index dba8467f50..a65763df97 100644 --- a/plugins/WhoIsOnline/db_scripts/update_1_0.xml +++ b/plugins/WhoIsOnline/db_scripts/update_1_0.xml @@ -1,5 +1,6 @@ UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'WhoIsOnline' + UpdateStepsCode::updateStep10RetrievePreviousSettings stop From ab651b0d84dc383c8b0933ed186abb9a4a9c3e33 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sun, 11 Jan 2026 17:08:09 +0100 Subject: [PATCH 073/109] small fixes --- plugins/AnnouncementList/classes/AnnouncementList.php | 2 +- plugins/Birthday/classes/Birthday.php | 2 +- plugins/Calendar/classes/Calendar.php | 2 +- plugins/EventList/classes/EventList.php | 2 +- .../classes/Presenter/EventListPreferencesPresenter.php | 3 +-- 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/plugins/AnnouncementList/classes/AnnouncementList.php b/plugins/AnnouncementList/classes/AnnouncementList.php index 60ef8fa063..420c3fb73d 100644 --- a/plugins/AnnouncementList/classes/AnnouncementList.php +++ b/plugins/AnnouncementList/classes/AnnouncementList.php @@ -119,7 +119,7 @@ private static function getAnnouncementsData() : array } // show preview text - if ($config['announcement_list_show_full_description'] === 1) { + if ($config['announcement_list_show_full_description'] === true) { $plgNewDescription = $plgAnnouncement->getValue('ann_description'); } elseif ($config['announcement_list_show_preview_chars'] > 0) { // remove all html tags except some format tags diff --git a/plugins/Birthday/classes/Birthday.php b/plugins/Birthday/classes/Birthday.php index b1e445cf20..d60a1dd2e2 100644 --- a/plugins/Birthday/classes/Birthday.php +++ b/plugins/Birthday/classes/Birthday.php @@ -115,7 +115,7 @@ private static function getBirthdaysData() : array } // Check if the role condition has been set - if (isset($config['birthday_roles_sql']) && is_array($config['birthday_roles_sql']) && count($config['birthday_roles_sql']) > 0) { + if (!empty($config['birthday_roles_sql'])) { $sqlRol = 'IN (' . implode(',', $config['birthday_roles_sql']) . ')'; } else { $sqlRol = 'IS NOT NULL'; diff --git a/plugins/Calendar/classes/Calendar.php b/plugins/Calendar/classes/Calendar.php index b6d85c3137..556c3b3e87 100644 --- a/plugins/Calendar/classes/Calendar.php +++ b/plugins/Calendar/classes/Calendar.php @@ -311,7 +311,7 @@ private static function getCalendarsData() : string } // Check if the role condition has been set - if (isset(self::$pluginConfig['calendar_roles_sql']) && is_array(self::$pluginConfig['calendar_roles_sql']) && count(self::$pluginConfig['calendar_roles_sql']) > 0) { + if (!empty(self::$pluginConfig['calendar_roles_sql'])) { $sqlRoleIds = 'IN (' . implode(',', self::$pluginConfig['calendar_roles_sql']) . ')'; } else { $sqlRoleIds = 'IS NOT NULL'; diff --git a/plugins/EventList/classes/EventList.php b/plugins/EventList/classes/EventList.php index cd58f843a6..76e2dad227 100644 --- a/plugins/EventList/classes/EventList.php +++ b/plugins/EventList/classes/EventList.php @@ -83,7 +83,7 @@ private static function getEventsData() : array INNER JOIN ' . TBL_CATEGORIES . ' AS cat ON cat_id = dat_cat_id WHERE cat_id IN (' . Database::getQmForValues($catIdParams) . ') - AND dat_begin >= ? -- DATETIME_NOW + AND dat_end >= ? -- DATETIME_NOW ' . $plgSqlCategories . ' ORDER BY dat_begin LIMIT ' . $config['event_list_events_count']; diff --git a/plugins/EventList/classes/Presenter/EventListPreferencesPresenter.php b/plugins/EventList/classes/Presenter/EventListPreferencesPresenter.php index d7277ccf29..ef88117e39 100644 --- a/plugins/EventList/classes/Presenter/EventListPreferencesPresenter.php +++ b/plugins/EventList/classes/Presenter/EventListPreferencesPresenter.php @@ -87,11 +87,10 @@ public static function createEventListForm(Smarty $smarty): string FROM ' . TBL_EVENTS . ' AS evt INNER JOIN ' . TBL_CATEGORIES . ' AS cat WHERE cat_id IN (' . $gDb->getQmForValues($catIdParams) . ') - AND dat_begin >= ? -- DATETIME_NOW ORDER BY dat_timestamp_create DESC'; $sqlData = array( 'query' => $sql, - 'params' => array_merge($catIdParams, array(DATETIME_NOW)) + 'params' => array_merge($catIdParams) ); $formEventList->addSelectBoxFromSql( From 84d6d65148803cb9763807bd69f3737068dc5d65 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sun, 11 Jan 2026 17:28:44 +0100 Subject: [PATCH 074/109] merge: Login form could not be called within an iframe from master --- plugins/LoginForm/classes/LoginForm.php | 32 ++++++++++++++++--------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/plugins/LoginForm/classes/LoginForm.php b/plugins/LoginForm/classes/LoginForm.php index 79e7112e75..bd64d55624 100644 --- a/plugins/LoginForm/classes/LoginForm.php +++ b/plugins/LoginForm/classes/LoginForm.php @@ -8,7 +8,7 @@ use Admidio\Infrastructure\Utils\SecurityUtils; use Admidio\Roles\Entity\Role; use Admidio\UI\Presenter\FormPresenter; - +use Admidio\UI\Presenter\PagePresenter; use InvalidArgumentException; use Exception; use Throwable; @@ -68,7 +68,7 @@ private static function getLoginData() : array * @brief Creates the login form * @return FormPresenter Returns the login form presenter */ - private static function createLoginForm() : FormPresenter + private static function createLoginForm(PagePresenter $formPage) : FormPresenter { global $gL10n, $gDb, $gCurrentOrgId, $gSettingsManager, $gCurrentOrganization; @@ -113,9 +113,9 @@ private static function createLoginForm() : FormPresenter $form = new FormPresenter( 'adm_plugin_login_form', - 'plugin.login-form.edit.tpl', + ADMIDIO_PATH . FOLDER_PLUGINS . '/LoginForm/templates/plugin.login-form.edit.tpl', ADMIDIO_URL . FOLDER_SYSTEM . '/login.php?mode=check', - null, + $formPage, array('type' => 'vertical', 'setFocus' => false, 'showRequiredFields' => false) ); $form->addInput( @@ -203,13 +203,23 @@ public static function doRender($page = null) : bool $loginFormPlugin->showHtmlPage('plugin.login-form.view.tpl'); } } else { - $form = self::createLoginForm(); - $smarty = $loginFormPlugin->createSmartyObject(); - $smarty->assign('settings', $gSettingsManager); - $smarty->assign('showRegisterLink', self::$pluginConfig['login_form_show_register_link']); - $form->addToSmarty($smarty); - $gCurrentSession->addFormObject($form); - echo $smarty->fetch('plugin.login-form.edit.tpl'); + $formPage = $loginFormPlugin->getPage(); + $form = self::createLoginForm($formPage); + if (isset($page)) { + $smarty = $loginFormPlugin->createSmartyObject(); + $smarty->assign('settings', $gSettingsManager); + $smarty->assign('showRegisterLink', self::$pluginConfig['login_form_show_register_link']); + $form->addToSmarty($smarty); + $gCurrentSession->addFormObject($form); + echo $smarty->fetch('plugin.login-form.edit.tpl'); + } else { + $_SESSION['login_forward_url_post'] = '1'; // Force a reload of the entire page, especially if it was loaded from an iframe. + $form->addToHtmlPage(); + $gCurrentSession->addFormObject($form); + $formPage->assignSmartyVariable('settings', $gSettingsManager); + $formPage->assignSmartyVariable('showRegisterLink', self::$pluginConfig['login_form_show_register_link']); + $formPage->show(); + } } } else { throw new InvalidArgumentException($gL10n->get('SYS_INVALID_PAGE_VIEW')); From 0323340bd5dfdfe9b7d8f393ba76a0b86a4eff36 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sun, 11 Jan 2026 17:41:40 +0100 Subject: [PATCH 075/109] refactor: update method documentation to clarify settings retrieval process --- .../classes/Service/UpdateStepsCode.php | 10 ++++++---- plugins/Birthday/classes/Service/UpdateStepsCode.php | 6 ++++-- plugins/Calendar/classes/Service/UpdateStepsCode.php | 8 +++++--- plugins/EventList/classes/Service/UpdateStepsCode.php | 10 ++++++---- .../classes/Service/UpdateStepsCode.php | 6 ++++-- plugins/LoginForm/classes/Service/UpdateStepsCode.php | 6 ++++-- .../RandomPhoto/classes/Service/UpdateStepsCode.php | 6 ++++-- .../WhoIsOnline/classes/Service/UpdateStepsCode.php | 6 ++++-- 8 files changed, 37 insertions(+), 21 deletions(-) diff --git a/plugins/AnnouncementList/classes/Service/UpdateStepsCode.php b/plugins/AnnouncementList/classes/Service/UpdateStepsCode.php index 2318e1f378..230d23caca 100644 --- a/plugins/AnnouncementList/classes/Service/UpdateStepsCode.php +++ b/plugins/AnnouncementList/classes/Service/UpdateStepsCode.php @@ -2,7 +2,9 @@ namespace Plugins\AnnouncementList\classes\Service; use Admidio\Infrastructure\Database; +use Admidio\Infrastructure\Exception; use Plugins\AnnouncementList\classes\AnnouncementList; +use ReflectionException; /** * @copyright The Admidio Team @@ -26,12 +28,12 @@ public static function setDatabase(Database $database) } /** - * Add default fields for the inventory module. - * @throws Exception + * Retrieve previous settings from config file and update the database settings accordingly. + * @throws Exception|ReflectionException */ public static function updateStep10RetrievePreviousSettings() { - global $gSettingsManager; + global $gSettingsManager; $pluginAnnouncementList = AnnouncementList::getInstance(); $configValues = $pluginAnnouncementList::getPluginConfig(); @@ -70,7 +72,7 @@ public static function updateStep10RetrievePreviousSettings() FROM ' . TBL_CATEGORIES . ' WHERE cat_name = ? AND cat_type = \'ANN\''; - $pdoStatement = $gDb->queryPrepared($sql, array($category)); + $pdoStatement = self::$db->queryPrepared($sql, array($category)); $row = $pdoStatement->fetch(); if ($row !== false) { $categoryIds[] = (int)$row['cat_id']; diff --git a/plugins/Birthday/classes/Service/UpdateStepsCode.php b/plugins/Birthday/classes/Service/UpdateStepsCode.php index 565bc9eebb..14e1a24612 100644 --- a/plugins/Birthday/classes/Service/UpdateStepsCode.php +++ b/plugins/Birthday/classes/Service/UpdateStepsCode.php @@ -2,7 +2,9 @@ namespace Plugins\Birthday\classes\Service; use Admidio\Infrastructure\Database; +use Admidio\Infrastructure\Exception; use Plugins\Birthday\classes\Birthday; +use ReflectionException; /** * @copyright The Admidio Team @@ -26,8 +28,8 @@ public static function setDatabase(Database $database) } /** - * Add default fields for the inventory module. - * @throws Exception + * Retrieve previous settings from config file and update the database settings accordingly. + * @throws Exception|ReflectionException */ public static function updateStep10RetrievePreviousSettings() { diff --git a/plugins/Calendar/classes/Service/UpdateStepsCode.php b/plugins/Calendar/classes/Service/UpdateStepsCode.php index 7124f882f0..a1c7caac52 100644 --- a/plugins/Calendar/classes/Service/UpdateStepsCode.php +++ b/plugins/Calendar/classes/Service/UpdateStepsCode.php @@ -2,7 +2,9 @@ namespace Plugins\Calendar\classes\Service; use Admidio\Infrastructure\Database; +use Admidio\Infrastructure\Exception; use Plugins\Calendar\classes\Calendar; +use ReflectionException; /** * @copyright The Admidio Team @@ -26,8 +28,8 @@ public static function setDatabase(Database $database) } /** - * Add default fields for the inventory module. - * @throws Exception + * Retrieve previous settings from config file and update the database settings accordingly. + * @throws Exception|ReflectionException */ public static function updateStep10RetrievePreviousSettings() { @@ -78,7 +80,7 @@ public static function updateStep10RetrievePreviousSettings() FROM ' . TBL_CATEGORIES . ' WHERE cat_name = ? AND cat_type = \'EVT\''; - $pdoStatement = $gDb->queryPrepared($sql, array($category)); + $pdoStatement = self::$db->queryPrepared($sql, array($category)); $row = $pdoStatement->fetch(); if ($row !== false) { $categoryIds[] = (int)$row['cat_id']; diff --git a/plugins/EventList/classes/Service/UpdateStepsCode.php b/plugins/EventList/classes/Service/UpdateStepsCode.php index 8530ff32bb..2fccc46ce4 100644 --- a/plugins/EventList/classes/Service/UpdateStepsCode.php +++ b/plugins/EventList/classes/Service/UpdateStepsCode.php @@ -2,7 +2,9 @@ namespace Plugins\EventList\classes\Service; use Admidio\Infrastructure\Database; +use Admidio\Infrastructure\Exception; use Plugins\EventList\classes\EventList; +use ReflectionException; /** * @copyright The Admidio Team @@ -26,12 +28,12 @@ public static function setDatabase(Database $database) } /** - * Add default fields for the inventory module. - * @throws Exception + * Retrieve previous settings from config file and update the database settings accordingly. + * @throws Exception|ReflectionException */ public static function updateStep10RetrievePreviousSettings() { - global $gDb, $gSettingsManager, $gCurrentUser; + global $gSettingsManager; $pluginEventList = EventList::getInstance(); $configValues = $pluginEventList::getPluginConfig(); @@ -75,7 +77,7 @@ public static function updateStep10RetrievePreviousSettings() FROM ' . TBL_CATEGORIES . ' WHERE cat_name = ? AND cat_type = \'EVT\''; - $pdoStatement = $gDb->queryPrepared($sql, array($category)); + $pdoStatement = self::$db->queryPrepared($sql, array($category)); $row = $pdoStatement->fetch(); if ($row !== false) { $categoryIds[] = (int)$row['cat_id']; diff --git a/plugins/LatestDocumentsFiles/classes/Service/UpdateStepsCode.php b/plugins/LatestDocumentsFiles/classes/Service/UpdateStepsCode.php index 1f4ab856db..24579e8351 100644 --- a/plugins/LatestDocumentsFiles/classes/Service/UpdateStepsCode.php +++ b/plugins/LatestDocumentsFiles/classes/Service/UpdateStepsCode.php @@ -2,7 +2,9 @@ namespace Plugins\LatestDocumentsFiles\classes\Service; use Admidio\Infrastructure\Database; +use Admidio\Infrastructure\Exception; use Plugins\LatestDocumentsFiles\classes\LatestDocumentsFiles; +use ReflectionException; /** * @copyright The Admidio Team @@ -26,8 +28,8 @@ public static function setDatabase(Database $database) } /** - * Add default fields for the inventory module. - * @throws Exception + * Retrieve previous settings from config file and update the database settings accordingly. + * @throws Exception|ReflectionException */ public static function updateStep10RetrievePreviousSettings() { diff --git a/plugins/LoginForm/classes/Service/UpdateStepsCode.php b/plugins/LoginForm/classes/Service/UpdateStepsCode.php index 2788507b96..a8cc0f39a7 100644 --- a/plugins/LoginForm/classes/Service/UpdateStepsCode.php +++ b/plugins/LoginForm/classes/Service/UpdateStepsCode.php @@ -2,7 +2,9 @@ namespace Plugins\LoginForm\classes\Service; use Admidio\Infrastructure\Database; +use Admidio\Infrastructure\Exception; use Plugins\LoginForm\classes\LoginForm; +use ReflectionException; /** * @copyright The Admidio Team @@ -26,8 +28,8 @@ public static function setDatabase(Database $database) } /** - * Add default fields for the inventory module. - * @throws Exception + * Retrieve previous settings from config file and update the database settings accordingly. + * @throws Exception|ReflectionException */ public static function updateStep10RetrievePreviousSettings() { diff --git a/plugins/RandomPhoto/classes/Service/UpdateStepsCode.php b/plugins/RandomPhoto/classes/Service/UpdateStepsCode.php index 326cb684c0..eb9b562437 100644 --- a/plugins/RandomPhoto/classes/Service/UpdateStepsCode.php +++ b/plugins/RandomPhoto/classes/Service/UpdateStepsCode.php @@ -2,7 +2,9 @@ namespace Plugins\RandomPhoto\classes\Service; use Admidio\Infrastructure\Database; +use Admidio\Infrastructure\Exception; use Plugins\RandomPhoto\classes\RandomPhoto; +use ReflectionException; /** * @copyright The Admidio Team @@ -26,8 +28,8 @@ public static function setDatabase(Database $database) } /** - * Add default fields for the inventory module. - * @throws Exception + * Retrieve previous settings from config file and update the database settings accordingly. + * @throws Exception|ReflectionException */ public static function updateStep10RetrievePreviousSettings() { diff --git a/plugins/WhoIsOnline/classes/Service/UpdateStepsCode.php b/plugins/WhoIsOnline/classes/Service/UpdateStepsCode.php index e69ed5ab6b..3d17264fcd 100644 --- a/plugins/WhoIsOnline/classes/Service/UpdateStepsCode.php +++ b/plugins/WhoIsOnline/classes/Service/UpdateStepsCode.php @@ -2,7 +2,9 @@ namespace Plugins\WhoIsOnline\classes\Service; use Admidio\Infrastructure\Database; +use Admidio\Infrastructure\Exception; use Plugins\WhoIsOnline\classes\WhoIsOnline; +use ReflectionException; /** * @copyright The Admidio Team @@ -26,8 +28,8 @@ public static function setDatabase(Database $database) } /** - * Add default fields for the inventory module. - * @throws Exception + * Retrieve previous settings from config file and update the database settings accordingly. + * @throws Exception|ReflectionException */ public static function updateStep10RetrievePreviousSettings() { From 578533efbf1443490a58b8f2f4d3c4790619d281 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sun, 11 Jan 2026 20:26:23 +0100 Subject: [PATCH 076/109] feat: add warnings and information during update process of admidio corresponding to the plugins --- install/db_scripts/update_5_1.xml | 15 ++-- .../parts/form.part.info.tpl | 5 ++ install/templates/update.successful.tpl | 14 ++++ install/update.php | 52 ++++++++++++ languages/en.xml | 4 + .../Service/UpdateStepsCode.php | 79 ++++++++++++++++++- 6 files changed, 161 insertions(+), 8 deletions(-) create mode 100644 install/templates/sys-template-parts/parts/form.part.info.tpl diff --git a/install/db_scripts/update_5_1.xml b/install/db_scripts/update_5_1.xml index 6bc887e37d..9b40bfe286 100644 --- a/install/db_scripts/update_5_1.xml +++ b/install/db_scripts/update_5_1.xml @@ -1,13 +1,14 @@ - INSERT INTO %PREFIX%_components (com_type, com_name, com_name_intern, com_version, com_beta) + INSERT INTO %PREFIX%_components (com_type, com_name, com_name_intern, com_version, com_beta) VALUES ('MODULE', 'SYS_PLUGIN_MANAGER', 'PLUGINS', '5.0.0', 0) - INSERT INTO %PREFIX%_menu (men_com_id, men_men_id_parent, men_uuid, men_node, men_order, men_standard, men_name_intern, men_url, men_icon, men_name, men_description) + INSERT INTO %PREFIX%_menu (men_com_id, men_men_id_parent, men_uuid, men_node, men_order, men_standard, men_name_intern, men_url, men_icon, men_name, men_description) VALUES ((SELECT com_id FROM %PREFIX%_components WHERE com_name_intern = 'PLUGINS'), 2, %UUID%, false, 5, true, 'plugins', '/modules/plugins.php', 'puzzle', 'SYS_PLUGIN_MANAGER', 'SYS_PLUGIN_MANAGER_DESC') - UPDATE %PREFIX%_menu SET men_url = REPLACE(men_url, '/adm_plugins', 'plugins') WHERE men_url LIKE '%/adm_plugins%' - UpdateStepsCode::updateStep51InstallOverviewPlugins - ALTER TABLE %PREFIX%_preferences MODIFY COLUMN prf_name varchar(100) NOT NULL - ALTER TABLE %PREFIX%_preferences ALTER COLUMN prf_name TYPE varchar(100) - ALTER TABLE %PREFIX%_preferences ALTER COLUMN prf_name SET NOT NULL + UPDATE %PREFIX%_menu SET men_url = REPLACE(men_url, '/adm_plugins', 'plugins') WHERE men_url LIKE '%/adm_plugins%' + UpdateStepsCode::updateStep51InstallOverviewPlugins + UpdateStepsCode::updateStep51CheckFor3rdPartyPlugins + ALTER TABLE %PREFIX%_preferences MODIFY COLUMN prf_name varchar(100) NOT NULL + ALTER TABLE %PREFIX%_preferences ALTER COLUMN prf_name TYPE varchar(100) + ALTER TABLE %PREFIX%_preferences ALTER COLUMN prf_name SET NOT NULL stop diff --git a/install/templates/sys-template-parts/parts/form.part.info.tpl b/install/templates/sys-template-parts/parts/form.part.info.tpl new file mode 100644 index 0000000000..85de8ebc26 --- /dev/null +++ b/install/templates/sys-template-parts/parts/form.part.info.tpl @@ -0,0 +1,5 @@ +{if $data.alertInfo} + +{/if} diff --git a/install/templates/update.successful.tpl b/install/templates/update.successful.tpl index dce4b54fdc..31552727ce 100644 --- a/install/templates/update.successful.tpl +++ b/install/templates/update.successful.tpl @@ -7,6 +7,20 @@ {$l10n->get('INS_UPDATING_WAS_SUCCESSFUL')}
+ {if $updateWarnings|@count > 0 || $updateInfos|@count > 0} +

{$l10n->get('SYS_NOTE')}

+ {if $updateInfos|@count > 0} + {foreach from=$updateInfos item=data} + {include file="sys-template-parts/parts/form.part.info.tpl"} + {/foreach} + {/if} + {if $updateWarnings|@count > 0} + {foreach from=$updateWarnings item=data} + {include file="sys-template-parts/parts/form.part.warning.tpl"} + {/foreach} + {/if} + {/if} +

{$l10n->get('INS_UPDATE_TO_VERSION_SUCCESSFUL', array(ADMIDIO_VERSION_TEXT))}

{$l10n->get('INS_SUPPORT_FURTHER_DEVELOPMENT')} diff --git a/install/update.php b/install/update.php index efc6b8627a..19a55b7c92 100644 --- a/install/update.php +++ b/install/update.php @@ -305,9 +305,61 @@ function showErrorMessage(string $message, bool $reloadPage = false): void )); exit(); } elseif ($getMode === 'result') { + // check if there are warnings about the plugins + $updateWarnings = array(); + $updateInfos = array(); + // the variables are stored in a cookie so that they survive the redirect after the update + $cookie = isset($_COOKIE['adm_update_plugins_warnings']) ? json_decode($_COOKIE['adm_update_plugins_warnings'], true) : []; + $gWarnOldPlugins = false; + $gWarn3rdPartyPlugins = false; + $gWarnOldPluginsFolder = false; + $gInfo3rdPartyPlugins = false; + + if (!empty($cookie)) { + if (isset($cookie['warn_old_plugins'])) { + $gWarnOldPlugins = $cookie['warn_old_plugins']; + } + if (isset($cookie['warn_3rd_party_plugins'])) { + $gWarn3rdPartyPlugins = $cookie['warn_3rd_party_plugins']; + } + if (isset($cookie['warn_old_plugins_folder'])) { + $gWarnOldPluginsFolder = $cookie['warn_old_plugins_folder']; + } + if (isset($cookie['info_3rd_party_plugins'])) { + $gInfo3rdPartyPlugins = $cookie['info_3rd_party_plugins']; + } + } + + if ($gWarnOldPlugins) { + $updateWarnings[] = array( + 'id' => 'warn_old_plugins', + 'alertWarning' => $gL10n->get('INS_WARNING_OLD_ADM_PLUGINS_COULD_NOT_BE_DELETED', array('adm_plugins', 'adm_plugins')) + ); + } + if ($gWarn3rdPartyPlugins) { + $updateWarnings[] = array( + 'id' => 'warn_3rd_party_plugins', + 'alertWarning' => $gL10n->get('INS_WARNING_3RD_PARRTY_PLUGINS_COULD_NOT_BE_MOVED', array('plugins', 'adm_plugins')) + ); + } + if ($gWarnOldPluginsFolder) { + $updateWarnings[] = array( + 'id' => 'warn_old_plugins_folder', + 'alertWarning' => $gL10n->get('INS_WARNING_OLD_ADM_PLUGINS_FOLDER_COULD_NOT_BE_DELETED', array('adm_plugins', 'adm_plugins')) + ); + } + if ($gInfo3rdPartyPlugins) { + $updateInfos[] = array( + 'id' => 'info_3rd_party_plugins', + 'alertInfo' => $gL10n->get('INS_INFO_3RD_PARRTY_PLUGINS_HAVE_BEEN_MOVED', array('plugins')) + ); + } + // show notice that update was successful $page = new InstallationPresenter('admidio-update-successful', $gL10n->get('INS_UPDATE')); $page->addTemplateFile('update.successful.tpl'); + $page->assignSmartyVariable('updateWarnings', $updateWarnings); + $page->assignSmartyVariable('updateInfos', $updateInfos); $page->setUpdateModus(); $page->addJavascript('$("#buttonDonate").focus();', true); $page->show(); diff --git a/languages/en.xml b/languages/en.xml index 9e5ec2b7d6..b308f67588 100644 --- a/languages/en.xml +++ b/languages/en.xml @@ -35,6 +35,7 @@ File #VAR1_BOLD# could not be opened. Groups Hostname is not valid. Enter a valid host name or IP address. + Some 3rd party plugins have been moved to the new plugin folder #VAR1_BOLD#. Please check the functionality of these plugins after the update. Install Admidio Installation The database already contains an Admidio installation. An additional installation is not possible. @@ -60,6 +61,9 @@ Update to version #VAR1# Update process successful This is a beta version of Admidio.\n\nUsage can be risky due to possible instability and data loss. Please use as test environment only! + Some old admidio plugin folders could not be deleted from the old plugin folder #VAR1_BOLD#.\nPlease check the folder #VAR2_BOLD# within your Admidio installation and delete the old plugin folders manually and delete the old adm_plugins folder afterward. + The old plugin folder #VAR1_BOLD# could not be deleted.\nPlease check the folder #VAR2_BOLD# within your Admidio installation and delete the old adm_plugins folder manually. + Some 3rd party plugin folders could not be moved to the new plugin folder #VAR1_BOLD#.\nPlease check the folder #VAR2_BOLD# within your Admidio installation and move the 3rd party plugin folders manually and delete the old adm_plugins folder afterward. This assistant helps you to set up the Admidio member management. All necessary data will be requested so that the system can be fully set up and you can log in as an administrator.\n\nIf you have questions or problems with the installation, please check #VAR1#our installation instructions#VAR2# or contact us at #VAR3#our support forum#VAR4#. You have already updated the directories of Admidio with a new version. Now the database has to be updated from the current version #VAR2# to the version #VAR1#, so that Admidio can run with the new version.\n\nIf you have questions or problems with the update, please check #VAR3#our update instruction#VAR4# or contact #VAR5#our support forum#VAR6#. Welcome to the installation of Admidio diff --git a/src/InstallationUpdate/Service/UpdateStepsCode.php b/src/InstallationUpdate/Service/UpdateStepsCode.php index 580e8b7b14..bc7aa2668c 100644 --- a/src/InstallationUpdate/Service/UpdateStepsCode.php +++ b/src/InstallationUpdate/Service/UpdateStepsCode.php @@ -16,9 +16,11 @@ use Admidio\Infrastructure\Database; use Admidio\Infrastructure\Entity\Text; use DateTime; +use PDOException; use Ramsey\Uuid\Uuid; use Admidio\Infrastructure\Exception; use RuntimeException; +use UnexpectedValueException; // this must be declared for backwards compatibility. Can be removed if update scripts don't use it anymore const TBL_DATES = TABLE_PREFIX . '_dates'; @@ -44,7 +46,82 @@ public static function setDatabase(Database $database) self::$db = $database; } - public static function updateStep51InstallOverviewPlugins() + public static function updateStep51CheckFor3rdPartyPlugins(): void + { + global $gLogger, $gL10n; + + $arrayOldOverviewPlugins = array('announcement-list', 'birthday', 'calendar', 'event-list', 'latest-documents-files', 'login_form', 'random_photo', 'who-is-online'); + $oldFolderPluginPath = ADMIDIO_PATH . '/adm_plugins'; + $gWarnOldPlugins = false; + $gWarn3rdPartyPlugins = false; + $gInfo3rdPartyPlugins = false; + $gWarnOldPluginsFolder = false; + + // get all folders inside the adm_plugins folder + $pluginFolders = FileSystemUtils::getDirectoryContent($oldFolderPluginPath, false, true, array(FileSystemUtils::CONTENT_TYPE_DIRECTORY)); + foreach ($pluginFolders as $oldPluginPath => $type) { + $folderName = basename($oldPluginPath); + if (in_array($folderName, $arrayOldOverviewPlugins)) { + // the old plugin is no longer supported, so we remove it + try { + FileSystemUtils::deleteDirectoryIfExists($oldPluginPath, true); + } catch (Exception|RuntimeException|UnexpectedValueException $exception) { + // no rights to delete the old folder, then continue the update process + $gWarnOldPlugins = true; + continue; + } + } else { + // there is a 3rd party plugin installed, so we try to move it to the new plugin folder + $newPluginPath = ADMIDIO_PATH . FOLDER_PLUGINS . DIRECTORY_SEPARATOR . $folderName; + try { + FileSystemUtils::moveDirectory($oldPluginPath, $newPluginPath); + // now we need to check if there is a menu entry for this plugin and if yes we need to update the path by replacing adm_plugins with plugins + $sql = 'UPDATE ' . TBL_MENU . ' SET men_url = REPLACE(men_url, \'adm_plugins/' . $folderName . '\', \'' . DIRECTORY_SEPARATOR . FOLDER_PLUGINS . DIRECTORY_SEPARATOR . $folderName . '\') WHERE men_url LIKE \'%adm_plugins/' . $folderName . '%\' '; + self::$db->queryPrepared($sql); + $gInfo3rdPartyPlugins = true; + } catch (Exception|PDOException|RuntimeException|UnexpectedValueException $exception) { + // no rights to move the old folder, then continue the update process + $gWarn3rdPartyPlugins = true; + continue; + } + } + } + + if ($gWarnOldPlugins) { + $gLogger->warning($gL10n->get('INS_WARNING_OLD_ADM_PLUGINS_COULD_NOT_BE_DELETED', array('adm_plugins', 'adm_plugins'))); + } + if ($gWarn3rdPartyPlugins) { + $gLogger->warning($gL10n->get('INS_WARNING_3RD_PARRTY_PLUGINS_COULD_NOT_BE_MOVED', array('plugins', 'adm_plugins'))); + } + if ($gInfo3rdPartyPlugins) { + $gLogger->info($gL10n->get('INS_INFO_3RD_PARRTY_PLUGINS_HAVE_BEEN_MOVED', array('plugins'))); + } + + if (!$gWarnOldPlugins && !$gWarn3rdPartyPlugins) { + // if nothing happened we can delete the old adm_plugins folder + try { + FileSystemUtils::deleteDirectoryIfExists($oldFolderPluginPath, false); + } catch (Exception|RuntimeException|UnexpectedValueException $exception) { + // no rights to delete the old folder, then continue the update process + // but warn the user that the folder could not be deleted + $gWarnOldPluginsFolder = true; + $gLogger->warning($gL10n->get('INS_WARNING_OLD_ADM_PLUGINS_FOLDER_COULD_NOT_BE_DELETED', array('adm_plugins', 'adm_plugins'))); + } + } + + // set a cookie to show the warnings/information after the update process + if ($gWarnOldPlugins || $gWarn3rdPartyPlugins || $gWarnOldPluginsFolder || $gInfo3rdPartyPlugins) { + $cookieValue = array( + 'warn_old_plugins' => $gWarnOldPlugins, + 'warn_3rd_party_plugins' => $gWarn3rdPartyPlugins, + 'warn_old_plugins_folder' => $gWarnOldPluginsFolder, + 'info_3rd_party_plugins' => $gInfo3rdPartyPlugins + ); + setcookie('adm_update_plugins_warnings', json_encode($cookieValue), time() + 3600, '/'); + } + } + + public static function updateStep51InstallOverviewPlugins(): void { $pluginManager = new PluginManager(); $plugins = $pluginManager->getAvailablePlugins(); From 945aee1b74362a6a558754b5ef71b04052bfee30 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sun, 11 Jan 2026 20:28:21 +0100 Subject: [PATCH 077/109] refactor: rename demo folder to demo_data in composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index d85dc42235..4a0be99429 100644 --- a/composer.json +++ b/composer.json @@ -76,7 +76,7 @@ "!plugins/login_form", "!plugins/random_photo", "!plugins/who-is-online", - "demo", + "demo_data", "!vendor/*", "vendor/maennchen/zipstream-php/test", "vendor/markbaker/complex/examples", From 4da844e0d980255ab750300015c9e61f3100f209 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sun, 11 Jan 2026 20:33:32 +0100 Subject: [PATCH 078/109] fix: use correct path for demo data of am_my_files --- demo_data/build.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo_data/build.php b/demo_data/build.php index dec00c9f3c..c033f17471 100644 --- a/demo_data/build.php +++ b/demo_data/build.php @@ -82,7 +82,7 @@ function prepareAdmidioDataFolder(): void } closedir($dh); - FileSystemUtils::copyDirectory(ADMIDIO_PATH . '/demo/adm_my_files', ADMIDIO_PATH . FOLDER_DATA, array('overwriteContent' => true)); + FileSystemUtils::copyDirectory(ADMIDIO_PATH . '/demo_data/adm_my_files', ADMIDIO_PATH . FOLDER_DATA, array('overwriteContent' => true)); } /** From 097a7803c7494db9ba1753719b3f39760468efe8 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sun, 25 Jan 2026 18:34:30 +0100 Subject: [PATCH 079/109] - feat: implement com_overview_plugin column in components table instead of using ADM_PLUGIN and PLUGIN as com_name - feat: implement a check if the old am_plugins folder still exists before performing updateStep51CheckFor3rdPartyPlugins --- install/db_scripts/db.sql | 1 + install/db_scripts/update_5_1.xml | 11 +++++----- .../db_scripts/update_1_0.xml | 2 +- plugins/Birthday/db_scripts/update_1_0.xml | 2 +- plugins/Calendar/db_scripts/update_1_0.xml | 2 +- plugins/EventList/db_scripts/update_1_0.xml | 2 +- .../db_scripts/update_1_0.xml | 2 +- plugins/LoginForm/db_scripts/update_1_0.xml | 2 +- plugins/RandomPhoto/db_scripts/update_1_0.xml | 2 +- plugins/WhoIsOnline/db_scripts/update_1_0.xml | 2 +- src/Components/Entity/ComponentUpdate.php | 2 +- src/Infrastructure/Plugins/PluginAbstract.php | 22 +++++++++---------- .../Service/UpdateStepsCode.php | 5 +++++ 13 files changed, 32 insertions(+), 25 deletions(-) diff --git a/install/db_scripts/db.sql b/install/db_scripts/db.sql index 73e5e703e6..66a8c8669c 100644 --- a/install/db_scripts/db.sql +++ b/install/db_scripts/db.sql @@ -160,6 +160,7 @@ CREATE TABLE %PREFIX%_components com_update_step integer NOT NULL DEFAULT 0, com_update_completed boolean NOT NULL DEFAULT true, com_timestamp_installed timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + com_overview_plugin boolean NOT NULL DEFAULT false, PRIMARY KEY (com_id) ) ENGINE = InnoDB diff --git a/install/db_scripts/update_5_1.xml b/install/db_scripts/update_5_1.xml index 9b40bfe286..6596b07000 100644 --- a/install/db_scripts/update_5_1.xml +++ b/install/db_scripts/update_5_1.xml @@ -5,10 +5,11 @@ INSERT INTO %PREFIX%_menu (men_com_id, men_men_id_parent, men_uuid, men_node, men_order, men_standard, men_name_intern, men_url, men_icon, men_name, men_description) VALUES ((SELECT com_id FROM %PREFIX%_components WHERE com_name_intern = 'PLUGINS'), 2, %UUID%, false, 5, true, 'plugins', '/modules/plugins.php', 'puzzle', 'SYS_PLUGIN_MANAGER', 'SYS_PLUGIN_MANAGER_DESC') UPDATE %PREFIX%_menu SET men_url = REPLACE(men_url, '/adm_plugins', 'plugins') WHERE men_url LIKE '%/adm_plugins%' - UpdateStepsCode::updateStep51InstallOverviewPlugins - UpdateStepsCode::updateStep51CheckFor3rdPartyPlugins - ALTER TABLE %PREFIX%_preferences MODIFY COLUMN prf_name varchar(100) NOT NULL - ALTER TABLE %PREFIX%_preferences ALTER COLUMN prf_name TYPE varchar(100) - ALTER TABLE %PREFIX%_preferences ALTER COLUMN prf_name SET NOT NULL + ALTER TABLE %PREFIX%_components ADD COLUMN com_overview_plugin boolean not null default false + UpdateStepsCode::updateStep51InstallOverviewPlugins + UpdateStepsCode::updateStep51CheckFor3rdPartyPlugins + ALTER TABLE %PREFIX%_preferences MODIFY COLUMN prf_name varchar(100) NOT NULL + ALTER TABLE %PREFIX%_preferences ALTER COLUMN prf_name TYPE varchar(100) + ALTER TABLE %PREFIX%_preferences ALTER COLUMN prf_name SET NOT NULL stop diff --git a/plugins/AnnouncementList/db_scripts/update_1_0.xml b/plugins/AnnouncementList/db_scripts/update_1_0.xml index 6032748a4f..d293505ece 100644 --- a/plugins/AnnouncementList/db_scripts/update_1_0.xml +++ b/plugins/AnnouncementList/db_scripts/update_1_0.xml @@ -1,6 +1,6 @@ - UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'AnnouncementList' + UPDATE %PREFIX%_components SET com_overview_plugin = 1 WHERE com_type = 'PLUGIN' AND com_name_intern = 'AnnouncementList' UpdateStepsCode::updateStep10RetrievePreviousSettings stop diff --git a/plugins/Birthday/db_scripts/update_1_0.xml b/plugins/Birthday/db_scripts/update_1_0.xml index 883001a52a..09169a4244 100644 --- a/plugins/Birthday/db_scripts/update_1_0.xml +++ b/plugins/Birthday/db_scripts/update_1_0.xml @@ -1,6 +1,6 @@ - UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'Birthday' + UPDATE %PREFIX%_components SET com_overview_plugin = 1 WHERE com_type = 'PLUGIN' AND com_name_intern = 'Birthday' UpdateStepsCode::updateStep10RetrievePreviousSettings stop diff --git a/plugins/Calendar/db_scripts/update_1_0.xml b/plugins/Calendar/db_scripts/update_1_0.xml index 5b6691e742..b71c445542 100644 --- a/plugins/Calendar/db_scripts/update_1_0.xml +++ b/plugins/Calendar/db_scripts/update_1_0.xml @@ -1,6 +1,6 @@ - UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'Calendar' + UPDATE %PREFIX%_components SET com_overview_plugin = 1 WHERE com_type = 'PLUGIN' AND com_name_intern = 'Calendar' UpdateStepsCode::updateStep10RetrievePreviousSettings stop diff --git a/plugins/EventList/db_scripts/update_1_0.xml b/plugins/EventList/db_scripts/update_1_0.xml index 250ea8f3df..4a12a79080 100644 --- a/plugins/EventList/db_scripts/update_1_0.xml +++ b/plugins/EventList/db_scripts/update_1_0.xml @@ -1,6 +1,6 @@ - UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'EventList' + UPDATE %PREFIX%_components SET com_overview_plugin = 1 WHERE com_type = 'PLUGIN' AND com_name_intern = 'EventList' UpdateStepsCode::updateStep10RetrievePreviousSettings stop diff --git a/plugins/LatestDocumentsFiles/db_scripts/update_1_0.xml b/plugins/LatestDocumentsFiles/db_scripts/update_1_0.xml index 56dfaffe72..653ffdb01b 100644 --- a/plugins/LatestDocumentsFiles/db_scripts/update_1_0.xml +++ b/plugins/LatestDocumentsFiles/db_scripts/update_1_0.xml @@ -1,6 +1,6 @@ - UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'LatestDocumentsFiles' + UPDATE %PREFIX%_components SET com_overview_plugin = 1 WHERE com_type = 'PLUGIN' AND com_name_intern = 'LatestDocumentsFiles' UpdateStepsCode::updateStep10RetrievePreviousSettings stop diff --git a/plugins/LoginForm/db_scripts/update_1_0.xml b/plugins/LoginForm/db_scripts/update_1_0.xml index aae5dfb5c4..8902e0eaae 100644 --- a/plugins/LoginForm/db_scripts/update_1_0.xml +++ b/plugins/LoginForm/db_scripts/update_1_0.xml @@ -1,6 +1,6 @@ - UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'LoginForm' + UPDATE %PREFIX%_components SET com_overview_plugin = 1 WHERE com_type = 'PLUGIN' AND com_name_intern = 'LoginForm' UpdateStepsCode::updateStep10RetrievePreviousSettings stop diff --git a/plugins/RandomPhoto/db_scripts/update_1_0.xml b/plugins/RandomPhoto/db_scripts/update_1_0.xml index 366b5fec99..02cf34e1ff 100644 --- a/plugins/RandomPhoto/db_scripts/update_1_0.xml +++ b/plugins/RandomPhoto/db_scripts/update_1_0.xml @@ -1,6 +1,6 @@ - UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'RandomPhoto' + UPDATE %PREFIX%_components SET com_overview_plugin = 1 WHERE com_type = 'PLUGIN' AND com_name_intern = 'RandomPhoto' UpdateStepsCode::updateStep10RetrievePreviousSettings stop diff --git a/plugins/WhoIsOnline/db_scripts/update_1_0.xml b/plugins/WhoIsOnline/db_scripts/update_1_0.xml index a65763df97..e82cda8412 100644 --- a/plugins/WhoIsOnline/db_scripts/update_1_0.xml +++ b/plugins/WhoIsOnline/db_scripts/update_1_0.xml @@ -1,6 +1,6 @@ - UPDATE %PREFIX%_components SET com_type = 'ADM_PLUGIN' WHERE com_type = 'PLUGIN' AND com_name_intern = 'WhoIsOnline' + UPDATE %PREFIX%_components SET com_overview_plugin = 1 WHERE com_type = 'PLUGIN' AND com_name_intern = 'WhoIsOnline' UpdateStepsCode::updateStep10RetrievePreviousSettings stop diff --git a/src/Components/Entity/ComponentUpdate.php b/src/Components/Entity/ComponentUpdate.php index 62d929263a..c51d4e2070 100644 --- a/src/Components/Entity/ComponentUpdate.php +++ b/src/Components/Entity/ComponentUpdate.php @@ -84,7 +84,7 @@ private function getXmlObject(int $mainVersion, int $minorVersion): SimpleXMLEle $gLogger->warning($message, array('filePath' => $updateFile)); throw new UnexpectedValueException($message); - } elseif ($this->getValue('com_type') === 'PLUGIN' || $this->getValue('com_type') === 'ADM_PLUGIN') { + } elseif ($this->getValue('com_type') === 'PLUGIN') { $updateFile = ADMIDIO_PATH . FOLDER_PLUGINS . '/' . $this->getValue('com_name_intern') . '/db_scripts/update_'.$mainVersion.'_'.$minorVersion.'.xml'; if (is_file($updateFile)) { diff --git a/src/Infrastructure/Plugins/PluginAbstract.php b/src/Infrastructure/Plugins/PluginAbstract.php index 7cb57c53a0..763a55c667 100644 --- a/src/Infrastructure/Plugins/PluginAbstract.php +++ b/src/Infrastructure/Plugins/PluginAbstract.php @@ -217,13 +217,13 @@ public static function getInstance(): PluginAbstract if (self::$instances[$class]->isInstalled()) { global $gDb; // get the component id of the plugin - $sql = 'SELECT com_id FROM ' . TBL_COMPONENTS . ' WHERE com_name = ? AND (com_type = ? OR com_type = ?)'; - $statement = $gDb->queryPrepared($sql, array(self::getName(), 'PLUGIN', 'ADM_PLUGIN')); + $sql = 'SELECT com_id FROM ' . TBL_COMPONENTS . ' WHERE com_name = ? AND com_type = ?'; + $statement = $gDb->queryPrepared($sql, array(self::getName(), 'PLUGIN')); self::$pluginComId = (int)$statement->fetchColumn(); // get the installed version of the plugin - $sql = 'SELECT com_version FROM ' . TBL_COMPONENTS . ' WHERE com_name = ? AND (com_type = ? OR com_type = ?)'; - $statement = $gDb->queryPrepared($sql, array(self::getName(), 'PLUGIN', 'ADM_PLUGIN')); + $sql = 'SELECT com_version FROM ' . TBL_COMPONENTS . ' WHERE com_name = ? AND com_type = ?'; + $statement = $gDb->queryPrepared($sql, array(self::getName(), 'PLUGIN')); self::$version = (string)$statement->fetchColumn(); } @@ -522,8 +522,8 @@ public static function isInstalled(): bool { global $gDb; // check if the plugin exists in components database table - $sql = 'SELECT COUNT(*) AS count FROM ' . TBL_COMPONENTS . ' WHERE com_name = ? AND (com_type = ? OR com_type = ?)'; - $statement = $gDb->queryPrepared($sql, array(self::getName(), 'PLUGIN', 'ADM_PLUGIN')); + $sql = 'SELECT COUNT(*) AS count FROM ' . TBL_COMPONENTS . ' WHERE com_name = ? AND com_type = ?'; + $statement = $gDb->queryPrepared($sql, array(self::getName(), 'PLUGIN')); $columns = (int)$statement->fetchColumn(); return $columns > 0; @@ -570,9 +570,9 @@ public static function isVisible(): bool public static function isOverviewPlugin(): bool { global $gDb; - // check if the plugin exists in components database table and is of type 'ADM_PLUGIN' - $sql = 'SELECT COUNT(*) AS count FROM ' . TBL_COMPONENTS . ' WHERE com_name = ? AND com_type = ?'; - $statement = $gDb->queryPrepared($sql, array(self::getName(), 'ADM_PLUGIN')); + // check if the plugin exists in components database table and is of type 'PLUGIN' and has overview flag + $sql = 'SELECT COUNT(*) AS count FROM ' . TBL_COMPONENTS . ' WHERE com_name = ? AND com_type = ? AND com_overview_plugin = ?'; + $statement = $gDb->queryPrepared($sql, array(self::getName(), 'PLUGIN', true)); $columns = (int)$statement->fetchColumn(); return $columns > 0; @@ -658,8 +658,8 @@ public static function doInstall(): bool // if there is only one sql file, take it $sqlFile = $sqlFiles[0]; } else { - // if there are multiple sql files, we need to find the install file - // the install file needs to be named *install.sql + // if there are multiple sql files, we need to find the installation file + // the installation file needs to be named *install.sql foreach ($sqlFiles as $file) { if (str_contains($file, 'install')) { $sqlFile = $file; diff --git a/src/InstallationUpdate/Service/UpdateStepsCode.php b/src/InstallationUpdate/Service/UpdateStepsCode.php index bc7aa2668c..6497a8045f 100644 --- a/src/InstallationUpdate/Service/UpdateStepsCode.php +++ b/src/InstallationUpdate/Service/UpdateStepsCode.php @@ -57,6 +57,11 @@ public static function updateStep51CheckFor3rdPartyPlugins(): void $gInfo3rdPartyPlugins = false; $gWarnOldPluginsFolder = false; + // check if the old adm_plugins folder exists + if (!is_dir($oldFolderPluginPath)) { + return; + } + // get all folders inside the adm_plugins folder $pluginFolders = FileSystemUtils::getDirectoryContent($oldFolderPluginPath, false, true, array(FileSystemUtils::CONTENT_TYPE_DIRECTORY)); foreach ($pluginFolders as $oldPluginPath => $type) { From 2d691d23e6453a915b52f05204412f0ddc507052 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sun, 25 Jan 2026 20:20:56 +0100 Subject: [PATCH 080/109] feat: update menu entry methods to public and enhance SQL file handling in plugin installation/uninstallation --- src/Infrastructure/Plugins/PluginAbstract.php | 125 +++++++++--------- src/UI/Presenter/PluginsPresenter.php | 27 +++- 2 files changed, 87 insertions(+), 65 deletions(-) diff --git a/src/Infrastructure/Plugins/PluginAbstract.php b/src/Infrastructure/Plugins/PluginAbstract.php index 763a55c667..2a518c6562 100644 --- a/src/Infrastructure/Plugins/PluginAbstract.php +++ b/src/Infrastructure/Plugins/PluginAbstract.php @@ -60,7 +60,7 @@ public function __wakeup() * This method is called during the installation of the plugin. * @throws Exception */ - private static function addMenuEntry(): void + public static function addMenuEntry(): void { global $gDb; @@ -86,7 +86,7 @@ private static function addMenuEntry(): void * This method is called during the uninstallation of the plugin. * @throws Exception */ - private static function removeMenuEntry(): void + public static function removeMenuEntry(): void { global $gDb; @@ -97,7 +97,6 @@ private static function removeMenuEntry(): void if ($pluginMenuEntry->readDataByColumns(array('men_name_intern' => $className))) { $pluginMenuEntry->delete(); } - } /** @@ -174,7 +173,7 @@ private function readPluginMetadata(): void } $configData = json_decode(file_get_contents($configFile), true); if ($configData === null) { - throw new Exception('Plugin configuration file is not valid JSON.'); + throw new Exception('Plugin configuration file ' . $configFile . ' is not valid JSON.'); } else { self::$name = $configData['name'] ?? ''; self::$dependencies = $configData['dependencies'] ?? array(); @@ -650,40 +649,43 @@ public static function doInstall(): bool } } - // check if the plugin has a .sql file to create the database tables - $sqlFiles = self::getStaticFiles('sql', self::$pluginPath . DIRECTORY_SEPARATOR . 'db_scripts'); - if (isset($sqlFiles) && count($sqlFiles) > 0) { - $sqlFile = null; - if (count($sqlFiles) === 1) { - // if there is only one sql file, take it - $sqlFile = $sqlFiles[0]; - } else { - // if there are multiple sql files, we need to find the installation file - // the installation file needs to be named *install.sql - foreach ($sqlFiles as $file) { - if (str_contains($file, 'install')) { - $sqlFile = $file; - break; + // check if the db_scripts folder exists + if (is_dir(self::$pluginPath . DIRECTORY_SEPARATOR . 'db_scripts')) { + // check if the plugin has a .sql file to create the database tables + $sqlFiles = self::getStaticFiles('sql', self::$pluginPath . DIRECTORY_SEPARATOR . 'db_scripts'); + if (isset($sqlFiles) && count($sqlFiles) > 0) { + $sqlFile = null; + if (count($sqlFiles) === 1) { + // if there is only one sql file, take it + $sqlFile = $sqlFiles[0]; + } else { + // if there are multiple sql files, we need to find the installation file + // the installation file needs to be named *install.sql + foreach ($sqlFiles as $file) { + if (str_contains($file, 'install')) { + $sqlFile = $file; + break; + } } } - } - if ($sqlFile !== null) { - // read data from sql install script and execute all statements to the current database - if (!is_file($sqlFile)) { - throw new Exception('INS_DATABASE_FILE_NOT_FOUND', array(basename($sqlFile), dirname($sqlFile))); - } + if ($sqlFile !== null) { + // read data from sql install script and execute all statements to the current database + if (!is_file($sqlFile)) { + throw new Exception('INS_DATABASE_FILE_NOT_FOUND', array(basename($sqlFile), dirname($sqlFile))); + } - try { - $sqlStatements = Database::getSqlStatementsFromSqlFile($sqlFile); - } catch (RuntimeException) { - throw new Exception('INS_ERROR_OPEN_FILE', array($sqlFile)); - } + try { + $sqlStatements = Database::getSqlStatementsFromSqlFile($sqlFile); + } catch (RuntimeException) { + throw new Exception('INS_ERROR_OPEN_FILE', array($sqlFile)); + } - self::toggleForeignKeyChecks(false); - foreach ($sqlStatements as $sqlStatement) { - $gDb->queryPrepared($sqlStatement); + self::toggleForeignKeyChecks(false); + foreach ($sqlStatements as $sqlStatement) { + $gDb->queryPrepared($sqlStatement); + } + self::toggleForeignKeyChecks(true); } - self::toggleForeignKeyChecks(true); } } @@ -732,38 +734,41 @@ public static function doUninstall(array $options = array()): bool global $gDb, $gSettingsManager; - // check if the plugin has a .sql file to delete the database tables - $sqlFiles = self::getStaticFiles('sql', self::$pluginPath . DIRECTORY_SEPARATOR . 'db_scripts'); - if (isset($sqlFiles) && count($sqlFiles) > 0) { - $sqlFile = null; - // if there is only a db.sql file, no uninstall script is needed - if (count($sqlFiles) > 1) { - // if there are multiple sql files, we need to find the uninstall file - // the file needs to be named *uninstall.sql - foreach ($sqlFiles as $file) { - if (str_contains($file, 'uninstall')) { - $sqlFile = $file; - break; + // check if the db_scripts folder exists + if (is_dir(self::$pluginPath . DIRECTORY_SEPARATOR . 'db_scripts')) { + // check if the plugin has a .sql file to delete the database tables + $sqlFiles = self::getStaticFiles('sql', self::$pluginPath . DIRECTORY_SEPARATOR . 'db_scripts'); + if (isset($sqlFiles) && count($sqlFiles) > 0) { + $sqlFile = null; + // if there is only a db.sql file, no uninstall script is needed + if (count($sqlFiles) > 1) { + // if there are multiple sql files, we need to find the uninstallation file + // the file needs to be named *uninstall.sql + foreach ($sqlFiles as $file) { + if (str_contains($file, 'uninstall')) { + $sqlFile = $file; + break; + } } } - } - if ($sqlFile !== null) { - // read data from sql install script and execute all statements to the current database - if (!is_file($sqlFile)) { - throw new Exception('INS_DATABASE_FILE_NOT_FOUND', array(basename($sqlFile), dirname($sqlFile))); - } + if ($sqlFile !== null) { + // read data from sql install script and execute all statements to the current database + if (!is_file($sqlFile)) { + throw new Exception('INS_DATABASE_FILE_NOT_FOUND', array(basename($sqlFile), dirname($sqlFile))); + } - try { - $sqlStatements = Database::getSqlStatementsFromSqlFile($sqlFile); - } catch (RuntimeException) { - throw new Exception('INS_ERROR_OPEN_FILE', array($sqlFile)); - } + try { + $sqlStatements = Database::getSqlStatementsFromSqlFile($sqlFile); + } catch (RuntimeException) { + throw new Exception('INS_ERROR_OPEN_FILE', array($sqlFile)); + } - self::toggleForeignKeyChecks(false); - foreach ($sqlStatements as $sqlStatement) { - $gDb->queryPrepared($sqlStatement); + self::toggleForeignKeyChecks(false); + foreach ($sqlStatements as $sqlStatement) { + $gDb->queryPrepared($sqlStatement); + } + self::toggleForeignKeyChecks(true); } - self::toggleForeignKeyChecks(true); } } diff --git a/src/UI/Presenter/PluginsPresenter.php b/src/UI/Presenter/PluginsPresenter.php index f7e5eaa7a8..1ed71e98c1 100644 --- a/src/UI/Presenter/PluginsPresenter.php +++ b/src/UI/Presenter/PluginsPresenter.php @@ -117,11 +117,28 @@ public function prepareData(): void // add actions for the plugin if ($interface->isInstalled()) { // add showPreferences action - $templateRow['actions'][] = array( - 'url' => SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/preferences.php', array('panel' => preg_replace('/\s+/', '_', preg_replace('/[^a-z0-9_ ]/', '', strtolower(Language::translateIfTranslationStrId($interface->getName())))))), - 'icon' => 'bi bi-gear', - 'tooltip' => $gL10n->get('SYS_PLUGIN_PREFERENCES') - ); + // if there is a custom defined preferences file in the metadata then use this file + if (isset($interface->getMetadata()['preferencesFile']) && !empty($interface->getMetadata()['preferencesFile'])) { + // check, if the file starts with a / or \\ indicating an absolute path, if so we don't need to add a directory separator + if (str_starts_with($interface->getMetadata()['preferencesFile'], '/') || str_starts_with($interface->getMetadata()['preferencesFile'], '\\')) { + $url = ADMIDIO_URL . FOLDER_PLUGINS . DIRECTORY_SEPARATOR . $interface->getComponentName() . $interface->getMetadata()['preferencesFile']; + } else { + $url = ADMIDIO_URL . FOLDER_PLUGINS . DIRECTORY_SEPARATOR . $interface->getComponentName() . DIRECTORY_SEPARATOR . $interface->getMetadata()['preferencesFile']; + } + $templateRow['actions'][] = array( + 'url' => $url, + 'icon' => 'bi bi-gear', + 'tooltip' => $gL10n->get('SYS_PLUGIN_PREFERENCES') + ); + } else { + // else use the preferences panel based on the plugin name + $templateRow['actions'][] = array( + 'url' => SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/preferences.php', array('panel' => preg_replace('/\s+/', '_', preg_replace('/[^a-z0-9_ ]/', '', strtolower(Language::translateIfTranslationStrId($interface->getName())))))), + 'icon' => 'bi bi-gear', + 'tooltip' => $gL10n->get('SYS_PLUGIN_PREFERENCES') + ); + } + // add update action if an update is available if ($interface->isUpdateAvailable()) { $templateRow['actions'][] = array( From ed83cc58cb603f45691913a73c62908cfc4fc16d Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sun, 25 Jan 2026 20:41:38 +0100 Subject: [PATCH 081/109] feat: add parameters to doInstall and doUninstall methods to control if a menu entry should be created or if the plugin creates the necessary entries by itself --- src/Infrastructure/Plugins/PluginAbstract.php | 10 ++++++---- src/Infrastructure/Plugins/PluginInterface.php | 4 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Infrastructure/Plugins/PluginAbstract.php b/src/Infrastructure/Plugins/PluginAbstract.php index 2a518c6562..2b3b261c77 100644 --- a/src/Infrastructure/Plugins/PluginAbstract.php +++ b/src/Infrastructure/Plugins/PluginAbstract.php @@ -622,7 +622,7 @@ private static function toggleForeignKeyChecks(bool $enable): void * @return bool * @throws Exception */ - public static function doInstall(): bool + public static function doInstall(bool $addMenuEntry = true): bool { global $gDb, $gSettingsManager; @@ -704,7 +704,7 @@ public static function doInstall(): bool self::$version = self::$metadata['version']; // add the plugin menu entry to the database - if (!self::isOverviewPlugin()) { + if (!self::isOverviewPlugin() && $addMenuEntry) { self::addMenuEntry(); } @@ -721,7 +721,7 @@ public static function doInstall(): bool * @throws Exception * @throws InvalidArgumentException */ - public static function doUninstall(array $options = array()): bool + public static function doUninstall(bool $removeMenuEntry = true, array $options = array()): bool { if (!is_array($options)) { throw new InvalidArgumentException('Options must be an "array".'); @@ -783,7 +783,9 @@ public static function doUninstall(array $options = array()): bool $gSettingsManager->resetAll(); // remove the plugin menu entry - self::removeMenuEntry(); + if ($removeMenuEntry) { + self::removeMenuEntry(); + } // delete the plugin from the components table $plugin = new Component($gDb, self::$pluginComId); diff --git a/src/Infrastructure/Plugins/PluginInterface.php b/src/Infrastructure/Plugins/PluginInterface.php index 7a256c37b1..1204f764a7 100644 --- a/src/Infrastructure/Plugins/PluginInterface.php +++ b/src/Infrastructure/Plugins/PluginInterface.php @@ -124,7 +124,7 @@ public static function doClassAutoload(): bool; * @return bool * @throws Exception */ - public static function doInstall(): bool; + public static function doInstall(bool $addMenuEntry = true): bool; /** * @param array $options @@ -132,7 +132,7 @@ public static function doInstall(): bool; * @throws Exception * @throws InvalidArgumentException */ - public static function doUninstall(array $options = array()): bool; + public static function doUninstall(bool $removeMenuEntry = true, array $options = array()): bool; /** * @return bool From 3b8a4aa897ea5fd1cf9cd2f0598e7e8c8bb1dae4 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sun, 1 Feb 2026 11:56:37 +0100 Subject: [PATCH 082/109] feat: - stop initialising preference panel if the plugin implements an own preferences page defined by config key 'preferencesFile' - implement autoloading of plugins - redesign installation/update procedure based on new config key 'overviewPlugin' --- composer.json | 3 +- install/install_steps/start_installation.php | 8 +- src/Infrastructure/Plugins/PluginAbstract.php | 109 +++++++++++++++--- .../Plugins/PluginInterface.php | 2 +- .../Service/UpdateStepsCode.php | 8 +- 5 files changed, 105 insertions(+), 25 deletions(-) diff --git a/composer.json b/composer.json index 4a0be99429..808ee57def 100644 --- a/composer.json +++ b/composer.json @@ -50,8 +50,7 @@ }, "autoload": { "psr-4": { - "Admidio\\": "src/", - "Plugins\\": "plugins/" + "Admidio\\": "src/" }, "classmap": [ "system/classes/", diff --git a/install/install_steps/start_installation.php b/install/install_steps/start_installation.php index ccc2558f2e..9d3564cfa9 100644 --- a/install/install_steps/start_installation.php +++ b/install/install_steps/start_installation.php @@ -288,12 +288,12 @@ // install all overview plugins $pluginManager = new PluginManager(); $plugins = $pluginManager->getAvailablePlugins(); -$arrayOverviewPlugins = array('AnnouncementList', 'Birthday', 'Calendar', 'EventList', 'LatestDocumentsFiles', 'LoginForm', 'RandomPhoto', 'WhoIsOnline'); -foreach ($plugins as $pluginName => $plugin) { - if (in_array($pluginName, $arrayOverviewPlugins)) { +foreach ($plugins as $plugin) { + $instance = $plugin['interface']::getInstance(); + if (isset($instance->getMetadata()['overviewPlugin']) && $instance->getMetadata()['overviewPlugin'] === true) { // Install the overview plugin - $plugin['interface']::getInstance()->doInstall(); + $instance->doInstall(); } } diff --git a/src/Infrastructure/Plugins/PluginAbstract.php b/src/Infrastructure/Plugins/PluginAbstract.php index 2b3b261c77..8b84204a75 100644 --- a/src/Infrastructure/Plugins/PluginAbstract.php +++ b/src/Infrastructure/Plugins/PluginAbstract.php @@ -9,6 +9,8 @@ use Admidio\Infrastructure\Exception; use Admidio\Infrastructure\Database; +use Composer\Autoload\ClassLoader; + use InvalidArgumentException; use RecursiveDirectoryIterator; use RecursiveIteratorIterator; @@ -106,9 +108,40 @@ public static function removeMenuEntry(): void */ public static function initPreferencePanelCallback(): void { - // find a preference panel for this plugin - $preferencesFile = self::getPluginPath() . '/classes/Presenter/' . basename(self::getPluginPath()) . 'PreferencesPresenter.php'; - $preferencesClass = is_file($preferencesFile) ? self::getClassNameFromFile($preferencesFile) : null; + $callingPlugin = admFuncVariableIsValid($_GET, 'panel', 'string', array('defaultValue' => '')); + + $psr4 = self::$metadata['autoload']['psr-4'] ?? null; + $preferencesFile = self::$metadata['preferencesFile'] ?? null; + + // if a preferences file is defined in the metadata, the plugin handles the preferences itself + if (isset($preferencesFile)) { + return; + } + + // check if psr4 autoload mappings are defined, otherwise we cannot find the presenter class + if (!is_array($psr4)) { + return; + } + + // look for presenter class path in the psr4 autoload mappings + $preferencesClass = null; + + foreach ($psr4 as $prefix => $relativePath) { + if (str_contains(strtolower($prefix), $callingPlugin)) { + $presenterBasePath = self::getPluginPath() . DIRECTORY_SEPARATOR . $relativePath; + // now loop over all files in the presenter path to find a preferences presenter + $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($presenterBasePath)); + foreach ($it as $file) { + if (!$file->isFile() || !str_contains($file->getFilename(), 'PreferencesPresenter.php')) { + continue; + } + $preferencesFile = $file->getPathname(); + $preferencesClass = self::getClassNameFromFile($preferencesFile); + break; + } + } + } + if (isset($preferencesClass) && class_exists($preferencesClass)) { // get the function name for the preferences panel $functionName = 'create' . basename(self::getPluginPath()) . 'Form'; @@ -202,7 +235,6 @@ public static function getInstance(): PluginAbstract $class = get_called_class(); if (!array_key_exists($class, self::$instances)) { self::$instances[$class] = new $class(); - self::$instances[$class]->doClassAutoload(); } // set the plugin path to the folder of this class @@ -212,6 +244,9 @@ public static function getInstance(): PluginAbstract // read the plugin metadata self::$instances[$class]->readPluginMetadata(); + // after we have the plugin path and metadata, we can do the class autoload + self::$instances[$class]->doClassAutoload($class); + // check if the plugin is installed if (self::$instances[$class]->isInstalled()) { global $gDb; @@ -448,10 +483,6 @@ public static function checkDependencies(): bool return true; } - // ensure Composer’s PSR‑4 autoloader is registered - if (!self::doClassAutoload()) { - throw new RuntimeException('Could not load Composer autoloader at ' . ADMIDIO_PATH . '/vendor/autoload.php'); - } $missing = array(); // loop over all dependencies and check if they are available @@ -590,17 +621,67 @@ public static function isUpdateAvailable(): bool * @return bool * @throws Exception */ - public static function doClassAutoload(): bool + public static function doClassAutoload(string $class): bool { - $autoloadPath = ADMIDIO_PATH . '/vendor/autoload.php'; + // Register plugin PSR-4 autoload mappings from plugin metadata (no DB required). + // Each plugin can define in its JSON: + // { + // "autoload": { "psr-4": { "Vendor\\Plugin\\": "classes/" } } + // } + try { + if (class_exists(ClassLoader::class)) { + $loaders = ClassLoader::getRegisteredLoaders(); + $composerLoader = reset($loaders); - if (is_file($autoloadPath)) { - require_once($autoloadPath); + if ($composerLoader) { + $existingPrefixes = $composerLoader->getPrefixesPsr4(); - return true; + $instance = self::$instances[$class]; + + // check if the instance is valid + if (!$instance instanceof PluginAbstract) { + return false; + } + + // read the plugin metadata if not already done + if (empty($instance::$metadata)) { + $instance->readPluginMetadata(); + } + + // check if psr4 autoload mappings are defined + $psr4 = $instance::$metadata['autoload']['psr-4'] ?? null; + if (!is_array($psr4)) { + return false; + } + + // register each PSR-4 mapping for this plugin + foreach ($psr4 as $prefix => $relativePath) { + if (!is_string($prefix) || !is_string($relativePath)) { + continue; + } + + $prefix = rtrim($prefix, '\\') . '\\'; + $absolutePath = $instance::$pluginPath . DIRECTORY_SEPARATOR . trim($relativePath, "/\\"); + + if (!is_dir($absolutePath)) { + continue; + } + + // already registered? + if (isset($existingPrefixes[$prefix]) && in_array($absolutePath, $existingPrefixes[$prefix], true)) { + continue; + } + + // register the PSR-4 mapping for this plugin + $composerLoader->addPsr4($prefix, $absolutePath, true); + } + } + } + } catch (\Throwable $e) { + throw new Exception('Error during plugin class autoload registration: ' . $e->getMessage()); } - return false; + return true; } /** diff --git a/src/Infrastructure/Plugins/PluginInterface.php b/src/Infrastructure/Plugins/PluginInterface.php index 1204f764a7..9f5fd52bbd 100644 --- a/src/Infrastructure/Plugins/PluginInterface.php +++ b/src/Infrastructure/Plugins/PluginInterface.php @@ -118,7 +118,7 @@ public static function isUpdateAvailable(): bool; * @return bool * @throws Exception */ - public static function doClassAutoload(): bool; + public static function doClassAutoload(string $class): bool; /** * @return bool diff --git a/src/InstallationUpdate/Service/UpdateStepsCode.php b/src/InstallationUpdate/Service/UpdateStepsCode.php index 6497a8045f..02b71bdc02 100644 --- a/src/InstallationUpdate/Service/UpdateStepsCode.php +++ b/src/InstallationUpdate/Service/UpdateStepsCode.php @@ -130,12 +130,12 @@ public static function updateStep51InstallOverviewPlugins(): void { $pluginManager = new PluginManager(); $plugins = $pluginManager->getAvailablePlugins(); - $arrayOverviewPlugins = array('AnnouncementList', 'Birthday', 'Calendar', 'EventList', 'LatestDocumentsFiles', 'LoginForm', 'RandomPhoto', 'WhoIsOnline'); - foreach ($plugins as $pluginName => $plugin) { - if (in_array($pluginName, $arrayOverviewPlugins)) { + foreach ($plugins as $plugin) { + $instance = $plugin['interface']::getInstance(); + if (isset($instance->getMetadata()['overviewPlugin']) && $instance->getMetadata()['overviewPlugin'] === true) { // Install the overview plugin - $plugin['interface']::getInstance()->doInstall(); + $instance->doInstall(); } } } From 24a6010bd3472034e0ed632bfd88219ca28e7f41 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sun, 1 Feb 2026 13:15:36 +0100 Subject: [PATCH 083/109] fix installation process of plugins --- src/Infrastructure/Plugins/PluginAbstract.php | 30 +++++++++++++++---- src/Infrastructure/Plugins/PluginManager.php | 8 +++++ .../Service/UpdateStepsCode.php | 5 ++++ 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/Infrastructure/Plugins/PluginAbstract.php b/src/Infrastructure/Plugins/PluginAbstract.php index 8b84204a75..08f663d556 100644 --- a/src/Infrastructure/Plugins/PluginAbstract.php +++ b/src/Infrastructure/Plugins/PluginAbstract.php @@ -772,11 +772,31 @@ public static function doInstall(bool $addMenuEntry = true): bool // install the plugin $componentUpdateHandle = new ComponentUpdate($gDb); - $componentUpdateHandle->readDataByColumns(array('com_type' => 'PLUGIN', 'com_name' => self::getName(), 'com_name_intern' => basename(self::$pluginPath))); - // define the update class name for the plugin - // if the class does not exist, it will be ignored when performing updatePlugin() - $updateStepCodeNamespace = 'Plugins\\' . basename(self::$pluginPath) . '\\classes\\Service\\'; - $componentUpdateHandle->updatePlugin(self::$metadata['version'], $updateStepCodeNamespace); + $componentUpdateHandle->readDataByColumns( + array( + 'com_type' => 'PLUGIN', + 'com_name' => self::getName(), + 'com_name_intern' => basename(self::$pluginPath), + 'com_overview_plugin' => self::$metadata['overviewPlugin'] + ) + ); + + // after we have the plugin path and metadata, we can do the class autoload + self::doClassAutoload(get_called_class()); + // check if psr4 autoload mappings are defined + $psr4 = self::$metadata['autoload']['psr-4'] ?? null; + if (is_array($psr4) && count($psr4) > 0) { + // define the update class namespace for the plugin + foreach ($psr4 as $prefix => $relativePath) { + if (!is_string($prefix) || !is_string($relativePath)) { + continue; + } + + // if the class does not exist, it will be ignored when performing updatePlugin() + $updateStepCodeNamespace = $prefix . 'Service\\'; + $componentUpdateHandle->updatePlugin(self::$metadata['version'], $updateStepCodeNamespace); + } + } // set the new component id of the plugin self::$pluginComId = $componentUpdateHandle->getValue('com_id'); diff --git a/src/Infrastructure/Plugins/PluginManager.php b/src/Infrastructure/Plugins/PluginManager.php index cadea57594..8b5cf17d98 100644 --- a/src/Infrastructure/Plugins/PluginManager.php +++ b/src/Infrastructure/Plugins/PluginManager.php @@ -34,6 +34,14 @@ public function getAvailablePlugins() : array|object if (is_dir($pluginFolder)) { $pluginClassFile = $pluginFolder . DIRECTORY_SEPARATOR . 'classes' . DIRECTORY_SEPARATOR . $entry . '.php'; $className = is_file($pluginClassFile) ? $this->getClassNameFromFile($pluginClassFile) : null; + + // The classname only contains the namespace of the plugin itself, so we need a way to find the class to get an instance of it. + // The problem is, that if the plugin isn't installed yet, we cannot use autoloading to find the class. + // Therefore, we check if the class exists first. If not, we include the file manually. + if ($className !== null && !class_exists($className)) { + include_once $pluginClassFile; + } + $instance = $className != null ? $className::getInstance() : null; // find the main plugin file diff --git a/src/InstallationUpdate/Service/UpdateStepsCode.php b/src/InstallationUpdate/Service/UpdateStepsCode.php index 02b71bdc02..6f8b7b7baf 100644 --- a/src/InstallationUpdate/Service/UpdateStepsCode.php +++ b/src/InstallationUpdate/Service/UpdateStepsCode.php @@ -128,6 +128,11 @@ public static function updateStep51CheckFor3rdPartyPlugins(): void public static function updateStep51InstallOverviewPlugins(): void { + global $gDb; + + // because we added the new column com_overview_plugin to the components table before, we need to reload the database columns + $gDb->initializeTableColumnProperties(); + $pluginManager = new PluginManager(); $plugins = $pluginManager->getAvailablePlugins(); From d99476bc1a74f95bcb269a2b27174e94d42d73ad Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sun, 1 Feb 2026 13:18:43 +0100 Subject: [PATCH 084/109] refactor: redesign calendar plugin --- plugins/{Calendar/Calendar.json => calendar/calendar.json} | 6 ++++++ plugins/{Calendar => calendar}/classes/Calendar.php | 2 +- .../classes/Presenter/CalendarPreferencesPresenter.php | 4 ++-- .../classes/Service/UpdateStepsCode.php | 4 ++-- plugins/{Calendar => calendar}/db_scripts/update_1_0.xml | 0 plugins/{Calendar => calendar}/index.php | 2 +- plugins/{Calendar => calendar}/languages/bg.xml | 0 plugins/{Calendar => calendar}/languages/da.xml | 0 plugins/{Calendar => calendar}/languages/de-DE.xml | 0 plugins/{Calendar => calendar}/languages/de.xml | 0 plugins/{Calendar => calendar}/languages/el.xml | 0 plugins/{Calendar => calendar}/languages/en.xml | 0 plugins/{Calendar => calendar}/languages/es.xml | 0 plugins/{Calendar => calendar}/languages/et.xml | 0 plugins/{Calendar => calendar}/languages/fi.xml | 0 plugins/{Calendar => calendar}/languages/fr.xml | 0 plugins/{Calendar => calendar}/languages/hu.xml | 0 plugins/{Calendar => calendar}/languages/nb.xml | 0 plugins/{Calendar => calendar}/languages/nl.xml | 0 plugins/{Calendar => calendar}/languages/pl.xml | 0 plugins/{Calendar => calendar}/languages/pt-BR.xml | 0 plugins/{Calendar => calendar}/languages/pt.xml | 0 plugins/{Calendar => calendar}/languages/ru.xml | 0 plugins/{Calendar => calendar}/languages/sv.xml | 0 plugins/{Calendar => calendar}/languages/uk.xml | 0 plugins/{Calendar => calendar}/languages/zh.xml | 0 .../{Calendar => calendar}/templates/plugin.calendar.tpl | 0 .../templates/preferences.plugin.calendar.tpl | 0 28 files changed, 12 insertions(+), 6 deletions(-) rename plugins/{Calendar/Calendar.json => calendar/calendar.json} (96%) rename plugins/{Calendar => calendar}/classes/Calendar.php (99%) rename plugins/{Calendar => calendar}/classes/Presenter/CalendarPreferencesPresenter.php (98%) rename plugins/{Calendar => calendar}/classes/Service/UpdateStepsCode.php (98%) rename plugins/{Calendar => calendar}/db_scripts/update_1_0.xml (100%) rename plugins/{Calendar => calendar}/index.php (95%) rename plugins/{Calendar => calendar}/languages/bg.xml (100%) rename plugins/{Calendar => calendar}/languages/da.xml (100%) rename plugins/{Calendar => calendar}/languages/de-DE.xml (100%) rename plugins/{Calendar => calendar}/languages/de.xml (100%) rename plugins/{Calendar => calendar}/languages/el.xml (100%) rename plugins/{Calendar => calendar}/languages/en.xml (100%) rename plugins/{Calendar => calendar}/languages/es.xml (100%) rename plugins/{Calendar => calendar}/languages/et.xml (100%) rename plugins/{Calendar => calendar}/languages/fi.xml (100%) rename plugins/{Calendar => calendar}/languages/fr.xml (100%) rename plugins/{Calendar => calendar}/languages/hu.xml (100%) rename plugins/{Calendar => calendar}/languages/nb.xml (100%) rename plugins/{Calendar => calendar}/languages/nl.xml (100%) rename plugins/{Calendar => calendar}/languages/pl.xml (100%) rename plugins/{Calendar => calendar}/languages/pt-BR.xml (100%) rename plugins/{Calendar => calendar}/languages/pt.xml (100%) rename plugins/{Calendar => calendar}/languages/ru.xml (100%) rename plugins/{Calendar => calendar}/languages/sv.xml (100%) rename plugins/{Calendar => calendar}/languages/uk.xml (100%) rename plugins/{Calendar => calendar}/languages/zh.xml (100%) rename plugins/{Calendar => calendar}/templates/plugin.calendar.tpl (100%) rename plugins/{Calendar => calendar}/templates/preferences.plugin.calendar.tpl (100%) diff --git a/plugins/Calendar/Calendar.json b/plugins/calendar/calendar.json similarity index 96% rename from plugins/Calendar/Calendar.json rename to plugins/calendar/calendar.json index 4d87e87758..2531e5ab13 100644 --- a/plugins/Calendar/Calendar.json +++ b/plugins/calendar/calendar.json @@ -6,6 +6,12 @@ "url": "https://www.admidio.org", "icon": "bi-calendar-week-fill", "mainFile": "index.php", + "overviewPlugin": true, + "autoload": { + "psr-4": { + "Calendar\\classes\\": "classes/" + } + }, "dependencies": [ "Admidio\\Infrastructure\\Database", "Admidio\\Infrastructure\\Plugins\\Overview", diff --git a/plugins/Calendar/classes/Calendar.php b/plugins/calendar/classes/Calendar.php similarity index 99% rename from plugins/Calendar/classes/Calendar.php rename to plugins/calendar/classes/Calendar.php index 556c3b3e87..cfddd5a08a 100644 --- a/plugins/Calendar/classes/Calendar.php +++ b/plugins/calendar/classes/Calendar.php @@ -1,6 +1,6 @@ Date: Sun, 1 Feb 2026 13:20:27 +0100 Subject: [PATCH 085/109] refactor: redesign birthday plugin --- plugins/{Birthday/Birthday.json => birthday/birthday.json} | 6 ++++++ plugins/{Birthday => birthday}/classes/Birthday.php | 2 +- .../classes/Presenter/BirthdayPreferencesPresenter.php | 4 ++-- .../classes/Service/UpdateStepsCode.php | 4 ++-- plugins/{Birthday => birthday}/db_scripts/update_1_0.xml | 0 plugins/{Birthday => birthday}/index.php | 2 +- plugins/{Birthday => birthday}/languages/bg.xml | 0 plugins/{Birthday => birthday}/languages/da.xml | 0 plugins/{Birthday => birthday}/languages/de-DE.xml | 0 plugins/{Birthday => birthday}/languages/de.xml | 0 plugins/{Birthday => birthday}/languages/el.xml | 0 plugins/{Birthday => birthday}/languages/en.xml | 0 plugins/{Birthday => birthday}/languages/es.xml | 0 plugins/{Birthday => birthday}/languages/et.xml | 0 plugins/{Birthday => birthday}/languages/fi.xml | 0 plugins/{Birthday => birthday}/languages/fr.xml | 0 plugins/{Birthday => birthday}/languages/hu.xml | 0 plugins/{Birthday => birthday}/languages/nb.xml | 0 plugins/{Birthday => birthday}/languages/nl.xml | 0 plugins/{Birthday => birthday}/languages/pl.xml | 0 plugins/{Birthday => birthday}/languages/pt-BR.xml | 0 plugins/{Birthday => birthday}/languages/pt.xml | 0 plugins/{Birthday => birthday}/languages/ru.xml | 0 plugins/{Birthday => birthday}/languages/sv.xml | 0 plugins/{Birthday => birthday}/languages/uk.xml | 0 plugins/{Birthday => birthday}/languages/zh.xml | 0 .../{Birthday => birthday}/templates/plugin.birthday.tpl | 0 .../templates/preferences.plugin.birthday.tpl | 0 28 files changed, 12 insertions(+), 6 deletions(-) rename plugins/{Birthday/Birthday.json => birthday/birthday.json} (96%) rename plugins/{Birthday => birthday}/classes/Birthday.php (99%) rename plugins/{Birthday => birthday}/classes/Presenter/BirthdayPreferencesPresenter.php (98%) rename plugins/{Birthday => birthday}/classes/Service/UpdateStepsCode.php (98%) rename plugins/{Birthday => birthday}/db_scripts/update_1_0.xml (100%) rename plugins/{Birthday => birthday}/index.php (94%) rename plugins/{Birthday => birthday}/languages/bg.xml (100%) rename plugins/{Birthday => birthday}/languages/da.xml (100%) rename plugins/{Birthday => birthday}/languages/de-DE.xml (100%) rename plugins/{Birthday => birthday}/languages/de.xml (100%) rename plugins/{Birthday => birthday}/languages/el.xml (100%) rename plugins/{Birthday => birthday}/languages/en.xml (100%) rename plugins/{Birthday => birthday}/languages/es.xml (100%) rename plugins/{Birthday => birthday}/languages/et.xml (100%) rename plugins/{Birthday => birthday}/languages/fi.xml (100%) rename plugins/{Birthday => birthday}/languages/fr.xml (100%) rename plugins/{Birthday => birthday}/languages/hu.xml (100%) rename plugins/{Birthday => birthday}/languages/nb.xml (100%) rename plugins/{Birthday => birthday}/languages/nl.xml (100%) rename plugins/{Birthday => birthday}/languages/pl.xml (100%) rename plugins/{Birthday => birthday}/languages/pt-BR.xml (100%) rename plugins/{Birthday => birthday}/languages/pt.xml (100%) rename plugins/{Birthday => birthday}/languages/ru.xml (100%) rename plugins/{Birthday => birthday}/languages/sv.xml (100%) rename plugins/{Birthday => birthday}/languages/uk.xml (100%) rename plugins/{Birthday => birthday}/languages/zh.xml (100%) rename plugins/{Birthday => birthday}/templates/plugin.birthday.tpl (100%) rename plugins/{Birthday => birthday}/templates/preferences.plugin.birthday.tpl (100%) diff --git a/plugins/Birthday/Birthday.json b/plugins/birthday/birthday.json similarity index 96% rename from plugins/Birthday/Birthday.json rename to plugins/birthday/birthday.json index 24f3b65ec2..c97f28443b 100644 --- a/plugins/Birthday/Birthday.json +++ b/plugins/birthday/birthday.json @@ -6,6 +6,12 @@ "url": "https://www.admidio.org", "icon": "bi-cake2", "mainFile": "index.php", + "overviewPlugin": true, + "autoload": { + "psr-4": { + "Birthday\\classes\\": "classes/" + } + }, "dependencies": [ "Admidio\\Infrastructure\\Plugins\\Overview", "Admidio\\Infrastructure\\Plugins\\PluginAbstract", diff --git a/plugins/Birthday/classes/Birthday.php b/plugins/birthday/classes/Birthday.php similarity index 99% rename from plugins/Birthday/classes/Birthday.php rename to plugins/birthday/classes/Birthday.php index d60a1dd2e2..22953dc7de 100644 --- a/plugins/Birthday/classes/Birthday.php +++ b/plugins/birthday/classes/Birthday.php @@ -1,6 +1,6 @@ Date: Sun, 1 Feb 2026 13:47:35 +0100 Subject: [PATCH 086/109] temporary allow all commits in plugins --- .gitignore | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 79dde60897..4c806e4973 100644 --- a/.gitignore +++ b/.gitignore @@ -10,16 +10,7 @@ !/adm_my_files/index.html # Only allow commit of official plugins -/plugins/* -!/plugins/Birthday/ -!/plugins/Calendar/ -!/plugins/LoginForm/ -!/plugins/RandomPhoto/ -!/plugins/AnnouncementList/ -!/plugins/EventList/ -!/plugins/LatestDocumentsFiles/ -!/plugins/WhoIsOnline/ -!/plugins/CategoryReport/ + # Only allow commit of official themes /themes/* From 79cfb0b1670c8877b163718a5ac6431c1d86bc64 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sun, 1 Feb 2026 13:49:29 +0100 Subject: [PATCH 087/109] refactor: redesign announcement list plugin --- .../announcement_list.json} | 6 ++++++ .../classes/AnnouncementList.php | 2 +- .../Presenter/AnnouncementListPreferencesPresenter.php | 4 ++-- .../classes/Service/UpdateStepsCode.php | 4 ++-- .../db_scripts/update_1_0.xml | 0 plugins/{AnnouncementList => announcement_list}/index.php | 2 +- .../languages/bg.xml | 0 .../languages/da.xml | 0 .../languages/de-DE.xml | 0 .../languages/de.xml | 0 .../languages/el.xml | 0 .../languages/en.xml | 0 .../languages/es.xml | 0 .../languages/et.xml | 0 .../languages/fi.xml | 0 .../languages/fr.xml | 0 .../languages/hu.xml | 0 .../languages/nb.xml | 0 .../languages/nl.xml | 0 .../languages/pl.xml | 0 .../languages/pt-BR.xml | 0 .../languages/pt.xml | 0 .../languages/ru.xml | 0 .../languages/sv.xml | 0 .../languages/uk.xml | 0 .../templates/plugin.announcement-list.tpl | 0 .../templates/preferences.plugin.announcement-list.tpl | 0 27 files changed, 12 insertions(+), 6 deletions(-) rename plugins/{AnnouncementList/AnnouncementList.json => announcement_list/announcement_list.json} (94%) rename plugins/{AnnouncementList => announcement_list}/classes/AnnouncementList.php (99%) rename plugins/{AnnouncementList => announcement_list}/classes/Presenter/AnnouncementListPreferencesPresenter.php (98%) rename plugins/{AnnouncementList => announcement_list}/classes/Service/UpdateStepsCode.php (97%) rename plugins/{AnnouncementList => announcement_list}/db_scripts/update_1_0.xml (100%) rename plugins/{AnnouncementList => announcement_list}/index.php (93%) rename plugins/{AnnouncementList => announcement_list}/languages/bg.xml (100%) rename plugins/{AnnouncementList => announcement_list}/languages/da.xml (100%) rename plugins/{AnnouncementList => announcement_list}/languages/de-DE.xml (100%) rename plugins/{AnnouncementList => announcement_list}/languages/de.xml (100%) rename plugins/{AnnouncementList => announcement_list}/languages/el.xml (100%) rename plugins/{AnnouncementList => announcement_list}/languages/en.xml (100%) rename plugins/{AnnouncementList => announcement_list}/languages/es.xml (100%) rename plugins/{AnnouncementList => announcement_list}/languages/et.xml (100%) rename plugins/{AnnouncementList => announcement_list}/languages/fi.xml (100%) rename plugins/{AnnouncementList => announcement_list}/languages/fr.xml (100%) rename plugins/{AnnouncementList => announcement_list}/languages/hu.xml (100%) rename plugins/{AnnouncementList => announcement_list}/languages/nb.xml (100%) rename plugins/{AnnouncementList => announcement_list}/languages/nl.xml (100%) rename plugins/{AnnouncementList => announcement_list}/languages/pl.xml (100%) rename plugins/{AnnouncementList => announcement_list}/languages/pt-BR.xml (100%) rename plugins/{AnnouncementList => announcement_list}/languages/pt.xml (100%) rename plugins/{AnnouncementList => announcement_list}/languages/ru.xml (100%) rename plugins/{AnnouncementList => announcement_list}/languages/sv.xml (100%) rename plugins/{AnnouncementList => announcement_list}/languages/uk.xml (100%) rename plugins/{AnnouncementList => announcement_list}/templates/plugin.announcement-list.tpl (100%) rename plugins/{AnnouncementList => announcement_list}/templates/preferences.plugin.announcement-list.tpl (100%) diff --git a/plugins/AnnouncementList/AnnouncementList.json b/plugins/announcement_list/announcement_list.json similarity index 94% rename from plugins/AnnouncementList/AnnouncementList.json rename to plugins/announcement_list/announcement_list.json index 25091c1a2e..6f78af9327 100644 --- a/plugins/AnnouncementList/AnnouncementList.json +++ b/plugins/announcement_list/announcement_list.json @@ -6,6 +6,12 @@ "url": "https://www.admidio.org", "icon": "bi-newspaper", "mainFile": "index.php", + "overviewPlugin": true, + "autoload": { + "psr-4": { + "AnnouncementList\\classes\\": "classes/" + } + }, "dependencies": [ "Admidio\\Announcements\\Entity\\Announcement", "Admidio\\Infrastructure\\Database", diff --git a/plugins/AnnouncementList/classes/AnnouncementList.php b/plugins/announcement_list/classes/AnnouncementList.php similarity index 99% rename from plugins/AnnouncementList/classes/AnnouncementList.php rename to plugins/announcement_list/classes/AnnouncementList.php index 420c3fb73d..e61bc98507 100644 --- a/plugins/AnnouncementList/classes/AnnouncementList.php +++ b/plugins/announcement_list/classes/AnnouncementList.php @@ -1,6 +1,6 @@ Date: Sun, 1 Feb 2026 13:50:59 +0100 Subject: [PATCH 088/109] refactor: redesign event list plugin --- plugins/{EventList => event_list}/classes/EventList.php | 2 +- .../classes/Presenter/EventListPreferencesPresenter.php | 4 ++-- .../classes/Service/UpdateStepsCode.php | 4 ++-- plugins/{EventList => event_list}/db_scripts/update_1_0.xml | 0 .../EventList.json => event_list/event_list.json} | 6 ++++++ plugins/{EventList => event_list}/index.php | 2 +- plugins/{EventList => event_list}/languages/bg.xml | 0 plugins/{EventList => event_list}/languages/da.xml | 0 plugins/{EventList => event_list}/languages/de-DE.xml | 0 plugins/{EventList => event_list}/languages/de.xml | 0 plugins/{EventList => event_list}/languages/el.xml | 0 plugins/{EventList => event_list}/languages/en.xml | 0 plugins/{EventList => event_list}/languages/es.xml | 0 plugins/{EventList => event_list}/languages/et.xml | 0 plugins/{EventList => event_list}/languages/fi.xml | 0 plugins/{EventList => event_list}/languages/fr.xml | 0 plugins/{EventList => event_list}/languages/hu.xml | 0 plugins/{EventList => event_list}/languages/nb.xml | 0 plugins/{EventList => event_list}/languages/nl.xml | 0 plugins/{EventList => event_list}/languages/pl.xml | 0 plugins/{EventList => event_list}/languages/pt-BR.xml | 0 plugins/{EventList => event_list}/languages/pt.xml | 0 plugins/{EventList => event_list}/languages/ru.xml | 0 plugins/{EventList => event_list}/languages/sv.xml | 0 plugins/{EventList => event_list}/languages/uk.xml | 0 plugins/{EventList => event_list}/languages/zh.xml | 0 .../templates/plugin.event-list.tpl | 0 .../templates/preferences.plugin.event-list.tpl | 0 28 files changed, 12 insertions(+), 6 deletions(-) rename plugins/{EventList => event_list}/classes/EventList.php (99%) rename plugins/{EventList => event_list}/classes/Presenter/EventListPreferencesPresenter.php (98%) rename plugins/{EventList => event_list}/classes/Service/UpdateStepsCode.php (98%) rename plugins/{EventList => event_list}/db_scripts/update_1_0.xml (100%) rename plugins/{EventList/EventList.json => event_list/event_list.json} (95%) rename plugins/{EventList => event_list}/index.php (94%) rename plugins/{EventList => event_list}/languages/bg.xml (100%) rename plugins/{EventList => event_list}/languages/da.xml (100%) rename plugins/{EventList => event_list}/languages/de-DE.xml (100%) rename plugins/{EventList => event_list}/languages/de.xml (100%) rename plugins/{EventList => event_list}/languages/el.xml (100%) rename plugins/{EventList => event_list}/languages/en.xml (100%) rename plugins/{EventList => event_list}/languages/es.xml (100%) rename plugins/{EventList => event_list}/languages/et.xml (100%) rename plugins/{EventList => event_list}/languages/fi.xml (100%) rename plugins/{EventList => event_list}/languages/fr.xml (100%) rename plugins/{EventList => event_list}/languages/hu.xml (100%) rename plugins/{EventList => event_list}/languages/nb.xml (100%) rename plugins/{EventList => event_list}/languages/nl.xml (100%) rename plugins/{EventList => event_list}/languages/pl.xml (100%) rename plugins/{EventList => event_list}/languages/pt-BR.xml (100%) rename plugins/{EventList => event_list}/languages/pt.xml (100%) rename plugins/{EventList => event_list}/languages/ru.xml (100%) rename plugins/{EventList => event_list}/languages/sv.xml (100%) rename plugins/{EventList => event_list}/languages/uk.xml (100%) rename plugins/{EventList => event_list}/languages/zh.xml (100%) rename plugins/{EventList => event_list}/templates/plugin.event-list.tpl (100%) rename plugins/{EventList => event_list}/templates/preferences.plugin.event-list.tpl (100%) diff --git a/plugins/EventList/classes/EventList.php b/plugins/event_list/classes/EventList.php similarity index 99% rename from plugins/EventList/classes/EventList.php rename to plugins/event_list/classes/EventList.php index 76e2dad227..50a9a9ebec 100644 --- a/plugins/EventList/classes/EventList.php +++ b/plugins/event_list/classes/EventList.php @@ -1,6 +1,6 @@ Date: Sun, 1 Feb 2026 13:52:17 +0100 Subject: [PATCH 089/109] refactor: redesign latest documents files plugin --- .../classes/LatestDocumentsFiles.php | 2 +- .../Presenter/LatestDocumentsFilesPreferencesPresenter.php | 4 ++-- .../classes/Service/UpdateStepsCode.php | 4 ++-- .../db_scripts/update_1_0.xml | 0 .../index.php | 2 +- .../languages/bg.xml | 0 .../languages/da.xml | 0 .../languages/de-DE.xml | 0 .../languages/de.xml | 0 .../languages/el.xml | 0 .../languages/en.xml | 0 .../languages/es.xml | 0 .../languages/et.xml | 0 .../languages/fi.xml | 0 .../languages/fr.xml | 0 .../languages/hu.xml | 0 .../languages/nb.xml | 0 .../languages/nl.xml | 0 .../languages/pl.xml | 0 .../languages/pt-BR.xml | 0 .../languages/pt.xml | 0 .../languages/ru.xml | 0 .../languages/sv.xml | 0 .../languages/uk.xml | 0 .../languages/zh.xml | 0 .../latest_documents_files.json} | 6 ++++++ .../templates/plugin.latest-documents-files.tpl | 0 .../templates/preferences.plugin.latest-documents-files.tpl | 0 28 files changed, 12 insertions(+), 6 deletions(-) rename plugins/{LatestDocumentsFiles => latest_documents_files}/classes/LatestDocumentsFiles.php (99%) rename plugins/{LatestDocumentsFiles => latest_documents_files}/classes/Presenter/LatestDocumentsFilesPreferencesPresenter.php (97%) rename plugins/{LatestDocumentsFiles => latest_documents_files}/classes/Service/UpdateStepsCode.php (95%) rename plugins/{LatestDocumentsFiles => latest_documents_files}/db_scripts/update_1_0.xml (100%) rename plugins/{LatestDocumentsFiles => latest_documents_files}/index.php (92%) rename plugins/{LatestDocumentsFiles => latest_documents_files}/languages/bg.xml (100%) rename plugins/{LatestDocumentsFiles => latest_documents_files}/languages/da.xml (100%) rename plugins/{LatestDocumentsFiles => latest_documents_files}/languages/de-DE.xml (100%) rename plugins/{LatestDocumentsFiles => latest_documents_files}/languages/de.xml (100%) rename plugins/{LatestDocumentsFiles => latest_documents_files}/languages/el.xml (100%) rename plugins/{LatestDocumentsFiles => latest_documents_files}/languages/en.xml (100%) rename plugins/{LatestDocumentsFiles => latest_documents_files}/languages/es.xml (100%) rename plugins/{LatestDocumentsFiles => latest_documents_files}/languages/et.xml (100%) rename plugins/{LatestDocumentsFiles => latest_documents_files}/languages/fi.xml (100%) rename plugins/{LatestDocumentsFiles => latest_documents_files}/languages/fr.xml (100%) rename plugins/{LatestDocumentsFiles => latest_documents_files}/languages/hu.xml (100%) rename plugins/{LatestDocumentsFiles => latest_documents_files}/languages/nb.xml (100%) rename plugins/{LatestDocumentsFiles => latest_documents_files}/languages/nl.xml (100%) rename plugins/{LatestDocumentsFiles => latest_documents_files}/languages/pl.xml (100%) rename plugins/{LatestDocumentsFiles => latest_documents_files}/languages/pt-BR.xml (100%) rename plugins/{LatestDocumentsFiles => latest_documents_files}/languages/pt.xml (100%) rename plugins/{LatestDocumentsFiles => latest_documents_files}/languages/ru.xml (100%) rename plugins/{LatestDocumentsFiles => latest_documents_files}/languages/sv.xml (100%) rename plugins/{LatestDocumentsFiles => latest_documents_files}/languages/uk.xml (100%) rename plugins/{LatestDocumentsFiles => latest_documents_files}/languages/zh.xml (100%) rename plugins/{LatestDocumentsFiles/LatestDocumentsFiles.json => latest_documents_files/latest_documents_files.json} (92%) rename plugins/{LatestDocumentsFiles => latest_documents_files}/templates/plugin.latest-documents-files.tpl (100%) rename plugins/{LatestDocumentsFiles => latest_documents_files}/templates/preferences.plugin.latest-documents-files.tpl (100%) diff --git a/plugins/LatestDocumentsFiles/classes/LatestDocumentsFiles.php b/plugins/latest_documents_files/classes/LatestDocumentsFiles.php similarity index 99% rename from plugins/LatestDocumentsFiles/classes/LatestDocumentsFiles.php rename to plugins/latest_documents_files/classes/LatestDocumentsFiles.php index 4bd3a0265b..72f721fabe 100644 --- a/plugins/LatestDocumentsFiles/classes/LatestDocumentsFiles.php +++ b/plugins/latest_documents_files/classes/LatestDocumentsFiles.php @@ -1,6 +1,6 @@ Date: Sun, 1 Feb 2026 13:53:15 +0100 Subject: [PATCH 090/109] refactor: redesign login form plugin --- plugins/{LoginForm => login_form}/classes/LoginForm.php | 2 +- .../classes/Presenter/LoginFormPreferencesPresenter.php | 4 ++-- .../classes/Service/UpdateStepsCode.php | 4 ++-- plugins/{LoginForm => login_form}/db_scripts/update_1_0.xml | 0 plugins/{LoginForm => login_form}/index.php | 2 +- plugins/{LoginForm => login_form}/languages/bg.xml | 0 plugins/{LoginForm => login_form}/languages/da.xml | 0 plugins/{LoginForm => login_form}/languages/de-DE.xml | 0 plugins/{LoginForm => login_form}/languages/de.xml | 0 plugins/{LoginForm => login_form}/languages/el.xml | 0 plugins/{LoginForm => login_form}/languages/en.xml | 0 plugins/{LoginForm => login_form}/languages/es.xml | 0 plugins/{LoginForm => login_form}/languages/et.xml | 0 plugins/{LoginForm => login_form}/languages/fi.xml | 0 plugins/{LoginForm => login_form}/languages/fr.xml | 0 plugins/{LoginForm => login_form}/languages/hu.xml | 0 plugins/{LoginForm => login_form}/languages/it.xml | 0 plugins/{LoginForm => login_form}/languages/nb.xml | 0 plugins/{LoginForm => login_form}/languages/nl.xml | 0 plugins/{LoginForm => login_form}/languages/pl.xml | 0 plugins/{LoginForm => login_form}/languages/pt-BR.xml | 0 plugins/{LoginForm => login_form}/languages/pt.xml | 0 plugins/{LoginForm => login_form}/languages/ru.xml | 0 plugins/{LoginForm => login_form}/languages/sv.xml | 0 plugins/{LoginForm => login_form}/languages/uk.xml | 0 plugins/{LoginForm => login_form}/languages/zh.xml | 0 .../LoginForm.json => login_form/login_form.json} | 6 ++++++ .../templates/plugin.login-form.edit.tpl | 0 .../templates/plugin.login-form.view.tpl | 0 .../templates/preferences.plugin.login-form.tpl | 0 30 files changed, 12 insertions(+), 6 deletions(-) rename plugins/{LoginForm => login_form}/classes/LoginForm.php (99%) rename plugins/{LoginForm => login_form}/classes/Presenter/LoginFormPreferencesPresenter.php (98%) rename plugins/{LoginForm => login_form}/classes/Service/UpdateStepsCode.php (97%) rename plugins/{LoginForm => login_form}/db_scripts/update_1_0.xml (100%) rename plugins/{LoginForm => login_form}/index.php (95%) rename plugins/{LoginForm => login_form}/languages/bg.xml (100%) rename plugins/{LoginForm => login_form}/languages/da.xml (100%) rename plugins/{LoginForm => login_form}/languages/de-DE.xml (100%) rename plugins/{LoginForm => login_form}/languages/de.xml (100%) rename plugins/{LoginForm => login_form}/languages/el.xml (100%) rename plugins/{LoginForm => login_form}/languages/en.xml (100%) rename plugins/{LoginForm => login_form}/languages/es.xml (100%) rename plugins/{LoginForm => login_form}/languages/et.xml (100%) rename plugins/{LoginForm => login_form}/languages/fi.xml (100%) rename plugins/{LoginForm => login_form}/languages/fr.xml (100%) rename plugins/{LoginForm => login_form}/languages/hu.xml (100%) rename plugins/{LoginForm => login_form}/languages/it.xml (100%) rename plugins/{LoginForm => login_form}/languages/nb.xml (100%) rename plugins/{LoginForm => login_form}/languages/nl.xml (100%) rename plugins/{LoginForm => login_form}/languages/pl.xml (100%) rename plugins/{LoginForm => login_form}/languages/pt-BR.xml (100%) rename plugins/{LoginForm => login_form}/languages/pt.xml (100%) rename plugins/{LoginForm => login_form}/languages/ru.xml (100%) rename plugins/{LoginForm => login_form}/languages/sv.xml (100%) rename plugins/{LoginForm => login_form}/languages/uk.xml (100%) rename plugins/{LoginForm => login_form}/languages/zh.xml (100%) rename plugins/{LoginForm/LoginForm.json => login_form/login_form.json} (94%) rename plugins/{LoginForm => login_form}/templates/plugin.login-form.edit.tpl (100%) rename plugins/{LoginForm => login_form}/templates/plugin.login-form.view.tpl (100%) rename plugins/{LoginForm => login_form}/templates/preferences.plugin.login-form.tpl (100%) diff --git a/plugins/LoginForm/classes/LoginForm.php b/plugins/login_form/classes/LoginForm.php similarity index 99% rename from plugins/LoginForm/classes/LoginForm.php rename to plugins/login_form/classes/LoginForm.php index bd64d55624..0e58ab9f1a 100644 --- a/plugins/LoginForm/classes/LoginForm.php +++ b/plugins/login_form/classes/LoginForm.php @@ -1,6 +1,6 @@ Date: Sun, 1 Feb 2026 13:54:18 +0100 Subject: [PATCH 091/109] refactor: redesign random photo plugin --- .../classes/Presenter/RandomPhotoPreferencesPresenter.php | 4 ++-- .../{RandomPhoto => random_photo}/classes/RandomPhoto.php | 2 +- .../classes/Service/UpdateStepsCode.php | 4 ++-- .../{RandomPhoto => random_photo}/db_scripts/update_1_0.xml | 0 plugins/{RandomPhoto => random_photo}/index.php | 2 +- plugins/{RandomPhoto => random_photo}/languages/bg.xml | 0 plugins/{RandomPhoto => random_photo}/languages/da.xml | 0 plugins/{RandomPhoto => random_photo}/languages/de-DE.xml | 0 plugins/{RandomPhoto => random_photo}/languages/de.xml | 0 plugins/{RandomPhoto => random_photo}/languages/el.xml | 0 plugins/{RandomPhoto => random_photo}/languages/en.xml | 0 plugins/{RandomPhoto => random_photo}/languages/et.xml | 0 plugins/{RandomPhoto => random_photo}/languages/fi.xml | 0 plugins/{RandomPhoto => random_photo}/languages/fr.xml | 0 plugins/{RandomPhoto => random_photo}/languages/hu.xml | 0 plugins/{RandomPhoto => random_photo}/languages/nb.xml | 0 plugins/{RandomPhoto => random_photo}/languages/nl.xml | 0 plugins/{RandomPhoto => random_photo}/languages/pl.xml | 0 plugins/{RandomPhoto => random_photo}/languages/pt.xml | 0 plugins/{RandomPhoto => random_photo}/languages/ru.xml | 0 plugins/{RandomPhoto => random_photo}/languages/sv.xml | 0 plugins/{RandomPhoto => random_photo}/languages/uk.xml | 0 .../RandomPhoto.json => random_photo/random_photo.json} | 6 ++++++ .../templates/plugin.random-photo.tpl | 0 .../templates/preferences.plugin.random-photo.tpl | 0 25 files changed, 12 insertions(+), 6 deletions(-) rename plugins/{RandomPhoto => random_photo}/classes/Presenter/RandomPhotoPreferencesPresenter.php (98%) rename plugins/{RandomPhoto => random_photo}/classes/RandomPhoto.php (99%) rename plugins/{RandomPhoto => random_photo}/classes/Service/UpdateStepsCode.php (97%) rename plugins/{RandomPhoto => random_photo}/db_scripts/update_1_0.xml (100%) rename plugins/{RandomPhoto => random_photo}/index.php (94%) rename plugins/{RandomPhoto => random_photo}/languages/bg.xml (100%) rename plugins/{RandomPhoto => random_photo}/languages/da.xml (100%) rename plugins/{RandomPhoto => random_photo}/languages/de-DE.xml (100%) rename plugins/{RandomPhoto => random_photo}/languages/de.xml (100%) rename plugins/{RandomPhoto => random_photo}/languages/el.xml (100%) rename plugins/{RandomPhoto => random_photo}/languages/en.xml (100%) rename plugins/{RandomPhoto => random_photo}/languages/et.xml (100%) rename plugins/{RandomPhoto => random_photo}/languages/fi.xml (100%) rename plugins/{RandomPhoto => random_photo}/languages/fr.xml (100%) rename plugins/{RandomPhoto => random_photo}/languages/hu.xml (100%) rename plugins/{RandomPhoto => random_photo}/languages/nb.xml (100%) rename plugins/{RandomPhoto => random_photo}/languages/nl.xml (100%) rename plugins/{RandomPhoto => random_photo}/languages/pl.xml (100%) rename plugins/{RandomPhoto => random_photo}/languages/pt.xml (100%) rename plugins/{RandomPhoto => random_photo}/languages/ru.xml (100%) rename plugins/{RandomPhoto => random_photo}/languages/sv.xml (100%) rename plugins/{RandomPhoto => random_photo}/languages/uk.xml (100%) rename plugins/{RandomPhoto/RandomPhoto.json => random_photo/random_photo.json} (94%) rename plugins/{RandomPhoto => random_photo}/templates/plugin.random-photo.tpl (100%) rename plugins/{RandomPhoto => random_photo}/templates/preferences.plugin.random-photo.tpl (100%) diff --git a/plugins/RandomPhoto/classes/Presenter/RandomPhotoPreferencesPresenter.php b/plugins/random_photo/classes/Presenter/RandomPhotoPreferencesPresenter.php similarity index 98% rename from plugins/RandomPhoto/classes/Presenter/RandomPhotoPreferencesPresenter.php rename to plugins/random_photo/classes/Presenter/RandomPhotoPreferencesPresenter.php index e7190da8af..62409d22c1 100644 --- a/plugins/RandomPhoto/classes/Presenter/RandomPhotoPreferencesPresenter.php +++ b/plugins/random_photo/classes/Presenter/RandomPhotoPreferencesPresenter.php @@ -1,12 +1,12 @@ Date: Sun, 1 Feb 2026 13:55:11 +0100 Subject: [PATCH 092/109] refactor: redesign who is online plugin --- .../classes/Presenter/WhoIsOnlinePreferencesPresenter.php | 4 ++-- .../classes/Service/UpdateStepsCode.php | 4 ++-- .../{WhoIsOnline => who_is_online}/classes/WhoIsOnline.php | 2 +- .../db_scripts/update_1_0.xml | 0 plugins/{WhoIsOnline => who_is_online}/index.php | 2 +- plugins/{WhoIsOnline => who_is_online}/languages/bg.xml | 0 plugins/{WhoIsOnline => who_is_online}/languages/da.xml | 0 plugins/{WhoIsOnline => who_is_online}/languages/de-DE.xml | 0 plugins/{WhoIsOnline => who_is_online}/languages/de.xml | 0 plugins/{WhoIsOnline => who_is_online}/languages/el.xml | 0 plugins/{WhoIsOnline => who_is_online}/languages/en.xml | 0 plugins/{WhoIsOnline => who_is_online}/languages/es.xml | 0 plugins/{WhoIsOnline => who_is_online}/languages/et.xml | 0 plugins/{WhoIsOnline => who_is_online}/languages/fi.xml | 0 plugins/{WhoIsOnline => who_is_online}/languages/fr.xml | 0 plugins/{WhoIsOnline => who_is_online}/languages/hu.xml | 0 plugins/{WhoIsOnline => who_is_online}/languages/nb.xml | 0 plugins/{WhoIsOnline => who_is_online}/languages/nl.xml | 0 plugins/{WhoIsOnline => who_is_online}/languages/pl.xml | 0 plugins/{WhoIsOnline => who_is_online}/languages/pt-BR.xml | 0 plugins/{WhoIsOnline => who_is_online}/languages/pt.xml | 0 plugins/{WhoIsOnline => who_is_online}/languages/ru.xml | 0 plugins/{WhoIsOnline => who_is_online}/languages/sv.xml | 0 plugins/{WhoIsOnline => who_is_online}/languages/uk.xml | 0 plugins/{WhoIsOnline => who_is_online}/languages/zh.xml | 0 .../templates/plugin.who-is-online.tpl | 0 .../templates/preferences.plugin.who-is-online.tpl | 0 .../WhoIsOnline.json => who_is_online/who_is_online.json} | 6 ++++++ 28 files changed, 12 insertions(+), 6 deletions(-) rename plugins/{WhoIsOnline => who_is_online}/classes/Presenter/WhoIsOnlinePreferencesPresenter.php (98%) rename plugins/{WhoIsOnline => who_is_online}/classes/Service/UpdateStepsCode.php (97%) rename plugins/{WhoIsOnline => who_is_online}/classes/WhoIsOnline.php (99%) rename plugins/{WhoIsOnline => who_is_online}/db_scripts/update_1_0.xml (100%) rename plugins/{WhoIsOnline => who_is_online}/index.php (93%) rename plugins/{WhoIsOnline => who_is_online}/languages/bg.xml (100%) rename plugins/{WhoIsOnline => who_is_online}/languages/da.xml (100%) rename plugins/{WhoIsOnline => who_is_online}/languages/de-DE.xml (100%) rename plugins/{WhoIsOnline => who_is_online}/languages/de.xml (100%) rename plugins/{WhoIsOnline => who_is_online}/languages/el.xml (100%) rename plugins/{WhoIsOnline => who_is_online}/languages/en.xml (100%) rename plugins/{WhoIsOnline => who_is_online}/languages/es.xml (100%) rename plugins/{WhoIsOnline => who_is_online}/languages/et.xml (100%) rename plugins/{WhoIsOnline => who_is_online}/languages/fi.xml (100%) rename plugins/{WhoIsOnline => who_is_online}/languages/fr.xml (100%) rename plugins/{WhoIsOnline => who_is_online}/languages/hu.xml (100%) rename plugins/{WhoIsOnline => who_is_online}/languages/nb.xml (100%) rename plugins/{WhoIsOnline => who_is_online}/languages/nl.xml (100%) rename plugins/{WhoIsOnline => who_is_online}/languages/pl.xml (100%) rename plugins/{WhoIsOnline => who_is_online}/languages/pt-BR.xml (100%) rename plugins/{WhoIsOnline => who_is_online}/languages/pt.xml (100%) rename plugins/{WhoIsOnline => who_is_online}/languages/ru.xml (100%) rename plugins/{WhoIsOnline => who_is_online}/languages/sv.xml (100%) rename plugins/{WhoIsOnline => who_is_online}/languages/uk.xml (100%) rename plugins/{WhoIsOnline => who_is_online}/languages/zh.xml (100%) rename plugins/{WhoIsOnline => who_is_online}/templates/plugin.who-is-online.tpl (100%) rename plugins/{WhoIsOnline => who_is_online}/templates/preferences.plugin.who-is-online.tpl (100%) rename plugins/{WhoIsOnline/WhoIsOnline.json => who_is_online/who_is_online.json} (94%) diff --git a/plugins/WhoIsOnline/classes/Presenter/WhoIsOnlinePreferencesPresenter.php b/plugins/who_is_online/classes/Presenter/WhoIsOnlinePreferencesPresenter.php similarity index 98% rename from plugins/WhoIsOnline/classes/Presenter/WhoIsOnlinePreferencesPresenter.php rename to plugins/who_is_online/classes/Presenter/WhoIsOnlinePreferencesPresenter.php index 14080d5e8d..be962de30f 100644 --- a/plugins/WhoIsOnline/classes/Presenter/WhoIsOnlinePreferencesPresenter.php +++ b/plugins/who_is_online/classes/Presenter/WhoIsOnlinePreferencesPresenter.php @@ -1,12 +1,12 @@ Date: Sun, 1 Feb 2026 13:55:33 +0100 Subject: [PATCH 093/109] fix: plugin class loading mechanism --- src/Infrastructure/Plugins/PluginManager.php | 30 ++++++++++++++------ 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/Infrastructure/Plugins/PluginManager.php b/src/Infrastructure/Plugins/PluginManager.php index 8b5cf17d98..408f253997 100644 --- a/src/Infrastructure/Plugins/PluginManager.php +++ b/src/Infrastructure/Plugins/PluginManager.php @@ -31,15 +31,29 @@ public function getAvailablePlugins() : array|object } $pluginFolder = $this->pluginsPath . DIRECTORY_SEPARATOR . $entry; + $className = null; + $pluginClassFile = null; + if (is_dir($pluginFolder)) { - $pluginClassFile = $pluginFolder . DIRECTORY_SEPARATOR . 'classes' . DIRECTORY_SEPARATOR . $entry . '.php'; - $className = is_file($pluginClassFile) ? $this->getClassNameFromFile($pluginClassFile) : null; - - // The classname only contains the namespace of the plugin itself, so we need a way to find the class to get an instance of it. - // The problem is, that if the plugin isn't installed yet, we cannot use autoloading to find the class. - // Therefore, we check if the class exists first. If not, we include the file manually. - if ($className !== null && !class_exists($className)) { - include_once $pluginClassFile; + // loop over all class files to find the main plugin class file in the classes folder + foreach (scandir($pluginFolder . DIRECTORY_SEPARATOR . 'classes') as $classFileEntry) { + if ($classFileEntry === '.' || $classFileEntry === '..' || !is_file($pluginFolder . DIRECTORY_SEPARATOR . 'classes' . DIRECTORY_SEPARATOR . $classFileEntry)) { + continue; + } + + $pluginClassFile = $pluginFolder . DIRECTORY_SEPARATOR . 'classes' . DIRECTORY_SEPARATOR . $classFileEntry; + $className = is_file($pluginClassFile) ? $this->getClassNameFromFile($pluginClassFile) : null; + + // The classname only contains the namespace of the plugin itself, so we need a way to find the class to get an instance of it. + // The problem is, that if the plugin isn't installed yet, we cannot use autoloading to find the class. + // Therefore, we check if the class exists first. If not, we include the file manually. + if ($className !== null && !class_exists($className)) { + include_once $pluginClassFile; + + if (is_subclass_of($className, PluginAbstract::class)) { + break; + } + } } $instance = $className != null ? $className::getInstance() : null; From 9e5e04982f13331b040a10bf8a6d8386b27702d9 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sun, 1 Feb 2026 14:45:56 +0100 Subject: [PATCH 094/109] - undo temporary allow all commits in plugins folder - remove CategoryReport from official plugins list --- .gitignore | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.gitignore b/.gitignore index 4c806e4973..de5ba8562d 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,15 @@ !/adm_my_files/index.html # Only allow commit of official plugins +/plugins/* +!/plugins/birthday/ +!/plugins/calendar/ +!/plugins/login_form/ +!/plugins/random_photo/ +!/plugins/announcement_list/ +!/plugins/event_list/ +!/plugins/latest_documents_files/ +!/plugins/who_is_online/ # Only allow commit of official themes From 0b86e93b2850e61948b38d7ecf0fd296c0ceb643 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sun, 1 Feb 2026 15:48:52 +0100 Subject: [PATCH 095/109] fix: initPreferencesCallback() --- src/Infrastructure/Plugins/PluginAbstract.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Infrastructure/Plugins/PluginAbstract.php b/src/Infrastructure/Plugins/PluginAbstract.php index 08f663d556..d51f9b24d0 100644 --- a/src/Infrastructure/Plugins/PluginAbstract.php +++ b/src/Infrastructure/Plugins/PluginAbstract.php @@ -108,8 +108,10 @@ public static function removeMenuEntry(): void */ public static function initPreferencePanelCallback(): void { - $callingPlugin = admFuncVariableIsValid($_GET, 'panel', 'string', array('defaultValue' => '')); + // get the calling plugin name in lowercase and without underscores, hyphens, spaces or other special characters + $callingPlugin = strtolower(preg_replace('/[^a-zA-Z0-9]/', '', self::getComponentName())); + // get psr4 autoload mappings and preferences file from metadata $psr4 = self::$metadata['autoload']['psr-4'] ?? null; $preferencesFile = self::$metadata['preferencesFile'] ?? null; @@ -143,8 +145,10 @@ public static function initPreferencePanelCallback(): void } if (isset($preferencesClass) && class_exists($preferencesClass)) { - // get the function name for the preferences panel - $functionName = 'create' . basename(self::getPluginPath()) . 'Form'; + + // get the function name for the preferences panel form + $className = str_replace('PreferencesPresenter', '', (new ReflectionClass($preferencesClass))->getShortName()); + $functionName = 'create' . $className . 'Form'; if (!method_exists($preferencesClass, $functionName)) { throw new Exception('The preferences class ' . $preferencesClass . ' does not have a method ' . $functionName . '().'); } From caa6564c56d7ff378820cdf57357220803ec8a0a Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sun, 1 Feb 2026 15:49:39 +0100 Subject: [PATCH 096/109] refactor: update XML steps of all plugins --- plugins/announcement_list/db_scripts/update_1_0.xml | 3 +-- plugins/birthday/db_scripts/update_1_0.xml | 3 +-- plugins/calendar/db_scripts/update_1_0.xml | 3 +-- plugins/event_list/db_scripts/update_1_0.xml | 3 +-- plugins/latest_documents_files/db_scripts/update_1_0.xml | 3 +-- plugins/login_form/db_scripts/update_1_0.xml | 3 +-- plugins/random_photo/db_scripts/update_1_0.xml | 3 +-- plugins/who_is_online/db_scripts/update_1_0.xml | 3 +-- 8 files changed, 8 insertions(+), 16 deletions(-) diff --git a/plugins/announcement_list/db_scripts/update_1_0.xml b/plugins/announcement_list/db_scripts/update_1_0.xml index d293505ece..c0cffa9222 100644 --- a/plugins/announcement_list/db_scripts/update_1_0.xml +++ b/plugins/announcement_list/db_scripts/update_1_0.xml @@ -1,6 +1,5 @@ - UPDATE %PREFIX%_components SET com_overview_plugin = 1 WHERE com_type = 'PLUGIN' AND com_name_intern = 'AnnouncementList' - UpdateStepsCode::updateStep10RetrievePreviousSettings + UpdateStepsCode::updateStep10RetrievePreviousSettings stop diff --git a/plugins/birthday/db_scripts/update_1_0.xml b/plugins/birthday/db_scripts/update_1_0.xml index 09169a4244..c0cffa9222 100644 --- a/plugins/birthday/db_scripts/update_1_0.xml +++ b/plugins/birthday/db_scripts/update_1_0.xml @@ -1,6 +1,5 @@ - UPDATE %PREFIX%_components SET com_overview_plugin = 1 WHERE com_type = 'PLUGIN' AND com_name_intern = 'Birthday' - UpdateStepsCode::updateStep10RetrievePreviousSettings + UpdateStepsCode::updateStep10RetrievePreviousSettings stop diff --git a/plugins/calendar/db_scripts/update_1_0.xml b/plugins/calendar/db_scripts/update_1_0.xml index b71c445542..c0cffa9222 100644 --- a/plugins/calendar/db_scripts/update_1_0.xml +++ b/plugins/calendar/db_scripts/update_1_0.xml @@ -1,6 +1,5 @@ - UPDATE %PREFIX%_components SET com_overview_plugin = 1 WHERE com_type = 'PLUGIN' AND com_name_intern = 'Calendar' - UpdateStepsCode::updateStep10RetrievePreviousSettings + UpdateStepsCode::updateStep10RetrievePreviousSettings stop diff --git a/plugins/event_list/db_scripts/update_1_0.xml b/plugins/event_list/db_scripts/update_1_0.xml index 4a12a79080..c0cffa9222 100644 --- a/plugins/event_list/db_scripts/update_1_0.xml +++ b/plugins/event_list/db_scripts/update_1_0.xml @@ -1,6 +1,5 @@ - UPDATE %PREFIX%_components SET com_overview_plugin = 1 WHERE com_type = 'PLUGIN' AND com_name_intern = 'EventList' - UpdateStepsCode::updateStep10RetrievePreviousSettings + UpdateStepsCode::updateStep10RetrievePreviousSettings stop diff --git a/plugins/latest_documents_files/db_scripts/update_1_0.xml b/plugins/latest_documents_files/db_scripts/update_1_0.xml index 653ffdb01b..c0cffa9222 100644 --- a/plugins/latest_documents_files/db_scripts/update_1_0.xml +++ b/plugins/latest_documents_files/db_scripts/update_1_0.xml @@ -1,6 +1,5 @@ - UPDATE %PREFIX%_components SET com_overview_plugin = 1 WHERE com_type = 'PLUGIN' AND com_name_intern = 'LatestDocumentsFiles' - UpdateStepsCode::updateStep10RetrievePreviousSettings + UpdateStepsCode::updateStep10RetrievePreviousSettings stop diff --git a/plugins/login_form/db_scripts/update_1_0.xml b/plugins/login_form/db_scripts/update_1_0.xml index 8902e0eaae..c0cffa9222 100644 --- a/plugins/login_form/db_scripts/update_1_0.xml +++ b/plugins/login_form/db_scripts/update_1_0.xml @@ -1,6 +1,5 @@ - UPDATE %PREFIX%_components SET com_overview_plugin = 1 WHERE com_type = 'PLUGIN' AND com_name_intern = 'LoginForm' - UpdateStepsCode::updateStep10RetrievePreviousSettings + UpdateStepsCode::updateStep10RetrievePreviousSettings stop diff --git a/plugins/random_photo/db_scripts/update_1_0.xml b/plugins/random_photo/db_scripts/update_1_0.xml index 02cf34e1ff..c0cffa9222 100644 --- a/plugins/random_photo/db_scripts/update_1_0.xml +++ b/plugins/random_photo/db_scripts/update_1_0.xml @@ -1,6 +1,5 @@ - UPDATE %PREFIX%_components SET com_overview_plugin = 1 WHERE com_type = 'PLUGIN' AND com_name_intern = 'RandomPhoto' - UpdateStepsCode::updateStep10RetrievePreviousSettings + UpdateStepsCode::updateStep10RetrievePreviousSettings stop diff --git a/plugins/who_is_online/db_scripts/update_1_0.xml b/plugins/who_is_online/db_scripts/update_1_0.xml index e82cda8412..c0cffa9222 100644 --- a/plugins/who_is_online/db_scripts/update_1_0.xml +++ b/plugins/who_is_online/db_scripts/update_1_0.xml @@ -1,6 +1,5 @@ - UPDATE %PREFIX%_components SET com_overview_plugin = 1 WHERE com_type = 'PLUGIN' AND com_name_intern = 'WhoIsOnline' - UpdateStepsCode::updateStep10RetrievePreviousSettings + UpdateStepsCode::updateStep10RetrievePreviousSettings stop From 5e660ca67a1484a22abbbaf29db4adeab5301ba8 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sun, 1 Feb 2026 16:01:47 +0100 Subject: [PATCH 097/109] fix: only install admidio plugins by default --- install/install_steps/start_installation.php | 7 ++++--- src/Infrastructure/Plugins/PluginAbstract.php | 2 +- src/InstallationUpdate/Service/UpdateStepsCode.php | 7 ++++--- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/install/install_steps/start_installation.php b/install/install_steps/start_installation.php index 9d3564cfa9..0fa31a4837 100644 --- a/install/install_steps/start_installation.php +++ b/install/install_steps/start_installation.php @@ -288,10 +288,11 @@ // install all overview plugins $pluginManager = new PluginManager(); $plugins = $pluginManager->getAvailablePlugins(); +$admidioOverviewPlugins = array('announcement_list', 'birthday', 'calendar', 'event_list', 'latest_documents_files', 'login_form', 'random_photo', 'who_is_online'); -foreach ($plugins as $plugin) { - $instance = $plugin['interface']::getInstance(); - if (isset($instance->getMetadata()['overviewPlugin']) && $instance->getMetadata()['overviewPlugin'] === true) { +foreach ($plugins as $pluginName => $plugin) { + if (in_array($pluginName, $admidioOverviewPlugins)) { + $instance = $plugin['interface']::getInstance(); // Install the overview plugin $instance->doInstall(); } diff --git a/src/Infrastructure/Plugins/PluginAbstract.php b/src/Infrastructure/Plugins/PluginAbstract.php index d51f9b24d0..14ae23dbe0 100644 --- a/src/Infrastructure/Plugins/PluginAbstract.php +++ b/src/Infrastructure/Plugins/PluginAbstract.php @@ -780,7 +780,7 @@ public static function doInstall(bool $addMenuEntry = true): bool array( 'com_type' => 'PLUGIN', 'com_name' => self::getName(), - 'com_name_intern' => basename(self::$pluginPath), + 'com_name_intern' => strtoupper(basename(self::$pluginPath)), 'com_overview_plugin' => self::$metadata['overviewPlugin'] ) ); diff --git a/src/InstallationUpdate/Service/UpdateStepsCode.php b/src/InstallationUpdate/Service/UpdateStepsCode.php index 6f8b7b7baf..77974ca717 100644 --- a/src/InstallationUpdate/Service/UpdateStepsCode.php +++ b/src/InstallationUpdate/Service/UpdateStepsCode.php @@ -135,10 +135,11 @@ public static function updateStep51InstallOverviewPlugins(): void $pluginManager = new PluginManager(); $plugins = $pluginManager->getAvailablePlugins(); + $admidioOverviewPlugins = array('announcement_list', 'birthday', 'calendar', 'event_list', 'latest_documents_files', 'login_form', 'random_photo', 'who_is_online'); - foreach ($plugins as $plugin) { - $instance = $plugin['interface']::getInstance(); - if (isset($instance->getMetadata()['overviewPlugin']) && $instance->getMetadata()['overviewPlugin'] === true) { + foreach ($plugins as $pluginName => $plugin) { + if (in_array($pluginName, $admidioOverviewPlugins)) { + $instance = $plugin['interface']::getInstance(); // Install the overview plugin $instance->doInstall(); } From 7adb9c9ec2ad60bdd900bd65b4ff812eb2f38da1 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sun, 1 Feb 2026 16:16:24 +0100 Subject: [PATCH 098/109] feat: add isAdmidioPlugin() method and update installation logic for Admidio plugins --- install/install_steps/start_installation.php | 7 +++---- src/Infrastructure/Plugins/PluginAbstract.php | 13 +++++++++++++ src/Infrastructure/Plugins/PluginInterface.php | 6 ++++++ src/InstallationUpdate/Service/UpdateStepsCode.php | 7 +++---- src/UI/Presenter/PluginsPresenter.php | 2 +- 5 files changed, 26 insertions(+), 9 deletions(-) diff --git a/install/install_steps/start_installation.php b/install/install_steps/start_installation.php index 0fa31a4837..e87923a0c6 100644 --- a/install/install_steps/start_installation.php +++ b/install/install_steps/start_installation.php @@ -288,11 +288,10 @@ // install all overview plugins $pluginManager = new PluginManager(); $plugins = $pluginManager->getAvailablePlugins(); -$admidioOverviewPlugins = array('announcement_list', 'birthday', 'calendar', 'event_list', 'latest_documents_files', 'login_form', 'random_photo', 'who_is_online'); -foreach ($plugins as $pluginName => $plugin) { - if (in_array($pluginName, $admidioOverviewPlugins)) { - $instance = $plugin['interface']::getInstance(); +foreach ($plugins as $plugin) { + $instance = $plugin['interface']::getInstance(); + if ($instance->isAdmidioPlugin()) { // Install the overview plugin $instance->doInstall(); } diff --git a/src/Infrastructure/Plugins/PluginAbstract.php b/src/Infrastructure/Plugins/PluginAbstract.php index 14ae23dbe0..9988ebd62f 100644 --- a/src/Infrastructure/Plugins/PluginAbstract.php +++ b/src/Infrastructure/Plugins/PluginAbstract.php @@ -612,6 +612,19 @@ public static function isOverviewPlugin(): bool return $columns > 0; } + /** + * @return bool + * @throws Exception + */ + public static function isAdmidioPlugin(): bool + { + $admidioOverviewPlugins = array('announcement_list', 'birthday', 'calendar', 'event_list', 'latest_documents_files', 'login_form', 'random_photo', 'who_is_online'); + + if (in_array(strtolower(self::getComponentName()), $admidioOverviewPlugins)) { + return true; + } + return false; + } /** * @return bool * @throws Exception diff --git a/src/Infrastructure/Plugins/PluginInterface.php b/src/Infrastructure/Plugins/PluginInterface.php index 9f5fd52bbd..a4ce2fc33a 100644 --- a/src/Infrastructure/Plugins/PluginInterface.php +++ b/src/Infrastructure/Plugins/PluginInterface.php @@ -108,6 +108,12 @@ public static function isVisible(): bool; */ public static function isOverviewPlugin(): bool; + /** + * @return bool + * @throws Exception + */ + public static function isAdmidioPlugin(): bool; + /** * @return bool * @throws Exception diff --git a/src/InstallationUpdate/Service/UpdateStepsCode.php b/src/InstallationUpdate/Service/UpdateStepsCode.php index 77974ca717..44b2097395 100644 --- a/src/InstallationUpdate/Service/UpdateStepsCode.php +++ b/src/InstallationUpdate/Service/UpdateStepsCode.php @@ -135,11 +135,10 @@ public static function updateStep51InstallOverviewPlugins(): void $pluginManager = new PluginManager(); $plugins = $pluginManager->getAvailablePlugins(); - $admidioOverviewPlugins = array('announcement_list', 'birthday', 'calendar', 'event_list', 'latest_documents_files', 'login_form', 'random_photo', 'who_is_online'); - foreach ($plugins as $pluginName => $plugin) { - if (in_array($pluginName, $admidioOverviewPlugins)) { - $instance = $plugin['interface']::getInstance(); + foreach ($plugins as $plugin) { + $instance = $plugin['interface']::getInstance(); + if ($instance->isAdmidioPlugin()) { // Install the overview plugin $instance->doInstall(); } diff --git a/src/UI/Presenter/PluginsPresenter.php b/src/UI/Presenter/PluginsPresenter.php index 1ed71e98c1..78d54361bf 100644 --- a/src/UI/Presenter/PluginsPresenter.php +++ b/src/UI/Presenter/PluginsPresenter.php @@ -147,7 +147,7 @@ public function prepareData(): void 'tooltip' => $gL10n->get('SYS_PLUGIN_UPDATE') ); } - if (!$interface->isOverviewPlugin()) { + if (!$interface->isAdmidioPlugin()) { // add uninstall action $templateRow['actions'][] = array( 'url' => SecurityUtils::encodeUrl(ADMIDIO_URL . FOLDER_MODULES . '/plugins.php', array('mode' => 'uninstall', 'name' => $pluginName)), From ad7f79ebe332a9158ddd812c2c251c5a711bb158 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sun, 1 Feb 2026 18:52:59 +0100 Subject: [PATCH 099/109] Update composer.lock --- composer.lock | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/composer.lock b/composer.lock index 9bfbf9da4d..ef980fc70d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "eefd88e82bdb246e8126f1287c84737b", + "content-hash": "9963b82f17dc3d560c114b2bd9b3cf4e", "packages": [ { "name": "bjeavons/zxcvbn-php", @@ -64,16 +64,16 @@ }, { "name": "brick/math", - "version": "0.14.1", + "version": "0.14.2", "source": { "type": "git", "url": "https://github.com/brick/math.git", - "reference": "f05858549e5f9d7bb45875a75583240a38a281d0" + "reference": "55c950aa71a2cabc1d8f2bec1f8a7020bd244aa2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/f05858549e5f9d7bb45875a75583240a38a281d0", - "reference": "f05858549e5f9d7bb45875a75583240a38a281d0", + "url": "https://api.github.com/repos/brick/math/zipball/55c950aa71a2cabc1d8f2bec1f8a7020bd244aa2", + "reference": "55c950aa71a2cabc1d8f2bec1f8a7020bd244aa2", "shasum": "" }, "require": { @@ -112,7 +112,7 @@ ], "support": { "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.14.1" + "source": "https://github.com/brick/math/tree/0.14.2" }, "funding": [ { @@ -120,7 +120,7 @@ "type": "github" } ], - "time": "2025-11-24T14:40:29+00:00" + "time": "2026-01-30T14:03:11+00:00" }, { "name": "composer/pcre", @@ -2674,16 +2674,16 @@ }, { "name": "symfony/http-foundation", - "version": "v7.4.3", + "version": "v7.4.5", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "a70c745d4cea48dbd609f4075e5f5cbce453bd52" + "reference": "446d0db2b1f21575f1284b74533e425096abdfb6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/a70c745d4cea48dbd609f4075e5f5cbce453bd52", - "reference": "a70c745d4cea48dbd609f4075e5f5cbce453bd52", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/446d0db2b1f21575f1284b74533e425096abdfb6", + "reference": "446d0db2b1f21575f1284b74533e425096abdfb6", "shasum": "" }, "require": { @@ -2732,7 +2732,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v7.4.3" + "source": "https://github.com/symfony/http-foundation/tree/v7.4.5" }, "funding": [ { @@ -2752,7 +2752,7 @@ "type": "tidelift" } ], - "time": "2025-12-23T14:23:49+00:00" + "time": "2026-01-27T16:16:02+00:00" }, { "name": "symfony/polyfill-mbstring", @@ -3012,7 +3012,6 @@ "ext-iconv": "*", "ext-json": "*", "ext-pdo": "*", - "ext-posix": "*", "ext-simplexml": "*", "ext-zip": "*" }, @@ -3020,5 +3019,5 @@ "platform-overrides": { "php": "8.2.0" }, - "plugin-api-version": "2.9.0" + "plugin-api-version": "2.6.0" } From 9095ce6c6c8cffd0c3892e45df8c0370f840016e Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sat, 7 Feb 2026 12:22:28 +0100 Subject: [PATCH 100/109] fix: skip plugins without an interface during installation --- install/install_steps/start_installation.php | 5 +++++ src/InstallationUpdate/Service/UpdateStepsCode.php | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/install/install_steps/start_installation.php b/install/install_steps/start_installation.php index fbab48f2a6..6f8e679c7c 100644 --- a/install/install_steps/start_installation.php +++ b/install/install_steps/start_installation.php @@ -291,6 +291,11 @@ $plugins = $pluginManager->getAvailablePlugins(); foreach ($plugins as $plugin) { + // check, if the plugin has an interface, if not, scip it + if (!isset($plugin['interface']) || $plugin['interface'] == null) { + continue; + } + // check if the plugin is an overview plugin, if so, install it $instance = $plugin['interface']::getInstance(); if ($instance->isAdmidioPlugin()) { // Install the overview plugin diff --git a/src/InstallationUpdate/Service/UpdateStepsCode.php b/src/InstallationUpdate/Service/UpdateStepsCode.php index e477058fe1..a8b12f93dc 100644 --- a/src/InstallationUpdate/Service/UpdateStepsCode.php +++ b/src/InstallationUpdate/Service/UpdateStepsCode.php @@ -137,6 +137,11 @@ public static function updateStep51InstallOverviewPlugins(): void $plugins = $pluginManager->getAvailablePlugins(); foreach ($plugins as $plugin) { + // check, if the plugin has an interface, if not, scip it + if (!isset($plugin['interface']) || $plugin['interface'] == null) { + continue; + } + // check if the plugin is an overview plugin, if so, install it $instance = $plugin['interface']::getInstance(); if ($instance->isAdmidioPlugin()) { // Install the overview plugin From 139dc29d79c5ab95c973a383d6c50d4e57e49889 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sat, 7 Feb 2026 12:38:13 +0100 Subject: [PATCH 101/109] fix: update plugin directory names to use hyphens instead of underscores --- .gitignore | 12 ++++++------ composer.json | 12 ++++++------ src/Infrastructure/Plugins/PluginAbstract.php | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index de5ba8562d..5898032709 100644 --- a/.gitignore +++ b/.gitignore @@ -13,12 +13,12 @@ /plugins/* !/plugins/birthday/ !/plugins/calendar/ -!/plugins/login_form/ -!/plugins/random_photo/ -!/plugins/announcement_list/ -!/plugins/event_list/ -!/plugins/latest_documents_files/ -!/plugins/who_is_online/ +!/plugins/login-form/ +!/plugins/random-photo/ +!/plugins/announcement-list/ +!/plugins/event-list/ +!/plugins/latest-documents-files/ +!/plugins/who-is-online/ # Only allow commit of official themes diff --git a/composer.json b/composer.json index 29b4b2216e..5c5139bf71 100644 --- a/composer.json +++ b/composer.json @@ -67,14 +67,14 @@ "!adm_my_files/ecard_templates", "!adm_my_files/mail_templates", "plugins/*", - "!plugins/announcement_list", + "!plugins/announcement-list", "!plugins/birthday", "!plugins/calendar", - "!plugins/event_list", - "!plugins/latest_documents_files", - "!plugins/login_form", - "!plugins/random_photo", - "!plugins/who_is_online", + "!plugins/event-list", + "!plugins/latest-documents-files", + "!plugins/login-form", + "!plugins/random-photo", + "!plugins/who-is-online", "demo_data", "!vendor/*", "vendor/maennchen/zipstream-php/test", diff --git a/src/Infrastructure/Plugins/PluginAbstract.php b/src/Infrastructure/Plugins/PluginAbstract.php index 9988ebd62f..4b0ac8088f 100644 --- a/src/Infrastructure/Plugins/PluginAbstract.php +++ b/src/Infrastructure/Plugins/PluginAbstract.php @@ -618,7 +618,7 @@ public static function isOverviewPlugin(): bool */ public static function isAdmidioPlugin(): bool { - $admidioOverviewPlugins = array('announcement_list', 'birthday', 'calendar', 'event_list', 'latest_documents_files', 'login_form', 'random_photo', 'who_is_online'); + $admidioOverviewPlugins = array('announcement-list', 'birthday', 'calendar', 'event-list', 'latest-documents-files', 'login-form', 'random-photo', 'who-is-online'); if (in_array(strtolower(self::getComponentName()), $admidioOverviewPlugins)) { return true; From b95a7ab16f06f517a3698e0dd55d64da384fdd70 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sat, 7 Feb 2026 12:58:20 +0100 Subject: [PATCH 102/109] fix: reset update warnings cookie after reading values --- install/update.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/install/update.php b/install/update.php index 19a55b7c92..29288c3d90 100644 --- a/install/update.php +++ b/install/update.php @@ -330,6 +330,9 @@ function showErrorMessage(string $message, bool $reloadPage = false): void } } + // reset the cookie after reading the values so that the warnings are only shown once + setcookie('adm_update_plugins_warnings', '', time() - 3600, '/'); + if ($gWarnOldPlugins) { $updateWarnings[] = array( 'id' => 'warn_old_plugins', From dbedde3f878508aa375faabfe7383fd4821ccd5a Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sat, 7 Feb 2026 14:52:06 +0100 Subject: [PATCH 103/109] fix: rename announcement list plugin --- .../announcement-list.json} | 0 .../classes/AnnouncementList.php | 0 .../classes/Presenter/AnnouncementListPreferencesPresenter.php | 0 .../classes/Service/UpdateStepsCode.php | 0 .../db_scripts/update_1_0.xml | 0 plugins/{announcement_list => announcement-list}/index.php | 0 plugins/{announcement_list => announcement-list}/languages/bg.xml | 0 plugins/{announcement_list => announcement-list}/languages/da.xml | 0 .../{announcement_list => announcement-list}/languages/de-DE.xml | 0 plugins/{announcement_list => announcement-list}/languages/de.xml | 0 plugins/{announcement_list => announcement-list}/languages/el.xml | 0 plugins/{announcement_list => announcement-list}/languages/en.xml | 0 plugins/{announcement_list => announcement-list}/languages/es.xml | 0 plugins/{announcement_list => announcement-list}/languages/et.xml | 0 plugins/{announcement_list => announcement-list}/languages/fi.xml | 0 plugins/{announcement_list => announcement-list}/languages/fr.xml | 0 plugins/{announcement_list => announcement-list}/languages/hu.xml | 0 plugins/{announcement_list => announcement-list}/languages/nb.xml | 0 plugins/{announcement_list => announcement-list}/languages/nl.xml | 0 plugins/{announcement_list => announcement-list}/languages/pl.xml | 0 .../{announcement_list => announcement-list}/languages/pt-BR.xml | 0 plugins/{announcement_list => announcement-list}/languages/pt.xml | 0 plugins/{announcement_list => announcement-list}/languages/ru.xml | 0 plugins/{announcement_list => announcement-list}/languages/sv.xml | 0 plugins/{announcement_list => announcement-list}/languages/uk.xml | 0 .../templates/plugin.announcement-list.tpl | 0 .../templates/preferences.plugin.announcement-list.tpl | 0 27 files changed, 0 insertions(+), 0 deletions(-) rename plugins/{announcement_list/announcement_list.json => announcement-list/announcement-list.json} (100%) rename plugins/{announcement_list => announcement-list}/classes/AnnouncementList.php (100%) rename plugins/{announcement_list => announcement-list}/classes/Presenter/AnnouncementListPreferencesPresenter.php (100%) rename plugins/{announcement_list => announcement-list}/classes/Service/UpdateStepsCode.php (100%) rename plugins/{announcement_list => announcement-list}/db_scripts/update_1_0.xml (100%) rename plugins/{announcement_list => announcement-list}/index.php (100%) rename plugins/{announcement_list => announcement-list}/languages/bg.xml (100%) rename plugins/{announcement_list => announcement-list}/languages/da.xml (100%) rename plugins/{announcement_list => announcement-list}/languages/de-DE.xml (100%) rename plugins/{announcement_list => announcement-list}/languages/de.xml (100%) rename plugins/{announcement_list => announcement-list}/languages/el.xml (100%) rename plugins/{announcement_list => announcement-list}/languages/en.xml (100%) rename plugins/{announcement_list => announcement-list}/languages/es.xml (100%) rename plugins/{announcement_list => announcement-list}/languages/et.xml (100%) rename plugins/{announcement_list => announcement-list}/languages/fi.xml (100%) rename plugins/{announcement_list => announcement-list}/languages/fr.xml (100%) rename plugins/{announcement_list => announcement-list}/languages/hu.xml (100%) rename plugins/{announcement_list => announcement-list}/languages/nb.xml (100%) rename plugins/{announcement_list => announcement-list}/languages/nl.xml (100%) rename plugins/{announcement_list => announcement-list}/languages/pl.xml (100%) rename plugins/{announcement_list => announcement-list}/languages/pt-BR.xml (100%) rename plugins/{announcement_list => announcement-list}/languages/pt.xml (100%) rename plugins/{announcement_list => announcement-list}/languages/ru.xml (100%) rename plugins/{announcement_list => announcement-list}/languages/sv.xml (100%) rename plugins/{announcement_list => announcement-list}/languages/uk.xml (100%) rename plugins/{announcement_list => announcement-list}/templates/plugin.announcement-list.tpl (100%) rename plugins/{announcement_list => announcement-list}/templates/preferences.plugin.announcement-list.tpl (100%) diff --git a/plugins/announcement_list/announcement_list.json b/plugins/announcement-list/announcement-list.json similarity index 100% rename from plugins/announcement_list/announcement_list.json rename to plugins/announcement-list/announcement-list.json diff --git a/plugins/announcement_list/classes/AnnouncementList.php b/plugins/announcement-list/classes/AnnouncementList.php similarity index 100% rename from plugins/announcement_list/classes/AnnouncementList.php rename to plugins/announcement-list/classes/AnnouncementList.php diff --git a/plugins/announcement_list/classes/Presenter/AnnouncementListPreferencesPresenter.php b/plugins/announcement-list/classes/Presenter/AnnouncementListPreferencesPresenter.php similarity index 100% rename from plugins/announcement_list/classes/Presenter/AnnouncementListPreferencesPresenter.php rename to plugins/announcement-list/classes/Presenter/AnnouncementListPreferencesPresenter.php diff --git a/plugins/announcement_list/classes/Service/UpdateStepsCode.php b/plugins/announcement-list/classes/Service/UpdateStepsCode.php similarity index 100% rename from plugins/announcement_list/classes/Service/UpdateStepsCode.php rename to plugins/announcement-list/classes/Service/UpdateStepsCode.php diff --git a/plugins/announcement_list/db_scripts/update_1_0.xml b/plugins/announcement-list/db_scripts/update_1_0.xml similarity index 100% rename from plugins/announcement_list/db_scripts/update_1_0.xml rename to plugins/announcement-list/db_scripts/update_1_0.xml diff --git a/plugins/announcement_list/index.php b/plugins/announcement-list/index.php similarity index 100% rename from plugins/announcement_list/index.php rename to plugins/announcement-list/index.php diff --git a/plugins/announcement_list/languages/bg.xml b/plugins/announcement-list/languages/bg.xml similarity index 100% rename from plugins/announcement_list/languages/bg.xml rename to plugins/announcement-list/languages/bg.xml diff --git a/plugins/announcement_list/languages/da.xml b/plugins/announcement-list/languages/da.xml similarity index 100% rename from plugins/announcement_list/languages/da.xml rename to plugins/announcement-list/languages/da.xml diff --git a/plugins/announcement_list/languages/de-DE.xml b/plugins/announcement-list/languages/de-DE.xml similarity index 100% rename from plugins/announcement_list/languages/de-DE.xml rename to plugins/announcement-list/languages/de-DE.xml diff --git a/plugins/announcement_list/languages/de.xml b/plugins/announcement-list/languages/de.xml similarity index 100% rename from plugins/announcement_list/languages/de.xml rename to plugins/announcement-list/languages/de.xml diff --git a/plugins/announcement_list/languages/el.xml b/plugins/announcement-list/languages/el.xml similarity index 100% rename from plugins/announcement_list/languages/el.xml rename to plugins/announcement-list/languages/el.xml diff --git a/plugins/announcement_list/languages/en.xml b/plugins/announcement-list/languages/en.xml similarity index 100% rename from plugins/announcement_list/languages/en.xml rename to plugins/announcement-list/languages/en.xml diff --git a/plugins/announcement_list/languages/es.xml b/plugins/announcement-list/languages/es.xml similarity index 100% rename from plugins/announcement_list/languages/es.xml rename to plugins/announcement-list/languages/es.xml diff --git a/plugins/announcement_list/languages/et.xml b/plugins/announcement-list/languages/et.xml similarity index 100% rename from plugins/announcement_list/languages/et.xml rename to plugins/announcement-list/languages/et.xml diff --git a/plugins/announcement_list/languages/fi.xml b/plugins/announcement-list/languages/fi.xml similarity index 100% rename from plugins/announcement_list/languages/fi.xml rename to plugins/announcement-list/languages/fi.xml diff --git a/plugins/announcement_list/languages/fr.xml b/plugins/announcement-list/languages/fr.xml similarity index 100% rename from plugins/announcement_list/languages/fr.xml rename to plugins/announcement-list/languages/fr.xml diff --git a/plugins/announcement_list/languages/hu.xml b/plugins/announcement-list/languages/hu.xml similarity index 100% rename from plugins/announcement_list/languages/hu.xml rename to plugins/announcement-list/languages/hu.xml diff --git a/plugins/announcement_list/languages/nb.xml b/plugins/announcement-list/languages/nb.xml similarity index 100% rename from plugins/announcement_list/languages/nb.xml rename to plugins/announcement-list/languages/nb.xml diff --git a/plugins/announcement_list/languages/nl.xml b/plugins/announcement-list/languages/nl.xml similarity index 100% rename from plugins/announcement_list/languages/nl.xml rename to plugins/announcement-list/languages/nl.xml diff --git a/plugins/announcement_list/languages/pl.xml b/plugins/announcement-list/languages/pl.xml similarity index 100% rename from plugins/announcement_list/languages/pl.xml rename to plugins/announcement-list/languages/pl.xml diff --git a/plugins/announcement_list/languages/pt-BR.xml b/plugins/announcement-list/languages/pt-BR.xml similarity index 100% rename from plugins/announcement_list/languages/pt-BR.xml rename to plugins/announcement-list/languages/pt-BR.xml diff --git a/plugins/announcement_list/languages/pt.xml b/plugins/announcement-list/languages/pt.xml similarity index 100% rename from plugins/announcement_list/languages/pt.xml rename to plugins/announcement-list/languages/pt.xml diff --git a/plugins/announcement_list/languages/ru.xml b/plugins/announcement-list/languages/ru.xml similarity index 100% rename from plugins/announcement_list/languages/ru.xml rename to plugins/announcement-list/languages/ru.xml diff --git a/plugins/announcement_list/languages/sv.xml b/plugins/announcement-list/languages/sv.xml similarity index 100% rename from plugins/announcement_list/languages/sv.xml rename to plugins/announcement-list/languages/sv.xml diff --git a/plugins/announcement_list/languages/uk.xml b/plugins/announcement-list/languages/uk.xml similarity index 100% rename from plugins/announcement_list/languages/uk.xml rename to plugins/announcement-list/languages/uk.xml diff --git a/plugins/announcement_list/templates/plugin.announcement-list.tpl b/plugins/announcement-list/templates/plugin.announcement-list.tpl similarity index 100% rename from plugins/announcement_list/templates/plugin.announcement-list.tpl rename to plugins/announcement-list/templates/plugin.announcement-list.tpl diff --git a/plugins/announcement_list/templates/preferences.plugin.announcement-list.tpl b/plugins/announcement-list/templates/preferences.plugin.announcement-list.tpl similarity index 100% rename from plugins/announcement_list/templates/preferences.plugin.announcement-list.tpl rename to plugins/announcement-list/templates/preferences.plugin.announcement-list.tpl From 0ace784bb032ba5524cbb5178b5f5926d250c5f5 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sat, 7 Feb 2026 14:52:52 +0100 Subject: [PATCH 104/109] fix: rename event list plugin --- plugins/{event_list => event-list}/classes/EventList.php | 0 .../classes/Presenter/EventListPreferencesPresenter.php | 0 .../classes/Service/UpdateStepsCode.php | 0 plugins/{event_list => event-list}/db_scripts/update_1_0.xml | 0 .../{event_list/event_list.json => event-list/event-list.json} | 0 plugins/{event_list => event-list}/index.php | 0 plugins/{event_list => event-list}/languages/bg.xml | 0 plugins/{event_list => event-list}/languages/da.xml | 0 plugins/{event_list => event-list}/languages/de-DE.xml | 0 plugins/{event_list => event-list}/languages/de.xml | 0 plugins/{event_list => event-list}/languages/el.xml | 0 plugins/{event_list => event-list}/languages/en.xml | 0 plugins/{event_list => event-list}/languages/es.xml | 0 plugins/{event_list => event-list}/languages/et.xml | 0 plugins/{event_list => event-list}/languages/fi.xml | 0 plugins/{event_list => event-list}/languages/fr.xml | 0 plugins/{event_list => event-list}/languages/hu.xml | 0 plugins/{event_list => event-list}/languages/nb.xml | 0 plugins/{event_list => event-list}/languages/nl.xml | 0 plugins/{event_list => event-list}/languages/pl.xml | 0 plugins/{event_list => event-list}/languages/pt-BR.xml | 0 plugins/{event_list => event-list}/languages/pt.xml | 0 plugins/{event_list => event-list}/languages/ru.xml | 0 plugins/{event_list => event-list}/languages/sv.xml | 0 plugins/{event_list => event-list}/languages/uk.xml | 0 plugins/{event_list => event-list}/languages/zh.xml | 0 .../{event_list => event-list}/templates/plugin.event-list.tpl | 0 .../templates/preferences.plugin.event-list.tpl | 0 28 files changed, 0 insertions(+), 0 deletions(-) rename plugins/{event_list => event-list}/classes/EventList.php (100%) rename plugins/{event_list => event-list}/classes/Presenter/EventListPreferencesPresenter.php (100%) rename plugins/{event_list => event-list}/classes/Service/UpdateStepsCode.php (100%) rename plugins/{event_list => event-list}/db_scripts/update_1_0.xml (100%) rename plugins/{event_list/event_list.json => event-list/event-list.json} (100%) rename plugins/{event_list => event-list}/index.php (100%) rename plugins/{event_list => event-list}/languages/bg.xml (100%) rename plugins/{event_list => event-list}/languages/da.xml (100%) rename plugins/{event_list => event-list}/languages/de-DE.xml (100%) rename plugins/{event_list => event-list}/languages/de.xml (100%) rename plugins/{event_list => event-list}/languages/el.xml (100%) rename plugins/{event_list => event-list}/languages/en.xml (100%) rename plugins/{event_list => event-list}/languages/es.xml (100%) rename plugins/{event_list => event-list}/languages/et.xml (100%) rename plugins/{event_list => event-list}/languages/fi.xml (100%) rename plugins/{event_list => event-list}/languages/fr.xml (100%) rename plugins/{event_list => event-list}/languages/hu.xml (100%) rename plugins/{event_list => event-list}/languages/nb.xml (100%) rename plugins/{event_list => event-list}/languages/nl.xml (100%) rename plugins/{event_list => event-list}/languages/pl.xml (100%) rename plugins/{event_list => event-list}/languages/pt-BR.xml (100%) rename plugins/{event_list => event-list}/languages/pt.xml (100%) rename plugins/{event_list => event-list}/languages/ru.xml (100%) rename plugins/{event_list => event-list}/languages/sv.xml (100%) rename plugins/{event_list => event-list}/languages/uk.xml (100%) rename plugins/{event_list => event-list}/languages/zh.xml (100%) rename plugins/{event_list => event-list}/templates/plugin.event-list.tpl (100%) rename plugins/{event_list => event-list}/templates/preferences.plugin.event-list.tpl (100%) diff --git a/plugins/event_list/classes/EventList.php b/plugins/event-list/classes/EventList.php similarity index 100% rename from plugins/event_list/classes/EventList.php rename to plugins/event-list/classes/EventList.php diff --git a/plugins/event_list/classes/Presenter/EventListPreferencesPresenter.php b/plugins/event-list/classes/Presenter/EventListPreferencesPresenter.php similarity index 100% rename from plugins/event_list/classes/Presenter/EventListPreferencesPresenter.php rename to plugins/event-list/classes/Presenter/EventListPreferencesPresenter.php diff --git a/plugins/event_list/classes/Service/UpdateStepsCode.php b/plugins/event-list/classes/Service/UpdateStepsCode.php similarity index 100% rename from plugins/event_list/classes/Service/UpdateStepsCode.php rename to plugins/event-list/classes/Service/UpdateStepsCode.php diff --git a/plugins/event_list/db_scripts/update_1_0.xml b/plugins/event-list/db_scripts/update_1_0.xml similarity index 100% rename from plugins/event_list/db_scripts/update_1_0.xml rename to plugins/event-list/db_scripts/update_1_0.xml diff --git a/plugins/event_list/event_list.json b/plugins/event-list/event-list.json similarity index 100% rename from plugins/event_list/event_list.json rename to plugins/event-list/event-list.json diff --git a/plugins/event_list/index.php b/plugins/event-list/index.php similarity index 100% rename from plugins/event_list/index.php rename to plugins/event-list/index.php diff --git a/plugins/event_list/languages/bg.xml b/plugins/event-list/languages/bg.xml similarity index 100% rename from plugins/event_list/languages/bg.xml rename to plugins/event-list/languages/bg.xml diff --git a/plugins/event_list/languages/da.xml b/plugins/event-list/languages/da.xml similarity index 100% rename from plugins/event_list/languages/da.xml rename to plugins/event-list/languages/da.xml diff --git a/plugins/event_list/languages/de-DE.xml b/plugins/event-list/languages/de-DE.xml similarity index 100% rename from plugins/event_list/languages/de-DE.xml rename to plugins/event-list/languages/de-DE.xml diff --git a/plugins/event_list/languages/de.xml b/plugins/event-list/languages/de.xml similarity index 100% rename from plugins/event_list/languages/de.xml rename to plugins/event-list/languages/de.xml diff --git a/plugins/event_list/languages/el.xml b/plugins/event-list/languages/el.xml similarity index 100% rename from plugins/event_list/languages/el.xml rename to plugins/event-list/languages/el.xml diff --git a/plugins/event_list/languages/en.xml b/plugins/event-list/languages/en.xml similarity index 100% rename from plugins/event_list/languages/en.xml rename to plugins/event-list/languages/en.xml diff --git a/plugins/event_list/languages/es.xml b/plugins/event-list/languages/es.xml similarity index 100% rename from plugins/event_list/languages/es.xml rename to plugins/event-list/languages/es.xml diff --git a/plugins/event_list/languages/et.xml b/plugins/event-list/languages/et.xml similarity index 100% rename from plugins/event_list/languages/et.xml rename to plugins/event-list/languages/et.xml diff --git a/plugins/event_list/languages/fi.xml b/plugins/event-list/languages/fi.xml similarity index 100% rename from plugins/event_list/languages/fi.xml rename to plugins/event-list/languages/fi.xml diff --git a/plugins/event_list/languages/fr.xml b/plugins/event-list/languages/fr.xml similarity index 100% rename from plugins/event_list/languages/fr.xml rename to plugins/event-list/languages/fr.xml diff --git a/plugins/event_list/languages/hu.xml b/plugins/event-list/languages/hu.xml similarity index 100% rename from plugins/event_list/languages/hu.xml rename to plugins/event-list/languages/hu.xml diff --git a/plugins/event_list/languages/nb.xml b/plugins/event-list/languages/nb.xml similarity index 100% rename from plugins/event_list/languages/nb.xml rename to plugins/event-list/languages/nb.xml diff --git a/plugins/event_list/languages/nl.xml b/plugins/event-list/languages/nl.xml similarity index 100% rename from plugins/event_list/languages/nl.xml rename to plugins/event-list/languages/nl.xml diff --git a/plugins/event_list/languages/pl.xml b/plugins/event-list/languages/pl.xml similarity index 100% rename from plugins/event_list/languages/pl.xml rename to plugins/event-list/languages/pl.xml diff --git a/plugins/event_list/languages/pt-BR.xml b/plugins/event-list/languages/pt-BR.xml similarity index 100% rename from plugins/event_list/languages/pt-BR.xml rename to plugins/event-list/languages/pt-BR.xml diff --git a/plugins/event_list/languages/pt.xml b/plugins/event-list/languages/pt.xml similarity index 100% rename from plugins/event_list/languages/pt.xml rename to plugins/event-list/languages/pt.xml diff --git a/plugins/event_list/languages/ru.xml b/plugins/event-list/languages/ru.xml similarity index 100% rename from plugins/event_list/languages/ru.xml rename to plugins/event-list/languages/ru.xml diff --git a/plugins/event_list/languages/sv.xml b/plugins/event-list/languages/sv.xml similarity index 100% rename from plugins/event_list/languages/sv.xml rename to plugins/event-list/languages/sv.xml diff --git a/plugins/event_list/languages/uk.xml b/plugins/event-list/languages/uk.xml similarity index 100% rename from plugins/event_list/languages/uk.xml rename to plugins/event-list/languages/uk.xml diff --git a/plugins/event_list/languages/zh.xml b/plugins/event-list/languages/zh.xml similarity index 100% rename from plugins/event_list/languages/zh.xml rename to plugins/event-list/languages/zh.xml diff --git a/plugins/event_list/templates/plugin.event-list.tpl b/plugins/event-list/templates/plugin.event-list.tpl similarity index 100% rename from plugins/event_list/templates/plugin.event-list.tpl rename to plugins/event-list/templates/plugin.event-list.tpl diff --git a/plugins/event_list/templates/preferences.plugin.event-list.tpl b/plugins/event-list/templates/preferences.plugin.event-list.tpl similarity index 100% rename from plugins/event_list/templates/preferences.plugin.event-list.tpl rename to plugins/event-list/templates/preferences.plugin.event-list.tpl From 5a2c9985fff40c1f60f8a33fb83179b60b8537a8 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sat, 7 Feb 2026 14:53:41 +0100 Subject: [PATCH 105/109] fix: rename latest documents files plugin --- .../classes/LatestDocumentsFiles.php | 0 .../Presenter/LatestDocumentsFilesPreferencesPresenter.php | 0 .../classes/Service/UpdateStepsCode.php | 0 .../db_scripts/update_1_0.xml | 0 .../{latest_documents_files => latest-documents-files}/index.php | 0 .../languages/bg.xml | 0 .../languages/da.xml | 0 .../languages/de-DE.xml | 0 .../languages/de.xml | 0 .../languages/el.xml | 0 .../languages/en.xml | 0 .../languages/es.xml | 0 .../languages/et.xml | 0 .../languages/fi.xml | 0 .../languages/fr.xml | 0 .../languages/hu.xml | 0 .../languages/nb.xml | 0 .../languages/nl.xml | 0 .../languages/pl.xml | 0 .../languages/pt-BR.xml | 0 .../languages/pt.xml | 0 .../languages/ru.xml | 0 .../languages/sv.xml | 0 .../languages/uk.xml | 0 .../languages/zh.xml | 0 .../latest-documents-files.json} | 0 .../templates/plugin.latest-documents-files.tpl | 0 .../templates/preferences.plugin.latest-documents-files.tpl | 0 28 files changed, 0 insertions(+), 0 deletions(-) rename plugins/{latest_documents_files => latest-documents-files}/classes/LatestDocumentsFiles.php (100%) rename plugins/{latest_documents_files => latest-documents-files}/classes/Presenter/LatestDocumentsFilesPreferencesPresenter.php (100%) rename plugins/{latest_documents_files => latest-documents-files}/classes/Service/UpdateStepsCode.php (100%) rename plugins/{latest_documents_files => latest-documents-files}/db_scripts/update_1_0.xml (100%) rename plugins/{latest_documents_files => latest-documents-files}/index.php (100%) rename plugins/{latest_documents_files => latest-documents-files}/languages/bg.xml (100%) rename plugins/{latest_documents_files => latest-documents-files}/languages/da.xml (100%) rename plugins/{latest_documents_files => latest-documents-files}/languages/de-DE.xml (100%) rename plugins/{latest_documents_files => latest-documents-files}/languages/de.xml (100%) rename plugins/{latest_documents_files => latest-documents-files}/languages/el.xml (100%) rename plugins/{latest_documents_files => latest-documents-files}/languages/en.xml (100%) rename plugins/{latest_documents_files => latest-documents-files}/languages/es.xml (100%) rename plugins/{latest_documents_files => latest-documents-files}/languages/et.xml (100%) rename plugins/{latest_documents_files => latest-documents-files}/languages/fi.xml (100%) rename plugins/{latest_documents_files => latest-documents-files}/languages/fr.xml (100%) rename plugins/{latest_documents_files => latest-documents-files}/languages/hu.xml (100%) rename plugins/{latest_documents_files => latest-documents-files}/languages/nb.xml (100%) rename plugins/{latest_documents_files => latest-documents-files}/languages/nl.xml (100%) rename plugins/{latest_documents_files => latest-documents-files}/languages/pl.xml (100%) rename plugins/{latest_documents_files => latest-documents-files}/languages/pt-BR.xml (100%) rename plugins/{latest_documents_files => latest-documents-files}/languages/pt.xml (100%) rename plugins/{latest_documents_files => latest-documents-files}/languages/ru.xml (100%) rename plugins/{latest_documents_files => latest-documents-files}/languages/sv.xml (100%) rename plugins/{latest_documents_files => latest-documents-files}/languages/uk.xml (100%) rename plugins/{latest_documents_files => latest-documents-files}/languages/zh.xml (100%) rename plugins/{latest_documents_files/latest_documents_files.json => latest-documents-files/latest-documents-files.json} (100%) rename plugins/{latest_documents_files => latest-documents-files}/templates/plugin.latest-documents-files.tpl (100%) rename plugins/{latest_documents_files => latest-documents-files}/templates/preferences.plugin.latest-documents-files.tpl (100%) diff --git a/plugins/latest_documents_files/classes/LatestDocumentsFiles.php b/plugins/latest-documents-files/classes/LatestDocumentsFiles.php similarity index 100% rename from plugins/latest_documents_files/classes/LatestDocumentsFiles.php rename to plugins/latest-documents-files/classes/LatestDocumentsFiles.php diff --git a/plugins/latest_documents_files/classes/Presenter/LatestDocumentsFilesPreferencesPresenter.php b/plugins/latest-documents-files/classes/Presenter/LatestDocumentsFilesPreferencesPresenter.php similarity index 100% rename from plugins/latest_documents_files/classes/Presenter/LatestDocumentsFilesPreferencesPresenter.php rename to plugins/latest-documents-files/classes/Presenter/LatestDocumentsFilesPreferencesPresenter.php diff --git a/plugins/latest_documents_files/classes/Service/UpdateStepsCode.php b/plugins/latest-documents-files/classes/Service/UpdateStepsCode.php similarity index 100% rename from plugins/latest_documents_files/classes/Service/UpdateStepsCode.php rename to plugins/latest-documents-files/classes/Service/UpdateStepsCode.php diff --git a/plugins/latest_documents_files/db_scripts/update_1_0.xml b/plugins/latest-documents-files/db_scripts/update_1_0.xml similarity index 100% rename from plugins/latest_documents_files/db_scripts/update_1_0.xml rename to plugins/latest-documents-files/db_scripts/update_1_0.xml diff --git a/plugins/latest_documents_files/index.php b/plugins/latest-documents-files/index.php similarity index 100% rename from plugins/latest_documents_files/index.php rename to plugins/latest-documents-files/index.php diff --git a/plugins/latest_documents_files/languages/bg.xml b/plugins/latest-documents-files/languages/bg.xml similarity index 100% rename from plugins/latest_documents_files/languages/bg.xml rename to plugins/latest-documents-files/languages/bg.xml diff --git a/plugins/latest_documents_files/languages/da.xml b/plugins/latest-documents-files/languages/da.xml similarity index 100% rename from plugins/latest_documents_files/languages/da.xml rename to plugins/latest-documents-files/languages/da.xml diff --git a/plugins/latest_documents_files/languages/de-DE.xml b/plugins/latest-documents-files/languages/de-DE.xml similarity index 100% rename from plugins/latest_documents_files/languages/de-DE.xml rename to plugins/latest-documents-files/languages/de-DE.xml diff --git a/plugins/latest_documents_files/languages/de.xml b/plugins/latest-documents-files/languages/de.xml similarity index 100% rename from plugins/latest_documents_files/languages/de.xml rename to plugins/latest-documents-files/languages/de.xml diff --git a/plugins/latest_documents_files/languages/el.xml b/plugins/latest-documents-files/languages/el.xml similarity index 100% rename from plugins/latest_documents_files/languages/el.xml rename to plugins/latest-documents-files/languages/el.xml diff --git a/plugins/latest_documents_files/languages/en.xml b/plugins/latest-documents-files/languages/en.xml similarity index 100% rename from plugins/latest_documents_files/languages/en.xml rename to plugins/latest-documents-files/languages/en.xml diff --git a/plugins/latest_documents_files/languages/es.xml b/plugins/latest-documents-files/languages/es.xml similarity index 100% rename from plugins/latest_documents_files/languages/es.xml rename to plugins/latest-documents-files/languages/es.xml diff --git a/plugins/latest_documents_files/languages/et.xml b/plugins/latest-documents-files/languages/et.xml similarity index 100% rename from plugins/latest_documents_files/languages/et.xml rename to plugins/latest-documents-files/languages/et.xml diff --git a/plugins/latest_documents_files/languages/fi.xml b/plugins/latest-documents-files/languages/fi.xml similarity index 100% rename from plugins/latest_documents_files/languages/fi.xml rename to plugins/latest-documents-files/languages/fi.xml diff --git a/plugins/latest_documents_files/languages/fr.xml b/plugins/latest-documents-files/languages/fr.xml similarity index 100% rename from plugins/latest_documents_files/languages/fr.xml rename to plugins/latest-documents-files/languages/fr.xml diff --git a/plugins/latest_documents_files/languages/hu.xml b/plugins/latest-documents-files/languages/hu.xml similarity index 100% rename from plugins/latest_documents_files/languages/hu.xml rename to plugins/latest-documents-files/languages/hu.xml diff --git a/plugins/latest_documents_files/languages/nb.xml b/plugins/latest-documents-files/languages/nb.xml similarity index 100% rename from plugins/latest_documents_files/languages/nb.xml rename to plugins/latest-documents-files/languages/nb.xml diff --git a/plugins/latest_documents_files/languages/nl.xml b/plugins/latest-documents-files/languages/nl.xml similarity index 100% rename from plugins/latest_documents_files/languages/nl.xml rename to plugins/latest-documents-files/languages/nl.xml diff --git a/plugins/latest_documents_files/languages/pl.xml b/plugins/latest-documents-files/languages/pl.xml similarity index 100% rename from plugins/latest_documents_files/languages/pl.xml rename to plugins/latest-documents-files/languages/pl.xml diff --git a/plugins/latest_documents_files/languages/pt-BR.xml b/plugins/latest-documents-files/languages/pt-BR.xml similarity index 100% rename from plugins/latest_documents_files/languages/pt-BR.xml rename to plugins/latest-documents-files/languages/pt-BR.xml diff --git a/plugins/latest_documents_files/languages/pt.xml b/plugins/latest-documents-files/languages/pt.xml similarity index 100% rename from plugins/latest_documents_files/languages/pt.xml rename to plugins/latest-documents-files/languages/pt.xml diff --git a/plugins/latest_documents_files/languages/ru.xml b/plugins/latest-documents-files/languages/ru.xml similarity index 100% rename from plugins/latest_documents_files/languages/ru.xml rename to plugins/latest-documents-files/languages/ru.xml diff --git a/plugins/latest_documents_files/languages/sv.xml b/plugins/latest-documents-files/languages/sv.xml similarity index 100% rename from plugins/latest_documents_files/languages/sv.xml rename to plugins/latest-documents-files/languages/sv.xml diff --git a/plugins/latest_documents_files/languages/uk.xml b/plugins/latest-documents-files/languages/uk.xml similarity index 100% rename from plugins/latest_documents_files/languages/uk.xml rename to plugins/latest-documents-files/languages/uk.xml diff --git a/plugins/latest_documents_files/languages/zh.xml b/plugins/latest-documents-files/languages/zh.xml similarity index 100% rename from plugins/latest_documents_files/languages/zh.xml rename to plugins/latest-documents-files/languages/zh.xml diff --git a/plugins/latest_documents_files/latest_documents_files.json b/plugins/latest-documents-files/latest-documents-files.json similarity index 100% rename from plugins/latest_documents_files/latest_documents_files.json rename to plugins/latest-documents-files/latest-documents-files.json diff --git a/plugins/latest_documents_files/templates/plugin.latest-documents-files.tpl b/plugins/latest-documents-files/templates/plugin.latest-documents-files.tpl similarity index 100% rename from plugins/latest_documents_files/templates/plugin.latest-documents-files.tpl rename to plugins/latest-documents-files/templates/plugin.latest-documents-files.tpl diff --git a/plugins/latest_documents_files/templates/preferences.plugin.latest-documents-files.tpl b/plugins/latest-documents-files/templates/preferences.plugin.latest-documents-files.tpl similarity index 100% rename from plugins/latest_documents_files/templates/preferences.plugin.latest-documents-files.tpl rename to plugins/latest-documents-files/templates/preferences.plugin.latest-documents-files.tpl From 5ea61b05eaed3aecad32e99834c9641bbe8e4778 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sat, 7 Feb 2026 14:54:32 +0100 Subject: [PATCH 106/109] fix: rename login form plugin --- plugins/{login_form => login-form}/classes/LoginForm.php | 0 .../classes/Presenter/LoginFormPreferencesPresenter.php | 0 .../classes/Service/UpdateStepsCode.php | 0 plugins/{login_form => login-form}/db_scripts/update_1_0.xml | 0 plugins/{login_form => login-form}/index.php | 0 plugins/{login_form => login-form}/languages/bg.xml | 0 plugins/{login_form => login-form}/languages/da.xml | 0 plugins/{login_form => login-form}/languages/de-DE.xml | 0 plugins/{login_form => login-form}/languages/de.xml | 0 plugins/{login_form => login-form}/languages/el.xml | 0 plugins/{login_form => login-form}/languages/en.xml | 0 plugins/{login_form => login-form}/languages/es.xml | 0 plugins/{login_form => login-form}/languages/et.xml | 0 plugins/{login_form => login-form}/languages/fi.xml | 0 plugins/{login_form => login-form}/languages/fr.xml | 0 plugins/{login_form => login-form}/languages/hu.xml | 0 plugins/{login_form => login-form}/languages/it.xml | 0 plugins/{login_form => login-form}/languages/nb.xml | 0 plugins/{login_form => login-form}/languages/nl.xml | 0 plugins/{login_form => login-form}/languages/pl.xml | 0 plugins/{login_form => login-form}/languages/pt-BR.xml | 0 plugins/{login_form => login-form}/languages/pt.xml | 0 plugins/{login_form => login-form}/languages/ru.xml | 0 plugins/{login_form => login-form}/languages/sv.xml | 0 plugins/{login_form => login-form}/languages/uk.xml | 0 plugins/{login_form => login-form}/languages/zh.xml | 0 .../{login_form/login_form.json => login-form/login-form.json} | 0 .../templates/plugin.login-form.edit.tpl | 0 .../templates/plugin.login-form.view.tpl | 0 .../templates/preferences.plugin.login-form.tpl | 0 30 files changed, 0 insertions(+), 0 deletions(-) rename plugins/{login_form => login-form}/classes/LoginForm.php (100%) rename plugins/{login_form => login-form}/classes/Presenter/LoginFormPreferencesPresenter.php (100%) rename plugins/{login_form => login-form}/classes/Service/UpdateStepsCode.php (100%) rename plugins/{login_form => login-form}/db_scripts/update_1_0.xml (100%) rename plugins/{login_form => login-form}/index.php (100%) rename plugins/{login_form => login-form}/languages/bg.xml (100%) rename plugins/{login_form => login-form}/languages/da.xml (100%) rename plugins/{login_form => login-form}/languages/de-DE.xml (100%) rename plugins/{login_form => login-form}/languages/de.xml (100%) rename plugins/{login_form => login-form}/languages/el.xml (100%) rename plugins/{login_form => login-form}/languages/en.xml (100%) rename plugins/{login_form => login-form}/languages/es.xml (100%) rename plugins/{login_form => login-form}/languages/et.xml (100%) rename plugins/{login_form => login-form}/languages/fi.xml (100%) rename plugins/{login_form => login-form}/languages/fr.xml (100%) rename plugins/{login_form => login-form}/languages/hu.xml (100%) rename plugins/{login_form => login-form}/languages/it.xml (100%) rename plugins/{login_form => login-form}/languages/nb.xml (100%) rename plugins/{login_form => login-form}/languages/nl.xml (100%) rename plugins/{login_form => login-form}/languages/pl.xml (100%) rename plugins/{login_form => login-form}/languages/pt-BR.xml (100%) rename plugins/{login_form => login-form}/languages/pt.xml (100%) rename plugins/{login_form => login-form}/languages/ru.xml (100%) rename plugins/{login_form => login-form}/languages/sv.xml (100%) rename plugins/{login_form => login-form}/languages/uk.xml (100%) rename plugins/{login_form => login-form}/languages/zh.xml (100%) rename plugins/{login_form/login_form.json => login-form/login-form.json} (100%) rename plugins/{login_form => login-form}/templates/plugin.login-form.edit.tpl (100%) rename plugins/{login_form => login-form}/templates/plugin.login-form.view.tpl (100%) rename plugins/{login_form => login-form}/templates/preferences.plugin.login-form.tpl (100%) diff --git a/plugins/login_form/classes/LoginForm.php b/plugins/login-form/classes/LoginForm.php similarity index 100% rename from plugins/login_form/classes/LoginForm.php rename to plugins/login-form/classes/LoginForm.php diff --git a/plugins/login_form/classes/Presenter/LoginFormPreferencesPresenter.php b/plugins/login-form/classes/Presenter/LoginFormPreferencesPresenter.php similarity index 100% rename from plugins/login_form/classes/Presenter/LoginFormPreferencesPresenter.php rename to plugins/login-form/classes/Presenter/LoginFormPreferencesPresenter.php diff --git a/plugins/login_form/classes/Service/UpdateStepsCode.php b/plugins/login-form/classes/Service/UpdateStepsCode.php similarity index 100% rename from plugins/login_form/classes/Service/UpdateStepsCode.php rename to plugins/login-form/classes/Service/UpdateStepsCode.php diff --git a/plugins/login_form/db_scripts/update_1_0.xml b/plugins/login-form/db_scripts/update_1_0.xml similarity index 100% rename from plugins/login_form/db_scripts/update_1_0.xml rename to plugins/login-form/db_scripts/update_1_0.xml diff --git a/plugins/login_form/index.php b/plugins/login-form/index.php similarity index 100% rename from plugins/login_form/index.php rename to plugins/login-form/index.php diff --git a/plugins/login_form/languages/bg.xml b/plugins/login-form/languages/bg.xml similarity index 100% rename from plugins/login_form/languages/bg.xml rename to plugins/login-form/languages/bg.xml diff --git a/plugins/login_form/languages/da.xml b/plugins/login-form/languages/da.xml similarity index 100% rename from plugins/login_form/languages/da.xml rename to plugins/login-form/languages/da.xml diff --git a/plugins/login_form/languages/de-DE.xml b/plugins/login-form/languages/de-DE.xml similarity index 100% rename from plugins/login_form/languages/de-DE.xml rename to plugins/login-form/languages/de-DE.xml diff --git a/plugins/login_form/languages/de.xml b/plugins/login-form/languages/de.xml similarity index 100% rename from plugins/login_form/languages/de.xml rename to plugins/login-form/languages/de.xml diff --git a/plugins/login_form/languages/el.xml b/plugins/login-form/languages/el.xml similarity index 100% rename from plugins/login_form/languages/el.xml rename to plugins/login-form/languages/el.xml diff --git a/plugins/login_form/languages/en.xml b/plugins/login-form/languages/en.xml similarity index 100% rename from plugins/login_form/languages/en.xml rename to plugins/login-form/languages/en.xml diff --git a/plugins/login_form/languages/es.xml b/plugins/login-form/languages/es.xml similarity index 100% rename from plugins/login_form/languages/es.xml rename to plugins/login-form/languages/es.xml diff --git a/plugins/login_form/languages/et.xml b/plugins/login-form/languages/et.xml similarity index 100% rename from plugins/login_form/languages/et.xml rename to plugins/login-form/languages/et.xml diff --git a/plugins/login_form/languages/fi.xml b/plugins/login-form/languages/fi.xml similarity index 100% rename from plugins/login_form/languages/fi.xml rename to plugins/login-form/languages/fi.xml diff --git a/plugins/login_form/languages/fr.xml b/plugins/login-form/languages/fr.xml similarity index 100% rename from plugins/login_form/languages/fr.xml rename to plugins/login-form/languages/fr.xml diff --git a/plugins/login_form/languages/hu.xml b/plugins/login-form/languages/hu.xml similarity index 100% rename from plugins/login_form/languages/hu.xml rename to plugins/login-form/languages/hu.xml diff --git a/plugins/login_form/languages/it.xml b/plugins/login-form/languages/it.xml similarity index 100% rename from plugins/login_form/languages/it.xml rename to plugins/login-form/languages/it.xml diff --git a/plugins/login_form/languages/nb.xml b/plugins/login-form/languages/nb.xml similarity index 100% rename from plugins/login_form/languages/nb.xml rename to plugins/login-form/languages/nb.xml diff --git a/plugins/login_form/languages/nl.xml b/plugins/login-form/languages/nl.xml similarity index 100% rename from plugins/login_form/languages/nl.xml rename to plugins/login-form/languages/nl.xml diff --git a/plugins/login_form/languages/pl.xml b/plugins/login-form/languages/pl.xml similarity index 100% rename from plugins/login_form/languages/pl.xml rename to plugins/login-form/languages/pl.xml diff --git a/plugins/login_form/languages/pt-BR.xml b/plugins/login-form/languages/pt-BR.xml similarity index 100% rename from plugins/login_form/languages/pt-BR.xml rename to plugins/login-form/languages/pt-BR.xml diff --git a/plugins/login_form/languages/pt.xml b/plugins/login-form/languages/pt.xml similarity index 100% rename from plugins/login_form/languages/pt.xml rename to plugins/login-form/languages/pt.xml diff --git a/plugins/login_form/languages/ru.xml b/plugins/login-form/languages/ru.xml similarity index 100% rename from plugins/login_form/languages/ru.xml rename to plugins/login-form/languages/ru.xml diff --git a/plugins/login_form/languages/sv.xml b/plugins/login-form/languages/sv.xml similarity index 100% rename from plugins/login_form/languages/sv.xml rename to plugins/login-form/languages/sv.xml diff --git a/plugins/login_form/languages/uk.xml b/plugins/login-form/languages/uk.xml similarity index 100% rename from plugins/login_form/languages/uk.xml rename to plugins/login-form/languages/uk.xml diff --git a/plugins/login_form/languages/zh.xml b/plugins/login-form/languages/zh.xml similarity index 100% rename from plugins/login_form/languages/zh.xml rename to plugins/login-form/languages/zh.xml diff --git a/plugins/login_form/login_form.json b/plugins/login-form/login-form.json similarity index 100% rename from plugins/login_form/login_form.json rename to plugins/login-form/login-form.json diff --git a/plugins/login_form/templates/plugin.login-form.edit.tpl b/plugins/login-form/templates/plugin.login-form.edit.tpl similarity index 100% rename from plugins/login_form/templates/plugin.login-form.edit.tpl rename to plugins/login-form/templates/plugin.login-form.edit.tpl diff --git a/plugins/login_form/templates/plugin.login-form.view.tpl b/plugins/login-form/templates/plugin.login-form.view.tpl similarity index 100% rename from plugins/login_form/templates/plugin.login-form.view.tpl rename to plugins/login-form/templates/plugin.login-form.view.tpl diff --git a/plugins/login_form/templates/preferences.plugin.login-form.tpl b/plugins/login-form/templates/preferences.plugin.login-form.tpl similarity index 100% rename from plugins/login_form/templates/preferences.plugin.login-form.tpl rename to plugins/login-form/templates/preferences.plugin.login-form.tpl From f58f2352986fae3c7bd111befd4f6a009132cbe8 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sat, 7 Feb 2026 14:55:22 +0100 Subject: [PATCH 107/109] fix: rename random photo plugin --- .../classes/Presenter/RandomPhotoPreferencesPresenter.php | 0 plugins/{random_photo => random-photo}/classes/RandomPhoto.php | 0 .../classes/Service/UpdateStepsCode.php | 0 plugins/{random_photo => random-photo}/db_scripts/update_1_0.xml | 0 plugins/{random_photo => random-photo}/index.php | 0 plugins/{random_photo => random-photo}/languages/bg.xml | 0 plugins/{random_photo => random-photo}/languages/da.xml | 0 plugins/{random_photo => random-photo}/languages/de-DE.xml | 0 plugins/{random_photo => random-photo}/languages/de.xml | 0 plugins/{random_photo => random-photo}/languages/el.xml | 0 plugins/{random_photo => random-photo}/languages/en.xml | 0 plugins/{random_photo => random-photo}/languages/et.xml | 0 plugins/{random_photo => random-photo}/languages/fi.xml | 0 plugins/{random_photo => random-photo}/languages/fr.xml | 0 plugins/{random_photo => random-photo}/languages/hu.xml | 0 plugins/{random_photo => random-photo}/languages/nb.xml | 0 plugins/{random_photo => random-photo}/languages/nl.xml | 0 plugins/{random_photo => random-photo}/languages/pl.xml | 0 plugins/{random_photo => random-photo}/languages/pt.xml | 0 plugins/{random_photo => random-photo}/languages/ru.xml | 0 plugins/{random_photo => random-photo}/languages/sv.xml | 0 plugins/{random_photo => random-photo}/languages/uk.xml | 0 .../random_photo.json => random-photo/random-photo.json} | 0 .../templates/plugin.random-photo.tpl | 0 .../templates/preferences.plugin.random-photo.tpl | 0 25 files changed, 0 insertions(+), 0 deletions(-) rename plugins/{random_photo => random-photo}/classes/Presenter/RandomPhotoPreferencesPresenter.php (100%) rename plugins/{random_photo => random-photo}/classes/RandomPhoto.php (100%) rename plugins/{random_photo => random-photo}/classes/Service/UpdateStepsCode.php (100%) rename plugins/{random_photo => random-photo}/db_scripts/update_1_0.xml (100%) rename plugins/{random_photo => random-photo}/index.php (100%) rename plugins/{random_photo => random-photo}/languages/bg.xml (100%) rename plugins/{random_photo => random-photo}/languages/da.xml (100%) rename plugins/{random_photo => random-photo}/languages/de-DE.xml (100%) rename plugins/{random_photo => random-photo}/languages/de.xml (100%) rename plugins/{random_photo => random-photo}/languages/el.xml (100%) rename plugins/{random_photo => random-photo}/languages/en.xml (100%) rename plugins/{random_photo => random-photo}/languages/et.xml (100%) rename plugins/{random_photo => random-photo}/languages/fi.xml (100%) rename plugins/{random_photo => random-photo}/languages/fr.xml (100%) rename plugins/{random_photo => random-photo}/languages/hu.xml (100%) rename plugins/{random_photo => random-photo}/languages/nb.xml (100%) rename plugins/{random_photo => random-photo}/languages/nl.xml (100%) rename plugins/{random_photo => random-photo}/languages/pl.xml (100%) rename plugins/{random_photo => random-photo}/languages/pt.xml (100%) rename plugins/{random_photo => random-photo}/languages/ru.xml (100%) rename plugins/{random_photo => random-photo}/languages/sv.xml (100%) rename plugins/{random_photo => random-photo}/languages/uk.xml (100%) rename plugins/{random_photo/random_photo.json => random-photo/random-photo.json} (100%) rename plugins/{random_photo => random-photo}/templates/plugin.random-photo.tpl (100%) rename plugins/{random_photo => random-photo}/templates/preferences.plugin.random-photo.tpl (100%) diff --git a/plugins/random_photo/classes/Presenter/RandomPhotoPreferencesPresenter.php b/plugins/random-photo/classes/Presenter/RandomPhotoPreferencesPresenter.php similarity index 100% rename from plugins/random_photo/classes/Presenter/RandomPhotoPreferencesPresenter.php rename to plugins/random-photo/classes/Presenter/RandomPhotoPreferencesPresenter.php diff --git a/plugins/random_photo/classes/RandomPhoto.php b/plugins/random-photo/classes/RandomPhoto.php similarity index 100% rename from plugins/random_photo/classes/RandomPhoto.php rename to plugins/random-photo/classes/RandomPhoto.php diff --git a/plugins/random_photo/classes/Service/UpdateStepsCode.php b/plugins/random-photo/classes/Service/UpdateStepsCode.php similarity index 100% rename from plugins/random_photo/classes/Service/UpdateStepsCode.php rename to plugins/random-photo/classes/Service/UpdateStepsCode.php diff --git a/plugins/random_photo/db_scripts/update_1_0.xml b/plugins/random-photo/db_scripts/update_1_0.xml similarity index 100% rename from plugins/random_photo/db_scripts/update_1_0.xml rename to plugins/random-photo/db_scripts/update_1_0.xml diff --git a/plugins/random_photo/index.php b/plugins/random-photo/index.php similarity index 100% rename from plugins/random_photo/index.php rename to plugins/random-photo/index.php diff --git a/plugins/random_photo/languages/bg.xml b/plugins/random-photo/languages/bg.xml similarity index 100% rename from plugins/random_photo/languages/bg.xml rename to plugins/random-photo/languages/bg.xml diff --git a/plugins/random_photo/languages/da.xml b/plugins/random-photo/languages/da.xml similarity index 100% rename from plugins/random_photo/languages/da.xml rename to plugins/random-photo/languages/da.xml diff --git a/plugins/random_photo/languages/de-DE.xml b/plugins/random-photo/languages/de-DE.xml similarity index 100% rename from plugins/random_photo/languages/de-DE.xml rename to plugins/random-photo/languages/de-DE.xml diff --git a/plugins/random_photo/languages/de.xml b/plugins/random-photo/languages/de.xml similarity index 100% rename from plugins/random_photo/languages/de.xml rename to plugins/random-photo/languages/de.xml diff --git a/plugins/random_photo/languages/el.xml b/plugins/random-photo/languages/el.xml similarity index 100% rename from plugins/random_photo/languages/el.xml rename to plugins/random-photo/languages/el.xml diff --git a/plugins/random_photo/languages/en.xml b/plugins/random-photo/languages/en.xml similarity index 100% rename from plugins/random_photo/languages/en.xml rename to plugins/random-photo/languages/en.xml diff --git a/plugins/random_photo/languages/et.xml b/plugins/random-photo/languages/et.xml similarity index 100% rename from plugins/random_photo/languages/et.xml rename to plugins/random-photo/languages/et.xml diff --git a/plugins/random_photo/languages/fi.xml b/plugins/random-photo/languages/fi.xml similarity index 100% rename from plugins/random_photo/languages/fi.xml rename to plugins/random-photo/languages/fi.xml diff --git a/plugins/random_photo/languages/fr.xml b/plugins/random-photo/languages/fr.xml similarity index 100% rename from plugins/random_photo/languages/fr.xml rename to plugins/random-photo/languages/fr.xml diff --git a/plugins/random_photo/languages/hu.xml b/plugins/random-photo/languages/hu.xml similarity index 100% rename from plugins/random_photo/languages/hu.xml rename to plugins/random-photo/languages/hu.xml diff --git a/plugins/random_photo/languages/nb.xml b/plugins/random-photo/languages/nb.xml similarity index 100% rename from plugins/random_photo/languages/nb.xml rename to plugins/random-photo/languages/nb.xml diff --git a/plugins/random_photo/languages/nl.xml b/plugins/random-photo/languages/nl.xml similarity index 100% rename from plugins/random_photo/languages/nl.xml rename to plugins/random-photo/languages/nl.xml diff --git a/plugins/random_photo/languages/pl.xml b/plugins/random-photo/languages/pl.xml similarity index 100% rename from plugins/random_photo/languages/pl.xml rename to plugins/random-photo/languages/pl.xml diff --git a/plugins/random_photo/languages/pt.xml b/plugins/random-photo/languages/pt.xml similarity index 100% rename from plugins/random_photo/languages/pt.xml rename to plugins/random-photo/languages/pt.xml diff --git a/plugins/random_photo/languages/ru.xml b/plugins/random-photo/languages/ru.xml similarity index 100% rename from plugins/random_photo/languages/ru.xml rename to plugins/random-photo/languages/ru.xml diff --git a/plugins/random_photo/languages/sv.xml b/plugins/random-photo/languages/sv.xml similarity index 100% rename from plugins/random_photo/languages/sv.xml rename to plugins/random-photo/languages/sv.xml diff --git a/plugins/random_photo/languages/uk.xml b/plugins/random-photo/languages/uk.xml similarity index 100% rename from plugins/random_photo/languages/uk.xml rename to plugins/random-photo/languages/uk.xml diff --git a/plugins/random_photo/random_photo.json b/plugins/random-photo/random-photo.json similarity index 100% rename from plugins/random_photo/random_photo.json rename to plugins/random-photo/random-photo.json diff --git a/plugins/random_photo/templates/plugin.random-photo.tpl b/plugins/random-photo/templates/plugin.random-photo.tpl similarity index 100% rename from plugins/random_photo/templates/plugin.random-photo.tpl rename to plugins/random-photo/templates/plugin.random-photo.tpl diff --git a/plugins/random_photo/templates/preferences.plugin.random-photo.tpl b/plugins/random-photo/templates/preferences.plugin.random-photo.tpl similarity index 100% rename from plugins/random_photo/templates/preferences.plugin.random-photo.tpl rename to plugins/random-photo/templates/preferences.plugin.random-photo.tpl From b27e806fba4bca6a300b9e7cc960df2aed668cd8 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sat, 7 Feb 2026 14:56:05 +0100 Subject: [PATCH 108/109] fix: rename who is online plugin --- .../classes/Presenter/WhoIsOnlinePreferencesPresenter.php | 0 .../classes/Service/UpdateStepsCode.php | 0 plugins/{who_is_online => who-is-online}/classes/WhoIsOnline.php | 0 .../{who_is_online => who-is-online}/db_scripts/update_1_0.xml | 0 plugins/{who_is_online => who-is-online}/index.php | 0 plugins/{who_is_online => who-is-online}/languages/bg.xml | 0 plugins/{who_is_online => who-is-online}/languages/da.xml | 0 plugins/{who_is_online => who-is-online}/languages/de-DE.xml | 0 plugins/{who_is_online => who-is-online}/languages/de.xml | 0 plugins/{who_is_online => who-is-online}/languages/el.xml | 0 plugins/{who_is_online => who-is-online}/languages/en.xml | 0 plugins/{who_is_online => who-is-online}/languages/es.xml | 0 plugins/{who_is_online => who-is-online}/languages/et.xml | 0 plugins/{who_is_online => who-is-online}/languages/fi.xml | 0 plugins/{who_is_online => who-is-online}/languages/fr.xml | 0 plugins/{who_is_online => who-is-online}/languages/hu.xml | 0 plugins/{who_is_online => who-is-online}/languages/nb.xml | 0 plugins/{who_is_online => who-is-online}/languages/nl.xml | 0 plugins/{who_is_online => who-is-online}/languages/pl.xml | 0 plugins/{who_is_online => who-is-online}/languages/pt-BR.xml | 0 plugins/{who_is_online => who-is-online}/languages/pt.xml | 0 plugins/{who_is_online => who-is-online}/languages/ru.xml | 0 plugins/{who_is_online => who-is-online}/languages/sv.xml | 0 plugins/{who_is_online => who-is-online}/languages/uk.xml | 0 plugins/{who_is_online => who-is-online}/languages/zh.xml | 0 .../templates/plugin.who-is-online.tpl | 0 .../templates/preferences.plugin.who-is-online.tpl | 0 .../who_is_online.json => who-is-online/who-is-online.json} | 0 28 files changed, 0 insertions(+), 0 deletions(-) rename plugins/{who_is_online => who-is-online}/classes/Presenter/WhoIsOnlinePreferencesPresenter.php (100%) rename plugins/{who_is_online => who-is-online}/classes/Service/UpdateStepsCode.php (100%) rename plugins/{who_is_online => who-is-online}/classes/WhoIsOnline.php (100%) rename plugins/{who_is_online => who-is-online}/db_scripts/update_1_0.xml (100%) rename plugins/{who_is_online => who-is-online}/index.php (100%) rename plugins/{who_is_online => who-is-online}/languages/bg.xml (100%) rename plugins/{who_is_online => who-is-online}/languages/da.xml (100%) rename plugins/{who_is_online => who-is-online}/languages/de-DE.xml (100%) rename plugins/{who_is_online => who-is-online}/languages/de.xml (100%) rename plugins/{who_is_online => who-is-online}/languages/el.xml (100%) rename plugins/{who_is_online => who-is-online}/languages/en.xml (100%) rename plugins/{who_is_online => who-is-online}/languages/es.xml (100%) rename plugins/{who_is_online => who-is-online}/languages/et.xml (100%) rename plugins/{who_is_online => who-is-online}/languages/fi.xml (100%) rename plugins/{who_is_online => who-is-online}/languages/fr.xml (100%) rename plugins/{who_is_online => who-is-online}/languages/hu.xml (100%) rename plugins/{who_is_online => who-is-online}/languages/nb.xml (100%) rename plugins/{who_is_online => who-is-online}/languages/nl.xml (100%) rename plugins/{who_is_online => who-is-online}/languages/pl.xml (100%) rename plugins/{who_is_online => who-is-online}/languages/pt-BR.xml (100%) rename plugins/{who_is_online => who-is-online}/languages/pt.xml (100%) rename plugins/{who_is_online => who-is-online}/languages/ru.xml (100%) rename plugins/{who_is_online => who-is-online}/languages/sv.xml (100%) rename plugins/{who_is_online => who-is-online}/languages/uk.xml (100%) rename plugins/{who_is_online => who-is-online}/languages/zh.xml (100%) rename plugins/{who_is_online => who-is-online}/templates/plugin.who-is-online.tpl (100%) rename plugins/{who_is_online => who-is-online}/templates/preferences.plugin.who-is-online.tpl (100%) rename plugins/{who_is_online/who_is_online.json => who-is-online/who-is-online.json} (100%) diff --git a/plugins/who_is_online/classes/Presenter/WhoIsOnlinePreferencesPresenter.php b/plugins/who-is-online/classes/Presenter/WhoIsOnlinePreferencesPresenter.php similarity index 100% rename from plugins/who_is_online/classes/Presenter/WhoIsOnlinePreferencesPresenter.php rename to plugins/who-is-online/classes/Presenter/WhoIsOnlinePreferencesPresenter.php diff --git a/plugins/who_is_online/classes/Service/UpdateStepsCode.php b/plugins/who-is-online/classes/Service/UpdateStepsCode.php similarity index 100% rename from plugins/who_is_online/classes/Service/UpdateStepsCode.php rename to plugins/who-is-online/classes/Service/UpdateStepsCode.php diff --git a/plugins/who_is_online/classes/WhoIsOnline.php b/plugins/who-is-online/classes/WhoIsOnline.php similarity index 100% rename from plugins/who_is_online/classes/WhoIsOnline.php rename to plugins/who-is-online/classes/WhoIsOnline.php diff --git a/plugins/who_is_online/db_scripts/update_1_0.xml b/plugins/who-is-online/db_scripts/update_1_0.xml similarity index 100% rename from plugins/who_is_online/db_scripts/update_1_0.xml rename to plugins/who-is-online/db_scripts/update_1_0.xml diff --git a/plugins/who_is_online/index.php b/plugins/who-is-online/index.php similarity index 100% rename from plugins/who_is_online/index.php rename to plugins/who-is-online/index.php diff --git a/plugins/who_is_online/languages/bg.xml b/plugins/who-is-online/languages/bg.xml similarity index 100% rename from plugins/who_is_online/languages/bg.xml rename to plugins/who-is-online/languages/bg.xml diff --git a/plugins/who_is_online/languages/da.xml b/plugins/who-is-online/languages/da.xml similarity index 100% rename from plugins/who_is_online/languages/da.xml rename to plugins/who-is-online/languages/da.xml diff --git a/plugins/who_is_online/languages/de-DE.xml b/plugins/who-is-online/languages/de-DE.xml similarity index 100% rename from plugins/who_is_online/languages/de-DE.xml rename to plugins/who-is-online/languages/de-DE.xml diff --git a/plugins/who_is_online/languages/de.xml b/plugins/who-is-online/languages/de.xml similarity index 100% rename from plugins/who_is_online/languages/de.xml rename to plugins/who-is-online/languages/de.xml diff --git a/plugins/who_is_online/languages/el.xml b/plugins/who-is-online/languages/el.xml similarity index 100% rename from plugins/who_is_online/languages/el.xml rename to plugins/who-is-online/languages/el.xml diff --git a/plugins/who_is_online/languages/en.xml b/plugins/who-is-online/languages/en.xml similarity index 100% rename from plugins/who_is_online/languages/en.xml rename to plugins/who-is-online/languages/en.xml diff --git a/plugins/who_is_online/languages/es.xml b/plugins/who-is-online/languages/es.xml similarity index 100% rename from plugins/who_is_online/languages/es.xml rename to plugins/who-is-online/languages/es.xml diff --git a/plugins/who_is_online/languages/et.xml b/plugins/who-is-online/languages/et.xml similarity index 100% rename from plugins/who_is_online/languages/et.xml rename to plugins/who-is-online/languages/et.xml diff --git a/plugins/who_is_online/languages/fi.xml b/plugins/who-is-online/languages/fi.xml similarity index 100% rename from plugins/who_is_online/languages/fi.xml rename to plugins/who-is-online/languages/fi.xml diff --git a/plugins/who_is_online/languages/fr.xml b/plugins/who-is-online/languages/fr.xml similarity index 100% rename from plugins/who_is_online/languages/fr.xml rename to plugins/who-is-online/languages/fr.xml diff --git a/plugins/who_is_online/languages/hu.xml b/plugins/who-is-online/languages/hu.xml similarity index 100% rename from plugins/who_is_online/languages/hu.xml rename to plugins/who-is-online/languages/hu.xml diff --git a/plugins/who_is_online/languages/nb.xml b/plugins/who-is-online/languages/nb.xml similarity index 100% rename from plugins/who_is_online/languages/nb.xml rename to plugins/who-is-online/languages/nb.xml diff --git a/plugins/who_is_online/languages/nl.xml b/plugins/who-is-online/languages/nl.xml similarity index 100% rename from plugins/who_is_online/languages/nl.xml rename to plugins/who-is-online/languages/nl.xml diff --git a/plugins/who_is_online/languages/pl.xml b/plugins/who-is-online/languages/pl.xml similarity index 100% rename from plugins/who_is_online/languages/pl.xml rename to plugins/who-is-online/languages/pl.xml diff --git a/plugins/who_is_online/languages/pt-BR.xml b/plugins/who-is-online/languages/pt-BR.xml similarity index 100% rename from plugins/who_is_online/languages/pt-BR.xml rename to plugins/who-is-online/languages/pt-BR.xml diff --git a/plugins/who_is_online/languages/pt.xml b/plugins/who-is-online/languages/pt.xml similarity index 100% rename from plugins/who_is_online/languages/pt.xml rename to plugins/who-is-online/languages/pt.xml diff --git a/plugins/who_is_online/languages/ru.xml b/plugins/who-is-online/languages/ru.xml similarity index 100% rename from plugins/who_is_online/languages/ru.xml rename to plugins/who-is-online/languages/ru.xml diff --git a/plugins/who_is_online/languages/sv.xml b/plugins/who-is-online/languages/sv.xml similarity index 100% rename from plugins/who_is_online/languages/sv.xml rename to plugins/who-is-online/languages/sv.xml diff --git a/plugins/who_is_online/languages/uk.xml b/plugins/who-is-online/languages/uk.xml similarity index 100% rename from plugins/who_is_online/languages/uk.xml rename to plugins/who-is-online/languages/uk.xml diff --git a/plugins/who_is_online/languages/zh.xml b/plugins/who-is-online/languages/zh.xml similarity index 100% rename from plugins/who_is_online/languages/zh.xml rename to plugins/who-is-online/languages/zh.xml diff --git a/plugins/who_is_online/templates/plugin.who-is-online.tpl b/plugins/who-is-online/templates/plugin.who-is-online.tpl similarity index 100% rename from plugins/who_is_online/templates/plugin.who-is-online.tpl rename to plugins/who-is-online/templates/plugin.who-is-online.tpl diff --git a/plugins/who_is_online/templates/preferences.plugin.who-is-online.tpl b/plugins/who-is-online/templates/preferences.plugin.who-is-online.tpl similarity index 100% rename from plugins/who_is_online/templates/preferences.plugin.who-is-online.tpl rename to plugins/who-is-online/templates/preferences.plugin.who-is-online.tpl diff --git a/plugins/who_is_online/who_is_online.json b/plugins/who-is-online/who-is-online.json similarity index 100% rename from plugins/who_is_online/who_is_online.json rename to plugins/who-is-online/who-is-online.json From a2a4bd0ce3cacc8034d501f3b75d73badd6e64f1 Mon Sep 17 00:00:00 2001 From: Mathias Huth Date: Sat, 7 Feb 2026 15:03:22 +0100 Subject: [PATCH 109/109] fix: overview plugin enabled check --- src/Infrastructure/Plugins/PluginManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Infrastructure/Plugins/PluginManager.php b/src/Infrastructure/Plugins/PluginManager.php index 408f253997..6d0405a3e6 100644 --- a/src/Infrastructure/Plugins/PluginManager.php +++ b/src/Infrastructure/Plugins/PluginManager.php @@ -179,7 +179,7 @@ public function getOverviewPlugins() : array $configValues = $plugin['interface']->getPluginConfigValues(); $enabled = false; foreach ($configValues as $key => $value) { - if (preg_match('/_enabled$/', $key) && $value === 1 || ($value === 2 && $gValidLogin)) { + if (str_ends_with($key, '_plugin_enabled') && ($value === 1 || ($value === 2 && $gValidLogin))) { $enabled = true; break; }