From 85b7cac4eec69b4b394c6fb6d703da1919607034 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Thu, 6 Mar 2025 16:37:03 +1100 Subject: [PATCH 01/40] initial commit #655 --- .../BasepackagesServiceProvider/Packages/Progress.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php index 93f0f8b9d..babb428fc 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php @@ -483,7 +483,11 @@ public function resetProgress($reRegisterMethods = true) $this->deleteProgressFile(true); if ($reRegisterMethods) { - $this->registerMethods($progressFile['registeredMethods']); + if (isset($progressFile['registeredMethods'])) { + $this->registerMethods($progressFile['registeredMethods']); + } else { + $this->registerMethods($progressFile['allProcesses']); + } } } From c057ea404b688562f6bf06972dd3f323098533f1 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Thu, 6 Mar 2025 16:49:00 +1100 Subject: [PATCH 02/40] update issue #655 --- .../BasepackagesServiceProvider/Packages/Progress.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php index babb428fc..7a39b554d 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php @@ -606,7 +606,11 @@ protected function writeProgressFile( $file['allProcesses'] = $file['registeredMethods'] = $methods; } else if ($unregister) { $progressFile = $this->readProgressFile(); - $file['allProcesses'] = $progressFile['registeredMethods']; + if (isset($progressFile['registeredMethods'])) { + $file['allProcesses'] = $progressFile['registeredMethods']; + } else { + $file['allProcesses'] = $progressFile['allProcesses']; + } } } From b439bcb5025bc3c28d8c47834659c3918f5c34be Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Thu, 6 Mar 2025 18:46:07 +1100 Subject: [PATCH 03/40] update issue #655 --- .../BasepackagesServiceProvider/Packages/Progress.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php index 7a39b554d..e7ae72b78 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php @@ -675,7 +675,11 @@ protected function writeProgressFile( $file['runners'] = $runners; } - $file['registeredMethods'] = $progressFile['registeredMethods']; + if (isset($progressFile['registeredMethods'])) { + $file['registeredMethods'] = $progressFile['registeredMethods']; + } else { + $file['registeredMethods'] = $progressFile['allProcesses']; + } } $file['processes'] = $methods; From bf63a5a8643ff46fff15c32e5a91165c8fd24472 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Thu, 6 Mar 2025 18:58:00 +1100 Subject: [PATCH 04/40] update issue #655 --- public/core/default/js/footer/core/Baz/BazProgress.js | 4 +++- public/core/default/js/footer/jsFooterCore.js | 4 +++- .../BasepackagesServiceProvider/Packages/Progress.php | 1 - 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/public/core/default/js/footer/core/Baz/BazProgress.js b/public/core/default/js/footer/core/Baz/BazProgress.js index 646a13da1..3c2ae7099 100644 --- a/public/core/default/js/footer/core/Baz/BazProgress.js +++ b/public/core/default/js/footer/core/Baz/BazProgress.js @@ -203,7 +203,9 @@ var BazProgress = function() { if (hasDetails) { $('#' + $(element)[0].id + '-details-button').off(); - $('#' + $(element)[0].id + '-details-button').click(function() { + $('#' + $(element)[0].id + '-details-button').click(function(e) { + e.preventDefault(); + var text = $('#' + $(element)[0].id + '-details-button').text().toLowerCase(); if (text === 'show details') { diff --git a/public/core/default/js/footer/jsFooterCore.js b/public/core/default/js/footer/jsFooterCore.js index 67a732a4b..fd2f2cd5b 100644 --- a/public/core/default/js/footer/jsFooterCore.js +++ b/public/core/default/js/footer/jsFooterCore.js @@ -12061,7 +12061,9 @@ var BazProgress = function() { if (hasDetails) { $('#' + $(element)[0].id + '-details-button').off(); - $('#' + $(element)[0].id + '-details-button').click(function() { + $('#' + $(element)[0].id + '-details-button').click(function(e) { + e.preventDefault(); + var text = $('#' + $(element)[0].id + '-details-button').text().toLowerCase(); if (text === 'show details') { diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php index e7ae72b78..ff6cf9342 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php @@ -164,7 +164,6 @@ public function getProgress($session = null, $returnArray = false) 'totalPercentComplete' => $this->getPercentComplete($progressFile, false), 'percentComplete' => $this->getPercentComplete($progressFile), 'runners' => $progressFile['runners'] ?? false, - 'callResult' => $callResult, 'errors' => $errors, 'details' => $details ]; From 93e6d4c26ed9ec1691eb6e2905ddff1357fe9312 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Fri, 7 Mar 2025 00:10:57 +1100 Subject: [PATCH 05/40] fix issue #656 --- .../DatabaseServiceProvider/Ff/Store.php | 33 +++++++------------ 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php b/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php index 9fcfe38a9..4f739ec1a 100644 --- a/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php +++ b/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php @@ -129,27 +129,18 @@ public function getSchemaMetaData($relations = false) $rmd['columnUnique'] = []; $rmd['storeRelations'] = []; - if (isset($schemaArr['properties'])) { - foreach ($schemaArr['properties'] as $column => $property) { - if (isset($property['type'][1]) && $property['type'][1] === 'array') { - if (isset($property['relation'])) { - $relation = explode('|', $property['relation']); - - if (count($relation) > 0 && isset($relation[2])) { - try { - $relation[2] = explode('+', $relation[2])[0]; - $relationsStore = new Store($relation[2], $this->databasePath, $this->ff); - - $rmd = array_replace_recursive($rmd, $relationsStore->getSchemaMetaData()); - - $rmd['storeRelations'][$column] = []; - $rmd['storeRelations'][$column] = $relationsStore->getSchemaMetaData(); - $rmd['storeRelations'][$column]['relationStore'] = $relation[2]; - } catch (\Exception $e) { - throw $e; - } - } - } + if (isset($schemaArr['relations'])) { + foreach ($schemaArr['relations'] as $alias => $relation) { + if (isset($relation['table']) && isset($this->relationStores[$relation['table']])) { + $rmd = array_replace_recursive($rmd, $this->relationStores[$relation['table']]->getSchemaMetaData()); + $rmd['storeRelations'][$alias] = []; + $rmd['storeRelations'][$alias] = $this->relationStores[$relation['table']]->getSchemaMetaData(); + $rmd['storeRelations'][$alias]['relationStore'] = $relation['table']; + } else if (isset($relation[1]) && isset($this->relationStores[$relation[1]['table']])) { + $rmd = array_replace_recursive($rmd, $this->relationStores[$relation[1]['table']]->getSchemaMetaData()); + $rmd['storeRelations'][$alias] = []; + $rmd['storeRelations'][$alias] = $this->relationStores[$relation[1]['table']]->getSchemaMetaData(); + $rmd['storeRelations'][$alias]['relationStore'] = $relation[1]['table']; } } } From 5d511188648fdade16429b87d4baf6f2cf274a5f Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Fri, 7 Mar 2025 00:28:58 +1100 Subject: [PATCH 06/40] minor bug fix with relation conditions issue #656 --- system/Base/Providers/DatabaseServiceProvider/Ff/Store.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php b/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php index 4f739ec1a..11b73c263 100644 --- a/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php +++ b/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php @@ -1037,7 +1037,7 @@ public function getRelations($data, $relationsConditions = false) } if (isset($relationsConditions[$relation['alias']])) {//Relation with condition - $criteria = array_merge($criteria, $relationsConditions[$relation['alias']]); + array_push($criteria, [$relationsConditions[$relation['alias']]]); } try { @@ -1076,7 +1076,7 @@ public function getRelations($data, $relationsConditions = false) } if (isset($relationsConditions[$relation['alias']])) {//Relation with condition - $criteria = array_merge($criteria, $relationsConditions[$relation['alias']]); + array_push($criteria, [$relationsConditions[$relation['alias']]]); } try { From 61854c89fdad191eb88c89b29ccfe05ab0a000dc Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Fri, 7 Mar 2025 00:38:33 +1100 Subject: [PATCH 07/40] update #655, add cancel button to module. --- apps/Core/Views/Default/html/modules/queue/analyse.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/Core/Views/Default/html/modules/queue/analyse.html b/apps/Core/Views/Default/html/modules/queue/analyse.html index d82d44a83..cf5e6834b 100644 --- a/apps/Core/Views/Default/html/modules/queue/analyse.html +++ b/apps/Core/Views/Default/html/modules/queue/analyse.html @@ -250,7 +250,7 @@ dataCollectionSectionForm['vars']['queue'] = JSON.parse('{{queue}}'); dataCollectionSectionForm['funcs'] = { }; dataCollectionSectionForm['funcs']['init'] = function() { - BazProgress.buildProgressBar($('#installer-progress'), false, true, true, false); + BazProgress.buildProgressBar($('#installer-progress'), false, true, true, true); if ($.fn.DataTable && !$.fn.DataTable.isDataTable('#{{componentId}}-{{sectionId}}-queue-table')) { $('#{{componentId}}-{{sectionId}}-queue-table').DataTable({ From d13bca97c5ad9b427ccc8af72be1837e19e5f6bd Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Fri, 7 Mar 2025 03:18:23 +1100 Subject: [PATCH 08/40] fix issue #657 --- .../DatabaseServiceProvider/Ff/Classes/DocumentFinder.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/DocumentFinder.php b/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/DocumentFinder.php index f61d8b518..95b43e11b 100644 --- a/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/DocumentFinder.php +++ b/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/DocumentFinder.php @@ -111,7 +111,6 @@ public function findDocuments(bool $getOneDocument, bool $reduceAndJoinPossible) } else { foreach ($indexJson as $key => $ids) { if ($limit && count($ids) > $limit) { - self::skip($ids, $skip); self::limit($ids, $limit); } @@ -119,7 +118,7 @@ public function findDocuments(bool $getOneDocument, bool $reduceAndJoinPossible) $key = strtolower($key); if (strtolower($condition[0][1]) === 'like') { - if (str_starts_with($key, strtolower($keyword))) { + if (str_starts_with($key, strtolower($indexChars))) { foreach ($ids as $id) { $indexIdData = $this->store->findById($id); @@ -131,7 +130,7 @@ public function findDocuments(bool $getOneDocument, bool $reduceAndJoinPossible) } else if ($condition[0][1] === '=' || $condition[0][1] === '===' ) { - if ($key === strtolower($keyword)) { + if ($key === strtolower($indexChars)) { foreach ($ids as $id) { $indexIdData = $this->store->findById($id); From b17a20cbb527379043230bccc859d0536f958bcf Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Fri, 7 Mar 2025 14:30:36 +1100 Subject: [PATCH 09/40] initial commit, issue #658 --- .../Packages/Progress.php | 47 +++++++++++-------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php index ff6cf9342..3c9abae4e 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php @@ -522,26 +522,8 @@ public function cancelProgress($fileName = null) if ($progressFile) { if (isset($progressFile['pid']) && $progressFile['pid'] > 0) { - exec('ps -aux | grep ' . $progressFile['pid'], $output, $result); - - if ($result === 0 && - count($output) > 0 - ) { - if (str_contains($output[0], 'php')) { - exec('kill -9 ' . $progressFile['pid'], $output, $result); - - if ($result !== 0) { - $this->addResponse('Error terminating process', 1, ['output' => $output]); - - return false; - } - - $this->writeProgressFile(methods: [],progressFile: $progressFile); - - $this->addResponse('Successfully terminating process'); - - return $this->resetProgress(); - } + if ($this->terminatePid($progressFile['pid'] !== true)) { + return false; } } @@ -559,6 +541,31 @@ public function cancelProgress($fileName = null) } } + public function terminatePid($pid) + { + exec('ps -aux | grep ' . $pid, $output, $result); + + if ($result === 0 && count($output) > 0) { + if (str_contains($output[0], 'php')) { + exec('kill -9 ' . $pid, $output, $result); + + if ($result !== 0) { + $this->addResponse('Error terminating process', 1, ['output' => $output]); + + return false; + } + + $this->writeProgressFile(methods: [],progressFile: $progressFile); + + $this->addResponse('Successfully terminating process'); + + return $this->resetProgress(); + } + } + + return true; + } + protected function readProgressFile($session = null) { if (!$this->progressFileName) { From fcb243d415ee165ad52ab998df419166f58c27b5 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Fri, 7 Mar 2025 16:47:21 +1100 Subject: [PATCH 10/40] fix issue #584 & #657 --- system/Base/BasePackage.php | 24 ++- .../ApiClientServices/ApiClientServices.php | 4 + .../Ff/Classes/DocumentFinder.php | 187 +++++++++++------- .../Ff/Classes/IndexHandler.php | 6 +- .../DatabaseServiceProvider/Ff/Store.php | 63 ++++-- 5 files changed, 184 insertions(+), 100 deletions(-) diff --git a/system/Base/BasePackage.php b/system/Base/BasePackage.php index 9b276cba3..a1b2bee18 100644 --- a/system/Base/BasePackage.php +++ b/system/Base/BasePackage.php @@ -190,7 +190,9 @@ public function getById(int $id, bool $resetCache = false, bool $enableCache = t return false; } else { - $this->ffStore = $this->ff->store($this->ffStoreToUse); + if (!$this->ffStore) { + $this->ffStore = $this->ff->store($this->ffStoreToUse); + } $this->ffData = $this->ffStore->findById($id, $this->ffRelations, $this->ffRelationsConditions); @@ -247,7 +249,9 @@ public function getFirst($by = null, $value = null, bool $resetCache = false, bo throw $e; } } else { - $this->ffStore = $this->ff->store($this->ffStoreToUse); + if (!$this->ffStore) { + $this->ffStore = $this->ff->store($this->ffStoreToUse); + } if ($by === 'id') { $value = (int) $value; @@ -277,7 +281,9 @@ public function getAll(bool $resetCache = false, bool $enableCache = true, $mode if ($this->config->databasetype === 'db') { $allPackages = $this->getByParams(['conditions'=>''], $resetCache, $enableCache, $model); } else { - $this->ffStore = $this->ff->store($this->ffStoreToUse); + if (!$this->ffStore) { + $this->ffStore = $this->ff->store($this->ffStoreToUse); + } $allPackages = $this->ffStore->findAll(); @@ -357,7 +363,9 @@ public function getByParams(array $params, bool $resetCache = false, bool $enabl throw new \Exception('getByParams needs parameter conditions to be set.'); } else { - $this->ffStore = $this->ff->store($this->ffStoreToUse); + if (!$this->ffStore) { + $this->ffStore = $this->ff->store($this->ffStoreToUse); + } $relationColumns = []; @@ -1234,7 +1242,9 @@ public function add(array $data, $resetCache = true) $create = ${$this->packageNameModel}->create(); } else { - $this->ffStore = $this->ff->store($this->ffStoreToUse); + if (!$this->ffStore) { + $this->ffStore = $this->ff->store($this->ffStoreToUse); + } if ($this->ffAddUsingUpdateOrInsert) { if (isset($data['id']) && (int) $data['id'] !== 0) { @@ -1308,7 +1318,9 @@ public function update(array $data, $resetCache = true) $update = ${$this->packageNameModel}->update(); } else { - $this->ffStore = $this->ff->store($this->ffStoreToUse); + if (!$this->ffStore) { + $this->ffStore = $this->ff->store($this->ffStoreToUse); + } $update = $this->ffData = $this->ffStore->update($data); diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/ApiClientServices/ApiClientServices.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/ApiClientServices/ApiClientServices.php index cfcbafbf6..df0812cfe 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/ApiClientServices/ApiClientServices.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/ApiClientServices/ApiClientServices.php @@ -183,6 +183,10 @@ protected function switchApiModel($api = null) $this->packageName = 'apiClientServices'; } + + if ($this->config->databasetype !== 'db') { + $this->ffStore = null; + } } public function addApi(array $data) diff --git a/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/DocumentFinder.php b/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/DocumentFinder.php index 95b43e11b..01cd2733b 100644 --- a/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/DocumentFinder.php +++ b/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/DocumentFinder.php @@ -20,6 +20,14 @@ class DocumentFinder protected $storeConfiguration; + protected $minIndexChars = 3; + + protected $multiWords = true; + + protected $multiWordsSeparator = '+'; + + protected $minMultiWordsChars = 4; + public function __construct(string $storePath, array $queryBuilderProperties, string $primaryKey, $store) { $this->storePath = $storePath; @@ -31,6 +39,19 @@ public function __construct(string $storePath, array $queryBuilderProperties, st $this->store = $store; $this->storeConfiguration = $this->store->getStoreConfiguration(); + + if (isset($this->storeConfiguration['min_index_chars'])) { + $this->minIndexChars = $this->storeConfiguration['min_index_chars']; + } + if (isset($this->storeConfiguration['multi_words'])) { + $this->multiWords = $this->storeConfiguration['multi_words']; + } + if (isset($this->storeConfiguration['multi_words_separator'])) { + $this->multiWordsSeparator = $this->storeConfiguration['multi_words_separator']; + } + if (isset($this->storeConfiguration['min_multi_words_chars'])) { + $this->minMultiWordsChars = $this->storeConfiguration['min_multi_words_chars']; + } } public function findDocuments(bool $getOneDocument, bool $reduceAndJoinPossible): array @@ -59,9 +80,7 @@ public function findDocuments(bool $getOneDocument, bool $reduceAndJoinPossible) $indexSearched = false; - if ($this->storeConfiguration['indexing']) { - // This has to be rewritten to include multiple keywords using spaces - // Example: If we want to search for wes aus, it should search for all entries with Wes keyword and that also includes Aus keyword. + if ($this->storeConfiguration['readIndex']) { if (count($conditions) > 0) { foreach ($conditions as $condition) { if (isset($condition[0]) && @@ -69,82 +88,29 @@ public function findDocuments(bool $getOneDocument, bool $reduceAndJoinPossible) ) { $indexSearched = true; - $keyword = trim($condition[0][2], '%');//This needs to extend - - if (strlen($keyword) < $this->storeConfiguration['min_index_chars']) { - continue; - } + //trim % (like), change space to + for multikeyword search. + $keyword = str_replace(' ', '+', strtolower(trim($condition[0][2], '%'))); - $indexChars = strtolower(substr($keyword, 0, $this->storeConfiguration['min_index_chars'])); + if ($this->multiWords === true && str_contains($keyword, '+')) { + $keywordArr = explode('+', $keyword); - try { - $indexFile = IoHelper::getFileContent( - $this->storeConfiguration['indexesPath'] . $condition[0][0] . '/' . $indexChars . '.json' - ); + foreach ($keywordArr as $key => $keyword) { + if (strlen($keyword) < $this->minMultiWordsChars) { + continue; + } - $indexFile = strtolower($indexFile); + $indexChars = strtolower(mb_substr($keyword, 0, $this->minIndexChars, 'UTF-8')); - $indexJson = json_decode($indexFile, true); + $found = array_merge($found, $this->searchIndexes($condition, $indexChars, $skip, $limit, $keyword)); + } + } else { + if (strlen($keyword) < $this->minIndexChars) { + continue; + } - if (count($indexJson) > 0) { - if ($limit && count($indexJson) > 0) { - self::skip($indexJson, $skip); - self::limit($indexJson, $limit); - } + $indexChars = strtolower(mb_substr($keyword, 0, $this->minIndexChars, 'UTF-8')); - if (isset($indexJson[strtolower($keyword)])) { - if (count($indexJson[strtolower($keyword)]) === 1) { - $indexIdData = $this->store->findById($indexJson[strtolower($keyword)][0]); - - if ($indexIdData) { - $found[] = $indexIdData; - } - } else { - foreach ($indexJson[strtolower($keyword)] as $id) { - $indexIdData = $this->store->findById($id); - - if ($indexIdData) { - $found[] = $indexIdData; - } - } - } - } else { - foreach ($indexJson as $key => $ids) { - if ($limit && count($ids) > $limit) { - self::skip($ids, $skip); - self::limit($ids, $limit); - } - - $key = strtolower($key); - - if (strtolower($condition[0][1]) === 'like') { - if (str_starts_with($key, strtolower($indexChars))) { - foreach ($ids as $id) { - $indexIdData = $this->store->findById($id); - - if ($indexIdData) { - $found[] = $indexIdData; - } - } - } - } else if ($condition[0][1] === '=' || - $condition[0][1] === '===' - ) { - if ($key === strtolower($indexChars)) { - foreach ($ids as $id) { - $indexIdData = $this->store->findById($id); - - if ($indexIdData) { - $found[] = $indexIdData; - } - } - } - } - } - } - } - } catch (\Exception $e) { - $found = []; + $found = array_merge($found, $this->searchIndexes($condition, $indexChars, $skip, $limit, $keyword)); } } } @@ -235,6 +201,81 @@ public function findDocuments(bool $getOneDocument, bool $reduceAndJoinPossible) return $found; } + protected function searchIndexes($condition, $indexChars, $skip, $limit, $keyword) + { + try { + $indexFile = IoHelper::getFileContent( + $this->storeConfiguration['indexesPath'] . $condition[0][0] . '/' . $indexChars . '.json' + ); + + $indexFile = strtolower($indexFile); + + $indexJson = json_decode($indexFile, true); + + if (count($indexJson) > 0) { + if ($limit && count($indexJson) > 0) { + self::skip($indexJson, $skip); + self::limit($indexJson, $limit); + } + + if (isset($indexJson[$keyword])) { + if (count($indexJson[$keyword]) === 1) { + $indexIdData = $this->store->findById($indexJson[$keyword][0]); + + if ($indexIdData) { + $found[] = $indexIdData; + } + } else { + foreach ($indexJson[$keyword] as $id) { + $indexIdData = $this->store->findById($id); + + if ($indexIdData) { + $found[] = $indexIdData; + } + } + } + } else { + foreach ($indexJson as $key => $ids) { + if ($limit && count($ids) > $limit) { + self::skip($ids, $skip); + self::limit($ids, $limit); + } + + $key = strtolower($key); + + if (strtolower($condition[0][1]) === 'like') { + if (str_starts_with($key, $indexChars)) { + foreach ($ids as $id) { + $indexIdData = $this->store->findById($id); + + if ($indexIdData) { + $found[] = $indexIdData; + } + } + } + } else if ($condition[0][1] === '=' || + $condition[0][1] === '===' + ) { + if ($key === $indexChars) { + foreach ($ids as $id) { + $indexIdData = $this->store->findById($id); + + if ($indexIdData) { + $found[] = $indexIdData; + } + } + } + } + } + } + } + } catch (\Exception $e) { + $found = []; + } + + return $found; + } + protected function getDataPath(): string { return $this->storePath . Store::dataDirectory; diff --git a/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/IndexHandler.php b/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/IndexHandler.php index 5f2fb5364..5b6fe270d 100644 --- a/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/IndexHandler.php +++ b/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/IndexHandler.php @@ -18,7 +18,7 @@ class IndexHandler protected $multiWordsSeparator = ' '; - protected $minMultiWordsChars = 5; + protected $minMultiWordsChars = 4; protected $folderPermissions = 0777; @@ -102,6 +102,10 @@ public function setIndex($content, $remove = false) } } else { if (is_string($content[$index])) { + if (strlen($content[$index]) < $this->minIndexChars) { + continue; + } + $indexChars = strtolower(mb_substr($content[$index], 0, $this->minIndexChars, 'UTF-8')); if (str_contains($indexChars, '/')) {//this will result in subdirectories diff --git a/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php b/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php index 11b73c263..95d7312a5 100644 --- a/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php +++ b/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php @@ -27,6 +27,7 @@ class Store protected $defaultCacheLifetime = null; protected $indexesPath = ''; + protected $readIndex = false; protected $indexing = false; protected $minIndexChars = 3; protected $multiWords = true; @@ -1260,6 +1261,7 @@ protected function setConfigurationAndSchema(array $configuration = [], array $s if (count($configuration["indexes"]) > 0) { $configuration['indexing'] = true; + $configuration['readIndex'] = true; } } @@ -1271,6 +1273,14 @@ protected function setConfigurationAndSchema(array $configuration = [], array $s $this->indexing = $configuration["indexing"]; } + if (array_key_exists("readIndex", $configuration)) { + if (!is_bool($configuration["readIndex"])) { + throw new InvalidConfigurationException("readIndex has to be boolean"); + } + + $this->readIndex = $configuration["readIndex"]; + } + if (array_key_exists("auto_cache", $configuration)) { if (!is_bool($configuration["auto_cache"])) { throw new InvalidConfigurationException("auto_cache has to be boolean"); @@ -1396,27 +1406,28 @@ protected function storeConfiguration() { $this->storeConfiguration = [ - "auto_cache" => $this->useCache, - "cache_lifetime" => $this->defaultCacheLifetime, - "primary_key" => $this->primaryKey, + "auto_cache" => &$this->useCache, + "cache_lifetime" => &$this->defaultCacheLifetime, + "primary_key" => &$this->primaryKey, "search" => [ - "min_length" => $this->searchOptions["minLength"], - "mode" => $this->searchOptions["mode"], - "score_key" => $this->searchOptions["scoreKey"], - "algorithm" => $this->searchOptions["algorithm"] + "min_length" => &$this->searchOptions["minLength"], + "mode" => &$this->searchOptions["mode"], + "score_key" => &$this->searchOptions["scoreKey"], + "algorithm" => &$this->searchOptions["algorithm"] ], - "folder_permissions" => $this->folderPermissions, - "indexing" => $this->indexing, - "min_index_chars" => $this->minIndexChars, - "multi_words" => $this->multiWords, - "multi_words_separator" => $this->multiWordsSeparator, - "min_multi_words_chars" => $this->minMultiWordsChars, - "uniqueFields" => $this->uniqueFields, - "indexes" => $this->indexes, - "storePath" => $this->storePath, - "databasePath" => $this->databasePath, - "indexesPath" => $this->indexesPath, - "model" => $this->model + "folder_permissions" => &$this->folderPermissions, + "readIndex" => &$this->readIndex, + "indexing" => &$this->indexing, + "min_index_chars" => &$this->minIndexChars, + "multi_words" => &$this->multiWords, + "multi_words_separator" => &$this->multiWordsSeparator, + "min_multi_words_chars" => &$this->minMultiWordsChars, + "uniqueFields" => &$this->uniqueFields, + "indexes" => &$this->indexes, + "storePath" => &$this->storePath, + "databasePath" => &$this->databasePath, + "indexesPath" => &$this->indexesPath, + "model" => &$this->model ]; } @@ -1801,10 +1812,22 @@ public function getIndexing() return $this->indexing; } - public function setIndexing($indexing = true) + public function setIndexing($indexing) { $this->indexing = $indexing; return $this->getIndexing(); } + + public function getReadIndex() + { + return $this->readIndex; + } + + public function setReadIndex($index) + { + $this->readIndex = $index; + + return $this->getReadIndex(); + } } \ No newline at end of file From fdbdb104c26a3ee262f9bbce9c4e1ce9a4cc4893 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Fri, 7 Mar 2025 16:48:14 +1100 Subject: [PATCH 11/40] fix issue #658 --- .../Packages/Progress.php | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php index 3c9abae4e..74dfd48f8 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Progress.php @@ -522,18 +522,16 @@ public function cancelProgress($fileName = null) if ($progressFile) { if (isset($progressFile['pid']) && $progressFile['pid'] > 0) { - if ($this->terminatePid($progressFile['pid'] !== true)) { - return false; - } - } - - $progressFile['runners']['running'] = false; - $progressFile['runners']['next'] = false; - $this->writeProgressFile(methods: [], progressFile: $progressFile, register: true); + return $this->terminatePid($progressFile); + } else { + $progressFile['runners']['running'] = false; + $progressFile['runners']['next'] = false; + $this->writeProgressFile(methods: [], progressFile: $progressFile, register: true); - $this->addResponse('Process not running', 1); + $this->addResponse('Process not running', 1); - return false; + return false; + } } else { $this->addResponse('Error loading progressfile!', 1); @@ -541,13 +539,13 @@ public function cancelProgress($fileName = null) } } - public function terminatePid($pid) + public function terminatePid($progressFile) { - exec('ps -aux | grep ' . $pid, $output, $result); + exec('ps -aux | grep ' . $progressFile['pid'], $output, $result); if ($result === 0 && count($output) > 0) { if (str_contains($output[0], 'php')) { - exec('kill -9 ' . $pid, $output, $result); + exec('kill -9 ' . $progressFile['pid'], $output, $result); if ($result !== 0) { $this->addResponse('Error terminating process', 1, ['output' => $output]); From af637afe5e5d16d93f3e8cf0ad33a7a33e50bd86 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Fri, 7 Mar 2025 20:53:14 +1100 Subject: [PATCH 12/40] fix issue #198 and #659 --- .../core/Baz/BazContentSectionWithListing.js | 65 ++++++++++--------- public/core/default/js/footer/jsFooterCore.js | 63 ++++++++++-------- 2 files changed, 71 insertions(+), 57 deletions(-) diff --git a/public/core/default/js/footer/core/Baz/BazContentSectionWithListing.js b/public/core/default/js/footer/core/Baz/BazContentSectionWithListing.js index bead534ca..23cb8a766 100644 --- a/public/core/default/js/footer/core/Baz/BazContentSectionWithListing.js +++ b/public/core/default/js/footer/core/Baz/BazContentSectionWithListing.js @@ -1125,6 +1125,8 @@ next : '' }, zeroRecords : datatableOptions.zeroRecords, + emptyTable : ' Loading...', + info : 'Showing _START_ to _END_ of _TOTAL_ entries', infoEmpty : 'No entries found', infoFiltered : ' - filtered from _MAX_ shown entries', searchPlaceholder: 'Search shown ' + thisOptions.listOptions.componentName + '...', @@ -1211,6 +1213,18 @@ } that._tableInit(reDraw); that._registerEvents(); + if (response.rows) { + if (typeof response.rows === 'string') { + response.rows = JSON.parse(response.rows); + } + + if (response.rows.data && response.rows.data.length === 0) { + if ($('#' + sectionId + '-table tbody td.dataTables_empty').length === 1) { + $('.dataTables_empty').last().html('No entries found'); + $('.dataTables_info').html('No entries found'); + } + } + } }); // TODO: fix card-body height when more rows are loaded. // TODO: BULK Edit/Delete @@ -1298,33 +1312,32 @@ // Datatable Events //Responsive - thisOptions['datatable'].on('draw responsive-resize responsive-display', function() { + thisOptions['datatable'].on('draw responsive-resize responsive-display', function(e, datatable, row, showHide) { + if (e.type === 'responsive-display') { + if (showHide) { + $($(row.node()).next('.child')).find('li').prepend( + '' + ); + + that._changeResponsiveLiWidths($($(row.node()).next('.child'))); + + $($(row.node()).next('.child')).find('.dtr-expand').click(function() { + if ($(this).parent().is('.text-truncate')) { + $(this).parent().removeClass('text-truncate dt-colTextTruncate'); + $(this).removeClass('fa-plus-circle text-info').addClass('fa-minus-circle text-danger'); + } else { + $(this).parent().addClass('text-truncate dt-colTextTruncate'); + $(this).removeClass('fa-minus-circle text-danger').addClass('fa-plus-circle text-info'); + that._changeResponsiveLiWidths($($(row.node()).next('.child'))); + } + }); + } + } + BazContentLoader.init({}); thisOptions['datatable'].columns.adjust().responsive.recalc(); }); - //Toggle response rows open/close - thisOptions['datatable'].on('responsive-display', function(e, datatable, row, showHide) { - if (showHide) { - $($(row.node()).next('.child')).find('li').prepend( - '' - ); - - that._changeResponsiveLiWidths($($(row.node()).next('.child'))); - - $($(row.node()).next('.child')).find('.dtr-expand').click(function() { - if ($(this).parent().is('.text-truncate')) { - $(this).parent().removeClass('text-truncate dt-colTextTruncate'); - $(this).removeClass('fa-plus-circle text-info').addClass('fa-minus-circle text-danger'); - } else { - $(this).parent().addClass('text-truncate dt-colTextTruncate'); - $(this).removeClass('fa-minus-circle text-danger').addClass('fa-plus-circle text-info'); - that._changeResponsiveLiWidths($($(row.node()).next('.child'))); - } - }); - } - }); - //Search $('.dataTables_filter').find('input').keyup(function() { if ($(this).val() === '') { @@ -1332,12 +1345,6 @@ } }); - thisOptions['datatable'].on('draw', function () { - if ($('#' + sectionId + '-table tbody td.dataTables_empty').length === 1) { - $('.dataTables_empty').last().html('No entries found'); - } - }); - //Length Change thisOptions['datatable'].on('length.dt', function (e, settings, len) { if (len === -1) { diff --git a/public/core/default/js/footer/jsFooterCore.js b/public/core/default/js/footer/jsFooterCore.js index fd2f2cd5b..8146c4d58 100644 --- a/public/core/default/js/footer/jsFooterCore.js +++ b/public/core/default/js/footer/jsFooterCore.js @@ -6710,6 +6710,8 @@ Object.defineProperty(exports, '__esModule', { value: true }); next : '' }, zeroRecords : datatableOptions.zeroRecords, + emptyTable : ' Loading...', + info : 'Showing _START_ to _END_ of _TOTAL_ entries', infoEmpty : 'No entries found', infoFiltered : ' - filtered from _MAX_ shown entries', searchPlaceholder: 'Search shown ' + thisOptions.listOptions.componentName + '...', @@ -6796,6 +6798,18 @@ Object.defineProperty(exports, '__esModule', { value: true }); } that._tableInit(reDraw); that._registerEvents(); + if (response.rows) { + if (typeof response.rows === 'string') { + response.rows = JSON.parse(response.rows); + } + + if (response.rows.data && response.rows.data.length === 0) { + if ($('#' + sectionId + '-table tbody td.dataTables_empty').length === 1) { + $('.dataTables_empty').last().html('No entries found'); + $('.dataTables_info').html('No entries found'); + } + } + } }); // TODO: fix card-body height when more rows are loaded. // TODO: BULK Edit/Delete @@ -6883,31 +6897,30 @@ Object.defineProperty(exports, '__esModule', { value: true }); // Datatable Events //Responsive - thisOptions['datatable'].on('draw responsive-resize responsive-display', function() { - BazContentLoader.init({}); - thisOptions['datatable'].columns.adjust().responsive.recalc(); - }); - - //Toggle response rows open/close - thisOptions['datatable'].on('responsive-display', function(e, datatable, row, showHide) { - if (showHide) { - $($(row.node()).next('.child')).find('li').prepend( - '' - ); + thisOptions['datatable'].on('draw responsive-resize responsive-display', function(e, datatable, row, showHide) { + if (e.type === 'responsive-display') { + if (showHide) { + $($(row.node()).next('.child')).find('li').prepend( + '' + ); - that._changeResponsiveLiWidths($($(row.node()).next('.child'))); + that._changeResponsiveLiWidths($($(row.node()).next('.child'))); - $($(row.node()).next('.child')).find('.dtr-expand').click(function() { - if ($(this).parent().is('.text-truncate')) { - $(this).parent().removeClass('text-truncate dt-colTextTruncate'); - $(this).removeClass('fa-plus-circle text-info').addClass('fa-minus-circle text-danger'); - } else { - $(this).parent().addClass('text-truncate dt-colTextTruncate'); - $(this).removeClass('fa-minus-circle text-danger').addClass('fa-plus-circle text-info'); - that._changeResponsiveLiWidths($($(row.node()).next('.child'))); - } - }); + $($(row.node()).next('.child')).find('.dtr-expand').click(function() { + if ($(this).parent().is('.text-truncate')) { + $(this).parent().removeClass('text-truncate dt-colTextTruncate'); + $(this).removeClass('fa-plus-circle text-info').addClass('fa-minus-circle text-danger'); + } else { + $(this).parent().addClass('text-truncate dt-colTextTruncate'); + $(this).removeClass('fa-minus-circle text-danger').addClass('fa-plus-circle text-info'); + that._changeResponsiveLiWidths($($(row.node()).next('.child'))); + } + }); + } } + + BazContentLoader.init({}); + thisOptions['datatable'].columns.adjust().responsive.recalc(); }); //Search @@ -6917,12 +6930,6 @@ Object.defineProperty(exports, '__esModule', { value: true }); } }); - thisOptions['datatable'].on('draw', function () { - if ($('#' + sectionId + '-table tbody td.dataTables_empty').length === 1) { - $('.dataTables_empty').last().html('No entries found'); - } - }); - //Length Change thisOptions['datatable'].on('length.dt', function (e, settings, len) { if (len === -1) { From d6f71acebe41948e486786fa67739f2110358882 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Sun, 9 Mar 2025 02:47:37 +1100 Subject: [PATCH 13/40] initial commit #660 --- system/Base/Installer/Packages/Setup.php | 4 +- .../Register/Basepackages/Workers/Calls.php | 78 ++++++++++ .../Register/Basepackages/Workers/Tasks.php | 82 ++++++++++- .../Setup/Register/Modules/External.php | 4 +- .../Setup/Register/Modules/Package.php | 20 ++- .../Base/Installer/Packages/Setup/Schema.php | 6 + .../Schema/Basepackages/Workers/Calls.php | 103 +++++++++++++ .../Schema/Basepackages/Workers/Tasks.php | 9 +- .../Setup/Schema/Modules/Externals.php | 3 +- .../Workers/BasepackagesWorkersCalls.php | 24 +++ .../Workers/BasepackagesWorkersTasks.php | 2 +- .../Packages/Progress.php | 4 + .../Packages/Workers.php | 138 ++++++++++++++---- .../Packages/Workers/Calls.php | 73 +++++++++ .../Packages/Workers/Calls/ProcessDbSync.php | 2 +- .../Workers/Calls/ProcessEmailQueue.php | 2 +- .../Calls/ProcessImportExportQueue.php | 2 +- .../Packages/Workers/Calls/ProcessPsef.php | 21 +++ .../Packages/Workers/Tasks.php | 14 -- .../Modules/Packages.php | 11 ++ .../TaskCallInstaller.php | 79 ++++++++++ .../WidgetInstaller.php | 1 + 22 files changed, 616 insertions(+), 66 deletions(-) create mode 100644 system/Base/Installer/Packages/Setup/Register/Basepackages/Workers/Calls.php create mode 100644 system/Base/Installer/Packages/Setup/Schema/Basepackages/Workers/Calls.php create mode 100644 system/Base/Providers/BasepackagesServiceProvider/Packages/Model/Workers/BasepackagesWorkersCalls.php create mode 100644 system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls/ProcessPsef.php create mode 100644 system/Base/Providers/ModulesServiceProvider/TaskCallInstaller.php create mode 100644 system/Base/Providers/ModulesServiceProvider/WidgetInstaller.php diff --git a/system/Base/Installer/Packages/Setup.php b/system/Base/Installer/Packages/Setup.php index b91cf62c4..5292b2a4d 100644 --- a/system/Base/Installer/Packages/Setup.php +++ b/system/Base/Installer/Packages/Setup.php @@ -611,7 +611,7 @@ protected function registerCoreMenu($componentJsonFile) protected function registerCorePackage(array $packageFile) { - return (new RegisterPackage())->register($this->db, $this->ff, $packageFile, $this->helper); + return (new RegisterPackage())->register($this->db, $this->ff, $packageFile, $this->helper, $this->basepackages, $this->container, $this->postData['databasetype']); } protected function registerCoreMiddleware(array $middlewareFile) @@ -754,7 +754,7 @@ protected function registerSchedules() protected function registerTasks() { - (new RegisterTasks())->register($this->db, $this->ff); + (new RegisterTasks())->register($this->db, $this->ff, $this->postData['databasetype']); return true; } diff --git a/system/Base/Installer/Packages/Setup/Register/Basepackages/Workers/Calls.php b/system/Base/Installer/Packages/Setup/Register/Basepackages/Workers/Calls.php new file mode 100644 index 000000000..9eea448c6 --- /dev/null +++ b/system/Base/Installer/Packages/Setup/Register/Basepackages/Workers/Calls.php @@ -0,0 +1,78 @@ +utils->init($container)->scanDir( + 'system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls/' + ); + + if (count($callsArr['files']) > 0) { + foreach ($callsArr['files'] as $key => $call) { + $call = ucfirst($call); + $call = str_replace('/', '\\', $call); + $call = str_replace('.php', '', $call); + + $callClass = new $call; + $callReflection = new \ReflectionClass($call); + + if ($databasetype !== 'db') { + $callStorage = $ff->store('basepackages_workers_calls'); + + $dbCall = $callStorage->findBy(['name', '=', $callReflection->getShortName()]); + } else { + $dbCall = + $db->fetchAll( + "SELECT * FROM basepackages_workers_calls WHERE name = :name", + Enum::FETCH_ASSOC, + [ + "name" => $callReflection->getShortName(), + ] + ); + } + + if ($dbCall && count($dbCall) > 0) { + $dbCall = $dbCall[0]; + } + + if (!$dbCall) { + $dbCall = []; + $dbCall['name'] = $callReflection->getShortName(); + $dbCall['display_name'] = $callReflection->getShortName(); + $dbCall['class'] = $callReflection->getName(); + if ($callReflection->hasProperty('funcDisplayName')) { + $dbCall['display_name'] = $callReflection->getProperty('funcDisplayName')->getValue($callClass); + } + $dbCall['description'] = ''; + if ($callReflection->hasProperty('funcDescription')) { + $dbCall['description'] = $callReflection->getProperty('funcDescription')->getValue($callClass); + } + $dbCall['can_be_scheduled'] = true; + if ($callReflection->hasProperty('funcCanBeScheduled')) { + $dbCall['can_be_scheduled'] = $callReflection->getProperty('funcCanBeScheduled')->getValue($callClass); + } + $dbCall['can_be_run_on_demand'] = true; + if ($callReflection->hasProperty('funcCanBeRunOnDemand')) { + $dbCall['can_be_run_on_demand'] = $callReflection->getProperty('funcCanBeRunOnDemand')->getValue($callClass); + } + $dbCall['package_id'] = $corePackageId; + + if ($db) { + $db->insertAsDict('basepackages_workers_calls', $dbCall); + } + + if ($ff) { + $callStore = $ff->store('basepackages_workers_calls'); + + $callStore->updateOrInsert($dbCall); + } + } + } + } + } +} \ No newline at end of file diff --git a/system/Base/Installer/Packages/Setup/Register/Basepackages/Workers/Tasks.php b/system/Base/Installer/Packages/Setup/Register/Basepackages/Workers/Tasks.php index ee8494107..a78431312 100644 --- a/system/Base/Installer/Packages/Setup/Register/Basepackages/Workers/Tasks.php +++ b/system/Base/Installer/Packages/Setup/Register/Basepackages/Workers/Tasks.php @@ -4,8 +4,20 @@ class Tasks { - public function register($db, $ff) + protected $db; + + protected $ff; + + protected $databasetype; + + public function register($db, $ff, $databasetype) { + $this->db = $db; + + $this->ff = $ff; + + $this->databasetype = $databasetype; + $taskArr = $this->systemSchedules(); foreach ($taskArr as $key => $task) { @@ -23,6 +35,25 @@ public function register($db, $ff) protected function systemSchedules() { + if ($this->databasetype !== 'db') { + $callStore = $this->ff->store('basepackages_workers_calls'); + + $dbCall = $callStore->findBy(['name', '=', 'ProcessEmailQueue']); + } else { + $dbCall = + $this->db->fetchAll( + "SELECT * FROM basepackages_workers_calls WHERE name = :name", + Enum::FETCH_ASSOC, + [ + "name" => 'ProcessEmailQueue', + ] + ); + } + + if ($dbCall && count($dbCall) > 0) { + $dbCall = $dbCall[0]; + } + $taskArr = []; //Email High Priority (encrypted - with codes) @@ -31,7 +62,7 @@ protected function systemSchedules() 'name' => 'Email (Confidential)', 'description' => 'High priority emails that are confidential (with passwords or codes) that are time sensitive.', 'exec_type' => 'php', - 'call' => 'processemailqueue', + 'cid' => $dbCall['id'], 'call_args' => '{"priority":"1", "confidential":true}', 'schedule_id' => 1, 'is_on_demand' => 0, @@ -47,7 +78,7 @@ protected function systemSchedules() 'name' => 'Email (High Priority)', 'description' => 'High priority emails.', 'exec_type' => 'php', - 'call' => 'processemailqueue', + 'cid' => $dbCall['id'], 'call_args' => '{"priority":"1"}', 'schedule_id' => 0, 'is_on_demand' => 1, @@ -63,7 +94,7 @@ protected function systemSchedules() 'name' => 'Email (Medium Priority)', 'description' => 'Medium priority emails like notification emails.', 'exec_type' => 'php', - 'call' => 'processemailqueue', + 'cid' => $dbCall['id'], 'call_args' => '{"priority":"2"}', 'schedule_id' => 0, 'is_on_demand' => 1, @@ -79,7 +110,7 @@ protected function systemSchedules() 'name' => 'Email (Low Priority)', 'description' => 'Low priority emails like notification emails.', 'exec_type' => 'php', - 'call' => 'processemailqueue', + 'cid' => $dbCall['id'], 'call_args' => '{"priority":"3"}', 'schedule_id' => 0, 'is_on_demand' => 1, @@ -89,13 +120,30 @@ protected function systemSchedules() ]; array_push($taskArr, $taskEntry); + if ($this->databasetype !== 'db') { + $dbCall = $callStore->findBy(['name', '=', 'ProcessImportExportQueue']); + } else { + $dbCall = + $this->db->fetchAll( + "SELECT * FROM basepackages_workers_calls WHERE name = :name", + Enum::FETCH_ASSOC, + [ + "name" => 'ProcessImportExportQueue', + ] + ); + } + + if ($dbCall && count($dbCall) > 0) { + $dbCall = $dbCall[0]; + } + //Import/Export (Export) $taskEntry = [ 'name' => 'Import/Export (Export)', 'description' => 'Import/Export Tools - Export', 'exec_type' => 'php', - 'call' => 'processimportexportqueue', + 'cid' => $dbCall['id'], 'call_args' => '{"process":"export"}', 'schedule_id' => 0, 'is_on_demand' => 1, @@ -111,7 +159,7 @@ protected function systemSchedules() 'name' => 'Import/Export (Low Priority)', 'description' => 'Import/Export Tools - Import', 'exec_type' => 'php', - 'call' => 'processimportexportqueue', + 'cid' => $dbCall['id'], 'call_args' => '{"process":"import"}', 'schedule_id' => 0, 'is_on_demand' => 1, @@ -121,13 +169,31 @@ protected function systemSchedules() ]; array_push($taskArr, $taskEntry); + if ($this->databasetype !== 'db') { + $dbCall = $callStore->findBy(['name', '=', 'ProcessDbSync']); + } else { + $dbCall = + $this->db->fetchAll( + "SELECT * FROM basepackages_workers_calls WHERE name = :name", + Enum::FETCH_ASSOC, + [ + "name" => 'ProcessDbSync', + ] + ); + } + + if ($dbCall && count($dbCall) > 0) { + $dbCall = $dbCall[0]; + } + + //DB Sync (Hybrid Mode) $taskEntry = [ 'name' => 'DB Sync (Hybric Mode)', 'description' => 'Update database with changed made to the FF Store.', 'exec_type' => 'php', - 'call' => 'processdbsync', + 'cid' => $dbCall['id'], 'call_args' => '{}', 'schedule_id' => 0, 'is_on_demand' => 1, diff --git a/system/Base/Installer/Packages/Setup/Register/Modules/External.php b/system/Base/Installer/Packages/Setup/Register/Modules/External.php index 4f9beed19..c5aabcc82 100644 --- a/system/Base/Installer/Packages/Setup/Register/Modules/External.php +++ b/system/Base/Installer/Packages/Setup/Register/Modules/External.php @@ -2,6 +2,8 @@ namespace System\Base\Installer\Packages\Setup\Register\Modules; +use Phalcon\Db\Enum; + class External { public function register($db, $ff, $composerJsonFile, $helper) @@ -126,7 +128,7 @@ protected function getCoreId($db, $ff) ); if ($core) { - return $core['id']; + return $core[0]['id']; } } diff --git a/system/Base/Installer/Packages/Setup/Register/Modules/Package.php b/system/Base/Installer/Packages/Setup/Register/Modules/Package.php index 928a73473..9101c2dfd 100644 --- a/system/Base/Installer/Packages/Setup/Register/Modules/Package.php +++ b/system/Base/Installer/Packages/Setup/Register/Modules/Package.php @@ -2,9 +2,11 @@ namespace System\Base\Installer\Packages\Setup\Register\Modules; +use System\Base\Installer\Packages\Setup\Register\Basepackages\Workers\Calls; + class Package { - public function register($db, $ff, $packageFile, $helper) + public function register($db, $ff, $packageFile, $helper, $basepackages, $container, $databasetype) { $package = [ @@ -32,14 +34,30 @@ public function register($db, $ff, $packageFile, $helper) 'updated_by' => 0 ]; + $corePackageId = null; + if ($db) { $db->insertAsDict('modules_packages', $package); + + if ($package['name'] === 'Core') { + $corePackageId = (int) $db->lastInsertId(); + } } if ($ff) { $packageStore = $ff->store('modules_packages'); $packageStore->updateOrInsert($package); + + if ($package['name'] === 'Core') { + $corePackageId = (int) $packageStore->getLastInsertedId(); + } + } + + if ($corePackageId) { + $registerCalls = new Calls; + + $registerCalls->register($db, $ff, $basepackages, $container, $corePackageId, $databasetype); } } } \ No newline at end of file diff --git a/system/Base/Installer/Packages/Setup/Schema.php b/system/Base/Installer/Packages/Setup/Schema.php index 21fe9a780..9647bdef0 100644 --- a/system/Base/Installer/Packages/Setup/Schema.php +++ b/system/Base/Installer/Packages/Setup/Schema.php @@ -37,6 +37,7 @@ use System\Base\Installer\Packages\Setup\Schema\Basepackages\Users\Profiles; use System\Base\Installer\Packages\Setup\Schema\Basepackages\Users\Roles; use System\Base\Installer\Packages\Setup\Schema\Basepackages\Widgets; +use System\Base\Installer\Packages\Setup\Schema\Basepackages\Workers\Calls; use System\Base\Installer\Packages\Setup\Schema\Basepackages\Workers\Jobs; use System\Base\Installer\Packages\Setup\Schema\Basepackages\Workers\Schedules; use System\Base\Installer\Packages\Setup\Schema\Basepackages\Workers\Tasks; @@ -105,6 +106,7 @@ use System\Base\Providers\BasepackagesServiceProvider\Packages\Model\Users\BasepackagesUsersAccounts; use System\Base\Providers\BasepackagesServiceProvider\Packages\Model\Users\BasepackagesUsersProfiles; use System\Base\Providers\BasepackagesServiceProvider\Packages\Model\Users\BasepackagesUsersRoles; +use System\Base\Providers\BasepackagesServiceProvider\Packages\Model\Workers\BasepackagesWorkersCalls; use System\Base\Providers\BasepackagesServiceProvider\Packages\Model\Workers\BasepackagesWorkersJobs; use System\Base\Providers\BasepackagesServiceProvider\Packages\Model\Workers\BasepackagesWorkersSchedules; use System\Base\Providers\BasepackagesServiceProvider\Packages\Model\Workers\BasepackagesWorkersTasks; @@ -290,6 +292,10 @@ public function getSchema($dev) 'schema' => new Schedules, 'model' => new BasepackagesWorkersSchedules, ], + 'basepackages_workers_calls' => [ + 'schema' => new Calls, + 'model' => new BasepackagesWorkersCalls, + ], 'basepackages_workers_tasks' => [ 'schema' => new Tasks, 'model' => new BasepackagesWorkersTasks, diff --git a/system/Base/Installer/Packages/Setup/Schema/Basepackages/Workers/Calls.php b/system/Base/Installer/Packages/Setup/Schema/Basepackages/Workers/Calls.php new file mode 100644 index 000000000..2399eec68 --- /dev/null +++ b/system/Base/Installer/Packages/Setup/Schema/Basepackages/Workers/Calls.php @@ -0,0 +1,103 @@ + [ + new Column( + 'id', + [ + 'type' => Column::TYPE_SMALLINTEGER, + 'notNull' => true, + 'autoIncrement' => true, + 'primary' => true, + ] + ), + new Column( + 'name', + [ + 'type' => Column::TYPE_VARCHAR, + 'size' => 100, + 'notNull' => true, + ] + ), + new Column( + 'display_name', + [ + 'type' => Column::TYPE_VARCHAR, + 'size' => 255, + 'notNull' => true, + ] + ), + new Column( + 'description', + [ + 'type' => Column::TYPE_VARCHAR, + 'size' => 2048, + 'notNull' => false, + ] + ), + new Column( + 'class', + [ + 'type' => Column::TYPE_VARCHAR, + 'size' => 512, + 'notNull' => true, + ] + ), + new Column( + 'can_be_scheduled', + [ + 'type' => Column::TYPE_BOOLEAN, + 'notNull' => true, + ] + ), + new Column( + 'can_be_run_on_demand', + [ + 'type' => Column::TYPE_BOOLEAN, + 'notNull' => true, + ] + ), + new Column( + 'package_id', + [ + 'type' => Column::TYPE_INTEGER, + 'notNull' => true, + ] + ) + ], + 'indexes' => [ + new Index( + 'column_UNIQUE', + [ + 'class' + ], + 'UNIQUE' + ) + ] + ]; + } + + public function indexes() + { + return + [ + new Index( + 'column_INDEX', + [ + 'name' + ], + 'INDEX' + ) + ]; + } +} \ No newline at end of file diff --git a/system/Base/Installer/Packages/Setup/Schema/Basepackages/Workers/Tasks.php b/system/Base/Installer/Packages/Setup/Schema/Basepackages/Workers/Tasks.php index 5faa6adb3..f21545687 100644 --- a/system/Base/Installer/Packages/Setup/Schema/Basepackages/Workers/Tasks.php +++ b/system/Base/Installer/Packages/Setup/Schema/Basepackages/Workers/Tasks.php @@ -86,11 +86,10 @@ public function columns() 'notNull' => true, ] ), - new Column( - 'call', + new Column(//Call ID + 'cid', [ - 'type' => Column::TYPE_VARCHAR, - 'size' => 2048, + 'type' => Column::TYPE_INTEGER, 'notNull' => false, ] ), @@ -101,7 +100,7 @@ public function columns() 'notNull' => false, ] ), - new Column( + new Column(//Raw Process Id 'pid', [ 'type' => Column::TYPE_INTEGER, diff --git a/system/Base/Installer/Packages/Setup/Schema/Modules/Externals.php b/system/Base/Installer/Packages/Setup/Schema/Modules/Externals.php index df1756c5d..8dca5b5cf 100644 --- a/system/Base/Installer/Packages/Setup/Schema/Modules/Externals.php +++ b/system/Base/Installer/Packages/Setup/Schema/Modules/Externals.php @@ -148,7 +148,8 @@ public function columns() new Index( 'column_UNIQUE', [ - 'name' + 'name', + 'developer' ], 'UNIQUE' ) diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Model/Workers/BasepackagesWorkersCalls.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Model/Workers/BasepackagesWorkersCalls.php new file mode 100644 index 000000000..64d05e4e5 --- /dev/null +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Model/Workers/BasepackagesWorkersCalls.php @@ -0,0 +1,24 @@ +progressFileName === 'setup') { + return; + } + if (!$progressFile) { $progressFile = $this->checkProgressFile(); } diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers.php index 252844a61..0576a2536 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers.php @@ -2,16 +2,16 @@ namespace System\Base\Providers\BasepackagesServiceProvider\Packages; -use GO\Scheduler; use Carbon\Carbon; +use GO\Scheduler; use GO\Traits\Interval; -use System\Base\BasePackage; -use League\Flysystem\UnableToReadFile; use League\Flysystem\FilesystemException; -use System\Base\Providers\BasepackagesServiceProvider\Packages\Workers\Jobs; +use League\Flysystem\UnableToReadFile; +use System\Base\BasePackage; use System\Base\Providers\BasepackagesServiceProvider\Packages\Workers\Calls; -use System\Base\Providers\BasepackagesServiceProvider\Packages\Workers\Tasks; +use System\Base\Providers\BasepackagesServiceProvider\Packages\Workers\Jobs; use System\Base\Providers\BasepackagesServiceProvider\Packages\Workers\Schedules; +use System\Base\Providers\BasepackagesServiceProvider\Packages\Workers\Tasks; use System\Base\Providers\BasepackagesServiceProvider\Packages\Workers\Workers as WorkersWorkers; class Workers extends BasePackage @@ -30,6 +30,8 @@ class Workers extends BasePackage public $jobs; + public $calls; + protected $cron; protected $scheduledJobs = []; @@ -46,12 +48,10 @@ class Workers extends BasePackage protected $enabledTasks; - protected $availableCalls; + // protected $availableCalls; protected $outputDir; - protected $calls; - public function init(bool $resetCache = false) { $this->workers = (new WorkersWorkers())->init(true); @@ -62,6 +62,8 @@ public function init(bool $resetCache = false) $this->jobs = (new Jobs())->init(); + $this->calls = (new Calls())->init(); + if ($this->checkPath('var/workers')) { $this->schedulerSettings['tempDir'] = base_path('var/workers'); } @@ -79,8 +81,8 @@ public function init(bool $resetCache = false) $this->enabledTasks = $this->tasks->getEnabledTasks(); - $this->availableCalls = array_keys($this->tasks->getAllCalls()); - + // $this->availableCalls = array_keys($this->tasks->getAllCalls()); + // trace([$this->availableCalls]); return $this; } @@ -670,7 +672,7 @@ protected function schedulePhpSchedules($class, $args, $schedule) $args['job']['id'] => null ]; - if (property_exists($class, 'php_args') && method_exists($class,'getPhpArgs')) { + if (method_exists($class,'getPhpArgs')) { $phpArgs = array_merge($phpArgs, (new $class)->getPhpArgs()); } @@ -813,21 +815,49 @@ protected function schedulePhpSchedules($class, $args, $schedule) protected function scheduleRawSchedules($class, $args, $schedule) { + $class = new $class; + + $rawCmd = null; + + if (method_exists($class, 'getRawCmd')) { + $rawCmd = $class->getRawCmd(); + } + + if (is_null($rawCmd)) { + $this->calls->packagesData->responseCode = 1; + $this->calls->packagesData->responseMessage = 'Raw command not provided in the Calls class file.'; + + $this->calls->addJobResult($this->calls->packagesData, $args); + + $this->calls->updateJobTask(4, $args); + + return false; + } + $rawArgs = []; - if (property_exists($class, 'raw_args') && method_exists($class,'getRawArgs')) { - $rawArgs = (new $class)->getRawArgs(); + if (method_exists($class,'getRawArgs')) { + $rawArgs = $class->getRawArgs(); } if ($schedule['type'] === 'everyminute') { $this->scheduler->raw( - $task['raw'], + $rawCmd, $rawArgs, $args['task']['id'] . '-' . $schedule['type'] - )->everyminute(); + )-> + onlyOne(null, $this->removeStuckLockFile($args['task'], $schedule, null, $rawCmd))-> + output($this->outputDir . '/' . $args['task']['id'] . '-' . $schedule['type'] . '.log')-> + before(function() use ($args) { + $this->processBefore($args); + })-> + then(function () use ($args) { + $this->processThen($args); + }, true) + ->everyminute(); } else if ($schedule['type'] === 'everyxminutes') { $this->scheduler->raw( - $task['raw'], + $rawCmd, $rawArgs, $args['task']['id'] . '-' . $schedule['type'] )->everyminute( @@ -835,45 +865,90 @@ protected function scheduleRawSchedules($class, $args, $schedule) ); } else if ($schedule['type'] === 'everyxminutesbetween') { $this->scheduler->raw( - $task['raw'], + $rawCmd, $rawArgs, $args['task']['id'] . '-' . $schedule['type'] - )->everyminute( + )-> + onlyOne(null, $this->removeStuckLockFile($args['task'], $schedule, null, $rawCmd))-> + output($this->outputDir . '/' . $args['task']['id'] . '-' . $schedule['type'] . '.log')-> + before(function() use ($args) { + $this->processBefore($args); + })-> + then(function () use ($args) { + $this->processThen($args); + }, true) + ->everyminute( (int) $schedule['params']['minutes'] ); } else if ($schedule['type'] === 'hourly') { $this->scheduler->raw( - $task['raw'], + $rawCmd, $rawArgs, $args['task']['id'] . '-' . $schedule['type'] - )->hourly( + )-> + onlyOne(null, $this->removeStuckLockFile($args['task'], $schedule, null, $rawCmd))-> + output($this->outputDir . '/' . $args['task']['id'] . '-' . $schedule['type'] . '.log')-> + before(function() use ($args) { + $this->processBefore($args); + })-> + then(function () use ($args) { + $this->processThen($args); + }, true) + ->hourly( (int) $schedule['params']['hourly_minutes'] ); } else if ($schedule['type'] === 'daily') { $this->scheduler->raw( - $task['raw'], + $rawCmd, $rawArgs, $args['task']['id'] . '-' . $schedule['type'] - )->daily( + )-> + onlyOne(null, $this->removeStuckLockFile($args['task'], $schedule, null, $rawCmd))-> + output($this->outputDir . '/' . $args['task']['id'] . '-' . $schedule['type'] . '.log')-> + before(function() use ($args) { + $this->processBefore($args); + })-> + then(function () use ($args) { + $this->processThen($args); + }, true) + ->daily( (int) $schedule['params']['daily_hours'], (int) $schedule['params']['daily_minutes'] ); } else if ($schedule['type'] === 'weekly') { $this->scheduler->raw( - $task['raw'], + $rawCmd, $rawArgs, $args['task']['id'] . '-' . $schedule['type'] . '-' . $day - )->weekly( + )-> + onlyOne(null, $this->removeStuckLockFile($args['task'], $schedule, null, $rawCmd))-> + output($this->outputDir . '/' . $args['task']['id'] . '-' . $schedule['type'] . '.log')-> + before(function() use ($args) { + $this->processBefore($args); + })-> + then(function () use ($args) { + $this->processThen($args); + }, true) + ->weekly( $this->dayOfWeek, (int) $schedule['params']['weekly_hours'], (int) $schedule['params']['weekly_minutes'] ); } else if ($schedule['type'] === 'monthly') { $this->scheduler->raw( - $task['raw'], + $rawCmd, $rawArgs, $args['task']['id'] . '-' . $schedule['type'] . '-' . $month - )->monthly( + )-> + onlyOne(null, $this->removeStuckLockFile($args['task'], $schedule, null, $rawCmd))-> + output($this->outputDir . '/' . $args['task']['id'] . '-' . $schedule['type'] . '.log')-> + before(function() use ($args) { + $this->processBefore($args); + })-> + then(function () use ($args) { + $this->processThen($args); + }, true) + ->monthly( (int) $this->month, (int) $this->dateOfMonth, (int) $schedule['params']['monthly_hours'], @@ -884,14 +959,16 @@ protected function scheduleRawSchedules($class, $args, $schedule) protected function processBefore($args) { - $this->calls = new Calls; - $this->calls->updateJobTask(2, $args); } - protected function processThen($args) + protected function processThen($args, $rawCmd = false) { - $args['task']['pid'] = $this->getTaskProcessId($args['task'], base_path('public/index.php workers exec')); + if ($rawCmd) { + $args['task']['pid'] = $this->getTaskProcessId($args['task'], null, $rawCmd); + } else { + $args['task']['pid'] = $this->getTaskProcessId($args['task'], base_path('public/index.php workers exec')); + } $this->basepackages->workers->tasks->updateTask($args['task']); // var_dump($args); @@ -951,6 +1028,7 @@ protected function getTaskProcessId($task, $phpScript = null, $rawCommand = null } else if ($task['exec_type'] === 'raw' && $rawCommand) { // } + return $pid; } diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls.php index 7b2684088..4d6811633 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls.php @@ -3,13 +3,86 @@ namespace System\Base\Providers\BasepackagesServiceProvider\Packages\Workers; use System\Base\BasePackage; +use System\Base\Providers\BasepackagesServiceProvider\Packages\Model\Workers\BasepackagesWorkersCalls; class Calls extends BasePackage { + protected $modelToUse = BasepackagesWorkersCalls::class; + + protected $packageName = 'calls'; + + public $calls; + protected $startTime; protected $stopTime; + public function init(bool $resetCache = false) + { + $this->getAll($resetCache); + + return $this; + } + + public function getByCallName($name) + { + if ($this->config->databasetype === 'db') { + $conditions = + [ + 'conditions' => 'name = :name:', + 'bind' => + [ + 'name' => $name + ] + ]; + + $call = $this->getByParams($conditions); + } else { + $this->ffStore = $this->ff->store($this->ffStoreToUse); + + $call = $this->ffStore->findBy(['name', '=', $name]); + } + + if ($call && count($call) > 0) { + return $call[0]; + } + + return false; + } + + public function addCall(array $data) + { + if ($this->add($data)) { + $this->addResponse('Added new call ' . $data['name']); + } else { + $this->addResponse('Error adding new call', 1); + } + } + + public function updateCall(array $data) + { + $call = $this->getById($data['id']); + + $call = array_merge($call, $data); + + if ($this->update($call)) { + $this->addResponse('Updated call ' . $call['name']); + } else { + $this->addResponse('Error updating call', 1); + } + } + + public function removeCall(array $data) + { + $call = $this->getById($data['id']); + + if ($this->remove($data['id'])) { + $this->addResponse('Call removed'); + } else { + $this->addResponse('Error removing call', 1); + } + } + public function updateJobTask($status, $args) { $this->updateJob($status, $args); diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls/ProcessDbSync.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls/ProcessDbSync.php index 1e77f895c..12908af14 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls/ProcessDbSync.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls/ProcessDbSync.php @@ -7,7 +7,7 @@ class ProcessDbSync extends Calls { - public $funcName = 'Process DB Sync (Hybrid mode)'; + public $funcDisplayName = 'Process DB Sync (Hybrid mode)'; public function run(array $args = []) { diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls/ProcessEmailQueue.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls/ProcessEmailQueue.php index 0836a5c24..0184fc33e 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls/ProcessEmailQueue.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls/ProcessEmailQueue.php @@ -6,7 +6,7 @@ class ProcessEmailQueue extends Calls { - public $funcName = 'Process Email Queue'; + public $funcDisplayName = 'Process Email Queue'; protected $args; diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls/ProcessImportExportQueue.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls/ProcessImportExportQueue.php index 1d3f65a25..f6623c2da 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls/ProcessImportExportQueue.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls/ProcessImportExportQueue.php @@ -7,7 +7,7 @@ class ProcessImportExportQueue extends Calls { - public $funcName = 'Process Import/Export Queue'; + public $funcDisplayName = 'Process Import/Export Queue'; protected $args; diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls/ProcessPsef.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls/ProcessPsef.php new file mode 100644 index 000000000..5a0e3fccb --- /dev/null +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls/ProcessPsef.php @@ -0,0 +1,21 @@ +raw_cwd = 'ls -al /'; + + return $this->raw_cwd; + } +} \ No newline at end of file diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Tasks.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Tasks.php index bdf4fb839..b1ba33459 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Tasks.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Tasks.php @@ -66,12 +66,6 @@ public function getAllCalls() public function addTask(array $data) { - if (isset($data['type']) && $data['type'] == 0) { - $this->addResponse('Cannot add system task.', 1); - - return false; - } - if (!isset($data['priority']) || (isset($data['priority']) && $data['priority'] == '0')) { $data['priority'] = '1'; } @@ -90,14 +84,6 @@ public function updateTask(array $data) { $task = $this->getById($data['id']); - if (!isset($data['via_job']) && - (isset($task['type']) && $task['type'] == 0) - ) { - $this->addResponse('Cannot update system task.', 1); - - return false; - } - if (!isset($data['priority']) || (isset($data['priority']) && $data['priority'] == '0')) { $data['priority'] = '1'; } diff --git a/system/Base/Providers/ModulesServiceProvider/Modules/Packages.php b/system/Base/Providers/ModulesServiceProvider/Modules/Packages.php index e0a1fd965..260b8d04f 100644 --- a/system/Base/Providers/ModulesServiceProvider/Modules/Packages.php +++ b/system/Base/Providers/ModulesServiceProvider/Modules/Packages.php @@ -171,6 +171,17 @@ public function getPackageByName($name) return false; } + public function getPackageByClass($class) + { + foreach($this->packages as $package) { + if (strtolower($package['class']) === strtolower($class)) { + return $package; + } + } + + return false; + } + public function getPackagesForCategory($category) { $packages = []; diff --git a/system/Base/Providers/ModulesServiceProvider/TaskCallInstaller.php b/system/Base/Providers/ModulesServiceProvider/TaskCallInstaller.php new file mode 100644 index 000000000..e044d1dfe --- /dev/null +++ b/system/Base/Providers/ModulesServiceProvider/TaskCallInstaller.php @@ -0,0 +1,79 @@ +localContent->fileExists($packageFile)) { + $installPackageJsonFile = $this->helper->decode($this->localContent->read($packageFile), true); + + $package = $this->modules->packages->getPackageByClass($installPackageJsonFile['class']); + + if ($package) { + $packageFolder = 'apps/' . implode('/', array_slice(explode('\\', get_class($packageClass)), 1, -2)) . '/TaskCalls/'; + + $callsArr = $this->basepackages->utils->scanDir($packageFolder); + + if (count($callsArr['files']) > 0) { + foreach ($callsArr['files'] as $key => $call) { + $call = ucfirst($call); + $call = str_replace('/', '\\', $call); + $call = str_replace('.php', '', $call); + + $callClass = new $call; + $callReflection = new \ReflectionClass($call); + + $dbCall = $this->basepackages->workers->calls->getByCallName($callReflection->getShortName()); + + if (!$dbCall) { + $dbCall = []; + $dbCall['name'] = $callReflection->getShortName(); + $dbCall['display_name'] = $callReflection->getShortName(); + $dbCall['class'] = $callReflection->getName(); + if ($callReflection->hasProperty('funcDisplayName')) { + $dbCall['display_name'] = $callReflection->getProperty('funcDisplayName')->getValue($callClass); + } + $dbCall['description'] = ''; + if ($callReflection->hasProperty('funcDescription')) { + $dbCall['description'] = $callReflection->getProperty('funcDescription')->getValue($callClass); + } + $dbCall['can_be_scheduled'] = true; + if ($callReflection->hasProperty('funcCanBeScheduled')) { + $dbCall['can_be_scheduled'] = $callReflection->getProperty('funcCanBeScheduled')->getValue($callClass); + } + $dbCall['can_be_run_on_demand'] = true; + if ($callReflection->hasProperty('funcCanBeRunOnDemand')) { + $dbCall['can_be_run_on_demand'] = $callReflection->getProperty('funcCanBeRunOnDemand')->getValue($callClass); + } + $dbCall['package_id'] = $package['id']; + + $this->basepackages->workers->calls->addCall($dbCall); + } + } + } + } + } + } catch (FilesystemException | UnableToCheckExistence | UnableToReadFile | \throwable $e) { + throw $e; + } + + return true; + } + + public function uninstallTaskCall($packageClass) + { + //Check for running jobs + //Uninstall Task associated with the call + //Uninstall Call + } +} \ No newline at end of file diff --git a/system/Base/Providers/ModulesServiceProvider/WidgetInstaller.php b/system/Base/Providers/ModulesServiceProvider/WidgetInstaller.php new file mode 100644 index 000000000..d05e2d238 --- /dev/null +++ b/system/Base/Providers/ModulesServiceProvider/WidgetInstaller.php @@ -0,0 +1 @@ +//Will be used to install Component Widgets via modules \ No newline at end of file From ffcc3322219fa0e8d0d5b2ed0fee8047bcb25913 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Sun, 9 Mar 2025 15:46:15 +1100 Subject: [PATCH 14/40] fix auth after implementing fix for issue #657 --- .../BasepackagesServiceProvider/Packages/Users/Accounts.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Users/Accounts.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Users/Accounts.php index 915c9c48f..9231e4f39 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Users/Accounts.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Users/Accounts.php @@ -24,6 +24,8 @@ class Accounts extends BasePackage public function getAccountById(int $id) { + $this->ffStore = $this->ff->store($this->ffStoreToUse); + $this->setFFRelations(true); $this->setFFRelationsConditions( From db5539663752303d47f81e69ba45e7bf8fbb85a7 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Sun, 9 Mar 2025 18:59:41 +1100 Subject: [PATCH 15/40] update issue #660 --- .../System/Workers/Tasks/TasksComponent.php | 29 ++++++++- apps/Core/Packages/Adminltetags/Tags/Tree.php | 16 ++++- .../html/system/workers/tasks/form.html | 60 ++++++++++++++++--- system/Base/BasePackage.php | 2 +- .../Workers/BasepackagesWorkersCalls.php | 26 ++++++++ .../Workers/BasepackagesWorkersTasks.php | 26 ++++++++ .../Packages/Workers.php | 32 ++++++++-- .../Packages/Workers/Calls.php | 2 + .../Packages/Workers/Calls/ProcessDbSync.php | 2 + .../Workers/Calls/ProcessEmailQueue.php | 2 + .../Calls/ProcessImportExportQueue.php | 2 + .../Packages/Workers/Tasks.php | 45 +++----------- 12 files changed, 190 insertions(+), 54 deletions(-) diff --git a/apps/Core/Components/System/Workers/Tasks/TasksComponent.php b/apps/Core/Components/System/Workers/Tasks/TasksComponent.php index fc807c794..5453412b4 100644 --- a/apps/Core/Components/System/Workers/Tasks/TasksComponent.php +++ b/apps/Core/Components/System/Workers/Tasks/TasksComponent.php @@ -11,11 +11,15 @@ class TasksComponent extends BaseComponent protected $tasks; + protected $calls; + protected $schedules; public function initialize() { $this->tasks = $this->basepackages->workers->tasks; + + $this->calls = $this->basepackages->workers->calls->calls; } /** @@ -26,7 +30,29 @@ public function viewAction() $this->schedules = $this->basepackages->workers->schedules->schedules; if (isset($this->getData()['id'])) { - $calls = $this->tasks->getAllCalls(); + $calls = []; + + if ($this->calls && count($this->calls) > 0) { + foreach ($this->calls as $thisCalls) { + if (!$thisCalls['package']) { + continue; + } + + if (!isset($calls[$thisCalls['id']])) { + $calls[$thisCalls['id']] = []; + } + + $calls[$thisCalls['id']]['id'] = $thisCalls['id']; + $calls[$thisCalls['id']]['name'] = $thisCalls['display_name'] ?? $thisCalls['name']; + $calls[$thisCalls['id']]['description'] = $thisCalls['description']; + $calls[$thisCalls['id']]['package_id'] = $thisCalls['package_id']; + $calls[$thisCalls['id']]['package_name'] = $thisCalls['package']['display_name'] ?? $thisCalls['package']['name']; + } + } + + $this->tasks->setFFRelations(true); + + // $calls = $this->tasks->getAllCalls(); $this->view->calls = $calls; @@ -45,6 +71,7 @@ public function viewAction() $this->view->task = $task; } + $this->view->pick('tasks/view'); return; diff --git a/apps/Core/Packages/Adminltetags/Tags/Tree.php b/apps/Core/Packages/Adminltetags/Tags/Tree.php index dbc63acc2..517bf633b 100644 --- a/apps/Core/Packages/Adminltetags/Tags/Tree.php +++ b/apps/Core/Packages/Adminltetags/Tags/Tree.php @@ -398,7 +398,21 @@ protected function treeItem($key, $items, $itemIcon, $children = null) $key = $itemValue[$this->fieldParams['fieldDataSelect' . $selectType . 'OptionsKey']]; if (count($this->fieldParams['fieldDataSelect' . $selectType . 'OptionsValue']) === 1) { - $value = $itemValue[$this->fieldParams['fieldDataSelect' . $selectType . 'OptionsValue'][0]]; + if (is_string($this->fieldParams['fieldDataSelect' . $selectType . 'OptionsValue'][0])) { + $optionsValueKey = explode(':', $this->fieldParams['fieldDataSelect' . $selectType . 'OptionsValue'][0]); + } + + if (count($optionsValueKey) === 1) { + $optionsValueKey = $optionsValueKey[0]; + + if (isset($itemValue[$optionsValueKey])) { + $value = $itemValue[$optionsValueKey]; + } + } else { + if (isset($itemValue[$optionsValueKey[0]]) && isset($itemValue[$optionsValueKey[1]])) { + $value = $itemValue[$optionsValueKey[0]] . ' (' . $itemValue[$optionsValueKey[1]] . ')'; + } + } } else { foreach ($this->fieldParams['fieldDataSelect' . $selectType . 'OptionsValue'] as $optionsValueKey) { if (is_string($optionsValueKey)) { diff --git a/apps/Core/Views/Default/html/system/workers/tasks/form.html b/apps/Core/Views/Default/html/system/workers/tasks/form.html index f5988a750..039d03a47 100644 --- a/apps/Core/Views/Default/html/system/workers/tasks/form.html +++ b/apps/Core/Views/Default/html/system/workers/tasks/form.html @@ -22,7 +22,7 @@ {% set taskScheduleDisabled = true %} {% endif %} {% set taskExecType = task['exec_type'] %} - {% set taskCall = task['call'] %} + {% set taskCall = task['cid'] %} {% set taskCallArgs = task['call_args'] %} {% else %} {% set taskId = '' %} @@ -259,8 +259,8 @@ 'componentName' : componentName, 'componentId' : componentId, 'sectionId' : sectionId, - 'fieldId' : 'call', - 'fieldLabel' : 'Call Function', + 'fieldId' : 'cid', + 'fieldLabel' : 'Call Function (Package)', 'fieldType' : 'select2', 'fieldHelp' : true, 'fieldHelpTooltipContent' : "Task's function to call", @@ -269,14 +269,34 @@ 'fieldBazPostOnCreate' : true, 'fieldBazPostOnUpdate' : true, 'fieldDataSelect2Options' : calls, - 'fieldDataSelect2OptionsKey' : 'func', - 'fieldDataSelect2OptionsValue' : 'name', + 'fieldDataSelect2OptionsKey' : 'id', + 'fieldDataSelect2OptionsValue' : 'name:package_name', 'fieldDataSelect2OptionsArray' : true, 'fieldDataSelect2OptionsSelected' : taskCall ] )}} +
+
+ {{adminltetags.useTag('fields', + [ + 'component' : component, + 'componentName' : componentName, + 'componentId' : componentId, + 'sectionId' : sectionId, + 'fieldId' : 'call_description', + 'fieldLabel' : false, + 'fieldType' : 'html', + 'fieldHelp' : false, + 'fieldHelpTooltipContent' : '', + 'fieldBazJstreeSearch' : false, + 'fieldBazScan' : false + ] + )}} +
+
+ {% set calls = json_encode(calls, 16) %}
{{adminltetags.useTag('fields', @@ -333,6 +353,9 @@ dataCollectionSection['{{componentId}}-{{sectionId}}-form']; } +dataCollectionSectionForm['vars'] = { }; +dataCollectionSectionForm['vars']['calls'] = JSON.parse('{{calls}}'); + dataCollectionSection = $.extend(dataCollectionSection, { '{{componentId}}-{{sectionId}}-id' : { }, @@ -361,21 +384,40 @@ '{{componentId}}-{{sectionId}}-schedule_id' : { placeholder : "SELECT SCHEDULE" }, - '{{componentId}}-{{sectionId}}-call' : { - placeholder : "SELECT FUNCTION TO CALL" + '{{componentId}}-{{sectionId}}-cid' : { + placeholder : "SELECT FUNCTION TO CALL", + afterInit: function() { + var id; + + $('#{{componentId}}-{{sectionId}}-call').on('select2:select', function(e) { + id = e.params.data.id; + + if (dataCollectionSectionForm['vars']['calls'][id]) { + if (dataCollectionSectionForm['vars']['calls'][id]['description'] && + dataCollectionSectionForm['vars']['calls'][id]['description'] !== '' + ) { + $('#{{componentId}}-{{sectionId}}-call_description').html(' ' + dataCollectionSectionForm['vars']['calls'][id]['description'] + ''); + } else { + $('#{{componentId}}-{{sectionId}}-call_description').html(''); + } + } else { + $('#{{componentId}}-{{sectionId}}-call_description').html(''); + } + }); + } }, '{{componentId}}-{{sectionId}}-form' : { rules: { '{{componentId}}-{{sectionId}}-name' : 'required', '{{componentId}}-{{sectionId}}-priority' : 'required', '{{componentId}}-{{sectionId}}-schedule_id' : 'required', - '{{componentId}}-{{sectionId}}-call' : 'required' + '{{componentId}}-{{sectionId}}-cid' : 'required' }, messages: { '{{componentId}}-{{sectionId}}-name' : 'Please enter Service name', '{{componentId}}-{{sectionId}}-priority' : 'Please enter priority between 1 and 10', '{{componentId}}-{{sectionId}}-schedule_id' : 'Please select a schedule', - '{{componentId}}-{{sectionId}}-call' : 'Please select a function to call' + '{{componentId}}-{{sectionId}}-cid' : 'Please select a function to call' } } }); diff --git a/system/Base/BasePackage.php b/system/Base/BasePackage.php index a1b2bee18..2991a7e6d 100644 --- a/system/Base/BasePackage.php +++ b/system/Base/BasePackage.php @@ -285,7 +285,7 @@ public function getAll(bool $resetCache = false, bool $enableCache = true, $mode $this->ffStore = $this->ff->store($this->ffStoreToUse); } - $allPackages = $this->ffStore->findAll(); + $allPackages = $this->ffStore->findAll(null, null, null, $this->ffRelations, $this->ffRelationsConditions); $this->setFfStoreToUse(); } diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Model/Workers/BasepackagesWorkersCalls.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Model/Workers/BasepackagesWorkersCalls.php index 64d05e4e5..c6c5b3f92 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Model/Workers/BasepackagesWorkersCalls.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Model/Workers/BasepackagesWorkersCalls.php @@ -3,9 +3,12 @@ namespace System\Base\Providers\BasepackagesServiceProvider\Packages\Model\Workers; use System\Base\BaseModel; +use System\Base\Providers\ModulesServiceProvider\Modules\Model\ModulesPackages; class BasepackagesWorkersCalls extends BaseModel { + protected $modelRelations = []; + public $id; public $name; @@ -21,4 +24,27 @@ class BasepackagesWorkersCalls extends BaseModel public $can_be_run_on_demand; public $package_id; + + public function initialize() + { + $this->modelRelations['package']['relationObj'] = $this->hasOne( + 'package_id', + ModulesPackages::class, + 'id', + [ + 'alias' => 'package' + ] + ); + + parent::initialize(); + } + + public function getModelRelations() + { + if (count($this->modelRelations) === 0) { + $this->initialize(); + } + + return $this->modelRelations; + } } \ No newline at end of file diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Model/Workers/BasepackagesWorkersTasks.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Model/Workers/BasepackagesWorkersTasks.php index 574fc6714..15cc45bb8 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Model/Workers/BasepackagesWorkersTasks.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Model/Workers/BasepackagesWorkersTasks.php @@ -3,9 +3,12 @@ namespace System\Base\Providers\BasepackagesServiceProvider\Packages\Model\Workers; use System\Base\BaseModel; +use System\Base\Providers\BasepackagesServiceProvider\Packages\Model\Workers\BasepackagesWorkersCalls; class BasepackagesWorkersTasks extends BaseModel { + protected $modelRelations = []; + public $id; public $name; @@ -41,4 +44,27 @@ class BasepackagesWorkersTasks extends BaseModel public $email; public $result; + + public function initialize() + { + $this->modelRelations['call']['relationObj'] = $this->hasOne( + 'cid', + BasepackagesWorkersCalls::class, + 'id', + [ + 'alias' => 'call' + ] + ); + + parent::initialize(); + } + + public function getModelRelations() + { + if (count($this->modelRelations) === 0) { + $this->initialize(); + } + + return $this->modelRelations; + } } \ No newline at end of file diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers.php index 0576a2536..e1426e1b7 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers.php @@ -81,8 +81,24 @@ public function init(bool $resetCache = false) $this->enabledTasks = $this->tasks->getEnabledTasks(); - // $this->availableCalls = array_keys($this->tasks->getAllCalls()); - // trace([$this->availableCalls]); + $this->availableCalls = []; + + if ($this->calls->calls && count($this->calls->calls) > 0) { + foreach ($this->calls->calls as $thisCalls) { + if (!$thisCalls['package']) { + continue; + } + + if (!isset($calls[$thisCalls['id']])) { + $calls[$thisCalls['id']] = []; + } + + $this->availableCalls[$thisCalls['id']]['id'] = $thisCalls['id']; + $this->availableCalls[$thisCalls['id']]['name'] = $thisCalls['name']; + $this->availableCalls[$thisCalls['id']]['package_class'] = $thisCalls['package']['class']; + } + } + return $this; } @@ -110,8 +126,16 @@ public function run() $schedule = $this->schedules->getSchedulesSchedule($task['schedule_id']); $class = null; - if (in_array($task['call'], $this->availableCalls)) { - $class = 'System\\Base\\Providers\\BasepackagesServiceProvider\\Packages\\Workers\\Calls\\' . ucfirst($task['call']); + if (isset($this->availableCalls[$task['cid']])) { + if (str_starts_with($this->availableCalls[$task['cid']]['package_class'], 'System')) { + $class = 'System\\Base\\Providers\\BasepackagesServiceProvider\\Packages\\Workers\\Calls\\' . ucfirst($this->availableCalls[$task['cid']]['name']); + } else if (str_starts_with($this->availableCalls[$task['cid']]['package_class'], 'Apps')) { + $packageClassArr = explode('\\', $this->availableCalls[$task['cid']]['package_class']); + unset($packageClassArr[$this->helper->lastKey($packageClassArr)]); + $this->availableCalls[$task['cid']]['package_class'] = implode('\\', $packageClassArr); + + $class = $this->availableCalls[$task['cid']]['package_class'] . '\\TaskCalls\\' . ucfirst($this->availableCalls[$task['cid']]['name']); + } } else { $task['enabled'] = 0; $task['status'] = 3;//Error diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls.php index 4d6811633..5f86f5636 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls.php @@ -19,6 +19,8 @@ class Calls extends BasePackage public function init(bool $resetCache = false) { + $this->setFFRelations(true); + $this->getAll($resetCache); return $this; diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls/ProcessDbSync.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls/ProcessDbSync.php index 12908af14..892e82ea3 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls/ProcessDbSync.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls/ProcessDbSync.php @@ -9,6 +9,8 @@ class ProcessDbSync extends Calls { public $funcDisplayName = 'Process DB Sync (Hybrid mode)'; + public $funcDescription = 'Process sync of FF data with DB data.'; + public function run(array $args = []) { $thisCall = $this; diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls/ProcessEmailQueue.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls/ProcessEmailQueue.php index 0184fc33e..98b5171ba 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls/ProcessEmailQueue.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls/ProcessEmailQueue.php @@ -8,6 +8,8 @@ class ProcessEmailQueue extends Calls { public $funcDisplayName = 'Process Email Queue'; + public $funcDescription = 'Process email queue with this call.'; + protected $args; public function run(array $args = []) diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls/ProcessImportExportQueue.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls/ProcessImportExportQueue.php index f6623c2da..d343f3f46 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls/ProcessImportExportQueue.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls/ProcessImportExportQueue.php @@ -9,6 +9,8 @@ class ProcessImportExportQueue extends Calls { public $funcDisplayName = 'Process Import/Export Queue'; + public $funcDescription = 'Process import/export processes with this call.'; + protected $args; public function run(array $args = []) diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Tasks.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Tasks.php index b1ba33459..9e3ea8b96 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Tasks.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Tasks.php @@ -24,46 +24,13 @@ public function getFunctionsDir() public function init(bool $resetCache = false) { + $this->setFFRelations(true); + $this->getAll($resetCache); return $this; } - public function getAllCalls() - { - $callsArr = - $this->localContent->listContents($this->callsDir, true) - ->filter(fn (StorageAttributes $attributes) => $attributes->isFile()) - ->map(fn (StorageAttributes $attributes) => $attributes->path()) - ->toArray(); - - $calls = []; - - if (count($callsArr) > 0) { - foreach ($callsArr as $key => $call) { - $call = ucfirst($call); - $call = str_replace('/', '\\', $call); - $call = str_replace('.php', '', $call); - - try { - $call = new $call(); - - $calls[$call->packageName]['func'] = $call->packageName; - $calls[$call->packageName]['name'] = $call->funcName; - - } catch (\throwable $e) { - - if ($this->config->logs->exceptions) { - $this->logger->logExceptions->critical(json_trace($e)); - } - continue; - } - } - } - - return $calls; - } - public function addTask(array $data) { if (!isset($data['priority']) || (isset($data['priority']) && $data['priority'] == '0')) { @@ -116,6 +83,8 @@ public function removeTask(array $data) public function forceNextRun(array $data) { + $this->setFFRelations(true); + $task = $this->getById($data['id']); $task = array_merge($task, $data); @@ -124,7 +93,7 @@ public function forceNextRun(array $data) if (isset($data['cancel']) && $data['cancel'] == 'true') { if ($this->config->databasetype === 'hybrid' && - $task['call'] === 'processdbsync' + $task['call']['name'] === 'ProcessDbSync' ) { $this->ff->setSync(false); } @@ -205,7 +174,7 @@ public function findByCallArgs($argValue, $argKey = null, $function = null) } foreach ($this->tasks as $taskKey => $task) { - if ($function && $task['call'] !== $function) { + if ($function && $task['call']['name'] !== $function) { continue; } @@ -228,7 +197,7 @@ public function findByCall($function) } foreach ($this->tasks as $taskKey => $task) { - if ($task['call'] === $function) { + if ($task['call']['name'] === $function) { return $task; } } From ca14af422a77ae2c6c836e94f1acbb25bc37362c Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Sun, 9 Mar 2025 22:33:26 +1100 Subject: [PATCH 16/40] cleanup #660 --- .../BasepackagesServiceProvider/Packages/Workers/Tasks.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Tasks.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Tasks.php index 9e3ea8b96..93c4ae35a 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Tasks.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Tasks.php @@ -13,15 +13,8 @@ class Tasks extends BasePackage protected $packageName = 'tasks'; - protected $callsDir = 'system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Calls/'; - public $tasks; - public function getFunctionsDir() - { - return $this->callsDir; - } - public function init(bool $resetCache = false) { $this->setFFRelations(true); From b117848ea16b83ed749cf953650c5a70e9266716 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Mon, 10 Mar 2025 04:17:07 +1100 Subject: [PATCH 17/40] fix issue #661 --- .../Ff/Classes/DocumentFinder.php | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/DocumentFinder.php b/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/DocumentFinder.php index 01cd2733b..a4d09cca9 100644 --- a/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/DocumentFinder.php +++ b/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/DocumentFinder.php @@ -89,7 +89,11 @@ public function findDocuments(bool $getOneDocument, bool $reduceAndJoinPossible) $indexSearched = true; //trim % (like), change space to + for multikeyword search. - $keyword = str_replace(' ', '+', strtolower(trim($condition[0][2], '%'))); + if (is_string($condition[0][2])) { + $keyword = str_replace(' ', '+', strtolower(trim($condition[0][2], '%'))); + } else { + $keyword = $condition[0][2]; + } if ($this->multiWords === true && str_contains($keyword, '+')) { $keywordArr = explode('+', $keyword); @@ -99,7 +103,11 @@ public function findDocuments(bool $getOneDocument, bool $reduceAndJoinPossible) continue; } - $indexChars = strtolower(mb_substr($keyword, 0, $this->minIndexChars, 'UTF-8')); + if (is_string($keyword)) { + $indexChars = strtolower(mb_substr($keyword, 0, $this->minIndexChars, 'UTF-8')); + } else { + $indexChars = $keyword; + } $found = array_merge($found, $this->searchIndexes($condition, $indexChars, $skip, $limit, $keyword)); } @@ -108,7 +116,11 @@ public function findDocuments(bool $getOneDocument, bool $reduceAndJoinPossible) continue; } - $indexChars = strtolower(mb_substr($keyword, 0, $this->minIndexChars, 'UTF-8')); + if (is_string($keyword)) { + $indexChars = strtolower(mb_substr($keyword, 0, $this->minIndexChars, 'UTF-8')); + } else { + $indexChars = $keyword; + } $found = array_merge($found, $this->searchIndexes($condition, $indexChars, $skip, $limit, $keyword)); } From 050eb89545d9fb7ec3640b3133743be80cb766ae Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Tue, 11 Mar 2025 13:50:39 +1100 Subject: [PATCH 18/40] fix issue #664 --- .../Packages/Workers/Schedules.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Schedules.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Schedules.php index a63e7af8a..435ce79a8 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Schedules.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers/Schedules.php @@ -76,16 +76,24 @@ public function removeSchedule(array $data) return false; } - $assignedToTasks = - $this->basepackages->workers->tasks->getByParams( + if ($this->config->databasetype === 'db') { + $params = [ 'conditions' => 'schedule_id = :sid:', 'bind' => [ 'sid' => $schedule['id'] ] - ] - ); + ]; + } else { + $params = [ + 'conditions' => [ + ['schedule_id', '=', $schedule['id']] + ] + ]; + } + + $assignedToTasks = $this->basepackages->workers->tasks->getByParams($params); if ($assignedToTasks && count($assignedToTasks) > 0) { $this->addResponse('Schedule assigned to task. Cannot remove schedule.', 1); From 039d9ac11c076d96180c45a52dca027b1921139b Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Tue, 11 Mar 2025 14:37:28 +1100 Subject: [PATCH 19/40] fix issue #665 --- .../System/Users/Profile/ProfileComponent.php | 4 ++++ .../Default/html/system/users/profile/form.html | 12 ++++++++++++ .../Setup/Schema/Basepackages/Users/Profiles.php | 14 ++++++++++++++ .../Model/Users/BasepackagesUsersProfiles.php | 4 ++++ 4 files changed, 34 insertions(+) diff --git a/apps/Core/Components/System/Users/Profile/ProfileComponent.php b/apps/Core/Components/System/Users/Profile/ProfileComponent.php index 66f61da0c..ce96cf0e3 100644 --- a/apps/Core/Components/System/Users/Profile/ProfileComponent.php +++ b/apps/Core/Components/System/Users/Profile/ProfileComponent.php @@ -60,6 +60,10 @@ public function viewAction() $this->view->canUse2fa = $this->profiles->packagesData->canUse2fa; + $this->view->countries = $this->basepackages->geoCountries->getAll()->geoCountries; + + $this->view->timezones = $this->basepackages->geoTimezones->getAll()->geoTimezones; + $apis = $this->api->getApiInfo(false, true); $passwordApis = []; if ($apis && count($apis) > 0) { diff --git a/apps/Core/Views/Default/html/system/users/profile/form.html b/apps/Core/Views/Default/html/system/users/profile/form.html index a5fe97874..805d121d8 100644 --- a/apps/Core/Views/Default/html/system/users/profile/form.html +++ b/apps/Core/Views/Default/html/system/users/profile/form.html @@ -82,6 +82,12 @@ 'tabInclude' : 'profile/form/contactdetails', 'tabIncludeParams' : ['profile' : profile, 'account' : account] ], + 'locale' : + [ + 'tabTitle' : 'Locale', + 'tabInclude' : 'profile/form/locale', + 'tabIncludeParams' : ['profile' : profile, 'account' : account] + ], 'address' : [ 'tabTitle' : 'Address', @@ -326,6 +332,12 @@ '{{componentId}}-{{sectionId}}-secondary_email' : { }, '{{componentId}}-{{sectionId}}-cc_emails_to_secondary_email' : { }, '{{componentId}}-{{sectionId}}-contact_notes' : { }, + '{{componentId}}-{{sectionId}}-locale_country_id' : { + placeholder : 'SELECT COUNTRY' + }, + '{{componentId}}-{{sectionId}}-locale_timezone_id' : { + placeholder : 'SELECT TIMEZONE' + }, '{{componentId}}-{{sectionId}}-address_id' : { }, '{{componentId}}-{{sectionId}}-current_password' : { afterInit: function() { diff --git a/system/Base/Installer/Packages/Setup/Schema/Basepackages/Users/Profiles.php b/system/Base/Installer/Packages/Setup/Schema/Basepackages/Users/Profiles.php index 4bfe32a5e..3e7a26e92 100644 --- a/system/Base/Installer/Packages/Setup/Schema/Basepackages/Users/Profiles.php +++ b/system/Base/Installer/Packages/Setup/Schema/Basepackages/Users/Profiles.php @@ -137,6 +137,20 @@ public function columns() 'notNull' => false, ] ), + new Column( + 'locale_country_id', + [ + 'type' => Column::TYPE_SMALLINTEGER, + 'notNull' => false, + ] + ), + new Column( + 'locale_timezone_id', + [ + 'type' => Column::TYPE_SMALLINTEGER, + 'notNull' => false, + ] + ), new Column( 'settings', [ diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Model/Users/BasepackagesUsersProfiles.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Model/Users/BasepackagesUsersProfiles.php index ea8b6076d..243d8c1bc 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Model/Users/BasepackagesUsersProfiles.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Model/Users/BasepackagesUsersProfiles.php @@ -42,6 +42,10 @@ class BasepackagesUsersProfiles extends BaseModel public $contact_notes; + public $locale_country_id; + + public $locale_timezone_id; + public $settings; public function initialize() From 22d3f31854ed23dd0bd81757895d273f41101bc1 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Tue, 11 Mar 2025 14:42:55 +1100 Subject: [PATCH 20/40] fix issue #665, added form to accounts. --- .../Users/Accounts/AccountsComponent.php | 4 ++ .../html/system/users/accounts/form.html | 11 ++++ .../system/users/accounts/form/locale.html | 60 +++++++++++++++++++ .../system/users/profile/form/locale.html | 60 +++++++++++++++++++ 4 files changed, 135 insertions(+) create mode 100644 apps/Core/Views/Default/html/system/users/accounts/form/locale.html create mode 100644 apps/Core/Views/Default/html/system/users/profile/form/locale.html diff --git a/apps/Core/Components/System/Users/Accounts/AccountsComponent.php b/apps/Core/Components/System/Users/Accounts/AccountsComponent.php index f6425cb96..cbe0c2650 100644 --- a/apps/Core/Components/System/Users/Accounts/AccountsComponent.php +++ b/apps/Core/Components/System/Users/Accounts/AccountsComponent.php @@ -82,6 +82,10 @@ public function viewAction() $this->view->apps = $this->accounts->packagesData->apps; $this->view->roles = $this->accounts->packagesData->roles; + + $this->view->countries = $this->basepackages->geoCountries->getAll()->geoCountries; + + $this->view->timezones = $this->basepackages->geoTimezones->getAll()->geoTimezones; } $this->addResponse( diff --git a/apps/Core/Views/Default/html/system/users/accounts/form.html b/apps/Core/Views/Default/html/system/users/accounts/form.html index b016778ae..33bbb4457 100644 --- a/apps/Core/Views/Default/html/system/users/accounts/form.html +++ b/apps/Core/Views/Default/html/system/users/accounts/form.html @@ -63,6 +63,11 @@ [ 'tabTitle' : 'Tools', 'tabInclude' : 'accounts/form/tools' + ], + 'locale' : + [ + 'tabTitle' : 'Locale', + 'tabInclude' : 'accounts/form/locale' ] ] ] @@ -115,6 +120,12 @@ '{{componentId}}-{{sectionId}}-force_pwreset' : { }, '{{componentId}}-{{sectionId}}-force_logout' : { }, '{{componentId}}-{{sectionId}}-disable_twofa_otp' : { }, + '{{componentId}}-{{sectionId}}-locale_country_id' : { + placeholder : 'SELECT COUNTRY' + }, + '{{componentId}}-{{sectionId}}-locale_timezone_id' : { + placeholder : 'SELECT TIMEZONE' + }, //Validation '{{componentId}}-{{sectionId}}-form' : { ignore: ':submit, :reset, :image, :disabled, .ignore, .cr-slider', diff --git a/apps/Core/Views/Default/html/system/users/accounts/form/locale.html b/apps/Core/Views/Default/html/system/users/accounts/form/locale.html new file mode 100644 index 000000000..a88463875 --- /dev/null +++ b/apps/Core/Views/Default/html/system/users/accounts/form/locale.html @@ -0,0 +1,60 @@ +{% set countryId = 0 %} +{% if account['profile']['locale_country_id'] is defined %} + {% set countryId = account['profile']['locale_country_id'] %} +{% endif %} +{% set timezoneId = 0 %} +{% if account['profile']['locale_timezone_id'] is defined %} + {% set timezoneId = account['profile']['locale_timezone_id'] %} +{% endif %} +
+
+ {{adminltetags.useTag('fields', + [ + 'component' : component, + 'componentName' : componentName, + 'componentId' : componentId, + 'sectionId' : sectionId, + 'fieldId' : 'locale_country_id', + 'fieldLabel' : 'Country', + 'fieldType' : 'select2', + 'fieldHelp' : true, + 'fieldHelpTooltipContent' : 'Select country', + 'fieldRequired' : false, + 'fieldBazScan' : true, + 'fieldBazJstreeSearch' : true, + 'fieldBazPostOnCreate' : true, + 'fieldBazPostOnUpdate' : true, + 'fieldDataSelect2Options' : countries, + 'fieldDataSelect2OptionsKey' : 'id', + 'fieldDataSelect2OptionsValue' : 'name', + 'fieldDataSelect2OptionsArray' : true, + 'fieldDataSelect2OptionsSelected' : countryId + ] + )}} +
+
+ {{adminltetags.useTag('fields', + [ + 'component' : component, + 'componentName' : componentName, + 'componentId' : componentId, + 'sectionId' : sectionId, + 'fieldId' : 'locale_timezone_id', + 'fieldLabel' : 'Timezone', + 'fieldType' : 'select2', + 'fieldHelp' : true, + 'fieldHelpTooltipContent' : 'Select timezone', + 'fieldRequired' : false, + 'fieldBazScan' : true, + 'fieldBazJstreeSearch' : true, + 'fieldBazPostOnCreate' : true, + 'fieldBazPostOnUpdate' : true, + 'fieldDataSelect2Options' : timezones, + 'fieldDataSelect2OptionsKey' : 'id', + 'fieldDataSelect2OptionsValue' : 'zone_name', + 'fieldDataSelect2OptionsArray' : true, + 'fieldDataSelect2OptionsSelected' : timezoneId + ] + )}} +
+
\ No newline at end of file diff --git a/apps/Core/Views/Default/html/system/users/profile/form/locale.html b/apps/Core/Views/Default/html/system/users/profile/form/locale.html new file mode 100644 index 000000000..b7aaad65e --- /dev/null +++ b/apps/Core/Views/Default/html/system/users/profile/form/locale.html @@ -0,0 +1,60 @@ +{% set countryId = 0 %} +{% if profile['locale_country_id'] is defined %} + {% set countryId = profile['locale_country_id'] %} +{% endif %} +{% set timezoneId = 0 %} +{% if profile['locale_timezone_id'] is defined %} + {% set timezoneId = profile['locale_timezone_id'] %} +{% endif %} +
+
+ {{adminltetags.useTag('fields', + [ + 'component' : component, + 'componentName' : componentName, + 'componentId' : componentId, + 'sectionId' : sectionId, + 'fieldId' : 'locale_country_id', + 'fieldLabel' : 'Country', + 'fieldType' : 'select2', + 'fieldHelp' : true, + 'fieldHelpTooltipContent' : 'Select country', + 'fieldRequired' : false, + 'fieldBazScan' : true, + 'fieldBazJstreeSearch' : true, + 'fieldBazPostOnCreate' : true, + 'fieldBazPostOnUpdate' : true, + 'fieldDataSelect2Options' : countries, + 'fieldDataSelect2OptionsKey' : 'id', + 'fieldDataSelect2OptionsValue' : 'name', + 'fieldDataSelect2OptionsArray' : true, + 'fieldDataSelect2OptionsSelected' : countryId + ] + )}} +
+
+ {{adminltetags.useTag('fields', + [ + 'component' : component, + 'componentName' : componentName, + 'componentId' : componentId, + 'sectionId' : sectionId, + 'fieldId' : 'locale_timezone_id', + 'fieldLabel' : 'Timezone', + 'fieldType' : 'select2', + 'fieldHelp' : true, + 'fieldHelpTooltipContent' : 'Select timezone', + 'fieldRequired' : false, + 'fieldBazScan' : true, + 'fieldBazJstreeSearch' : true, + 'fieldBazPostOnCreate' : true, + 'fieldBazPostOnUpdate' : true, + 'fieldDataSelect2Options' : timezones, + 'fieldDataSelect2OptionsKey' : 'id', + 'fieldDataSelect2OptionsValue' : 'zone_name', + 'fieldDataSelect2OptionsArray' : true, + 'fieldDataSelect2OptionsSelected' : timezoneId + ] + )}} +
+
\ No newline at end of file From f033017bb42badda617d982698d921209e6c36f8 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Tue, 11 Mar 2025 16:09:20 +1100 Subject: [PATCH 21/40] fix issue #666 --- .../Base/Providers/AccessServiceProvider/Access/Auth.php | 8 ++++---- .../Packages/Users/Accounts.php | 6 ++++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/system/Base/Providers/AccessServiceProvider/Access/Auth.php b/system/Base/Providers/AccessServiceProvider/Access/Auth.php index 9cbc2d514..f02f53072 100644 --- a/system/Base/Providers/AccessServiceProvider/Access/Auth.php +++ b/system/Base/Providers/AccessServiceProvider/Access/Auth.php @@ -246,7 +246,7 @@ protected function clearAccountRecaller() '0', 1, '/', - null, + true, $this->domains->getDomain()['name'], true ); @@ -258,7 +258,7 @@ protected function clearAccountRecaller() '0', 1, '/', - null, + true, $this->domains->getDomain()['name'], true ); @@ -495,7 +495,7 @@ protected function setUserIdCooikie() $this->account['id'], $this->cookieTimeout, '/', - null, + true, $this->domains->getDomain()['name'], true ); @@ -647,7 +647,7 @@ protected function setRecaller() $identifier . $this->separator . $token, $this->cookieTimeout, '/', - null, + true, $this->domains->getDomain()['name'], true ); diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Users/Accounts.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Users/Accounts.php index 9231e4f39..2d0fcdbbe 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Users/Accounts.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Users/Accounts.php @@ -888,6 +888,8 @@ function($allowed) use ($id, $appId) { } else { $this->ffStoreToUse = 'basepackages_users_accounts_canlogin'; + $this->ffStore = $this->ff->store($this->ffStoreToUse); + $this->getByParams(['conditions' => [['account_id', '=', $id],['app_id', '=', $appId]]]); $canLogin = $this->ffData; @@ -917,6 +919,8 @@ function($allowed) use ($id, $appId) { foreach ($canLogin as $login) { $this->ffStoreToUse = 'basepackages_users_accounts_canlogin'; + $this->ffStore = $this->ff->store($this->ffStoreToUse); + $this->remove($login['id']); } } @@ -947,6 +951,8 @@ function($sessionObj) use ($id, $session) { if ($this->ffData) { $this->ffStoreToUse = 'basepackages_users_accounts_sessions'; + $this->ffStore = $this->ff->store($this->ffStoreToUse); + $this->getByParams(['conditions' => [['account_id', '=', $id],['session_id', '=', $session]]]); $hasSession = $this->ffData; From a4a4e4d7ac40938dce5ab43c25f012844a9092d6 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Tue, 11 Mar 2025 16:42:00 +1100 Subject: [PATCH 22/40] update issue #666 --- .../Base/Providers/AccessServiceProvider/Access/Auth.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/system/Base/Providers/AccessServiceProvider/Access/Auth.php b/system/Base/Providers/AccessServiceProvider/Access/Auth.php index f02f53072..cfe969da2 100644 --- a/system/Base/Providers/AccessServiceProvider/Access/Auth.php +++ b/system/Base/Providers/AccessServiceProvider/Access/Auth.php @@ -246,7 +246,7 @@ protected function clearAccountRecaller() '0', 1, '/', - true, + $this->config->dev === true ? false : true, $this->domains->getDomain()['name'], true ); @@ -258,7 +258,7 @@ protected function clearAccountRecaller() '0', 1, '/', - true, + $this->config->dev === true ? false : true, $this->domains->getDomain()['name'], true ); @@ -495,7 +495,7 @@ protected function setUserIdCooikie() $this->account['id'], $this->cookieTimeout, '/', - true, + $this->config->dev === true ? false : true, $this->domains->getDomain()['name'], true ); @@ -647,7 +647,7 @@ protected function setRecaller() $identifier . $this->separator . $token, $this->cookieTimeout, '/', - true, + $this->config->dev === true ? false : true, $this->domains->getDomain()['name'], true ); From e52d8a5a7e9f5aa9ffd9ddca5818067b8fad73f5 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Wed, 12 Mar 2025 00:38:09 +1100 Subject: [PATCH 23/40] fix issue #667. Also fixed some minor bugs with bundle not able to generate URL and error thrown if there is no remote repo while syncing. --- .../Packages/Devtools/Modules/DevtoolsModules.php | 11 +++++++++-- .../Views/Default/html/devtools/modules/module.html | 6 ++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/apps/Core/Packages/Devtools/Modules/DevtoolsModules.php b/apps/Core/Packages/Devtools/Modules/DevtoolsModules.php index f71fc4d5e..e651ca3e8 100644 --- a/apps/Core/Packages/Devtools/Modules/DevtoolsModules.php +++ b/apps/Core/Packages/Devtools/Modules/DevtoolsModules.php @@ -647,7 +647,7 @@ public function validateFilesHash($module) (isset($module['repo_details']['latestRelease']['name']) && $module['repo_details']['latestRelease']['name'] !== $module['version']) ) { - $module = $this->modules->manager->getModuleInfo( + $moduleSync = $this->modules->manager->getModuleInfo( [ 'module_type' => $module['module_type'], 'module_id' => $module['id'], @@ -655,11 +655,16 @@ public function validateFilesHash($module) 'getLatestRelease' => true ] ); + + if ($moduleSync) { + $module = array_merge($module, $moduleSync); + } } $module['repoExists'] = true; if (isset($module['repo_details']['latestRelease']['name'])) { + $module['latestRelease'] = []; $module['latestRelease'] = $module['repo_details']['latestRelease']['name']; } else { $module['latestRelease'] = false; @@ -3520,7 +3525,9 @@ public function generateModuleRepoUrl($data) $this->validation->init()->add('api_id', PresenceOf::class, ["message" => "Please provide api id."]); $this->validation->add('app_type', PresenceOf::class, ["message" => "Please provide app type."]); $this->validation->add('module_type', PresenceOf::class, ["message" => "Please provide module type."]); - $this->validation->add('category', PresenceOf::class, ["message" => "Please provide module category."]); + if ($data['module_type'] !== 'bundles') { + $this->validation->add('category', PresenceOf::class, ["message" => "Please provide module category."]); + } if (!$this->validateData($data)) { return false; diff --git a/apps/Core/Views/Default/html/devtools/modules/module.html b/apps/Core/Views/Default/html/devtools/modules/module.html index 542fcbbac..764a6602d 100644 --- a/apps/Core/Views/Default/html/devtools/modules/module.html +++ b/apps/Core/Views/Default/html/devtools/modules/module.html @@ -3515,16 +3515,18 @@ path += routeArr.join('/'); } else { + var nameArr; if (moduleType === 'views') { if (dataCollectionSectionForm['vars']['subview']) { path += dataCollectionSectionForm['vars']['moduleDependencies']['views'][0]['name'] + '/html/'; - path += $('#{{componentId}}-{{sectionId}}-name').val().toLowerCase(); + nameArr = $('#{{componentId}}-{{sectionId}}-name').val().split(/(?=[A-Z])/); + path += nameArr.join('/').toLowerCase(); } else { path += $('#{{componentId}}-{{sectionId}}-name').val(); } pathPublic += $('#{{componentId}}-{{sectionId}}-name').val().toLowerCase(); } else { - var nameArr = $('#{{componentId}}-{{sectionId}}-name').val().split(/(?=[A-Z])/); + nameArr = $('#{{componentId}}-{{sectionId}}-name').val().split(/(?=[A-Z])/); path += nameArr.join('/'); } } From 8dc87f5d136110bfbd157c55345849bcc13d9a6e Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Wed, 12 Mar 2025 02:26:08 +1100 Subject: [PATCH 24/40] update issue #666, added cookies set for setup --- system/Base/Installer/Components/Setup.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/Base/Installer/Components/Setup.php b/system/Base/Installer/Components/Setup.php index 9d8ff6309..bf4eb054a 100644 --- a/system/Base/Installer/Components/Setup.php +++ b/system/Base/Installer/Components/Setup.php @@ -788,7 +788,7 @@ protected function renderView($precheckFail = false, $onlyUpdateDb = false, $mes $this->session->getId(), time() + 600, '/', - null, + $this->postData['dev'] == 'true' ? false : true, null, true, [ From 44155e4c43738f040a070aaa7fc8ac985d99f661 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Wed, 12 Mar 2025 02:27:03 +1100 Subject: [PATCH 25/40] update issue #666 --- system/Base/Installer/Components/Setup.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/Base/Installer/Components/Setup.php b/system/Base/Installer/Components/Setup.php index bf4eb054a..3b7678730 100644 --- a/system/Base/Installer/Components/Setup.php +++ b/system/Base/Installer/Components/Setup.php @@ -788,7 +788,7 @@ protected function renderView($precheckFail = false, $onlyUpdateDb = false, $mes $this->session->getId(), time() + 600, '/', - $this->postData['dev'] == 'true' ? false : true, + false, null, true, [ From 68eefb520d7bc0d4f0cb2d0eb4bf9e9c0aa1d871 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Wed, 12 Mar 2025 02:30:44 +1100 Subject: [PATCH 26/40] update issue #666, domain name cannot be null --- system/Base/Installer/Components/Setup.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/Base/Installer/Components/Setup.php b/system/Base/Installer/Components/Setup.php index 3b7678730..7f93ca565 100644 --- a/system/Base/Installer/Components/Setup.php +++ b/system/Base/Installer/Components/Setup.php @@ -789,7 +789,7 @@ protected function renderView($precheckFail = false, $onlyUpdateDb = false, $mes time() + 600, '/', false, - null, + $this->request->getHttpHost(), true, [ 'samesite' => 'Strict' From ba975ae957045bbc4e25a5c11880c4b1fbe8c960 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Wed, 12 Mar 2025 02:38:48 +1100 Subject: [PATCH 27/40] update issue #666, fix setup cookies. --- system/Base/Installer/Packages/Setup.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/system/Base/Installer/Packages/Setup.php b/system/Base/Installer/Packages/Setup.php index 5292b2a4d..287da976d 100644 --- a/system/Base/Installer/Packages/Setup.php +++ b/system/Base/Installer/Packages/Setup.php @@ -303,8 +303,8 @@ protected function cleanOldCookies() '0', 1, '/', - null, - null, + false, + $this->request->getHttpHost(), true ); @@ -315,8 +315,8 @@ protected function cleanOldCookies() '0', 1, '/', - null, - null, + false, + $this->request->getHttpHost(), true ); @@ -325,8 +325,8 @@ protected function cleanOldCookies() '0', 1, '/', - null, - null, + false, + $this->request->getHttpHost(), true ); From 2f0725b8166453788f95929fbce0f7e12701fd7c Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Wed, 12 Mar 2025 15:48:01 +1100 Subject: [PATCH 28/40] fix issue #668. enabled preserve keys for numeric index. --- .../Ff/Classes/DocumentFinder.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/DocumentFinder.php b/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/DocumentFinder.php index a4d09cca9..cb82e1a85 100644 --- a/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/DocumentFinder.php +++ b/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/DocumentFinder.php @@ -112,11 +112,11 @@ public function findDocuments(bool $getOneDocument, bool $reduceAndJoinPossible) $found = array_merge($found, $this->searchIndexes($condition, $indexChars, $skip, $limit, $keyword)); } } else { - if (strlen($keyword) < $this->minIndexChars) { - continue; - } - if (is_string($keyword)) { + if (strlen($keyword) < $this->minIndexChars) { + continue; + } + $indexChars = strtolower(mb_substr($keyword, 0, $this->minIndexChars, 'UTF-8')); } else { $indexChars = $keyword; @@ -285,7 +285,7 @@ protected function searchIndexes($condition, $indexChars, $skip, $limit, $keywor $found = []; } - return $found; + return $found ?? []; } protected function getDataPath(): string @@ -330,7 +330,7 @@ protected static function skip(array &$found, $skip) return; } - $found = array_slice($found, $skip); + $found = array_slice($found, $skip, null, true); } protected static function limit(array &$found, $limit) @@ -339,7 +339,7 @@ protected static function limit(array &$found, $limit) return; } - $found = array_slice($found, 0, $limit); + $found = array_slice($found, 0, $limit, true); } protected static function performSearch(array &$found, array $search, array $searchOptions) From 346086c298f3b6d65e7c672f1c0c6761cc42e11a Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Wed, 12 Mar 2025 17:02:23 +1100 Subject: [PATCH 29/40] fix issue #669 --- .../Adminltetags/Traits/DynamicTable.php | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/apps/Core/Packages/Adminltetags/Traits/DynamicTable.php b/apps/Core/Packages/Adminltetags/Traits/DynamicTable.php index b004cf455..d8b8295f9 100644 --- a/apps/Core/Packages/Adminltetags/Traits/DynamicTable.php +++ b/apps/Core/Packages/Adminltetags/Traits/DynamicTable.php @@ -21,7 +21,8 @@ public function generateDTContent( int $componentId = null, $resetCache = false, $enableCache = true, - $packageData = [] + $packageData = [], + $excludeColumns = [] ) { if (gettype($package) === 'string') { $package = $this->usePackage($package); @@ -43,9 +44,9 @@ public function generateDTContent( $modelsColumnMap = $package->getModelsColumnMap($this->removeEscapeFromName($columnsForTable)); if (isset($modelsColumnMap['columns'])) { - $table['columns'] = $this->sortColumns($columnsForTable, $modelsColumnMap['columns']); + $table['columns'] = $this->sortColumns($columnsForTable, $modelsColumnMap['columns'], $excludeColumns); } else { - $table['columns'] = $this->sortColumns($columnsForTable, $modelsColumnMap); + $table['columns'] = $this->sortColumns($columnsForTable, $modelsColumnMap, $excludeColumns); } if ($dtReplaceColumnsTitle && count($dtReplaceColumnsTitle) > 0) { @@ -80,9 +81,9 @@ public function generateDTContent( $modelsColumnMap = $package->getModelsColumnMap($this->removeEscapeFromName($columnsForFilter)); if (isset($modelsColumnMap['columns'])) { - $table['filterColumns'] = $this->sortColumns($columnsForFilter, $modelsColumnMap['columns']); + $table['filterColumns'] = $this->sortColumns($columnsForFilter, $modelsColumnMap['columns'], $excludeColumns); } else { - $table['filterColumns'] = $this->sortColumns($columnsForFilter, $modelsColumnMap); + $table['filterColumns'] = $this->sortColumns($columnsForFilter, $modelsColumnMap, $excludeColumns); } foreach ($filtersArr as $key => $filter) { @@ -281,7 +282,7 @@ protected function extractColumnsForTable($columnsForTable, $rows) return $rows; } - protected function sortColumns($columnsForTable, $dbColumns) + protected function sortColumns($columnsForTable, $dbColumns, $excludeColumns = []) { $columnsForTable = $this->removeEscapeFromName($columnsForTable); @@ -290,6 +291,10 @@ protected function sortColumns($columnsForTable, $dbColumns) $sortedColumns = array_merge(['id' => $dbColumns['id']]); foreach ($columnsForTable as $key => $column) { + if (in_array($column, $excludeColumns)) { + continue; + } + if ($column !== 'id') { if ($dbColumns[$column]) { $sortedColumns[$column] = $dbColumns[$column]; From ee18cc6022b1e3faf815840bb0f6264f80f05019 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Thu, 13 Mar 2025 04:16:16 +1100 Subject: [PATCH 30/40] fix issue #670 --- .../Providers/DatabaseServiceProvider/Ff.php | 2 ++ .../Ff/Classes/IndexHandler.php | 3 ++ .../DatabaseServiceProvider/Ff/Store.php | 28 +++++++++++++++++-- .../ModulesServiceProvider/DbInstaller.php | 2 +- 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/system/Base/Providers/DatabaseServiceProvider/Ff.php b/system/Base/Providers/DatabaseServiceProvider/Ff.php index 2de3aaf2f..00def01d9 100644 --- a/system/Base/Providers/DatabaseServiceProvider/Ff.php +++ b/system/Base/Providers/DatabaseServiceProvider/Ff.php @@ -329,6 +329,8 @@ public function generateConfig($tableName, $tableClass, $tableModel, $configArr return $config; } + $config['uniqueFields'] = []; + $config['indexes'] = []; if (isset($tableClass->columns()['indexes'])) { foreach ($tableClass->columns()['indexes'] as $index) { if ($index->getType() === 'UNIQUE' && $index->getColumns() && count($index->getColumns()) > 0) { diff --git a/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/IndexHandler.php b/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/IndexHandler.php index 5b6fe270d..c4f4194be 100644 --- a/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/IndexHandler.php +++ b/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/IndexHandler.php @@ -142,6 +142,8 @@ protected function writeIndex($indexPointer, $index, $indexChars, $content, $rem if (count($indexJson[$content]) === 0) { return IoHelper::deleteFile($this->indexesPath . $index . '/' . $indexChars . '.json'); } + + $indexJson[$content] = array_values($indexJson[$content]); } else { if (!in_array($indexPointer, $indexJson[$content])) { array_push($indexJson[$content], $indexPointer); @@ -150,6 +152,7 @@ protected function writeIndex($indexPointer, $index, $indexChars, $content, $rem } else { if (!$remove) { $indexJson[$content] = [$indexPointer]; + $indexJson[$content] = array_values($indexJson[$content]); } } diff --git a/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php b/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php index 95d7312a5..a9cda2840 100644 --- a/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php +++ b/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php @@ -1496,10 +1496,32 @@ protected function validateData(array $data) } if (count($criteria) > 0) { - $found = $this->findOneBy($criteria); + $found = $this->findBy($criteria); - if ($found) { - throw new IOException("Duplicate entry found for field: $uniqueField. $uniqueField should be unique. Store: " . $this->storeName); + $duplicate = false; + + if ($found && count($found) > 0) { + foreach ($found as $foundArr) { + $match = false; + + foreach ($criteria as $criteriaArr) { + if (isset($foundArr[$criteriaArr[0]]) && $foundArr[$criteriaArr[0]] === $criteriaArr[2]) { + $match = true; + } else { + $match = false; + } + } + + if ($match) { + $duplicate = $foundArr['id']; + + break; + } + } + } + + if ($duplicate) { + throw new IOException("Duplicate entry with ID: $duplicate found for field: $uniqueField. $uniqueField should be unique. Store: " . $this->storeName); } } } diff --git a/system/Base/Providers/ModulesServiceProvider/DbInstaller.php b/system/Base/Providers/ModulesServiceProvider/DbInstaller.php index 1e71c31d4..b17c38174 100644 --- a/system/Base/Providers/ModulesServiceProvider/DbInstaller.php +++ b/system/Base/Providers/ModulesServiceProvider/DbInstaller.php @@ -123,7 +123,7 @@ public function installDb($databases) $config = $this->ff->generateConfig($tableName, $tableClass['schema'], $tableClass['model'], $tableConfigParams); $schema = $this->ff->generateSchema($tableName, $tableClass['schema'], $tableClass['model']); - $this->ff->store($tableName, $config, $schema, $this->ff); + $this->ff->store($tableName, $config, $schema); if (method_exists($tableClass['schema'], 'indexes')) { array_push($storesToIndex, $tableName); From 72b6cd275a3b5a4201cce7885ad066cb6a8ca972 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Thu, 13 Mar 2025 04:16:50 +1100 Subject: [PATCH 31/40] update issue #332 --- .../Packages/Adminltetags/Tags/Buttons/ButtonGroup.php | 10 +++++++--- .../BasepackagesServiceProvider/Packages/Workers.php | 3 --- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/apps/Core/Packages/Adminltetags/Tags/Buttons/ButtonGroup.php b/apps/Core/Packages/Adminltetags/Tags/Buttons/ButtonGroup.php index 33a63ad07..7d22581a0 100644 --- a/apps/Core/Packages/Adminltetags/Tags/Buttons/ButtonGroup.php +++ b/apps/Core/Packages/Adminltetags/Tags/Buttons/ButtonGroup.php @@ -143,7 +143,9 @@ protected function buildButton() if ($this->params['groupRadioButtonChecked'] === $button['value']) { $hasButtonChecked = 'checked'; $hasButtonCheckedClasses = 'active focus'; - if ($this->params['groupRadioButtonStyle'] === 'outline') { + if (isset($this->params['groupRadioButtonStyle']) && + $this->params['groupRadioButtonStyle'] === 'outline' + ) { $hasButtonCheckedBgClass = ''; } else { $hasButtonCheckedBgClass = 'bg-' . $button['type']; @@ -157,7 +159,9 @@ protected function buildButton() if (isset($button['checked']) && $button['checked'] === true) { $hasButtonChecked = 'checked'; $hasButtonCheckedClasses = 'active focus'; - if ($this->params['groupRadioButtonStyle'] === 'outline') { + if (isset($this->params['groupRadioButtonStyle']) && + $this->params['groupRadioButtonStyle'] === 'outline' + ) { $hasButtonCheckedBgClass = ''; } else { $hasButtonCheckedBgClass = 'bg-' . $button['type']; @@ -169,7 +173,7 @@ protected function buildButton() } } - if (isset($buton['disabled']) && $buton['disabled'] === true) { + if (isset($button['disabled']) && $button['disabled'] === true) { $hasButtonDisabled = 'disabled'; $hasButtonCursor = 'style=cursor:default;'; } else { diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers.php index e1426e1b7..380b0d549 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Workers.php @@ -456,7 +456,6 @@ protected function shouldSchedule($task, $schedule) (int) $schedule['params']['minutes'] )->executionTime; - // $secsLeft = $this->cron->getNextRunDate()->getTimestamp() - time(); $nextRun = $this->cron->getNextRunDate()->format('Y-m-d H:i:s'); } else if ($schedule['type'] === 'hourly') { $this->cron = @@ -464,7 +463,6 @@ protected function shouldSchedule($task, $schedule) (int) $schedule['params']['hourly_minutes'] )->executionTime; - // $secsLeft = $this->cron->getNextRunDate()->getTimestamp() - time(); $nextRun = $this->cron->getNextRunDate()->format('Y-m-d H:i:s'); } else if ($schedule['type'] === 'daily') { $this->cron = @@ -473,7 +471,6 @@ protected function shouldSchedule($task, $schedule) (int) $schedule['params']['daily_minutes'] )->executionTime; - // $secsLeft = $this->cron->getNextRunDate()->getTimestamp() - time(); $nextRun = $this->cron->getNextRunDate()->format('Y-m-d H:i:s'); if ($task['next_run'] !== $this->cron->getNextRunDate()) { From 61229cc684e0a885ac8e1b4d3835650ba471ca82 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Thu, 13 Mar 2025 18:41:28 +1100 Subject: [PATCH 32/40] fix issue #671 --- .../Ff/Classes/DocumentFinder.php | 105 ++++++++++-------- 1 file changed, 61 insertions(+), 44 deletions(-) diff --git a/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/DocumentFinder.php b/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/DocumentFinder.php index cb82e1a85..a829443c6 100644 --- a/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/DocumentFinder.php +++ b/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/DocumentFinder.php @@ -80,50 +80,19 @@ public function findDocuments(bool $getOneDocument, bool $reduceAndJoinPossible) $indexSearched = false; + //Note: for now index searches are using "OR" condition. If there are 2 more conditions to search, + //both conditions data will be searched. This needs to be extended to include keywords like "OR" and "AND" if ($this->storeConfiguration['readIndex']) { if (count($conditions) > 0) { - foreach ($conditions as $condition) { - if (isset($condition[0]) && - in_array($condition[0][0], $this->storeConfiguration['indexes']) - ) { - $indexSearched = true; + foreach ($conditions as $conditionKey => $condition) { + $conditionArr = $condition; - //trim % (like), change space to + for multikeyword search. - if (is_string($condition[0][2])) { - $keyword = str_replace(' ', '+', strtolower(trim($condition[0][2], '%'))); - } else { - $keyword = $condition[0][2]; - } - - if ($this->multiWords === true && str_contains($keyword, '+')) { - $keywordArr = explode('+', $keyword); - - foreach ($keywordArr as $key => $keyword) { - if (strlen($keyword) < $this->minMultiWordsChars) { - continue; - } - - if (is_string($keyword)) { - $indexChars = strtolower(mb_substr($keyword, 0, $this->minIndexChars, 'UTF-8')); - } else { - $indexChars = $keyword; - } - - $found = array_merge($found, $this->searchIndexes($condition, $indexChars, $skip, $limit, $keyword)); - } - } else { - if (is_string($keyword)) { - if (strlen($keyword) < $this->minIndexChars) { - continue; - } - - $indexChars = strtolower(mb_substr($keyword, 0, $this->minIndexChars, 'UTF-8')); - } else { - $indexChars = $keyword; - } - - $found = array_merge($found, $this->searchIndexes($condition, $indexChars, $skip, $limit, $keyword)); + if (is_array($condition[0])) { + foreach ($condition as $conditionArr) { + $this->processIndexes($conditionArr, $found, $skip, $limit); } + } else { + $this->processIndexes($conditionArr, $found, $skip, $limit); } } } @@ -213,11 +182,59 @@ public function findDocuments(bool $getOneDocument, bool $reduceAndJoinPossible) return $found; } + protected function processIndexes($conditionArr, &$found, $skip, $limit) + { + if (isset($conditionArr[0]) && + in_array($conditionArr[0], $this->storeConfiguration['indexes']) + ) { + $indexSearched = true; + + //trim % (like), change space to + for multikeyword search. + if (is_string($conditionArr[2])) { + $keyword = str_replace(' ', '+', strtolower(trim($conditionArr[0][2], '%'))); + } else { + $keyword = $conditionArr[2]; + } + + if ($this->multiWords === true && str_contains($keyword, '+')) { + $keywordArr = explode('+', $keyword); + + foreach ($keywordArr as $key => $keyword) { + if (strlen($keyword) < $this->minMultiWordsChars) { + continue; + } + + if (is_string($keyword)) { + $indexChars = strtolower(mb_substr($keyword, 0, $this->minIndexChars, 'UTF-8')); + } else { + $indexChars = $keyword; + } + + $found = array_merge($found, $this->searchIndexes($conditionArr, $indexChars, $skip, $limit, $keyword)); + } + } else { + if (is_string($keyword)) { + if (strlen($keyword) < $this->minIndexChars) { + return []; + } + + $indexChars = strtolower(mb_substr($keyword, 0, $this->minIndexChars, 'UTF-8')); + } else { + $indexChars = $keyword; + } + + $found = array_merge($found, $this->searchIndexes($conditionArr, $indexChars, $skip, $limit, $keyword)); + } + } + + return $found ?? []; + } + protected function searchIndexes($condition, $indexChars, $skip, $limit, $keyword) { try { $indexFile = IoHelper::getFileContent( - $this->storeConfiguration['indexesPath'] . $condition[0][0] . '/' . $indexChars . '.json' + $this->storeConfiguration['indexesPath'] . $condition[0] . '/' . $indexChars . '.json' ); $indexFile = strtolower($indexFile); @@ -255,7 +272,7 @@ protected function searchIndexes($condition, $indexChars, $skip, $limit, $keywor $key = strtolower($key); - if (strtolower($condition[0][1]) === 'like') { + if (strtolower($condition[1]) === 'like') { if (str_starts_with($key, $indexChars)) { foreach ($ids as $id) { $indexIdData = $this->store->findById($id); @@ -265,8 +282,8 @@ protected function searchIndexes($condition, $indexChars, $skip, $limit, $keywor } } } - } else if ($condition[0][1] === '=' || - $condition[0][1] === '===' + } else if ($condition[1] === '=' || + $condition[1] === '===' ) { if ($key === $indexChars) { foreach ($ids as $id) { From d76c33102a693ae1fb29b199c53ac8fc8c7a1c32 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Fri, 14 Mar 2025 20:09:41 +1100 Subject: [PATCH 33/40] fix issue #672 --- system/Base/Helpers.php | 14 +- .../Providers/DatabaseServiceProvider/Ff.php | 2 +- .../Ff/Classes/IndexHandler.php | 123 ++++++++++++++---- .../DatabaseServiceProvider/Ff/Store.php | 2 +- 4 files changed, 105 insertions(+), 36 deletions(-) diff --git a/system/Base/Helpers.php b/system/Base/Helpers.php index 189780ee2..3ca32cf8f 100644 --- a/system/Base/Helpers.php +++ b/system/Base/Helpers.php @@ -248,17 +248,19 @@ function checkCtype($str, $ctype = 'alnum', $ignoreChars = null) { $ignoreChars = [' ', '&', '&', ',', ':', ';']; } + $string = trim(str_replace($ignoreChars, '' , $str)); + if ($ctype === 'alnum') { - if (ctype_alnum(trim(str_replace($ignoreChars, '' , $str)))) { - return trim(str_replace($ignoreChars, '' , $str)); + if (ctype_alnum($string)) { + return $string; } } else if ($ctype === 'alpha') { - if (ctype_alpha(trim(str_replace($ignoreChars, '' , $str)))) { - return trim(str_replace($ignoreChars, '' , $str)); + if (ctype_alpha($string)) { + return $string; } } else if ($ctype === 'digits') { - if (ctype_digit(trim(str_replace($ignoreChars, '' , $str)))) { - return trim(str_replace($ignoreChars, '' , $str)); + if (ctype_digit($string)) { + return $string; } } diff --git a/system/Base/Providers/DatabaseServiceProvider/Ff.php b/system/Base/Providers/DatabaseServiceProvider/Ff.php index 00def01d9..3bf5e53ac 100644 --- a/system/Base/Providers/DatabaseServiceProvider/Ff.php +++ b/system/Base/Providers/DatabaseServiceProvider/Ff.php @@ -341,7 +341,7 @@ public function generateConfig($tableName, $tableClass, $tableModel, $configArr if (method_exists($tableClass, 'indexes')) { $columns = []; - $columnsTypeToIndex = [0,2,5,7,9,14];//int, chars, varchars + $columnsTypeToIndex = [0,2,5,7,9,14,22];//int, chars, varchars foreach ($tableClass->columns()['columns'] as $column) { $columns[$column->getName()] = $column; diff --git a/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/IndexHandler.php b/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/IndexHandler.php index c4f4194be..e00ebb564 100644 --- a/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/IndexHandler.php +++ b/system/Base/Providers/DatabaseServiceProvider/Ff/Classes/IndexHandler.php @@ -22,6 +22,8 @@ class IndexHandler protected $folderPermissions = 0777; + protected $reIndexIndexes = []; + public function __construct(array $storeConfiguration) { $this->storeConfiguration = $storeConfiguration; @@ -56,13 +58,13 @@ public function __construct(array $storeConfiguration) } } - public function setIndex($content, $remove = false) + public function setIndex($content, $remove = false, $reIndex = false) { if (is_string($content)) { $content = json_decode($content, true); } - $indexPointer = $content['id']; + $contentId = $content['id']; IoHelper::createFolder($this->indexesPath, $this->folderPermissions); @@ -75,30 +77,54 @@ public function setIndex($content, $remove = false) $contentArr = explode($this->multiWordsSeparator, $content[$index]); if (count($contentArr) > 1) { - foreach ($contentArr as $content) { - if (strlen($content) < $this->minMultiWordsChars) { + foreach ($contentArr as $contentWord) { + $contentWord = strtolower($contentWord); + + if (strlen($contentWord) < $this->minMultiWordsChars) { continue; } - $indexChars = strtolower(mb_substr($content, 0, $this->minIndexChars, 'UTF-8')); + $indexChars = strtolower(mb_substr($contentWord, 0, $this->minIndexChars, 'UTF-8')); if (str_contains($indexChars, '/')) {//this will result in subdirectories continue; } - $this->writeIndex($indexPointer, $index, $indexChars, $content, $remove); + if (!checkCtype($contentWord, 'alpha')) {//Ignore Special chars + continue; + } + + if ($reIndex) { + $this->addToReindexIndexes($contentId, $index, $indexChars, $contentWord); + } else { + $this->writeIndex($contentId, $index, $indexChars, $contentWord, $remove); + } } } else { + $content[$index] = strtolower($content[$index]); + $indexChars = strtolower(mb_substr($content[$index], 0, $this->minIndexChars, 'UTF-8')); if (str_contains($indexChars, '/')) {//this will result in subdirectories continue; } - $this->writeIndex($indexPointer, $index, $indexChars, $content[$index], $remove); + if (!checkCtype($content[$index], 'alpha')) {//Ignore Special chars + continue; + } + + if ($reIndex) { + $this->addToReindexIndexes($contentId, $index, $indexChars, $content[$index]); + } else { + $this->writeIndex($contentId, $index, $indexChars, $content[$index], $remove); + } } } else { - $this->writeIndex($indexPointer, $index, $content[$index], $content[$index], $remove); + if ($reIndex) { + $this->addToReindexIndexes($contentId, $index, $content[$index], $content[$index]); + } else { + $this->writeIndex($contentId, $index, $content[$index], $content[$index], $remove); + } } } else { if (is_string($content[$index])) { @@ -106,22 +132,55 @@ public function setIndex($content, $remove = false) continue; } + $content[$index] = strtolower($content[$index]); + $indexChars = strtolower(mb_substr($content[$index], 0, $this->minIndexChars, 'UTF-8')); if (str_contains($indexChars, '/')) {//this will result in subdirectories continue; } - $this->writeIndex($indexPointer, $index, $indexChars, $content[$index], $remove); + if (!checkCtype($content[$index], 'alpha')) {//Ignore Special chars + continue; + } + + if ($reIndex) { + $this->addToReindexIndexes($contentId, $index, $indexChars, $content[$index]); + } else { + $this->writeIndex($contentId, $index, $indexChars, $content[$index], $remove); + } } else { - $this->writeIndex($indexPointer, $index, $content[$index], $content[$index], $remove); + if ($reIndex) { + $this->addToReindexIndexes($contentId, $index, $content[$index], $content[$index]); + } else { + $this->writeIndex($contentId, $index, $content[$index], $content[$index], $remove); + } } } } } } - protected function writeIndex($indexPointer, $index, $indexChars, $content, $remove = false) + protected function addToReindexIndexes($contentId, $index, $indexChars, $content) + { + if (!isset($this->reIndexIndexes[$index])) { + $this->reIndexIndexes[$index] = []; + } + + if (!isset($this->reIndexIndexes[$index][$indexChars])) { + $this->reIndexIndexes[$index][$indexChars] = []; + } + + if (!isset($this->reIndexIndexes[$index][$indexChars][$content])) { + $this->reIndexIndexes[$index][$indexChars][$content] = []; + } + + if (!in_array($contentId, $this->reIndexIndexes[$index][$indexChars][$content])) { + array_push($this->reIndexIndexes[$index][$indexChars][$content], $contentId); + } + } + + protected function writeIndex($contentId, $index, $indexChars, $content, $remove = false) { try { $indexFile = $this->getIndex($index, $indexChars); @@ -133,7 +192,7 @@ protected function writeIndex($indexPointer, $index, $indexChars, $content, $rem if (isset($indexJson[$content])) { if ($remove) { - $key = array_search($indexPointer, $indexJson[$content]); + $key = array_search($contentId, $indexJson[$content]); if ($key !== false) { unset($indexJson[$content][$key]); @@ -145,13 +204,13 @@ protected function writeIndex($indexPointer, $index, $indexChars, $content, $rem $indexJson[$content] = array_values($indexJson[$content]); } else { - if (!in_array($indexPointer, $indexJson[$content])) { - array_push($indexJson[$content], $indexPointer); + if (!in_array($contentId, $indexJson[$content])) { + array_push($indexJson[$content], $contentId); } } } else { if (!$remove) { - $indexJson[$content] = [$indexPointer]; + $indexJson[$content] = [$contentId]; $indexJson[$content] = array_values($indexJson[$content]); } } @@ -190,24 +249,32 @@ public function reIndex($dataPath = null) $dataPath = $this->storeConfiguration['storePath'] . 'data/'; } - if ($handle = opendir($dataPath)) { - while (false !== ($entry = readdir($handle))) { - if ($entry === "." || $entry === "..") { - continue; - } + $scanDir = scandir($dataPath); + $files = []; + array_walk($scanDir, function($file) use (&$files) { + if ($file !== '..' && $file !== '.') { + array_push($files, (int) str_replace('.json', '', $file)); + } + }); + sort($files); - $documentPath = $dataPath . $entry; + foreach ($files as $entry) { + $documentPath = $dataPath . $entry . '.json'; - try { - $data = IoHelper::getFileContent($documentPath); + try { + $data = IoHelper::getFileContent($documentPath); - $this->setIndex($data); - } catch (\Exception $exception) { - continue; - } + $this->setIndex($data, false, true); + } catch (Exception $exception) { + continue; } + } - closedir($handle); + //We write all index files here + foreach ($this->reIndexIndexes as $index => $files) { + foreach ($files as $content => $values) { + IoHelper::writeContentToFile($this->indexesPath . $index . '/' . $content . '.json', json_encode($values)); + } } } } \ No newline at end of file diff --git a/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php b/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php index a9cda2840..f74cbfe06 100644 --- a/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php +++ b/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php @@ -32,7 +32,7 @@ class Store protected $minIndexChars = 3; protected $multiWords = true; protected $multiWordsSeparator = ' '; - protected $minMultiWordsChars = 5; + protected $minMultiWordsChars = 4; protected $indexes = []; protected $model = null; From 7b71eabf1723932b0e9e5fe26852134d90a1e0f6 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Mon, 17 Mar 2025 15:01:35 +1100 Subject: [PATCH 34/40] fix issue #673, Now you can define value to be grabbed from hierarchy array using key1/key2/key3. If the value needs to be taken from key3, it will loop through the array to get the value. --- apps/Core/Packages/Adminltetags/Tags/Tree.php | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/apps/Core/Packages/Adminltetags/Tags/Tree.php b/apps/Core/Packages/Adminltetags/Tags/Tree.php index 517bf633b..8a1087b4a 100644 --- a/apps/Core/Packages/Adminltetags/Tags/Tree.php +++ b/apps/Core/Packages/Adminltetags/Tags/Tree.php @@ -398,20 +398,21 @@ protected function treeItem($key, $items, $itemIcon, $children = null) $key = $itemValue[$this->fieldParams['fieldDataSelect' . $selectType . 'OptionsKey']]; if (count($this->fieldParams['fieldDataSelect' . $selectType . 'OptionsValue']) === 1) { - if (is_string($this->fieldParams['fieldDataSelect' . $selectType . 'OptionsValue'][0])) { - $optionsValueKey = explode(':', $this->fieldParams['fieldDataSelect' . $selectType . 'OptionsValue'][0]); - } - - if (count($optionsValueKey) === 1) { - $optionsValueKey = $optionsValueKey[0]; + if (str_contains($this->fieldParams['fieldDataSelect' . $selectType . 'OptionsValue'][0], '/')) { + $hierarchyOptionValue = explode('/', $this->fieldParams['fieldDataSelect' . $selectType . 'OptionsValue'][0]); - if (isset($itemValue[$optionsValueKey])) { - $value = $itemValue[$optionsValueKey]; + if (count($hierarchyOptionValue) === 1) { + $value = $itemValue[$hierarchyOptionValue[0]]; + } else { + $itemValueArr = []; + $itemValueArr = $itemValue; + foreach ($hierarchyOptionValue as $optionsValueArr) { + $itemValueArr = $itemValueArr[$optionsValueArr]; + } + $value = $itemValueArr; } } else { - if (isset($itemValue[$optionsValueKey[0]]) && isset($itemValue[$optionsValueKey[1]])) { - $value = $itemValue[$optionsValueKey[0]] . ' (' . $itemValue[$optionsValueKey[1]] . ')'; - } + $value = $itemValue[$this->fieldParams['fieldDataSelect' . $selectType . 'OptionsValue'][0]]; } } else { foreach ($this->fieldParams['fieldDataSelect' . $selectType . 'OptionsValue'] as $optionsValueKey) { From 677fac3ab2a952d6abce66bf287636dae7e33e53 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Mon, 17 Mar 2025 15:04:00 +1100 Subject: [PATCH 35/40] fix issue #674 --- .../DatabaseServiceProvider/Ff/Store.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php b/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php index f74cbfe06..f2d345965 100644 --- a/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php +++ b/system/Base/Providers/DatabaseServiceProvider/Ff/Store.php @@ -1675,6 +1675,24 @@ protected function normalizeData(array $data, $jsonToArray = false): array } } + if ($type === 'string') { + if (is_integer($data[$propertyKey]) || is_float($data[$propertyKey])) { + $data[$propertyKey] = (string) $data[$propertyKey]; + } + + if (is_bool($data[$propertyKey])) { + if ($data[$propertyKey] === true || + $data[$propertyKey] === 1 + ) { + $data[$propertyKey] = 'true'; + } else if ($data[$propertyKey] === false || + $data[$propertyKey] === 0 + ) { + $data[$propertyKey] = 'false'; + } + } + } + if ($type === 'boolean') { if (is_string($data[$propertyKey])) { if ($data[$propertyKey] === 'false' || From cf0603e3d48d6bf28dae4206c60ae3bb4e27a0f8 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Mon, 17 Mar 2025 15:04:23 +1100 Subject: [PATCH 36/40] update issue #332 --- public/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/index.php b/public/index.php index 482532023..fb46a35f0 100644 --- a/public/index.php +++ b/public/index.php @@ -94,4 +94,4 @@ } } } -} +} \ No newline at end of file From a84961e979801d2fd67fd3937b1e630a25185cd7 Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Fri, 21 Mar 2025 21:37:11 +1100 Subject: [PATCH 37/40] fix issue #677 --- system/Base/BaseComponent.php | 17 +++++++++-------- .../ErrorServiceProvider/ExceptionHandlers.php | 9 ++++++--- ...rrectCSRF.php => IncorrectCSRFException.php} | 2 +- ...pe.php => IncorrectRequestTypeException.php} | 2 +- 4 files changed, 17 insertions(+), 13 deletions(-) rename system/Base/Providers/ErrorServiceProvider/Exceptions/{IncorrectCSRF.php => IncorrectCSRFException.php} (61%) rename system/Base/Providers/ErrorServiceProvider/Exceptions/{IncorrectRequestType.php => IncorrectRequestTypeException.php} (58%) diff --git a/system/Base/BaseComponent.php b/system/Base/BaseComponent.php index 2797efbc2..074992f29 100644 --- a/system/Base/BaseComponent.php +++ b/system/Base/BaseComponent.php @@ -7,8 +7,8 @@ use Phalcon\Mvc\View; use System\Base\Exceptions\ControllerNotFoundException; use System\Base\Exceptions\IdNotFoundException; -use System\Base\Providers\ErrorServiceProvider\Exceptions\IncorrectCSRF; -use System\Base\Providers\ErrorServiceProvider\Exceptions\IncorrectRequestType; +use System\Base\Providers\ErrorServiceProvider\Exceptions\IncorrectCSRFException; +use System\Base\Providers\ErrorServiceProvider\Exceptions\IncorrectRequestTypeException; abstract class BaseComponent extends Controller { @@ -179,11 +179,11 @@ public function checkComponentWidgets() protected function requestIsPost($checkCSRF = true) { if (!$this->request->isPost()) { - throw new IncorrectRequestType('post'); + throw new IncorrectRequestTypeException('post'); } - if (!$this->checkCSRF()) { - return false; + if ($checkCSRF) { + $this->checkCSRF(); } } @@ -498,11 +498,12 @@ protected function checkCSRF() { if ($this->request->isPost() || $this->request->isPut() || $this->request->isDelete()) { if (!$this->security->checkToken(null, null, false)) { - $this->view->responseCode = 2; + throw new IncorrectCSRFException('CSRF Token Error! Please refresh page.'); + // $this->view->responseCode = 2; - $this->view->responseMessage = 'CSRF Token Error! Please refresh page.'; + // $this->view->responseMessage = 'CSRF Token Error! Please refresh page.'; - return $this->sendJson(); + // return $this->sendJson(); } } diff --git a/system/Base/Providers/ErrorServiceProvider/ExceptionHandlers.php b/system/Base/Providers/ErrorServiceProvider/ExceptionHandlers.php index 863c97aef..34de6611b 100644 --- a/system/Base/Providers/ErrorServiceProvider/ExceptionHandlers.php +++ b/system/Base/Providers/ErrorServiceProvider/ExceptionHandlers.php @@ -66,11 +66,14 @@ public function handleValidationException($exception) return $this->response->redirect($exception->getPath()); } - public function handleCsrfTokenException() + public function handleIncorrectCSRFException($exception) { - $this->flash->now('warning', 'Session expired, please login again.'); + if ($this->request->getBestAccept() === 'application/json') { + + $this->addResponse($exception->getMessage(), 1); - return $this->response->redirect('/auth/login'); + return $this->sendJson(); + } } public function handleInvalidDataException($exception) diff --git a/system/Base/Providers/ErrorServiceProvider/Exceptions/IncorrectCSRF.php b/system/Base/Providers/ErrorServiceProvider/Exceptions/IncorrectCSRFException.php similarity index 61% rename from system/Base/Providers/ErrorServiceProvider/Exceptions/IncorrectCSRF.php rename to system/Base/Providers/ErrorServiceProvider/Exceptions/IncorrectCSRFException.php index 6f1096b5f..8f47aae51 100644 --- a/system/Base/Providers/ErrorServiceProvider/Exceptions/IncorrectCSRF.php +++ b/system/Base/Providers/ErrorServiceProvider/Exceptions/IncorrectCSRFException.php @@ -2,7 +2,7 @@ namespace System\Base\Providers\ErrorServiceProvider\Exceptions; -class IncorrectCSRF extends \Exception +class IncorrectCSRFException extends \Exception { } \ No newline at end of file diff --git a/system/Base/Providers/ErrorServiceProvider/Exceptions/IncorrectRequestType.php b/system/Base/Providers/ErrorServiceProvider/Exceptions/IncorrectRequestTypeException.php similarity index 58% rename from system/Base/Providers/ErrorServiceProvider/Exceptions/IncorrectRequestType.php rename to system/Base/Providers/ErrorServiceProvider/Exceptions/IncorrectRequestTypeException.php index aa10910e7..62de6d8c3 100644 --- a/system/Base/Providers/ErrorServiceProvider/Exceptions/IncorrectRequestType.php +++ b/system/Base/Providers/ErrorServiceProvider/Exceptions/IncorrectRequestTypeException.php @@ -2,7 +2,7 @@ namespace System\Base\Providers\ErrorServiceProvider\Exceptions; -class IncorrectRequestType extends \Exception +class IncorrectRequestTypeException extends \Exception { } \ No newline at end of file From 347ad1c6aca5c03d81fb13041c6cb54eed2e596c Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Sat, 3 May 2025 15:02:09 +1000 Subject: [PATCH 38/40] Initial commit #678 --- .../System/Filters/FiltersComponent.php | 131 +++++++++--------- .../Setup/Register/Basepackages/Filter.php | 2 + .../Setup/Schema/Basepackages/Filters.php | 8 ++ .../Packages/Filters.php | 126 +++++++---------- .../Packages/Model/BasepackagesFilters.php | 2 + 5 files changed, 130 insertions(+), 139 deletions(-) diff --git a/apps/Core/Components/System/Filters/FiltersComponent.php b/apps/Core/Components/System/Filters/FiltersComponent.php index 4585de0df..2f0beebce 100644 --- a/apps/Core/Components/System/Filters/FiltersComponent.php +++ b/apps/Core/Components/System/Filters/FiltersComponent.php @@ -22,82 +22,83 @@ public function initialize() */ public function viewAction() { - if ($this->app['id'] == 1) { - $components = $this->modules->components->components; - - foreach ($components as $key => $component) { - $components[$key]['name'] = $component['name'] . ' (' . $component['category'] . ')'; - } - - $this->view->components = $components; - - if (isset($this->getData()['id'])) { - if ($this->getData()['id'] != 0) { - $filter = $this->filters->getById($this->getData()['id']); + if (isset($this->getData()['id'])) { + if ($this->getData()['id'] != 0) { + $filter = $this->filters->getById($this->getData()['id']); - if (!$filter) { - return $this->throwIdNotFound(); - } - - $this->view->filter = $filter; + if (!$filter) { + return $this->throwIdNotFound(); } - $this->view->pick('filters/view'); - - return; + $this->view->filter = $filter; } - if ($this->request->isPost()) { - $replaceColumns = - [ - 'filter_type' => ['html' => - [ - '0' => 'System', - '1' => 'User', - '2' => 'User', - ] - ], - 'is_default' => ['html' => - [ - '0' => 'No', - '1' => 'Yes' - ] - ], - 'auto_generated' => ['html' => - [ - '0' => 'No', - '1' => 'Yes' - ] - ] - ]; + $this->view->pick('filters/view'); + + return; + } else { + if ($this->app['id'] == 1) { + $components = $this->modules->components->components; } else { - $replaceColumns = null; + $components = $this->modules->components->getComponentsForAppType($this->app['app_type']); } - $controlActions = + foreach ($components as $key => $component) { + $components[$key]['name'] = $component['name'] . ' (' . $component['category'] . ')'; + } + + $this->view->components = $components; + } + + if ($this->request->isPost()) { + $replaceColumns = [ - 'actionsToEnable' => - [ - 'edit' => 'system/filters', - 'remove' => 'system/filters/remove' + 'filter_type' => ['html' => + [ + '0' => 'System', + '1' => 'User' + ] + ], + 'is_default' => ['html' => + [ + '0' => 'No', + '1' => 'Yes' + ] + ], + 'auto_generated' => ['html' => + [ + '0' => 'No', + '1' => 'Yes' + ] ] ]; - - $this->generateDTContent( - $this->filters, - 'system/filters/view', - null, - ['name', 'filter_type', 'auto_generated', 'is_default'], - true, - ['name', 'filter_type', 'auto_generated', 'is_default'], - $controlActions, - null, - $replaceColumns, - 'name' - ); - - $this->view->pick('filters/list'); + } else { + $replaceColumns = null; } + + $controlActions = + [ + 'actionsToEnable' => + [ + 'edit' => 'system/filters', + 'remove' => 'system/filters/remove' + ] + ]; + + $this->generateDTContent( + $this->filters, + 'system/filters/view', + null, + ['name', 'app_type', 'filter_type', 'auto_generated', 'is_default'], + true, + ['name', 'app_type', 'filter_type', 'auto_generated', 'is_default'], + $controlActions, + null, + $replaceColumns, + 'name' + ); + + $this->view->pick('filters/list'); } /** @@ -112,7 +113,7 @@ public function addAction() $this->view->filters = $this->filters->packagesData->filters; } else { - //Adding close in add as cloning requires add permission so both add and clone can be performed in same action. + //Adding clone in add as cloning requires add permission so both add and clone can be performed in same action. if (isset($this->postData()['clone']) && $this->postData()['clone']) { $this->filters->cloneFilter($this->postData()); } else { diff --git a/system/Base/Installer/Packages/Setup/Register/Basepackages/Filter.php b/system/Base/Installer/Packages/Setup/Register/Basepackages/Filter.php index 45079dfe3..8c04f4edd 100644 --- a/system/Base/Installer/Packages/Setup/Register/Basepackages/Filter.php +++ b/system/Base/Installer/Packages/Setup/Register/Basepackages/Filter.php @@ -21,6 +21,7 @@ public function register($db, $ff) $filter = [ 'name' => 'Exclude Auto Generated Filters', + 'app_type' => 'core', 'component_id' => $filterComponent[0]['id'], 'conditions' => '-|auto_generated|equals|0&', 'filter_type' => 0, @@ -41,6 +42,7 @@ public function register($db, $ff) $filter = [ 'name' => 'Exclude Auto Generated Filters', + 'app_type' => 'core', 'component_id' => $filterComponent['id'], 'conditions' => '-|auto_generated|equals|0&', 'filter_type' => 0, diff --git a/system/Base/Installer/Packages/Setup/Schema/Basepackages/Filters.php b/system/Base/Installer/Packages/Setup/Schema/Basepackages/Filters.php index 216b96cfc..f82ad33e7 100644 --- a/system/Base/Installer/Packages/Setup/Schema/Basepackages/Filters.php +++ b/system/Base/Installer/Packages/Setup/Schema/Basepackages/Filters.php @@ -28,6 +28,14 @@ public function columns() 'notNull' => true, ] ), + new Column( + 'app_type', + [ + 'type' => Column::TYPE_VARCHAR, + 'size' => 50, + 'notNull' => true, + ] + ), new Column( 'component_id', [ diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Filters.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Filters.php index 88bb46ab7..6396eb868 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Filters.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Filters.php @@ -2,7 +2,6 @@ namespace System\Base\Providers\BasepackagesServiceProvider\Packages; -// use Apps\Core\Packages\Hrms\Employees\Employees; use System\Base\BasePackage; use System\Base\Providers\BasepackagesServiceProvider\Packages\Model\BasepackagesFilters; @@ -20,7 +19,6 @@ public function getFiltersForComponent(int $componentId) if ($checkShowAllFilters) { return $this->getFilters($componentId); - } else { $this->addShowAllFilter($componentId); @@ -48,15 +46,24 @@ protected function checkShowAllFilters(int $componentId) return $this->getByParams( [ - 'conditions' => 'component_id = :cid: AND auto_generated = :ag:', + 'conditions' => 'component_id = :cid: AND auto_generated = :ag: AND app_type = :at:', 'bind' => [ 'cid' => $componentId, - 'ag' => 1 + 'ag' => 1, + 'at' => $this->app['app_type'] ] ], true ); } else { - return $this->getByParams(['conditions' => [['component_id', '=', $componentId], ['auto_generated', '=', 1]]]); + return $this->getByParams( + ['conditions' => + [ + ['component_id', '=', $componentId], + ['auto_generated', '=', 1], + ['app_type', '=', $this->app['app_type']] + ] + ] + ); } } @@ -64,20 +71,15 @@ protected function getFilters(int $componentId, array $account = null) { $component = $this->modules->components->getComponentById($componentId); - // $employeesPackage = $this->init()->checkPackage('Apps\Core\Packages\Hrms\Employees\Employees'); - - // if ($employeesPackage) { - // $employeesPackage = new \Apps\Core\Packages\Hrms\Employees\Employees; - // } - if ($account && isset($account['id'])) { if ($this->config->databasetype === 'db') { $filtersArr = $this->getByParams( [ - 'conditions' => 'component_id = :cid: AND (account_id = :aid: OR account_id = :aid0:)', + 'conditions' => 'component_id = :cid: AND app_type = :at: AND (account_id = :aid: OR account_id = :aid0:)', 'bind' => [ 'cid' => $componentId, + 'at' => $this->app['app_type'], 'aid' => $account['id'], 'aid0' => 0 ] @@ -90,6 +92,7 @@ protected function getFilters(int $componentId, array $account = null) 'conditions' => [ ['component_id', '=', $componentId], + ['app_type', '=', $this->app['app_type']] ], [ ['account_id', '=', $account['id']], @@ -150,18 +153,6 @@ protected function getFilters(int $componentId, array $account = null) 'name' => $sharingAccount['email'] ]; } - - // if ($employeesPackage) { - // $employee = $employeesPackage->searchByAccountId($sharingAid); - - // if ($employee) { - // $filter['shared_ids']['eids'][$sharingAidKey] = - // [ - // 'id' => $sharingAid, - // 'name' => $employee['full_name'] - // ]; - // } - // } } } @@ -176,9 +167,10 @@ protected function getFilters(int $componentId, array $account = null) $sharedFiltersArr = $this->getByParams( [ - 'conditions' => 'component_id = :cid: AND shared_ids IS NOT NULL', + 'conditions' => 'component_id = :cid: AND app_type = :at: AND shared_ids IS NOT NULL', 'bind' => [ - 'cid' => $componentId + 'cid' => $componentId, + 'at' => $this->app['app_type'] ] ] ); @@ -188,6 +180,7 @@ protected function getFilters(int $componentId, array $account = null) [ 'conditions' => [ ['component_id', '=', $componentId], + ['app_type', '=', $this->app['app_type']], ['shared_ids', '!=', null] ] ] @@ -207,20 +200,11 @@ protected function getFilters(int $componentId, array $account = null) ) { foreach ($filter['shared_ids']['rids'] as $ridKey => $rid) { if ($rid == $account['role_id']) { + $sharedBy = $this->basepackages->accounts->getById($filter['account_id']); - // if ($employeesPackage) { - // $employee = $employeesPackage->searchByAccountId($filter['account_id']); - - // if ($employee) { - // $filter['employee_full_name'] = $employee['full_name']; - // } - // } else { - $sharedBy = $this->basepackages->accounts->getById($filter['account_id']); - - if ($sharedBy) { - $filter['account_email'] = $sharedBy['email']; - } - // } + if ($sharedBy) { + $filter['account_email'] = $sharedBy['email']; + } $filter['shared_ids'] = $this->escaper->escapeHtml($this->helper->encode($filter['shared_ids'])); @@ -235,20 +219,11 @@ protected function getFilters(int $componentId, array $account = null) ) { foreach ($filter['shared_ids']['aids'] as $aidKey => $aid) { if ($aid == $account['id']) { + $sharedBy = $this->basepackages->accounts->getById($filter['account_id']); - // if ($employeesPackage) { - // $employee = $employeesPackage->searchByAccountId($filter['account_id']); - - // if ($employee) { - // $filter['employee_full_name'] = $employee['full_name']; - // } - // } else { - $sharedBy = $this->basepackages->accounts->getById($filter['account_id']); - - if ($sharedBy) { - $filter['account_email'] = $sharedBy['email']; - } - // } + if ($sharedBy) { + $filter['account_email'] = $sharedBy['email']; + } $filter['shared_ids'] = $this->escaper->escapeHtml($this->helper->encode($filter['shared_ids'])); @@ -273,9 +248,10 @@ protected function getFilters(int $componentId, array $account = null) $filtersArr = $this->getByParams( [ - 'conditions' => 'component_id = :cid:', + 'conditions' => 'component_id = :cid: AND app_type = :at:', 'bind' => [ - 'cid' => $componentId + 'cid' => $componentId, + 'at' => $this->app['app_type'] ] ] ); @@ -284,7 +260,8 @@ protected function getFilters(int $componentId, array $account = null) $this->getByParams( [ 'conditions' => [ - ['component_id', '=', $componentId] + ['component_id', '=', $componentId], + ['app_type', '=', $this->app['app_type']] ] ] ); @@ -332,6 +309,7 @@ protected function addShowAllFilter(int $componentId) $this->addFilter( [ 'name' => 'Show All ' . $component['name'], + 'app_type' => $this->app['app_type'], 'conditions' => '', 'component_id' => $componentId, 'filter_type' => 0,//System @@ -386,6 +364,7 @@ protected function addFilterForNotifications($component) $this->addFilter( [ 'name' => $name, + 'app_type' => $this->app['app_type'], 'conditions' => $condition, 'component_id' => $component['id'], 'filter_type' => 0,//System @@ -445,6 +424,7 @@ protected function addFilterForEmailQueue($component) $this->addFilter( [ 'name' => $name, + 'app_type' => $this->app['app_type'], 'conditions' => $condition, 'component_id' => $component['id'], 'filter_type' => 0,//System @@ -504,6 +484,7 @@ protected function addFilterForWorkersJobs($component) $this->addFilter( [ 'name' => $name, + 'app_type' => $this->app['app_type'], 'conditions' => $condition, 'component_id' => $component['id'], 'filter_type' => 0,//System @@ -577,20 +558,8 @@ public function updateFilter(array $data) } if (isset($data['shared_ids']) && is_array($data['shared_ids'])) { - //Convert EmployeeIds to AccountIds $data['shared_ids']['aids'] = []; - // if (isset($data['shared_ids']['eids']) && count($data['shared_ids']['eids']) > 0) { - // $employees = $this->usePackage(Employees::class); - - // foreach ($data['shared_ids']['eids'] as $eidKey => $eid) { - // $searchEmployee = $employees->getById($eid); - - // if ($searchEmployee) { - // array_push($data['shared_ids']['aids'], $searchEmployee['id']); - // } - // } - // unset($data['shared_ids']['eids']); - // } + $data['shared_ids'] = $this->helper->encode($data['shared_ids']); } @@ -701,30 +670,39 @@ public function getDefaultFilter(int $componentId) if ($this->config->databasetype === 'db') { $params = [ - 'conditions' => 'component_id = :cid: AND is_default = :isd: AND account_id = :aid:', + 'conditions' => 'component_id = :cid: AND is_default = :isd: AND account_id = :aid: AND app_type = :at:', 'bind' => [ 'cid' => $componentId, 'isd' => '1', - 'aid' => $account['id'] + 'aid' => $account['id'], + 'at' => $this->app['app_type'] ] ]; } else { - $params = ['conditions' => [['component_id', '=', $componentId], ['is_default', '=', 1], ['account_id', '=', $account['id']]]]; + $params = ['conditions' => + [ + ['component_id', '=', $componentId], + ['is_default', '=', 1], + ['account_id', '=', $account['id']], + ['app_type', '=', $this->app['app_type']], + ] + ]; } } else { if ($this->config->databasetype === 'db') { $params = [ - 'conditions' => 'component_id = :cid: AND is_default = :isd:', + 'conditions' => 'component_id = :cid: AND is_default = :isd: AND app_type = :at:', 'bind' => [ 'cid' => $componentId, - 'isd' => '1' + 'isd' => '1', + 'at' => $this->app['app_type'] ] ]; } else { - $params = ['conditions' => [['component_id', '=', $componentId], ['is_default', '=', 1]]]; + $params = ['conditions' => [['component_id', '=', $componentId], ['is_default', '=', 1], ['app_type', '=', $this->app['app_type']]]]; } } diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Model/BasepackagesFilters.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Model/BasepackagesFilters.php index 78249dfe1..68e089d4b 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Model/BasepackagesFilters.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Model/BasepackagesFilters.php @@ -10,6 +10,8 @@ class BasepackagesFilters extends BaseModel public $name; + public $app_type; + public $component_id; public $conditions; From 065fcc1b04f689e224cd4772a8390e9dfed92d5c Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Sun, 4 May 2025 15:33:46 +1000 Subject: [PATCH 39/40] fix issue #443 --- .../Access/Auth/Password.php | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/system/Base/Providers/AccessServiceProvider/Access/Auth/Password.php b/system/Base/Providers/AccessServiceProvider/Access/Auth/Password.php index 4587b67af..a86379e01 100644 --- a/system/Base/Providers/AccessServiceProvider/Access/Auth/Password.php +++ b/system/Base/Providers/AccessServiceProvider/Access/Auth/Password.php @@ -280,8 +280,8 @@ protected function checkPwPolicyComplex($data) $stringLengthArr['max']['checkLength'] = (int) $this->core->core['settings']['security']['passwordPolicySettings']['passwordPolicyLengthMax']; $stringLengthArr['messageMinimum']['checkLength'] = "passwordPolicyLengthMin|Password minimum length requirement failed."; $stringLengthArr['messageMaximum']['checkLength'] = "passwordPolicyLengthMax|Password maximum length requirement failed."; - $stringLengthArr['includedMinimum']['checkLength'] = false; - $stringLengthArr['includedMaximum']['checkLength'] = false; + $stringLengthArr['includedMinimum']['checkLength'] = true; + $stringLengthArr['includedMaximum']['checkLength'] = true; //Uppercase if ($this->core->core['settings']['security']['passwordPolicySettings']['passwordPolicyUppercase'] == true) { @@ -305,8 +305,8 @@ protected function checkPwPolicyComplex($data) $stringLengthArr['max']['checkUpperLength'] = (int) $this->core->core['settings']['security']['passwordPolicySettings']['passwordPolicyUppercaseMaxCount']; $stringLengthArr['messageMinimum']['checkUpperLength'] = "passwordPolicyUppercaseMinCount|Password minimum length requirement failed."; $stringLengthArr['messageMaximum']['checkUpperLength'] = "passwordPolicyUppercaseMaxCount|Password maximum length requirement failed."; - $stringLengthArr['includedMinimum']['checkUpperLength'] = false; - $stringLengthArr['includedMaximum']['checkUpperLength'] = false; + $stringLengthArr['includedMinimum']['checkUpperLength'] = true; + $stringLengthArr['includedMaximum']['checkUpperLength'] = true; } $this->passwordPolicyErrors['passwordPolicyUppercaseInclude'] = false; @@ -329,8 +329,8 @@ protected function checkPwPolicyComplex($data) $stringLengthArr['max']['checkUpperInclude'] = 0; $stringLengthArr['messageMinimum']['checkUpperInclude'] = "passwordPolicyUppercaseInclude|Password has invalid uppercase character."; $stringLengthArr['messageMaximum']['checkUpperInclude'] = "passwordPolicyUppercaseInclude|Password has invalid uppercase character."; - $stringLengthArr['includedMinimum']['checkUpperInclude'] = false; - $stringLengthArr['includedMaximum']['checkUpperInclude'] = false; + $stringLengthArr['includedMinimum']['checkUpperInclude'] = true; + $stringLengthArr['includedMaximum']['checkUpperInclude'] = true; } } @@ -364,8 +364,8 @@ protected function checkPwPolicyComplex($data) $stringLengthArr['max']['checkLowerLength'] = (int) $this->core->core['settings']['security']['passwordPolicySettings']['passwordPolicyLowercaseMaxCount']; $stringLengthArr['messageMinimum']['checkLowerLength'] = "passwordPolicyLowercaseMinCount|Password minimum length requirement failed."; $stringLengthArr['messageMaximum']['checkLowerLength'] = "passwordPolicyLowercaseMaxCount|Password maximum length requirement failed."; - $stringLengthArr['includedMinimum']['checkLowerLength'] = false; - $stringLengthArr['includedMaximum']['checkLowerLength'] = false; + $stringLengthArr['includedMinimum']['checkLowerLength'] = true; + $stringLengthArr['includedMaximum']['checkLowerLength'] = true; } $this->passwordPolicyErrors['passwordPolicyLowercaseInclude'] = false; @@ -388,8 +388,8 @@ protected function checkPwPolicyComplex($data) $stringLengthArr['max']['checkLowerInclude'] = 0; $stringLengthArr['messageMinimum']['checkLowerInclude'] = "passwordPolicyLowercaseInclude|Password has invalid lowercase character."; $stringLengthArr['messageMaximum']['checkLowerInclude'] = "passwordPolicyLowercaseInclude|Password has invalid lowercase character."; - $stringLengthArr['includedMinimum']['checkLowerInclude'] = false; - $stringLengthArr['includedMaximum']['checkLowerInclude'] = false; + $stringLengthArr['includedMinimum']['checkLowerInclude'] = true; + $stringLengthArr['includedMaximum']['checkLowerInclude'] = true; } } @@ -423,8 +423,8 @@ protected function checkPwPolicyComplex($data) $stringLengthArr['max']['checkNumbersLength'] = (int) $this->core->core['settings']['security']['passwordPolicySettings']['passwordPolicyNumbersMaxCount']; $stringLengthArr['messageMinimum']['checkNumbersLength'] = "passwordPolicyNumbersMinCount|Password minimum length requirement failed."; $stringLengthArr['messageMaximum']['checkNumbersLength'] = "passwordPolicyNumbersMaxCount|Password maximum length requirement failed."; - $stringLengthArr['includedMinimum']['checkNumbersLength'] = false; - $stringLengthArr['includedMaximum']['checkNumbersLength'] = false; + $stringLengthArr['includedMinimum']['checkNumbersLength'] = true; + $stringLengthArr['includedMaximum']['checkNumbersLength'] = true; } $this->passwordPolicyErrors['passwordPolicyNumbersInclude'] = false; @@ -447,8 +447,8 @@ protected function checkPwPolicyComplex($data) $stringLengthArr['max']['checkNumbersInclude'] = 0; $stringLengthArr['messageMinimum']['checkNumbersInclude'] = "passwordPolicyNumbersInclude|Password has invalid numbers."; $stringLengthArr['messageMaximum']['checkNumbersInclude'] = "passwordPolicyNumbersInclude|Password has invalid numbers."; - $stringLengthArr['includedMinimum']['checkNumbersInclude'] = false; - $stringLengthArr['includedMaximum']['checkNumbersInclude'] = false; + $stringLengthArr['includedMinimum']['checkNumbersInclude'] = true; + $stringLengthArr['includedMaximum']['checkNumbersInclude'] = true; } } @@ -482,8 +482,8 @@ protected function checkPwPolicyComplex($data) $stringLengthArr['max']['checkSymbolsLength'] = (int) $this->core->core['settings']['security']['passwordPolicySettings']['passwordPolicySymbolsMaxCount']; $stringLengthArr['messageMinimum']['checkSymbolsLength'] = "passwordPolicySymbolsMinCount|Password minimum length requirement failed."; $stringLengthArr['messageMaximum']['checkSymbolsLength'] = "passwordPolicySymbolsMaxCount|Password maximum length requirement failed."; - $stringLengthArr['includedMinimum']['checkSymbolsLength'] = false; - $stringLengthArr['includedMaximum']['checkSymbolsLength'] = false; + $stringLengthArr['includedMinimum']['checkSymbolsLength'] = true; + $stringLengthArr['includedMaximum']['checkSymbolsLength'] = true; } $this->passwordPolicyErrors['passwordPolicySymbolsInclude'] = false; @@ -506,8 +506,8 @@ protected function checkPwPolicyComplex($data) $stringLengthArr['max']['checkSymbolsInclude'] = 0; $stringLengthArr['messageMinimum']['checkSymbolsInclude'] = "passwordPolicySymbolsInclude|Password has invalid symbols."; $stringLengthArr['messageMaximum']['checkSymbolsInclude'] = "passwordPolicySymbolsInclude|Password has invalid symbols."; - $stringLengthArr['includedMinimum']['checkSymbolsInclude'] = false; - $stringLengthArr['includedMaximum']['checkSymbolsInclude'] = false; + $stringLengthArr['includedMinimum']['checkSymbolsInclude'] = true; + $stringLengthArr['includedMaximum']['checkSymbolsInclude'] = true; } } From d8767583dcb7a9078f108204a63b548a5b92647c Mon Sep 17 00:00:00 2001 From: "Gurdeep Singh (Guru)" Date: Sun, 4 May 2025 15:48:44 +1000 Subject: [PATCH 40/40] fix issue #680 --- .../BasepackagesServiceProvider/Packages/Utils.php | 8 ++++---- .../Generator/ComputerPasswordGenerator.php | 13 ++++++++++++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/system/Base/Providers/BasepackagesServiceProvider/Packages/Utils.php b/system/Base/Providers/BasepackagesServiceProvider/Packages/Utils.php index 328a46547..8c4baacc9 100644 --- a/system/Base/Providers/BasepackagesServiceProvider/Packages/Utils.php +++ b/system/Base/Providers/BasepackagesServiceProvider/Packages/Utils.php @@ -238,16 +238,16 @@ protected function initPasswordGenerator($params = []) $maxCountTotal = 0; if (isset($params['passwordpolicyuppercase'])) { - $uppercase = $params['passwordpolicyuppercase'] == true ? true : false ; + $uppercase = $params['passwordpolicyuppercase'] == 'true' ? true : false ; } if (isset($params['passwordpolicylowercase'])) { - $lowercase = $params['passwordpolicylowercase'] == true ? true : false ; + $lowercase = $params['passwordpolicylowercase'] == 'true' ? true : false ; } if (isset($params['passwordpolicynumbers'])) { - $numbers = $params['passwordpolicynumbers'] == true ? true : false ; + $numbers = $params['passwordpolicynumbers'] == 'true' ? true : false ; } if (isset($params['passwordpolicysymbols'])) { - $symbols = $params['passwordpolicysymbols'] == true ? true : false ; + $symbols = $params['passwordpolicysymbols'] == 'true' ? true : false ; } if (isset($params['passwordpolicyavoidsimilar'])) { $avoid_similar = $params['passwordpolicyavoidsimilar'] == 'true' ? true : false ; diff --git a/system/Base/Providers/SecurityServiceProvider/PasswordGenerator/Generator/ComputerPasswordGenerator.php b/system/Base/Providers/SecurityServiceProvider/PasswordGenerator/Generator/ComputerPasswordGenerator.php index 8a6147e8c..ac014e505 100644 --- a/system/Base/Providers/SecurityServiceProvider/PasswordGenerator/Generator/ComputerPasswordGenerator.php +++ b/system/Base/Providers/SecurityServiceProvider/PasswordGenerator/Generator/ComputerPasswordGenerator.php @@ -95,13 +95,19 @@ protected function getCharactersAsPer($option, $characters, $per, $enabledOption $count = $this->getMinimumCount($option); } else if ($per === 'maximum') { $max = $this->getMaximumCount($option); + $passwordLength = \strlen($this->password); - if (!$max) { + if ($max) { + if ($max < $this->getLength('minimum')) { + $max = $this->getLength('minimum'); + } + } else { $max = $this->getLength('minimum'); } $numbersOfCharsNeeded = $max - $passwordLength; + $count = ceil($numbersOfCharsNeeded/$enabledOptionsCount); if ($count <= 0) { @@ -124,15 +130,20 @@ protected function getCharactersAsPer($option, $characters, $per, $enabledOption public function generatePassword() { $this->password = $this->getCharacters('minimum'); + $passwordLength = \strlen($this->password); + $expectedPasswordLength = $this->getLength('minimum'); + if ($passwordLength < $expectedPasswordLength) { $this->password .= $this->getCharacters('maximum'); + $passwordLength = \strlen($this->password); } if ($passwordLength > $expectedPasswordLength) { $substrlength = $expectedPasswordLength - $passwordLength; + $this->password = substr($this->password, 0, $substrlength); }