From cf284000151bf705f5a70c0f7c6b5f52a0cb5320 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Sun, 2 Feb 2025 18:00:45 +1100 Subject: [PATCH 01/54] update issue #34. Added delete source option in settings. Fixed bugs. --- .../Backuprestore/BackuprestoreComponent.php | 4 +- .../Views/Default/html/modules/analyse.html | 17 +- .../Views/Default/html/modules/settings.html | 39 +- .../Core/Views/Default/html/modules/view.html | 12 + .../Packages/BackupRestore.php | 242 ++++--- .../Packages/Progress.php | 23 +- .../ModulesServiceProvider/Installer.php | 598 ++++-------------- .../ModulesServiceProvider/Queues.php | 5 +- 8 files changed, 363 insertions(+), 577 deletions(-) diff --git a/apps/Core/Components/System/Tools/Backuprestore/BackuprestoreComponent.php b/apps/Core/Components/System/Tools/Backuprestore/BackuprestoreComponent.php index aced6f136..6f350f8fe 100644 --- a/apps/Core/Components/System/Tools/Backuprestore/BackuprestoreComponent.php +++ b/apps/Core/Components/System/Tools/Backuprestore/BackuprestoreComponent.php @@ -19,7 +19,7 @@ public function viewAction() $this->getNewToken(); if (isset($this->getData()['analyse']) && $this->getData()['analyse'] == 'info') { - $backupInfoFile = $this->basepackages->backuprestore->init('analyse')->analyseBackinfoFile($this->getData()['id']); + $backupInfoFile = $this->basepackages->backuprestore->init()->analyseBackinfoFile($this->getData()['id']); if ($backupInfoFile) { return $this->view->getPartial('backuprestore/analyse/analysis', ['backupInfoFile' => $backupInfoFile]); @@ -72,7 +72,7 @@ public function backupAction() { $this->requestIsPost(); - if ($this->basepackages->backuprestore->init()->backup($this->postData())) { + if ($this->basepackages->backuprestore->init('backup')->backup($this->postData())) { $this->addResponse( $this->basepackages->backuprestore->packagesData->responseMessage, $this->basepackages->backuprestore->packagesData->responseCode, diff --git a/apps/Core/Views/Default/html/modules/analyse.html b/apps/Core/Views/Default/html/modules/analyse.html index 23ae10323..8f10e963e 100644 --- a/apps/Core/Views/Default/html/modules/analyse.html +++ b/apps/Core/Views/Default/html/modules/analyse.html @@ -199,7 +199,7 @@ dataCollectionSectionForm['vars']['queue'] = JSON.parse('{{queue}}'); dataCollectionSectionForm['funcs'] = { }; dataCollectionSectionForm['funcs']['init'] = function() { - BazProgress.buildProgressBar($('#installer-progress'), false, false, true); + BazProgress.buildProgressBar($('#installer-progress'), false, true, true); if ($.fn.DataTable && !$.fn.DataTable.isDataTable('#{{componentId}}-{{sectionId}}-queue-table')) { $('#{{componentId}}-{{sectionId}}-queue-table').DataTable({ @@ -242,8 +242,9 @@ postData['settings']['backupSettings']['password_protect'] = $('#{{componentId}}-{{sectionId}}-password_protect').val().trim(); postData['settings']['backupSettings']['notes'] = $('#{{componentId}}-{{sectionId}}-notes').val().trim(); postData['settings']['emailReport'] = $('#{{componentId}}-{{sectionId}}-email_report').val().trim(); - postData['settings']['rsync'] = { }; - postData['settings']['rsync']['deleteDestinationFiles'] = $('#{{componentId}}-{{sectionId}}-delete_destination_files')[0].checked; + postData['settings']['files'] = { }; + postData['settings']['files']['deleteSourceFiles'] = $('#{{componentId}}-{{sectionId}}-delete_source_files')[0].checked; + postData['settings']['files']['deleteDestinationFiles'] = $('#{{componentId}}-{{sectionId}}-delete_destination_files')[0].checked; $.post('{{links.url("modules/saveQueueSettings")}}', postData, function(response) { if (response.tokenKey && response.token) { @@ -311,6 +312,7 @@ $('#{{componentId}}-{{sectionId}}-perform-precheck').attr('hidden', true); $('#{{componentId}}-{{sectionId}}-process-queue').attr('hidden', true); $('#{{componentId}}-{{sectionId}}-process-queue').children('i').attr('hidden', true); + $('#{{componentId}}-{{sectionId}}-cancel').attr('hidden', true); } } else { paginatedPNotify('error', { @@ -457,8 +459,12 @@ if (object === 'analyse_logs' || object === 'precheck_logs' || object === 'result_logs') { if (logObject[object] !== '-') { if ($(this).data()['moduletype'] !== 'external') { - logObject[object] = JSON.parse(logObject[object]); - logObject[object] = BazHelpers.createHtmlList({'obj': logObject[object]}); + try { + logObject[object] = JSON.parse(logObject[object]); + logObject[object] = BazHelpers.createHtmlList({'obj': logObject[object]}); + } catch (e) { + //Do nothing + } } logObject[object] = '
' + logObject[object] + '
'; @@ -536,6 +542,7 @@ '{{componentId}}-{{sectionId}}-password_protect' : { }, '{{componentId}}-{{sectionId}}-notes' : { }, '{{componentId}}-{{sectionId}}-email_report' : { }, + '{{componentId}}-{{sectionId}}-delete_source_files' : { }, '{{componentId}}-{{sectionId}}-delete_destination_files' : { }, '{{componentId}}-{{sectionId}}-form' : $.extend(dataCollectionSectionForm, { rules: { diff --git a/apps/Core/Views/Default/html/modules/settings.html b/apps/Core/Views/Default/html/modules/settings.html index f8b348c4f..41aff11c1 100644 --- a/apps/Core/Views/Default/html/modules/settings.html +++ b/apps/Core/Views/Default/html/modules/settings.html @@ -42,9 +42,13 @@ {% if queue['settings']['backupSettings']['keys'] == 'true' %} {% set settingsBackupSettingsKeysChecked = true %} {% endif %} -{% set settingsRSyncDeleteDestinationFilesChecked = false %} -{% if queue['settings']['rsync']['deleteDestinationFiles'] == 'true' %} - {% set settingsRSyncDeleteDestinationFilesChecked = true %} +{% set settingsFilesDeleteSourceFilesChecked = false %} +{% if queue['settings']['files']['deleteSourceFiles'] == 'true' %} + {% set settingsFilesDeleteSourceFilesChecked = true %} +{% endif %} +{% set settingsFilesDeleteDestinationFilesChecked = false %} +{% if queue['settings']['files']['deleteDestinationFiles'] == 'true' %} + {% set settingsFilesDeleteDestinationFilesChecked = true %} {% endif %}
@@ -443,8 +447,8 @@ 'componentName' : componentName, 'componentId' : componentId, 'sectionId' : sectionId, - 'fieldId' : 'rsync_settings', - 'fieldLabel' : 'RSYNC SETTINGS', + 'fieldId' : 'files_settings', + 'fieldLabel' : 'FILES SETTINGS', 'fieldLabelLegend' : true, 'fieldHidden' : false, 'fieldType' : 'html', @@ -458,6 +462,29 @@
+
+ {{adminltetags.useTag('fields', + [ + 'component' : component, + 'componentName' : componentName, + 'componentId' : componentId, + 'sectionId' : sectionId, + 'fieldId' : 'delete_source_files', + 'fieldLabel' : false, + 'fieldHelp' : true, + 'fieldHelpTooltipContent' : 'Delete downloaded source files? Files are only deleted on successful installation/upgrade.', + 'fieldRequired' : false, + 'fieldType' : 'checkbox', + 'fieldCheckboxType' : 'success', + 'fieldCheckboxChecked' : settingsFilesDeleteSourceFilesChecked, + 'fieldCheckboxLabel' : 'DELETE SOURCE FILES?', + 'fieldBazJstreeSearch' : true, + 'fieldBazPostOnCreate' : false, + 'fieldBazPostOnUpdate' : false, + 'fieldBazScan' : true + ] + )}} +
{{adminltetags.useTag('fields', [ @@ -472,7 +499,7 @@ 'fieldRequired' : false, 'fieldType' : 'checkbox', 'fieldCheckboxType' : 'danger', - 'fieldCheckboxChecked' : settingsRSyncDeleteDestinationFilesChecked, + 'fieldCheckboxChecked' : settingsFilesDeleteDestinationFilesChecked, 'fieldCheckboxLabel' : 'RSYNC DELETE DESTINATION FILES?', 'fieldBazJstreeSearch' : true, 'fieldBazPostOnCreate' : false, diff --git a/apps/Core/Views/Default/html/modules/view.html b/apps/Core/Views/Default/html/modules/view.html index ed2a1d5d5..753d9fd03 100644 --- a/apps/Core/Views/Default/html/modules/view.html +++ b/apps/Core/Views/Default/html/modules/view.html @@ -3,6 +3,8 @@ {% set precheckHidden = false %} {% set analyseHidden = false %} {% set processHidden = true %} + {% set cancelHidden = false %} + {% set closeHidden = true %} {% if queue['status'] == 1 %} {% set precheckHidden = false %} {% set precheckTitle = 'Re-Perform Precheck' %} @@ -11,6 +13,8 @@ {% set precheckHidden = true %} {% set analyseHidden = true %} {% set processHidden = true %} + {% set cancelHidden = true %} + {% set closeHidden = false %} {% endif %} {% set footerContent = adminltetags.useTag('buttons', @@ -47,6 +51,14 @@ 'title' : 'Cancel', 'type' : 'secondary', 'position' : 'right', + 'hidden' : cancelHidden, + 'url' : links.url('modules') + ], + 'close' : [ + 'title' : 'Close', + 'type' : 'secondary', + 'position' : 'right', + 'hidden' : closeHidden, 'url' : links.url('modules') ] ] diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/BackupRestore.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/BackupRestore.php index 75964d015..465816452 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/BackupRestore.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/BackupRestore.php @@ -28,7 +28,7 @@ class BackupRestore extends BasePackage protected $restoreProgressMethods; - public function init($process = 'backup') + public function init($process = null) { $this->zip = new \ZipArchive; @@ -72,7 +72,7 @@ protected function withProgress($method, $arguments) } } - public function backup(array $data) + public function backup(array $data, $viaModuleInstaller = false) { set_time_limit(300);//5 mins @@ -90,9 +90,11 @@ public function backup(array $data) if ($noOptions) { $this->addResponse('Nothing to backup!', 1, []); - $this->basepackages->progress->preCheckComplete(false); + if (!$viaModuleInstaller) { + $this->basepackages->progress->preCheckComplete(false); - $this->basepackages->progress->resetProgress(); + $this->basepackages->progress->resetProgress(); + } return false; } @@ -119,9 +121,11 @@ public function backup(array $data) ) { $this->addResponse('Protect password missing!', 1, []); - $this->basepackages->progress->preCheckComplete(false); + if (!$viaModuleInstaller) { + $this->basepackages->progress->preCheckComplete(false); - $this->basepackages->progress->resetProgress(); + $this->basepackages->progress->resetProgress(); + } return false; } @@ -134,99 +138,125 @@ public function backup(array $data) } } if ($noFilesOptions) { - $this->basepackages->progress->unregisterMethods(['generateStructure']); + if ($viaModuleInstaller) { + $this->basepackages->progress->unregisterMethods(['createBackup'], 'method', ['generateStructure']); + } else { + $this->basepackages->progress->unregisterMethods(['generateStructure']); + } } if (!isset($this->backupInfo['request']['database']) || (isset($this->backupInfo['request']['database']) && $this->backupInfo['request']['database'] != 'true') ) { - $this->basepackages->progress->unregisterMethods(['performDbBackup']); + if ($viaModuleInstaller) { + $this->basepackages->progress->unregisterMethods(['createBackup'], 'method', ['performDbBackup']); + } else { + $this->basepackages->progress->unregisterMethods(['performDbBackup']); + } } - $this->basepackages->progress->preCheckComplete(); + if (!$viaModuleInstaller) { + $this->basepackages->progress->preCheckComplete(); - foreach ($this->backupProgressMethods as $method) { - if ($this->withProgress($method['method'], $data) === false) { - return false; - } + foreach ($this->backupProgressMethods as $method) { + if ($this->withProgress($method['method'], $data) === false) { + return false; + } - usleep(500); + usleep(500); + } } return true; } - protected function generateStructure(array $data) + public function generateStructure() { - $this->zip->open(base_path($this->backupLocation . $this->backupInfo['backupName']), $this->zip::CREATE); + try { + $this->zip->open(base_path($this->backupLocation . $this->backupInfo['backupName']), $this->zip::CREATE); - if (isset($this->backupInfo['request']['database']) && $this->backupInfo['request']['database'] == 'true') { - if ($this->core->core['settings']['databasetype'] != 'db') { - $this->getContent($this->basepackages->utils->scanDir('.ff/')); + if (isset($this->backupInfo['request']['database']) && $this->backupInfo['request']['database'] == 'true') { + if ($this->core->core['settings']['databasetype'] != 'db') { + $this->getContent($this->basepackages->utils->scanDir('.ff/')); + } } - } - if (isset($this->backupInfo['request']['apps_dir']) && $this->backupInfo['request']['apps_dir'] == 'true') { - $this->getContent($this->basepackages->utils->scanDir('apps/')); - } - if (isset($this->backupInfo['request']['systems_dir']) && $this->backupInfo['request']['systems_dir'] == 'true') { - $this->getContent($this->basepackages->utils->scanDir('system/')); - } - if (isset($this->backupInfo['request']['public_dir']) && $this->backupInfo['request']['public_dir'] == 'true') { - $this->getContent($this->basepackages->utils->scanDir('public/')); - } - if (isset($this->backupInfo['request']['private_dir']) && $this->backupInfo['request']['private_dir'] == 'true') { - $this->getContent($this->basepackages->utils->scanDir('private/')); - } - if (isset($this->backupInfo['request']['var_dir']) && $this->backupInfo['request']['var_dir'] == 'true') { - $this->getContent($this->basepackages->utils->scanDir('var/')); - } - if (isset($this->backupInfo['request']['external_dir']) && $this->backupInfo['request']['external_dir'] == 'true') { - if (isset($this->backupInfo['request']['external_vendor_dir']) && $this->backupInfo['request']['external_vendor_dir'] == 'true') { - $this->getContent($this->basepackages->utils->scanDir('external/')); - } else { - $this->getContent($this->basepackages->utils->scanDir('external/', false)); + if (isset($this->backupInfo['request']['apps_dir']) && $this->backupInfo['request']['apps_dir'] == 'true') { + $this->getContent($this->basepackages->utils->scanDir('apps/')); + } + if (isset($this->backupInfo['request']['systems_dir']) && $this->backupInfo['request']['systems_dir'] == 'true') { + $this->getContent($this->basepackages->utils->scanDir('system/')); + } + if (isset($this->backupInfo['request']['public_dir']) && $this->backupInfo['request']['public_dir'] == 'true') { + $this->getContent($this->basepackages->utils->scanDir('public/')); + } + if (isset($this->backupInfo['request']['private_dir']) && $this->backupInfo['request']['private_dir'] == 'true') { + $this->getContent($this->basepackages->utils->scanDir('private/')); + } + if (isset($this->backupInfo['request']['var_dir']) && $this->backupInfo['request']['var_dir'] == 'true') { + $this->getContent($this->basepackages->utils->scanDir('var/')); + } + if (isset($this->backupInfo['request']['external_dir']) && $this->backupInfo['request']['external_dir'] == 'true') { + if (isset($this->backupInfo['request']['external_vendor_dir']) && $this->backupInfo['request']['external_vendor_dir'] == 'true') { + $this->getContent($this->basepackages->utils->scanDir('external/')); + } else { + $this->getContent($this->basepackages->utils->scanDir('external/', false)); + } } - } - if (isset($this->backupInfo['request']['old_backups_dir']) && $this->backupInfo['request']['old_backups_dir'] == 'true') { - $this->getContent($this->basepackages->utils->scanDir('.backups/')); - $this->getContent($this->basepackages->utils->scanDir('.backupsdb/')); - $this->getContent($this->basepackages->utils->scanDir('.backupsff/')); - } + if (isset($this->backupInfo['request']['old_backups_dir']) && $this->backupInfo['request']['old_backups_dir'] == 'true') { + $this->getContent($this->basepackages->utils->scanDir('.backups/')); + $this->getContent($this->basepackages->utils->scanDir('.backupsdb/')); + $this->getContent($this->basepackages->utils->scanDir('.backupsff/')); + } - return true; + return true; + } catch (\Exception | \throwable $e) { + $this->addResponse('Backup Error: ' . $e->getMessage(), 1); + + $this->basepackages->progress->resetProgress(); + + return false; + } } - protected function zipBackupFiles(array $data) + public function zipBackupFiles() { - foreach ($this->backupInfo['files'] as $file) { - if (!$this->addToZip(base_path($file), $file)) { + try { + foreach ($this->backupInfo['files'] as $file) { + if (!$this->addToZip(base_path($file), $file)) { + return false; + } + } + + if (isset($this->backupInfo['request']['password_protect']) && $this->backupInfo['request']['password_protect'] !== '') { + $this->backupInfo['request']['password_protect'] = + $this->secTools->hashPassword($this->backupInfo['request']['password_protect'], 4); + } + + try { + $this->localContent->write('var/tmp/backupInfo.json' , $this->helper->encode($this->backupInfo)); + } catch (\ErrorException | FilesystemException | UnableToWriteFile $exception) { + throw $exception; + } + + //Dont Encrypt info file as we need to know if encryption is applied or not during restore. We can encrypt the content in case we want to hide something (like we are encrypting the password_protect password) + if (!$this->addToZip(base_path('var/tmp/backupInfo.json'), 'backupInfo.json', false)) { return false; } - } - if (isset($this->backupInfo['request']['password_protect']) && $this->backupInfo['request']['password_protect'] !== '') { - $this->backupInfo['request']['password_protect'] = - $this->secTools->hashPassword($this->backupInfo['request']['password_protect'], 4); - } + $this->zip->close(); - try { - $this->localContent->write('var/tmp/backupInfo.json' , $this->helper->encode($this->backupInfo)); - } catch (\ErrorException | FilesystemException | UnableToWriteFile $exception) { - throw $exception; - } + return true; + } catch (\Exception | \throwable $e) { + $this->addResponse('Backup Error: ' . $e->getMessage(), 1); + + $this->basepackages->progress->resetProgress(); - //Dont Encrypt info file as we need to know if encryption is applied or not during restore. We can encrypt the content in case we want to hide something (like we are encrypting the password_protect password) - if (!$this->addToZip(base_path('var/tmp/backupInfo.json'), 'backupInfo.json', false)) { return false; } - - $this->zip->close(); - - return true; } - protected function performDbBackup(array $data) + public function performDbBackup() { foreach ($this->core->core['settings']['dbs'] as $dbKey => $db) { try { @@ -266,35 +296,41 @@ protected function performDbBackup(array $data) return true; } - protected function finishBackup(array $data) + public function finishBackup(array $data) { - if ($this->basepackages->storages->storeFile( - 'private', - '.backups', - null, - $this->backupInfo['backupName'], - filesize(base_path('.backups/' . $this->backupInfo['backupName'])), - 'application/zip', - true - ) - ) { - $this->basepackages->storages->changeOrphanStatus( - null, - null, - false, - null, - $this->backupInfo['backupName'] - ); - - $this->addResponse('Generated backup ' . $this->backupInfo['backupName'] . '.', - 0, - ['filename' => $this->backupInfo['backupName'], - 'uuid' => $this->basepackages->storages->packagesData->responseData['uuid'], - 'request' => $data - ] - ); + try { + if ($this->basepackages->storages->storeFile( + 'private', + '.backups', + null, + $this->backupInfo['backupName'], + filesize(base_path('.backups/' . $this->backupInfo['backupName'])), + 'application/zip', + true + ) + ) { + $this->basepackages->storages->changeOrphanStatus( + null, + null, + false, + null, + $this->backupInfo['backupName'] + ); + + $this->addResponse('Generated backup ' . $this->backupInfo['backupName'] . '.', + 0, + ['filename' => $this->backupInfo['backupName'], + 'uuid' => $this->basepackages->storages->packagesData->responseData['uuid'], + 'request' => $data + ] + ); + + return true; + } + } catch (\Exception | \throwable $e) { + $this->addResponse('Backup Error: ' . $e->getMessage(), 1); - return true; + $this->basepackages->progress->resetProgress(); } return false; @@ -718,7 +754,7 @@ private function getDbKey($dbConfig = null) } } - protected function registerBackupProgressMethods() + public function getBackupProgressMethods() { $this->backupProgressMethods = [ @@ -740,10 +776,17 @@ protected function registerBackupProgressMethods() ] ]; + return $this->backupProgressMethods; + } + + protected function registerBackupProgressMethods() + { + $this->getBackupProgressMethods(); + $this->basepackages->progress->registerMethods($this->backupProgressMethods); } - protected function registerRestoreProgressMethods() + public function getRestoreProgressMethods() { $this->restoreProgressMethods = [ @@ -761,6 +804,13 @@ protected function registerRestoreProgressMethods() ] ]; + return $this->restoreProgressMethods; + } + + protected function registerRestoreProgressMethods() + { + $this->getRestoreProgressMethods(); + $this->basepackages->progress->registerMethods($this->restoreProgressMethods); } } \ No newline at end of file diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php index 59b3f3e32..89fc29f93 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php @@ -81,19 +81,28 @@ public function registerMethods(array $methods) return false; } - public function unregisterMethods(array $methods, $using = 'method')//Either Method or Text as identifier in case of duplicate methods. + public function unregisterMethods(array $methods, $using = 'method', array $childs = [])//Either Method or Text as identifier in case of duplicate methods. { $progressFile = $this->readProgressFile(); + if ($using !== 'method' && $using !== 'text') { + $using = 'method'; + } + if (isset($progressFile['processes']) && count($progressFile['processes']) > 0) { foreach ($methods as $method) { foreach ($progressFile['processes'] as $progressFileKey => $progressFileMethod) { - if ($using === 'method') { - if ($progressFileMethod['method'] === $method) { - unset($progressFile['processes'][$progressFileKey]); - } - } else if ($using === 'text') { - if ($progressFileMethod['text'] === $method) { + if ($progressFileMethod[$using] === $method) { + if (count($childs) > 0 && + isset($progressFile['processes'][$progressFileKey]['childs']) && + count($progressFile['processes'][$progressFileKey]['childs']) > 0 + ) { + foreach ($progressFile['processes'][$progressFileKey]['childs'] as $childKey => $child) { + if (in_array($child[$using], $childs)) { + unset($progressFile['processes'][$progressFileKey]['childs'][$childKey]); + } + } + } else { unset($progressFile['processes'][$progressFileKey]); } } diff --git a/system/Base/Providers/ModulesServiceProvider/Installer.php b/system/Base/Providers/ModulesServiceProvider/Installer.php index ee2865f8d..735d84049 100644 --- a/system/Base/Providers/ModulesServiceProvider/Installer.php +++ b/system/Base/Providers/ModulesServiceProvider/Installer.php @@ -7,6 +7,7 @@ use League\Flysystem\UnableToCopyFile; use League\Flysystem\UnableToDeleteDirectory; use League\Flysystem\UnableToDeleteFile; +use League\Flysystem\UnableToListContents; use League\Flysystem\UnableToMoveFile; use League\Flysystem\UnableToReadFile; use League\Flysystem\UnableToRetrieveMetadata; @@ -51,6 +52,8 @@ class Installer extends BasePackage protected $storesToIndex = []; + protected $progressFileName = 'modulesinstaller'; + public function init($process = 'precheck') { $this->queue = $this->modules->queues->getActiveQueue(); @@ -73,7 +76,7 @@ public function init($process = 'precheck') throw $e; } - $this->basepackages->progress->init(null, 'modulesinstaller'); + $this->basepackages->progress->init(null, $this->progressFileName); if ($this->basepackages->progress->checkProgressFile()) { $this->basepackages->progress->deleteProgressFile(); @@ -128,7 +131,7 @@ public function runProcess(array $data) return false; } - set_time_limit(300);//5 mins + set_time_limit(600);//10 mins if ($this->process === 'runprecheck') { $this->basepackages->progress->preCheckComplete(); @@ -139,7 +142,6 @@ public function runProcess(array $data) return false; } - // usleep(500); } $this->queue['status'] = 1; @@ -156,9 +158,13 @@ public function runProcess(array $data) return false; } - // usleep(500); } - // + + $this->queue['status'] = 2; + + $this->modules->queues->update($this->queue); + + $this->addResponse('Process complete', 0, ['queue' => $this->queue]); } } @@ -643,7 +649,7 @@ protected function runRsync($args) ] ]; - if ($this->queue['settings']['rsync']['deleteDestinationFiles']) { + if ($this->queue['settings']['files']['deleteDestinationFiles']) { $rsyncSettings[Rsync::CONF_OPTIONS][Rsync::OPT_DELETE_AFTER] = true; } @@ -681,7 +687,7 @@ protected function runRsync($args) } } - if ($this->queue['settings']['rsync']['deleteDestinationFiles']) { + if ($this->queue['settings']['files']['deleteDestinationFiles']) { if (str_starts_with($output, 'deleting')) { if (!str_ends_with($output, '/') && !str_ends_with($output, '.git') && @@ -697,14 +703,14 @@ protected function runRsync($args) if ($precheck) { $this->queue['results'][$taskName][$module['module_type']][$module['id']]['precheck'] = 'pass'; - if ($this->queue['settings']['rsync']['deleteDestinationFiles']) { + if ($this->queue['settings']['files']['deleteDestinationFiles']) { $preCheckQueueLogs = $this->helper->encode(['modifiedFiles' => $modifiedFiles, 'deleteFiles' => $deleteFiles]); } else { $preCheckQueueLogs = $this->helper->encode(['modifiedFiles' => $modifiedFiles]); } } else { $this->queue['results'][$taskName][$module['module_type']][$module['id']]['result'] = 'pass'; - if ($this->queue['settings']['rsync']['deleteDestinationFiles']) { + if ($this->queue['settings']['files']['deleteDestinationFiles']) { $resultQueueLogs = $this->helper->encode(['modifiedFiles' => $modifiedFiles, 'deleteFiles' => $deleteFiles]); } else { $resultQueueLogs = $this->helper->encode(['modifiedFiles' => $modifiedFiles]); @@ -812,14 +818,18 @@ protected function updateVersion($args) $package['version'] = $package['update_version']; $package['updated_on'] = date('c'); + $package['update_available'] = 0; if ($this->access->auth->account() && isset($this->access->auth->account()['id'])) { $package['updated_by'] = $this->access->auth->account()['id']; } $this->modules->packages->update($package); + + $this->core->core['version'] = $package['version']; + + $this->core->update($this->core->core); } catch (\throwable $e) { - trace([$e]); $this->queue['results'][$taskName][$module['module_type']][$module['id']]['result'] = 'fail'; return $this->queueHasErrors( @@ -866,7 +876,7 @@ public function cleanup(array $what) } } - protected function createBackup() + protected function createBackup($args) { if ((bool) $this->queue['settings']['backupSettings']['backup'] === false) { return true; @@ -876,12 +886,74 @@ protected function createBackup() $this->queue['settings']['backupSettings']['notes'] = 'Backup taken while processing module installer queue with ID: ' . $this->queue['id']; } - return $this->basepackages->backuprestore->init()->backup($this->queue['settings']['backupSettings']); - } + $taskName = $args[0]; + $module = $args[1]; - protected function rollBack() - { - // + $this->queue['results'][$taskName][$module['module_type']][$module['id']]['result'] = 'pass'; + $resultQueueLogs = &$this->queue['results'][$taskName][$module['module_type']][$module['id']]['result_logs']; + + $backupInit = $this->basepackages->backuprestore->init()->backup($this->queue['settings']['backupSettings'], true); + + if (!$backupInit) { + $this->queue['results'][$taskName][$module['module_type']][$module['id']]['result'] = 'fail'; + + return $this->queueHasErrors( + $this->basepackages->backuprestore->packagesData->responseMessage, + $resultQueueLogs, + false + ); + } + + $progress = $this->basepackages->progress->getProgress(); + + if (is_string($progress)) { + $progress = $this->helper->decode($progress, true); + } + + if ($progress['runners']['running']['method'] === 'createBackup') { + if (isset($progress['runners']['running']['childs']) && + is_array($progress['runners']['running']['childs']) && + count($progress['runners']['running']['childs']) > 0 + ) { + foreach ($progress['runners']['running']['childs'] as $child) { + $method = $child['method']; + + $this->basepackages->progress->updateProgress('createBackup', null, false, $method); + + if ($method === 'finishBackup') { + $call = $this->basepackages->backuprestore->$method($this->queue['settings']['backupSettings']); + } else { + $call = $this->basepackages->backuprestore->$method(); + } + + if ($call === false) { + $this->queue['results'][$taskName][$module['module_type']][$module['id']]['result'] = 'fail'; + + return $this->queueHasErrors( + $this->basepackages->backuprestore->packagesData->responseMessage, + $resultQueueLogs, + false + ); + } + + if ($call !== false) { + $call = true; + } + + $this->basepackages->progress->updateProgress('createBackup', $call, false, $method); + } + } + + return true; + } + + $this->queue['results'][$taskName][$module['module_type']][$module['id']]['result'] = 'fail'; + + return $this->queueHasErrors( + 'Progress Error!', + $resultQueueLogs, + false + ); } protected function registerRunPrecheckProgressMethods() @@ -1013,7 +1085,9 @@ protected function registerRunProcessProgressMethods() array_push($this->runProcessProgressMethods, [ 'method' => 'createBackup', - 'text' => 'Creating filesystem and database backup...' + 'text' => 'Creating filesystem and database backup...', + 'args' => [$taskName, $module], + 'childs' => $this->basepackages->backuprestore->getBackupProgressMethods() ] ); array_push($this->runProcessProgressMethods, @@ -1037,6 +1111,13 @@ protected function registerRunProcessProgressMethods() 'args' => [$taskName, $module], ] ); + array_push($this->runProcessProgressMethods, + [ + 'method' => 'deleteSourceFiles-' . $module['id'] . '-' . strtolower(str_replace(' ', '', $module['name'])), + 'text' => 'Updating version for ' . $module['name'] . ' (' . ucfirst($module['module_type']) . ')...', + 'args' => [$taskName, $module], + ] + ); } } } @@ -1171,454 +1252,53 @@ protected function getComposerJsonFile() } } - // protected function checkDependencies() - // { - // if (count($this->modulesToProcess) === 0) { - // return true; - // } - - // // var_dump($this->modulesToProcess);die(); - // foreach ($this->modulesToProcess as $moduleName => $module) { - // $this->preCheckResult[$moduleName] = []; - // $this->preCheckResult[$moduleName]['module'] = $module['module']; - // $this->preCheckResult[$moduleName]['result'] = 'success'; - // $this->preCheckResult[$moduleName]['logs'] = ''; - - // $names = explode('-', $moduleName); - - // try { - // $jsonFile = $this->helper->decode($this->localContent->read($module['location'] . 'Install/' . substr($names[1], 0, -1) . '.json'), true); - // } catch (\throwable $e) { - // $this->preCheckResult[$moduleName]['result'] = 'error'; - // $this->preCheckResult[$moduleName]['logs'] .= 'Reading module ' . $moduleName . ' install JSON file resulted in error. '; - - // continue;//move onto the next one. - // } - - // // Make sure we have an entry for all module dependencies. Even if there are no dependencies, we need to make sure we have empty array for them. - // if (!isset($jsonFile['dependencies']) || - // (isset($jsonFile['dependencies']) && - // (!isset($jsonFile['dependencies']['core']) || - // !isset($jsonFile['dependencies']['components']) || - // !isset($jsonFile['dependencies']['packages']) || - // !isset($jsonFile['dependencies']['middlewares']) || - // !isset($jsonFile['dependencies']['views']))) - // ) { - // $this->preCheckResult[$moduleName]['result'] = 'error'; - // $this->preCheckResult[$moduleName]['logs'] .= 'Reading module ' . $moduleName . ' dependencies resulted in error. '; - - // continue;//move onto the next one. - // } - - // //Check Core dependency - // if (Version::greaterThan($jsonFile['dependencies']['core']['version'], $this->core->getVersion())) { - // //Lets check for latest release on Core as required version is greater than installed version. - // $core = $this->modules->packages->getPackageByName('core'); - // $core = $this->modules->manager->updateModuleRepoDetails($core); - - // if ($core) { - // $this->preCheckResult[$moduleName]['result'] = 'warning'; - // $this->preCheckResult[$moduleName]['logs'] .= 'Module ' . $moduleName . ' needs core version : ' . $core['update_version'] . '. Installed version of core is : ' . $core['version'] . '. Adding Core to list of updates. '; - - // $this->preCheckResult['core'] = []; - // $this->preCheckResult['core']['module'] = $core; - // $this->preCheckResult['core']['result'] = 'warning'; - // $name = $module['module']['name']; - // if (isset($module['module']['display_name'])) { - // $name = $module['module']['display_name']; - // } - // $this->preCheckResult['core']['logs'] = 'Added to queue as required by module : ' . $name . '. '; - // } - // } - - // // - // } - - // var_dump($this->preCheckResult);die(); - // // $this->getLatestRepositoryModulesData(); - - // ${$this->postData()['type']} = - // $this->{$this->postData()['type']}->getById($this->postData()['id'])->getAllArr(); - - // $dependencies = - // json_decode(${$this->postData()['type']}['dependencies'], true); - - // $checkForDependencies = $this->checkRegisteredDependencies($dependencies); - - // if (is_array($checkForDependencies)) { - // $this->packagesData->responseCode = 1; - - // $this->packagesData->responseMessage = - // 'Dependency ' . $checkForDependencies['name'] . ' not found!
' . - // 'Check repository ' . $checkForDependencies['repo'] . ' for further details.'; - - // return $this->packagesData; - // } - - // return true; - // } - - // protected function checkRegisteredDependencies($dependencies) - // { - // $found = true; - - // $this->dependenciesToDownload = []; - - // foreach ($dependencies as $dependencyKey => $dependencyValue) { - // if ($dependencyKey === 'app') { - // $dependencyKey = $dependencyKey . 's'; - // } - - // if (!isset($dependencyValue['name'])) { //if dependency is an array - // foreach ($dependencyValue as $multiDependencyKey => $multiDependencyValue) { - - // $thisDependency = - // $this->{$dependencyKey}->getAll( - // [ - // 'name' => $multiDependencyValue['name'], - // 'repo' => $multiDependencyValue['repo'], - // 'version' => $multiDependencyValue['version'] - // ] - // ); - - // if (!$thisDependency) { - - // $thisDependency = - // $this->{$dependencyKey}->getAll( - // [ - // 'name' => $multiDependencyValue['name'], - // 'repo' => $multiDependencyValue['repo'], - // 'update_version' => $multiDependencyValue['version'], - // ] - // ); - - // if ($thisDependency) { - - // if ($thisDependency[0]->get('update_available') === 1) { - - // $multiDependencyValue['type'] = $dependencyKey; - // $multiDependencyValue['id'] = $thisDependency[0]->get('id'); - // array_push($this->dependenciesToDownload, $multiDependencyValue); - // } - - // $found = true; - - // } else { - // $found = $multiDependencyValue; - - // return $found; - // } - // } else { - // if ($thisDependency[0]->get('installed') === 0) { - - // $multiDependencyValue['type'] = $dependencyKey; - // $multiDependencyValue['id'] = $thisDependency[0]->get('id'); - // array_push($this->dependenciesToDownload, $multiDependencyValue); - // } - - // $found = true; - // } - // } - // } else { - - // $thisDependency = - // $this->{$dependencyKey}->getAll( - // [ - // 'name' => $dependencyValue['name'], - // 'repo' => $dependencyValue['repo'], - // 'version' => $dependencyValue['version'], - // ] - // ); - - // if (!$thisDependency) { - - // $thisDependency = - // $this->{$dependencyKey}->getAll( - // [ - // 'name' => $dependencyValue['name'], - // 'repo' => $dependencyValue['repo'], - // 'update_version' => $dependencyValue['version'], - // ] - // ); - - // if ($thisDependency) { - - // if ($thisDependency[0]->get('update_available') === 1) { - - // $dependencyValue['type'] = $dependencyKey; - // $dependencyValue['id'] = $thisDependency[0]->get('id'); - // array_push($this->dependenciesToDownload, $dependencyValue); - - // } - - // $found = true; - - // } else { - // $found = $dependencyValue; - - // return $found; - // } - - // } else { - // if ($thisDependency[0]->get('installed') === 0) { - - // $dependencyValue['type'] = $dependencyKey; - // $dependencyValue['id'] = $thisDependency[0]->get('id'); - // array_push($this->dependenciesToDownload, $dependencyValue); - - // } - - // $found = true; - // } - // } - // } - - // return $found; - // } - - - - // protected function getLatestRepositoryModulesData() - // { - // $repositories = getAllArr($this->repositories->getAll()); - - // if (count($repositories) > 0) { - // $modules = $this->packages->use(Modules::class); - - // foreach ($repositories as $repositoryKey => $repositoryValue) { - // $sync = $modules->syncRemoteWithLocal($repositoryValue['id']); - - // if ($sync->packagesData['responseCode'] === 1) { - // $this->packagesData->responseCode = 1; - - // $this->packagesData->responseMessage = 'Error Syncing with repository ' . $repositoryValue['name']; - - // return $this->packagesData; - // } - // } - // } - // } - - // protected function createBackup() - // { - // trace([$this->queue]); - // $this->basepackages->backuprestore->init()->backup(); - - // - // $this->backupLocation = '.backups/'; + protected function deleteSourceFiles($args) + { + if ((bool) $this->queue['settings']['files']['deleteSourceFiles'] === false) { + return true; + } - // $now = new \DateTime('now'); + $taskName = $args[0]; + $module = $args[1]; - // $this->zip->open(base_path($this->backupLocation . '/' . $now->format('Y_m_d_H_i_s') . '.zip'), $this->zip::CREATE); + try { + $this->queue['results'][$taskName][$module['module_type']][$module['id']]['result'] = 'fail'; + $resultQueueLogs = &$this->queue['results'][$taskName][$module['module_type']][$module['id']]['result_logs']; - // $framework = []; - // $framework['dir'] = []; - // $framework['file'] = []; + $modulesToInstallOrUpdate = $this->modules->manager->getModuleInfo( + [ + 'module_type' => $module['module_type'], + 'module_id' => $module['id'] + ] + ); - // $rootContents = $this->localContent->listContents('/'); + $files = + $this->basepackages->utils->scanDir( + 'var/tmp/installer/' . $modulesToInstallOrUpdate['repo_details']['details']['name'] . '-' . $modulesToInstallOrUpdate['repo_details']['latestRelease']['name'] + ); - // foreach ($rootContents as $rootKey => $rootValue) { - // if ($rootValue['type'] === 'dir') { - // if ($rootValue['path'] !== '.backups' && - // $rootValue['path'] !== '.git' && - // $rootValue['path'] !== 'vendor' - // ) { - // array_push($framework['dir'], $rootValue['path']); - // } - // } else if ($rootValue['type'] === 'file') { - // if ($rootValue['path'] !== '.gitignore' && - // $rootValue['path'] !== '.htaccess.example' - // ) { - // array_push($framework['file'], $rootValue['path']); - // } - // } - // } + if (count($files['files']) > 0) { + foreach ($files['files'] as $file) { + $this->localContent->delete($file); + } + } - // foreach ($framework['dir'] as $dirKey => $dirValue) { - // $rootDirContents[$dirValue] = $this->localContent->listContents($dirValue, true); - // } + if (count($files['dirs']) > 0) { + foreach ($files['dirs'] as $dir) { + $this->localContent->deleteDirectory($dir); + } + } - // foreach ($rootDirContents as $rootDirContentsKey => $rootDirContentsValue) { - // if (count($rootDirContentsValue) > 0) { - // foreach ($rootDirContentsValue as $subDirectoryKey => $subDirectory) { - // if ($subDirectory['type'] === 'dir') { - // $this->zip->addEmptyDir($subDirectory['dirname']); - // } else if ($subDirectory['type'] === 'file') { - // $this->zip->addFile($subDirectory['path']); - // } - // } - // } else { - // $this->zip->addEmptyDir($rootDirContentsKey); - // } - // }; - - // foreach ($framework['file'] as $fileKey => $fileValue) { - // $this->zip->addFile($fileValue); - // } + $this->localContent->deleteDirectory( + 'var/tmp/installer/' . $modulesToInstallOrUpdate['repo_details']['details']['name'] . '-' . $modulesToInstallOrUpdate['repo_details']['latestRelease']['name'] + ); - // $this->zip->close(); - - // $this->packagesData->backupFile = $now->format('Y_m_d_H_i_s') . '.zip'; - - // $this->packagesData->responseCode = 0; - // } - - // protected function processInstall() - // { - // foreach ($this->modulesToInstall as $moduleToInstallKey => $moduleToInstall) { - - // $repoNameArr = explode('/', $moduleToInstall['repo']); - // $repoName = end($repoNameArr); - - // $this->downloadPackagesAndDependencies($moduleToInstall); - - // $contents = $this->extractDownloadedPackagesAndDependencies( - // $moduleToInstall['name'], - // $repoName, - // $moduleToInstall['type'] - // ); - - // if ($contents) { - // $files = $this->copyFilesToDestination( - // $contents, - // $moduleToInstall['name'], - // $repoName, - // $moduleToInstall['type'] - // ); - // } - - - // $this->{$moduleToInstall['type']}->update( - // [ - // 'id' => $moduleToInstall['id'], - // 'installed' => 1, - // 'files' => json_encode($files), - // ] - // ); - // } - // } - - // protected function processUpdate() - // { - // $files = []; - - // foreach ($this->modulesToInstall as $moduleToInstallKey => $moduleToInstall) { - // // - // //Delete only files first - // //Check if directory is empty, then delete directory - // //check if directory is html_compiled, if so, then scan directory, delete all files first and then all directories. - // //Copy all files. - // // - // var_dump(json_decode($this->{$moduleToInstall['type']}->getById($moduleToInstall['id'])->getAllArr()['files'], true)); - // // $repoNameArr = explode('/', $moduleToInstall['repo']); - // // $repoName = end($repoNameArr); - - // // $this->downloadPackagesAndDependencies($moduleToInstall); - - // // $contents = $this->extractDownloadedPackagesAndDependencies( - // // $moduleToInstall['name'], - // // $repoName, - // // $moduleToInstall['type'] - // // ); - - // // if ($contents) { - // // $files = $this->copyFilesToDestination( - // // $contents, - // // $moduleToInstall['name'], - // // $repoName, - // // $moduleToInstall['type'] - // // ); - // // } - - - // // $this->{$moduleToInstall['type']}->update( - // // [ - // // 'id' => $moduleToInstall['id'], - // // 'installed' => 1, - // // 'files' => json_encode($files), - // // ] - // // ); - // } - // } - - // protected function copyFilesToDestination($contents, $name, $repoName, $type) - // { - // $installedFiles = []; - // $installedFiles['dir'] = []; - // $installedFiles['files'] = []; - - // foreach ($contents as $contentKey => $content) { - // $destDir = - // str_replace( - // $this->downloadLocation . '/' . strtolower($repoName) . '-master/', - // '', - // $content['dirname'] - // ); - - // if ($content['type'] === 'dir') { - - // $this->localContent->createDirectory($destDir . '/' . $content['basename']); - - // array_push($installedFiles['dir'], $destDir . '/' . $content['basename']); - - // } else if ($content['type'] === 'file') { - - // if ($content['basename'] !== '.gitkeep') { - - // $this->localContent->copy($content['path'], $destDir . '/' . $content['basename']); - - // array_push($installedFiles['files'], $destDir . '/' . $content['basename']); - // } - - // } - // } - - // return $installedFiles; - // // if ($type === 'components' || $type === 'packages' || $type === 'middlewares') { - // // if ($type === 'components') { - // // $this->localContent->write( - // // $type . '/'. $this->appName . '/Install/' . $this->componentName . '/files.info', json_encode($installedFiles) - // // ); - // // } else if ($type === 'packages') { - // // $this->localContent->write( - // // $type . '/'. $this->appName . '/Install/' . $this->packageName . '/files.info', json_encode($installedFiles) - // // ); - // // } else if ($type === 'middlewares') { - // // $this->localContent->write( - // // $type . '/'. $this->appName . '/Install/' . $this->middlewareName . '/files.info', json_encode($installedFiles) - // // ); - // // } - // // } else { - // // $this->localContent->write($type . '/'. $this->appName . '/files.info', json_encode($installedFiles)); - // // } - // } - - // protected function deleteDownloads() - // { - // $downloadsToDelete = $this->localContent->listContents('.downloads', true); - - // $downloadedFiles = []; - // $downloadedFiles['dir'] = []; - // $downloadedFiles['files'] = []; - - // foreach ($downloadsToDelete as $key => $value) { - // if ($value['type'] === 'dir') { - // array_push($downloadedFiles['dir'], $value['path']); - // } else if ($value['type'] === 'file') { - // array_push($downloadedFiles['files'], $value['path']); - // } - // } - - // if (count($downloadedFiles['files']) > 0) { - // foreach ($downloadedFiles['files'] as $fileKey => $file) { - // $this->localContent->delete($file); - // } - // } - - // if (count($downloadedFiles['dir']) > 0) { - // foreach ($downloadedFiles['dir'] as $dirKey => $dir) { - // $this->localContent->deleteDir($dir); - // } - // } - // } + $this->queue['results'][$taskName][$module['module_type']][$module['id']]['result'] = 'pass'; + } catch (UnableToListContents | UnableToDeleteDirectory | UnableToDeleteFile | \throwable $e) { + return $this->queueHasErrors( + $e->getMessage(), + $resultQueueLogs + ); + } + } } \ No newline at end of file diff --git a/system/Base/Providers/ModulesServiceProvider/Queues.php b/system/Base/Providers/ModulesServiceProvider/Queues.php index 6618cc1eb..fd29a9d0a 100644 --- a/system/Base/Providers/ModulesServiceProvider/Queues.php +++ b/system/Base/Providers/ModulesServiceProvider/Queues.php @@ -71,8 +71,9 @@ protected function addActiveQueue() 'password_protect' => $this->basepackages->utils->generateNewPassword()['password'], 'notes' => '', ], - 'rsync' => + 'files' => [ + 'deleteSourceFiles' => false, 'deleteDestinationFiles' => false ], 'emailReport' => $this->access->auth->account()['email'] @@ -278,7 +279,7 @@ public function saveQueueSettings($data) } } - array_walk($data['settings']['rsync'], function(&$setting, $index) { + array_walk($data['settings']['files'], function(&$setting, $index) { if ($setting !== '') { if ($setting == 'true') { $setting = true; From 66afd430b0107907e8987802a1094678cf2a43ac Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Sun, 2 Feb 2025 18:02:23 +1100 Subject: [PATCH 02/54] update #34, update version is the last runner. --- system/Base/Providers/ModulesServiceProvider/Installer.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system/Base/Providers/ModulesServiceProvider/Installer.php b/system/Base/Providers/ModulesServiceProvider/Installer.php index 735d84049..c2038c87a 100644 --- a/system/Base/Providers/ModulesServiceProvider/Installer.php +++ b/system/Base/Providers/ModulesServiceProvider/Installer.php @@ -1106,14 +1106,14 @@ protected function registerRunProcessProgressMethods() ); array_push($this->runProcessProgressMethods, [ - 'method' => 'updateVersion-' . $module['id'] . '-' . strtolower(str_replace(' ', '', $module['name'])), + 'method' => 'deleteSourceFiles-' . $module['id'] . '-' . strtolower(str_replace(' ', '', $module['name'])), 'text' => 'Updating version for ' . $module['name'] . ' (' . ucfirst($module['module_type']) . ')...', 'args' => [$taskName, $module], ] ); array_push($this->runProcessProgressMethods, [ - 'method' => 'deleteSourceFiles-' . $module['id'] . '-' . strtolower(str_replace(' ', '', $module['name'])), + 'method' => 'updateVersion-' . $module['id'] . '-' . strtolower(str_replace(' ', '', $module['name'])), 'text' => 'Updating version for ' . $module['name'] . ' (' . ucfirst($module['module_type']) . ')...', 'args' => [$taskName, $module], ] From 9254a2d518260b47225c35e45b8d02c02a997093 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Sun, 2 Feb 2025 19:57:27 +1100 Subject: [PATCH 03/54] update #34, Added email report method. --- .../Views/Default/html/modules/analyse.html | 19 ++++++-- system/Base/Helpers.php | 48 +++++++++++++++++++ .../ModulesServiceProvider/Installer.php | 34 ++++++++++++- 3 files changed, 95 insertions(+), 6 deletions(-) diff --git a/apps/Core/Views/Default/html/modules/analyse.html b/apps/Core/Views/Default/html/modules/analyse.html index 8f10e963e..d1494457f 100644 --- a/apps/Core/Views/Default/html/modules/analyse.html +++ b/apps/Core/Views/Default/html/modules/analyse.html @@ -295,11 +295,6 @@ } if (response.responseCode == 0) { - paginatedPNotify('success', { - text : response.responseMessage, - textTrusted : true - }); - if (postData['process'] === 'runprecheck') { $('#{{componentId}}-{{sectionId}}-re-analyse').removeClass('disabled'); $('#{{componentId}}-{{sectionId}}-perform-precheck').text(' RE-PERFORM PRECHECK'); @@ -313,7 +308,21 @@ $('#{{componentId}}-{{sectionId}}-process-queue').attr('hidden', true); $('#{{componentId}}-{{sectionId}}-process-queue').children('i').attr('hidden', true); $('#{{componentId}}-{{sectionId}}-cancel').attr('hidden', true); + + var notifyText = response.responseMessage; + var notifyType = 'success'; + if (response.responseData && response.responseData.emailReport && response.responseData.emailReport == true) { + notifyText += '. An email report was successfully sent to : ' + $('#{{componentId}}-{{sectionId}}-email_report').val().trim(); + } else { + notifyType = 'notice'; + notifyText += '. Failed to send email report!'; + } } + + paginatedPNotify(notifyType, { + text : notifyText, + textTrusted : true + }); } else { paginatedPNotify('error', { text : response.responseMessage, diff --git a/system/Base/Helpers.php b/system/Base/Helpers.php index c20444975..9bced6cf1 100644 --- a/system/Base/Helpers.php +++ b/system/Base/Helpers.php @@ -473,6 +473,30 @@ function array_get_values_recursive($keys = [], array $arr) { } } +if (!function_exists('extractLineFromFile')) { + function extractLineFromFile($file, $word) + { + $lineWithWord = NULL; + + $handle = fopen($file, "r"); + + if ($handle) { + while (($line = fgets($handle)) !== false) { + if (strpos($line, $word) === 0) { + $parts = explode(' ', $line); + + $lineWithWord = rtrim(trim($parts[1]), ';'); + + break; + } + } + + fclose($handle); + } + + return $lineWithWord; + } +} if (!function_exists('arraySqueeze')) { //$task = keep - Keep the data of defined keys, remove rest @@ -518,4 +542,28 @@ function arrayFilterKeywords($array, array $keywords, $task = 'keep') return $array; } +} + +if (!function_exists('printArrayList')) { + function printArrayList($array) { + $html = "
    "; + + foreach($array as $k => $v) { + if (!is_array($v) && !is_null($v) && is_string($v) && str_starts_with($v, '{') && str_ends_with($v, '}')) { + $v = @json_decode($v, true); + } + + if (is_array($v)) { + $html .= "
  • " . $k . " :
  • "; + $html .= " " . printArrayList($v); + continue; + } + + $html .= "
  • " . $k . " : " . $v . "
  • "; + } + + $html .= "
"; + + return $html; + } } \ No newline at end of file diff --git a/system/Base/Providers/ModulesServiceProvider/Installer.php b/system/Base/Providers/ModulesServiceProvider/Installer.php index c2038c87a..912e842d0 100644 --- a/system/Base/Providers/ModulesServiceProvider/Installer.php +++ b/system/Base/Providers/ModulesServiceProvider/Installer.php @@ -164,7 +164,12 @@ public function runProcess(array $data) $this->modules->queues->update($this->queue); - $this->addResponse('Process complete', 0, ['queue' => $this->queue]); + $emailReport = false; + if ($this->queue['settings']['emailReport'] !== '') { + $emailReport = $this->emailReport(); + } + + $this->addResponse('Process complete', 0, ['queue' => $this->queue, 'emailReport' => $emailReport]); } } @@ -1301,4 +1306,31 @@ protected function deleteSourceFiles($args) ); } } + + protected function emailReport() + { + //If Email is not configured, we cannot send report. + if (!$this->basepackages->email->setup()) { + return true; + } + + $addresses = explode(',', $this->queue['settings']['emailReport']); + + return $this->addEmailToQueue($addresses); + } + + protected function addEmailToQueue(array $addresses) + { + $emailData['app_id'] = $this->apps->getAppInfo()['id']; + $emailData['domain_id'] = $this->domains->getDomain()['id']; + $emailData['status'] = 1; + $emailData['priority'] = 1; + $emailData['confidential'] = 0; + $emailData['to_addresses'] = $addresses; + $emailData['subject'] = 'Queue Report for Queue ID: ' . $this->queue['id']; + //Move this to template in future. + $emailData['body'] = printArrayList($this->queue); + + return $this->basepackages->emailqueue->addToQueue($emailData); + } } \ No newline at end of file From 19054142fd26ac24b961c4be5de3b8d1665614cb Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Sun, 2 Feb 2025 20:02:37 +1100 Subject: [PATCH 04/54] fix issue #574 --- apps/Core/Components/Apps/AppsComponent.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/Core/Components/Apps/AppsComponent.php b/apps/Core/Components/Apps/AppsComponent.php index 06d87f498..c5742f0d8 100644 --- a/apps/Core/Components/Apps/AppsComponent.php +++ b/apps/Core/Components/Apps/AppsComponent.php @@ -378,7 +378,7 @@ public function updateAction() $this->apps->packagesData->responseCode ); - $this->addToNotification('update', 'Updated app ' . $this->postData()['name'], null, $this->apps->packagesData->last); + $this->addToNotification('update', 'Updated app', null, $this->apps->packagesData->last); } /** From 1bd364fba2e0000275b1b05b83b616defd622ab3 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Sun, 2 Feb 2025 20:10:02 +1100 Subject: [PATCH 05/54] Fix issue #585 --- system/Base/Installer/Packages/Setup.php | 7 ------- .../Packages/Setup/Register/Modules/Component.php | 4 ---- .../Packages/Setup/Register/Modules/Middleware.php | 4 ---- .../Installer/Packages/Setup/Register/Modules/Package.php | 4 ---- .../Installer/Packages/Setup/Register/Modules/View.php | 4 ---- .../Installer/Packages/Setup/Schema/Modules/Components.php | 7 ------- .../Packages/Setup/Schema/Modules/Middlewares.php | 7 ------- .../Installer/Packages/Setup/Schema/Modules/Packages.php | 7 ------- .../Base/Installer/Packages/Setup/Schema/Modules/Views.php | 7 ------- 9 files changed, 51 deletions(-) diff --git a/system/Base/Installer/Packages/Setup.php b/system/Base/Installer/Packages/Setup.php index 5c5bfbe08..99de83d05 100644 --- a/system/Base/Installer/Packages/Setup.php +++ b/system/Base/Installer/Packages/Setup.php @@ -521,13 +521,6 @@ protected function registerModule($type) $this->registerStorages($jsonFile); } - $jsonFile['files'] = []; - - if ($jsonFile['name'] === 'Core') { - $jsonFile['files'] = - array_merge_recursive($this->basepackages->utils->init($this->container)->scanDir('system/', true), $this->basepackages->utils->init($this->container)->scanDir('apps/', true)); - } - $this->registerCorePackage($jsonFile); } } diff --git a/system/Base/Installer/Packages/Setup/Register/Modules/Component.php b/system/Base/Installer/Packages/Setup/Register/Modules/Component.php index b37cbca8b..0a61d2a19 100644 --- a/system/Base/Installer/Packages/Setup/Register/Modules/Component.php +++ b/system/Base/Installer/Packages/Setup/Register/Modules/Component.php @@ -40,10 +40,6 @@ public function register($db, $ff, $componentFile, $menuId, $helper) 'installed' => 1, 'apps' => $helper->encode($componentApp), - 'files' => - isset($componentFile['files']) ? - $helper->encode($componentFile['files']) : - $helper->encode([]), 'settings' => isset($componentFile['settings']) ? $helper->encode($componentFile['settings']) : diff --git a/system/Base/Installer/Packages/Setup/Register/Modules/Middleware.php b/system/Base/Installer/Packages/Setup/Register/Modules/Middleware.php index 417519945..b155e5b0b 100644 --- a/system/Base/Installer/Packages/Setup/Register/Modules/Middleware.php +++ b/system/Base/Installer/Packages/Setup/Register/Modules/Middleware.php @@ -36,10 +36,6 @@ public function register($db, $ff, $middlewareFile, $helper) 'apps' => $apps, 'api_id' => 1, 'installed' => 1, - 'files' => - isset($middlewareFile['files']) ? - $helper->encode($middlewareFile['files']) : - $helper->encode([]), 'updated_by' => 0 ]; diff --git a/system/Base/Installer/Packages/Setup/Register/Modules/Package.php b/system/Base/Installer/Packages/Setup/Register/Modules/Package.php index ad5458ebd..928a73473 100644 --- a/system/Base/Installer/Packages/Setup/Register/Modules/Package.php +++ b/system/Base/Installer/Packages/Setup/Register/Modules/Package.php @@ -29,10 +29,6 @@ public function register($db, $ff, $packageFile, $helper) $helper->encode(['1'=>['enabled'=>true]]), 'api_id' => 1, 'installed' => 1, - 'files' => - isset($packageFile['files']) ? - $helper->encode($packageFile['files']) : - $helper->encode([]), 'updated_by' => 0 ]; diff --git a/system/Base/Installer/Packages/Setup/Register/Modules/View.php b/system/Base/Installer/Packages/Setup/Register/Modules/View.php index 98fbd99ed..c47cc97a5 100644 --- a/system/Base/Installer/Packages/Setup/Register/Modules/View.php +++ b/system/Base/Installer/Packages/Setup/Register/Modules/View.php @@ -31,10 +31,6 @@ public function register($db, $ff, $viewFile, $helper) $helper->encode(['1'=>['enabled'=>true]]), 'api_id' => 1, 'installed' => 1, - 'files' => - isset($viewFile['files']) ? - $helper->encode($viewFile['files']) : - $helper->encode([]), 'updated_by' => 0 ]; diff --git a/system/Base/Installer/Packages/Setup/Schema/Modules/Components.php b/system/Base/Installer/Packages/Setup/Schema/Modules/Components.php index dad56a6d0..6f891b8b0 100644 --- a/system/Base/Installer/Packages/Setup/Schema/Modules/Components.php +++ b/system/Base/Installer/Packages/Setup/Schema/Modules/Components.php @@ -151,13 +151,6 @@ public function columns() 'notNull' => true, ] ), - new Column( - 'files', - [ - 'type' => Column::TYPE_MEDIUMTEXT, - 'notNull' => false, - ] - ), new Column( 'api_id', [ diff --git a/system/Base/Installer/Packages/Setup/Schema/Modules/Middlewares.php b/system/Base/Installer/Packages/Setup/Schema/Modules/Middlewares.php index 41d5d05a4..435c3be6f 100644 --- a/system/Base/Installer/Packages/Setup/Schema/Modules/Middlewares.php +++ b/system/Base/Installer/Packages/Setup/Schema/Modules/Middlewares.php @@ -129,13 +129,6 @@ public function columns() 'notNull' => true, ] ), - new Column( - 'files', - [ - 'type' => Column::TYPE_MEDIUMTEXT, - 'notNull' => false, - ] - ), new Column( 'api_id', [ diff --git a/system/Base/Installer/Packages/Setup/Schema/Modules/Packages.php b/system/Base/Installer/Packages/Setup/Schema/Modules/Packages.php index 6a331bf1f..66b7a9d8d 100644 --- a/system/Base/Installer/Packages/Setup/Schema/Modules/Packages.php +++ b/system/Base/Installer/Packages/Setup/Schema/Modules/Packages.php @@ -129,13 +129,6 @@ public function columns() 'notNull' => true, ] ), - new Column( - 'files', - [ - 'type' => Column::TYPE_MEDIUMTEXT, - 'notNull' => false, - ] - ), new Column( 'api_id', [ diff --git a/system/Base/Installer/Packages/Setup/Schema/Modules/Views.php b/system/Base/Installer/Packages/Setup/Schema/Modules/Views.php index 1d4cc8f11..80334687c 100644 --- a/system/Base/Installer/Packages/Setup/Schema/Modules/Views.php +++ b/system/Base/Installer/Packages/Setup/Schema/Modules/Views.php @@ -143,13 +143,6 @@ public function columns() 'notNull' => true, ] ), - new Column( - 'files', - [ - 'type' => Column::TYPE_MEDIUMTEXT, - 'notNull' => false, - ] - ), new Column( 'api_id', [ From e12b62c794fcfe32ac2404f4d57735baa14348c2 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Sun, 2 Feb 2025 20:20:59 +1100 Subject: [PATCH 06/54] fix issue #586 --- system/Base/Installer/Components/Setup.php | 6 ++++++ system/Base/Installer/View/setup.phtml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/system/Base/Installer/Components/Setup.php b/system/Base/Installer/Components/Setup.php index f1366026f..91419852b 100644 --- a/system/Base/Installer/Components/Setup.php +++ b/system/Base/Installer/Components/Setup.php @@ -800,6 +800,12 @@ protected function renderView($precheckFail = false, $onlyUpdateDb = false, $mes $this->localContent->read('/system/Base/Providers/BasepackagesServiceProvider/Packages/Geo/Data/AllCountries.json'), true ); + + $this->view->coreJson = + $this->helper->decode( + $this->localContent->read('system/Base/Installer/Packages/Setup/Register/Modules/Packages/Providers/Core/package.json'), + true + ); } echo $this->container->getShared('view')->render( diff --git a/system/Base/Installer/View/setup.phtml b/system/Base/Installer/View/setup.phtml index b638e553d..05a3218fb 100644 --- a/system/Base/Installer/View/setup.phtml +++ b/system/Base/Installer/View/setup.phtml @@ -44,7 +44,7 @@
SP Framework Database Update
-
SP Framework Core Setup
+
SP Framework Core Setup ()
From 1f13420f7fcea9fd51f46c2f173b4919e6d889a8 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Mon, 3 Feb 2025 01:10:19 +1100 Subject: [PATCH 07/54] cleanup #332 --- apps/Core/Components/Home/HomeComponent.php | 1 - apps/Core/Middlewares/IpFilter/IpFilter.php | 1 - 2 files changed, 2 deletions(-) diff --git a/apps/Core/Components/Home/HomeComponent.php b/apps/Core/Components/Home/HomeComponent.php index fb81ce37d..3d28243eb 100644 --- a/apps/Core/Components/Home/HomeComponent.php +++ b/apps/Core/Components/Home/HomeComponent.php @@ -2,7 +2,6 @@ namespace Apps\Core\Components\Home; -use Phalcon\Helper\Arr; use System\Base\BaseComponent; class HomeComponent extends BaseComponent diff --git a/apps/Core/Middlewares/IpFilter/IpFilter.php b/apps/Core/Middlewares/IpFilter/IpFilter.php index 1acd3252d..c3a7adc55 100644 --- a/apps/Core/Middlewares/IpFilter/IpFilter.php +++ b/apps/Core/Middlewares/IpFilter/IpFilter.php @@ -2,7 +2,6 @@ namespace Apps\Core\Middlewares\IpFilter; -use Phalcon\Mvc\View; use System\Base\BaseMiddleware; class IpFilter extends BaseMiddleware From 3e1241fba028c009f2a681a57340d87aa973362b Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Mon, 3 Feb 2025 01:11:32 +1100 Subject: [PATCH 08/54] update #352 - add errors to view gitignore. --- apps/Core/Packages/Devtools/Modules/Files/ViewsGitignore.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/Core/Packages/Devtools/Modules/Files/ViewsGitignore.txt b/apps/Core/Packages/Devtools/Modules/Files/ViewsGitignore.txt index 6c6f7e890..b6a8b6077 100644 --- a/apps/Core/Packages/Devtools/Modules/Files/ViewsGitignore.txt +++ b/apps/Core/Packages/Devtools/Modules/Files/ViewsGitignore.txt @@ -4,5 +4,6 @@ html/* !html/ !html/layouts/ !html/common/ +!html/errors/ !README.md !view.json \ No newline at end of file From 8e02fa6b1778335c8ddc1cc673521f7fba9fbf5a Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Mon, 3 Feb 2025 01:12:09 +1100 Subject: [PATCH 09/54] update #34 --- .../Packages/ApiClientServices/ApiClientServices.php | 9 +++++++++ .../Base/Providers/ModulesServiceProvider/Installer.php | 1 + system/Base/Providers/ModulesServiceProvider/Manager.php | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/ApiClientServices/ApiClientServices.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/ApiClientServices/ApiClientServices.php index 5dcecb075..a5bbc3680 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/ApiClientServices/ApiClientServices.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/ApiClientServices/ApiClientServices.php @@ -155,6 +155,9 @@ protected function switchApiModel($api = null) $api['location'] = ucfirst($api['location']); $api['category'] = ucfirst($api['category']); $api['provider'] = ucfirst($api['provider']); + if ($api['provider'] === 'Github' || $api['provider'] === 'Gitea') { + $api['location'] = 'Basepackages'; + } if ($api['location'] === 'Basepackages') { $modelClass = 'System\\Base\\Providers\\BasepackagesServiceProvider\\Packages\\Model\\ApiClientServices\\Apis\\' . $api['category'] . '\\'; @@ -179,6 +182,9 @@ public function addApi(array $data) $data['location'] = strtolower($data['location']); $data['category'] = strtolower($data['category']); $data['provider'] = strtolower($data['provider']); + if ($data['provider'] === 'github' || $data['provider'] === 'gitea') { + $data['location'] = 'basepackages'; + } $data = $this->encryptPassToken($data); @@ -209,6 +215,9 @@ public function updateApi(array $data) $data['location'] = strtolower($data['location']); $data['category'] = strtolower($data['category']); $data['provider'] = strtolower($data['provider']); + if ($data['provider'] === 'github' || $data['provider'] === 'gitea') { + $data['location'] = 'basepackages'; + } $data = $this->encryptPassToken($data); diff --git a/system/Base/Providers/ModulesServiceProvider/Installer.php b/system/Base/Providers/ModulesServiceProvider/Installer.php index 912e842d0..306c4fdc1 100644 --- a/system/Base/Providers/ModulesServiceProvider/Installer.php +++ b/system/Base/Providers/ModulesServiceProvider/Installer.php @@ -824,6 +824,7 @@ protected function updateVersion($args) $package['version'] = $package['update_version']; $package['updated_on'] = date('c'); $package['update_available'] = 0; + $package['update_version'] = ''; if ($this->access->auth->account() && isset($this->access->auth->account()['id'])) { $package['updated_by'] = $this->access->auth->account()['id']; diff --git a/system/Base/Providers/ModulesServiceProvider/Manager.php b/system/Base/Providers/ModulesServiceProvider/Manager.php index f7ea240cd..ef5d24454 100644 --- a/system/Base/Providers/ModulesServiceProvider/Manager.php +++ b/system/Base/Providers/ModulesServiceProvider/Manager.php @@ -578,7 +578,7 @@ protected function getRemoteModules() return true; } - $this->addResponse('Unable to Sync with remote server', 1); + $this->addResponse('Unable to sync with remote or remote has no module repositories!', 1); return false; } From 69094d0ac8d5f32e2cae14d519a54ec5b561047f Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Mon, 3 Feb 2025 01:12:43 +1100 Subject: [PATCH 10/54] cleanup #332 --- apps/Core/Components/Auth/AuthComponent.php | 6 +----- apps/Core/Views/Default/html/devtools/test/view.html | 1 - public/index.php | 2 +- .../BasepackagesServiceProvider/Packages/Filters.php | 6 +++--- system/Base/Providers/ErrorServiceProvider/Error.php | 4 ++-- 5 files changed, 7 insertions(+), 12 deletions(-) diff --git a/apps/Core/Components/Auth/AuthComponent.php b/apps/Core/Components/Auth/AuthComponent.php index aa45b934d..6becdbf5e 100644 --- a/apps/Core/Components/Auth/AuthComponent.php +++ b/apps/Core/Components/Auth/AuthComponent.php @@ -172,11 +172,7 @@ public function sendTwoFaEmailAction() { $this->requestIsPost(); - try { - $this->access->auth->twoFa->sendTwoFaEmail($this->postData()); - } catch (\Exception $e) { - var_dump($e);die(); - } + $this->access->auth->twoFa->sendTwoFaEmail($this->postData()); $this->addResponse( $this->access->auth->twoFa->packagesData->responseMessage, diff --git a/apps/Core/Views/Default/html/devtools/test/view.html b/apps/Core/Views/Default/html/devtools/test/view.html index 10148545d..4271c682a 100644 --- a/apps/Core/Views/Default/html/devtools/test/view.html +++ b/apps/Core/Views/Default/html/devtools/test/view.html @@ -1,7 +1,6 @@ Test +
+ {{adminltetags.useTag('modal', + [ + 'component' : component, + 'componentName' : componentName, + 'componentId' : componentId, + 'sectionId' : sectionId, + 'modalId' : 'queue-info-modal', + 'modalBodyInclude' : 'modules/queue/info', + 'modalSize' : 'xl', + 'modalHeader' : true, + 'modalFooter' : true, + 'modalHeaderCloseButton' : true, + 'modalEscClose' : true, + 'modalTitle' : ' INFO' + ] + )}} +
{{adminltetags.useTag('modal', [ @@ -589,13 +643,13 @@ 'componentId' : componentId, 'sectionId' : sectionId, 'modalId' : 'queue-settings-modal', - 'modalBodyInclude' : 'modules/settings', + 'modalBodyInclude' : 'modules/queue/settings', 'modalSize' : 'xl', 'modalHeader' : true, 'modalFooter' : true, 'modalHeaderCloseButton' : true, 'modalEscClose' : true, - 'modalTitle' : ' QUEUE SETTINGS', + 'modalTitle' : ' SETTINGS', 'modalFooterButtons' : [ 'component' : component, @@ -626,7 +680,7 @@ 'componentId' : componentId, 'sectionId' : sectionId, 'modalId' : 'queue-logs-modal', - 'modalBodyInclude' : 'modules/logs', + 'modalBodyInclude' : 'modules/queue/logs', 'modalSize' : 'xl', 'modalHeader' : true, 'modalFooter' : true, diff --git a/apps/Core/Views/Default/html/modules/queue/info.html b/apps/Core/Views/Default/html/modules/queue/info.html new file mode 100644 index 000000000..06e554768 --- /dev/null +++ b/apps/Core/Views/Default/html/modules/queue/info.html @@ -0,0 +1 @@ +info \ No newline at end of file diff --git a/apps/Core/Views/Default/html/modules/logs.html b/apps/Core/Views/Default/html/modules/queue/logs.html similarity index 100% rename from apps/Core/Views/Default/html/modules/logs.html rename to apps/Core/Views/Default/html/modules/queue/logs.html diff --git a/apps/Core/Views/Default/html/modules/settings.html b/apps/Core/Views/Default/html/modules/queue/settings.html similarity index 100% rename from apps/Core/Views/Default/html/modules/settings.html rename to apps/Core/Views/Default/html/modules/queue/settings.html diff --git a/apps/Core/Views/Default/html/modules/view.html b/apps/Core/Views/Default/html/modules/view.html index 0b0c0a8a2..3f105c463 100644 --- a/apps/Core/Views/Default/html/modules/view.html +++ b/apps/Core/Views/Default/html/modules/view.html @@ -78,10 +78,10 @@ 'cardFooter' : true, 'cardType' : 'primary', 'cardIcon' : 'th', - 'cardTitle' : 'Analyse Modules', + 'cardTitle' : 'Analyse Queue Modules', 'cardAdditionalClass' : 'rounded-0', 'cardCollapsed' : false, - 'cardBodyInclude' : 'modules/analyse', + 'cardBodyInclude' : 'modules/queue/analyse', 'cardShowTools' : ['maximize'], 'cardFooterContent' : footerContent ] From cbd6db077f8743f6465438970ac426270e58832c Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Sat, 8 Feb 2025 04:24:14 +1100 Subject: [PATCH 36/54] update issue #34. Add queue info and progress information to logs. --- .../Default/html/modules/queue/analyse.html | 105 ++++++++++++------ .../Default/html/modules/queue/info.html | 1 - .../Packages/Progress.php | 5 + .../ModulesServiceProvider/Installer.php | 97 ++++++++++++++-- .../ModulesServiceProvider/Manager.php | 2 + .../ModulesServiceProvider/Queues.php | 13 +++ 6 files changed, 181 insertions(+), 42 deletions(-) delete mode 100644 apps/Core/Views/Default/html/modules/queue/info.html diff --git a/apps/Core/Views/Default/html/modules/queue/analyse.html b/apps/Core/Views/Default/html/modules/queue/analyse.html index 56269cac0..932f1688c 100644 --- a/apps/Core/Views/Default/html/modules/queue/analyse.html +++ b/apps/Core/Views/Default/html/modules/queue/analyse.html @@ -15,7 +15,37 @@ {% if queue['tasks_count']['remove'] is defined %} {% set queueTasksCounterRemove = queue['tasks_count']['remove'] %} {% endif %} +{% set queueStatus = 'Analysis Complete' %} +{% if queue['status'] == '1' %} + {% set queueStatus = 'Precheck Complete' %} +{% elseif queue['status'] == '2' %} + {% set queueStatus = 'Process Complete' %} +{% endif %} +{% set queuePrecheckedAt = '-' %} +{% set queuePrecheckedBy = '-' %} +{% set queueProcessedAt = '-' %} +{% set queueProcessedBy = '-' %} +{% if queue['prechecked_at'] is defined %} + {% set queuePrecheckedAt = queue['prechecked_at'] %} +{% endif %} +{% if queue['prechecked_by'] is defined %} + {% set queuePrecheckedBy = queue['prechecked_by'] %} +{% endif %} +{% if queue['processed_at'] is defined %} + {% set queueProcessedAt = queue['processed_at'] %} +{% endif %} +{% if queue['processed_by'] is defined %} + {% set queueProcessedBy = queue['processed_by'] %} +{% endif %}
+
+ + {{queue['id']}} +
+
+ + {{queueStatus}} +
{{adminltetags.useTag('buttons', [ @@ -27,13 +57,6 @@ 'buttonType' : 'button', 'buttons' : [ - 'queue-info' : [ - 'title' : 'Queue Info', - 'size' : 'xs', - 'type' : 'primary', - 'position' : 'left', - 'icon' : 'info' - ], 'queue-settings' : [ 'title' : 'Queue Settings', 'size' : 'xs', @@ -47,6 +70,25 @@

+
+
+ + {{queuePrecheckedAt}} +
+
+ + {{queuePrecheckedBy}} +
+
+ + {{queueProcessedAt}} +
+
+ + {{queueProcessedBy}} +
+
+
{{adminltetags.useTag('fields', @@ -94,7 +136,7 @@ )}}
-
+
{% set moduleHtml = '' %} {% set hasAnalysisError = 'false' %} {% if queue['tasks']['analysed']|length > 0 %} @@ -315,6 +357,17 @@ $('#{{componentId}}-{{sectionId}}-perform-precheck').children('i').attr('hidden', true); $('#{{componentId}}-{{sectionId}}-process-queue').attr('disabled', false); $('#{{componentId}}-{{sectionId}}-process-queue').attr('hidden', false); + if (response.responseData.queue) { + if (response.responseData.queue.prechecked_at) { + $('#prechecked_at').html(response.responseData.queue.prechecked_at); + } + if (response.responseData.queue.prechecked_by) { + $('#prechecked_by').html(response.responseData.queue.prechecked_by); + } + if (response.responseData.queue.status == 1) { + $('#status').html('Precheck Complete'); + } + } } else if (postData['process'] === 'runprocess') { $('#{{componentId}}-{{sectionId}}-re-analyse').attr('hidden', true); $('#{{componentId}}-{{sectionId}}-perform-precheck').attr('hidden', true); @@ -322,6 +375,17 @@ $('#{{componentId}}-{{sectionId}}-process-queue').children('i').attr('hidden', true); $('#{{componentId}}-{{sectionId}}-cancel').attr('hidden', true); $('#{{componentId}}-{{sectionId}}-close').attr('hidden', false); + if (response.responseData.queue) { + if (response.responseData.queue.processed_at) { + $('#processed_at').html(response.responseData.queue.processed_at); + } + if (response.responseData.queue.processed_by) { + $('#processed_by').html(response.responseData.queue.processed_by); + } + if (response.responseData.queue.status == 2) { + $('#status').html('Process Complete'); + } + } if (response.responseData && response.responseData.emailReport && response.responseData.emailReport == true) { notifyText += '. An email report was successfully sent to : ' + $('#{{componentId}}-{{sectionId}}-email_report').val().trim(); @@ -449,13 +513,6 @@ }); }); - $('#{{componentId}}-{{sectionId}}-queue-info').off(); - $('#{{componentId}}-{{sectionId}}-queue-info').click(function(e) { - e.preventDefault(); - - $('#{{componentId}}-{{sectionId}}-queue-info-modal').modal('show'); - }); - $('.viewLogs').off(); $('.viewLogs').click(function(e) { e.preventDefault(); @@ -617,24 +674,6 @@ dataCollectionSectionForm['funcs']['init'](); }); -
- {{adminltetags.useTag('modal', - [ - 'component' : component, - 'componentName' : componentName, - 'componentId' : componentId, - 'sectionId' : sectionId, - 'modalId' : 'queue-info-modal', - 'modalBodyInclude' : 'modules/queue/info', - 'modalSize' : 'xl', - 'modalHeader' : true, - 'modalFooter' : true, - 'modalHeaderCloseButton' : true, - 'modalEscClose' : true, - 'modalTitle' : ' INFO' - ] - )}} -
{{adminltetags.useTag('modal', [ diff --git a/apps/Core/Views/Default/html/modules/queue/info.html b/apps/Core/Views/Default/html/modules/queue/info.html deleted file mode 100644 index 06e554768..000000000 --- a/apps/Core/Views/Default/html/modules/queue/info.html +++ /dev/null @@ -1 +0,0 @@ -info \ No newline at end of file diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php index 89fc29f93..ba2c8dda4 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php @@ -51,6 +51,11 @@ public function checkProgressFile($fileName = null) return false; } + public function getProgressFile() + { + return $this->readProgressFile(); + } + public function registerMethods(array $methods) { foreach ($methods as $key => $method) { diff --git a/system/Base/Providers/ModulesServiceProvider/Installer.php b/system/Base/Providers/ModulesServiceProvider/Installer.php index 970c3f3c9..8de746d1f 100644 --- a/system/Base/Providers/ModulesServiceProvider/Installer.php +++ b/system/Base/Providers/ModulesServiceProvider/Installer.php @@ -139,6 +139,10 @@ public function runProcess(array $data) foreach ($this->runPrecheckProgressMethods as $method) { if ($this->withProgress($method['method'], $method['args'] ?? []) === false) { + if ($this->basepackages->progress->checkProgressFile()) { + $this->addProgressToResult(true); + } + $this->modules->queues->update($this->queue); return false; @@ -146,15 +150,31 @@ public function runProcess(array $data) } $this->queue['status'] = 1; + $this->queue['prechecked_at'] = date('c'); + $this->queue['prechecked_by'] = '-'; + + if ($this->access->auth->account() && isset($this->access->auth->account()['id'])) { + $this->queue['prechecked_by'] = $this->access->auth->account()['id']; + } + + if ($this->basepackages->progress->checkProgressFile()) { + $this->addProgressToResult(); + } $this->modules->queues->update($this->queue); + $this->queue['prechecked_by'] = $this->access->auth->account()['email']; + $this->addResponse('Precheck complete', 0, ['queue' => $this->queue]); } else if ($this->process === 'runprocess') { $this->basepackages->progress->preCheckComplete(); foreach ($this->runProcessProgressMethods as $method) { if ($this->withProgress($method['method'], $method['args'] ?? []) === false) { + if ($this->basepackages->progress->checkProgressFile()) { + $this->addProgressToResult(true); + } + $this->modules->queues->update($this->queue); return false; @@ -162,6 +182,16 @@ public function runProcess(array $data) } $this->queue['status'] = 2; + $this->queue['processed_at'] = date('c'); + $this->queue['processed_by'] = '-'; + + if ($this->access->auth->account() && isset($this->access->auth->account()['id'])) { + $this->queue['processed_by'] = $this->access->auth->account()['id']; + } + + if ($this->basepackages->progress->checkProgressFile()) { + $this->addProgressToResult(); + } $this->modules->queues->update($this->queue); @@ -170,10 +200,55 @@ public function runProcess(array $data) $emailReport = $this->emailReport(); } + $this->queue['processed_by'] = $this->access->auth->account()['email']; + $this->addResponse('Process complete', 0, ['queue' => $this->queue, 'emailReport' => $emailReport]); } } + protected function addProgressToResult($failed = false) + { + $progressFile = $this->basepackages->progress->getProgressFile(); + + if (!$progressFile || + ($progressFile && !isset($progressFile['allProcesses'])) + ) { + return; + } + + if ($this->process === 'runprecheck') { + foreach ($progressFile['allProcesses'] as $key => $progress) { + if ($failed && !isset($progress['callResult'])) { + return; + } + if (!isset($this->queue['results'][$progress['args'][0]][$progress['args'][1]['module_type']][$progress['args'][1]['id']])) { + continue; + } + + $progressResultResult = &$this->queue['results'][$progress['args'][0]][$progress['args'][1]['module_type']][$progress['args'][1]['id']]; + + $progressResultResult['precheck_progress_logs'][$key]['progressTask'] = $progress['text']; + $progressResultResult['precheck_progress_logs'][$key]['progressResult'] = $progress['callResult'] == true ? 'Pass' : 'Fail'; + $progressResultResult['precheck_progress_logs'][$key]['progressExecTime'] = $progress['callExecTime']; + } + } else if ($this->process === 'runprocess') { + foreach ($progressFile['allProcesses'] as $key => $progress) { + if ($failed && !isset($progress['callResult'])) { + return; + } + if (!isset($this->queue['results'][$progress['args'][0]][$progress['args'][1]['module_type']][$progress['args'][1]['id']])) { + continue; + } + + $progressResultResult = &$this->queue['results'][$progress['args'][0]][$progress['args'][1]['module_type']][$progress['args'][1]['id']]; + + $progressResultResult['process_progress_logs'][$key]['progressTask'] = $progress['text']; + $progressResultResult['process_progress_logs'][$key]['progressResult'] = $progress['callResult'] == true ? 'Pass' : 'Fail'; + $progressResultResult['process_progress_logs'][$key]['progressExecTime'] = $progress['callExecTime']; + } + } + } + protected function precheckQueueData($args) { $taskName = $args[0]; @@ -1348,7 +1423,8 @@ protected function addProgressMethods(&$methods, $module, $taskName, $forTask, $ array_push($methods, [ 'method' => 'extractModulesDownloadedFromRepo-' . $module['id'] . '-' . strtolower(str_replace(' ', '', $module['name'])), - 'text' => 'Extracting downloaded module ' . $module['name'] . ' (' . ucfirst($module['module_type']) . ')...' + 'text' => 'Extracting downloaded module ' . $module['name'] . ' (' . ucfirst($module['module_type']) . ')...', + 'args' => [$taskName, $module] ] ); } else { @@ -1359,13 +1435,15 @@ protected function addProgressMethods(&$methods, $module, $taskName, $forTask, $ 'args' => [$taskName, $module, $precheck], ] ); - array_push($methods, - [ - 'method' => 'runModuleInstallScripts-' . $module['id'] . '-' . strtolower(str_replace(' ', '', $module['name'])), - 'text' => 'Running module install scripts for ' . $module['name'] . ' (' . ucfirst($module['module_type']) . ')...', - 'args' => [$taskName, $module], - ] - ); + if ($module['module_type'] !== 'views') { + array_push($methods, + [ + 'method' => 'runModuleInstallScripts-' . $module['id'] . '-' . strtolower(str_replace(' ', '', $module['name'])), + 'text' => 'Running module install scripts for ' . $module['name'] . ' (' . ucfirst($module['module_type']) . ')...', + 'args' => [$taskName, $module], + ] + ); + } array_push($methods, [ 'method' => 'deleteSourceFiles-' . $module['id'] . '-' . strtolower(str_replace(' ', '', $module['name'])), @@ -1373,6 +1451,9 @@ protected function addProgressMethods(&$methods, $module, $taskName, $forTask, $ 'args' => [$taskName, $module], ] ); + if (is_string($module['id']) && str_contains($module['id'], '-public')) { + return; + } array_push($methods, [ 'method' => 'updateVersion-' . $module['id'] . '-' . strtolower(str_replace(' ', '', $module['name'])), diff --git a/system/Base/Providers/ModulesServiceProvider/Manager.php b/system/Base/Providers/ModulesServiceProvider/Manager.php index 71b974ee2..6db0162cb 100644 --- a/system/Base/Providers/ModulesServiceProvider/Manager.php +++ b/system/Base/Providers/ModulesServiceProvider/Manager.php @@ -704,6 +704,8 @@ protected function getRemoteModuleJson($moduleType, $module, $onlyJson = false) } $jsonFileName = substr($moduleType, 0, -1) . '.json'; + } else if ($moduleType === 'packages' && $module['name'] === 'Core') { + $jsonFileName = 'system/Base/Installer/Packages/Setup/Register/Modules/Packages/Providers/Core/package.json'; } else { $jsonFileName = 'Install/' . substr($moduleType, 0, -1) . '.json'; } diff --git a/system/Base/Providers/ModulesServiceProvider/Queues.php b/system/Base/Providers/ModulesServiceProvider/Queues.php index b54c45ea7..b1b4d3ab1 100644 --- a/system/Base/Providers/ModulesServiceProvider/Queues.php +++ b/system/Base/Providers/ModulesServiceProvider/Queues.php @@ -36,6 +36,19 @@ public function getActiveQueue() $queue = $queue->toArray(); + if (isset($queue['prechecked_by']) && $queue['prechecked_by'] !== 0) { + $account = $this->basepackages->accounts->getAccountById($queue['prechecked_by']); + if ($account) { + $queue['prechecked_by'] = $account['email']; + } + } + if (isset($queue['processed_by']) && $queue['processed_by'] !== 0) { + $account = $this->basepackages->accounts->getAccountById($queue['processed_by']); + if ($account) { + $queue['processed_by'] = $account['email']; + } + } + return $queue; } From f7a450ad5588081428d403dfae2b4e4aa56851f4 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Sun, 9 Feb 2025 01:46:29 +1100 Subject: [PATCH 37/54] update #34. Added apptypes to installation. Fixed bugs. --- .../Devtools/Modules/DevtoolsModules.php | 4 +- .../Views/Default/html/modules/modules.html | 123 ++++++++---- system/Base/Helpers.php | 16 ++ .../ApiClientServices/Apis/Repos.php | 2 +- .../Packages/Dashboards.php | 4 + .../DatabaseServiceProvider/Ff/Store.php | 9 +- .../ModulesServiceProvider/Installer.php | 186 ++++++++++++------ .../ModulesServiceProvider/Manager.php | 34 ++-- .../ModulesServiceProvider/Queues.php | 112 ++++++----- 9 files changed, 322 insertions(+), 168 deletions(-) diff --git a/apps/Core/Packages/Devtools/Modules/DevtoolsModules.php b/apps/Core/Packages/Devtools/Modules/DevtoolsModules.php index 70ec5c2aa..e1e034424 100644 --- a/apps/Core/Packages/Devtools/Modules/DevtoolsModules.php +++ b/apps/Core/Packages/Devtools/Modules/DevtoolsModules.php @@ -539,7 +539,7 @@ protected function checkAppType($data) $this->addUpdateAppTypeFiles($data); } - if (strtolower($appType['app_type']) !== 'core' && + if (strtolower($data['app_type']) !== 'core' && $data['createrepo'] == true ) { if (!$this->checkRepo($data)) { @@ -3101,7 +3101,7 @@ public function generateModuleRepoUrl($data) } } - $this->addResponse('Generated Repo Url', 0, ['repo' => $url]); + $this->addResponse('Generated Repo Url', 0, ['repo' => strtolower($url)]); return true; } diff --git a/apps/Core/Views/Default/html/modules/modules.html b/apps/Core/Views/Default/html/modules/modules.html index 0c85c66a9..bf6a2fc3d 100644 --- a/apps/Core/Views/Default/html/modules/modules.html +++ b/apps/Core/Views/Default/html/modules/modules.html @@ -476,7 +476,6 @@
Select module from the tre if ($(this)[0].id === '{{componentId}}-{{sectionId}}-modules-repo-sync') { dataCollectionSectionForm['funcs']['toggleJstreeTool']($(this)[0].id); - dataCollectionSectionForm['funcs']['initSync']( $('#{{componentId}}-{{sectionId}}-modules').jstree().get_selected(true)[0].data.apiid ); @@ -689,12 +688,18 @@
Select module from the tre if (selected[0].id.startsWith('j')) { if (selected[0].data.type !== 'repo') { - $('#{{componentId}}-{{sectionId}}-modules').jstree().deselect_node(selected); + if (selected[0].data.type === 'apptype') { + dataCollectionSectionForm['funcs']['toggleJstreeTool']('{{componentId}}-{{sectionId}}-modules-repo-sync'); + dataCollectionSectionForm['funcs']['moduleinfo'](['loader']); + dataCollectionSectionForm['funcs']['getSelectedModuleInfo'](selected[0].data.id, true); + } else { + $('#{{componentId}}-{{sectionId}}-modules').jstree().deselect_node(selected); - dataCollectionSectionForm['funcs']['toggleJstreeTool']('{{componentId}}-{{sectionId}}-modules-repo-update'); - dataCollectionSectionForm['funcs']['toggleJstreeTool']('{{componentId}}-{{sectionId}}-modules-repo-sync'); - dataCollectionSectionForm['funcs']['moduleinfo'](['noinfo']); - return false; + dataCollectionSectionForm['funcs']['toggleJstreeTool']('{{componentId}}-{{sectionId}}-modules-repo-update'); + dataCollectionSectionForm['funcs']['toggleJstreeTool']('{{componentId}}-{{sectionId}}-modules-repo-sync'); + dataCollectionSectionForm['funcs']['moduleinfo'](['noinfo']); + return false; + } } else if (selected[0].data.type === 'repo') { dataCollectionSectionForm['funcs']['toggleJstreeTool']('{{componentId}}-{{sectionId}}-modules-repo-add', 'success', false); dataCollectionSectionForm['funcs']['toggleJstreeTool']('{{componentId}}-{{sectionId}}-modules-repo-update', 'warning', false); @@ -702,9 +707,8 @@
Select module from the tre 'href', '{{links.url("system/api/client/services/q/id/' + selected[0].data.apiid + '")}}' ); dataCollectionSectionForm['funcs']['toggleJstreeTool']('{{componentId}}-{{sectionId}}-modules-repo-sync', 'primary', false); + dataCollectionSectionForm['funcs']['moduleinfo'](); } - - dataCollectionSectionForm['funcs']['moduleinfo'](); } else { if (selected[0].data.type !== 'repo') { dataCollectionSectionForm['funcs']['toggleJstreeTool']('{{componentId}}-{{sectionId}}-modules-repo-update'); @@ -791,28 +795,33 @@
Select module from the tre } } -dataCollectionSectionForm['funcs']['getSelectedModuleInfo'] = function(selected) { +dataCollectionSectionForm['funcs']['getSelectedModuleInfo'] = function(selected, apptype = false) { if (!selected) { return false; } var splitModule, moduleType, moduleId; - splitModule = selected.split('-'); - moduleId = splitModule[1]; - - if (selected.startsWith('components')) { - moduleType = 'components'; - } else if (selected.startsWith('packages')) { - moduleType = 'packages'; - } else if (selected.startsWith('middlewares')) { - moduleType = 'middlewares'; - } else if (selected.startsWith('views')) { - moduleType = 'views'; - } else if (selected.startsWith('bundles')) { - moduleType = 'bundles'; - } else if (selected.startsWith('external')) { - moduleType = 'externals'; + if (apptype) { + moduleType = 'apptype'; + moduleId = selected; + } else { + splitModule = selected.split('-'); + moduleId = splitModule[1]; + + if (selected.startsWith('components')) { + moduleType = 'components'; + } else if (selected.startsWith('packages')) { + moduleType = 'packages'; + } else if (selected.startsWith('middlewares')) { + moduleType = 'middlewares'; + } else if (selected.startsWith('views')) { + moduleType = 'views'; + } else if (selected.startsWith('bundles')) { + moduleType = 'bundles'; + } else if (selected.startsWith('external')) { + moduleType = 'externals'; + } } if (moduleType && moduleId) { @@ -824,7 +833,7 @@
Select module from the tre return false; } -dataCollectionSectionForm['funcs']['getModuleInfo'] = function(moduleType, moduleId, sync = false) { +dataCollectionSectionForm['funcs']['getModuleInfo'] = function(moduleType, moduleId = null, sync = false) { var postData = { }; postData[$('#security-token').attr('name')] = $('#security-token').val(); postData['module_type'] = moduleType; @@ -849,7 +858,9 @@
Select module from the tre if (response.responseData.module) { dataCollectionSectionForm['vars']['module'] = response.responseData.module; - + if (moduleType === 'apptype') { + dataCollectionSectionForm['vars']['module']['module_type'] = 'apptype'; + } dataCollectionSectionForm['funcs']['processModuleInfo'](response.responseData.module); } } else if (response.responseCode == 1) { @@ -914,7 +925,11 @@
Select module from the tre $('#installed').html(moduleData.installed); $('#version').html(moduleData.version); $('#updated_by').html(moduleData.updated_by); - $('#module_type').html(moduleData.module_type); + if (moduleData.module_type) { + $('#module_type').html(moduleData.module_type); + } else { + $('#module_type').html('-'); + } if (moduleData.display_name) { $('#display_name').html(moduleData.display_name); } else { @@ -1175,9 +1190,13 @@
Select module from the tre dataCollectionSectionForm['funcs']['moduleinfo'](['loader', 'buttons'], ['repo-sync']); + var moduleId = dataCollectionSectionForm['vars']['module']['id']; + if (dataCollectionSectionForm['vars']['module']['module_type'] === 'apptype') { + moduleId = dataCollectionSectionForm['vars']['module']['app_type']; + } dataCollectionSectionForm['funcs']['getModuleInfo']( dataCollectionSectionForm['vars']['module']['module_type'], - dataCollectionSectionForm['vars']['module']['id'], + moduleId, true ); }); @@ -1216,29 +1235,47 @@
Select module from the tre if (task === 'install') { dataCollectionSectionForm['funcs']['moduleinfo'](['info', 'buttons'], ['cancel', 'repo-sync']); - dataCollectionSectionForm['funcs']['toggleJstreeTool']('{{componentId}}-{{sectionId}}-modules-filter-install', 'primary', false); - dataCollectionSectionForm['funcs']['toggleJstreeTool']('{{componentId}}-{{sectionId}}-modules-filter-queue', 'purple', false); - dataCollectionSectionForm['funcs']['applyColorsToTreeIconsAndUpdateText'](moduleType + '-' + id, true); + if (moduleType === 'apptype') { + dataCollectionSectionForm['funcs']['initQueueButtons'](); + } else { + dataCollectionSectionForm['funcs']['toggleJstreeTool']('{{componentId}}-{{sectionId}}-modules-filter-install', 'primary', false); + dataCollectionSectionForm['funcs']['toggleJstreeTool']('{{componentId}}-{{sectionId}}-modules-filter-queue', 'purple', false); + dataCollectionSectionForm['funcs']['applyColorsToTreeIconsAndUpdateText'](moduleType + '-' + id, true); + } } else if (task === 'update') { dataCollectionSectionForm['funcs']['moduleinfo'](['info', 'buttons'], ['cancel', 'repo-sync']); - dataCollectionSectionForm['funcs']['toggleJstreeTool']('{{componentId}}-{{sectionId}}-modules-filter-update', 'info', false); - dataCollectionSectionForm['funcs']['toggleJstreeTool']('{{componentId}}-{{sectionId}}-modules-filter-queue', 'purple', false); - dataCollectionSectionForm['funcs']['applyColorsToTreeIconsAndUpdateText'](moduleType + '-' + id); + if (moduleType === 'apptype') { + dataCollectionSectionForm['funcs']['initQueueButtons'](); + } else { + dataCollectionSectionForm['funcs']['toggleJstreeTool']('{{componentId}}-{{sectionId}}-modules-filter-update', 'info', false); + dataCollectionSectionForm['funcs']['toggleJstreeTool']('{{componentId}}-{{sectionId}}-modules-filter-queue', 'purple', false); + dataCollectionSectionForm['funcs']['applyColorsToTreeIconsAndUpdateText'](moduleType + '-' + id); + } } else if (task === 'uninstall') { dataCollectionSectionForm['funcs']['moduleinfo'](['info', 'buttons'], ['cancel', 'repo-sync']); - dataCollectionSectionForm['funcs']['toggleJstreeTool']('{{componentId}}-{{sectionId}}-modules-filter-uninstall', 'warning', false); - dataCollectionSectionForm['funcs']['toggleJstreeTool']('{{componentId}}-{{sectionId}}-modules-filter-queue', 'purple', false); - dataCollectionSectionForm['funcs']['applyColorsToTreeIconsAndUpdateText'](moduleType + '-' + id, false, true); + if (moduleType === 'apptype') { + dataCollectionSectionForm['funcs']['initQueueButtons'](); + } else { + dataCollectionSectionForm['funcs']['toggleJstreeTool']('{{componentId}}-{{sectionId}}-modules-filter-uninstall', 'warning', false); + dataCollectionSectionForm['funcs']['toggleJstreeTool']('{{componentId}}-{{sectionId}}-modules-filter-queue', 'purple', false); + dataCollectionSectionForm['funcs']['applyColorsToTreeIconsAndUpdateText'](moduleType + '-' + id, false, true); + } } else if (task === 'remove') { dataCollectionSectionForm['funcs']['moduleinfo'](['info', 'buttons'], ['cancel']); - dataCollectionSectionForm['funcs']['toggleJstreeTool']('{{componentId}}-{{sectionId}}-modules-filter-remove', 'danger', false); - dataCollectionSectionForm['funcs']['toggleJstreeTool']('{{componentId}}-{{sectionId}}-modules-filter-queue', 'purple', false); - dataCollectionSectionForm['funcs']['applyColorsToTreeIconsAndUpdateText'](moduleType + '-' + id, false, false, true); + if (moduleType === 'apptype') { + dataCollectionSectionForm['funcs']['initQueueButtons'](); + } else { + dataCollectionSectionForm['funcs']['toggleJstreeTool']('{{componentId}}-{{sectionId}}-modules-filter-remove', 'danger', false); + dataCollectionSectionForm['funcs']['toggleJstreeTool']('{{componentId}}-{{sectionId}}-modules-filter-queue', 'purple', false); + dataCollectionSectionForm['funcs']['applyColorsToTreeIconsAndUpdateText'](moduleType + '-' + id, false, false, true); + } } else if (task === 'cancel') { dataCollectionSectionForm['funcs']['processModuleInfo'](dataCollectionSectionForm['vars']['module']); for (var queueTask in dataCollectionSectionForm['vars']['queue']['tasks']) { - if (dataCollectionSectionForm['vars']['queue']['tasks'][queueTask].length === 0) { + if (!dataCollectionSectionForm['vars']['queue']['tasks'][queueTask] || + (dataCollectionSectionForm['vars']['queue']['tasks'][queueTask] && dataCollectionSectionForm['vars']['queue']['tasks'][queueTask].length === 0) + ) { dataCollectionSectionForm['funcs']['toggleJstreeTool']('{{componentId}}-{{sectionId}}-modules-filter-' + queueTask); } } @@ -1246,6 +1283,10 @@
Select module from the tre dataCollectionSectionForm['funcs']['applyColorsToTreeIconsAndUpdateText']( dataCollectionSectionForm['vars']['module']['module_type'] + '-' + dataCollectionSectionForm['vars']['module']['id'] ); + + if (dataCollectionSectionForm['vars']['queue']['total'] === 0) { + dataCollectionSectionForm['funcs']['initQueueButtons'](false); + } } else if (task === 'clearQueue') { dataCollectionSectionForm['funcs']['clearQueue'](); } diff --git a/system/Base/Helpers.php b/system/Base/Helpers.php index 9bced6cf1..a52c777a8 100644 --- a/system/Base/Helpers.php +++ b/system/Base/Helpers.php @@ -566,4 +566,20 @@ function printArrayList($array) { return $html; } +} + +if (!function_exists('arrayReplace')) { + function arrayReplace($array, $findKey, $replace) { + if (is_array($array)) { + foreach ($array as $key=>$val) { + if ($key === $findKey) { + $array[$key] = $replace; + } else if (is_array($array[$key])) { + $array[$key] = arrayReplace($array[$key], $findKey, $replace); + } + } + } + + return $array; + } } \ No newline at end of file diff --git a/system/Base/Installer/Packages/Setup/Register/Basepackages/ApiClientServices/Apis/Repos.php b/system/Base/Installer/Packages/Setup/Register/Basepackages/ApiClientServices/Apis/Repos.php index 99895c584..8ab1450e2 100644 --- a/system/Base/Installer/Packages/Setup/Register/Basepackages/ApiClientServices/Apis/Repos.php +++ b/system/Base/Installer/Packages/Setup/Register/Basepackages/ApiClientServices/Apis/Repos.php @@ -37,7 +37,7 @@ public function register($db, $ff, $postData) [ 'api_url' => 'https://api.github.com', 'org_user' => 'sp-modules', - 'repo_url' => 'https://github.com/sp-modules/', + 'repo_url' => 'https://github.com/sp-modules', 'branch' => 'main', 'auth_type' => 'autho', 'authorization' => '' diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Dashboards.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Dashboards.php index 74e7a6911..ce3580b88 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Dashboards.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Dashboards.php @@ -87,6 +87,8 @@ public function addDashboard(array $data) if ($this->access->auth->account()) { $data['user_default'] = [$this->access->auth->account()['id']]; } + } else { + $data['user_default'] = []; } $data = $this->getSharedIds($data); @@ -160,6 +162,8 @@ protected function getSharedIds($data) } catch (\throwable $e) { $data['shared'] = null; } + } else { + $data['shared'] = null; } return $data; diff --git a/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php b/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php index a5eeaf694..0600e3c23 100644 --- a/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php +++ b/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php @@ -1568,12 +1568,17 @@ protected function normalizeData(array $data, $jsonToArray = false): array continue; } - if ($type === 'boolean' || $type === 'integer') { + if ($type === 'integer') { if (is_string($data[$propertyKey])) { $data[$propertyKey] = (int) $data[$propertyKey]; } + } - if (is_int($data[$propertyKey]) && $type === 'boolean') { + if ($type === 'boolean') { + if (is_string($data[$propertyKey])) { + $data[$propertyKey] = $data[$propertyKey] === 'false' ? false : true; + } + if (is_int($data[$propertyKey])) { $data[$propertyKey] = $data[$propertyKey] === 0 ? false : true; } } diff --git a/system/Base/Providers/ModulesServiceProvider/Installer.php b/system/Base/Providers/ModulesServiceProvider/Installer.php index 8de746d1f..6d60eb03e 100644 --- a/system/Base/Providers/ModulesServiceProvider/Installer.php +++ b/system/Base/Providers/ModulesServiceProvider/Installer.php @@ -137,6 +137,9 @@ public function runProcess(array $data) if ($this->process === 'runprecheck') { $this->basepackages->progress->preCheckComplete(); + $this->queue['results'] = arrayReplace($this->queue['results'], 'precheck_progress_logs', []); + $this->modules->queues->update($this->queue); + foreach ($this->runPrecheckProgressMethods as $method) { if ($this->withProgress($method['method'], $method['args'] ?? []) === false) { if ($this->basepackages->progress->checkProgressFile()) { @@ -169,6 +172,9 @@ public function runProcess(array $data) } else if ($this->process === 'runprocess') { $this->basepackages->progress->preCheckComplete(); + $this->queue['results'] = arrayReplace($this->queue['results'], 'progress_progress_logs', []); + $this->modules->queues->update($this->queue); + foreach ($this->runProcessProgressMethods as $method) { if ($this->withProgress($method['method'], $method['args'] ?? []) === false) { if ($this->basepackages->progress->checkProgressFile()) { @@ -218,9 +224,17 @@ protected function addProgressToResult($failed = false) if ($this->process === 'runprecheck') { foreach ($progressFile['allProcesses'] as $key => $progress) { - if ($failed && !isset($progress['callResult'])) { + if ($failed && + (!isset($progress['callResult']) || + isset($progress['callResult']) && $progress['callResult'] === false) + ) { return; } + + if (!isset($progress['args'])) { + continue; + } + if (!isset($this->queue['results'][$progress['args'][0]][$progress['args'][1]['module_type']][$progress['args'][1]['id']])) { continue; } @@ -233,9 +247,17 @@ protected function addProgressToResult($failed = false) } } else if ($this->process === 'runprocess') { foreach ($progressFile['allProcesses'] as $key => $progress) { - if ($failed && !isset($progress['callResult'])) { + if ($failed && + (!isset($progress['callResult']) || + isset($progress['callResult']) && $progress['callResult'] === false) + ) { return; } + + if (!isset($progress['args'])) { + continue; + } + if (!isset($this->queue['results'][$progress['args'][0]][$progress['args'][1]['module_type']][$progress['args'][1]['id']])) { continue; } @@ -291,7 +313,8 @@ protected function precheckQueueData($args) return $this->queueHasErrors( $this->modules->manager->packagesData->responseMessage ?? 'Could not retrieve repository information for module: ' . $module['name'], - $preCheckQueueLogs + $preCheckQueueLogs, + true ); } else { $this->queue['results'][$taskName][$module['module_type']][$module['id']]['precheck'] = 'fail'; @@ -300,7 +323,8 @@ protected function precheckQueueData($args) return $this->queueHasErrors( $this->modules->manager->packagesData->responseMessage ?? 'Could not retrieve repository information for module: ' . $module['name'], - $preCheckQueueLogs + $preCheckQueueLogs, + true ); } @@ -901,12 +925,56 @@ protected function runRsync($args) ); $this->zipFile['name'] = $this->modulesToInstallOrUpdate['repo_details']['details']['name'] . '-' . - $this->modulesToInstallOrUpdate['repo_details']['latestRelease']['name']; + ($this->modulesToInstallOrUpdate['repo_details']['latestRelease']['name'] !== '' ? $this->modulesToInstallOrUpdate['repo_details']['latestRelease']['name'] : $this->modulesToInstallOrUpdate['repo_details']['latestRelease']['tag_name']); try { + if ($module['module_type'] === 'packages' && + $module['name'] === 'Core' + ) { + $destDir = ''; + } else { + $name = $this->helper->last(explode('-', strtolower($this->helper->last(explode('/', $module['repo']))))); + + $destDir = 'apps/' . ucfirst($module['app_type']) . '/' . ucfirst($module['module_type']) . '/' . ucfirst($name) . '/'; + + if ($module['module_type'] === 'apptype') { + $destDir = 'apps/' . ucfirst($module['name']) . '/'; + } + + if ($module['module_type'] === 'views') { + //for view check if the main view is installed before adding to queue. + if (isset($module['is_public']) && + $module['is_public'] == true + ) { + $destDir = 'public/' . strtolower($module['app_type']) . '/' . strtolower($module['name']) . '/'; + + $this->zipFile['name'] = $this->modulesToInstallOrUpdate['repo_details']['details']['name'] . + '-public-' . + $this->modulesToInstallOrUpdate['repo_details']['latestRelease']['name']; + + } else if (isset($module['is_subview']) && + $module['is_subview'] == true + ) { + $destDir = 'apps/' . ucfirst($module['app_type']) . '/' . ucfirst($module['module_type']) . '/' . ucfirst($module['base_view_name']) . '/html/' . strtolower($module['name']) . '/'; + } + } + + if (!$precheck) { + try { + if (!$this->localContent->directoryExists($destDir)) { + $this->localContent->createDirectory($destDir); + } + } catch (FilesystemException | UnableToCheckExistence | UnableToCreateDirectory | \throwable $e) { + throw $e; + } + } + } + + $srcDir = 'var/tmp/installer/' . $this->zipFile['name'] . '/' . $this->zipFile['name']; + $rsyncSettings = [ - Rsync::CONF_CWD => base_path('var/tmp/installer/' . $this->zipFile['name'] . '/' . $this->zipFile['name']), + Rsync::CONF_CWD => base_path($srcDir), Rsync::CONF_OPTIONS => [ Rsync::OPT_DRY_RUN => $precheck, @@ -925,33 +993,7 @@ protected function runRsync($args) $rsync = new Rsync($rsyncSettings); - if ($module['module_type'] === 'packages' && - $module['name'] === 'Core' - ) { - $rsync->sync( - '.', - base_path('') - ); - } else { - if (!$precheck) { - try { - if (!$this->localContent->directoryExists( - 'apps/' . ucfirst($module['app_type']) . '/' . ucfirst($module['module_type']) . '/' . ucfirst($module['name']) . '/' - )) { - $this->localContent->createDirectory( - 'apps/' . ucfirst($module['app_type']) . '/' . ucfirst($module['module_type']) . '/' . ucfirst($module['name']) . '/' - ); - } - } catch (FilesystemException | UnableToCheckExistence | UnableToCreateDirectory | \throwable $e) { - throw $e; - } - } - - $rsync->sync( - '.', - base_path('apps/' . ucfirst($module['app_type']) . '/' . ucfirst($module['module_type']) . '/' . ucfirst($module['name']) . '/') - ); - } + $rsync->sync('.', base_path($destDir)); if ($rsync->getExitCode() == 0) { $outputArr = explode(PHP_EOL, $rsync->getStdout()); @@ -1147,8 +1189,12 @@ protected function updateVersion($args) } try { - $moduleMethod = 'get' . ucfirst(substr($module['module_type'], 0, -1)) . 'ById'; - $moduleArr = $this->modules->{$module['module_type']}->$moduleMethod($module['id']); + if (str_contains($module['module_type'], 'apptype')) { + $moduleArr = $this->apps->types->getAppTypeById($module['id']); + } else { + $moduleMethod = 'get' . ucfirst(substr($module['module_type'], 0, -1)) . 'ById'; + $moduleArr = $this->modules->{$module['module_type']}->$moduleMethod($module['id']); + } if (!$moduleArr) { return $this->queueHasErrors( @@ -1181,8 +1227,11 @@ protected function updateVersion($args) if ($this->access->auth->account() && isset($this->access->auth->account()['id'])) { $moduleArr['updated_by'] = $this->access->auth->account()['id']; } - - $this->modules->{$module['module_type']}->update($moduleArr); + if (str_contains($module['module_type'], 'apptype')) { + $this->apps->types->update($moduleArr); + } else { + $this->modules->{$module['module_type']}->update($moduleArr); + } if ($module['module_type'] === 'packages' && $module['name'] === 'Core' @@ -1435,7 +1484,9 @@ protected function addProgressMethods(&$methods, $module, $taskName, $forTask, $ 'args' => [$taskName, $module, $precheck], ] ); - if ($module['module_type'] !== 'views') { + if ($module['module_type'] !== 'views' && + $module['module_type'] !== 'apptype' + ) { array_push($methods, [ 'method' => 'runModuleInstallScripts-' . $module['id'] . '-' . strtolower(str_replace(' ', '', $module['name'])), @@ -1444,6 +1495,15 @@ protected function addProgressMethods(&$methods, $module, $taskName, $forTask, $ ] ); } + if (!isset($module['is_public'])) { + array_push($methods, + [ + 'method' => 'updateVersion-' . $module['id'] . '-' . strtolower(str_replace(' ', '', $module['name'])), + 'text' => 'Updating version for ' . $module['name'] . ' (' . ucfirst($module['module_type']) . ')...', + 'args' => [$taskName, $module], + ] + ); + } array_push($methods, [ 'method' => 'deleteSourceFiles-' . $module['id'] . '-' . strtolower(str_replace(' ', '', $module['name'])), @@ -1451,16 +1511,6 @@ protected function addProgressMethods(&$methods, $module, $taskName, $forTask, $ 'args' => [$taskName, $module], ] ); - if (is_string($module['id']) && str_contains($module['id'], '-public')) { - return; - } - array_push($methods, - [ - 'method' => 'updateVersion-' . $module['id'] . '-' . strtolower(str_replace(' ', '', $module['name'])), - 'text' => 'Updating version for ' . $module['name'] . ' (' . ucfirst($module['module_type']) . ')...', - 'args' => [$taskName, $module], - ] - ); } } @@ -1737,26 +1787,34 @@ protected function deleteSourceFiles($args) ] ); - $files = - $this->basepackages->utils->scanDir( - 'var/tmp/installer/' . $modulesToInstallOrUpdate['repo_details']['details']['name'] . '-' . $modulesToInstallOrUpdate['repo_details']['latestRelease']['name'] - ); + $scanDirs = [ + 'var/tmp/installer/' . $modulesToInstallOrUpdate['repo_details']['details']['name'] . '-' . + ($modulesToInstallOrUpdate['repo_details']['latestRelease']['name'] !== '' ? $modulesToInstallOrUpdate['repo_details']['latestRelease']['name'] : $modulesToInstallOrUpdate['repo_details']['latestRelease']['tag_name']) + ]; - if (count($files['files']) > 0) { - foreach ($files['files'] as $file) { - $this->localContent->delete($file); - } + if (isset($module['is_public']) && $module['is_public'] == true) { + array_push($scanDirs, + 'var/tmp/installer/' . $modulesToInstallOrUpdate['repo_details']['details']['name'] . '-public-' . + ($modulesToInstallOrUpdate['repo_details']['latestRelease']['name'] !== '' ? $modulesToInstallOrUpdate['repo_details']['latestRelease']['name'] : $modulesToInstallOrUpdate['repo_details']['latestRelease']['tag_name'])); } - if (count($files['dirs']) > 0) { - foreach ($files['dirs'] as $dir) { - $this->localContent->deleteDirectory($dir); + foreach ($scanDirs as $scanDir) { + $files = $this->basepackages->utils->scanDir($scanDir); + + if (count($files['files']) > 0) { + foreach ($files['files'] as $file) { + $this->localContent->delete($file); + } } - } - $this->localContent->deleteDirectory( - 'var/tmp/installer/' . $modulesToInstallOrUpdate['repo_details']['details']['name'] . '-' . $modulesToInstallOrUpdate['repo_details']['latestRelease']['name'] - ); + if (count($files['dirs']) > 0) { + foreach ($files['dirs'] as $dir) { + $this->localContent->deleteDirectory($dir); + } + } + + $this->localContent->deleteDirectory($scanDir); + } $this->queue['results'][$taskName][$module['module_type']][$module['id']]['result'] = 'pass'; } catch (UnableToListContents | UnableToDeleteDirectory | UnableToDeleteFile | \throwable $e) { @@ -1765,6 +1823,8 @@ protected function deleteSourceFiles($args) $resultQueueLogs ); } + + return true; } protected function emailReport() diff --git a/system/Base/Providers/ModulesServiceProvider/Manager.php b/system/Base/Providers/ModulesServiceProvider/Manager.php index 6db0162cb..76f292a63 100644 --- a/system/Base/Providers/ModulesServiceProvider/Manager.php +++ b/system/Base/Providers/ModulesServiceProvider/Manager.php @@ -68,12 +68,15 @@ public function saveModuleSettings($data) public function getModuleInfo($data) { - $moduleId = $data['module_id']; - - if ($data['module_type'] === 'apptype') { - $module = $this->apps->types->getAppTypeById($data['module_id']); - $module['module_type'] = 'apptypes'; + if (str_contains($data['module_type'], 'apptype')) { + if (is_int($data['module_id'])) { + $module = $this->apps->types->getAppTypeById($data['module_id']); + } else if (is_string($data['module_id'])) { + $module = $this->apps->types->getAppTypeByType($data['module_id']); + } } else { + $moduleId = $data['module_id']; + if ($data['module_type'] === 'views' && str_contains($data['module_id'], '-public') ) { @@ -210,6 +213,15 @@ public function updateModuleRepoDetails($module, $data = null) $module['repo_details']['details'] = $responseArr; + $repoArr = explode('/', $module['repo']); + $names = explode('-', $this->helper->last($repoArr)); + + if (count($names) === 1) { + if (!isset($module['module_type'])) { + $module['module_type'] = 'apptypes'; + } + } + $this->remoteModules[$module['module_type']] = [$responseArr]; $latestRelease = $this->moduleNeedsUpgrade($responseArr, $module); @@ -225,7 +237,7 @@ public function updateModuleRepoDetails($module, $data = null) } } - if ($module['module_type'] === 'apptypes') { + if (str_contains($module['module_type'], 'apptype')) { $this->apps->types->update($module); } else { $this->modules->{$module['module_type']}->update($module); @@ -369,7 +381,7 @@ public function getRepositoryModules($data = []) if (!isset($sortedModules[$moduleArr['api_id']]['childs'][$moduleArr['app_type']])) { $sortedModules[$moduleArr['api_id']]['childs'][$moduleArr['app_type']] = []; $sortedModules[$moduleArr['api_id']]['childs'][$moduleArr['app_type']]['name'] = $moduleArr['app_type']; - $sortedModules[$moduleArr['api_id']]['childs'][$moduleArr['app_type']]['data']['type'] = 'app'; + $sortedModules[$moduleArr['api_id']]['childs'][$moduleArr['app_type']]['data']['type'] = 'apptype'; } if (!isset($sortedModules[$moduleArr['api_id']]['childs'][$moduleArr['app_type']]['childs'][$moduleArr['module_type']])) { @@ -693,7 +705,7 @@ protected function getRemoteModule($moduleName) protected function getRemoteModuleJson($moduleType, $module, $onlyJson = false) { - if ($moduleType === 'apptypes') { + if (str_contains($moduleType, 'apptype')) { $jsonFileName = 'Install/type.json'; } else { if ($moduleType === 'views' || $moduleType === 'bundles') {//remove "s" from the name @@ -785,7 +797,7 @@ protected function updateRemoteModulesToDB() $this->counter['updates']['count'] = 0; } - if ($remoteModulesType === 'apptypes') { + if (str_contains($remoteModulesType, 'apptype')) { $this->apps->types->update($updateRemotePackage); } else { $this->modules->{$remoteModulesType}->update($updateRemotePackage); @@ -837,7 +849,7 @@ protected function updateRemoteModulesToDB() $registerRemotePackage['api_id'] = $this->apiClientConfig['id']; - if ($remoteModulesType === 'apptypes') { + if (str_contains($remoteModulesType, 'apptype')) { $this->apps->types->add($registerRemotePackage); } else { if ($registerRemotePackage['module_type'] === 'components') { @@ -892,7 +904,7 @@ protected function findRemoteInLocal($remoteModules, $remoteModulesType) $repoUrl = $remoteModule['html_url']; } - if ($remoteModulesType === 'apptypes') { + if (str_contains($remoteModulesType, 'apptype')) { $localModule = $this->apps->types->getAppTypeByRepo($repoUrl); } else { $moduleMethod = 'get' . ucfirst(substr($remoteModulesType, 0, -1)) . 'ByRepo'; diff --git a/system/Base/Providers/ModulesServiceProvider/Queues.php b/system/Base/Providers/ModulesServiceProvider/Queues.php index b1b4d3ab1..7d67ef22f 100644 --- a/system/Base/Providers/ModulesServiceProvider/Queues.php +++ b/system/Base/Providers/ModulesServiceProvider/Queues.php @@ -424,8 +424,12 @@ public function analyseQueue(&$queue = null, $reAnalyse = false) } foreach ($moduleIds as $moduleIdKey => $moduleId) { - $moduleMethod = 'get' . ucfirst(substr($moduleType, 0, -1)) . 'ById'; - $module = $this->modules->$moduleType->$moduleMethod($moduleId); + if ($moduleType === 'apptype') { + $module = $this->apps->types->getAppTypeById($moduleId); + } else { + $moduleMethod = 'get' . ucfirst(substr($moduleType, 0, -1)) . 'ById'; + $module = $this->modules->$moduleType->$moduleMethod($moduleId); + } if (!$module) { unset($queue['tasks'][$taskName][$moduleType][$moduleIdKey]); @@ -453,7 +457,6 @@ public function analyseQueue(&$queue = null, $reAnalyse = false) if ($bundleModule) { $this->compareAndAddToQueue($bundles, $bundleModule, $taskName, $bundleType); - // $this->addToQueueTasksAndResults($taskName, $bundleType, $bundleModule); } else { $this->addToQueueTasksAndResults($taskName, $bundleType, $bundles, null, 'fail', $this->getApiClientServices($bundles, true)); } @@ -492,61 +495,63 @@ public function analyseQueue(&$queue = null, $reAnalyse = false) $module['dependencies'] = $module['repo_details']['latestRelease']['moduleJson']['dependencies']; } - if (isset($module['dependencies']) && is_string($module['dependencies'])) { - $module['dependencies'] = $this->helper->decode($module['dependencies'], true); - } - - foreach ($module['dependencies'] as $dependencyType => $dependencies) { - if (count($dependencies) === 0) { - continue; + if (isset($module['dependencies'])) { + if (is_string($module['dependencies'])) { + $module['dependencies'] = $this->helper->decode($module['dependencies'], true); } - if ($taskName === 'uninstall' || $taskName === 'remove') { - continue;//we dont process dependencies for anything other than install/update - } + foreach ($module['dependencies'] as $dependencyType => $dependencies) { + if (count($dependencies) === 0) { + continue; + } - if ($dependencyType === 'composer' || $dependencyType === 'external') { - $this->checkComposerAndAddToQueue($dependencies, $module); + if ($taskName === 'uninstall' || $taskName === 'remove') { + continue;//we dont process dependencies for anything other than install/update + } - continue; - } + if ($dependencyType === 'composer' || $dependencyType === 'external') { + $this->checkComposerAndAddToQueue($dependencies, $module); - if ($dependencyType === 'core') { - $core = $this->modules->packages->getPackageByRepo($dependencies['repo']); + continue; + } - $this->compareAndAddToQueue($dependencies, $core, 'first', 'packages'); - } else if ($dependencyType === 'apptype') { - $appType = $this->apps->types->getAppTypeByRepo($dependencies['repo']); + if ($dependencyType === 'core') { + $core = $this->modules->packages->getPackageByRepo($dependencies['repo']); - if ($appType) { - $this->compareAndAddToQueue($dependencies, $appType, $taskName, $dependencyType); + $this->compareAndAddToQueue($dependencies, $core, 'first', 'packages'); + } else if ($dependencyType === 'apptype') { + $appType = $this->apps->types->getAppTypeByRepo($dependencies['repo']); + + if ($appType) { + $this->compareAndAddToQueue($dependencies, $appType, $taskName, $dependencyType); + } else { + $this->addToQueueTasksAndResults($taskName, $dependencyType, $dependencies, null, 'fail', $this->getApiClientServices($dependencies, true)); + } } else { - $this->addToQueueTasksAndResults($taskName, $dependencyType, $dependencies, null, 'fail', $this->getApiClientServices($dependencies, true)); - } - } else { - if (count($dependencies) > 0) { - foreach ($dependencies as $dependency) { - if (!isset($this->queueTasks[$taskName][$dependencyType])) { - $this->queueTasks[$taskName][$dependencyType] = []; - } + if (count($dependencies) > 0) { + foreach ($dependencies as $dependency) { + if (!isset($this->queueTasks[$taskName][$dependencyType])) { + $this->queueTasks[$taskName][$dependencyType] = []; + } - $dependencyModuleMethod = 'get' . ucfirst(substr($dependencyType, 0, -1)) . 'ByRepo'; - $dependencyModule = $this->modules->$dependencyType->$dependencyModuleMethod($dependency['repo']); + $dependencyModuleMethod = 'get' . ucfirst(substr($dependencyType, 0, -1)) . 'ByRepo'; + $dependencyModule = $this->modules->$dependencyType->$dependencyModuleMethod($dependency['repo']); - if ($dependencyModule) { - $removeUninstallArr = ['remove', 'uninstall']; + if ($dependencyModule) { + $removeUninstallArr = ['remove', 'uninstall']; - foreach ($removeUninstallArr as $removeUninstall) { - if (isset($queue['tasks'][$removeUninstall][$dependencyType]) && in_array($dependencyModule['id'], $queue['tasks'][$removeUninstall][$dependencyType])) { - $this->addToQueueTasksAndResults($taskName, $dependencyType, $dependencyModule, null, 'fail', 'Dependency is in ' . $removeUninstall . ' task, but is also required by module ' . ($module['display_name'] ?? $module['name']) . ''); + foreach ($removeUninstallArr as $removeUninstall) { + if (isset($queue['tasks'][$removeUninstall][$dependencyType]) && in_array($dependencyModule['id'], $queue['tasks'][$removeUninstall][$dependencyType])) { + $this->addToQueueTasksAndResults($taskName, $dependencyType, $dependencyModule, null, 'fail', 'Dependency is in ' . $removeUninstall . ' task, but is also required by module ' . ($module['display_name'] ?? $module['name']) . ''); - continue 2; + continue 2; + } } - } - $this->compareAndAddToQueue($dependency, $dependencyModule, $taskName, $dependencyType); - } else { - $this->addToQueueTasksAndResults($taskName, $dependencyType, $dependency, null, 'fail', $this->getApiClientServices($dependency, true)); + $this->compareAndAddToQueue($dependency, $dependencyModule, $taskName, $dependencyType); + } else { + $this->addToQueueTasksAndResults($taskName, $dependencyType, $dependency, null, 'fail', $this->getApiClientServices($dependency, true)); + } } } } @@ -566,7 +571,7 @@ public function analyseQueue(&$queue = null, $reAnalyse = false) ) { $module['id'] = $module['id'] . '-public'; $module['display_name'] = $module['display_name'] . ' (Public)'; - // $module['name'] = ($module['display_name'] ?? $module['name']) . ' (Public)'; + $module['is_public'] = true; $module['repo'] = $module['repo'] . '-public'; $this->addToQueueTasksAndResults($taskName, $moduleType, $module); @@ -658,7 +663,7 @@ protected function compareAndAddToQueue($requestedModule, $installedModule, $tas ) { $installedModule['id'] = $installedModule['id'] . '-public'; $installedModule['display_name'] = $installedModule['display_name'] . ' (Public)'; - // $installedModule['name'] = ($installedModule['display_name'] ?? $installedModule['name']) . ' (Public)'; + $installedModule['is_public'] = true; $installedModule['repo'] = $installedModule['repo'] . '-public'; if ($installedModule['installed'] != '1') { @@ -691,7 +696,7 @@ protected function compareAndAddToQueue($requestedModule, $installedModule, $tas ) { $installedModule['id'] = $installedModule['id'] . '-public'; $installedModule['display_name'] = $installedModule['display_name'] . ' (Public)'; - // $installedModule['name'] = ($installedModule['display_name'] ?? $installedModule['name']) . ' (Public)'; + $installedModule['is_public'] = true; $installedModule['repo'] = $installedModule['repo'] . '-public'; $this->addToQueueTasksAndResults('install', $moduleType, $installedModule); @@ -798,9 +803,20 @@ protected function addToQueueTasksAndResults($taskName, $moduleType, $module, $v $this->queueTasks[$taskName][$moduleType][$module['id']]['module_type'] = $moduleType; if ($moduleType === 'views' && array_key_exists('is_subview', $module)) { $this->queueTasks[$taskName][$moduleType][$module['id']]['is_subview'] = $module['is_subview']; + if ($module['is_subview']) { + $repo = strtolower($this->helper->last(explode('/', $module['repo']))); + $names = explode('-', $repo); + array_pop($names); + $this->queueTasks[$taskName][$moduleType][$module['id']]['base_view_name'] = $this->helper->last($names); + } + } + if ($moduleType === 'views' && array_key_exists('is_public', $module)) { + $this->queueTasks[$taskName][$moduleType][$module['id']]['is_public'] = $module['is_public']; } if ($moduleType !== 'external') { - $this->queueTasks[$taskName][$moduleType][$module['id']]['app_type'] = $module['app_type']; + if (array_key_exists('app_type', $module)) { + $this->queueTasks[$taskName][$moduleType][$module['id']]['app_type'] = $module['app_type']; + } } if (!$version) { $this->queueTasks[$taskName][$moduleType][$module['id']]['version'] = From abea273c0566ad3ee26b86baca9617cd2fed021b Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Sun, 9 Feb 2025 15:36:50 +1100 Subject: [PATCH 38/54] fix issue #597 --- public/core/default/js/footer/core/Baz/BazTunnels.js | 5 +---- public/core/default/js/footer/jsFooterCore.js | 5 +---- .../core/default/js/header/dependencies/Baz/BazCore.js | 9 +++++++++ public/core/default/js/header/jsHeaderCore.js | 9 +++++++++ 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/public/core/default/js/footer/core/Baz/BazTunnels.js b/public/core/default/js/footer/core/Baz/BazTunnels.js index 0e0de81c2..b214e78c7 100644 --- a/public/core/default/js/footer/core/Baz/BazTunnels.js +++ b/public/core/default/js/footer/core/Baz/BazTunnels.js @@ -26,9 +26,6 @@ var BazTunnels = function() { dataCollection.env.wsTunnels.messenger = { }; dataCollection.env.wsTunnels.pusher = { }; - // var reconnectMessengerTunnel = null; - // var reconnectPusherTunnel = null; - // Error // function error(errorMsg) { // throw new Error(errorMsg); @@ -173,7 +170,7 @@ var BazTunnels = function() { BazHelpers.setTimeoutTimers.add(function() { initPusherTunnel(options); - }, 60000, null, 'initPusherTunnel'); + }, 30000, null, 'initPusherTunnel'); }, { 'skipSubprotocolCheck': true diff --git a/public/core/default/js/footer/jsFooterCore.js b/public/core/default/js/footer/jsFooterCore.js index a98e823da..468c3ed90 100644 --- a/public/core/default/js/footer/jsFooterCore.js +++ b/public/core/default/js/footer/jsFooterCore.js @@ -10100,9 +10100,6 @@ var BazTunnels = function() { dataCollection.env.wsTunnels.messenger = { }; dataCollection.env.wsTunnels.pusher = { }; - // var reconnectMessengerTunnel = null; - // var reconnectPusherTunnel = null; - // Error // function error(errorMsg) { // throw new Error(errorMsg); @@ -10247,7 +10244,7 @@ var BazTunnels = function() { BazHelpers.setTimeoutTimers.add(function() { initPusherTunnel(options); - }, 60000, null, 'initPusherTunnel'); + }, 30000, null, 'initPusherTunnel'); }, { 'skipSubprotocolCheck': true diff --git a/public/core/default/js/header/dependencies/Baz/BazCore.js b/public/core/default/js/header/dependencies/Baz/BazCore.js index 17261a46f..e99e9b46a 100644 --- a/public/core/default/js/header/dependencies/Baz/BazCore.js +++ b/public/core/default/js/header/dependencies/Baz/BazCore.js @@ -116,6 +116,15 @@ var BazCore = function() { if (dataCollection.env.currentRoute.indexOf('auth') === -1) { BazTunnels.init(); } + $('#body').on('bazContentLoaderAjaxComplete', function() { + //eslint-disable-next-line + console.log(dataCollection.env.wsTunnels.pusher._websocket_connected); + if (dataCollection.env.wsTunnels.pusher._websocket_connected !== 'undefined' && + dataCollection.env.wsTunnels.pusher._websocket_connected === false + ) { + BazTunnels.init(); + } + }); initPings(); } diff --git a/public/core/default/js/header/jsHeaderCore.js b/public/core/default/js/header/jsHeaderCore.js index ca25076a4..073c2206b 100644 --- a/public/core/default/js/header/jsHeaderCore.js +++ b/public/core/default/js/header/jsHeaderCore.js @@ -554,6 +554,15 @@ var BazCore = function() { if (dataCollection.env.currentRoute.indexOf('auth') === -1) { BazTunnels.init(); } + $('#body').on('bazContentLoaderAjaxComplete', function() { + //eslint-disable-next-line + console.log(dataCollection.env.wsTunnels.pusher._websocket_connected); + if (dataCollection.env.wsTunnels.pusher._websocket_connected !== 'undefined' && + dataCollection.env.wsTunnels.pusher._websocket_connected === false + ) { + BazTunnels.init(); + } + }); initPings(); } From ef5f41d2647a63113afe54bea831c5071a2bbdfe Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Sun, 9 Feb 2025 22:00:54 +1100 Subject: [PATCH 39/54] fix issue #600 --- system/Base/Providers/DatabaseServiceProvider/Ff.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/system/Base/Providers/DatabaseServiceProvider/Ff.php b/system/Base/Providers/DatabaseServiceProvider/Ff.php index 37a72a2e5..01e7f8716 100644 --- a/system/Base/Providers/DatabaseServiceProvider/Ff.php +++ b/system/Base/Providers/DatabaseServiceProvider/Ff.php @@ -615,11 +615,15 @@ public function reSync() if (is_array($storeDataValue)) { $storeDataValue = $this->helper->encode($storeDataValue); } + if (is_int($storeDataValue)) { + $storeDataValue = (string) $storeDataValue; + } + if (is_bool($storeDataValue)) { + $storeDataValue = $storeDataValue ? 1 : 0; + } } - $model->assign($storeData); - - $model->create(); + $this->db->insertAsDict($model->getSource(), $storeData); } return true; From 67b81afb866af3062fc925b815c23bf92d3f13ec Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Sun, 9 Feb 2025 22:28:33 +1100 Subject: [PATCH 40/54] Issue #599. Initial commit and fix bugs. --- .../System/Menus/Install/component.json | 42 +++++ .../System/Menus/MenusComponent.php | 89 ++++++++++ .../Devtools/Modules/DevtoolsModules.php | 4 +- .../Views/Default/html/system/menus/form.html | 167 ++++++++++++++++++ .../Views/Default/html/system/menus/list.html | 30 ++++ .../Views/Default/html/system/menus/view.html | 29 +++ system/Base/Installer/Packages/Setup.php | 6 +- .../Setup/Register/Basepackages/Menu.php | 7 +- .../Packages/Basepackages/Menus/package.json | 24 +++ .../Setup/Schema/Basepackages/Menus.php | 8 + .../Providers/AppsServiceProvider/Apps.php | 2 +- .../Packages/Menus.php | 28 ++- .../Packages/Model/BasepackagesMenus.php | 2 + 13 files changed, 424 insertions(+), 14 deletions(-) create mode 100644 apps/Core/Components/System/Menus/Install/component.json create mode 100644 apps/Core/Components/System/Menus/MenusComponent.php create mode 100644 apps/Core/Views/Default/html/system/menus/form.html create mode 100644 apps/Core/Views/Default/html/system/menus/list.html create mode 100644 apps/Core/Views/Default/html/system/menus/view.html create mode 100644 system/Base/Installer/Packages/Setup/Register/Modules/Packages/Basepackages/Menus/package.json diff --git a/apps/Core/Components/System/Menus/Install/component.json b/apps/Core/Components/System/Menus/Install/component.json new file mode 100644 index 000000000..5e19fbd99 --- /dev/null +++ b/apps/Core/Components/System/Menus/Install/component.json @@ -0,0 +1,42 @@ +{ + "route" : "system/menus", + "name" : "Menus", + "description" : "Manage menus via this component", + "module_type" : "components", + "app_type" : "core", + "category" : "admin", + "version" : "0.0.0", + "repo" : "https://.../", + "class" : "Apps\\Core\\Components\\System\\Menus\\MenusComponent", + "dependencies" : { + "core" : { + "name" : "Core", + "version" : "0.0.0", + "repo" : "https://.../" + }, + "components" : [], + "packages" : [], + "middlewares" : [], + "views" : [], + "external" : [] + }, + "menu" : { + "seq" : 7, + "system" : { + "icon" : "cogs", + "title" : "system", + "childs" : { + "menus" : { + "title" : "menus", + "icon" : "bars", + "link" : "system/menus" + } + } + } + }, + "settings" : { + "mandatory" : { + "core" : true + } + } +} \ No newline at end of file diff --git a/apps/Core/Components/System/Menus/MenusComponent.php b/apps/Core/Components/System/Menus/MenusComponent.php new file mode 100644 index 000000000..d98120d79 --- /dev/null +++ b/apps/Core/Components/System/Menus/MenusComponent.php @@ -0,0 +1,89 @@ +menus = $this->basepackages->menus; + } + + /** + * @acl(name=view) + */ + public function viewAction() + { + $this->view->appTypes = $this->apps->types->getInstalledAppTypes(); + + if (isset($this->getData()['id'])) { + if ($this->getData()['id'] != 0) { + $menu = $this->menus->getById($this->getData()['id']); + + if (!$menu) { + return $this->throwIdNotFound(); + } + + $this->view->menu = $menu; + } + + $this->view->pick('menus/view'); + + return; + } + + $controlActions = + [ + 'actionsToEnable' => + [ + 'view' => 'system/menus', + ] + ]; + + $this->generateDTContent( + $this->menus, + 'system/menus/view', + null, + ['route', 'app_type'], + true, + ['route', 'app_type'], + $controlActions, + null, + null, + 'id' + ); + + $this->view->pick('menus/list'); + } + + /** + * @acl(name=add) + */ + public function addAction() + { + // + } + + /** + * @acl(name=update) + */ + public function updateAction() + { + // + } + + /** + * @acl(name=remove) + */ + public function removeAction() + { + // + } +} \ No newline at end of file diff --git a/apps/Core/Packages/Devtools/Modules/DevtoolsModules.php b/apps/Core/Packages/Devtools/Modules/DevtoolsModules.php index e1e034424..fea35a473 100644 --- a/apps/Core/Packages/Devtools/Modules/DevtoolsModules.php +++ b/apps/Core/Packages/Devtools/Modules/DevtoolsModules.php @@ -1507,11 +1507,11 @@ protected function addUpdateComponentMenu($data) $data['menu'] = $this->helper->decode($data['menu'], true); if (isset($menu)) { - $this->basepackages->menus->updateMenu($data['menu_id'], $data['app_type'], $data['menu']); + $this->basepackages->menus->updateMenu($data['menu_id'], $data); return; } else { - $menu = $this->basepackages->menus->addMenu($data['app_type'], $data['menu']); + $menu = $this->basepackages->menus->addMenu($data); if ($menu) { $module = $this->modules->{$data['module_type']}->packagesData->last; diff --git a/apps/Core/Views/Default/html/system/menus/form.html b/apps/Core/Views/Default/html/system/menus/form.html new file mode 100644 index 000000000..cf26b9432 --- /dev/null +++ b/apps/Core/Views/Default/html/system/menus/form.html @@ -0,0 +1,167 @@ +{% if menu['id'] is defined %} + {% set menuId = menu['id'] %} + {% set menuRoute = menu['route'] %} + {% set menuAppType = menu['app_type'] %} + {% set menuMenu = menu['menu'] %} +{% else %} + {% set menuId = '' %} + {% set menuRoute = '' %} + {% set menuAppType = '' %} + {% set menuMenu = '' %} +{% endif %} +
+
+
+
+ {{adminltetags.useTag('fields', + [ + 'component' : component, + 'componentName' : componentName, + 'componentId' : componentId, + 'sectionId' : sectionId, + 'fieldId' : 'id', + 'fieldLabel' : 'Menu ID', + 'fieldType' : 'input', + 'fieldHelp' : true, + 'fieldHelpTooltipContent' : 'Menu ID', + 'fieldRequired' : true, + 'fieldBazScan' : true, + 'fieldBazPostOnCreate' : false, + 'fieldBazPostOnUpdate' : true, + 'fieldHidden' : true, + 'fieldDisabled' : true, + 'fieldValue' : menuId + ] + )}} +
+
+
+
+ {{adminltetags.useTag('fields', + [ + 'component' : component, + 'componentName' : componentName, + 'componentId' : componentId, + 'sectionId' : sectionId, + 'fieldId' : 'route', + 'fieldLabel' : 'Route', + 'fieldType' : 'input', + 'fieldHelp' : true, + 'fieldHelpTooltipContent' : 'Route Example: system/menus', + 'fieldRequired' : true, + 'fieldBazScan' : true, + 'fieldBazPostOnCreate' : true, + 'fieldBazPostOnUpdate' : true, + 'fieldDataInputMinLength' : 1, + 'fieldDataInputMaxLength' : 50, + 'fieldValue' : menuRoute + ] + )}} +
+
+ {{adminltetags.useTag('fields', + [ + 'component' : component, + 'componentName' : componentName, + 'componentId' : componentId, + 'sectionId' : sectionId, + 'fieldId' : 'app_type', + 'fieldLabel' : 'App Type', + 'fieldType' : 'select2', + 'fieldHelp' : true, + 'fieldHelpTooltipContent' : 'Select App Type for the menu.', + 'fieldRequired' : true, + 'fieldBazScan' : true, + 'fieldBazPostOnCreate' : true, + 'fieldBazPostOnUpdate' : true, + 'fieldDataSelect2Options' : appTypes, + 'fieldDataSelect2OptionsKey' : 'app_type', + 'fieldDataSelect2OptionsValue' : 'name', + 'fieldDataSelect2OptionsArray' : true, + 'fieldDataSelect2OptionsSelected' : menuAppType + ] + )}} +
+
+
+
+ {{adminltetags.useTag('fields', + [ + 'component' : component, + 'componentName' : componentName, + 'componentId' : componentId, + 'sectionId' : sectionId, + 'fieldId' : 'menu', + 'fieldLabel' : 'Menu', + 'fieldType' : 'textarea', + 'fieldDataMaxLength' : 4096, + 'fieldHelp' : true, + 'fieldHelpTooltipContent' : 'Menu', + 'fieldRequired' : true, + 'fieldBazScan' : true, + 'fieldBazPostOnCreate' : true, + 'fieldBazPostOnUpdate' : true, + 'fieldDataInputMaxLength' : 4096, + 'fieldTextareaRows' : 10, + 'fieldValue' : menuMenu + ] + )}} +
+
+
+
+ \ No newline at end of file diff --git a/apps/Core/Views/Default/html/system/menus/list.html b/apps/Core/Views/Default/html/system/menus/list.html new file mode 100644 index 000000000..7067e9104 --- /dev/null +++ b/apps/Core/Views/Default/html/system/menus/list.html @@ -0,0 +1,30 @@ +{{adminltetags.useTag('content', + [ + 'component' : table['component'], + 'componentName' : componentName, + 'componentId' : componentId, + 'parentComponentId' : parent, + 'sectionId' : 'listing', + 'contentType' : 'sectionWithListing', + 'cardHeader' : true, + 'cardType' : 'primary', + 'cardIcon' : 'bars', + 'cardTitle' : componentName, + 'cardAdditionalClass' : 'rounded-0', + 'dtFilter' : false, + 'dtFilters' : table['filters'], + 'dtFilterColumns' : table['filterColumns'], + 'dtFixedHeader' : true, + 'dtTable' : table, + 'dtColumns' : table['columns'], + 'dtPostUrl' : table['postUrl'], + 'dtPostUrlParams' : table['postUrlParams'], + 'dtStriped' : true, + 'dtStateSave' : false, + 'dtBordered' : false, + 'dtHideIdColumn' : true, + 'dtNoOfColumnsToShow' : 6, + 'dtTableCompact' : true, + 'dtZeroRecords' : 'No menus data available. Menus are added via component.json file during installation or you can make custom menu in the app.' + ] +)}} \ No newline at end of file diff --git a/apps/Core/Views/Default/html/system/menus/view.html b/apps/Core/Views/Default/html/system/menus/view.html new file mode 100644 index 000000000..b0c413839 --- /dev/null +++ b/apps/Core/Views/Default/html/system/menus/view.html @@ -0,0 +1,29 @@ +{% if menu['id'] is defined %} + {% set menuId = menu['id'] %} + {% set title = ' Menu (' ~ menu['route'] ~ ')' %} +{% else %} + {% set menuId = '' %} + {% set title = 'New Menu' %} +{% endif %} + +{{adminltetags.useTag('content', + [ + 'component' : component, + 'componentName' : componentName, + 'componentId' : componentId, + 'parentComponentId' : parent, + 'sectionId' : 'main', + 'contentType' : 'sectionWithForm', + 'cardHeader' : true, + 'cardFooter' : true, + 'cardType' : 'primary', + 'cardIcon' : 'bars', + 'cardTitle' : title, + 'cardAdditionalClass' : 'rounded-0', + 'cardBodyInclude' : 'menus/form', + 'formButtons' : + [ + 'closeActionUrl' : 'system/menus' + ] + ] +)}} \ No newline at end of file diff --git a/system/Base/Installer/Packages/Setup.php b/system/Base/Installer/Packages/Setup.php index 049b9700a..251b63762 100644 --- a/system/Base/Installer/Packages/Setup.php +++ b/system/Base/Installer/Packages/Setup.php @@ -465,7 +465,7 @@ protected function registerModule($type) } if ($jsonFile['menu'] && $jsonFile['menu'] !== 'false') { - $menuId = $this->registerCoreMenu($jsonFile['app_type'], $jsonFile['menu']); + $menuId = $this->registerCoreMenu($jsonFile); } else { $menuId = null; } @@ -600,9 +600,9 @@ protected function updateCoreAppComponents() return (new RegisterCoreApp())->update($this->db, $this->ff); } - protected function registerCoreMenu($appType, array $menu) + protected function registerCoreMenu($componentJsonFile) { - return (new RegisterMenu())->register($this->db, $this->ff, $appType, $menu, $this->helper); + return (new RegisterMenu())->register($this->db, $this->ff, $componentJsonFile, $this->helper); } protected function registerCorePackage(array $packageFile) diff --git a/system/Base/Installer/Packages/Setup/Register/Basepackages/Menu.php b/system/Base/Installer/Packages/Setup/Register/Basepackages/Menu.php index 3587b16c1..8065f4dc9 100644 --- a/system/Base/Installer/Packages/Setup/Register/Basepackages/Menu.php +++ b/system/Base/Installer/Packages/Setup/Register/Basepackages/Menu.php @@ -4,8 +4,10 @@ class Menu { - public function register($db, $ff, $appType, array $menu, $helper) + public function register($db, $ff, $componentJsonFile, $helper) { + $menu = $componentJsonFile['menu']; + if (isset($menu['seq'])) { $sequence = $menu['seq']; unset($menu['seq']); @@ -19,7 +21,8 @@ public function register($db, $ff, $appType, array $menu, $helper) [ 'menu' => $helper->encode($menu), 'apps' => $helper->encode(['1' => ['enabled' => true]]), - 'app_type' => $appType, + 'app_type' => $componentJsonFile['app_type'], + 'route' => $componentJsonFile['route'], 'sequence' => $sequence ]; diff --git a/system/Base/Installer/Packages/Setup/Register/Modules/Packages/Basepackages/Menus/package.json b/system/Base/Installer/Packages/Setup/Register/Modules/Packages/Basepackages/Menus/package.json new file mode 100644 index 000000000..00ee598a0 --- /dev/null +++ b/system/Base/Installer/Packages/Setup/Register/Modules/Packages/Basepackages/Menus/package.json @@ -0,0 +1,24 @@ +{ + "name" : "Menus", + "display_name" : "Menus", + "description" : "Menus package", + "module_type" : "packages", + "app_type" : "core", + "category" : "basepackages", + "version" : "0.0.0", + "repo" : "https://.../", + "class" : "System\\Base\\Providers\\BasepackagesServiceProvider\\Packages\\Menus", + "dependencies" : { + "core" : { + "name" : "Core", + "version" : "0.0.0", + "repo" : "https://.../" + }, + "components" : [], + "packages" : [], + "middlewares" : [], + "views" : [], + "external" : [] + }, + "settings" : {"componentRoute":"system/menus"} +} \ No newline at end of file diff --git a/system/Base/Installer/Packages/Setup/Schema/Basepackages/Menus.php b/system/Base/Installer/Packages/Setup/Schema/Basepackages/Menus.php index 7dd2f420e..d3fffe87d 100644 --- a/system/Base/Installer/Packages/Setup/Schema/Basepackages/Menus.php +++ b/system/Base/Installer/Packages/Setup/Schema/Basepackages/Menus.php @@ -44,6 +44,14 @@ public function columns() 'notNull' => true, ] ), + new Column( + 'route', + [ + 'type' => Column::TYPE_VARCHAR, + 'size' => 50, + 'notNull' => true, + ] + ), new Column( 'sequence', [ diff --git a/system/Base/Providers/AppsServiceProvider/Apps.php b/system/Base/Providers/AppsServiceProvider/Apps.php index 883632b71..3a0ae0caa 100644 --- a/system/Base/Providers/AppsServiceProvider/Apps.php +++ b/system/Base/Providers/AppsServiceProvider/Apps.php @@ -298,7 +298,7 @@ public function updateApp(array $data) $this->modules->components->updateComponents($app); } - if (isset($app['menus'])) { + if (isset($app['menus']) && $app['menus'] !== '') { $this->basepackages->menus->updateMenus($app); } diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Menus.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Menus.php index 99681ee7a..966822f3f 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Menus.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Menus.php @@ -9,7 +9,7 @@ class Menus extends BasePackage { protected $modelToUse = BasepackagesMenus::class; - protected $packageNameS = 'Menu'; + protected $packageName = 'menus'; public $menus; @@ -83,7 +83,11 @@ public function getMenusForAppType($appType) public function updateMenus($data) { - $menus = $this->helper->decode($data['menus'], true); + $menus = $data['menus']; + + if (is_string($menus)) { + $menus = $this->helper->decode($menus, true); + } if (count($menus) > 0) { foreach ($menus as $menuId => $value) { @@ -105,8 +109,10 @@ public function updateMenus($data) $this->init(true); } - public function addMenu($appType, array $menu) + public function addMenu($data) { + $menu = $data['menu']; + if (isset($menu['seq'])) { $sequence = $menu['seq']; unset($menu['seq']); @@ -119,7 +125,8 @@ public function addMenu($appType, array $menu) $insertMenu = $this->add([ 'menu' => $this->helper->encode($menu), 'apps' => $this->helper->encode([]), - 'app_type' => $appType, + 'app_type' => $data['app_type'], + 'route' => $data['route'], 'sequence' => $sequence ] ); @@ -131,8 +138,16 @@ public function addMenu($appType, array $menu) } } - public function updateMenu($id, $appType, array $menu) + public function updateMenu($id, array $data) { + $menu = $this->getById($id); + + if ($menu) { + $menu = array_merge($menu, $data['menu']); + } else { + $menu = $data['menu']; + } + if (isset($menu['seq'])) { $sequence = $menu['seq']; unset($menu['seq']); @@ -146,7 +161,8 @@ public function updateMenu($id, $appType, array $menu) 'id' => $id, 'menu' => $this->helper->encode($menu), 'apps' => $this->helper->encode([]), - 'app_type' => $appType, + 'app_type' => $data['app_type'], + 'route' => $data['route'], 'sequence' => $sequence ] ); diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Model/BasepackagesMenus.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Model/BasepackagesMenus.php index 9e44ac5ce..d5e30d14b 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Model/BasepackagesMenus.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Model/BasepackagesMenus.php @@ -14,5 +14,7 @@ class BasepackagesMenus extends BaseModel public $app_type; + public $route; + public $sequence; } \ No newline at end of file From 1268bfd11ad0018539d505435e3dffe21633c25b Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Sun, 9 Feb 2025 22:29:21 +1100 Subject: [PATCH 41/54] update #34. Adding menu installer for components. --- apps/Core/Components/Apps/AppsComponent.php | 2 +- .../Packages/Dashboards.php | 4 +++- .../ModulesServiceProvider/MenuInstaller.php | 16 ++++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 system/Base/Providers/ModulesServiceProvider/MenuInstaller.php diff --git a/apps/Core/Components/Apps/AppsComponent.php b/apps/Core/Components/Apps/AppsComponent.php index 824ced282..9f5b74223 100644 --- a/apps/Core/Components/Apps/AppsComponent.php +++ b/apps/Core/Components/Apps/AppsComponent.php @@ -381,7 +381,7 @@ public function updateAction() $this->apps->packagesData->responseCode ); - $this->addToNotification('update', 'Updated app', null, $this->apps->packagesData->last); + $this->addToNotification('update', 'Updated app', null, $this->apps->packagesData->last ?? []); } /** diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Dashboards.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Dashboards.php index ce3580b88..c739790ee 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Dashboards.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Dashboards.php @@ -74,7 +74,9 @@ public function getDashboardsByAppType($appType) public function addDashboard(array $data) { $data['app_default'] = 0; - $data['app_type'] = $this->apps->app['app_type']; + if (!isset($data['app_type'])) { + $data['app_type'] = $this->apps->app['app_type']; + } $data['created_by'] = 0; if ($this->access->auth->account()) { diff --git a/system/Base/Providers/ModulesServiceProvider/MenuInstaller.php b/system/Base/Providers/ModulesServiceProvider/MenuInstaller.php new file mode 100644 index 000000000..68e0f7357 --- /dev/null +++ b/system/Base/Providers/ModulesServiceProvider/MenuInstaller.php @@ -0,0 +1,16 @@ + Date: Sun, 9 Feb 2025 23:25:08 +1100 Subject: [PATCH 42/54] fix minor bugs #599 --- .../Default/html/devtools/test/view.html | 7 --- .../Packages/Menus.php | 44 ++++++++++++++----- 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/apps/Core/Views/Default/html/devtools/test/view.html b/apps/Core/Views/Default/html/devtools/test/view.html index 4271c682a..bd9098bad 100644 --- a/apps/Core/Views/Default/html/devtools/test/view.html +++ b/apps/Core/Views/Default/html/devtools/test/view.html @@ -1,11 +1,4 @@ Test \ No newline at end of file diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Menus.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Menus.php index 966822f3f..8f5786be4 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Menus.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Menus.php @@ -38,7 +38,11 @@ public function buildMenus($menus = null) $buildMenu = []; foreach (msort($menus, 'sequence') as $key => $menu) { - $menu = $this->helper->decode($menu['menu'], true); + if (is_string($menu['menu'])) { + $menu['menu'] = $this->helper->decode($menu['menu'], true); + } + + $menu = $menu['menu']; if ($menu) { $buildMenu = array_replace_recursive($buildMenu, $menu); @@ -81,7 +85,22 @@ public function getMenusForAppType($appType) return $this->buildMenus($menus); } - public function updateMenus($data) + public function getMenusByRouteForAppType($route, $appType) + { + $menus = []; + + foreach($this->menus as $menu) { + if ($menu['route'] === strtolower($route)) { + if ($menu['app_type'] === $appType) { + return $menu; + } + } + } + + return false; + } + + public function updateMenus(array $data) { $menus = $data['menus']; @@ -109,9 +128,9 @@ public function updateMenus($data) $this->init(true); } - public function addMenu($data) + public function addMenu(array $componentJsonFile) { - $menu = $data['menu']; + $menu = $componentJsonFile['menu']; if (isset($menu['seq'])) { $sequence = $menu['seq']; @@ -125,8 +144,8 @@ public function addMenu($data) $insertMenu = $this->add([ 'menu' => $this->helper->encode($menu), 'apps' => $this->helper->encode([]), - 'app_type' => $data['app_type'], - 'route' => $data['route'], + 'app_type' => $componentJsonFile['app_type'], + 'route' => $componentJsonFile['route'], 'sequence' => $sequence ] ); @@ -138,14 +157,17 @@ public function addMenu($data) } } - public function updateMenu($id, array $data) + public function updateMenu($id, array $componentJsonFile) { $menu = $this->getById($id); + if (is_string($menu['menu'])) { + $menu['menu'] = $this->helper->decode($menu['menu'], true); + } if ($menu) { - $menu = array_merge($menu, $data['menu']); + $menu = array_merge($menu['menu'], $componentJsonFile['menu']); } else { - $menu = $data['menu']; + $menu = $componentJsonFile['menu']; } if (isset($menu['seq'])) { @@ -161,8 +183,8 @@ public function updateMenu($id, array $data) 'id' => $id, 'menu' => $this->helper->encode($menu), 'apps' => $this->helper->encode([]), - 'app_type' => $data['app_type'], - 'route' => $data['route'], + 'app_type' => $componentJsonFile['app_type'], + 'route' => $componentJsonFile['route'], 'sequence' => $sequence ] ); From 891bca01c6fb49a666d1d2d866cfb2e288ab8108 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Sun, 9 Feb 2025 23:25:54 +1100 Subject: [PATCH 43/54] update issue #34. fix menu installer. --- .../Devtools/Test/TestComponent.php | 30 ++++++++++++------ .../ModulesServiceProvider/MenuInstaller.php | 31 +++++++++++++++++-- 2 files changed, 48 insertions(+), 13 deletions(-) diff --git a/apps/Core/Components/Devtools/Test/TestComponent.php b/apps/Core/Components/Devtools/Test/TestComponent.php index d638054b0..4a34c9334 100644 --- a/apps/Core/Components/Devtools/Test/TestComponent.php +++ b/apps/Core/Components/Devtools/Test/TestComponent.php @@ -7,20 +7,33 @@ class TestComponent extends BaseComponent { - protected $sourceDir = 'system/Base/Providers/BasepackagesServiceProvider/Packages/Geo/Data/'; - /** * @acl(name=view) */ public function viewAction() { - // var_dump($this->opCache->setCache('guru', ['guru'=>123], 'guru')); - // var_dump($this->opCache->getCache('guru', 'guru')); - // var_dump($this->opCache->removeCache()); + // $install = new \Apps\Fintech\Components\Dashboards\Install\Install; + + // $install->init()->install(); + // $adminComponents = $this->basepackages->utils->scanDir('apps/Core/Components/', true); - // $dicData = new DevtoolsDicExtractData; + // foreach ($adminComponents['files'] as $adminComponentKey => $adminComponent) { + // if (strpos($adminComponent, 'component.json')) { + // try { + // $jsonFile = + // $this->helper->decode( + // $this->localContent->read($adminComponent), + // true + // ); + // } catch (\throwable $e) { + // throw new \Exception($e->getMessage() . '. Problem reading component.json at location ' . $adminComponent); + // } - // $dicData->processDicData(); + // if ($jsonFile['menu'] && $jsonFile['menu'] !== 'false') { + // $this->basepackages->menus->addMenu($jsonFile); + // } + // } + // } } /** @@ -28,9 +41,6 @@ public function viewAction() */ public function apiViewAction() { - // usleep(50000); - // sleep(10); - // var_dump($_SESSION); $this->addResponse('Test', 0, ['connection' => $this->connection->getId(), 'session' => $this->session->getId()]); } diff --git a/system/Base/Providers/ModulesServiceProvider/MenuInstaller.php b/system/Base/Providers/ModulesServiceProvider/MenuInstaller.php index 68e0f7357..1dbdf239a 100644 --- a/system/Base/Providers/ModulesServiceProvider/MenuInstaller.php +++ b/system/Base/Providers/ModulesServiceProvider/MenuInstaller.php @@ -2,15 +2,40 @@ namespace System\Base\Providers\ModulesServiceProvider; +use League\Flysystem\FilesystemException; +use League\Flysystem\UnableToCheckExistence; +use League\Flysystem\UnableToReadFile; use System\Base\BasePackage; class MenuInstaller extends BasePackage { - public function installMenu(array $componentJsonFileArr) + public function installMenu($componentClass) { - $menu = $componentJsonFileArr['menu']; + try { + $file = 'apps/' . implode('/', array_slice(explode('\\', get_class($componentClass)), 1, -1)) . '/component.json'; + + if ($this->localContent->fileExists($file)) { + $installComponentJsonFile = $this->helper->decode($this->localContent->read($file), true); + + if (!isset($installComponentJsonFile['menu']) || + (isset($installComponentJsonFile['menu']) && (bool) $installComponentJsonFile['menu'] === false) + ) { + return true; + } + + $menu = $this->basepackages->menus->getMenusByRouteForAppType($installComponentJsonFile['route'], $installComponentJsonFile['app_type']); + + if ($menu) { + $this->basepackages->menus->updateMenu($menu['id'], $installComponentJsonFile); + } else { + $this->basepackages->menus->addMenu($installComponentJsonFile); + } + } + } catch (FilesystemException | UnableToCheckExistence | UnableToReadFile | \throwable $e) { + trace([$e]); + throw $e; + } - trace([$menu]); return true; } } \ No newline at end of file From 7364be1b25947ac5702461f3a22b59216ec18600 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Sun, 9 Feb 2025 23:41:13 +1100 Subject: [PATCH 44/54] update issue #600. Fix boolean normalization of data. --- .../Providers/DatabaseServiceProvider/Ff/Store.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php b/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php index 0600e3c23..971107a36 100644 --- a/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php +++ b/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php @@ -1576,8 +1576,17 @@ protected function normalizeData(array $data, $jsonToArray = false): array if ($type === 'boolean') { if (is_string($data[$propertyKey])) { - $data[$propertyKey] = $data[$propertyKey] === 'false' ? false : true; + if ($data[$propertyKey] === 'false' || + $data[$propertyKey] === '0' + ) { + $data[$propertyKey] = false; + } else if ($data[$propertyKey] === 'false' || + $data[$propertyKey] === '1' + ) { + $data[$propertyKey] = true; + } } + if (is_int($data[$propertyKey])) { $data[$propertyKey] = $data[$propertyKey] === 0 ? false : true; } From de855f4faad91e12b2d057b826e1ef8b1607f161 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Mon, 10 Feb 2025 12:34:18 +1100 Subject: [PATCH 45/54] Update issue #34, installer fix destination directory for different modules. Test app and fix views for new apps. --- apps/Core/Components/Apps/AppsComponent.php | 6 +-- .../ModulesServiceProvider/Installer.php | 41 +++++++++++++++---- .../ModulesServiceProvider/Modules/Views.php | 6 ++- .../ModulesServiceProvider/Queues.php | 3 ++ 4 files changed, 44 insertions(+), 12 deletions(-) diff --git a/apps/Core/Components/Apps/AppsComponent.php b/apps/Core/Components/Apps/AppsComponent.php index 9f5b74223..70378c4dc 100644 --- a/apps/Core/Components/Apps/AppsComponent.php +++ b/apps/Core/Components/Apps/AppsComponent.php @@ -189,7 +189,7 @@ public function viewAction() } //Views - $viewsArr = $this->modules->views->getViewsForAppType($app['app_type']); + $viewsArr = $this->modules->views->getViewsForAppType($app['app_type'], false); if (count($viewsArr) === 1) { array_push($mandatoryViews, $this->helper->first($viewsArr)['name']); @@ -346,7 +346,7 @@ public function addAction() { $this->requestIsPost(); - $viewsArr = $this->modules->views->getViewsForAppType($this->postData()['app_type']); + $viewsArr = $this->modules->views->getViewsForAppType($this->postData()['app_type'], false); if (count($viewsArr) === 0) { $this->addResponse('No Views Available for app type ' . $this->postData()['app_type'] . ' cannot proceed!', 1); @@ -520,7 +520,7 @@ public function getViewsForAppTypeAction() { $this->requestIsPost(); - $viewsArr = $this->modules->views->getViewsForAppType($this->postData()['app_type']); + $viewsArr = $this->modules->views->getViewsForAppType($this->postData()['app_type'], false); if ($viewsArr && count($viewsArr) > 0) { $views = []; diff --git a/system/Base/Providers/ModulesServiceProvider/Installer.php b/system/Base/Providers/ModulesServiceProvider/Installer.php index 6d60eb03e..9121493ad 100644 --- a/system/Base/Providers/ModulesServiceProvider/Installer.php +++ b/system/Base/Providers/ModulesServiceProvider/Installer.php @@ -933,15 +933,27 @@ protected function runRsync($args) ) { $destDir = ''; } else { - $name = $this->helper->last(explode('-', strtolower($this->helper->last(explode('/', $module['repo']))))); - - $destDir = 'apps/' . ucfirst($module['app_type']) . '/' . ucfirst($module['module_type']) . '/' . ucfirst($name) . '/'; - if ($module['module_type'] === 'apptype') { $destDir = 'apps/' . ucfirst($module['name']) . '/'; - } + } else if ($module['module_type'] === 'components') { + $destDir = 'apps/' . ucfirst($module['app_type']) . '/Components/'; + + $routeArr = explode('/', $module['route']); + + foreach ($routeArr as &$path) { + $path = ucfirst($path); + } + + $destDir .= implode('/', $routeArr) . '/'; + } else if ($module['module_type'] === 'middlewares') { + $destDir = 'apps/' . ucfirst($module['app_type']) . '/Middlewares/' . ucfirst($module['name']) . '/'; + } else if ($module['module_type'] === 'packages') { + $destDir = 'apps/' . ucfirst($module['app_type']) . '/Packages/'; + + $pathArr = preg_split('/(?=[A-Z])/', ucfirst($module['name']), -1, PREG_SPLIT_NO_EMPTY); - if ($module['module_type'] === 'views') { + $destDir .= implode('/', $pathArr) . '/'; + } else if ($module['module_type'] === 'views') { //for view check if the main view is installed before adding to queue. if (isset($module['is_public']) && $module['is_public'] == true @@ -951,11 +963,24 @@ protected function runRsync($args) $this->zipFile['name'] = $this->modulesToInstallOrUpdate['repo_details']['details']['name'] . '-public-' . $this->modulesToInstallOrUpdate['repo_details']['latestRelease']['name']; - } else if (isset($module['is_subview']) && $module['is_subview'] == true ) { - $destDir = 'apps/' . ucfirst($module['app_type']) . '/' . ucfirst($module['module_type']) . '/' . ucfirst($module['base_view_name']) . '/html/' . strtolower($module['name']) . '/'; + $destDir = 'apps/' . ucfirst($module['app_type']) . '/' . ucfirst($module['module_type']) . '/' . ucfirst($module['base_view_name']) . '/html/'; + + $pathArr = preg_split('/(?=[A-Z])/', ucfirst($module['name']), -1, PREG_SPLIT_NO_EMPTY); + + if (count($pathArr) > 1) { + foreach ($pathArr as &$path) { + $path = strtolower($path); + } + } else { + $pathArr[0] = strtolower($pathArr[0]); + } + + $destDir .= implode('/', $pathArr) . '/'; + } else { + $destDir = 'apps/' . ucfirst($module['app_type']) . '/Views/' . ucfirst($module['name']) . '/'; } } diff --git a/system/Base/Providers/ModulesServiceProvider/Modules/Views.php b/system/Base/Providers/ModulesServiceProvider/Modules/Views.php index 4956386bf..fb375db0b 100644 --- a/system/Base/Providers/ModulesServiceProvider/Modules/Views.php +++ b/system/Base/Providers/ModulesServiceProvider/Modules/Views.php @@ -406,12 +406,16 @@ public function getViewsForCategory($category) return $views; } - public function getViewsForAppType($appType) + public function getViewsForAppType($appType, $includeSubViews = true) { $views = []; foreach($this->views as $view) { if ($view['app_type'] === $appType) { + if ($view['is_subview'] && !$includeSubViews) { + continue; + } + $views[$view['id']] = $view; } } diff --git a/system/Base/Providers/ModulesServiceProvider/Queues.php b/system/Base/Providers/ModulesServiceProvider/Queues.php index 7d67ef22f..c0f0ba014 100644 --- a/system/Base/Providers/ModulesServiceProvider/Queues.php +++ b/system/Base/Providers/ModulesServiceProvider/Queues.php @@ -801,6 +801,9 @@ protected function addToQueueTasksAndResults($taskName, $moduleType, $module, $v $this->queueTasks[$taskName][$moduleType][$module['id']]['name'] = $module['name']; $this->queueTasks[$taskName][$moduleType][$module['id']]['display_name'] = $module['display_name'] ?? $module['name']; $this->queueTasks[$taskName][$moduleType][$module['id']]['module_type'] = $moduleType; + if ($moduleType === 'components') { + $this->queueTasks[$taskName][$moduleType][$module['id']]['route'] = $module['route']; + } if ($moduleType === 'views' && array_key_exists('is_subview', $module)) { $this->queueTasks[$taskName][$moduleType][$module['id']]['is_subview'] = $module['is_subview']; if ($module['is_subview']) { From 5b425a627b427aa25154139fd9893247eeedee03 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Mon, 10 Feb 2025 13:08:03 +1100 Subject: [PATCH 46/54] fix issue #601 --- apps/Core/Packages/Adminltetags/Tags/Fields/Files/Croppie.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/Core/Packages/Adminltetags/Tags/Fields/Files/Croppie.php b/apps/Core/Packages/Adminltetags/Tags/Fields/Files/Croppie.php index a45243f39..f8edb40e5 100644 --- a/apps/Core/Packages/Adminltetags/Tags/Fields/Files/Croppie.php +++ b/apps/Core/Packages/Adminltetags/Tags/Fields/Files/Croppie.php @@ -752,6 +752,7 @@ function uploadAvatar(avatarName) { formData.append("setOrphan", "' . $this->params['setOrphan'] . '"); formData.append("fileName", avatarName); formData.append("storagetype", "' . $this->params['storageType'] . '"); + formData.append($("#security-token").attr("name"), $("#security-token").val()); performUpload(formData); } @@ -892,7 +893,7 @@ function updateProfileThumbnail(remove = false) { } else { $("#profile-portrait").children("i").attr("hidden", true); $("#profile-portrait").children("img").attr("src", window.dataCollection.env.rootPath + window.dataCollection.env.appRoute + - "/system/storages/q/uuid/" + uploadUUIDs[0] + "/w/30"); + "/system/storages/q/uuid/" + uploadUUIDs[uploadUUIDs.length - 1] + "/w/30"); $("#profile-portrait").children("img").attr("hidden", false); window.dataCollection.env.profile.portrait = window.dataCollection.env.rootPath + window.dataCollection.env.appRoute + "/system/storages/q/uuid/" + uploadUUIDs[0] + "/w/80"; From c5bc03f14df818432da57f10805b0e835d839036 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Tue, 11 Feb 2025 03:21:10 +1100 Subject: [PATCH 47/54] Issue #602 Added ButtonGroup and moved dropdown from DropdownSplitButton to Dropdown so ButtonGroup can also call it. --- .../Tags/Buttons/ApplicationButton.php | 0 .../Adminltetags/Tags/Buttons/Button.php | 1 - .../Adminltetags/Tags/Buttons/ButtonGroup.php | 513 ++++++++++++++---- .../Adminltetags/Tags/Buttons/Dropdown.php | 115 ++++ .../Tags/Buttons/DropdownSplitButtons.php | 72 +-- apps/Core/Views/Default/html/auth/view.html | 20 +- .../Default/html/devtools/modules/select.html | 2 +- .../html/system/api/client/services/list.html | 2 +- .../Default/html/system/email/queue/list.html | 2 +- .../html/system/notifications/list.html | 2 +- .../Default/html/system/storages/list.html | 2 +- .../html/system/tools/importexport/list.html | 2 +- 12 files changed, 548 insertions(+), 185 deletions(-) create mode 100644 apps/Core/Packages/Adminltetags/Tags/Buttons/ApplicationButton.php create mode 100644 apps/Core/Packages/Adminltetags/Tags/Buttons/Dropdown.php diff --git a/apps/Core/Packages/Adminltetags/Tags/Buttons/ApplicationButton.php b/apps/Core/Packages/Adminltetags/Tags/Buttons/ApplicationButton.php new file mode 100644 index 000000000..e69de29bb diff --git a/apps/Core/Packages/Adminltetags/Tags/Buttons/Button.php b/apps/Core/Packages/Adminltetags/Tags/Buttons/Button.php index dc347cb12..d11fbdc08 100644 --- a/apps/Core/Packages/Adminltetags/Tags/Buttons/Button.php +++ b/apps/Core/Packages/Adminltetags/Tags/Buttons/Button.php @@ -62,7 +62,6 @@ protected function buildButtonParamsArr() // } foreach ($buttons as $buttonKey => $button) { - if (isset($button['title'])) { if ($button['title'] === false) { $this->buttonParams['title'] = ''; diff --git a/apps/Core/Packages/Adminltetags/Tags/Buttons/ButtonGroup.php b/apps/Core/Packages/Adminltetags/Tags/Buttons/ButtonGroup.php index 016c6296a..3bca686cf 100644 --- a/apps/Core/Packages/Adminltetags/Tags/Buttons/ButtonGroup.php +++ b/apps/Core/Packages/Adminltetags/Tags/Buttons/ButtonGroup.php @@ -37,6 +37,10 @@ public function __construct($view, $tag, $links, $escaper, $params, $buttonParam $this->params = $params; $this->buttonParams = $buttonParams; + + $this->buildButtonParamsArr(); + + $this->buildButton(); } public function getContent() @@ -44,114 +48,403 @@ public function getContent() return $this->content; } -// {# Radio Button Group #} -// {% elseif buttonType == 'button-radio-group' %} -// {% if buttonLabel %} -// -// {% endif %} -// {% if buttons %} -// {% if buttonBlock == true %} -// {% set hasButtonBlock = 'btn-block' %} -// {% endif %} -// {% if buttonPosition %} -// {% set hasButtonPosition = 'float-' ~ buttonPosition %} -// {% else %} -// {% set hasButtonPosition = '' %} -// {% endif %} -//
-// {% for buttonKey, button in buttons %} -// {% if not button.title == false %} -// {% if button.title %} -// {% set hasButtonTitle = button.title %} -// {% else %} -// {% set hasButtonTitle = ' missing_button_title' %} -// {% endif %} -// {% elseif button.title == false %} -// {% set hasButtonTitle = '' %} -// {% endif %} -// {% if button.size %} -// {% set hasButtonSize = 'btn-' ~ button.size %} -// {% else %} -// {% set hasButtonSize = 'btn-sm' %} -// {% endif %} -// {% if button.flat == true %} -// {% set hasButtonFlat = 'btn-flat' %} -// {% endif %} -// {% if button.type %} -// {% set hasButtonType = 'btn-' ~ button.type %} -// {% else %} -// {% set hasButtonType = 'btn-primary' %} -// {% endif %} -// {% if button.style == 'outline' %} -// {% set hasButtonType = 'btn-outline-' ~ button.type %} -// {% elseif button.style == 'gradient' %} -// {% set hasButtonType = 'bg-gradient-' ~ button.type %} -// {% endif %} -// {% if button.icon %} -// {% if button.title %} -// {% if button.iconPosition == 'after' %} -// {% set hasButtonIcon = '' %} -// {% else %} -// {% set hasButtonIcon = '' %} -// {% endif %} -// {% else %} -// {% set hasButtonIcon = '' %} -// {% endif %} -// {% else %} -// {% set hasButtonIcon = '' %} -// {% endif %} -// {% if fieldRadioButtonGroupButtonChecked %} -// {% if fieldRadioButtonGroupButtonChecked == button.dataValue %} -// {% set hasButtonChecked = 'checked' %} -// {% set hasButtonCheckedClasses = 'active focus' %} -// {% set hasButtonCheckedBgClass = 'bg-' ~ button.type %} -// {% else %} -// {% set hasButtonChecked = '' %} -// {% set hasButtonCheckedClasses = '' %} -// {% set hasButtonCheckedBgClass = '' %} -// {% endif %} -// {% else %} -// {% if button.checked %} -// {% set hasButtonChecked = 'checked' %} -// {% set hasButtonCheckedClasses = 'active focus' %} -// {% else %} -// {% set hasButtonChecked = '' %} -// {% set hasButtonCheckedClasses = '' %} -// {% endif %} -// {% endif %} -// {% if button.hidden == true %} -// {% set hasButtonHidden = 'hidden' %} -// {% else %} -// {% set hasButtonHidden = '' %} -// {% endif %} -// {% if button.disabled == true %} -// {% set hasButtonDisabled = 'disabled' %} -// {% set hasButtonCursor = 'style=cursor:default;' %} -// {% else %} -// {% set hasButtonDisabled = '' %} -// {% set hasButtonCursor = 'style=cursor:pointer;' %} -// {% endif %} -// {% if componentId and sectionId %} -// {% set hasButtonId = componentId ~ '-' ~ sectionId ~ '-' ~ buttonKey %} -// {% else %} -// {% set hasButtonId = buttonKey %} -// {% endif %} -// -// {% endfor %} -//
-// {% else %} -// {{('TEMPLATE ERROR: buttons (ARRAY) MISSING')}} -// {% endif %} -// {# button-group #} + protected function buildButtonParamsArr() + { + if (isset($this->params['buttons'])) { + $buttons = $this->params['buttons']; + } else { + $this->content .= 'Error: buttons (array) missing'; + return; + } + + // groupButtonType : horizontal, vertical, radio + $this->buttonParams['groupButtonType'] = 'btn-group'; + if (isset($this->params['groupButtonType'])) { + if ($this->params['groupButtonType'] === 'vertical') { + $this->buttonParams['groupButtonType'] = 'btn-group-vertical'; + } + } + + $this->buttonParams['groupButtonSize'] = + isset($this->params['groupButtonSize']) ? + $this->params['groupButtonSize'] : + 'md'; + + $this->buttonParams['groupButtonFlat'] = + isset($this->params['groupButtonFlat']) && $this->params['groupButtonFlat'] === true ? + 'btn-flat' : + ''; + + $this->buttonParams['groupButtonBlock'] = + isset($this->params['groupButtonBlock']) && $this->params['groupButtonBlock'] === true ? + 'btn-block' : + ''; + + $this->buttonParams['groupButtonPosition'] = + isset($this->params['groupButtonPosition']) ? + 'float-' . $this->params['groupButtonPosition'] : + ''; + } + + protected function buildButton() + { + if ($this->params['groupButtonType'] === 'radio') { + $this->buttonParams['groupButtonType'] = 'btn-group btn-group-toggle'; + + $this->content .= '
'; + foreach ($this->params['buttons'] as $buttonKey => $button) { + + $this->params['groupRadioButtonType'] = 'primary'; + if (isset($button['type'])) { + $this->params['groupRadioButtonType'] = $button['type']; + } + $this->buttonParams['groupRadioButtonType'] = 'bg-' . $this->params['groupRadioButtonType']; + + if (isset($this->params['groupRadioButtonStyle'])) { + if ($this->params['groupRadioButtonStyle'] === 'outline') { + $this->buttonParams['groupRadioButtonType'] = 'btn-outline-' . $this->params['groupRadioButtonType']; + } else if ($this->params['groupRadioButtonStyle'] === 'gradient') { + $this->buttonParams['groupRadioButtonType'] = 'bg-gradient-' . $this->params['groupRadioButtonType']; + } + } + + if (array_key_exists('title', $button) && $button['title'] !== false) { + $hasButtonTitle = $button['title']; + + if ($button['title'] === false) { + $hasButtonTitle = ''; + } + } else { + $hasButtonTitle = 'missing_button_title'; + } + + if (isset($button['icon'])) { + if (isset($button['title'])) { + if (isset($button['iconPosition']) && $button['iconPosition'] === 'after') { + $hasButtonIcon = ''; + } else { + $hasButtonIcon = ''; + } + } else { + $hasButtonIcon = ''; + } + } else { + $hasButtonIcon = ''; + } + + if (isset($this->params['groupRadioButtonChecked'])) { + if ($this->params['groupRadioButtonChecked'] === $button['dataValue']) { + $hasButtonChecked = 'checked'; + $hasButtonCheckedClasses = 'active focus'; + $hasButtonCheckedBgClass = 'bg-' . $button['groupRadioButtonType']; + } else { + $hasButtonChecked = ''; + $hasButtonCheckedClasses = ''; + $hasButtonCheckedBgClass = ''; + } + } else { + if (isset($button['checked']) && $button['checked'] === true) { + $hasButtonChecked = 'checked'; + $hasButtonCheckedClasses = 'active focus'; + $hasButtonCheckedBgClass = 'bg-' . $button['groupRadioButtonType']; + } else { + $hasButtonChecked = ''; + $hasButtonCheckedClasses = ''; + $hasButtonCheckedBgClass = ''; + } + } + + if (isset($buton['disabled']) && $buton['disabled'] === true) { + $hasButtonDisabled = 'disabled'; + $hasButtonCursor = 'style=cursor:default;'; + } else { + $hasButtonDisabled = ''; + $hasButtonCursor = 'style=cursor:pointer;'; + } + if (isset($this->params['componentId']) && isset($this->params['sectionId'])) { + $hasButtonId = $this->params['componentId'] . '-' . $this->params['sectionId'] . '-' . $buttonKey; + } else { + $hasButtonId = $buttonKey; + } + + $hasButtonAdditionalClass = ''; + if (isset($button['buttonAdditionalClass'])) { + $hasButtonAdditionalClass = $button['buttonAdditionalClass']; + } + + $this->content .= + ''; + } + } else { + $this->content .= '
'; + + foreach ($this->params['buttons'] as $buttonKey => $button) { + if (isset($button['dropdowns'])) { + if (isset($button['dropdownHover']) && $button['dropdownHover'] === true) { + $button['dropdownHover'] = 'dropdown-hover'; + } else { + $button['dropdownHover'] = ''; + } + + $button['dropdownDirection'] = + isset($button['dropdownDirection']) ? + $button['dropdownDirection'] : + '';//either dropup or '' + + $button['dropdownButtonType'] = + isset($button['dropdownButtonType']) ? + $button['dropdownButtonType'] : + 'primary'; + + $this->content .= '
'; + $this->content .= ''; + + $params = $this->params; + $params['buttonType'] = 'Dropdown'; + $params['dropdowns'] = $button['dropdowns']; + + $this->content .= $this->adminLTETags->useTag('buttons', $params); + + $this->content .= '
'; + } else { + if (isset($button['title'])) { + if ($button['title'] === false) { + $this->buttonParams['title'] = ''; + } else { + $this->buttonParams['title'] = $button['title']; + } + } else { + $this->buttonParams['title'] = 'Missing Button Title'; + } + + if (isset($button['icon']) && isset($button['title'])) { + if (isset($button['iconHidden']) && $button['iconHidden'] === true) { + $iconHidden = 'hidden'; + } else { + $iconHidden = ''; + } + if (isset($button['iconPosition']) && $button['iconPosition'] === 'after') { + $this->buttonParams['icon'] = + ''; + $this->buttonParams['iconPosition'] = 'after'; + } else { + $this->buttonParams['icon'] = + ''; + $this->buttonParams['iconPosition'] = ''; + } + } else { + $this->buttonParams['icon'] = ''; + $this->buttonParams['iconPosition'] = ''; + } + + if (isset($button['buttonId'])) { + $this->buttonParams['id'] = $button['buttonId']; + } else if (isset($this->params['componentId']) && isset($this->params['sectionId'])) { + $this->buttonParams['id'] = + $this->params['componentId'] . '-' . $this->params['sectionId'] . '-' . $buttonKey; + } else { + $this->buttonParams['id'] = $buttonKey; + } + + $this->buttonParams['url'] = + isset($button['url']) ? + $button['url'] : + ''; + + $this->buttonParams['hidden'] = + isset($button['hidden']) && $button['hidden'] === true ? + 'hidden' : + ''; + + if ($this->buttonParams['url'] === '') { + $this->buttonParams['disabled'] = + isset($button['disabled']) && $button['disabled'] === true ? + 'disabled' : + ''; + } else { + $this->buttonParams['disabled'] = ''; + if (isset($button['disabled']) && $button['disabled'] === true) { + if (isset($button['buttonAdditionalClass'])) { + $button['buttonAdditionalClass'] = $button['buttonAdditionalClass'] . ' disabled'; + } else { + $button['buttonAdditionalClass'] = 'disabled'; + } + } + } + + $this->buttonParams['additionalClass'] = + isset($button['buttonAdditionalClass']) ? + $button['buttonAdditionalClass'] : + ''; + + $this->buttonParams['tooltipPosition'] = + isset($button['tooltipPosition']) ? + $button['tooltipPosition'] : + 'auto'; + + $this->buttonParams['tooltipTitle'] = + isset($button['tooltipTitle']) ? + $button['tooltipTitle'] : + ''; + + if ($this->buttonParams['url'] !== '') { + $this->content .= + 'content .= + ''; + } + } + } + } + + $this->content .= '
'; + } +// Example: +//{{adminltetags.useTag('buttons', +// [ +// 'componentId' : 'core', +// 'sectionId' : 'main', +// 'buttonType' : 'ButtonGroup', +// 'groupButtonType' : 'horizontal', +// 'groupButtonSize' : 'btn-xs', +// 'groupButtonFlat' : false, +// 'groupButtonPosition' : 'left', +// 'buttons' : +// { +// 'apps-dropdowns' : +// { +// 'dropdowns' : +// { +// 'apptypes' : { +// 'title' : 'App Type', +// 'type' : 'primary', +// 'additionalClass' : 'contentAjaxLink', +// 'url' : '' +// }, +// } +// }, +// 'add-widgets' : { +// 'title' : 'Add Widgets', +// 'size' : 'xs', +// 'type' : 'primary', +// 'position' : 'right', +// 'icon' : 'plus' +// }, +// 'save-widgets' : { +// 'title' : 'Save', +// 'size' : 'xs', +// 'type' : 'primary', +// 'position' : 'right', +// 'icon' : 'save' +// }, +// 'divider-dropdowns' : +// { +// 'dropdowns' : +// { +// 'subviews' : { +// 'title' : 'Sub View', +// 'type' : 'primary', +// 'additionalClass' : 'contentAjaxLink', +// 'url' : '' +// }, +// 'divider' : 'divider', +// 'bundles' : { +// 'title' : 'Modules Bundle', +// 'type' : 'primary', +// 'additionalClass' : 'contentAjaxLink', +// 'url' : '' +// } +// } +// } +// } +// ] +// )}} +// radio +// {{adminltetags.useTag('buttons', +// [ +// 'componentId' : 'core', +// 'sectionId' : 'main', +// 'buttonType' : 'ButtonGroup', +// 'groupButtonType' : 'radio', +// 'groupButtonSize' : 'sm', +// 'groupButtonFlat' : false, +// 'groupButtonPosition' : 'left', +// 'groupRadioButtonStyle' : 'outline', +// 'buttons' : +// { +// 'add-widgets' : { +// 'title' : 'Add Widgets', +// 'icon' : 'plus', +// 'type' : 'success', +// 'value' : 'add' +// }, +// 'edit-widgets' : { +// 'title' : 'Edit Widgets', +// 'icon' : 'edit', +// 'type' : 'danger', +// 'value' : 'edit', +// 'disabled' : true +// }, +// 'save-widgets' : { +// 'title' : 'Save', +// 'type' : 'info', +// 'value' : 'save', +// 'icon' : 'save' +// } +// } +// ] +// )}} } \ No newline at end of file diff --git a/apps/Core/Packages/Adminltetags/Tags/Buttons/Dropdown.php b/apps/Core/Packages/Adminltetags/Tags/Buttons/Dropdown.php new file mode 100644 index 000000000..062b22638 --- /dev/null +++ b/apps/Core/Packages/Adminltetags/Tags/Buttons/Dropdown.php @@ -0,0 +1,115 @@ +view = $view; + + $this->tag = $tag; + + $this->links = $links; + + $this->escaper = $escaper; + + $this->adminLTETags = new Adminltetags(); + + $this->params = $params; + + $this->buttonParams = $buttonParams; + + $this->buildDropdownParamsArr(); + } + + public function getContent() + { + return $this->content; + } + + protected function buildDropdownParamsArr() + { + if (!isset($this->params['dropdowns'])) { + $this->content .= 'Error: dropdowns (array) missing'; + + return; + } + + $this->buttonParams['dropdownAlign'] = + isset($this->params['dropdownAlign']) && $this->params['dropdownAlign'] === 'right' ? + 'dropdown-menu-right' : + ''; + + $this->buildDropdown(); + } + + protected function buildDropdown() + { + $this->content .= + ''; + } +} \ No newline at end of file diff --git a/apps/Core/Packages/Adminltetags/Tags/Buttons/DropdownSplitButtons.php b/apps/Core/Packages/Adminltetags/Tags/Buttons/DropdownSplitButtons.php index 8f78fc87c..8b9e09a2a 100644 --- a/apps/Core/Packages/Adminltetags/Tags/Buttons/DropdownSplitButtons.php +++ b/apps/Core/Packages/Adminltetags/Tags/Buttons/DropdownSplitButtons.php @@ -39,8 +39,6 @@ public function __construct($view, $tag, $links, $escaper, $params, $buttonParam $this->buttonParams = $buttonParams; $this->buildButtonParamsArr(); - - $this->buildButton(); } public function getContent() @@ -50,10 +48,9 @@ public function getContent() protected function buildButtonParamsArr() { - if (isset($this->params['buttons'])) { - $buttons = $this->params['buttons']; - } else { - $this->content .= 'Error: buttons (array) missing'; + if (!isset($this->params['dropdowns'])) { + $this->content .= 'Error: dropdowns (array) missing'; + return; } @@ -78,17 +75,17 @@ protected function buildButtonParamsArr() //Whole Dropdown $this->buttonParams['dropdownHover'] = - isset($this->params['dropdownHover']) ? + (isset($this->params['dropdownHover']) && $this->params['dropdownHover'] === true) ? 'dropdown-hover' : ''; $this->buttonParams['dropdownDirection'] = isset($this->params['dropdownDirection']) ? - 'dropup' : - ''; + $this->params['dropdownDirection'] : + '';//either '' or 'dropup' $this->buttonParams['dropdownAlign'] = - isset($this->params['dropdownAlign']) && $this->params['dropdownAlign'] === 'right' ? + (isset($this->params['dropdownAlign']) && $this->params['dropdownAlign'] === 'right') ? 'dropdown-menu-right' : ''; @@ -98,6 +95,8 @@ protected function buildButtonParamsArr() } else { $this->buildButtonParamsArrSplit(); } + + $this->buildButton(); } protected function buildButtonParamsArrNoSplit() @@ -255,7 +254,7 @@ protected function buildButtonParamsArrSplit() protected function buildButton() { $this->content .= - '
'; + '
'; if (!$this->buttonParams['dropdownSplitButtonsSplit']) { $this->content .= @@ -325,53 +324,10 @@ protected function buildButton() '>Toggle Dropdown'; } - $this->content .= - '
'; + $this->content .= '
'; } } \ No newline at end of file diff --git a/apps/Core/Views/Default/html/auth/view.html b/apps/Core/Views/Default/html/auth/view.html index 4b7878d20..0d82f883f 100644 --- a/apps/Core/Views/Default/html/auth/view.html +++ b/apps/Core/Views/Default/html/auth/view.html @@ -20,17 +20,17 @@
{{adminltetags.useTag('fields', - [ - 'componentId' : componentId, - 'sectionId' : 'form', - 'fieldId' : 'user', - 'fieldLabel' : false, - 'fieldType' : 'input', - 'fieldInputType' : 'text', - 'fieldPlaceholder' : 'Username', - 'fieldGroupPostAddonIcon' : 'user' + [ + 'componentId' : componentId, + 'sectionId' : 'form', + 'fieldId' : 'user', + 'fieldLabel' : false, + 'fieldType' : 'input', + 'fieldInputType' : 'text', + 'fieldPlaceholder' : 'Username', + 'fieldGroupPostAddonIcon' : 'user' ] - )}} + )}}
diff --git a/apps/Core/Views/Default/html/devtools/modules/select.html b/apps/Core/Views/Default/html/devtools/modules/select.html index 8d7dfb0f1..6fbb4c888 100644 --- a/apps/Core/Views/Default/html/devtools/modules/select.html +++ b/apps/Core/Views/Default/html/devtools/modules/select.html @@ -51,7 +51,7 @@ 'dropdownButtonAdditionalClass' : 'text-uppercase', 'dropdownAlign' : 'right', 'buttonPosition' : 'right', - 'buttons' : + 'dropdowns' : { 'apptypes' : { 'title' : 'App Type', diff --git a/apps/Core/Views/Default/html/system/api/client/services/list.html b/apps/Core/Views/Default/html/system/api/client/services/list.html index 2044c1cb6..99ff46b84 100644 --- a/apps/Core/Views/Default/html/system/api/client/services/list.html +++ b/apps/Core/Views/Default/html/system/api/client/services/list.html @@ -52,7 +52,7 @@ 'dropdownButtonAdditionalClass' : 'text-uppercase', 'buttonPosition' : 'right', 'dropdownAlign' : 'right', - 'buttons' : apiButtons + 'dropdowns' : apiButtons }, 'dtTable' : table, 'dtColumns' : table['columns'], diff --git a/apps/Core/Views/Default/html/system/email/queue/list.html b/apps/Core/Views/Default/html/system/email/queue/list.html index b575dd87d..8ece19316 100644 --- a/apps/Core/Views/Default/html/system/email/queue/list.html +++ b/apps/Core/Views/Default/html/system/email/queue/list.html @@ -29,7 +29,7 @@ 'dropdownButtonAdditionalClass' : 'text-uppercase', 'buttonPosition' : 'right', 'dropdownAlign' : 'right', - 'buttons' : + 'dropdowns' : { 'process-high' : { 'title' : 'High Priority', diff --git a/apps/Core/Views/Default/html/system/notifications/list.html b/apps/Core/Views/Default/html/system/notifications/list.html index 1d46dcfbe..48fc78d61 100644 --- a/apps/Core/Views/Default/html/system/notifications/list.html +++ b/apps/Core/Views/Default/html/system/notifications/list.html @@ -60,7 +60,7 @@ 'dropdownButtonDisabled' : true, 'buttonPosition' : 'right', 'dropdownAlign' : 'right', - 'buttons' : + 'dropdowns' : { 'mark-read' : { 'title' : 'Read', diff --git a/apps/Core/Views/Default/html/system/storages/list.html b/apps/Core/Views/Default/html/system/storages/list.html index af667a542..7dace9692 100644 --- a/apps/Core/Views/Default/html/system/storages/list.html +++ b/apps/Core/Views/Default/html/system/storages/list.html @@ -26,7 +26,7 @@ 'dropdownButtonAdditionalClass' : 'text-uppercase', 'buttonPosition' : 'right', 'dropdownAlign' : 'right', - 'buttons' : + 'dropdowns' : { 'local-storage' : { 'title' : 'Local Storage', diff --git a/apps/Core/Views/Default/html/system/tools/importexport/list.html b/apps/Core/Views/Default/html/system/tools/importexport/list.html index 9d98c71a2..5f84ce938 100644 --- a/apps/Core/Views/Default/html/system/tools/importexport/list.html +++ b/apps/Core/Views/Default/html/system/tools/importexport/list.html @@ -29,7 +29,7 @@ 'dropdownButtonAdditionalClass' : 'text-uppercase', 'buttonPosition' : 'right', 'dropdownAlign' : 'right', - 'buttons' : + 'dropdowns' : { 'import' : { 'title' : 'Import', From dd8def38b784198a822ee5266a75143308dcbd91 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Tue, 11 Feb 2025 03:41:09 +1100 Subject: [PATCH 48/54] issuet #602 - fix minor bugs. --- .../Adminltetags/Tags/Buttons/ButtonGroup.php | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/apps/Core/Packages/Adminltetags/Tags/Buttons/ButtonGroup.php b/apps/Core/Packages/Adminltetags/Tags/Buttons/ButtonGroup.php index 3bca686cf..91593ac2f 100644 --- a/apps/Core/Packages/Adminltetags/Tags/Buttons/ButtonGroup.php +++ b/apps/Core/Packages/Adminltetags/Tags/Buttons/ButtonGroup.php @@ -39,8 +39,6 @@ public function __construct($view, $tag, $links, $escaper, $params, $buttonParam $this->buttonParams = $buttonParams; $this->buildButtonParamsArr(); - - $this->buildButton(); } public function getContent() @@ -54,6 +52,13 @@ protected function buildButtonParamsArr() $buttons = $this->params['buttons']; } else { $this->content .= 'Error: buttons (array) missing'; + + return; + } + + if (!isset($this->params['buttonId'])) { + $this->content .= 'Error: buttonId missing'; + return; } @@ -84,6 +89,8 @@ protected function buildButtonParamsArr() isset($this->params['groupButtonPosition']) ? 'float-' . $this->params['groupButtonPosition'] : ''; + + $this->buildButton(); } protected function buildButton() @@ -161,10 +168,12 @@ protected function buildButton() $hasButtonDisabled = ''; $hasButtonCursor = 'style=cursor:pointer;'; } - if (isset($this->params['componentId']) && isset($this->params['sectionId'])) { - $hasButtonId = $this->params['componentId'] . '-' . $this->params['sectionId'] . '-' . $buttonKey; - } else { - $hasButtonId = $buttonKey; + + $hasButtonValue = $buttonKey; + $hasButtonId = $buttonKey; + if (isset($button['value'])) { + $hasButtonValue = $button['value']; + $hasButtonId = $button['value']; } $hasButtonAdditionalClass = ''; @@ -172,9 +181,18 @@ protected function buildButton() $hasButtonAdditionalClass = $button['buttonAdditionalClass']; } + if (isset($this->params['buttonId'])) { + $hasButtonName = $this->params['buttonId']; + } else if (isset($this->params['componentId']) && isset($this->params['sectionId'])) { + $hasButtonName = + $this->params['componentId'] . '-' . $this->params['sectionId'] . '-' . $buttonKey; + } else { + $hasButtonName = $buttonKey; + } + $this->content .= '
'; } -// Example: -//{{adminltetags.useTag('buttons', -// [ -// 'componentId' : 'core', -// 'sectionId' : 'main', -// 'buttonType' : 'ButtonGroup', -// 'buttonId' : 'guru', -// 'groupButtonType' : 'horizontal', -// 'groupButtonSize' : 'btn-xs', -// 'groupButtonFlat' : false, -// 'groupButtonPosition' : 'left', -// 'buttons' : -// { -// 'apps-dropdowns' : -// { -// 'dropdowns' : -// { -// 'apptypes' : { -// 'title' : 'App Type', -// 'type' : 'primary', -// 'additionalClass' : 'contentAjaxLink', -// 'url' : '' -// }, -// } -// }, -// 'add-widgets' : { -// 'title' : 'Add Widgets', -// 'size' : 'xs', -// 'type' : 'primary', -// 'position' : 'right', -// 'icon' : 'plus' -// }, -// 'save-widgets' : { -// 'title' : 'Save', -// 'size' : 'xs', -// 'type' : 'primary', -// 'position' : 'right', -// 'icon' : 'save' -// }, -// 'divider-dropdowns' : -// { -// 'dropdowns' : -// { -// 'subviews' : { -// 'title' : 'Sub View', -// 'type' : 'primary', -// 'additionalClass' : 'contentAjaxLink', -// 'url' : '' -// }, -// 'divider' : 'divider', -// 'bundles' : { -// 'title' : 'Modules Bundle', -// 'type' : 'primary', -// 'additionalClass' : 'contentAjaxLink', -// 'url' : '' -// } -// } -// } -// } -// ] -// )}} -// radio -// {{adminltetags.useTag('buttons', -// [ -// 'componentId' : 'core', -// 'sectionId' : 'main', -// 'buttonType' : 'ButtonGroup', -// 'buttonId' : 'guru', -// 'groupButtonType' : 'radio', -// 'groupButtonSize' : 'sm', -// 'groupButtonFlat' : false, -// 'groupButtonPosition' : 'left', -// 'groupRadioButtonStyle' : 'outline', -// 'buttons' : -// { -// 'add-widgets' : { -// 'title' : 'Add Widgets', -// 'icon' : 'plus', -// 'type' : 'success', -// 'value' : 'add' -// }, -// 'edit-widgets' : { -// 'title' : 'Edit Widgets', -// 'icon' : 'edit', -// 'type' : 'danger', -// 'value' : 'edit', -// 'disabled' : true -// }, -// 'save-widgets' : { -// 'title' : 'Save', -// 'type' : 'info', -// 'value' : 'save', -// 'icon' : 'save' -// } -// } -// ] -// )}} -// To get checked data from js $("input[type='radio'][name='guru']:checked").data('value'); } \ No newline at end of file From bf840b61c33f69efb0150b00f71ceab6d7068559 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Tue, 11 Feb 2025 04:10:09 +1100 Subject: [PATCH 50/54] issue #602 - add ApplicationButton --- .../Tags/Buttons/ApplicationButton.php | 183 ++++++++++++++++++ 1 file changed, 183 insertions(+) diff --git a/apps/Core/Packages/Adminltetags/Tags/Buttons/ApplicationButton.php b/apps/Core/Packages/Adminltetags/Tags/Buttons/ApplicationButton.php index e69de29bb..4ba5498dd 100644 --- a/apps/Core/Packages/Adminltetags/Tags/Buttons/ApplicationButton.php +++ b/apps/Core/Packages/Adminltetags/Tags/Buttons/ApplicationButton.php @@ -0,0 +1,183 @@ +view = $view; + + $this->tag = $tag; + + $this->links = $links; + + $this->escaper = $escaper; + + $this->adminLTETags = new Adminltetags(); + + $this->params = $params; + + $this->buttonParams = $buttonParams; + + $this->buildButtonParamsArr(); + } + + public function getContent() + { + return $this->content; + } + + protected function buildButtonParamsArr() + { + if (isset($this->params['buttons'])) { + $buttons = $this->params['buttons']; + } else { + $this->content .= 'Error: buttons (array) missing'; + + return; + } + + if (!isset($this->params['buttonId'])) { + $this->content .= 'Error: buttonId missing'; + + return; + } + + foreach ($this->params['buttons'] as $buttonKey => $button) { + if (isset($button['title'])) { + if ($button['title'] === false) { + $this->buttonParams['title'] = ''; + } else { + $this->buttonParams['title'] = '' . $button['title'] . ''; + } + } else { + $this->buttonParams['title'] = 'Missing Button Title'; + } + + $this->buttonParams['position'] = + isset($button['position']) ? + 'float-' . $button['position'] : + ''; + + $this->buttonParams['flat'] = + isset($button['flat']) && $button['flat'] === true ? + 'btn-flat' : + ''; + + $this->buttonParams['type'] = + isset($button['type']) ? + 'bg-' . $button['type'] : + 'bg-primary'; + + if (isset($button['buttonId'])) { + $this->buttonParams['id'] = $button['buttonId']; + } else if (isset($this->params['componentId']) && isset($this->params['sectionId'])) { + $this->buttonParams['id'] = + $this->params['componentId'] . '-' . $this->params['sectionId'] . '-' . $buttonKey; + } else { + $this->buttonParams['id'] = $buttonKey; + } + + $this->buttonParams['url'] = + isset($button['url']) ? + $button['url'] : + ''; + + $this->buttonParams['hidden'] = + isset($button['hidden']) && $button['hidden'] === true ? + 'hidden' : + ''; + + if ($this->buttonParams['url'] === '') { + $this->buttonParams['disabled'] = + isset($button['disabled']) && $button['disabled'] === true ? + 'disabled' : + ''; + } else { + $this->buttonParams['disabled'] = ''; + if (isset($button['disabled']) && $button['disabled'] === true) { + if (isset($button['buttonAdditionalClass'])) { + $button['buttonAdditionalClass'] = $button['buttonAdditionalClass'] . ' disabled'; + } else { + $button['buttonAdditionalClass'] = 'disabled'; + } + } + } + + if (isset($button['icon'])) { + if (isset($button['iconHidden']) && $button['iconHidden'] === true) { + $iconHidden = 'hidden'; + } else { + $iconHidden = ''; + } + $this->buttonParams['icon'] = ''; + } else { + $this->buttonParams['icon'] = ''; + } + + $this->buttonParams['additionalClass'] = + isset($button['buttonAdditionalClass']) ? + $button['buttonAdditionalClass'] : + ''; + + $this->buttonParams['tooltipPosition'] = + isset($button['tooltipPosition']) ? + $button['tooltipPosition'] : + 'auto'; + + $this->buttonParams['tooltipTitle'] = + isset($button['tooltipTitle']) ? + $button['tooltipTitle'] : + ''; + + $this->buttonParams['badge'] = ''; + if (isset($button['badge'])) { + $this->buttonParams['badge'] = ''; + if (isset($button['badgeContent'])) { + $this->buttonParams['badge'] .= $button['badgeContent']; + } + $this->buttonParams['badge'] .= ''; + } + + $this->buildButton(); + } + } + + protected function buildButton() + { + $this->content .= + 'buttonParams['disabled'] . ' ' . + $this->buttonParams['hidden'] . '>' . + $this->buttonParams['badge'] . + $this->buttonParams['icon'] . + $this->buttonParams['title'] . + ''; + } +} \ No newline at end of file From 80090df21ab7a49d7829791cebafaa1f13a139f1 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Wed, 12 Feb 2025 00:52:01 +1100 Subject: [PATCH 51/54] Update issue #602 fix minor bugs with outline style --- .../Adminltetags/Tags/Buttons/ButtonGroup.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/apps/Core/Packages/Adminltetags/Tags/Buttons/ButtonGroup.php b/apps/Core/Packages/Adminltetags/Tags/Buttons/ButtonGroup.php index b94b0909d..facb3228d 100644 --- a/apps/Core/Packages/Adminltetags/Tags/Buttons/ButtonGroup.php +++ b/apps/Core/Packages/Adminltetags/Tags/Buttons/ButtonGroup.php @@ -143,7 +143,11 @@ protected function buildButton() if ($this->params['groupRadioButtonChecked'] === $button['dataValue']) { $hasButtonChecked = 'checked'; $hasButtonCheckedClasses = 'active focus'; - $hasButtonCheckedBgClass = 'bg-' . $button['groupRadioButtonType']; + if ($this->params['groupRadioButtonStyle'] === 'outline') { + $hasButtonCheckedBgClass = ''; + } else { + $hasButtonCheckedBgClass = 'bg-' . $button['type']; + } } else { $hasButtonChecked = ''; $hasButtonCheckedClasses = ''; @@ -153,7 +157,11 @@ protected function buildButton() if (isset($button['checked']) && $button['checked'] === true) { $hasButtonChecked = 'checked'; $hasButtonCheckedClasses = 'active focus'; - $hasButtonCheckedBgClass = 'bg-' . $button['groupRadioButtonType']; + if ($this->params['groupRadioButtonStyle'] === 'outline') { + $hasButtonCheckedBgClass = ''; + } else { + $hasButtonCheckedBgClass = 'bg-' . $button['type']; + } } else { $hasButtonChecked = ''; $hasButtonCheckedClasses = ''; From 48f55c82c86ac77c6fa29945f1a0773b7c1cf24e Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Wed, 12 Feb 2025 00:54:58 +1100 Subject: [PATCH 52/54] update issue #602 fix minor bug with data value --- apps/Core/Packages/Adminltetags/Tags/Buttons/ButtonGroup.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/Core/Packages/Adminltetags/Tags/Buttons/ButtonGroup.php b/apps/Core/Packages/Adminltetags/Tags/Buttons/ButtonGroup.php index facb3228d..33a63ad07 100644 --- a/apps/Core/Packages/Adminltetags/Tags/Buttons/ButtonGroup.php +++ b/apps/Core/Packages/Adminltetags/Tags/Buttons/ButtonGroup.php @@ -140,7 +140,7 @@ protected function buildButton() } if (isset($this->params['groupRadioButtonChecked'])) { - if ($this->params['groupRadioButtonChecked'] === $button['dataValue']) { + if ($this->params['groupRadioButtonChecked'] === $button['value']) { $hasButtonChecked = 'checked'; $hasButtonCheckedClasses = 'active focus'; if ($this->params['groupRadioButtonStyle'] === 'outline') { From abed5dd922c2b9400ca0d2bf454b6f8f557da490 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Wed, 12 Feb 2025 03:11:22 +1100 Subject: [PATCH 53/54] fix issue #603 --- .../default/js/header/dependencies/Baz/BazContentLoader.js | 4 ++++ public/core/default/js/header/jsHeaderCore.js | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/public/core/default/js/header/dependencies/Baz/BazContentLoader.js b/public/core/default/js/header/dependencies/Baz/BazContentLoader.js index 5f6c8f190..d0a3258b9 100644 --- a/public/core/default/js/header/dependencies/Baz/BazContentLoader.js +++ b/public/core/default/js/header/dependencies/Baz/BazContentLoader.js @@ -148,6 +148,10 @@ var BazContentLoader = function() { } function loadAjax(element, options, popped) { + if (element.length === 0) { + return false; + } + BazHelpers.setTimeoutTimers.stopAll();//Stop all timers from previous component. var urlToLoad, elementId; var dataCollection = window.dataCollection; diff --git a/public/core/default/js/header/jsHeaderCore.js b/public/core/default/js/header/jsHeaderCore.js index 073c2206b..660c19b10 100644 --- a/public/core/default/js/header/jsHeaderCore.js +++ b/public/core/default/js/header/jsHeaderCore.js @@ -148,6 +148,10 @@ var BazContentLoader = function() { } function loadAjax(element, options, popped) { + if (element.length === 0) { + return false; + } + BazHelpers.setTimeoutTimers.stopAll();//Stop all timers from previous component. var urlToLoad, elementId; var dataCollection = window.dataCollection; From 87a9c6206160a7b4e04b2a84ae371e995d23785a Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Wed, 12 Feb 2025 04:35:50 +1100 Subject: [PATCH 54/54] update #34. Added option buttons to disable backup. fixed some minor bugs. --- .../Devtools/Modules/DevtoolsModules.php | 9 +- .../Views/Default/html/modules/modules.html | 54 ++------ .../Default/html/modules/queue/analyse.html | 75 ++++++++---- .../Default/html/modules/queue/settings.html | 115 ++++++++++++------ .../core/default/js/footer/jsFooterPlugins.js | 1 - .../footer/plugins/pnotify/5.2.0/PNotify.js | 1 - .../ModulesServiceProvider/Queues.php | 36 ++---- 7 files changed, 153 insertions(+), 138 deletions(-) diff --git a/apps/Core/Packages/Devtools/Modules/DevtoolsModules.php b/apps/Core/Packages/Devtools/Modules/DevtoolsModules.php index fea35a473..d466964e6 100644 --- a/apps/Core/Packages/Devtools/Modules/DevtoolsModules.php +++ b/apps/Core/Packages/Devtools/Modules/DevtoolsModules.php @@ -2267,8 +2267,7 @@ public function generateRelease($data) if (isset($data['module_type']) && $data['module_type'] === 'views' && - isset($data['base_view_module_id']) && - $data['base_view_module_id'] == 0 + $module['is_subview'] === false ) { array_push($reposArr, $module['repo'] . '-public'); } @@ -2355,8 +2354,7 @@ public function generateRelease($data) if (isset($data['module_type']) && $data['module_type'] === 'views' && - isset($module['base_view_module_id']) && - $module['base_view_module_id'] == 0 + $module['is_subview'] === false ) { array_push($reposArr, $module['repo'] . '-public'); } @@ -2817,8 +2815,7 @@ protected function checkPullRequests($data) if (isset($data['module_type']) && $data['module_type'] === 'views' && - isset($data['base_view_module_id']) && - $data['base_view_module_id'] == 0 + $data['is_subview'] === false ) { array_push($reposArr, $data['repo'] . '-public'); } diff --git a/apps/Core/Views/Default/html/modules/modules.html b/apps/Core/Views/Default/html/modules/modules.html index bf6a2fc3d..e2d06e5b7 100644 --- a/apps/Core/Views/Default/html/modules/modules.html +++ b/apps/Core/Views/Default/html/modules/modules.html @@ -392,16 +392,24 @@
Select module from the tre $('#{{componentId}}-{{sectionId}}-modules').on('search.jstree', function(e, res) { if (dataCollectionSectionForm['vars']['syncInfo'] === '') { + var updateTexts = { }; + $(res.nodes).each(function(i, node) { var updateNode = $('#{{componentId}}-{{sectionId}}-modules').jstree().get_node(node); var apiNode = updateNode.parents[updateNode.parents.length - 2]; - var apiNodeObj = $('#{{componentId}}-{{sectionId}}-modules').jstree().get_node(apiNode); var update = 'update'; if (res.nodes.length > 1) { update = 'updates'; } - dataCollectionSectionForm['vars']['syncInfo'] += apiNodeObj.text + ' has ' + res.nodes.length + ' new ' + update + ' available.
'; + var apiNodeObj = $('#{{componentId}}-{{sectionId}}-modules').jstree().get_node(apiNode); + updateTexts[apiNodeObj.text] = ' has ' + res.nodes.length + ' new ' + update + ' available.'; }); + + if (Object.keys(updateTexts).length > 0) { + for (var updateText in updateTexts) { + dataCollectionSectionForm['vars']['syncInfo'] += updateText + updateTexts[updateText] + '
'; + } + } } if (dataCollectionSectionForm['vars']['initJstree'] === true) { @@ -416,7 +424,6 @@
Select module from the tre textTrusted : true }); } - } dataCollectionSectionForm['vars']['syncInfo'] = ''; @@ -1331,20 +1338,7 @@
Select module from the tre BazCore.updateBreadcrumb(); } }); - // dataCollectionSectionForm['funcs']['analyseQueue'](); }); - - // $('#{{componentId}}-{{sectionId}}-perform-precheck').click(function(e) { - // e.preventDefault(); - - // dataCollectionSectionForm['funcs']['processQueue'](); - // }); - - // $('#{{componentId}}-{{sectionId}}-process-queue').click(function(e) { - // e.preventDefault(); - - // dataCollectionSectionForm['funcs']['processQueue']('process'); - // }); } else { $('#{{componentId}}-{{sectionId}}-analyse-queue').addClass('disabled'); $('#{{componentId}}-{{sectionId}}-clear-queue').attr('disabled', true); @@ -1369,34 +1363,6 @@
Select module from the tre dataCollectionSectionForm['funcs']['moduleinfo'](['noinfo']); $('#{{componentId}}-{{sectionId}}-modules').jstree().deselect_all(); } -// dataCollectionSectionForm['funcs']['processQueue'] = function(task = 'precheck') { -// var postData = { }; -// postData[$('#security-token').attr('name')] = $('#security-token').val(); -// postData['queue'] = dataCollectionSectionForm['vars']['queue']['tasks']; -// postData['process'] = 'runprecheck'; -// if (task === 'process') { -// postData['process'] = 'runprocess'; -// } - -// $.post('{{links.url("modules/processQueue")}}', postData, function(response) { -// if (response.tokenKey && response.token) { -// $('#security-token').attr('name', response.tokenKey); -// $('#security-token').val(response.token); -// } - -// if (response.responseCode == 0) { -// paginatedPNotify('success', { -// text : response.responseMessage, -// textTrusted : true -// }); -// } else { -// paginatedPNotify('error', { -// text : response.responseMessage, -// textTrusted : true -// }); -// } -// }, 'json'); -// } dataCollectionSectionForm['funcs']['initSync'] = function(val) { dataCollectionSectionForm['vars']['sync'] = true; diff --git a/apps/Core/Views/Default/html/modules/queue/analyse.html b/apps/Core/Views/Default/html/modules/queue/analyse.html index 932f1688c..0567bf6c9 100644 --- a/apps/Core/Views/Default/html/modules/queue/analyse.html +++ b/apps/Core/Views/Default/html/modules/queue/analyse.html @@ -279,6 +279,13 @@ postData['id'] = dataCollectionSectionForm['vars']['queue']['id']; postData['settings'] = { }; postData['settings']['backupSettings'] = { }; + var backup = $("input[type='radio'][name='backup']:checked").data('value'); + + if (backup === 'backup-off') { + postData['settings']['backupSettings']['backup'] = false; + } else { + postData['settings']['backupSettings']['backup'] = true; + } postData['settings']['backupSettings']['apps_dir'] = $('#{{componentId}}-{{sectionId}}-apps_dir')[0].checked; postData['settings']['backupSettings']['systems_dir'] = $('#{{componentId}}-{{sectionId}}-systems_dir')[0].checked; postData['settings']['backupSettings']['public_dir'] = $('#{{componentId}}-{{sectionId}}-public_dir')[0].checked; @@ -305,6 +312,7 @@ if (response.responseCode == 0) { paginatedPNotify('success', {text : response.responseMessage}); + $('#{{componentId}}-{{sectionId}}-queue-settings-modal').modal('hide'); } else { paginatedPNotify('error', {text : response.responseMessage}); } @@ -569,7 +577,34 @@ dataCollectionSection = $.extend(dataCollectionSection, { - '{{componentId}}-{{sectionId}}-apps_dir' : { }, + '{{componentId}}-{{sectionId}}-apps_dir' : { + afterInit : function() { + var backup, disabled; + + $("input[type='radio'][name='backup']:checked").parents('.btn-group').click(function() { + backup = $("input[type='radio'][name='backup']:checked").data('value'); + + if (backup === 'backup-off') { + disabled = true; + } else { + disabled = false; + } + $('#{{componentId}}-{{sectionId}}-apps_dir').attr('disabled', disabled); + $('#{{componentId}}-{{sectionId}}-systems_dir').attr('disabled', disabled); + $('#{{componentId}}-{{sectionId}}-public_dir').attr('disabled', disabled); + $('#{{componentId}}-{{sectionId}}-private_dir').attr('disabled', disabled); + $('#{{componentId}}-{{sectionId}}-external_dir').attr('disabled', disabled); + $('#{{componentId}}-{{sectionId}}-html_compiled_dir').attr('disabled', disabled); + $('#{{componentId}}-{{sectionId}}-var_dir').attr('disabled', disabled); + $('#{{componentId}}-{{sectionId}}-external_vendor_dir').attr('disabled', disabled); + $('#{{componentId}}-{{sectionId}}-old_backups_dir').attr('disabled', disabled); + $('#{{componentId}}-{{sectionId}}-database').attr('disabled', disabled); + $('#{{componentId}}-{{sectionId}}-keys').attr('disabled', disabled); + $('#{{componentId}}-{{sectionId}}-password_protect').attr('disabled', disabled); + $('#{{componentId}}-{{sectionId}}-notes').attr('disabled', disabled); + }); + } + }, '{{componentId}}-{{sectionId}}-systems_dir' : { afterInit : function() { $('#{{componentId}}-{{sectionId}}-systems_dir').click(function() { @@ -643,23 +678,23 @@ }); function stringToBoolean(string) { - switch (string.toLowerCase().trim()) { - case "true": - case "yes": - case "1": - return true; - - case "false": - case "no": - case "0": - case null: - case undefined: - case 'undefined': - return false; - - default: - return JSON.parse(string); - } + switch (string.toLowerCase().trim()) { + case "true": + case "yes": + case "1": + return true; + + case "false": + case "no": + case "0": + case null: + case undefined: + case 'undefined': + return false; + + default: + return JSON.parse(string); + } } $(document).ready(function() { @@ -669,10 +704,6 @@ dataCollectionSectionForm['funcs']['init'](); }); - -$(window).on('load', function() { - dataCollectionSectionForm['funcs']['init'](); -});
{{adminltetags.useTag('modal', diff --git a/apps/Core/Views/Default/html/modules/queue/settings.html b/apps/Core/Views/Default/html/modules/queue/settings.html index 41aff11c1..8e61b4815 100644 --- a/apps/Core/Views/Default/html/modules/queue/settings.html +++ b/apps/Core/Views/Default/html/modules/queue/settings.html @@ -9,45 +9,56 @@ {% set settingsBackupSettingsOldBackupsDirChecked = false %} {% set settingsBackupSettingsDatabaseChecked = false %} {% set settingsBackupSettingsKeysChecked = false %} -{% if queue['settings']['backupSettings']['apps_dir'] == 'true' %} - {% set settingsBackupSettingsAppsDirChecked = true %} -{% endif %} -{% if queue['settings']['backupSettings']['systems_dir'] == 'true' %} - {% set settingsBackupSettingsSystemsDirChecked = true %} -{% endif %} -{% if queue['settings']['backupSettings']['public_dir'] == 'true' %} - {% set settingsBackupSettingsPublicDirChecked = true %} -{% endif %} -{% if queue['settings']['backupSettings']['private_dir'] == 'true' %} - {% set settingsBackupSettingsPrivateDirChecked = true %} -{% endif %} -{% if queue['settings']['backupSettings']['external_dir'] == 'true' %} - {% set settingsBackupSettingsExternalDirChecked = true %} -{% endif %} -{% if queue['settings']['backupSettings']['html_compiled_dir'] == 'true' %} - {% set settingsBackupSettingsHTMLCompiledDirChecked = true %} -{% endif %} -{% if queue['settings']['backupSettings']['var_dir'] == 'true' %} - {% set settingsBackupSettingsVarDirChecked = true %} -{% endif %} -{% if queue['settings']['backupSettings']['external_vendor_dir'] == 'true' %} - {% set settingsBackupSettingsExternalVendorDirChecked = true %} -{% endif %} -{% if queue['settings']['backupSettings']['old_backups_dir'] == 'true' %} - {% set settingsBackupSettingsOldBackupsDirChecked = true %} -{% endif %} -{% if queue['settings']['backupSettings']['database'] == 'true' %} - {% set settingsBackupSettingsDatabaseChecked = true %} -{% endif %} -{% if queue['settings']['backupSettings']['keys'] == 'true' %} - {% set settingsBackupSettingsKeysChecked = true %} +{% set settingsBackupSettingsKeysDisabled = false %} +{% set settingsBackupSettingsBackup = 'backup-off' %} +{% set settingsBackupSettingsPasswordProtectDisabled = true %} +{% set settingsBackupSettingsNotesDisabled = true %} +{% if queue['settings']['backupSettings']['backup'] == true %} + {% set settingsBackupSettingsPasswordProtectDisabled = false %} + {% set settingsBackupSettingsNotesDisabled = false %} + {% set settingsBackupSettingsBackup = 'backup-on' %} + {% if queue['settings']['backupSettings']['apps_dir'] == true %} + {% set settingsBackupSettingsAppsDirChecked = true %} + {% set settingsBackupSettingsKeysDisabled = true %} + {% endif %} + {% if queue['settings']['backupSettings']['systems_dir'] == true %} + {% set settingsBackupSettingsSystemsDirChecked = true %} + {% set settingsBackupSettingsKeysChecked = true %} + {% endif %} + {% if queue['settings']['backupSettings']['public_dir'] == true %} + {% set settingsBackupSettingsPublicDirChecked = true %} + {% endif %} + {% if queue['settings']['backupSettings']['private_dir'] == true %} + {% set settingsBackupSettingsPrivateDirChecked = true %} + {% endif %} + {% if queue['settings']['backupSettings']['external_dir'] == true %} + {% set settingsBackupSettingsExternalDirChecked = true %} + {% endif %} + {% if queue['settings']['backupSettings']['html_compiled_dir'] == true %} + {% set settingsBackupSettingsHTMLCompiledDirChecked = true %} + {% endif %} + {% if queue['settings']['backupSettings']['var_dir'] == true %} + {% set settingsBackupSettingsVarDirChecked = true %} + {% endif %} + {% if queue['settings']['backupSettings']['external_vendor_dir'] == true %} + {% set settingsBackupSettingsExternalVendorDirChecked = true %} + {% endif %} + {% if queue['settings']['backupSettings']['old_backups_dir'] == true %} + {% set settingsBackupSettingsOldBackupsDirChecked = true %} + {% endif %} + {% if queue['settings']['backupSettings']['database'] == true %} + {% set settingsBackupSettingsDatabaseChecked = true %} + {% endif %} + {% if queue['settings']['backupSettings']['keys'] == true %} + {% set settingsBackupSettingsKeysChecked = true %} + {% endif %} {% endif %} {% set settingsFilesDeleteSourceFilesChecked = false %} -{% if queue['settings']['files']['deleteSourceFiles'] == 'true' %} +{% if queue['settings']['files']['deleteSourceFiles'] == true %} {% set settingsFilesDeleteSourceFilesChecked = true %} {% endif %} {% set settingsFilesDeleteDestinationFilesChecked = false %} -{% if queue['settings']['files']['deleteDestinationFiles'] == 'true' %} +{% if queue['settings']['files']['deleteDestinationFiles'] == true %} {% set settingsFilesDeleteDestinationFilesChecked = true %} {% endif %}
@@ -75,6 +86,38 @@ )}}
+
+
+ {{adminltetags.useTag('buttons', + [ + 'component' : component, + 'componentName' : componentName, + 'componentId' : componentId, + 'sectionId' : sectionId, + 'buttonType' : 'ButtonGroup', + 'buttonId' : 'backup', + 'groupButtonType' : 'radio', + 'groupButtonSize' : 'sm', + 'groupButtonPosition' : 'right', + 'groupRadioButtonChecked' : settingsBackupSettingsBackup, + 'groupRadioButtonStyle' : 'outline', + 'buttons' : + { + 'backup-off' : { + 'title' : 'Backup Off', + 'type' : 'primary', + 'value' : 'backup-off' + }, + 'backup-on' : { + 'title' : 'Backup On', + 'type' : 'success', + 'value' : 'backup-on' + } + } + ] + )}} +
+
{{adminltetags.useTag('fields', @@ -331,7 +374,7 @@ 'fieldType' : 'checkbox', 'fieldCheckboxType' : 'danger', 'fieldCheckboxChecked' : settingsBackupSettingsKeysChecked, - 'fieldDisabled' : true, + 'fieldDisabled' : settingsBackupSettingsKeysDisabled, 'fieldCheckboxLabel' : 'SECURITY AND DB KEYS', 'fieldBazJstreeSearch' : true, 'fieldBazPostOnCreate' : false, @@ -355,6 +398,7 @@ 'fieldInputPasswordGenerate' : true, 'fieldInputPasswordStrengthMeter' : true, 'fieldHelp' : true, + 'fieldDisabled' : settingsBackupSettingsPasswordProtectDisabled, 'fieldHelpTooltipContent' : 'We will password protect the zip file if password is provided. Password protection is a must in case of Security and DB keys (if not provided, a new password will be auto generated). During restore, you need to enter this password, else restore will fail. Please keep this password safe.', 'fieldRequired' : false, 'fieldBazScan' : true, @@ -379,6 +423,7 @@ 'fieldType' : 'textarea', 'fieldDataMaxLength' : 2048, 'fieldHelp' : true, + 'fieldDisabled' : settingsBackupSettingsNotesDisabled, 'fieldHelpTooltipContent' : 'Backup Notes', 'fieldRequired' : false, 'fieldBazScan' : true, diff --git a/public/core/default/js/footer/jsFooterPlugins.js b/public/core/default/js/footer/jsFooterPlugins.js index f23583869..48decfe16 100644 --- a/public/core/default/js/footer/jsFooterPlugins.js +++ b/public/core/default/js/footer/jsFooterPlugins.js @@ -60,7 +60,6 @@ function paginatedPNotify(type, opts) { opts['stack'] = window.stackPaginate; opts['destroy'] = true; opts['delay'] = 2000; - opts['destroy'] = true; opts['titleTrusted'] = true; opts['modules'] = new Map([ ...PNotify.defaultModules, diff --git a/public/core/default/js/footer/plugins/pnotify/5.2.0/PNotify.js b/public/core/default/js/footer/plugins/pnotify/5.2.0/PNotify.js index 3738562e8..ced2e6a6e 100644 --- a/public/core/default/js/footer/plugins/pnotify/5.2.0/PNotify.js +++ b/public/core/default/js/footer/plugins/pnotify/5.2.0/PNotify.js @@ -37,7 +37,6 @@ function paginatedPNotify(type, opts) { opts['stack'] = window.stackPaginate; opts['destroy'] = true; opts['delay'] = 2000; - opts['destroy'] = true; opts['titleTrusted'] = true; opts['modules'] = new Map([ ...PNotify.defaultModules, diff --git a/system/Base/Providers/ModulesServiceProvider/Queues.php b/system/Base/Providers/ModulesServiceProvider/Queues.php index c0f0ba014..9a32e3fac 100644 --- a/system/Base/Providers/ModulesServiceProvider/Queues.php +++ b/system/Base/Providers/ModulesServiceProvider/Queues.php @@ -230,40 +230,18 @@ public function saveQueueSettings($data) return false; } - $noOptions = true; - array_walk($data['settings']['backupSettings'], function(&$setting, $index) use (&$noOptions) { - if ($index === 'notes' || - $index === 'password_protect' + if ($data['settings']['backupSettings']['backup'] == 'true') { + if ($data['settings']['backupSettings']['keys'] === true && + $data['settings']['backupSettings']['password_protect'] === '' ) { - return; - } + $this->addResponse('Password is required if keys are being backed up!', 1); - if ($setting !== '') { - if ($setting == 'true') { - $setting = true; - $noOptions = false; - } else { - $setting = false; - } - } else { - $setting = false; + return false; } - }); - if ($data['settings']['backupSettings']['keys'] === true && - $data['settings']['backupSettings']['password_protect'] === '' - ) { - $this->addResponse('Password is required if keys are being backed up!', 1); - - return false; - } - - if ($noOptions) {//No option selected disables backup. - $data['settings']['backupSettings']['backup'] = false; - $data['settings']['backupSettings']['password_protect'] = ''; - $data['settings']['backupSettings']['notes'] = ''; - } else { $data['settings']['backupSettings']['backup'] = true; + } else { + $data['settings']['backupSettings']['backup'] = false; } if ($data['settings']['emailReport'] !== '') {