diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..8f2b3f192 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,11 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: bug, P3 +assignees: oyeaussie +type: Bug + +--- + + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..1dc5cfd42 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,11 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: enhancement, P3 +assignees: oyeaussie +type: Feature + +--- + + diff --git a/.gitignore b/.gitignore index b2157d7b9..72a620f63 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ public/1/* public/2/* public/* +!public/ping.ico !public/core/ private/* *.sublime-project diff --git a/README.md b/README.md index ae13706b1..3beca538c 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ # SP Framework - Core Caution!!! - Do not use in production. A man from downunder is still working on it... + +![Alt](https://repobeats.axiom.co/api/embed/adfc9873368b036fb044bd21afb3cfae6cc5a11b.svg "Repository Analytics") \ No newline at end of file diff --git a/apps/Core/Components/Apps/AppsComponent.php b/apps/Core/Components/Apps/AppsComponent.php index dd728c7d8..c427248ad 100644 --- a/apps/Core/Components/Apps/AppsComponent.php +++ b/apps/Core/Components/Apps/AppsComponent.php @@ -26,20 +26,34 @@ public function viewAction() return $this->throwIdNotFound(); } - if (!isset($app['default_component']) || - isset($app['default_component']) && $app['default_component'] == '0' + $dashboard = $this->modules->components->getComponentByNameForAppType('dashboards', $app['app_type']); + $home = $this->modules->components->getComponentByNameForAppType('home', $app['app_type']); + $errors = $this->modules->components->getComponentByNameForAppType('errors', $app['app_type']); + + if (!isset($app['default_component_guests']) || + isset($app['default_component_guests']) && $app['default_component_guests'] == '0' ) { if ($app['app_type'] === 'core' || $app['app_type'] === 'dash') { - $dashboard = $this->modules->components->getComponentByNameForAppType('dashboards', $app['app_type']); - if ($dashboard) { - $app['default_component'] = $dashboard['id']; + $app['default_component_guests'] = $dashboard['id']; } } else { - $home = $this->modules->components->getComponentByNameForAppType('home', $app['app_type']); + if ($home) { + $app['default_component_guests'] = $home['id']; + } + } + } + if (!isset($app['default_component_users']) || + isset($app['default_component_users']) && $app['default_component_users'] == '0' + ) { + if ($app['app_type'] === 'core' || $app['app_type'] === 'dash') { + if ($dashboard) { + $app['default_component_users'] = $dashboard['id']; + } + } else { if ($home) { - $app['default_component'] = $home['id']; + $app['default_component_users'] = $home['id']; } } } @@ -47,13 +61,9 @@ public function viewAction() if (!isset($app['errors_component']) || isset($app['errors_component']) && $app['errors_component'] == '0' ) { - $errors = $this->modules->components->getComponentByNameForAppType('errors', $app['app_type']); - if ($errors) { $app['errors_component'] = $errors['id']; } else { - $home = $this->modules->components->getComponentByNameForAppType('home', $app['app_type']); - if ($home) { $app['errors_component'] = $home['id']; } @@ -121,7 +131,27 @@ public function viewAction() $this->view->menuBaseStructure = $this->view->modulesMenus = []; } + $selectGuestComponents = []; + $selectUserComponents = []; + $this->view->dashboardComponentId = 0; + $this->view->pageComponentId = 0; foreach ($componentsArr as $key => &$componentValue) { + if ($app['app_type'] === 'core' || $app['app_type'] === 'dash') { + if ($componentValue['route'] !== 'home') { + $selectUserComponents[$key] = $componentValue; + } + $selectGuestComponents[$key] = $componentValue; + } else { + $selectUserComponents[$key] = $componentValue; + $selectGuestComponents[$key] = $componentValue; + } + + if ($componentValue['route'] === 'dashboards') { + $this->view->dashboardComponentId = $componentValue['id']; + } + if ($componentValue['route'] === 'pages') { + $this->view->pageComponentId = $componentValue['id']; + } if ($componentValue['apps']) { if (is_string($componentValue['apps'])) { $componentValue['apps'] = $this->helper->decode($componentValue['apps'], true); @@ -132,10 +162,10 @@ public function viewAction() } } - if (isset($dashboard) && $dashboard) { - if ($dashboard['id'] == $componentValue['id']) { - $componentValue['apps'][$app['id']]['enabled'] = true; - } + if ($dashboard && + $dashboard['id'] == $componentValue['id'] + ) { + $componentValue['apps'][$app['id']]['enabled'] = true; } if ($componentValue['settings']) { @@ -164,7 +194,7 @@ public function viewAction() } } - $components[$key] = $componentValue; + $components[$componentValue['id']] = $componentValue; } //Middlewares @@ -245,7 +275,9 @@ public function viewAction() } } - $this->view->components = msort($components, 'name'); + $this->view->components = msort(array: $components, key: 'name', preserveKey: true); + $this->view->selectUserComponents = $selectUserComponents; + $this->view->selectGuestComponents = $selectGuestComponents; $this->view->middlewares = msort($middlewares, 'sequence'); $this->view->views = msort($views, 'name'); $this->view->mandatoryComponents = $mandatoryComponents; @@ -266,6 +298,7 @@ public function viewAction() $this->view->acceptableUsernames = $this->apps->getAcceptableUsernamesForAppId(); $this->view->dashboards = $this->basepackages->dashboards->init()->getDashboardsByAppType($app['app_type']); + $this->view->pages = $this->basepackages->pages->init()->pages; } else { $this->view->app = null; $domains = $this->domains->domains; @@ -367,7 +400,9 @@ public function addAction() $this->apps->packagesData->responseData ); - $this->addToNotification('add', 'Added new app ' . $this->postData()['name'], null, $this->apps->packagesData->last); + if ($this->apps->packagesData->responseCode === 0) { + $this->addToNotification('add', 'Added new app ' . $this->postData()['name'], null, $this->apps->packagesData->last); + } } /** @@ -386,7 +421,9 @@ public function updateAction() $this->apps->packagesData->responseCode ); - $this->addToNotification('update', 'Updated app', null, $this->apps->packagesData->last ?? []); + if ($this->apps->packagesData->responseCode === 0) { + $this->addToNotification('update', 'Updated app', null, $this->apps->packagesData->last ?? []); + } } /** @@ -405,7 +442,9 @@ public function removeAction() $this->apps->packagesData->responseCode ); - $this->addToNotification('remove', 'Removed app with ID ' . $this->postData()['id']); + if ($this->apps->packagesData->responseCode === 0) { + $this->addToNotification('remove', 'Removed app with ID ' . $this->postData()['id']); + } } public function getFiltersAction() diff --git a/apps/Core/Components/Auth/AuthComponent.php b/apps/Core/Components/Auth/AuthComponent.php index 6becdbf5e..c3ecf4a02 100644 --- a/apps/Core/Components/Auth/AuthComponent.php +++ b/apps/Core/Components/Auth/AuthComponent.php @@ -88,7 +88,7 @@ public function loginAction() { $this->requestIsPost(); - $auth = $this->access->auth->attempt($this->postData()); + $auth = $this->access->auth->login($this->postData()); $this->addResponse( $this->access->auth->packagesData->responseMessage, diff --git a/apps/Core/Components/Dashboards/DashboardsComponent.php b/apps/Core/Components/Dashboards/DashboardsComponent.php index aa405d32b..24ccc7618 100644 --- a/apps/Core/Components/Dashboards/DashboardsComponent.php +++ b/apps/Core/Components/Dashboards/DashboardsComponent.php @@ -12,16 +12,25 @@ class DashboardsComponent extends BaseComponent public function viewAction() { if (isset($this->getData()['widgets'])) { - $this->getNewToken(); - if ($this->getData()['widgets'] == 'info') { return $this->basepackages->widgets->getWidget($this->getData()['id'], 'info')['info']; } else if ($this->getData()['widgets'] == 'content') {//This is when we add the widget via list of widgets in dashboard. $dashboardWidget = $this->basepackages->dashboards->getDashboardWidgetById($this->getData()['id'], $this->getData()['did']); - $dashboardWidget['getWidgetData'] = true; + if ($dashboardWidget) { + $dashboardWidget['getWidgetData'] = true; + + $dashboardWidgetContent = $this->basepackages->widgets->getWidget($this->getData()['wid'], 'content', $dashboardWidget); - return $this->basepackages->widgets->getWidget($this->getData()['wid'], 'content', $dashboardWidget)['content']; + if (isset($dashboardWidgetContent['content'])) { + return $dashboardWidgetContent['content']; + } + } + + //Remove Widget as it might be stale as the source content would have been deleted. + $this->basepackages->dashboards->removeWidgetFromDashboard(['dashboard_id' => $this->getData()['did'], 'id' => $this->getData()['id']]); + + return false; } } else { if (is_string($this->app['settings'])) { @@ -34,7 +43,7 @@ public function viewAction() if ($this->getData()['id'] != 0) { $dashboardId = $this->getData()['id']; - $dashboard = $this->basepackages->dashboards->getDashboardById($dashboardId, true, false); + $dashboard = $this->basepackages->dashboards->getDashboardById($dashboardId, true); if (isset($this->app['settings']['defaultDashboard'])) { if ($this->app['settings']['defaultDashboard'] == $dashboard['id']) { @@ -134,9 +143,11 @@ public function viewAction() $this->view->dashboards = $dashboards; - $this->view->dashboard = $this->basepackages->dashboards->getDashboardById($dashboardId, true, false); + $this->view->dashboard = $this->basepackages->dashboards->getDashboardById($dashboardId, true); + + $this->view->widgetsTree = $this->basepackages->widgets->getWidgetsTree('dashboards'); - $this->view->widgetsTree = $this->basepackages->widgets->getWidgetsTree(); + $this->getNewToken();//We need this token as we initiate a getDashboardWidgets(); } } } diff --git a/apps/Core/Components/Devtools/Extractgeodata/ExtractgeodataComponent.php b/apps/Core/Components/Devtools/Extractgeodata/ExtractgeodataComponent.php index 6d8fae27b..5a3e13039 100644 --- a/apps/Core/Components/Devtools/Extractgeodata/ExtractgeodataComponent.php +++ b/apps/Core/Components/Devtools/Extractgeodata/ExtractgeodataComponent.php @@ -41,8 +41,9 @@ public function processAction() $success = false; if (isset($this->postData()['geo']) && $this->postData()['geo'] == 'true') { - $success = $this->geoExtractDataPackage->downloadGeoData(); - $success = $this->geoExtractDataPackage->processGeoData(); + $success = $this->geoExtractDataPackage->downloadGeoCountriesData(); + $success = $this->geoExtractDataPackage->downloadGeoPostcodeData(); + $success = $this->geoExtractDataPackage->processGeoCountriesData(); } if (isset($this->postData()['timezone']) && $this->postData()['timezone'] == 'true') { @@ -85,13 +86,18 @@ protected function registerProgressMethods() $methods = array_merge($methods, [ [ - 'method' => 'downloadGeoData', - 'text' => 'Download Geo Location Data...', + 'method' => 'downloadGeoCountriesData', + 'text' => 'Download Geo Location Countries Data...', 'remoteWeb' => true ], [ - 'method' => 'processGeoData', - 'text' => 'Process Geo Location Data...' + 'method' => 'downloadGeoPostcodeData', + 'text' => 'Download Geo Location Postcode Data...', + 'remoteWeb' => true + ], + [ + 'method' => 'processGeoCountriesData', + 'text' => 'Process Geo Location Countries Data...' ] ] ); diff --git a/apps/Core/Components/Devtools/Migrator/MigratorComponent.php b/apps/Core/Components/Devtools/Migrator/MigratorComponent.php index 787778df5..187bf812a 100644 --- a/apps/Core/Components/Devtools/Migrator/MigratorComponent.php +++ b/apps/Core/Components/Devtools/Migrator/MigratorComponent.php @@ -13,7 +13,7 @@ public function initialize() { $this->migratorPackage = $this->usePackage(DevtoolsMigrator::class); - $this->setModuleSettings(true); + $this->setModuleSettings(); $this->setModuleSettingsData([ 'apis' => $this->migratorPackage->getAvailableApis(true, false), diff --git a/apps/Core/Components/Devtools/Modules/ModulesComponent.php b/apps/Core/Components/Devtools/Modules/ModulesComponent.php index de4b51cbe..d00b1ecd7 100644 --- a/apps/Core/Components/Devtools/Modules/ModulesComponent.php +++ b/apps/Core/Components/Devtools/Modules/ModulesComponent.php @@ -18,7 +18,7 @@ public function initialize() { $this->modulesPackage = $this->usePackage(DevtoolsModules::class); - $this->setModuleSettings(true); + $this->setModuleSettings(); $this->setModuleSettingsData([ 'apis' => $this->modulesPackage->getAvailableApis(true, false), @@ -55,26 +55,41 @@ public function viewAction() } } + $this->view->includecoremodules = false; if (isset($this->getData()['includecoremodules'])) { $this->view->includecoremodules = true; } + $this->view->clone = false; if (isset($this->getData()['clone'])) { $this->view->clone = true; } + $this->view->newrelease = false; if (isset($this->getData()['newrelease'])) { $this->view->newrelease = true; } + $this->view->subview = false; if (isset($this->getData()['subview'])) { $this->view->subview = true; } + $this->view->selectedAppType = 0; + if (isset($this->getData()['apptype'])) { + $this->view->selectedAppType = $this->getData()['apptype']; + } + $appTypesArr = $this->apps->types->types; $appTypes = []; foreach ($appTypesArr as $key => $value) { + if (isset($this->getData()['id']) && $this->view->selectedAppType !== 0) { + if ($value['app_type'] !== $this->view->selectedAppType) { + continue; + } + } + $appTypes[$value['app_type']]['id'] = $value['app_type']; $appTypes[$value['app_type']]['name'] = $value['name']; } @@ -105,24 +120,77 @@ public function viewAction() foreach ($modulesTypeArr as $modulesType) { if ($modulesType === 'bundles') { $modulesArr['modules'] = msort($this->modules->{$modulesType}->{$modulesType}, 'name'); + + foreach ($modulesArr['modules'] as $typesModuleKey => $typesModule) { + if (isset($this->getData()['apptype'])) { + if ($typesModule['app_type'] !== $this->getData()['apptype']) { + if (isset($this->getData()['includecoremodules'])) { + if ($typesModule['app_type'] !== 'core' && + $typesModule['app_type'] !== $this->getData()['apptype'] + ) { + unset($modulesArr['modules'][$typesModuleKey]); + } + } else { + if ($typesModule['app_type'] !== $this->getData()['apptype']) { + unset($modulesArr['modules'][$typesModuleKey]); + } + } + } + } + } } else if ($modulesType === 'apptypes') { $modulesArr['modules'] = msort($this->apps->types->types, 'name'); - if (!isset($this->getData()['includecoremodules'])) { - foreach ($modulesArr['modules'] as $typesModuleKey => $typesModule) { + + foreach ($modulesArr['modules'] as $typesModuleKey => $typesModule) { + $modulesArr['modules'][$typesModuleKey]['data']['app_type'] = $typesModule['app_type']; + + if (!isset($this->getData()['includecoremodules'])) { if ($typesModule['app_type'] === 'core') { unset($modulesArr['modules'][$typesModuleKey]); } } + + if (isset($this->getData()['apptype'])) { + if ($typesModule['app_type'] !== $this->getData()['apptype']) { + if (isset($this->getData()['includecoremodules'])) { + if ($typesModule['app_type'] !== 'core' && + $typesModule['app_type'] !== $this->getData()['apptype'] + ) { + unset($modulesArr['modules'][$typesModuleKey]); + } + } else { + if ($typesModule['app_type'] !== $this->getData()['apptype']) { + unset($modulesArr['modules'][$typesModuleKey]); + } + } + } + } } } else { $modulesArr = $this->processModulesArr(msort($this->modules->{$modulesType}->{$modulesType}, 'name')); ${$modulesType . 'CategoryArr'} = $modulesArr['categoryArr']; + + foreach ($modulesArr['modules'] as $typesModuleKey => $typesModule) { + if (isset($this->getData()['apptype'])) { + if (isset($this->getData()['includecoremodules'])) { + if ($typesModule['app_type'] !== 'core' && + $typesModule['app_type'] !== $this->getData()['apptype'] + ) { + unset($modulesArr['modules'][$typesModuleKey]); + } + } else { + if ($typesModule['app_type'] !== $this->getData()['apptype']) { + unset($modulesArr['modules'][$typesModuleKey]); + } + } + } + } } if ($modulesArr['modules'] && count($modulesArr['modules']) > 0) { if ($modulesType === 'views') { - if (isset($this->view->subview)) { - foreach ($modulesArr['modules'] as $moduleArrKey => $moduleArr) { + foreach ($modulesArr['modules'] as $moduleArrKey => $moduleArr) { + if ($this->view->subview) { if (array_key_exists('is_subview', $moduleArr) && $moduleArr['is_subview'] == true ) { @@ -130,10 +198,10 @@ public function viewAction() } $modules[$modulesType]['value'] = ucfirst($modulesType); $modules[$modulesType]['childs'][$moduleArrKey] = $moduleArr; + } else { + $modules[$modulesType]['value'] = ucfirst($modulesType); + $modules[$modulesType]['childs'] = $modulesArr['modules']; } - } else if (!isset($this->view->subview)) { - $modules[$modulesType]['value'] = ucfirst($modulesType); - $modules[$modulesType]['childs'] = $modulesArr['modules']; } } else { $modules[$modulesType]['value'] = ucfirst($modulesType); @@ -176,7 +244,7 @@ public function viewAction() unset($modules['components']); unset($modules['middlewares']); unset($modules['bundles']); - if (!isset($this->view->subview)) { + if (!$this->view->subview) { unset($modules['views']); } } @@ -193,12 +261,14 @@ public function viewAction() foreach ($modulesTypeArr['childs'] as $childKey => &$child) { $child = $this->modulesPackage->validateFilesHash($child); - if ($child['repoExists'] && !$child['isModified'] && $child['latestRelease']) { + if ($child['repoExists'] && !$child['isModified'] && !$child['releasePending'] && $child['latestRelease']) { unset($modules[$moduleType]['childs'][$childKey]); + + continue; } - if (isset($child['modified_files']) && count($child['modified_files']) > 0) { - $modifiedModules[$child['id']] = $child['modified_files']; + if ($child['isModified'] && isset($child['modified_files'])) { + $modifiedModules[$child['module_type']][$child['id']] = $child['modified_files']; } } } @@ -215,39 +285,42 @@ public function viewAction() $this->view->modules = $modules; - $modulesJson = []; + $apis = $this->modulesPackage->getAvailableApis(false, true); - foreach ($modules as $moduleKey => $moduleJson) { - if ($moduleKey === 'bundles' && - !$this->view->bundles - ) { - continue; - } + $this->view->modulesJson = ''; + if (isset($this->getData()['id'])) { + $modulesJson = []; - foreach ($moduleJson['childs'] as $childKey => $child) { - $modulesJson[$moduleKey][$child['id']] = - [ - 'id' => $child['id'], - 'name' => $child['name'], - 'version' => $child['version'] ?? null, - 'repo' => $child['repo'] ?? null, - ]; + foreach ($modules as $moduleKey => $moduleJson) { + if ($moduleKey === 'bundles' && + !$this->view->bundles + ) { + continue; + } - if ($moduleKey === 'views') { + foreach ($moduleJson['childs'] as $childKey => $child) { $modulesJson[$moduleKey][$child['id']] = - array_merge($modulesJson[$moduleKey][$child['id']], - [ - 'base_view_module_id' => $child['base_view_module_id'], - 'is_subview' => $child['is_subview'] ?? false - ] - ); + [ + 'id' => $child['id'], + 'name' => $child['name'], + 'version' => $child['version'] ?? null, + 'repo' => $child['repo'] ?? null, + ]; + + if ($moduleKey === 'views') { + $modulesJson[$moduleKey][$child['id']] = + array_merge($modulesJson[$moduleKey][$child['id']], + [ + 'base_view_module_id' => $child['base_view_module_id'], + 'is_subview' => $child['is_subview'] ?? false + ] + ); + } } } - } - - $this->view->modulesJson = $this->helper->encode($modulesJson); - $apis = $this->modulesPackage->getAvailableApis(false, true); + $this->view->modulesJson = $this->helper->encode($modulesJson); + } if (isset($this->getData()['id']) && isset($this->getData()['module']) && @@ -278,7 +351,8 @@ public function viewAction() $this->view->apis = $apis; $this->view->moduleTypes = $this->modulesPackage->getModuleTypes(); $this->view->moduleSettings = $this->modulesPackage->getDefaultSettings(); - if (isset($this->view->subview)) { + $this->view->moduleFilters = $this->modulesPackage->getDefaultFilters(); + if ($this->view->subview) { $this->view->moduleDependencies = $this->modulesPackage->getDefaultDependencies($type, true); } else { $this->view->moduleDependencies = $this->modulesPackage->getDefaultDependencies($type); @@ -405,6 +479,9 @@ public function viewAction() if (isset($module['settings']) && is_array($module['settings'])) { $this->view->moduleSettings = $module['settings'] = $this->helper->encode($module['settings']); } + if (isset($module['filters']) && is_array($module['filters'])) { + $this->view->moduleFilters = $module['filters'] = $this->helper->encode($module['filters']); + } if (isset($module['dependencies']) && is_array($module['dependencies'])) { $this->view->moduleDependencies = $module['dependencies'] = $this->helper->encode($module['dependencies']); } @@ -427,7 +504,6 @@ public function viewAction() $module['module_type'] = 'apptypes'; $module['id'] = $module['module_details']['id']; - } catch (\throwable $e) { throw new \Exception($e->getMessage()); } @@ -571,6 +647,19 @@ public function updateAction() ); } + public function bulkAction() + { + $this->requestIsPost(); + + $this->modulesPackage->bulkModule($this->postData()); + + $this->addResponse( + $this->modulesPackage->packagesData->responseMessage, + $this->modulesPackage->packagesData->responseCode, + $this->modulesPackage->packagesData->responseData ?? [] + ); + } + public function removeAction() { $this->requestIsPost(); @@ -583,6 +672,18 @@ public function removeAction() ); } + public function toggleVisibilityRepoAction() + { + $this->requestIsPost(); + + $this->modulesPackage->toggleVisibilityRepo($this->postData()); + + $this->addResponse( + $this->modulesPackage->packagesData->responseMessage, + $this->modulesPackage->packagesData->responseCode + ); + } + public function removeRepoAction() { $this->requestIsPost(); @@ -614,6 +715,8 @@ protected function processModulesArr($modulesArr) $modulesArr['categoryArr'] = []; foreach ($modulesArr['modules'] as $key => &$module) { + $modulesArr['modules'][$key]['data']['app_type'] = $module['app_type']; + if (!isset($modulesArr['categoryArr'][$module['category']])) { $modulesArr['categoryArr'][$module['category']]['id'] = $module['category']; $modulesArr['categoryArr'][$module['category']]['name'] = ucfirst($module['category']); @@ -888,4 +991,17 @@ public function getModifiedFilesHashAction() $this->modulesPackage->packagesData->responseCode ); } + + public function getDiffAction() + { + $this->requestIsPost(); + + $this->modulesPackage->getDiff($this->postData()); + + $this->addResponse( + $this->modulesPackage->packagesData->responseMessage, + $this->modulesPackage->packagesData->responseCode, + $this->modulesPackage->packagesData->responseData ?? [], + ); + } } \ No newline at end of file diff --git a/apps/Core/Components/Errors/ErrorsComponent.php b/apps/Core/Components/Errors/ErrorsComponent.php index 9dae5d098..5dddd0d69 100644 --- a/apps/Core/Components/Errors/ErrorsComponent.php +++ b/apps/Core/Components/Errors/ErrorsComponent.php @@ -22,14 +22,28 @@ public function controllerNotFoundAction() public function controllerPackageDependencyErrorAction() { - $this->view->pick('errors/controllerdependencyerror'); + $this->view->pick('common/errors/controllerdependencyerror'); $this->addResponse('Component Dependency Error', 1); } public function controllerViewDependencyErrorAction() { - $this->view->pick('errors/controllerdependencyerror'); + $this->view->pick('common/errors/controllerdependencyerror'); + + $this->addResponse('Component Dependency Error', 1); + } + + public function appPackagePermissionDeniedAction() + { + $this->view->pick('common/errors/controllerdependencyerror'); + + $this->addResponse('Component Dependency Error', 1); + } + + public function appComponentPermissionDeniedAction() + { + $this->view->pick('common/errors/controllerdependencyerror'); $this->addResponse('Component Dependency Error', 1); } @@ -82,4 +96,4 @@ public function invalidDataAction(...$params) $this->addResponse('Invalid data provided. Error: ' . $params[0], 1); } -} \ No newline at end of file +} diff --git a/apps/Core/Components/Home/HomeComponent.php b/apps/Core/Components/Home/HomeComponent.php index c03bd4496..2a9e4a680 100644 --- a/apps/Core/Components/Home/HomeComponent.php +++ b/apps/Core/Components/Home/HomeComponent.php @@ -12,11 +12,19 @@ class HomeComponent extends BaseComponent public function viewAction() { try { - if ($this->app['default_component'] == 0) { - return; - } + if ($this->access->auth->check()) { + if ($this->app['default_component_users'] == 0) { + return; + } - $defaultComponent = $this->modules->components->getById($this->app['default_component']); + $defaultComponent = $this->modules->components->getById($this->app['default_component_users']); + } else { + if ($this->app['default_component_guests'] == 0) { + return; + } + + $defaultComponent = $this->modules->components->getById($this->app['default_component_guests']); + } if ($defaultComponent['class'] === get_class($this)) { return; diff --git a/apps/Core/Components/Modules/ModulesComponent.php b/apps/Core/Components/Modules/ModulesComponent.php index e8e6cc2f0..93a85ff08 100644 --- a/apps/Core/Components/Modules/ModulesComponent.php +++ b/apps/Core/Components/Modules/ModulesComponent.php @@ -10,7 +10,7 @@ public function initialize() { $this->modulesManager = $this->usePackage('manager'); - $this->setModuleSettings(true); + $this->setModuleSettings(); $this->setModuleSettingsData([ 'apis' => $this->modulesManager->getAvailableApis(true, false), diff --git a/apps/Core/Components/Pages/Install/component.json b/apps/Core/Components/Pages/Install/component.json new file mode 100644 index 000000000..0cbbed1dc --- /dev/null +++ b/apps/Core/Components/Pages/Install/component.json @@ -0,0 +1,53 @@ +{ + "name" : "Pages", + "route" : "pages", + "description" : "

Manage pages via this component

", + "module_type" : "components", + "app_type" : "core", + "category" : "admin", + "version" : "0.0.0", + "repo" : "https://.../", + "class" : "Apps\\Core\\Components\\Pages\\PagesComponent", + "dependencies" : + { + "core" : + { + "name" : "Core", + "version" : "0.0.0", + "repo" : "https://.../" + }, + "components" : [], + "packages" : [], + "middlewares" : [], + "views" : [], + "external" : [], + "externals" : [] + }, + "menu" : + { + "pages" : + { + "title" : "pages", + "icon" : "file-code", + "link" : "pages" + }, + "seq" : "0" + }, + "widgets" : + [ + { + "name" : "HTML Code", + "method" : "htmlCode", + "multiple" : true, + "max_multiple" : 20, + "settings" : [] + } + ], + "settings" : + { + "mandatory" : + { + "core" : true + } + } +} \ No newline at end of file diff --git a/apps/Core/Components/Pages/PagesComponent.php b/apps/Core/Components/Pages/PagesComponent.php new file mode 100644 index 000000000..acf6d0b3f --- /dev/null +++ b/apps/Core/Components/Pages/PagesComponent.php @@ -0,0 +1,217 @@ +pages = $this->basepackages->pages; + } + + /** + * @acl(name=view) + */ + public function viewAction() + { + if (isset($this->getData()['id'])) { + $this->view->mode = 'edit'; + + $this->view->contentSources = + [ + 'file' => [ + 'source'=> 'file', + 'name' => 'HTML File' + ], + 'code' => [ + 'source'=> 'code', + 'name' => 'HTML Code' + ], + ]; + + $appTypesArr = $this->apps->types->types; + $appTypes = []; + + foreach ($appTypesArr as $value) { + $appTypes[$value['app_type']]['id'] = $value['app_type']; + $appTypes[$value['app_type']]['name'] = $value['name']; + } + + $this->view->appTypes = $appTypes; + + $appsArr = $this->apps->apps; + $apps = []; + + foreach ($appsArr as $app) { + $apps[$app['id']]['id'] = $app['id']; + $apps[$app['id']]['name'] = $app['name']; + $apps[$app['id']]['route'] = $app['route']; + $apps[$app['id']]['data']['app_type'] = $app['app_type']; + } + + $this->view->apps = $apps; + + if ($this->getData()['id'] != 0) { + $page = $this->pages->getById($this->getData()['id']); + + if (!$page) { + return $this->throwIdNotFound(); + } + + if (!isset($this->getData()['edit'])) { + if (!in_array($this->apps->getAppInfo()['route'], $page['visible_on_apps'])) { + return $this->throwIdNotFound(); + } + if ($this->apps->getAppInfo()['app_type'] !== $page['app_type']) { + return $this->throwIdNotFound(); + } + + $this->getQueryArr['id'] = null;//Add this to disable token generation on page view. + + $this->view->mode = 'view'; + + unset($this->view->contentSources); + unset($this->view->apps); + + if ($page['content_source'] === 'file') { + //Check file existence + try { + $path = str_replace(base_path(), '', $this->view->getViewsDir()); + + if ($this->localContent->fileExists($path . 'pages/files/' . $page['html_file'] . '.html')) { + $page['html_code'] = $this->view->getPartial('pages/files/' . $page['html_file']); + } else { + $this->setErrorDispatcher('templateError'); + + return; + } + } catch (\throwable | FilesystemException | UnableToCheckExistence | UnableToReadFile $e) { + throw $e; + } + } else { + if (strpos($page['html_code'], '')) { + $page['html_code'] = 'JavaScript is not supported in pages. Page will not be processed!'; + + $this->view->setViewsDir($this->modules->views->getPhalconViewPath()); + + $this->view->page = $page; + + return; + } + } + + $page = $this->pages->processWidgets($page); + + $this->view->setViewsDir($this->modules->views->getPhalconViewPath()); + } + + $this->view->page = $page; + } + + $this->view->pick('pages/view'); + + return; + } else { + if ($this->dispatcher->wasForwarded()) { + $pageId = 0; + + if ($this->access->auth->account()) { + if (isset($this->app['settings']['defaultUserPage'])) { + $pageId = (int) $this->app['settings']['defaultUserPage']; + } + } else { + if (isset($this->app['settings']['defaultGuestPage'])) { + $pageId = (int) $this->app['settings']['defaultGuestPage']; + } + } + + $this->getQueryArr['id'] = $pageId; + + return $this->viewAction(); + } + } + + $controlActions = + [ + 'includeQ' => true, + 'actionsToEnable' => + [ + 'view' => 'pages/q/', + 'edit' => 'pages/q/edit/true/', + 'remove' => 'pages/remove/q/' + ] + ]; + + $this->generateDTContent( + $this->pages, + 'pages/view', + null, + ['name', 'app_type', 'visible_on_apps'], + true, + ['name', 'app_type', 'visible_on_apps'], + $controlActions, + [], + null, + 'name' + ); + + $this->view->pick('pages/list'); + } + + /** + * @acl(name=add) + */ + public function addAction() + { + $this->requestIsPost(); + + $this->pages->addPage($this->postData()); + + $this->addResponse( + $this->pages->packagesData->responseMessage, + $this->pages->packagesData->responseCode, + $this->pages->packagesData->responseData + ); + } + + /** + * @acl(name=update) + */ + public function updateAction() + { + $this->requestIsPost(); + + $this->pages->updatePage($this->postData()); + + $this->addResponse( + $this->pages->packagesData->responseMessage, + $this->pages->packagesData->responseCode, + $this->pages->packagesData->responseData + ); + } + + /** + * @acl(name=remove) + */ + public function removeAction() + { + $this->requestIsPost(); + + $this->pages->removePage($this->postData()); + + $this->addResponse( + $this->pages->packagesData->responseMessage, + $this->pages->packagesData->responseCode + ); + } +} \ No newline at end of file diff --git a/apps/Core/Components/Pages/Widgets.php b/apps/Core/Components/Pages/Widgets.php new file mode 100644 index 000000000..97a6b7451 --- /dev/null +++ b/apps/Core/Components/Pages/Widgets.php @@ -0,0 +1,14 @@ +getWidgetContent($widget, $dashboardWidget); + } +} \ No newline at end of file diff --git a/apps/Core/Components/Pages/Widgets/Install/component.json b/apps/Core/Components/Pages/Widgets/Install/component.json new file mode 100644 index 000000000..f81113fd0 --- /dev/null +++ b/apps/Core/Components/Pages/Widgets/Install/component.json @@ -0,0 +1,35 @@ +{ + "name" : "Pages Widgets", + "route" : "pages/widgets", + "description" : "

Manage pages widgets via this component

", + "module_type" : "components", + "app_type" : "core", + "category" : "admin", + "version" : "0.0.0", + "repo" : "https://.../", + "class" : "Apps\\Core\\Components\\Pages\\Widgets\\WidgetsComponent", + "dependencies" : + { + "core" : + { + "name" : "Core", + "version" : "0.0.0", + "repo" : "https://.../" + }, + "components" : [], + "packages" : [], + "middlewares" : [], + "views" : [], + "external" : [], + "externals" : [] + }, + "menu" : "false", + "widgets" : [], + "settings" : + { + "mandatory" : + { + "core" : true + } + } +} \ No newline at end of file diff --git a/apps/Core/Components/Pages/Widgets/WidgetsComponent.php b/apps/Core/Components/Pages/Widgets/WidgetsComponent.php new file mode 100644 index 000000000..e883f0029 --- /dev/null +++ b/apps/Core/Components/Pages/Widgets/WidgetsComponent.php @@ -0,0 +1,152 @@ +pageswidgets = $this->basepackages->pageswidgets; + } + + /** + * @acl(name=view) + */ + public function viewAction() + { + //In case of nested components, you need to disable parsing of main layout else view.html in pages directory will also be parsed. + $this->view->disableLevel(\Phalcon\Mvc\View::LEVEL_MAIN_LAYOUT); + + if (isset($this->getData()['widgetinfo']) && + $this->getData()['widgetinfo'] == 'true' + ) { + return $this->basepackages->widgets->getWidget($this->getData()['id'], 'info')['info']; + } + + if (isset($this->getData()['widgetsettings']) && + $this->getData()['widgetsettings'] == 'true' + ) { + return $this->basepackages->widgets->getWidget($this->getData()['id'], 'settings')['settings']; + } + + $this->view->widgetsTree = $this->basepackages->widgets->getWidgetsTree('pages'); + + if (isset($this->getData()['id'])) { + if ($this->getData()['id'] != 0) { + $pagewidget = $this->pageswidgets->getById($this->getData()['id']); + + if (!$pagewidget) { + return $this->throwIdNotFound(); + } + + $pagewidget['info'] = $this->basepackages->widgets->getWidget($pagewidget['widget_id'], 'info')['info']; + $pagewidget['settings'] = $this->basepackages->widgets->getWidget($pagewidget['widget_id'], 'settings', $pagewidget)['settings']; + + $this->view->pagewidget = $pagewidget; + + $viewsPath = base_path('apps/' . + ucfirst($this->component['app_type']) . + '/Views/' . $this->modules->views->getViewInfo()['name'] . + '/html/'); + $this->modules->views->setPhalconViewPath($viewsPath); + + $this->view->setViewsDir($this->modules->views->getPhalconViewPath() . 'pages/'); + } + + $this->view->pick('widgets/view'); + + return; + } + + $controlActions = + [ + 'actionsToEnable' => + [ + 'edit' => 'pages/widgets', + 'remove' => 'pages/widgets/remove/' + ] + ]; + + $replaceColumns = + function ($dataArr) { + if ($dataArr && is_array($dataArr) && count($dataArr) > 0) { + foreach ($dataArr as &$data) { + if (isset($this->view->widgetsTree[$data['widget_id']])) { + $data['widget_id'] = $this->view->widgetsTree[$data['widget_id']]['name']; + } + } + } + + return $dataArr; + }; + + $this->generateDTContent( + $this->pageswidgets, + 'pages/widgets/view', + null, + ['name', 'widget_id'], + true, + ['name', 'widget_id'], + $controlActions, + ['widget_id' => 'widget (app type)'], + $replaceColumns, + 'name' + ); + + $this->view->pick('widgets/list'); + } + + /** + * @acl(name=add) + */ + public function addAction() + { + $this->requestIsPost(); + + $this->pageswidgets->addPagesWidget($this->postData()); + + $this->addResponse( + $this->pageswidgets->packagesData->responseMessage, + $this->pageswidgets->packagesData->responseCode, + $this->pageswidgets->packagesData->responseData + ); + } + + /** + * @acl(name=update) + */ + public function updateAction() + { + $this->requestIsPost(); + + $this->pageswidgets->updatePagesWidget($this->postData()); + + $this->addResponse( + $this->pageswidgets->packagesData->responseMessage, + $this->pageswidgets->packagesData->responseCode, + $this->pageswidgets->packagesData->responseData + ); + } + + /** + * @acl(name=remove) + */ + public function removeAction() + { + $this->requestIsPost(); + + $this->pageswidgets->removePagesWidget($this->postData()); + + $this->addResponse( + $this->pageswidgets->packagesData->responseMessage, + $this->pageswidgets->packagesData->responseCode + ); + } +} \ No newline at end of file diff --git a/apps/Core/Components/Register/RegisterComponent.php b/apps/Core/Components/Register/RegisterComponent.php index 26678dde7..a5a993c3e 100644 --- a/apps/Core/Components/Register/RegisterComponent.php +++ b/apps/Core/Components/Register/RegisterComponent.php @@ -146,6 +146,8 @@ public function viewAction() $this->response->setStatusCode(404); return $this->response->send(); + + exit; } $this->view->setLayout('auth'); @@ -245,4 +247,4 @@ public function apiClientAction() return $this->api->registerClient(); } -} \ No newline at end of file +} diff --git a/apps/Core/Components/System/Core/CoreComponent.php b/apps/Core/Components/System/Core/CoreComponent.php index 5d30d3a9b..6cc8c7ea8 100644 --- a/apps/Core/Components/System/Core/CoreComponent.php +++ b/apps/Core/Components/System/Core/CoreComponent.php @@ -182,6 +182,26 @@ public function viewAction() $this->view->ffStores = $ffStores; + $this->view->countries = $this->basepackages->geoCountries->getAll()->geoCountries; + + $this->view->timezones = $this->basepackages->geoTimezones->getAll()->geoTimezones; + + if (!isset($core['settings']['locale']['country_iso3']) || + (isset($core['settings']['locale']['country_iso3']) && $core['settings']['locale']['country_iso3'] === '') + ) { + if ($this->config->locale->country_iso3) { + $core['settings']['locale']['country_iso3'] = $this->config->locale->country_iso3; + } + } + + if (!isset($core['settings']['locale']['timezone']) || + (isset($core['settings']['locale']['timezone']) && $core['settings']['locale']['timezone'] === '') + ) { + if ($this->config->locale->timezone) { + $core['settings']['locale']['timezone'] = $this->config->locale->timezone; + } + } + $this->view->core = $core; } } diff --git a/apps/Core/Components/System/Email/Queue/QueueComponent.php b/apps/Core/Components/System/Email/Queue/QueueComponent.php index 19eca1ac0..14a483b02 100644 --- a/apps/Core/Components/System/Email/Queue/QueueComponent.php +++ b/apps/Core/Components/System/Email/Queue/QueueComponent.php @@ -31,12 +31,13 @@ public function viewAction() $email = $this->formatStatus(0, $email); $email = $this->formatPriority(0, $email); - $email = $this->formatSentOn(0, $email); + $email = $this->formatSentOn(0, $email, true); $email = $this->formatToAddresses(0, $email); $email = $this->formatConfidential(0, $email); $this->view->email = $email; } + return; } @@ -69,9 +70,9 @@ function ($dataArr) { $this->emailqueue, 'system/email/queue/view', $conditions, - ['status', 'priority', 'sent_on', 'to_addresses', 'subject'], + ['status', 'priority', 'confidential', 'from', 'to_addresses', 'subject', 'sent_on'], true, - ['status', 'priority', 'sent_on', 'to_addresses', 'subject'], + ['status', 'priority', 'confidential', 'from', 'to_addresses', 'subject', 'sent_on'], $controlActions, null, $replaceColumns, @@ -86,6 +87,7 @@ protected function replaceColumns($dataArr) foreach ($dataArr as $dataKey => &$data) { $data = $this->formatStatus($dataKey, $data); $data = $this->formatPriority($dataKey, $data); + $data = $this->formatConfidential($dataKey, $data); $data = $this->formatSentOn($dataKey, $data); $data = $this->formatToAddresses($dataKey, $data); $data = $this->addRequeueButton($dataKey, $data); @@ -120,14 +122,18 @@ protected function formatPriority($rowId, $data) return $data; } - protected function formatSentOn($rowId, $data) + protected function formatSentOn($rowId, $data, $id = null) { if (!$data['sent_on']) { - $data['sent_on'] = - ' - - Send Now - '; + if ($id) { + $data['sent_on'] = '-'; + } else { + $data['sent_on'] = + ' + + Send Now + '; + } } return $data; @@ -139,7 +145,16 @@ protected function formatToAddresses($rowId, $data) $data['to_addresses'] = $this->helper->decode($data['to_addresses'], true); } - $data['to_addresses'] = implode(',', $data['to_addresses']); + $toAddresses = []; + foreach ($data['to_addresses'] as $toAddress) { + if (isset($toAddress['email']) && isset($toAddress['name'])) { + array_push($toAddresses, $toAddress['email'] . '|' . $toAddress['name']); + } else { + array_push($toAddresses, $toAddress); + } + } + + $data['to_addresses'] = implode(',', $toAddresses); return $data; } @@ -151,6 +166,8 @@ protected function formatConfidential($rowId, $data) $data['body'] = "Confidential emails are encrypted on the server and cannot be viewed."; } else if ($data['confidential'] == '0') { $data['confidential'] = 'No'; + } else { + $data['confidential'] = 'No'; } return $data; @@ -172,26 +189,11 @@ protected function addRequeueButton($rowId, $data) /** * @acl(name="update") */ - public function changePriorityAction() - { - $this->requestIsPost(); - - $this->emailqueue->changePriority($this->postData()); - - $this->addResponse( - $this->emailqueue->packagesData->responseMessage, - $this->emailqueue->packagesData->responseCode - ); - } - - /** - * @acl(name="remove") - */ - public function removeAction() + public function updateAction() { $this->requestIsPost(); - $this->emailqueue->removeEmailService($this->postData()); + $this->emailqueue->updateQueue($this->postData()); $this->addResponse( $this->emailqueue->packagesData->responseMessage, @@ -227,7 +229,7 @@ public function processQueueAction() ); } - public function requeueAction() + public function reQueueAction() { $this->requestIsPost(); diff --git a/apps/Core/Components/System/Email/Services/ServicesComponent.php b/apps/Core/Components/System/Email/Services/ServicesComponent.php index 3165b5102..d44f13fc3 100644 --- a/apps/Core/Components/System/Email/Services/ServicesComponent.php +++ b/apps/Core/Components/System/Email/Services/ServicesComponent.php @@ -11,9 +11,15 @@ class ServicesComponent extends BaseComponent protected $emailservices; - public function initialize() + public function initialize($onlyActivityLogs = false) { $this->emailservices = $this->basepackages->emailservices; + + $this->setActivityLogsPackage($this->emailservices, 'system/email/services/activitylogs', [], ['password' => '*****']); + + if ($onlyActivityLogs) { + return; + } } /** @@ -31,6 +37,7 @@ public function viewAction() $this->view->emailservice = $emailservice; } + $this->view->pick('services/view'); return; diff --git a/apps/Core/Components/System/Filters/FiltersComponent.php b/apps/Core/Components/System/Filters/FiltersComponent.php index 545dcd230..77ac5ff15 100644 --- a/apps/Core/Components/System/Filters/FiltersComponent.php +++ b/apps/Core/Components/System/Filters/FiltersComponent.php @@ -11,6 +11,8 @@ class FiltersComponent extends BaseComponent protected $filters; + protected $components; + public function initialize() { $this->filters = $this->basepackages->filters; @@ -53,26 +55,13 @@ public function viewAction() if ($this->request->isPost()) { $replaceColumns = - [ - 'filter_type' => ['html' => - [ - '0' => 'System', - '1' => 'User' - ] - ], - 'is_default' => ['html' => - [ - '0' => 'No', - '1' => 'Yes' - ] - ], - 'auto_generated' => ['html' => - [ - '0' => 'No', - '1' => 'Yes' - ] - ] - ]; + function ($dataArr) { + if ($dataArr && is_array($dataArr) && count($dataArr) > 0) { + return $this->replaceColumns($dataArr); + } + + return $dataArr; + }; } else { $replaceColumns = null; } @@ -90,11 +79,11 @@ public function viewAction() $this->filters, 'system/filters/view', null, - ['name', 'app_type', 'filter_type', 'auto_generated', 'is_default'], + ['name', 'app_type', 'component_id', 'filter_type', 'is_default', 'auto_generated'], true, - ['name', 'app_type', 'filter_type', 'auto_generated', 'is_default'], + ['name', 'app_type', 'component_id', 'filter_type', 'is_default', 'auto_generated'], $controlActions, - null, + ['component_id'=>'Component (id)'], $replaceColumns, 'name' ); @@ -102,6 +91,66 @@ public function viewAction() $this->view->pick('filters/list'); } + protected function replaceColumns($dataArr) + { + foreach ($dataArr as $dataKey => &$data) { + $data = $this->formatComponentId($dataKey, $data); + $data = $this->formatFilterType($dataKey, $data); + $data = $this->formatIsDefault($dataKey, $data); + $data = $this->formatAutogenerated($dataKey, $data); + } + + return $dataArr; + } + + protected function formatComponentId($rowId, $data) + { + if (!isset($this->components[$data['component_id']])) { + $component = $this->modules->components->getById($data['component_id']); + } else { + $component = $this->components[$data['component_id']]; + } + + if ($component) { + $data['component_id'] = $component['name'] . ' (' . $component['id'] . ')'; + } + + return $data; + } + + protected function formatFilterType($rowId, $data) + { + if ($data['filter_type'] == '0') { + $data['filter_type'] = 'System (' . $data['filter_type'] . ')'; + } else if ($data['filter_type'] == '1') { + $data['filter_type'] = 'User (' . $data['filter_type'] . ')'; + } + + return $data; + } + + protected function formatIsDefault($rowId, $data) + { + if ($data['is_default'] == '0') { + $data['is_default'] = 'No (' . $data['is_default'] . ')'; + } else if ($data['is_default'] == '1') { + $data['is_default'] = 'Yes (' . $data['is_default'] . ')'; + } + + return $data; + } + + protected function formatAutogenerated($rowId, $data) + { + if ($data['auto_generated'] == '0') { + $data['auto_generated'] = 'No (' . $data['auto_generated'] . ')'; + } else if ($data['auto_generated'] == '1') { + $data['auto_generated'] = 'Yes (' . $data['auto_generated'] . ')'; + } + + return $data; + } + /** * @acl(name=add) */ @@ -207,4 +256,4 @@ public function getdefaultfilterAction() $this->filters->packagesData->responseCode ); } -} \ No newline at end of file +} diff --git a/apps/Core/Components/System/Geo/Cities/CitiesComponent.php b/apps/Core/Components/System/Geo/Cities/CitiesComponent.php index 86b7bab22..d33abde1c 100644 --- a/apps/Core/Components/System/Geo/Cities/CitiesComponent.php +++ b/apps/Core/Components/System/Geo/Cities/CitiesComponent.php @@ -21,8 +21,8 @@ public function initialize() */ public function viewAction() { - $countriesArr = $this->basepackages->geoCountries->getAll()->geoCountries; - $statesArr = $this->basepackages->geoStates->getAll()->geoStates; + $countriesArr = $this->basepackages->geoCountries->geoCountries; + $statesArr = $this->basepackages->geoStates->geoStates; if (isset($this->getData()['id'])) { if ($this->getData()['id'] != 0) { @@ -48,7 +48,7 @@ public function viewAction() // 'includeQ' => true, 'actionsToEnable' => [ - 'view' => 'system/geo/cities', + 'edit' => 'system/geo/cities', ] ]; @@ -87,11 +87,11 @@ public function viewAction() $this->geoCities, 'system/geo/cities/view', null, - ['name', 'longitude', 'latitude', 'postcode', 'state_id', 'country_id'], + ['name', 'longitude', 'latitude', 'state_id', 'country_id'], true, - ['name', 'longitude', 'latitude', 'postcode', 'state_id', 'country_id'], + ['name', 'longitude', 'latitude', 'state_id', 'country_id'], $controlActions, - ['state_id'=>'State','postcode'=>'post code', 'country_id'=>'country'], + ['state_id'=>'State','country_id'=>'country'], $replaceColumns, 'name', // $dtAdditionControlButtons @@ -152,27 +152,4 @@ public function searchCityAction() $this->addResponse('Search Query Missing', 1); } } - - public function searchPostCodeAction() - { - $this->requestIsPost(); - - if ($this->postData()['search']) { - $searchQuery = $this->postData()['search']; - - if (strlen($searchQuery) < 3) { - return; - } - - $this->basepackages->geoCities->searchPostCodes($searchQuery); - - $this->addResponse( - $this->basepackages->geoCities->packagesData->responseMessage, - $this->basepackages->geoCities->packagesData->responseCode, - $this->basepackages->geoCities->packagesData->responseData ?? [] - ); - } else { - $this->addResponse('Search Query Missing', 1); - } - } } \ No newline at end of file diff --git a/apps/Core/Components/System/Geo/Holidays/HolidaysComponent.php b/apps/Core/Components/System/Geo/Holidays/HolidaysComponent.php index 23e8fd12c..e294b32a7 100644 --- a/apps/Core/Components/System/Geo/Holidays/HolidaysComponent.php +++ b/apps/Core/Components/System/Geo/Holidays/HolidaysComponent.php @@ -4,6 +4,7 @@ use Apps\Core\Packages\Adminltetags\Traits\DynamicTable; use System\Base\BaseComponent; +use System\Base\Providers\BasepackagesServiceProvider\Packages\Geo\GeoHolidays; class HolidaysComponent extends BaseComponent { @@ -51,7 +52,7 @@ public function viewAction() return $this->throwIdNotFound(); } - $holidayTagsArr = $this->basepackages->tags->getTagsByPackageNameAndPackageRowId('GeoHolidays', $holiday['id']); + $holidayTagsArr = $this->basepackages->tags->getTagsByPackageClassAndPackageRowId(str_replace('\\', '_', GeoHolidays::Class), $holiday['id']); if (count($holidayTagsArr) > 0) { foreach ($holidayTagsArr as $tag) { @@ -68,7 +69,7 @@ public function viewAction() $this->view->holidayTags = $holidayTags; - $this->view->tags = $this->basepackages->tags->getTagsByPackageName('GeoHolidays'); + $this->view->tags = $this->basepackages->tags->getTagsByPackageClass(str_replace('\\', '_', GeoHolidays::Class)); $this->view->pick('holidays/view'); @@ -87,6 +88,8 @@ public function viewAction() $replaceColumns = function ($dataArr) { if ($dataArr && is_array($dataArr) && count($dataArr) > 0) { + $states = []; + foreach ($dataArr as &$data) { if ($data['is_national_holiday'] == '1') { $data['is_national_holiday'] = 'Yes'; @@ -94,9 +97,17 @@ function ($dataArr) { } else { $data['is_national_holiday'] = 'No'; - $state = $this->basepackages->geoStates->getById($data['state_id']); + if (isset($states[$data['state_id']])) { + $state = $states[$data['state_id']]; + } else { + $state = $this->basepackages->geoStates->getById($data['state_id']); + } if ($state) { + if (!isset($states[$state['id']])) { + $states[$state['id']] = $state; + } + $data['state_id'] = $state['name']; } else { $data['state_id'] = '-'; diff --git a/apps/Core/Components/System/Geo/Postcodes/Install/component.json b/apps/Core/Components/System/Geo/Postcodes/Install/component.json new file mode 100644 index 000000000..01d8e1d10 --- /dev/null +++ b/apps/Core/Components/System/Geo/Postcodes/Install/component.json @@ -0,0 +1,59 @@ +{ + "name" : "Geo Postcodes", + "route" : "system/geo/postcodes", + "description" : "

Manage geo postcodes via this component

", + "module_type" : "components", + "app_type" : "core", + "category" : "admin", + "version" : "0.0.0", + "repo" : "https://.../", + "class" : "Apps\\Core\\Components\\System\\Geo\\Postcodes\\PostcodesComponent", + "dependencies" : + { + "core" : + { + "name" : "Core", + "version" : "0.0.0", + "repo" : "https://.../" + }, + "components" : [], + "packages" : [], + "middlewares" : [], + "views" : [], + "external" : [], + "externals" : [] + }, + "menu" : + { + "seq" : 6, + "system" : + { + "icon" : "cogs", + "title" : "system", + "childs" : + { + "geolocations" : + { + "title" : "Geo Locations", + "icon" : "globe", + "childs" : + { + "postcodes" : + { + "title" : "Postcodes", + "link" : "system/geo/postcodes" + } + } + } + } + } + }, + "widgets" : [], + "settings" : + { + "mandatory" : + { + "core" : true + } + } +} \ No newline at end of file diff --git a/apps/Core/Components/System/Geo/Postcodes/PostcodesComponent.php b/apps/Core/Components/System/Geo/Postcodes/PostcodesComponent.php new file mode 100644 index 000000000..56266fca8 --- /dev/null +++ b/apps/Core/Components/System/Geo/Postcodes/PostcodesComponent.php @@ -0,0 +1,177 @@ +geoPostcodes = $this->basepackages->geoPostcodes->init(); + } + + /** + * @acl(name=view) + */ + public function viewAction() + { + $statesArr = $this->basepackages->geoStates->geoStates; + $countriesArr = $this->basepackages->geoCountries->geoCountries; + + if (isset($this->getData()['id'])) { + if ($this->getData()['id'] != 0) { + $postcode = $this->basepackages->geoPostcodes->getById($this->getData()['id']); + + $this->view->postcode = $postcode; + } + + if (!$this->view->postcode) { + return $this->throwIdNotFound(); + } + + $this->view->pick('postcodes/view'); + + $this->view->countries = [$countriesArr[$postcode['country_id']]]; + $this->view->states = [$statesArr[$postcode['state_id']]]; + + return; + } + + $controlActions = + [ + // 'includeQ' => true, + 'actionsToEnable' => + [ + 'edit' => 'system/geo/postcodes', + ] + ]; + + if ($this->request->isPost()) { + $countries = []; + $states = []; + + if ($countriesArr) { + foreach ($countriesArr as $countriesKey => $country) { + $countries[$country['id']] = $country['name'] . ' (' . $country['id'] . ')'; + } + } + + if ($statesArr) { + foreach ($statesArr as $statesKey => $state) { + $states[$state['id']] = $state['name'] . ' (' . $state['id'] . ')'; + } + } + + $replaceColumns = + [ + 'state_id' => + [ + 'html' => $states + ], + 'country_id' => + [ + 'html' => $countries + ], + ]; + } else { + $replaceColumns = []; + } + + $this->generateDTContent( + $this->geoPostcodes, + 'system/geo/postcodes/view', + null, + ['code', 'name', 'state_id', 'country_id'], + true, + ['code', 'name', 'state_id', 'country_id'], + $controlActions, + ['code'=>'post code','state_id'=>'State','country_id'=>'country'], + $replaceColumns, + 'code' + ); + + $this->view->pick('postcodes/list'); + } + + /** + * @acl(name=add) + */ + public function addAction() + { + $this->requestIsPost(); + + $this->geoPostcodes->addPostcode($this->postData()); + + $this->addResponse( + $this->geoPostcodes->packagesData->responseMessage, + $this->geoPostcodes->packagesData->responseCode + ); + } + + /** + * @acl(name=update) + */ + public function updateAction() + { + $this->requestIsPost(); + + $this->geoPostcodes->updatePostcode($this->postData()); + + $this->addResponse( + $this->geoPostcodes->packagesData->responseMessage, + $this->geoPostcodes->packagesData->responseCode + ); + } + + public function searchPostcodeAction() + { + $this->requestIsPost(); + + if ($this->postData()['search']) { + $searchQuery = $this->postData()['search']; + + if (strlen($searchQuery) < 3) { + return; + } + + $this->basepackages->geoPostcodes->searchPostcodes($searchQuery); + + $this->addResponse( + $this->basepackages->geoPostcodes->packagesData->responseMessage, + $this->basepackages->geoPostcodes->packagesData->responseCode, + $this->basepackages->geoPostcodes->packagesData->responseData ?? [] + ); + } else { + $this->addResponse('Search Query Missing', 1); + } + } + + public function searchPostCodeNameAction() + { + $this->requestIsPost(); + + if ($this->postData()['search']) { + $searchQuery = $this->postData()['search']; + + if (strlen($searchQuery) < 3) { + return; + } + + $this->basepackages->geoPostcodes->searchPostCodes($searchQuery); + + $this->addResponse( + $this->basepackages->geoPostcodes->packagesData->responseMessage, + $this->basepackages->geoPostcodes->packagesData->responseCode, + $this->basepackages->geoPostcodes->packagesData->responseData ?? [] + ); + } else { + $this->addResponse('Search Query Missing', 1); + } + } +} \ No newline at end of file diff --git a/apps/Core/Components/System/Geo/Regions/RegionsComponent.php b/apps/Core/Components/System/Geo/Regions/RegionsComponent.php index 7919a57bd..da04dabc2 100644 --- a/apps/Core/Components/System/Geo/Regions/RegionsComponent.php +++ b/apps/Core/Components/System/Geo/Regions/RegionsComponent.php @@ -21,7 +21,7 @@ public function initialize() */ public function viewAction() { - $regionsArr = $this->basepackages->geoRegions->getAll()->geoRegions; + $regionsArr = $this->basepackages->geoRegions->geoRegions; if (isset($this->getData()['id'])) { if ($this->getData()['id'] != 0) { diff --git a/apps/Core/Components/System/Geo/States/StatesComponent.php b/apps/Core/Components/System/Geo/States/StatesComponent.php index 6e2495d80..95f5a7818 100644 --- a/apps/Core/Components/System/Geo/States/StatesComponent.php +++ b/apps/Core/Components/System/Geo/States/StatesComponent.php @@ -21,7 +21,7 @@ public function initialize() */ public function viewAction() { - $countriesArr = $this->basepackages->geoCountries->getAll()->geoCountries; + $countriesArr = $this->basepackages->geoCountries->geoCountries; if (isset($this->getData()['id'])) { if ($this->getData()['id'] != 0) { @@ -46,7 +46,7 @@ public function viewAction() // 'includeQ' => true, 'actionsToEnable' => [ - 'view' => 'system/geo/states', + 'edit' => 'system/geo/states', ] ]; @@ -73,9 +73,9 @@ public function viewAction() $this->geoStates, 'system/geo/states/view', null, - ['name', 'state_code', 'country_id'], + ['name', 'country_id'], true, - ['name', 'state_code', 'country_id'], + ['name', 'country_id'], $controlActions, null, $replaceColumns, @@ -91,7 +91,14 @@ public function viewAction() */ public function addAction() { - // + $this->requestIsPost(); + + $this->geoStates->addState($this->postData()); + + $this->addResponse( + $this->geoStates->packagesData->responseMessage, + $this->geoStates->packagesData->responseCode + ); } /** @@ -99,7 +106,14 @@ public function addAction() */ public function updateAction() { - // + $this->requestIsPost(); + + $this->geoStates->updateState($this->postData()); + + $this->addResponse( + $this->geoStates->packagesData->responseMessage, + $this->geoStates->packagesData->responseCode + ); } public function searchStateAction() diff --git a/apps/Core/Components/System/Geo/Timezones/Widgets.php b/apps/Core/Components/System/Geo/Timezones/Widgets.php index 88c8ed925..f2118531e 100644 --- a/apps/Core/Components/System/Geo/Timezones/Widgets.php +++ b/apps/Core/Components/System/Geo/Timezones/Widgets.php @@ -9,7 +9,7 @@ class Widgets extends ComponentsWidgets { public function worldClock($widget, $dashboardWidget) { - $timezonesArr = $this->componentObj->getDi()->getShared('basepackages')->geoTimezones->getAll()->geoTimezones; + $timezonesArr = $this->componentObj->getDi()->getShared('basepackages')->geoTimezones->geoTimezones; $timezones = []; foreach ($timezonesArr as $timezone) { diff --git a/apps/Core/Components/System/Menus/MenusComponent.php b/apps/Core/Components/System/Menus/MenusComponent.php index d98120d79..705e4e5af 100644 --- a/apps/Core/Components/System/Menus/MenusComponent.php +++ b/apps/Core/Components/System/Menus/MenusComponent.php @@ -44,6 +44,7 @@ public function viewAction() 'actionsToEnable' => [ 'view' => 'system/menus', + 'remove' => 'system/menus/remove', ] ]; @@ -57,7 +58,7 @@ public function viewAction() $controlActions, null, null, - 'id' + 'route' ); $this->view->pick('menus/list'); @@ -84,6 +85,13 @@ public function updateAction() */ public function removeAction() { - // + $this->requestIsPost(); + + $removeMenu = $this->menus->removeMenu($this->postData()); + + $this->addResponse( + $this->menus->packagesData->responseMessage, + $this->menus->packagesData->responseCode + ); } } \ No newline at end of file diff --git a/apps/Core/Components/System/Mutex/Install/component.json b/apps/Core/Components/System/Mutex/Install/component.json new file mode 100644 index 000000000..bd11f1731 --- /dev/null +++ b/apps/Core/Components/System/Mutex/Install/component.json @@ -0,0 +1,53 @@ +{ + "name" : "Mutex Lock", + "route" : "system/mutex", + "description" : "

Manage mutex lock data via this component

", + "module_type" : "components", + "app_type" : "core", + "category" : "admin", + "version" : "0.0.0", + "repo" : "https://.../", + "class" : "Apps\\Core\\Components\\System\\Mutex\\MutexComponent", + "dependencies" : + { + "core" : + { + "name" : "Core", + "version" : "0.0.0", + "repo" : "https://.../" + }, + "components" : [], + "packages" : [], + "middlewares" : [], + "views" : [], + "external" : [], + "externals" : [] + }, + "menu" : + { + "system" : + { + "title" : "system", + "icon" : "cogs", + "childs" : + { + "mutexlock" : + { + "title" : "mutex lock", + "icon" : "lock", + "link" : "system/mutex" + } + } + }, + "seq" : "0" + }, + "widgets" : [], + "filters" : [], + "settings" : + { + "mandatory" : + { + "core" : true + } + } +} \ No newline at end of file diff --git a/apps/Core/Components/System/Mutex/MutexComponent.php b/apps/Core/Components/System/Mutex/MutexComponent.php new file mode 100644 index 000000000..f434e1685 --- /dev/null +++ b/apps/Core/Components/System/Mutex/MutexComponent.php @@ -0,0 +1,105 @@ +mutex = $this->basepackages->mutex; + } + + /** + * @acl(name=view) + */ + public function viewAction() + { + $controlActions = + [ + // 'disableActionsForIds' => [1], + 'actionsToEnable' => + [ + 'remove' => 'system/mutex/remove' + ] + ]; + + $replaceColumns = + function ($dataArr) { + if ($dataArr && is_array($dataArr) && count($dataArr) > 0) { + return $this->replaceColumns($dataArr); + } + + return $dataArr; + }; + + $this->generateDTContent( + $this->mutex, + 'system/mutex/view', + null, + ['package_class', 'package_row_id', 'parent_lock_id', 'locked_at', 'account_id'], + false, + ['package_class', 'package_row_id', 'parent_lock_id', 'locked_at', 'account_id'], + null, + ['parent_lock_id' => 'Locked By (Mutex ID)', 'locked_at' => 'Locked At | Release At'], + $replaceColumns, + 'package_row_id' + ); + + $this->view->pick('mutex/list'); + } + + protected function replaceColumns($dataArr) + { + foreach ($dataArr as $dataKey => &$data) { + if (isset($data['locked_at']) && $data['locked_at'] > 0) { + $releaseTime = $data['locked_at'] + $this->mutex->getTimeout(); + $data['locked_at'] = (\Carbon\Carbon::parse($data['locked_at']))->toAtomString(); + $data['locked_at'] = $data['locked_at'] . ' | ' . (\Carbon\Carbon::parse($releaseTime))->toAtomString(); + } + + $account = $this->basepackages->accounts->getAccountById($data['account_id']); + + if ($account && isset($account['contact']['full_name'])) { + $data['account_id'] = $account['contact']['full_name']; + } + + $data = $this->generateRemoveButton($dataKey, $data); + } + + return $dataArr; + } + + protected function generateRemoveButton($rowId, $data) + { + if ($data['parent_lock_id'] == '0') { + $data['parent_lock_id'] = + ' + Remove lock + '; + } + + return $data; + } + + /** + * @acl(name="remove") + */ + public function removeAction() + { + $this->requestIsPost(); + + $this->mutex->releaseMutex($this->postData()); + + $this->addResponse( + $this->mutex->packagesData->responseMessage, + $this->mutex->packagesData->responseCode + ); + } +} \ No newline at end of file diff --git a/apps/Core/Components/System/Notifications/NotificationsComponent.php b/apps/Core/Components/System/Notifications/NotificationsComponent.php index 340d258ec..340e6f84a 100644 --- a/apps/Core/Components/System/Notifications/NotificationsComponent.php +++ b/apps/Core/Components/System/Notifications/NotificationsComponent.php @@ -52,6 +52,17 @@ function ($dataArr) { return $dataArr; }; + $quickFilterConditions = function() { + if (str_contains($this->postData()['conditions'], 'account_id')) { + throw new \Exception('Cannot access other users data!'); + } + + return + str_replace( + '-|', '-|app_id|equals|' . $this->apps->getAppInfo()['id'] . '&and|account_id|equals|' . $this->access->auth->account()['id'] . '&and|' , $this->postData()['conditions'] + ); + }; + $this->generateDTContent( $this->notifications, 'system/notifications/view', @@ -75,7 +86,10 @@ function ($dataArr) { false, null, false, - false + false, + [], + [], + $quickFilterConditions ); $this->view->pick('notifications/list'); @@ -132,13 +146,15 @@ protected function packageLinks() { $routeLinks = []; - foreach ($this->modules->packages->packages as $packageKey => $package) { + $packages = $this->modules->packages->getPackagesForAppType($this->app['app_type']); + + foreach ($packages as $packageKey => $package) { if ($package['settings'] && $package['settings'] !== '' && $package['settings'] !== '[]') { - if (is_string($package['settings'])) { + if (!is_array($package['settings'])) { $package['settings'] = $this->helper->decode($package['settings'], true); } if (isset($package['settings']['componentRoute'])) { - $routeLinks[$package['name']] = $package['settings']['componentRoute']; + $routeLinks[strtolower($package['name'])] = strtolower($package['settings']['componentRoute']); } } } @@ -152,7 +168,7 @@ protected function generateUserInfo($rowId, $data) $profile = $this->basepackages->profiles->getProfile($data['created_by']); if ($profile) { - $data['created_by'] = $profile['full_name']; + $data['created_by'] = $profile['contact']['full_name']; } else { $data['created_by'] = 'System'; } @@ -166,12 +182,18 @@ protected function generateUserInfo($rowId, $data) protected function generateLinkButton($rowId, $data) { if ($data['package_row_id']) { - if (array_key_exists($data['package_name'], $this->packageLinks())) { - $data['package_row_id'] = - ' - - '; + $link = '#'; + + if (array_key_exists(strtolower($data['package_name']), $this->packageLinks())) { + $link = $this->links->url($this->packageLinks()[strtolower($data['package_name'])] . '/q/id/' . $data['package_row_id']); + } else if ($key = array_search(strtolower($data['package_name']), $this->packageLinks())) { + $link = $this->links->url($this->packageLinks()[$key] . '/q/id/' . $data['package_row_id']); } + + $data['package_row_id'] = + ' + + '; } return $data; diff --git a/apps/Core/Components/System/Storages/StoragesComponent.php b/apps/Core/Components/System/Storages/StoragesComponent.php index 77fd8ed56..52d4cde8b 100644 --- a/apps/Core/Components/System/Storages/StoragesComponent.php +++ b/apps/Core/Components/System/Storages/StoragesComponent.php @@ -13,7 +13,7 @@ class StoragesComponent extends BaseComponent public function initialize() { - $this->setModuleSettings(true); + $this->setModuleSettings(); $this->storages = $this->usePackage('storages'); } diff --git a/apps/Core/Components/System/Tags/TagsComponent.php b/apps/Core/Components/System/Tags/TagsComponent.php index e61056e27..d492ca22b 100644 --- a/apps/Core/Components/System/Tags/TagsComponent.php +++ b/apps/Core/Components/System/Tags/TagsComponent.php @@ -27,11 +27,17 @@ public function viewAction() if ($this->getData()['id'] != 0) { $tag = $this->basepackages->tags->getById((int) $this->getData()['id']); - $this->view->tag = $tag; - - if (!$this->view->tag) { + if (!$tag) { return $this->throwIdNotFound(); } + + $package = $this->modules->packages->getPackageByClass(str_replace('_', '\\', $tag['package_class'])); + + if ($package) { + $tag['package_class'] = $package['name']; + } + + $this->view->tag = $tag; } $this->view->pick('tags/view'); @@ -55,6 +61,12 @@ public function viewAction() function ($dataArr) { if ($dataArr && is_array($dataArr) && count($dataArr) > 0) { foreach ($dataArr as &$data) { + $package = $this->modules->packages->getPackageByClass(str_replace('_', '\\', $data['package_class'])); + + if ($package) { + $data['package_class'] = $package['display_name']; + } + $data['package_row_ids'] = count($data['package_row_ids']); $data['name'] = '' . $data['name'] . ''; } @@ -70,8 +82,8 @@ function ($dataArr) { package : $this->tags, postUrl : 'system/tags/view', postUrlParams : null, - columnsForTable : ['name', 'package_name', 'swatch', 'package_row_ids'], - columnsForFilter : ['name', 'package_name', 'swatch'], + columnsForTable : ['name', 'package_class', 'swatch', 'package_row_ids'], + columnsForFilter : ['name', 'package_class', 'swatch'], controlActions : $controlActions, dtReplaceColumnsTitle : ['package_row_ids' => '# of times used'], dtReplaceColumns :$replaceColumns, diff --git a/apps/Core/Components/System/Users/Accounts/AccountsComponent.php b/apps/Core/Components/System/Users/Accounts/AccountsComponent.php index 94e5b4d83..4edc36a34 100644 --- a/apps/Core/Components/System/Users/Accounts/AccountsComponent.php +++ b/apps/Core/Components/System/Users/Accounts/AccountsComponent.php @@ -7,6 +7,7 @@ use Apps\Core\Packages\Crms\Customers\Customers; use Apps\Core\Packages\Hrms\Employees\Employees; use System\Base\BaseComponent; +use System\Base\Providers\BasepackagesServiceProvider\Packages\Users\Profiles; class AccountsComponent extends BaseComponent { @@ -30,7 +31,7 @@ public function viewAction() { if (isset($this->getData()['id'])) { if ($this->getData()['id'] != 0) { - $account = $this->accounts->generateViewData($this->getData()['id']); + $account = $this->accounts->generateViewData((int) $this->getData()['id']); if (!$account) { return $this->throwIdNotFound(); @@ -42,7 +43,7 @@ public function viewAction() if ($account) { $app = $this->apps->getAppInfo(); - $middlewares = $this->modules->middlewares->getMiddlewaresForAppType($app['app_type'],null); + $middlewares = $this->modules->middlewares->middlewares; $middlewareEnabledForApps = []; @@ -66,6 +67,7 @@ public function viewAction() if (count($middlewareEnabledForApps) > 0) { $this->view->aclMiddlewareEnabled = true; + foreach ($components as $key => $component) { if (!in_array($component['id'], $middlewareEnabledForApps)) { unset($components[$key]); @@ -83,9 +85,9 @@ public function viewAction() $this->view->roles = $this->accounts->packagesData->roles; - $this->view->countries = $this->basepackages->geoCountries->getAll()->geoCountries; + $this->view->countries = $this->basepackages->geoCountries->geoCountries; - $this->view->timezones = $this->basepackages->geoTimezones->getAll()->geoTimezones; + $this->view->timezones = $this->basepackages->geoTimezones->geoTimezones; } $this->addResponse( @@ -124,11 +126,11 @@ function ($dataArr) { $this->accounts, 'system/users/accounts/view', null, - ['profile_package_row_id', 'status', 'email', 'username', 'role_id', 'first_name', 'last_name', 'profile_package_name'], + ['profile_package_row_id', 'status', 'email', 'username', 'role_id', 'first_name', 'last_name', 'profile_package_class'], true, ['status', 'email', 'username', 'role_id', 'first_name', 'last_name'], $controlActions, - ['role_id' => 'role (ID)', 'profile_package_name' => 'Used By', 'profile_package_row_id' => 'link'], + ['role_id' => 'role (ID)', 'profile_package_class' => 'Used By', 'profile_package_row_id' => 'link'], $replaceColumns, 'email' ); @@ -153,6 +155,13 @@ protected function replaceColumns($dataArr) } else { $data['status'] = 'ENABLED'; } + + if (!isset($data['first_name'])) { + $data['first_name'] = '-'; + } + if (!isset($data['last_name'])) { + $data['last_name'] = '-'; + } } return $dataArr; @@ -174,20 +183,35 @@ protected function getProfilesData($data, $rowId = null) $profile = null; $componentRoute = null; - $profilePackage = $this->modules->packages->getPackageByName($data['profile_package_name']); + $profilePackage = $this->modules->packages->getPackageByClass(str_replace('_', '\\', $data['profile_package_class'])); - if ($data['profile_package_name'] === 'UsersProfiles') { + if ($data['profile_package_class'] === str_replace('\\', '_', Profiles::class)) { $profile = $this->basepackages->profiles->getById($data['profile_package_row_id']); } else if ($profilePackage) { - //Get profile information from packages class. + try { + $profilePackageClass = new $profilePackage['class']; + + $profile = $profilePackageClass->getById($data['profile_package_row_id']); + } catch (\throwable $e) { + //Do nothing. + } } + $profilePackageClassArr = explode('_', $data['profile_package_class']); + if ($profilePackage) { - if (is_string($profilePackage['settings'])) { - $profilePackage['settings'] = $this->helper->decode($profilePackage['settings'], true); - } - if (isset($profilePackage['settings']['componentRoute'])) { - $componentRoute = $profilePackage['settings']['componentRoute']; + if ($data['profile_package_class'] === str_replace('\\', '_', Profiles::class) || + strtolower($profilePackageClassArr[1]) === $this->apps->getAppInfo()['app_type'] + ) { + if (isset($profilePackage['settings']) && + is_string($profilePackage['settings']) + ) { + $profilePackage['settings'] = $this->helper->decode($profilePackage['settings'], true); + } + + if (isset($profilePackage['settings']['componentRoute'])) { + $componentRoute = $profilePackage['settings']['componentRoute']; + } } } @@ -200,7 +224,12 @@ protected function getProfilesData($data, $rowId = null) } } else { $data['profile_package_row_id'] = '-'; - $data['profile_package_name'] = '-'; + } + + if ($data['profile_package_class'] === str_replace('\\', '_', Profiles::class)) { + $data['profile_package_class'] = 'Profiles'; + } else { + $data['profile_package_class'] = $profilePackageClassArr[1] . $this->helper->last($profilePackageClassArr); } return $data; diff --git a/apps/Core/Components/System/Users/Profile/ProfileComponent.php b/apps/Core/Components/System/Users/Profile/ProfileComponent.php index ce96cf0e3..2bd171b8f 100644 --- a/apps/Core/Components/System/Users/Profile/ProfileComponent.php +++ b/apps/Core/Components/System/Users/Profile/ProfileComponent.php @@ -60,9 +60,9 @@ public function viewAction() $this->view->canUse2fa = $this->profiles->packagesData->canUse2fa; - $this->view->countries = $this->basepackages->geoCountries->getAll()->geoCountries; + $this->view->countries = $this->basepackages->geoCountries->geoCountries; - $this->view->timezones = $this->basepackages->geoTimezones->getAll()->geoTimezones; + $this->view->timezones = $this->basepackages->geoTimezones->geoTimezones; $apis = $this->api->getApiInfo(false, true); $passwordApis = []; @@ -74,6 +74,15 @@ public function viewAction() } } $this->view->passwordApis = msort($passwordApis, 'id'); + + $accountEnv = $this->basepackages->accounts->checkEnv($this->access->auth->account()['id'], false, false, true); + if ($accountEnv && isset($accountEnv['params'][$this->apps->getAppInfo()['id']])) { + $accountEnv = $accountEnv['params'][$this->apps->getAppInfo()['id']]; + } else { + $accountEnv = []; + } + + $this->view->accountEnv = $accountEnv; } else { return; } @@ -192,4 +201,16 @@ public function removeAccountAgentsAction() $this->basepackages->accounts->packagesData->responseCode ); } + + public function removeEnvRouteParamsAction() + { + $this->requestIsPost(); + + $this->basepackages->accounts->removeEnvRouteParams($this->postData()); + + $this->addResponse( + $this->basepackages->accounts->packagesData->responseMessage, + $this->basepackages->accounts->packagesData->responseCode + ); + } } \ No newline at end of file diff --git a/apps/Core/Components/System/Workers/Jobs/JobsComponent.php b/apps/Core/Components/System/Workers/Jobs/JobsComponent.php index e4e7b11a8..b10a9066c 100644 --- a/apps/Core/Components/System/Workers/Jobs/JobsComponent.php +++ b/apps/Core/Components/System/Workers/Jobs/JobsComponent.php @@ -14,6 +14,8 @@ class JobsComponent extends BaseComponent public function initialize() { $this->jobs = $this->basepackages->workers->jobs; + + $this->tasks = $this->basepackages->workers->tasks; } /** @@ -29,6 +31,12 @@ public function viewAction() return $this->throwIdNotFound(); } + $task = $this->tasks->getById((int) $job['task_id']); + + if ($task) { + $this->view->task = $task; + } + $this->view->job = $job; } @@ -64,11 +72,11 @@ function ($dataArr) { $this->jobs, 'system/workers/jobs/view', $conditions, - ['task_id', 'worker_id', 'run_on', 'status', 'execution_time'], + ['task_id', 'worker_id', 'run_on', 'status', 'total_execution_time', 'can_terminate'], true, - ['task_id', 'worker_id', 'run_on', 'status', 'execution_time'], + ['task_id', 'worker_id', 'run_on', 'status', 'total_execution_time', 'can_terminate'], $controlActions, - ['task_id'=>'task', 'worker_id'=>'worker'], + ['task_id' => 'task', 'worker_id' => 'worker', 'can_terminate' => 'terminate'], $replaceColumns, 'id', null, @@ -86,6 +94,7 @@ protected function replaceColumns($dataArr) $data = $this->formatTask($dataKey, $data); $data = $this->formatWorker($dataKey, $data); $data = $this->formatRunon($dataKey, $data); + $data = $this->formatTerminate($dataKey, $data); $data = $this->formatStatus($dataKey, $data); } @@ -105,7 +114,7 @@ protected function formatStatus($rowId, $data) } else if ($data['status'] == '4') { $data['status'] = 'Error!'; } else if ($data['status'] == '5') { - $data['status'] = 'Rescheduled!'; + $data['status'] = 'Rescheduled (No worker)'; } return $data; @@ -143,10 +152,49 @@ protected function formatRunon($rowId, $data) $data['run_on'] = $this->helper->decode($data['run_on']); } - if (is_array($data['run_on']) && isset($data['run_on'][0])) { - $data['run_on'] = $data['run_on'][0]; + if ($data['run_on'] && is_array($data['run_on'])) { + $data['run_on'] = $this->helper->last($data['run_on']); + } + + return $data; + } + + protected function formatTerminate($rowId, $data) + { + if ($data['can_terminate'] && $data['status'] == '2') { + $data['can_terminate'] = + ' + + '; + } else { + $data['can_terminate'] = '-'; } return $data; } + + public function terminateAction() + { + $this->requestIsPost(); + + $this->jobs->terminateJob($this->postData()); + + $this->addResponse( + $this->jobs->packagesData->responseMessage, + $this->jobs->packagesData->responseCode + ); + } + + public function getJobLogsAction() + { + $this->requestIsPost(); + + $this->jobs->getJobLogs($this->postData()); + + $this->addResponse( + $this->jobs->packagesData->responseMessage, + $this->jobs->packagesData->responseCode, + $this->jobs->packagesData->responseData ?? [], + ); + } } \ No newline at end of file diff --git a/apps/Core/Components/System/Workers/Tasks/TasksComponent.php b/apps/Core/Components/System/Workers/Tasks/TasksComponent.php index 5453412b4..d21b24306 100644 --- a/apps/Core/Components/System/Workers/Tasks/TasksComponent.php +++ b/apps/Core/Components/System/Workers/Tasks/TasksComponent.php @@ -29,6 +29,8 @@ public function viewAction() { $this->schedules = $this->basepackages->workers->schedules->schedules; + $this->view->jobLogsModes = $this->tasks->getJobLogsModes(); + if (isset($this->getData()['id'])) { $calls = []; @@ -52,14 +54,14 @@ public function viewAction() $this->tasks->setFFRelations(true); - // $calls = $this->tasks->getAllCalls(); - $this->view->calls = $calls; $this->view->schedules = $this->schedules; + $this->view->emailservices = $this->basepackages->emailservices->getAll()->emailServices; + if ($this->getData()['id'] != 0) { - $task = $this->tasks->getById($this->getData()['id']); + $task = $this->tasks->getById((int) $this->getData()['id']); if (!$task) { return $this->throwIdNotFound(); @@ -176,7 +178,7 @@ protected function formatSchedule($rowId, $data, $schedulesArr) protected function formatStatus($rowId, $data) { - if ($data['enabled'] == '0' && $data['status'] != '2') { + if ($data['enabled'] == '0' && $data['is_on_demand'] == '0') { $data['status'] = '-'; return $data; @@ -189,11 +191,11 @@ protected function formatStatus($rowId, $data) } else if ($data['status'] == '2') { $data['status'] = 'Running...'; } else if ($data['status'] == '3') { + $data['status'] = 'Success!'; + } else if ($data['status'] == '4') { $data['status'] = 'Error!'; - } - - if ($data['force_next_run'] == '1') { - return $data; + } else if ($data['status'] == '5') { + $data['status'] = 'Rescheduled (no workers)'; } return $data; diff --git a/apps/Core/Components/Viewssettings/ViewssettingsComponent.php b/apps/Core/Components/Viewssettings/ViewssettingsComponent.php index cf639040b..c212bc12b 100644 --- a/apps/Core/Components/Viewssettings/ViewssettingsComponent.php +++ b/apps/Core/Components/Viewssettings/ViewssettingsComponent.php @@ -20,6 +20,8 @@ public function initialize() public function viewAction() { if (isset($this->getData()['id'])) { + $this->useStorage('public'); + if ($this->getData()['id'] != 0) { $viewssettings = $this->modules->viewsSettings->getViewsSettingsById($this->getData()['id']); @@ -41,9 +43,14 @@ public function viewAction() if ($views) { foreach ($views as $viewKey => $view) { + if ($view['is_subview']) { + continue; + } + $apps[$value['id']]['views'][$view['id']]['id'] = $view['id']; $apps[$value['id']]['views'][$view['id']]['name'] = $view['name']; $apps[$value['id']]['views'][$view['id']]['display_name'] = $view['display_name']; + if (is_string($view['settings'])) { $view['settings'] = $this->helper->decode($view['settings'], true); } @@ -52,7 +59,6 @@ public function viewAction() is_array($view['settings']['branding']) ) { foreach ($view['settings']['branding'] as $brandKey => $brand) { - if (is_array($brand) && !isset($brand['brand'])) { // we unset it as branding is not correct. unset($view['settings']['branding'][$brandKey]); @@ -68,6 +74,7 @@ public function viewAction() } } } + $apps[$value['id']]['views'][$view['id']]['settings'] = $view['settings']; } } @@ -112,8 +119,25 @@ public function viewAction() $views = [$apps[$viewssettings['app_id']]['views'][$viewssettings['view_id']]]; } + $activeViewLayout = 'default'; + + if (isset($viewssettings['settings']['layouts']) && + is_array($viewssettings['settings']['layouts']) + ) { + foreach ($viewssettings['settings']['layouts'] as $layout) { + if (isset($layout['active']) && $layout['active'] == 'true') { + $activeViewLayout = $layout['view']; + + break; + } + } + } else { + $viewssettings['settings']['layouts'] = []; + } + $this->view->views = $views; $this->view->viewssettings = $viewssettings; + $this->view->activeViewLayout = $activeViewLayout; } else { $this->view->viewssettings = []; } diff --git a/apps/Core/Install/type.json b/apps/Core/Install/type.json index 1e2eb3d7a..873659409 100644 --- a/apps/Core/Install/type.json +++ b/apps/Core/Install/type.json @@ -1,6 +1,5 @@ { "app_type" : "core", - "dashboards" : true, "name" : "Core", "description" : "Core apps type for core modules.", "version" : "0.0.0", diff --git a/apps/Core/Middlewares/Acl/Acl.php b/apps/Core/Middlewares/Acl/Acl.php index f7a1f60cb..6962e12ec 100644 --- a/apps/Core/Middlewares/Acl/Acl.php +++ b/apps/Core/Middlewares/Acl/Acl.php @@ -25,8 +25,6 @@ class Acl extends BaseMiddleware protected $accountPermissions; - protected $rolePermissions; - protected $found = false; protected $isApi = false; @@ -41,7 +39,7 @@ public function process($data) } $this->actions = - ['view', 'add', 'update', 'remove', 'msview', 'msupdate']; + ['view', 'add', 'update', 'remove', 'msview', 'msupdate', 'activitylogs']; $rolesArr = $this->basepackages->roles->getAll()->roles; $roles = []; @@ -152,14 +150,15 @@ public function process($data) ); if (is_string($this->role['permissions'])) { - $this->rolePermissions = $this->helper->decode($this->role['permissions'], true); - } else { - $this->rolePermissions = $this->role['permissions']; + $this->role['permissions'] = $this->helper->decode($this->role['permissions'], true); } - foreach ($this->rolePermissions as $appKey => $app) { + + foreach ($this->role['permissions'] as $appKey => $app) { foreach ($app as $componentKey => $permission) { if ($this->app['id'] == $appKey) { - if ($this->components[$componentKey]['route'] === $this->controllerRoute) { + if (isset($this->components[$componentKey]) && + $this->components[$componentKey]['route'] === $this->controllerRoute + ) { if (($this->isApi && $this->helper->has($this->components[$componentKey]['api_acls'], $this->action)) || (!$this->isApi && $this->helper->has($this->components[$componentKey]['acls'], $this->action)) ) { diff --git a/apps/Core/Middlewares/Auth/Auth.php b/apps/Core/Middlewares/Auth/Auth.php index c598305e1..23c8904f0 100644 --- a/apps/Core/Middlewares/Auth/Auth.php +++ b/apps/Core/Middlewares/Auth/Auth.php @@ -18,7 +18,11 @@ public function process($data) try { $this->access->auth->setUserFromSession(); } catch (\Exception $e) { - $this->access->auth->logout(); + $this->access->auth->logout(true); + + $this->session->set('redirectUrl', $this->request->getUri()); + + return $this->response->redirect($data['appRoute'] . '/auth'); } } @@ -27,7 +31,11 @@ public function process($data) try { $this->access->auth->setUserFromRecaller(); } catch (\Exception $e) { - $this->access->auth->logout(); + $this->access->auth->logout(true); + + $this->session->set('redirectUrl', $this->request->getUri()); + + return $this->response->redirect($data['appRoute'] . '/auth'); } } diff --git a/apps/Core/Packages/Adminltetags/Tags/Activitylogs.php b/apps/Core/Packages/Adminltetags/Tags/Activitylogs.php index 82fbcd5f4..f86537d5c 100644 --- a/apps/Core/Packages/Adminltetags/Tags/Activitylogs.php +++ b/apps/Core/Packages/Adminltetags/Tags/Activitylogs.php @@ -25,10 +25,16 @@ public function getContent(array $params) protected function generateContent() { - if (!isset($this->params['activityLogs'])) { + if (!isset($this->params['activityLogs']['data'])) { throw new \Exception('Error: activityLogs (array) missing'); } + if (count($this->params['activityLogs']['data']) === 0) { + $this->content .= 'No activity logs available for this ID.'; + + return true; + } + if (isset($this->params['activityLogs']['paginationCounters'])) { if ($this->params['activityLogs']['paginationCounters']['first'] === $this->params['activityLogs']['paginationCounters']['current']) { $start = 1; @@ -46,12 +52,8 @@ protected function generateContent() } $this->content .= - '
-
- Showing ' . $start . ' to ' . $to . ' out of ' . $this->params['activityLogs']['paginationCounters']['filtered_items'] . ' -
-
'; - + '
+
' . $leftDisabled = ''; $rightDisabled = ''; @@ -59,17 +61,17 @@ protected function generateContent() $this->params['activityLogs']['paginationCounters']['current'] === 1 && $this->params['activityLogs']['paginationCounters']['last'] === 1 ) { - $leftDisabled = 'disabled'; - $rightDisabled = 'disabled'; + $leftDisabled = 'disabled text-muted'; + $rightDisabled = 'disabled text-muted'; } else if ($this->params['activityLogs']['paginationCounters']['first'] === 1 && $this->params['activityLogs']['paginationCounters']['current'] === 1 && $this->params['activityLogs']['paginationCounters']['last'] > 1 ) { - $leftDisabled = 'disabled'; + $leftDisabled = 'disabled text-muted'; $rightDisabled = ''; } else if ($this->params['activityLogs']['paginationCounters']['current'] === $this->params['activityLogs']['paginationCounters']['last']) { $leftDisabled = ''; - $rightDisabled = 'disabled'; + $rightDisabled = 'disabled text-muted'; } $this->content .= @@ -80,7 +82,10 @@ protected function generateContent()
  • - '; + + + Showing ' . $start . ' to ' . $to . ' out of ' . $this->params['activityLogs']['paginationCounters']['filtered_items'] . ' + '; $this->content .= '
    @@ -88,19 +93,19 @@ protected function generateContent() } $this->content .= - '
    + '
    '; - foreach ($this->params['activityLogs'] as $logsKey => $logs) { + foreach ($this->params['activityLogs']['data'] as $logsKey => $logs) { if ($logsKey === 'paginationCounters') { continue; } - if ($logs['activity_type'] === '1') { + if ($logs['activity_type'] == '1') { $icon = 'plus'; $bg = 'primary'; - } else if ($logs['activity_type'] === '2') { + } else if ($logs['activity_type'] == '2') { $icon = 'edit'; $bg = 'warning'; } @@ -108,7 +113,11 @@ protected function generateContent() if (isset($logs['account_id']) && $logs['account_id'] == 0) { $title = ' ' . $logs['account_full_name'] . ' '; } else { - $title = ' ' . $logs['account_full_name'] . ' (' . $logs['account_email'] . ') '; + if ($logs['account_portrait'] !== '') { + $title = $logs['account_portrait'] . '' . $logs['account_full_name'] . ' (' . $logs['account_email'] . ') '; + } else { + $title = ' ' . $logs['account_full_name'] . ' (' . $logs['account_email'] . ') '; + } } $logContent = '
    '; @@ -116,19 +125,19 @@ protected function generateContent() foreach ($logs['log'] as $logKey => $log) { if (!in_array($logKey, $this->params['disableKeys'])) { if (array_key_exists($logKey, $this->params['replaceValues'])) { - $log = $this->params['replaceValues'][$logKey][$log]; + $log = $this->params['replaceValues'][$logKey]; } if (array_key_exists($logKey, $this->params['replaceKeys'])) { $logKey = $this->params['replaceKeys'][$logKey]; } - $logKey = str_replace('_', ' ', $logKey); - - if (is_array($log)) { - $log = $this->helper->encode($log); + if (in_array($logKey, $this->params['isJson'])) { + if (is_array($log)) { + $log = $this->helper->encode($log); + } - if ($log === '[]') { - $log = ''; + if ($log === '[]' || $log === '{}') { + continue; } $jsonLog = $log; @@ -157,8 +166,10 @@ protected function generateContent() '; } + $logTitle = str_replace('_', ' ', $logKey); + $logContent .= - '
    ' . $logKey . '
    + '
    ' . $logTitle . '
    : ' . $log . '
    '; } } @@ -167,19 +178,18 @@ protected function generateContent() $this->content .= '
    - +
    - ' . $logs['created_at'] .' -
    ' . $title . '
    + ' . $logs['created_at'] .' +
    ' . $title . '
    ' . $logContent . '
    -
    '; } $this->content .= '
    - +
    @@ -196,11 +206,16 @@ protected function generateContent() $(".activity-logs-previous, .activity-logs-next").click(function(e) { e.preventDefault(); - var url = "' . $this->links->url('crypto/trades/getActivityLogs') . '"; + $("#baz-content").empty(); + $("#loader").attr("hidden", false); + + var url = "' . $this->links->url($this->params['activityLogs']['postLink']) . '"; var postData = { }; postData[$("#security-token").attr("name")] = $("#security-token").val(); - postData["id"] = $("#' . $this->params['componentId'] . '-main-id").val(); + postData["id"] = ' . $this->params['activityLogs']['id'] . '; + postData["packageClass"] = "' . $this->params['activityLogs']['packageClass'] . '"; + postData["postLink"] = "' . $this->params['activityLogs']['postLink'] . '"; if ($(this).is(".activity-logs-previous")) { postData["page"] = paginationCounters["previous"]; @@ -208,13 +223,9 @@ protected function generateContent() postData["page"] = paginationCounters["next"]; } - $.post(url, postData, function(response) { - if (response.responseCode == 0) { - if (response.responseData) { - $("#activity-logs").empty().html(response.responseData.logs); - } - } - }, "json"); + $("#baz-content").load(url, postData, function() { + $("#loader").attr("hidden", true); + }); }); '; } diff --git a/apps/Core/Packages/Adminltetags/Tags/Addresses.php b/apps/Core/Packages/Adminltetags/Tags/Addresses.php index 97cbe8243..5108c4f46 100644 --- a/apps/Core/Packages/Adminltetags/Tags/Addresses.php +++ b/apps/Core/Packages/Adminltetags/Tags/Addresses.php @@ -30,8 +30,6 @@ protected function generateContent() return; } - $this->addressesParams['addressTypes'] = $this->basepackages->addressbook->getAddressesTypes(); - try { $address = 'Apps\\Core\\Packages\\Adminltetags\\Tags\\Addresses\\' . ucfirst($this->params['addressFieldType']); diff --git a/apps/Core/Packages/Adminltetags/Tags/Addresses/Multiple.php b/apps/Core/Packages/Adminltetags/Tags/Addresses/Multiple.php index b2793c717..276a284b8 100644 --- a/apps/Core/Packages/Adminltetags/Tags/Addresses/Multiple.php +++ b/apps/Core/Packages/Adminltetags/Tags/Addresses/Multiple.php @@ -42,6 +42,8 @@ public function __construct($view, $tag, $links, $escaper, $params, $addressesPa $this->compSecId = $this->params['componentId'] . '-' . $this->params['sectionId']; + $this->buildSingleAddressData(); + $this->buildMultipleAddressesLayout(); } @@ -50,38 +52,122 @@ public function getContent() return $this->content; } + protected function buildSingleAddressData() + { + $this->addressesParams['searchType'] = + isset($this->params['searchType']) ? + $this->params['searchType'] : + 'city'; + + $fieldsArr = ['addressReference','attentionTo','streetAddress','streetAddress2','streetAddress3','streetAddress4','cityId','cityName','postCodeId','postCode','stateId','stateName','countryId','countryName']; + foreach ($fieldsArr as $field) { + $this->addressesParams[$field] = + isset($this->params[$field]) ? + $this->params[$field] : + ''; + } + + $this->addressesParams['attentionToFieldLabel'] = + isset($this->params['attentionToFieldLabel']) ? + $this->params['attentionToFieldLabel'] : + 'Attention To'; + + $this->addressesParams['streetAddressFieldLabel'] = + isset($this->params['streetAddressFieldLabel']) ? + $this->params['streetAddressFieldLabel'] : + 'Street Address'; + + $this->addressesParams['streetAddress2FieldLabel'] = + isset($this->params['streetAddress2FieldLabel']) ? + $this->params['streetAddress2FieldLabel'] : + 'Street Address 2'; + + $this->addressesParams['streetAddress3FieldLabel'] = + isset($this->params['streetAddress3FieldLabel']) ? + $this->params['streetAddress3FieldLabel'] : + 'Street Address 3'; + + $this->addressesParams['streetAddress4FieldLabel'] = + isset($this->params['streetAddress4FieldLabel']) ? + $this->params['streetAddress4FieldLabel'] : + 'Street Address 4'; + + $this->addressesParams['cityFieldLabel'] = + isset($this->params['cityFieldLabel']) ? + $this->params['cityFieldLabel'] : + 'City'; + + $this->addressesParams['postCodeFieldLabel'] = + isset($this->params['postCodeFieldLabel']) ? + $this->params['postCodeFieldLabel'] : + 'Post Code'; + + $this->addressesParams['stateFieldLabel'] = + isset($this->params['stateFieldLabel']) ? + $this->params['stateFieldLabel'] : + 'State'; + + $this->addressesParams['countryFieldLabel'] = + isset($this->params['countryFieldLabel']) ? + $this->params['countryFieldLabel'] : + 'Country'; + + $this->addressesParams['addressPostLink'] = + isset($this->params['addressPostLink']) ? + $this->params['addressPostLink'] : + ''; + + if ($this->addressesParams['addressPostLink'] !== '') { + if (!isset($this->params['addressPackageClass'])) { + throw new \Exception('addressPostLink requires addressPackageClass'); + } + if (!isset($this->params['addressPackageRowId'])) { + throw new \Exception('addressPostLink requires addressPackageRowId'); + } + + $this->addressesParams['addressPackageClass'] = $this->params['addressPackageClass']; + $this->addressesParams['addressPackageRowId'] = $this->params['addressPackageRowId']; + } else { + $this->addressesParams['addressPackageClass'] = ''; + $this->addressesParams['addressPackageRowId'] = ''; + } + + $this->addressesParams['addressSortable'] = + isset($this->params['addressSortable']) ? + $this->params['addressSortable'] : + true; + + $fieldsArr = null; + $field = null; + + $fieldsArr = ['includeAttentionTo','attentionToFieldHidden','includeStreet','streetAddressFieldHidden','streetAddress2FieldHidden','includeStreetExt','streetAddress3FieldHidden','streetAddress4FieldHidden','cityFieldHidden','postCodeFieldHidden','stateFieldHidden','countryFieldHidden','attentionToFieldDisabled','streetAddressFieldDisabled','streetAddress2FieldDisabled','streetAddress3FieldDisabled','streetAddress4FieldDisabled','cityFieldDisabled','postCodeFieldDisabled','stateFieldDisabled','countryFieldDisabled','attentionToFieldRequired','streetAddressFieldRequired','streetAddress2FieldRequired','streetAddress3FieldRequired','streetAddress4FieldRequired','cityFieldRequired','postCodeFieldRequired','stateFieldRequired','countryFieldRequired','addressReferenceFieldBazPostOnCreate','addressReferenceFieldBazPostOnUpdate','attentionToFieldBazPostOnCreate','attentionToFieldBazPostOnUpdate','streetAddressFieldBazPostOnCreate','streetAddressFieldBazPostOnUpdate','streetAddress2FieldBazPostOnCreate','streetAddress2FieldBazPostOnUpdate','streetAddress3FieldBazPostOnCreate','streetAddress3FieldBazPostOnUpdate','streetAddress4FieldBazPostOnCreate','streetAddress4FieldBazPostOnUpdate','cityFieldBazPostOnCreate','cityFieldBazPostOnUpdate','postCodeFieldBazPostOnCreate','postCodeFieldBazPostOnUpdate','stateFieldBazPostOnCreate','stateFieldBazPostOnUpdate','countryFieldBazPostOnCreate','countryFieldBazPostOnUpdate']; + + foreach ($fieldsArr as $field) { + $this->addressesParams[$field] = + isset($this->params[$field]) && + $this->params[$field] === true ? + true : + false; + } + } + protected function buildMultipleAddressesLayout() { + $this->addressesParams['multiple'] = true; + + $singleAddressArr = [ + 'component' => $this->params['component'], + 'componentName' => $this->params['componentName'], + 'componentId' => $this->params['componentId'], + 'sectionId' => $this->params['sectionId'], + 'addressFieldType' => 'single', + ]; + + $singleAddressArr = array_merge($singleAddressArr, $this->addressesParams); + $this->content .= '
    -
    -
    ' . - $this->adminLTETags->useTag('fields', - [ - 'component' => $this->params['component'], - 'componentName' => $this->params['componentName'], - 'componentId' => $this->params['componentId'], - 'sectionId' => $this->params['sectionId'], - 'fieldId' => 'address_types', - 'fieldLabel' => 'Address Types', - 'fieldType' => 'select2', - 'fieldHelp' => true, - 'fieldHelpTooltipContent' => 'Select Address Type', - 'fieldRequired' => true, - 'fieldBazScan' => true, - 'fieldBazJstreeSearch' => true, - 'fieldBazPostOnCreate' => false, - 'fieldBazPostOnUpdate' => false, - 'fieldDataSelect2Options' => $this->addressesParams['addressTypes'], - 'fieldDataSelect2OptionsKey' => 'id', - 'fieldDataSelect2OptionsValue' => 'name', - 'fieldDataSelect2OptionsArray' => true, - 'fieldDataSelect2OptionsSelected' => '' - ] - ) . ' -
    -
    ' . $this->adminLTETags->useTag('fields', @@ -152,49 +238,7 @@ protected function buildMultipleAddressesLayout()
    ' . - $this->adminLTETags->useTag('addresses', - [ - 'component' => $this->params['component'], - 'componentName' => $this->params['componentName'], - 'componentId' => $this->params['componentId'], - 'sectionId' => $this->params['sectionId'], - 'addressFieldType' => 'single', - 'includeStreet' => $this->params['includeStreet'], - 'includeAttentionTo' => $this->params['includeAttentionTo'], - 'searchType' => $this->params['searchType'], - 'attentionTo' => $this->params['attentionTo'], - 'attentionToFieldDisabled' => $this->params['attentionToFieldDisabled'], - 'attentionToFieldBazPostOnCreate' => $this->params['attentionToFieldBazPostOnCreate'], - 'attentionToFieldBazPostOnUpdate' => $this->params['attentionToFieldBazPostOnUpdate'], - 'streetAddress' => $this->params['streetAddress'], - 'streetAddressFieldDisabled' => $this->params['streetAddressFieldDisabled'], - 'streetAddressFieldBazPostOnCreate' => $this->params['streetAddressFieldBazPostOnCreate'], - 'streetAddressFieldBazPostOnUpdate' => $this->params['streetAddressFieldBazPostOnUpdate'], - 'streetAddress2' => $this->params['streetAddress2'], - 'streetAddress2FieldDisabled' => $this->params['streetAddress2FieldDisabled'], - 'streetAddress2FieldBazPostOnCreate' => $this->params['streetAddress2FieldBazPostOnCreate'], - 'streetAddress2FieldBazPostOnUpdate' => $this->params['streetAddress2FieldBazPostOnUpdate'], - 'cityId' => $this->params['cityId'], - 'cityName' => $this->params['cityName'], - 'cityFieldDisabled' => $this->params['cityFieldDisabled'], - 'cityFieldBazPostOnCreate' => $this->params['cityFieldBazPostOnCreate'], - 'cityFieldBazPostOnUpdate' => $this->params['cityFieldBazPostOnUpdate'], - 'postCode' => $this->params['postCode'], - 'postCodeFieldDisabled' => $this->params['postCodeFieldDisabled'], - 'postCodeFieldBazPostOnCreate' => $this->params['postCodeFieldBazPostOnCreate'], - 'postCodeFieldBazPostOnUpdate' => $this->params['postCodeFieldBazPostOnUpdate'], - 'stateId' => $this->params['stateId'], - 'stateName' => $this->params['stateName'], - 'stateFieldDisabled' => $this->params['stateFieldDisabled'], - 'stateFieldBazPostOnCreate' => $this->params['stateFieldBazPostOnCreate'], - 'stateFieldBazPostOnUpdate' => $this->params['stateFieldBazPostOnUpdate'], - 'countryId' => $this->params['countryId'], - 'countryName' => $this->params['countryName'], - 'countryFieldDisabled' => $this->params['countryFieldDisabled'], - 'countryFieldBazPostOnCreate' => $this->params['countryFieldBazPostOnCreate'], - 'countryFieldBazPostOnUpdate' => $this->params['countryFieldBazPostOnUpdate'] - ] - ) . + $this->adminLTETags->useTag('addresses', $singleAddressArr) . '
    @@ -210,7 +254,6 @@ protected function buildMultipleAddressesLayout() [ 'add-address' => [ 'title' => 'Add', - 'disabled' => true, 'size' => 'xs', 'type' => 'primary', 'icon' => 'plus', @@ -238,124 +281,129 @@ protected function buildMultipleAddressesLayout() '
    -
    '; - if (isset($this->addressesParams['addressTypes']) && count($this->addressesParams['addressTypes']) > 0) { - $addressTypesIds = []; - - foreach ($this->addressesParams['addressTypes'] as $type) { - $addressTypesIds[$this->compSecId . '-addresses-' . $type['id']] = $type['id']; - - $this->content .= - '
    -
    ' . - $this->adminLTETags->useTag('fields', - [ - 'component' => $this->params['component'], - 'componentName' => $this->params['componentName'], - 'componentId' => $this->params['componentId'], - 'sectionId' => $this->params['sectionId'], - 'fieldId' => 'addresses-' . $type['id'], - 'fieldLabel' => $type['name'], - 'fieldType' => 'html', - 'fieldHelp' => true, - 'fieldHelpTooltipContent' => $type['name'] . ' Note: First address is the list is primary address', - 'fieldAdditionalClass' => 'mb-0', - 'fieldRequired' => false, - 'fieldBazScan' => false, - 'fieldBazJstreeSearch' => true, - 'fieldBazPostOnCreate' => false, - 'fieldBazPostOnUpdate' => false - ] - ) . - '
      '; - - if (isset($this->params['address_ids']) && - count($this->params['address_ids']) > 0 && - isset($this->params['address_ids'][$type['id']]) && - count($this->params['address_ids'][$type['id']]) > 0 - ) { - $this->content .= - ''; - - foreach ($this->params['address_ids'][$type['id']] as $key => $address) { - if ($key === 0) { - $listType = 'success'; - } else { - $listType = 'secondary'; - } +
      +
      +
      ' . + $this->adminLTETags->useTag('fields', + [ + 'component' => $this->params['component'], + 'componentName' => $this->params['componentName'], + 'componentId' => $this->params['componentId'], + 'sectionId' => $this->params['sectionId'], + 'fieldId' => 'addresses', + 'fieldLabel' => 'Addresses', + 'fieldType' => 'html', + 'fieldHelp' => true, + 'fieldHelpTooltipContent' => 'List of addresses', + 'fieldAdditionalClass' => 'mb-0', + 'fieldRequired' => false, + 'fieldBazScan' => false, + 'fieldBazJstreeSearch' => true, + 'fieldBazPostOnCreate' => false, + 'fieldBazPostOnUpdate' => false + ] + ) . + '
        '; + if (isset($this->params['addresses']) && is_array($this->params['addresses']) && count($this->params['addresses']) > 0) { + $this->params['addresses'] = msort($this->params['addresses'], 'seq'); + + $this->content .= + ''; + + foreach ($this->params['addresses'] as $key => $address) { + $this->content .= + '
      • +
        '; + if ($this->addressesParams['addressSortable']) { $this->content .= - '
      • -
        -
        - -
        -
        - - - -
        -
        -
        -
        -
        -
        Attention To
        -
        ' . $address['attention_to'] . '
        -
        Street Address
        -
        ' . $address['street_address'] . '
        -
        Street Address 2
        -
        ' . $address['street_address_2'] . '
        -
        City
        -
        ' . $address['city_name'] . '
        -
        Post Code
        -
        ' . $address['post_code'] . '
        -
        State
        -
        ' . $address['state_name'] . '
        -
        Country
        -
        ' . $address['country_name'] . '
        -
        -
        -
        -
      • '; + '
        + +
        '; } - } else { + $this->content .= - '
        -
        -
        - Add ' . $type['name'] . ' -
        -
        -
        '; - } + '
        + + + +
        +
      +
      +
      +
      +
      Address Reference
      +
      ' . $address['address_reference'] . '
      '; + if (isset($address['attention_to']) && $address['attention_to'] !== '') { + $this->content .= + '
      Attention To
      +
      ' . $address['attention_to'] . '
      '; + } + $this->content .= + '
      Street Address
      +
      ' . $address['street_address'] . '
      '; + if (isset($address['street_address_2']) && $address['street_address_2'] !== '') { + $this->content .= + '
      Street Address 2
      +
      ' . $address['street_address_2'] . '
      '; + } + if (isset($address['street_address_3']) && $address['street_address_3'] !== '') { + $this->content .= + '
      Street Address 3
      +
      ' . $address['street_address_3'] . '
      '; + } + if (isset($address['street_address_4']) && $address['street_address_4'] !== '') { + $this->content .= + '
      Street Address 4
      +
      ' . $address['street_address_4'] . '
      '; + } + $this->content .= + '
      City
      +
      ' . $address['city_name'] . '
      +
      Post Code
      +
      ' . $address['post_code'] . '
      +
      State
      +
      ' . $address['state_name'] . '
      +
      Country
      +
      ' . $address['country_name'] . '
      +
      +
      +
      + '; + } + } else { + $this->content .= + '
      +
      +
      + Add New Address +
      +
      +
      '; + } - $this->content .= - '
    -
    -
    -
    '; - } - $addressTypesIds = $this->adminLTETags->helper->encode($addressTypesIds); - } - $this->content .= - '
    + $this->content .= + ' +
    +
    +
    ' . - $this->inclAddressesJs($addressTypesIds); + $this->inclAddressesJs(); } - protected function inclAddressesJs($addressTypesIds) + protected function inclAddressesJs() { $inclJs = ''; - - } else if ($this->params['searchType'] === 'state') { - + } else if ($this->addressesParams['searchType'] === 'state') { $this->content .= '
    ' . $this->inclState() . $this->inclCountry() . '
    '; @@ -337,9 +191,7 @@ protected function buildSingleAddressLayout() $this->content .= '});'; - - } else if ($this->params['searchType'] === 'country') { - + } else if ($this->addressesParams['searchType'] === 'country') { $this->content .= '
    ' . $this->inclCountry() . '
    '; @@ -348,7 +200,6 @@ protected function buildSingleAddressLayout() $this->content .= '});'; - } } else { $this->content .= @@ -387,12 +238,13 @@ protected function inclAttentionTo() 'fieldDisabled' => $this->addressesParams['attentionToFieldDisabled'], 'fieldRequired' => $this->addressesParams['attentionToFieldRequired'], 'fieldBazScan' => true, - 'fieldBazJstreeSearch' => true, + 'fieldBazJstreeSearch' => + (isset($this->params['multiple']) && $this->params['multiple'] === true) ? false : true, 'fieldBazPostOnCreate' => $this->addressesParams['attentionToFieldBazPostOnCreate'], 'fieldBazPostOnUpdate' => $this->addressesParams['attentionToFieldBazPostOnUpdate'], 'fieldDataInputMinLength' => 1, 'fieldDataInputMaxLength' => 100, - 'fieldValue' => $this->params['attentionTo'] + 'fieldValue' => $this->addressesParams['attentionTo'] ] ) . '
    @@ -419,12 +271,13 @@ protected function inclStreet() 'fieldDisabled' => $this->addressesParams['streetAddressFieldDisabled'], 'fieldRequired' => $this->addressesParams['streetAddressFieldRequired'], 'fieldBazScan' => true, - 'fieldBazJstreeSearch' => true, + 'fieldBazJstreeSearch' => + (isset($this->params['multiple']) && $this->params['multiple'] === true) ? false : true, 'fieldBazPostOnCreate' => $this->addressesParams['streetAddressFieldBazPostOnCreate'], 'fieldBazPostOnUpdate' => $this->addressesParams['streetAddressFieldBazPostOnUpdate'], 'fieldDataInputMinLength' => 1, 'fieldDataInputMaxLength' => 100, - 'fieldValue' => $this->params['streetAddress'] + 'fieldValue' => $this->addressesParams['streetAddress'] ] ) . '
    @@ -444,12 +297,72 @@ protected function inclStreet() 'fieldDisabled' => $this->addressesParams['streetAddress2FieldDisabled'], 'fieldRequired' => $this->addressesParams['streetAddress2FieldRequired'], 'fieldBazScan' => true, - 'fieldBazJstreeSearch' => true, + 'fieldBazJstreeSearch' => + (isset($this->params['multiple']) && $this->params['multiple'] === true) ? false : true, 'fieldBazPostOnCreate' => $this->addressesParams['streetAddress2FieldBazPostOnCreate'], 'fieldBazPostOnUpdate' => $this->addressesParams['streetAddress2FieldBazPostOnUpdate'], 'fieldDataInputMinLength' => 1, 'fieldDataInputMaxLength' => 100, - 'fieldValue' => $this->params['streetAddress2'] + 'fieldValue' => $this->addressesParams['streetAddress2'] + ] + ) . + ' + '; + } + + protected function inclStreetExt() + { + return + '
    +
    ' . + $this->adminLTETags->useTag('fields', + [ + 'component' => $this->params['component'], + 'componentName' => $this->params['componentName'], + 'componentId' => $this->params['componentId'], + 'sectionId' => $this->params['sectionId'], + 'fieldId' => 'street_address_3', + 'fieldLabel' => $this->addressesParams['streetAddress3FieldLabel'], + 'fieldType' => 'input', + 'fieldHelp' => true, + 'fieldHelpTooltipContent' => $this->addressesParams['streetAddress3FieldLabel'], + 'fieldHidden' => $this->addressesParams['streetAddress3FieldHidden'], + 'fieldDisabled' => $this->addressesParams['streetAddress3FieldDisabled'], + 'fieldRequired' => $this->addressesParams['streetAddress3FieldRequired'], + 'fieldBazScan' => true, + 'fieldBazJstreeSearch' => + (isset($this->params['multiple']) && $this->params['multiple'] === true) ? false : true, + 'fieldBazPostOnCreate' => $this->addressesParams['streetAddress3FieldBazPostOnCreate'], + 'fieldBazPostOnUpdate' => $this->addressesParams['streetAddress3FieldBazPostOnUpdate'], + 'fieldDataInputMinLength' => 1, + 'fieldDataInputMaxLength' => 100, + 'fieldValue' => $this->addressesParams['streetAddress3'] + ] + ) . + '
    +
    ' . + $this->adminLTETags->useTag('fields', + [ + 'component' => $this->params['component'], + 'componentName' => $this->params['componentName'], + 'componentId' => $this->params['componentId'], + 'sectionId' => $this->params['sectionId'], + 'fieldId' => 'street_address_4', + 'fieldLabel' => $this->addressesParams['streetAddress4FieldLabel'], + 'fieldType' => 'input', + 'fieldHelp' => true, + 'fieldHelpTooltipContent' => $this->addressesParams['streetAddress4FieldLabel'], + 'fieldHidden' => $this->addressesParams['streetAddress4FieldHidden'], + 'fieldDisabled' => $this->addressesParams['streetAddress4FieldDisabled'], + 'fieldRequired' => $this->addressesParams['streetAddress4FieldRequired'], + 'fieldBazScan' => true, + 'fieldBazJstreeSearch' => + (isset($this->params['multiple']) && $this->params['multiple'] === true) ? false : true, + 'fieldBazPostOnCreate' => $this->addressesParams['streetAddress4FieldBazPostOnCreate'], + 'fieldBazPostOnUpdate' => $this->addressesParams['streetAddress4FieldBazPostOnUpdate'], + 'fieldDataInputMinLength' => 1, + 'fieldDataInputMaxLength' => 100, + 'fieldValue' => $this->addressesParams['streetAddress4'] ] ) . '
    @@ -473,7 +386,7 @@ protected function inclCity() 'fieldBazScan' => true, 'fieldBazPostOnCreate' => $this->addressesParams['cityFieldBazPostOnCreate'], 'fieldBazPostOnUpdate' => $this->addressesParams['cityFieldBazPostOnUpdate'], - 'fieldValue' => $this->params['cityId'] + 'fieldValue' => $this->addressesParams['cityId'] ] ) . $this->adminLTETags->useTag('fields', @@ -489,7 +402,8 @@ protected function inclCity() 'fieldHelp' => true, 'fieldHelpTooltipContent' => 'Search ' . $this->addressesParams['cityFieldLabel'] . '. If there are no search results, try fixing the spelling or use full form for the name, ex=> use Saint instead of St.', 'fieldBazScan' => true, - 'fieldBazJstreeSearch' => true, + 'fieldBazJstreeSearch' => + (isset($this->params['multiple']) && $this->params['multiple'] === true) ? false : true, 'fieldBazPostOnCreate' => $this->addressesParams['cityFieldBazPostOnCreate'], 'fieldBazPostOnUpdate' => $this->addressesParams['cityFieldBazPostOnUpdate'], 'fieldHidden' => $this->addressesParams['cityFieldHidden'], @@ -497,7 +411,7 @@ protected function inclCity() 'fieldRequired' => $this->addressesParams['cityFieldRequired'], 'fieldDataInputMinLength' => 1, 'fieldDataInputMaxLength' => 100, - 'fieldValue' => $this->params['cityName'] + 'fieldValue' => $this->addressesParams['cityName'] ] ) . '
    '; @@ -507,6 +421,22 @@ protected function inclPostCode() { return '
    ' . + $this->adminLTETags->useTag('fields', + [ + 'component' => $this->params['component'], + 'componentName' => $this->params['componentName'], + 'componentId' => $this->params['componentId'], + 'sectionId' => $this->params['sectionId'], + 'fieldId' => 'post_code_id', + 'fieldLabel' => $this->addressesParams['postCodeFieldLabel'], + 'fieldHidden' => true, + 'fieldType' => 'input', + 'fieldBazScan' => true, + 'fieldBazPostOnCreate' => $this->addressesParams['postCodeFieldBazPostOnCreate'], + 'fieldBazPostOnUpdate' => $this->addressesParams['postCodeFieldBazPostOnUpdate'], + 'fieldValue' => $this->addressesParams['postCodeId'] + ] + ) . $this->adminLTETags->useTag('fields', [ 'component' => $this->params['component'], @@ -522,12 +452,13 @@ protected function inclPostCode() 'fieldDisabled' => $this->addressesParams['postCodeFieldDisabled'], 'fieldRequired' => $this->addressesParams['postCodeFieldRequired'], 'fieldBazScan' => true, - 'fieldBazJstreeSearch' => true, + 'fieldBazJstreeSearch' => + (isset($this->params['multiple']) && $this->params['multiple'] === true) ? false : true, 'fieldBazPostOnCreate' => $this->addressesParams['postCodeFieldBazPostOnCreate'], 'fieldBazPostOnUpdate' => $this->addressesParams['postCodeFieldBazPostOnUpdate'], 'fieldDataInputMinLength' => 1, 'fieldDataInputMaxLength' => 50, - 'fieldValue' => $this->params['postCode'] + 'fieldValue' => $this->addressesParams['postCode'] ] ) . '
    '; @@ -550,7 +481,7 @@ protected function inclState() 'fieldBazScan' => true, 'fieldBazPostOnCreate' => $this->addressesParams['stateFieldBazPostOnCreate'], 'fieldBazPostOnUpdate' => $this->addressesParams['stateFieldBazPostOnUpdate'], - 'fieldValue' => $this->params['stateId'] + 'fieldValue' => $this->addressesParams['stateId'] ] ) . $this->adminLTETags->useTag('fields', @@ -566,7 +497,8 @@ protected function inclState() 'fieldHelp' => true, 'fieldHelpTooltipContent' => 'Enter ' . $this->addressesParams['stateFieldLabel'], 'fieldBazScan' => true, - 'fieldBazJstreeSearch' => true, + 'fieldBazJstreeSearch' => + (isset($this->params['multiple']) && $this->params['multiple'] === true) ? false : true, 'fieldBazPostOnCreate' => $this->addressesParams['stateFieldBazPostOnCreate'], 'fieldBazPostOnUpdate' => $this->addressesParams['stateFieldBazPostOnUpdate'], 'fieldHidden' => $this->addressesParams['stateFieldHidden'], @@ -574,7 +506,7 @@ protected function inclState() 'fieldRequired' => $this->addressesParams['stateFieldRequired'], 'fieldDataInputMinLength' => 1, 'fieldDataInputMaxLength' => 100, - 'fieldValue' => $this->params['stateName'] + 'fieldValue' => $this->addressesParams['stateName'] ] ) . ''; @@ -597,7 +529,7 @@ protected function inclCountry() 'fieldBazScan' => true, 'fieldBazPostOnCreate' => $this->addressesParams['countryFieldBazPostOnCreate'], 'fieldBazPostOnUpdate' => $this->addressesParams['countryFieldBazPostOnUpdate'], - 'fieldValue' => $this->params['countryId'] + 'fieldValue' => $this->addressesParams['countryId'] ] ) . $this->adminLTETags->useTag('fields', @@ -613,7 +545,8 @@ protected function inclCountry() 'fieldHelp' => true, 'fieldHelpTooltipContent' => 'Enter ' . $this->addressesParams['countryFieldLabel'], 'fieldBazScan' => true, - 'fieldBazJstreeSearch' => true, + 'fieldBazJstreeSearch' => + (isset($this->params['multiple']) && $this->params['multiple'] === true) ? false : true, 'fieldBazPostOnCreate' => $this->addressesParams['countryFieldBazPostOnCreate'], 'fieldBazPostOnUpdate' => $this->addressesParams['countryFieldBazPostOnUpdate'], 'fieldHidden' => $this->addressesParams['countryFieldHidden'], @@ -621,7 +554,7 @@ protected function inclCountry() 'fieldRequired' => $this->addressesParams['countryFieldRequired'], 'fieldDataInputMinLength' => 1, 'fieldDataInputMaxLength' => 100, - 'fieldValue' => $this->params['countryName'] + 'fieldValue' => $this->addressesParams['countryName'] ] ) . ''; @@ -660,11 +593,18 @@ protected function inclBaseJs() if (isset($this->params['includeStreet']) && $this->params['includeStreet'] === true) { $baseJs .= - '"' . $this->compSecId . '-attention_to" : { }, + '"' . $this->compSecId . '-address_reference" : { }, + "' . $this->compSecId . '-attention_to" : { }, "' . $this->compSecId . '-street_address" : { }, "' . $this->compSecId . '-street_address_2" : { },'; } + if (isset($this->params['includeStreetExt']) && $this->params['includeStreetExt'] === true) { + $baseJs .= + '"' . $this->compSecId . '-street_address_3" : { }, + "' . $this->compSecId . '-street_address_4" : { },'; + } + return $baseJs; } @@ -730,13 +670,7 @@ className: "autoComplete_results" highlight: true, resultItem: { content: (data, source) => { - var postCode = "0"; - - if (data.value.postcode) { - postCode = data.value.postcode; - } - - source.innerHTML = data.match + " (Post Code: " + postCode + ", State: " + data.value.state_name + ", Country: " + data.value.country_name + ")"; + source.innerHTML = data.match + " (State: " + data.value.state_name + ", Country: " + data.value.country_name + ")"; }, element: "div" }, @@ -760,8 +694,6 @@ className: "autoComplete_results" $("#' . $this->compSecId . '-city_id").attr("value", feedback.selection.value.id); $("#' . $this->compSecId . '-city_name").blur(); $("#' . $this->compSecId . '-city_name").val(feedback.selection.value.name); - $("#' . $this->compSecId . '-post_code").val(feedback.selection.value.postcode); - $("#' . $this->compSecId . '-post_code").attr("value", feedback.selection.value.postcode); $("#' . $this->compSecId . '-state_id").val(feedback.selection.value.state_id); $("#' . $this->compSecId . '-state_id").attr("value", feedback.selection.value.state_id); $("#' . $this->compSecId . '-state_name").val(feedback.selection.value.state_name); @@ -799,13 +731,14 @@ className: "autoComplete_results" protected function inclPostCodeJs() { return - '"' . $this->compSecId . '-post_code" : { + '"' . $this->compSecId . '-post_code_id" : { }, + "' . $this->compSecId . '-post_code" : { afterInit : function() { dataCollectionSection["' . $this->compSecId . '-form"]["autoCompleteCities"] = new autoComplete({ data: { src: async() => { - const url = "' . $this->links->url("system/geo/cities/searchPostCode") . '"; + const url = "' . $this->links->url("system/geo/postcodes/searchPostCode") . '"; var myHeaders = new Headers(); myHeaders.append("accept", "application/json"); @@ -825,7 +758,7 @@ protected function inclPostCodeJs() const response = await responseData.json(); if (response.tokenKey && response.token) { - $("#security-token").attr("postcode", response.tokenKey); + $("#security-token").attr("name", response.tokenKey); $("#security-token").val(response.token); } @@ -835,7 +768,7 @@ protected function inclPostCodeJs() return []; } }, - key: ["postcode"], + key: ["code"], cache: false }, selector: "#' . $this->compSecId . '-post_code", @@ -857,13 +790,7 @@ className: "autoComplete_results" highlight: true, resultItem: { content: (data, source) => { - var cityName = ""; - - if (data.value.name) { - cityName = data.value.name; - } - - source.innerHTML = data.match + " (City: " + cityName + ", State: " + data.value.state_name + ", Country: " + data.value.country_name + ")"; + source.innerHTML = data.match + " (Locality: " + data.value.name + ", State: " + data.value.state_name + ", Country: " + data.value.country_name + ")"; }, element: "div" }, @@ -883,12 +810,10 @@ className: "autoComplete_results" } }, onSelection: feedback => { - $("#' . $this->compSecId . '-city_id").val(feedback.selection.value.id); - $("#' . $this->compSecId . '-city_id").attr("value", feedback.selection.value.id); - $("#' . $this->compSecId . '-city_name").blur(); - $("#' . $this->compSecId . '-city_name").val(feedback.selection.value.name); - $("#' . $this->compSecId . '-post_code").val(feedback.selection.value.postcode); - $("#' . $this->compSecId . '-post_code").attr("value", feedback.selection.value.postcode); + $("#' . $this->compSecId . '-post_code_id").val(feedback.selection.value.id); + $("#' . $this->compSecId . '-post_code_id").attr("value", feedback.selection.value.id); + $("#' . $this->compSecId . '-post_code").val(feedback.selection.value.code); + $("#' . $this->compSecId . '-post_code").attr("value", feedback.selection.value.code); $("#' . $this->compSecId . '-state_id").val(feedback.selection.value.state_id); $("#' . $this->compSecId . '-state_id").attr("value", feedback.selection.value.state_id); $("#' . $this->compSecId . '-state_name").val(feedback.selection.value.state_name); @@ -901,8 +826,6 @@ className: "autoComplete_results" }); // On delete $("#' . $this->compSecId . '-post_code").on("input propertychange", function() { - $("#' . $this->compSecId . '-city_id").val(0); - $("#' . $this->compSecId . '-city_id").attr("value", 0); $("#' . $this->compSecId . '-state_id").val(0); $("#' . $this->compSecId . '-state_id").attr("value", 0); $("#' . $this->compSecId . '-state_name").val(""); @@ -1126,4 +1049,4 @@ className: "autoComplete_results" return $countryJs; } -} +} \ No newline at end of file diff --git a/apps/Core/Packages/Adminltetags/Tags/Buttons/Button.php b/apps/Core/Packages/Adminltetags/Tags/Buttons/Button.php index d11fbdc08..44e566031 100644 --- a/apps/Core/Packages/Adminltetags/Tags/Buttons/Button.php +++ b/apps/Core/Packages/Adminltetags/Tags/Buttons/Button.php @@ -249,6 +249,15 @@ protected function buildButtonParamsArr() $button['tooltipTitle'] : ''; + if (isset($button['data'])) { + $this->buttonParams['dataAttr'] = ''; + foreach ($button['data'] as $dataKey => $dataValue) { + $this->buttonParams['dataAttr'] .= 'data-' . $dataKey . '="' . $dataValue . '" '; + } + } else { + $this->buttonParams['dataAttr'] = ''; + } + $this->buildButton(); } } @@ -257,7 +266,7 @@ protected function buildButton() { if ($this->buttonParams['url'] !== '') { $this->content .= - 'content .= ''; } } -} \ No newline at end of file +} diff --git a/apps/Core/Packages/Adminltetags/Tags/Buttons/Dropdown.php b/apps/Core/Packages/Adminltetags/Tags/Buttons/Dropdown.php index 062b22638..d9daece75 100644 --- a/apps/Core/Packages/Adminltetags/Tags/Buttons/Dropdown.php +++ b/apps/Core/Packages/Adminltetags/Tags/Buttons/Dropdown.php @@ -67,7 +67,7 @@ protected function buildDropdown() $this->content .= ' '; - //Check if employees package exists we show employees. We can extract the Account Ids from them. - // $employeesPackage = $this->init()->checkPackage('Apps\Core\Packages\Hrms\Employees\Employees'); - - // if ($employeesPackage) { - // $modalContent .= '
    - //
    ' . - // $this->useTag('fields', - // [ - // 'componentId' => $this->params['componentId'], - // 'sectionId' => $this->params['sectionId'] . '-filter-sharing', - // 'fieldId' => 'eids', - // 'fieldLabel' => 'Employee(s)', - // 'fieldType' => 'select2', - // 'fieldHelp' => true, - // 'fieldHelpTooltipContent' => 'Select Employees to share filter with', - // 'fieldBazScan' => true, - // 'fieldRequired' => false, - // 'fieldDataSelect2Options' => [], - // 'fieldDataSelect2Multiple' => true, - // 'fieldDataSelect2OptionsKey' => 'id', - // 'fieldDataSelect2OptionsValue' => 'name', - // 'fieldDataSelect2OptionsArray' => true - // ] - // ) . - // '
    - //
    '; - // } else { - $modalContent .= '
    -
    ' . - $this->useTag('fields', - [ - 'componentId' => $this->params['componentId'], - 'sectionId' => $this->params['sectionId'] . '-filter-sharing', - 'fieldId' => 'aids', - 'fieldLabel' => 'Account(s)', - 'fieldType' => 'select2', - 'fieldHelp' => true, - 'fieldHelpTooltipContent' => 'Select Accounts to share filter with', - 'fieldBazScan' => true, - 'fieldRequired' => false, - 'fieldDataSelect2Options' => [], - 'fieldDataSelect2Multiple' => true, - 'fieldDataSelect2OptionsKey' => 'id', - 'fieldDataSelect2OptionsValue' => 'name', - 'fieldDataSelect2OptionsArray' => true - ] - ) . - '
    -
    '; - // } + + $modalContent .= '
    +
    ' . + $this->useTag('fields', + [ + 'componentId' => $this->params['componentId'], + 'sectionId' => $this->params['sectionId'] . '-filter-sharing', + 'fieldId' => 'aids', + 'fieldLabel' => 'Account(s)', + 'fieldType' => 'select2', + 'fieldHelp' => true, + 'fieldHelpTooltipContent' => 'Select Accounts to share filter with', + 'fieldBazScan' => true, + 'fieldRequired' => false, + 'fieldDataSelect2Options' => [], + 'fieldDataSelect2Multiple' => true, + 'fieldDataSelect2OptionsKey' => 'id', + 'fieldDataSelect2OptionsValue' => 'name', + 'fieldDataSelect2OptionsArray' => true + ] + ) . + '
    +
    '; $modalContent .= ' @@ -772,23 +745,6 @@ protected function inclJs() $("#security-token").attr("name", response.tokenKey); $("#security-token").val(response.token); } - // if (response.employees) { - // var employeesData = []; - // for (var item of response.employees) { - // employeesData.push({ - // "id" : item["id"], - // "text" : item["full_name"] - // }); - // } - - // return { - // results: employeesData - // } - // } else { - return { - results : [] - } - // } }, cache: true }, @@ -899,33 +855,4 @@ protected function inclJs() ); '; } -} - //DropdownSplitButtons - Dropdown - // [ - // 'componentId' => $this->params['componentId'], - // 'sectionId' => $this->params['sectionId'], - // 'buttonType' => 'dropdownSplitButtons', - // 'buttonSize' => 'sm', - // 'dropdownButtonTitle' => 'Actions', - // 'dropdownSplitButtonsSplit' => true, - // 'dropdownButtonId' => 'modal-actions', - // 'dropdownDirection' => 'up', - // 'dropdownAlign' => 'right', - // 'buttons' => - // [ - // 'save' => [ - // 'title' => 'Save', - // 'disabled' => true, - // 'icon' => 'save' - // ], - // 'apply-new' => [ - // 'title' => 'Apply', - // 'disabled' => true, - // 'icon' => 'filter', - // ], - // 'saveapply' => [ - // 'title' => 'Save & Apply', - // 'disabled' => true, - // ] - // ] - // ] \ No newline at end of file +} \ No newline at end of file diff --git a/apps/Core/Packages/Adminltetags/Tags/Content/Listing/Table/DynamicTable.php b/apps/Core/Packages/Adminltetags/Tags/Content/Listing/Table/DynamicTable.php index e2fd3822b..0e9e0db54 100644 --- a/apps/Core/Packages/Adminltetags/Tags/Content/Listing/Table/DynamicTable.php +++ b/apps/Core/Packages/Adminltetags/Tags/Content/Listing/Table/DynamicTable.php @@ -90,6 +90,15 @@ protected function generateTableContent() $this->content .= ''; } + if (isset($this->params['dtAdditionalFields'])) { + $this->content .= + ''; + } + $this->content .= ''; } diff --git a/apps/Core/Packages/Adminltetags/Tags/Fields/Files/Croppie.php b/apps/Core/Packages/Adminltetags/Tags/Fields/Files/Croppie.php index f8edb40e5..3fdb577e5 100644 --- a/apps/Core/Packages/Adminltetags/Tags/Fields/Files/Croppie.php +++ b/apps/Core/Packages/Adminltetags/Tags/Fields/Files/Croppie.php @@ -52,6 +52,13 @@ public function getContent() protected function generateContent() { + if (!isset($this->params['filePackageClass'])) { + throw new \Exception('file package class information missing.'); + } + if (!isset($this->params['filePackageRowId'])) { + throw new \Exception('file package row id information missing.'); + } + $this->fieldParams['fieldCroppieLabel'] = isset($this->params['fieldCroppieLabel']) ? $this->params['fieldCroppieLabel'] : @@ -217,6 +224,16 @@ protected function generateContent() 'hidden' => true, 'size' => 'xs', 'buttonAdditionalClass' => 'mr-1 ml-1' + ], + $this->params['fieldId'] . '-croppie-cancel-2' => + [ + 'title' => false, + 'type' => 'secondary', + 'position' => 'left', + 'icon' => 'times', + 'hidden' => true, + 'size' => 'xs', + 'buttonAdditionalClass' => 'mr-1 ml-1' ] ] ); @@ -233,6 +250,7 @@ protected function generateContent() 'position' => 'left', 'icon' => 'history', 'hidden' => false, + 'type' => 'info', 'size' => 'xs', 'buttonAdditionalClass' => 'mr-1 ml-1' ] @@ -289,6 +307,7 @@ protected function generateContent() 'sectionId' => $this->params['sectionId'], 'fieldId' => $this->params['fieldId'], 'fieldLabel' => false, + 'fieldPlaceholder' => 'UUID', 'fieldType' => 'input', 'fieldHelp' => true, 'fieldHelpTooltipContent' => false, @@ -538,7 +557,6 @@ function initCroppie() { } $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-upload-image").change(function () { - $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-upload").attr("disabled", true); readFile(this); }); @@ -592,11 +610,10 @@ function initCroppie() { circle : ' . $this->fieldParams['fieldCroppieViewportCircle'] . ' }).then(function (croppedImage) { imageBlob = croppedImage; - $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie").attr("hidden", true); - $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-save").attr("hidden", true); - $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-cancel").attr("hidden", true); $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-image").attr("src", croppedImage); $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-image").attr("hidden", false); + $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie").attr("hidden", true); + croppieSaved(); }); //To Blob for upload @@ -613,7 +630,8 @@ function initCroppie() { }); }); - $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-cancel").click(function () { + $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-cancel, " + + "#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-cancel-2").click(function () { croppieReset(); }); @@ -623,6 +641,7 @@ function croppieReset() { $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-upload-image").attr("disabled", false); $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-save").attr("hidden", true); $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-cancel").attr("hidden", true); + $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-cancel-2").attr("hidden", true); $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-save-warning").attr("hidden", true); $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-image").attr("hidden", false); $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie").attr("hidden", true); @@ -656,6 +675,8 @@ function readFile(input) { var reader = new FileReader(); reader.onload = function (e) { + $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-upload").attr("disabled", true); + $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-upload").attr("hidden", true); $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-image").attr("hidden", true); $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie").attr("hidden", false); $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-save").attr("hidden", false); @@ -663,8 +684,9 @@ function readFile(input) { window["dataCollection"]["' . $this->params['componentId'] . '"]["' . $this->compSecId . '"]["' . $this->compSecId . '-' . $this->params['fieldId'] . '"].croppie("bind", { url: e.target.result }).then(function(){ - $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-female").attr("disabled", true); - $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-male").attr("disabled", true); + $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-female").attr("hidden", true); + $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-male").attr("hidden", true); + $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-recover").attr("hidden", true); }); } @@ -672,7 +694,7 @@ function readFile(input) { reader.readAsDataURL(input.files[0]); } else { - PNotify.error("Sorry - you\'re browser doesn\'t support the FileReader API"); + paginatedPNotify("error", {"title" :"Sorry - you\'re browser doesn\'t support the FileReader API"}); } } @@ -681,17 +703,21 @@ function readFile(input) { ) { $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-male").click(function() { $(this).attr("disabled", true); + $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-upload").attr("hidden", true); $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-upload").attr("disabled", true); $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-upload-image").attr("disabled", true); $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-female").attr("disabled", false); + $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-recover").attr("hidden", true); generateAvatar("M"); }); $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-female").click(function() { $(this).attr("disabled", true); + $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-upload").attr("hidden", true); $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-upload").attr("disabled", true); $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-upload-image").attr("disabled", true); $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-female").attr("disabled", true); $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-male").attr("disabled", false); + $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-recover").attr("hidden", true); generateAvatar("F"); }); } @@ -707,13 +733,13 @@ function generateAvatar(gender = "M", avatarFile = null) { $.post("' . $this->links->url("system/users/profile/generateavatar") . '", postData, function(response) { if (response.responseCode == 1) { - PNotify.error(response.responseMessage); + paginatedPNotify("error", {"title" :response.responseMessage}); return; } $(".' . $this->compSecId . '-' . $this->params['fieldId'] . '-image-content .image-text").html(response.avatarName); $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-image").attr("src", "data:image/png;base64," + response.avatar); - $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-remove").attr("hidden", false); + $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-cancel-2").attr("hidden", false); if (response.tokenKey && response.token) { $("#security-token").attr("name", response.tokenKey); @@ -728,6 +754,7 @@ function generateAvatar(gender = "M", avatarFile = null) { $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-save").attr("hidden", false); $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-save").off(); $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-save").click(function() { + $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-cancel-2").attr("hidden", true); $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-upload").attr("hidden", true); $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-male").attr("hidden", true); $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-female").attr("hidden", true); @@ -752,6 +779,8 @@ function uploadAvatar(avatarName) { formData.append("setOrphan", "' . $this->params['setOrphan'] . '"); formData.append("fileName", avatarName); formData.append("storagetype", "' . $this->params['storageType'] . '"); + formData.append("package_class", "' . $this->params['filePackageClass'] . '"); + formData.append("package_row_id", "' . $this->params['filePackageRowId'] . '"); formData.append($("#security-token").attr("name"), $("#security-token").val()); performUpload(formData); @@ -820,6 +849,8 @@ function uploadImage() { formData.append("setOrphan", "' . $this->params['setOrphan'] . '"); formData.append("fileName", imageName); formData.append("storagetype", "' . $this->params['storageType'] . '"); + formData.append("package_class", "' . $this->params['filePackageClass'] . '"); + formData.append("package_row_id", "' . $this->params['filePackageRowId'] . '"); formData.append($("#security-token").attr("name"), $("#security-token").val()); performUpload(formData); @@ -852,14 +883,9 @@ function performUpload(formData) { } else { $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '").val(response.responseData.uuid); } - $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-remove").attr("hidden", false); - $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-male").attr("hidden", true); - $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-female").attr("hidden", true); - $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-recover").attr("hidden", true); - $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-recover").attr("disabled", false); - $($("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-filename").parents(".form-group")[0]).addClass("d-none"); - $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-filename").attr("disabled", true); - $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-upload").attr("hidden", true); + + croppieSaved(); + $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '") .trigger( { @@ -868,15 +894,31 @@ function performUpload(formData) { } ); } else { - PNotify.error(response.responseMessage); + paginatedPNotify("error", {"title" :response.responseMessage}); croppieReset(); } } else { - PNotify.error("Image Upload Failed!"); + paginatedPNotify("error", {"title" :"Image Upload Failed!"}); } }); } + function croppieSaved() { + $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-remove").attr("hidden", false); + $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-male").attr("hidden", true); + $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-female").attr("hidden", true); + $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-refresh").attr("hidden", true); + $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-save").attr("hidden", true); + $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-save").attr("hidden", true); + $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-cancel").attr("hidden", true); + $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-cancel-2").attr("hidden", true); + $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-recover").attr("hidden", true); + $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-recover").attr("disabled", false); + $($("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-filename").parents(".form-group")[0]).addClass("d-none"); + $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-filename").attr("disabled", true); + $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-upload").attr("hidden", true); + } + function updateProfileThumbnail(remove = false) { $("body").off("sectionWithFormDataUpdated"); $("body").on("sectionWithFormDataUpdated", function() { @@ -893,7 +935,7 @@ function updateProfileThumbnail(remove = false) { } else { $("#profile-portrait").children("i").attr("hidden", true); $("#profile-portrait").children("img").attr("src", window.dataCollection.env.rootPath + window.dataCollection.env.appRoute + - "/system/storages/q/uuid/" + uploadUUIDs[uploadUUIDs.length - 1] + "/w/30"); + "/system/storages/q/uuid/" + uploadUUIDs[0] + "/w/30"); $("#profile-portrait").children("img").attr("hidden", false); window.dataCollection.env.profile.portrait = window.dataCollection.env.rootPath + window.dataCollection.env.appRoute + "/system/storages/q/uuid/" + uploadUUIDs[0] + "/w/80"; @@ -904,16 +946,18 @@ function updateProfileThumbnail(remove = false) { $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '").off(); $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '").on("croppieSaved", function(e) { - $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-refresh").attr("hidden", true); - $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-save").attr("hidden", true); - $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-female").attr("hidden", true); - $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-male").attr("hidden", true); - $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-upload").attr("hidden", true); - + croppieSaved(); }); } initCroppie(); + + $("#body").on("resetCroppie", function() { + croppieReset(); + }); + $("#body").on("saveCroppie", function() { + croppieSaved(); + }) } }, "' . $this->compSecId . '-' . $this->params['fieldId'] . '-croppie-avatar-filename" : { diff --git a/apps/Core/Packages/Adminltetags/Tags/Fields/Files/Dropzone.php b/apps/Core/Packages/Adminltetags/Tags/Fields/Files/Dropzone.php index 157a7dfb4..797f1d7b4 100644 --- a/apps/Core/Packages/Adminltetags/Tags/Fields/Files/Dropzone.php +++ b/apps/Core/Packages/Adminltetags/Tags/Fields/Files/Dropzone.php @@ -53,7 +53,13 @@ public function getContent() protected function generateContent() { if (!isset($this->params['storage'])) { - throw new \Exception('storage information missing for dropzone.'); + throw new \Exception('storage information missing.'); + } + if (!isset($this->params['filePackageClass'])) { + throw new \Exception('file package class information missing.'); + } + if (!isset($this->params['filePackageRowId'])) { + throw new \Exception('file package row id information missing.'); } $this->fieldParams['fieldDropzoneLabel'] = @@ -61,6 +67,16 @@ protected function generateContent() $this->params['fieldDropzoneLabel'] : false; + $this->fieldParams['fieldDropzonePreviewLabel'] = + isset($this->params['fieldDropzonePreviewLabel']) ? + $this->params['fieldDropzonePreviewLabel'] : + false; + + $this->fieldParams['fieldDropzonePreviewHelpTooltipContent'] = + isset($this->params['fieldDropzonePreviewHelpTooltipContent']) ? + $this->params['fieldDropzonePreviewHelpTooltipContent'] : + ''; + $this->fieldParams['fieldHelpTooltipContent'] = isset($this->params['fieldHelpTooltipContent']) ? $this->params['fieldHelpTooltipContent'] : @@ -86,6 +102,11 @@ protected function generateContent() true : false; + $this->fieldParams['arrange'] = + isset($this->params['arrange']) ? + $this->params['arrange'] : + 'horizontal';//Side by Side OR Vertical Uploader on top and preview on bottom + $this->fieldParams['sortable'] = isset($this->params['sortable']) ? $this->params['sortable'] : @@ -198,86 +219,98 @@ protected function generateContent() ); } - $this->content .= - '
    -
    -
    ' . - $this->adminLTETags->useTag('fields', - [ - 'component' => $this->params['component'], - 'componentName' => $this->params['componentName'], - 'componentId' => $this->params['componentId'], - 'sectionId' => $this->params['sectionId'], - 'fieldId' => $this->params['fieldId'], - 'fieldLabel' => $this->fieldParams['fieldDropzoneLabel'], - 'fieldType' => 'html', - 'fieldHelp' => true, - 'fieldHelpTooltipContent' => $this->fieldParams['fieldHelpTooltipContent'], - 'fieldAdditionalClass' => 'mb-0', - 'fieldRequired' => $this->fieldParams['fieldRequired'], - 'fieldBazScan' => true, - 'fieldBazJstreeSearch' => $this->fieldParams['fieldBazJstreeSearch'], - 'fieldBazPostOnCreate' => $this->fieldParams['fieldBazPostOnCreate'], - 'fieldBazPostOnUpdate' => $this->fieldParams['fieldBazPostOnUpdate'] - ] - ) . - $this->adminLTETags->useTag('buttons', - [ - 'componentId' => $this->params['componentId'], - 'sectionId' => $this->params['sectionId'], - 'buttonLabel' => false, - 'buttonType' => 'button', - 'buttons' => $dropzoneButtons - ] - ) . - ' -
    + $uploader = + '
    +
    ' . + $this->adminLTETags->useTag('fields', + [ + 'component' => $this->params['component'], + 'componentName' => $this->params['componentName'], + 'componentId' => $this->params['componentId'], + 'sectionId' => $this->params['sectionId'], + 'fieldId' => $this->params['fieldId'], + 'fieldLabel' => $this->fieldParams['fieldDropzoneLabel'], + 'fieldType' => 'html', + 'fieldHelp' => true, + 'fieldHelpTooltipContent' => $this->fieldParams['fieldHelpTooltipContent'], + 'fieldAdditionalClass' => 'mb-0', + 'fieldRequired' => $this->fieldParams['fieldRequired'], + 'fieldBazScan' => true, + 'fieldBazJstreeSearch' => $this->fieldParams['fieldBazJstreeSearch'], + 'fieldBazPostOnCreate' => $this->fieldParams['fieldBazPostOnCreate'], + 'fieldBazPostOnUpdate' => $this->fieldParams['fieldBazPostOnUpdate'] + ] + ) . + $this->adminLTETags->useTag('buttons', + [ + 'componentId' => $this->params['componentId'], + 'sectionId' => $this->params['sectionId'], + 'buttonLabel' => false, + 'buttonType' => 'button', + 'buttons' => $dropzoneButtons + ] + ) . + '
    -
    -
    -
      -
    • -
      -
      - -
      +
      +
      +
      +
        +
      • +
        +
        +
        -
        -
        - - - -
        -
        -
        -
        -
        -
        -
        - +
        +
        +
        + + + +
        +
        +
        +
        -
      • -
      -
      +
      + +
      +
      +
    • +
    -
    params['noPreview'] . '> -
    -
      '; +
    '; - if ($this->params['attachments'] && count($this->params['attachments']) > 0) { - $this->content .= - ''; + $preview = + '
    params['noPreview'] . '> +
    ' . + $this->adminLTETags->useTag('fields', + [ + 'component' => $this->params['component'], + 'componentName' => $this->params['componentName'], + 'componentId' => $this->params['componentId'], + 'sectionId' => $this->params['sectionId'], + 'fieldId' => $this->params['fieldId'], + 'fieldLabel' => $this->fieldParams['fieldDropzonePreviewLabel'], + 'fieldType' => 'html', + 'fieldHelp' => true, + 'fieldHelpTooltipContent' => $this->fieldParams['fieldDropzonePreviewHelpTooltipContent'], + 'fieldAdditionalClass' => 'mb-0', + 'fieldBazScan' => true + ] + ) . + '
      '; + if ($this->params['attachments'] && count($this->params['attachments']) > 0) { + $counter = 0; + foreach ($this->params['attachments'] as $attachmentKey => $attachment) { + if (!isset($attachment['uuid'])) { + continue; + } - foreach ($this->params['attachments'] as $attachmentKey => $attachment) { + if (isset($attachment['type'])) { if ($attachment['type'] === 'application/pdf') { $src = $this->links->images('/general/pdf.png'); $alt = 'pdf'; @@ -309,81 +342,88 @@ protected function generateContent() $src = $this->links->images('/general/file-unknown.png'); $alt = 'Unknwon File Type'; } + } else { + $src = $this->links->images('/general/file-unknown.png'); + $alt = 'Unknwon File Type'; + } - $this->content .= - '
    • '; + $preview .= + '
    • '; - if (isset($this->params['sortable']) && - $this->params['sortable'] === true - ) { - $this->content .= - ''; - } + if (isset($this->params['sortable']) && + $this->params['sortable'] === true + ) { + $preview .= + ''; + } - $this->content .= - $attachment['org_file_name'] . - '
      -
      '; + $preview .= + $attachment['org_file_name'] . + '
      +
      '; + + if (in_array($attachment['type'], $this->params['storage']['allowed_file_mime_types'])) { + $preview .= + '' . $alt . ''; + $download = true; + } else if (in_array($attachment['type'], $this->params['storage']['allowed_image_mime_types'])) { + $download = false; + + if ($this->params['storage']['permission'] === 'public') { + if (!isset($attachment['links'][$this->fieldParams['lightboxSize']])) { + $this->fieldParams['lightboxSize'] = $this->adminLTETags->helper->lastKey($attachment['links']); + } + $preview .= + ' + ' . $attachment['org_file_name'] . ' + '; + + } else { + $preview .= + ' + ' . $attachment['org_file_name'] . ' + '; + } - if (in_array($attachment['type'], $this->params['storage']['allowed_file_mime_types'])) { - $this->content .= - '' . $alt . ''; - $download = true; - } else if (in_array($attachment['type'], $this->params['storage']['allowed_image_mime_types'])) { - $download = false; + } else { + $download = true; + $preview .= + '' . $alt . ''; + } + $preview .= + '
      +
      + + + '; + + if (isset($download) && $download === true) { if ($this->params['storage']['permission'] === 'public') { - if (!isset($attachment['links'][$this->fieldParams['lightboxSize']])) { - $this->fieldParams['lightboxSize'] = $this->adminLTETags->helper->lastKey($attachment['links']); - } - $this->content .= - ' - ' . $attachment['org_file_name'] . ' - '; + + $preview .= + ' + + '; } else { - $this->content .= - ' - ' . $attachment['org_file_name'] . ' + $preview .= + ' + '; } - - } else { - $download = true; - $this->content .= - '' . $alt . ''; } - $this->content .= - '
      -
      - - - '; - - if (isset($download) && $download === true) { - if ($this->params['storage']['permission'] === 'public') { - - $this->content .= - ' - - '; + $preview .= + '
      +
      +
    • '; - } else { - $this->content .= - ' - - '; - } - } + $counter++; + } - $this->content .= - '
    -
    - '; - } - } else { - $this->content .= + if ($counter === 0) { + $preview .= '
    @@ -392,14 +432,37 @@ protected function generateContent()
    '; } + } else { + $preview .= + '
    +
    +
    + Add ' . $this->params['allowedUploads'] . ' +
    +
    +
    '; + } - $this->content .= ' - -
    + $preview .= ' +
    -
    ' . +
    '; + + if ($this->fieldParams['arrange'] === 'horizontal') { + $this->content .= + '
    +
    ' . $uploader . '
    +
    ' . $preview . '
    +
    '; + } else { + $this->content .= + '
    ' + . $uploader + . $preview . + '
    '; + } - $this->inclJs(); + $this->content .= $this->inclJs(); } protected function inclJs() @@ -475,7 +538,7 @@ function initEvents() { fieldId["dropzone"].on("addedfile", function(file) { if (file.size > maxFileSize) { fieldId["dropzone"].removeFile(file); - PNotify.error({ + paginatedPNotify("error", { title: file.name, text: "File size exceeds allowed size! File not added." }); @@ -516,19 +579,23 @@ function initEvents() { } else if (file.type === "text/csv") { src = "' . $this->links->images('/general/csv.png') . '"; alt = "csv"; + } else if (file.type.startsWith("image")) { + src = null; + alt = null; } else { src = "' . $this->links->images('/general/file-unknown.png') . '"; alt = "Unknwon File Type"; } if (indexOfFile !== -1 || indexOfImage !== -1) { - $(file.previewElement).children().find(".filename").html(file.name); - $(file.previewElement).children().find("[data-dz-thumbnail]").attr("src", src); - $(file.previewElement).children().find("[data-dz-thumbnail]").attr("alt", alt); - + if (src && alt) { + $(file.previewElement).children().find(".filename").html(file.name); + $(file.previewElement).children().find("[data-dz-thumbnail]").attr("src", src); + $(file.previewElement).children().find("[data-dz-thumbnail]").attr("alt", alt); + } } else if (indexOfFile === -1 && indexOfImage === -1) { fieldId["dropzone"].removeFile(file); - PNotify.error({ + paginatedPNotify("error", { title: file.name, text: "Extension not allowed! File not added." }); @@ -585,7 +652,7 @@ function initEvents() { if (file.accepted && file.status === "success") { if (response.responseCode != 0) { problemWithUpload = true; - PNotify.error({ + paginatedPNotify("error", { title: file.name, text: response.responseMessage }); @@ -651,8 +718,8 @@ function initEvents() { newList +='; if ($this->params['storage']['permission'] === 'public') { $inclJs .= - '\'\' + - \'\' + file.name + \'\' + + '\'\' + + \'\' + file.name + \'\' + \'\';'; } else { $inclJs .= @@ -721,7 +788,7 @@ function initEvents() { if (file.accepted === false) { fieldId["dropzone"].removeFile(file); - PNotify.error({ + paginatedPNotify("error", { title: "Limit Reached!", text: response + " Did not add file " + file.name + " to the queue." }); @@ -730,7 +797,7 @@ function initEvents() { //Fatal Error if (file.status === "error") { - PNotify.error({ + paginatedPNotify("error", { title: "ERROR", text: "Contact Administrator!" }); @@ -809,6 +876,8 @@ function registerSaveCancel() { "storagetype" : "' . $this->params['storage']['permission'] . '", "setOrphan" : "' . $this->params['setOrphan'] . '", "isPointer" : "' . $this->params['isPointer'] . '", + "package_class" : "' . $this->params['filePackageClass'] . '", + "package_row_id": "' . $this->params['filePackageRowId'] . '", "isBackupFile" : "' . $this->params['isBackupFile'] . '" }; @@ -852,8 +921,13 @@ function processDeleteUUIDs() { deleteFile(uuid); }); } + $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-dropzone-save").attr("hidden", true); $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-dropzone-cancel").attr("hidden", true); + $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-dropzone-upload").attr("disabled", false); + $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-dropzone-save").children("i").removeClass("fa-cog fa-spin").addClass("fa-save"); + $("#' . $this->compSecId . '-' . $this->params['fieldId'] . '-dropzone-save").attr("disabled", false); + deleteUUIDs = []; filesLimit = filesLimit + deleteUUIDsLength; initDropzone(); @@ -872,7 +946,7 @@ function deleteFile(uuid) { } if (response.responseCode != 0) { - PNotify.error({ + paginatedPNotify("error", { title: "Error:", text: response.responseMessage }); @@ -953,4 +1027,4 @@ function collectData() { return $inclJs; } -} +} \ No newline at end of file diff --git a/apps/Core/Packages/Adminltetags/Tags/Fields/Select2.php b/apps/Core/Packages/Adminltetags/Tags/Fields/Select2.php index a1fc6f376..45f339ee9 100644 --- a/apps/Core/Packages/Adminltetags/Tags/Fields/Select2.php +++ b/apps/Core/Packages/Adminltetags/Tags/Fields/Select2.php @@ -72,6 +72,11 @@ protected function generateContent() $this->params['fieldSelect2Type'] : 'primary'; + $this->fieldParams['fieldSelect2AdditionalClass'] = + isset($this->params['fieldSelect2AdditionalClass']) ? + $this->params['fieldSelect2AdditionalClass'] : + ''; + $this->fieldParams['fieldDataSelect2Multiple'] = isset($this->params['fieldDataSelect2Multiple']) && $this->params['fieldDataSelect2Multiple'] === true ? 'multiple="multiple"' : @@ -294,7 +299,7 @@ protected function preAddon() protected function select2() { $this->content .= - 'fieldParams['fieldBazPostOnCreate'] . ' ' . $this->fieldParams['fieldBazPostOnUpdate'] . ' ' . $this->fieldParams['fieldBazScan'] . ' class="form-control select2 select2-' . $this->fieldParams['fieldSelect2Type'] . ' ' . $this->fieldParams['fieldSelect2AdditionalClass'] . '" data-dropdown-css-class="select2-' . $this->fieldParams['fieldSelect2Type'] . '" ' . $this->fieldParams['fieldId'] . '" ' . $this->fieldParams['fieldName'] . '" style="width:' . $this->width . ';" ' . $this->fieldParams['fieldDataSelect2Multiple'] . ' ' . $this->fieldParams['fieldDataSelect2Create'] . ' ' . $this->fieldParams['fieldDataSelect2MultipleObject'] . ' ' . $this->fieldParams['fieldDisabled'] . ' ' . $this->fieldParams['fieldDataAttributes'] . '> '; if ($this->fieldParams['fieldDataSelect2TreeData']) { @@ -456,4 +461,4 @@ protected function postAddon() $this->content .= '
    '; } } -} \ No newline at end of file +} diff --git a/apps/Core/Packages/Adminltetags/Traits/DynamicTable.php b/apps/Core/Packages/Adminltetags/Traits/DynamicTable.php index b64b85a82..9e32e74e8 100644 --- a/apps/Core/Packages/Adminltetags/Traits/DynamicTable.php +++ b/apps/Core/Packages/Adminltetags/Traits/DynamicTable.php @@ -22,7 +22,8 @@ public function generateDTContent( $resetCache = false, $enableCache = true, $packageData = [], - $excludeColumns = [] + $excludeColumns = [], + $quickFilterConditions = null//Quick conditions function if needed to modify the conditions received ) { if (gettype($package) === 'string') { $package = $this->usePackage($package); @@ -147,6 +148,12 @@ public function generateDTContent( $conditions = array_replace($conditions, $postUrlParams); } + if (isset($this->postData()['quick_filter']) && isset($this->postData()['conditions']) && $quickFilterConditions && is_callable($quickFilterConditions)) { + $conditions['conditions'] = $quickFilterConditions(); + } else if (isset($this->postData()['quick_filter']) && isset($this->postData()['conditions'])) { + $conditions['conditions'] = $this->postData()['conditions']; + } + try { if (count($packageData) === 0) { $packageData = false; diff --git a/apps/Core/Packages/Devtools/GeoExtractData/Data b/apps/Core/Packages/Devtools/GeoExtractData/Data index 16e6db886..4efcb6a24 160000 --- a/apps/Core/Packages/Devtools/GeoExtractData/Data +++ b/apps/Core/Packages/Devtools/GeoExtractData/Data @@ -1 +1 @@ -Subproject commit 16e6db886f6a19ba8860686614567fd0c74edcdd +Subproject commit 4efcb6a24e0718dcf464f01afab306964b10dd4c diff --git a/apps/Core/Packages/Devtools/GeoExtractData/DevtoolsGeoExtractData.php b/apps/Core/Packages/Devtools/GeoExtractData/DevtoolsGeoExtractData.php index ed676bc3a..36516aac5 100644 --- a/apps/Core/Packages/Devtools/GeoExtractData/DevtoolsGeoExtractData.php +++ b/apps/Core/Packages/Devtools/GeoExtractData/DevtoolsGeoExtractData.php @@ -69,23 +69,40 @@ public function __call($method, $arguments) } } - protected function downloadGeoData() + protected function downloadGeoCountriesData() { - $this->method = 'downloadGeoData'; + $this->method = 'downloadGeoCountriesData'; return $this->downloadData( - 'https://raw.githubusercontent.com/dr5hn/countries-states-cities-database/master/json/countries%2Bstates%2Bcities.json', - base_path('apps/Core/Packages/Devtools/GeoExtractData/Data/countries+states+cities.json') + 'https://github.com/dr5hn/countries-states-cities-database/releases/latest/download/json-countries+states+cities.json.gz', + base_path('apps/Core/Packages/Devtools/GeoExtractData/Data/json-countries+states+cities.json.gz') ); } - protected function processGeoData() + protected function downloadGeoPostcodeData() { + $this->method = 'downloadGeoPostcodeData'; + + return $this->downloadData( + 'https://github.com/dr5hn/countries-states-cities-database/releases/latest/download/json-postcodes.json.gz', + base_path('apps/Core/Packages/Devtools/GeoExtractData/Data/json-postcodes.json.gz') + ); + } + + protected function processGeoCountriesData() + { + $this->ungzData('json-countries+states+cities.json.gz'); + $this->ungzData('json-postcodes.json.gz'); + $countries = []; try { - if ($this->localContent->fileExists($this->sourceDir . 'countries+states+cities.json')) { - $this->sourceFile = $this->helper->decode($this->localContent->read($this->sourceDir . 'countries+states+cities.json'), true); + if ($this->localContent->fileExists($this->sourceDir . 'json-countries+states+cities.json')) { + $this->sourceFile = $this->helper->decode($this->localContent->read($this->sourceDir . 'json-countries+states+cities.json'), true); + } + + if ($this->localContent->fileExists($this->sourceDir . 'json-postcodes.json')) { + $postcodesArr = $this->helper->decode($this->localContent->read($this->sourceDir . 'json-postcodes.json'), true); } } catch (FilesystemException | UnableToReadFile | \throwable $e) { $this->addResponse($e->getMessage(), 1); @@ -105,25 +122,48 @@ protected function processGeoData() if ($states && is_array($states) && count($states) > 0) { foreach ($states as $state) { - $stateName = str_replace(' ', '' , strtolower($state['name'])); - $cities = $state['cities']; unset($state['cities']); - $countries[$countryKey]['states'][$stateName] = $state; + $countries[$countryKey]['states'][$country['id'] . '-' . $state['id']] = $state; foreach ($cities as $city) { $cityName = str_replace(' ', '' , strtolower($city['name'])); - $countries[$countryKey]['states'][$stateName]['cities'][$cityName] = $city; + $countries[$countryKey]['states'][$country['id'] . '-' . $state['id']]['cities'][$cityName] = $city; } } + + $countries[$countryKey]['states'][$country['id'] . '-' . $state['id']]['postcodes'] = []; + } + } + } + + $postCodes = []; + + if ($postcodesArr && is_array($postcodesArr)) { + foreach ($postcodesArr as $postcode) { + if (!isset($postCodes[$postcode['country_id'] . '-' . $postcode['state_id']])) { + $postCodes[$postcode['country_id'] . '-' . $postcode['state_id']] = []; } + + $postCodes[$postcode['country_id'] . '-' . $postcode['state_id']][$postcode['id']]['id'] = $postcode['id']; + $postCodes[$postcode['country_id'] . '-' . $postcode['state_id']][$postcode['id']]['code'] = $postcode['code']; + $postCodes[$postcode['country_id'] . '-' . $postcode['state_id']][$postcode['id']]['name'] = $postcode['locality_name']; + $postCodes[$postcode['country_id'] . '-' . $postcode['state_id']][$postcode['id']]['city_id'] = $postcode['city_id']; } } foreach ($countries as $countryKey => &$country) { + if (isset($country['states'])) { + foreach ($country['states'] as &$state) { + if (isset($postCodes[$country['id'] . '-' . $state['id']])) { + $countries[$countryKey]['states'][$country['id'] . '-' . $state['id']]['postcodes'] = $postCodes[$country['id'] . '-' . $state['id']]; + } + } + } + $this->localContent->write($this->sourceDir . $countryKey . '.json', $this->helper->encode($country)); unset($country['states']); @@ -134,6 +174,35 @@ protected function processGeoData() return true; } + protected function ungzData($fileName) + { + try { + // Name of the output file (remove .gz) + $outFileName = str_replace('.gz', '', $fileName); + + // Open the gzipped file in read-binary mode + $gzFile = gzopen(base_path($this->sourceDir . $fileName), 'rb'); + // Open/Create the output file in write-binary mode + $outFile = fopen(base_path($this->sourceDir . $outFileName), 'wb'); + + // Read and write until the end of the compressed file + while (!gzeof($gzFile)) { + // Read 4KB at a time + fwrite($outFile, gzread($gzFile, 4096)); + } + + // Close the file pointers + fclose($outFile); + gzclose($gzFile); + } catch (\throwable $e) { + $this->addResponse($e->getMessage(), 1); + + return false; + } + + return true; + } + protected function zipData() { try { @@ -422,7 +491,10 @@ protected function downloadData($url, $sink) }, 'verify' => false, 'connect_timeout' => 5, - 'sink' => $sink + 'sink' => $sink, + 'headers' => [ + 'User-Agent' => 'Mozilla/5.0 (X11; Linux i686; rv:150.0) Gecko/20100101 Firefox/150.0' + ] ] ); diff --git a/apps/Core/Packages/Devtools/Modules/DevtoolsModules.php b/apps/Core/Packages/Devtools/Modules/DevtoolsModules.php index 2f82a280a..528ec6d1d 100644 --- a/apps/Core/Packages/Devtools/Modules/DevtoolsModules.php +++ b/apps/Core/Packages/Devtools/Modules/DevtoolsModules.php @@ -114,9 +114,9 @@ public function addModule($data) } try { - if ($this->generateNewFiles($data) && - $this->updateModuleJson($data, false, $viewPublic) && - $this->modules->{$data['module_type']}->add($data) + if ($this->modules->{$data['module_type']}->add($data) && + $this->generateNewFiles($data) && + $this->updateModuleJson($data, false, $viewPublic) ) { if (strtolower($data['app_type']) !== 'core') { $this->reCalculateFilesHash($this->modules->{$data['module_type']}->packagesData->last); @@ -174,6 +174,7 @@ public function addModule($data) 'newDirs' => $this->newDirs ] ); + return; } } catch (\Exception $e) { @@ -253,6 +254,7 @@ public function updateModule($data) if ($module['module_type'] === 'views' && $module['is_subview'] == true) { $viewPublic = false; } + if ($this->updateModuleJson($data, false, $viewPublic) && $this->modules->{$data['module_type']}->update($module) ) { @@ -260,9 +262,12 @@ public function updateModule($data) $this->reCalculateFilesHash($this->modules->{$data['module_type']}->packagesData->last); } - if ($data['module_type'] === 'components') { - $this->addUpdateComponentMenu($data); + if ($data['module_type'] === 'components' && strtolower($data['app_type']) === 'core') { + $this->addUpdateComponentMenu($module); + $this->addUpdateComponentWidgets($module); + $this->addUpdateComponentFilters($module); } + if ($data['module_type'] === 'views') { $viewsSettings = $this->modules->viewsSettings->getViewsSettingsByViewId($data['id']); @@ -271,6 +276,9 @@ public function updateModule($data) if (is_string($data['settings'])) { $data['settings'] = $this->helper->decode($data['settings'], true); } + if (isset($setting['settings']['branding']) && count($setting['settings']['branding']) > 0) { + unset($data['settings']['branding']); + } $setting['settings'] = array_replace($setting['settings'], $data['settings']); @@ -305,7 +313,7 @@ public function updateModule($data) return; } else { - if (!$this->checkRepo($data)) { + if (!$checkedRepo = $this->checkRepo($data)) { if (strtolower($data['app_type']) !== 'core') { $newRepo = $this->createRepo($data); } @@ -319,8 +327,17 @@ public function updateModule($data) ] ); - return; + return true; } + + $this->addResponse('Module updated & repo already exists. Run git commands locally to initialize the repo locally.', + 0, + [ + 'newRepo' => $checkedRepo + ] + ); + + return true; } } @@ -334,10 +351,29 @@ public function updateModule($data) $this->core->update($core); } - if ((isset($data['run_install_uninstall']) && $data['run_install_uninstall'] == true) || - (isset($data['truncate_table']) && $data['truncate_table'] == true) + if ((isset($data['run_install_uninstall']) && (bool) $data['run_install_uninstall'] == true) || + (isset($data['truncate_table']) && (bool) $data['truncate_table'] == true) ) { - $this->runInstallUninstallTruncateTable($data); + $reinstall = false; + $truncate = false; + + if ((isset($data['run_install_uninstall']) && (bool) $data['run_install_uninstall'] == true)) { + $reinstall = true; + + if (strtolower($data['app_type']) === 'core' && + strtolower($data['name']) !== 'core' + ) { + $this->addResponse('Module updated. But, only core module can run install/uninstall!', 1); + + return; + } + } + + if ((isset($data['truncate_table']) && (bool) $data['truncate_table'] == true)) { + $truncate = true; + } + + $this->runInstallUninstallTruncateTable($data, $reinstall, $truncate); } $this->addResponse('Module updated'); @@ -354,6 +390,86 @@ public function updateModule($data) $this->addResponse('Error updating Module', 1); } + public function bulkModule($data) + { + if (!isset($data['bulk_actions']) || + (isset($data['bulk_actions']) && is_array($data['bulk_actions']) && count($data['bulk_actions']) === 0) + ) { + $this->addResponse('Provide a list of modules to perform action on.', 1); + + return false; + } + + if (!isset($data['task'])) { + $this->addResponse('Bulk action task not provided.', 1); + + return false; + } + + foreach ($data['bulk_actions'] as $module_type => $moduleList) { + if ($module_type === 'bundles') { + continue; + } + if ($data['task'] === 'truncate' && $module_type !== 'packages') { + continue; + } + if ($data['task'] === 'run_script' && $module_type === 'views') { + continue; + } + + if (count($moduleList) > 0) { + foreach ($moduleList as $moduleId) { + $moduleToUpdate = null; + + if ($module_type === 'apptypes') { + $moduleToUpdate = $this->apps->types->getAppTypeById((int) $moduleId); + } else { + $moduleToUpdate = $this->modules->{$module_type}->getById((int) $moduleId); + } + + if (isset($moduleToUpdate)) { + if ($moduleToUpdate['name'] === 'Core' && + $data['task'] !== 'run_script' + ) { + continue; + } + + try { + $update = false; + if ($data['task'] === 'install') { + $moduleToUpdate['installed'] = 1; + $update = true; + } else if ($data['task'] === 'uninstall') { + $moduleToUpdate['installed'] = 0; + $update = true; + } else if ($data['task'] === 'truncate') { + $this->runInstallUninstallTruncateTable($moduleToUpdate, false, true); + } else if ($data['task'] === 'run_script') { + $this->runInstallUninstallTruncateTable($moduleToUpdate, true, false); + } + + if ($update) { + if ($module_type === 'apptypes') { + $this->apps->types->update($moduleToUpdate); + } else { + $this->modules->{$module_type}->update($moduleToUpdate); + } + } + } catch (\throwable $e) { + $this->addResponse($e->getMessage(), 1); + + return false; + } + } + } + } + } + + $this->addResponse('Bulk action performed successfully!'); + + return true; + } + protected function precheck($data) { if ($data['api_id'] != '0' && @@ -553,7 +669,13 @@ protected function getFilesHash($module) public function reCalculateFilesHash($module, $remove = false, $viaGenerateRelease = false, $viaValidation = false, $force = false) { + $releasePending = false; + if ($force) { + if (isset($module['release_pending']) && $module['release_pending'] == 'true') { + $releasePending = true; + } + $module = $this->modules->{$module['module_type']}->getById($module['id']); } @@ -596,7 +718,9 @@ public function reCalculateFilesHash($module, $remove = false, $viaGenerateRelea $hashFiles = []; foreach ($filesToHash as $fileToHash) { - if (str_ends_with($fileToHash, '/')) { + if (str_ends_with($fileToHash, '#')) {//For Commenting + continue; + } else if (str_ends_with($fileToHash, '/')) { $fileToHashDirList = $this->basepackages->utils->scanDir($moduleLocation . $fileToHash, true); if ($fileToHashDirList && count($fileToHashDirList['files']) > 0) { @@ -611,6 +735,19 @@ public function reCalculateFilesHash($module, $remove = false, $viaGenerateRelea $moduleLocationFiles['files'] = array_merge($moduleLocationFiles['files'], $hashFiles); } } + } else { + $files = $this->basepackages->utils->scanDir( + $moduleLocation, + true, + [ + '.git/', + 'linter-backup/' + ] + ); + + if ($files && count($files['files']) > 0) { + $moduleLocationFiles['files'] = array_merge($moduleLocationFiles['files'], $files['files']); + } } } else { $files = $this->basepackages->utils->scanDir( @@ -634,7 +771,21 @@ public function reCalculateFilesHash($module, $remove = false, $viaGenerateRelea foreach ($moduleLocationFiles['files'] as $file) { $filePath = $file; - $file = str_replace($moduleLocation, '', $file); + if (count($moduleLocations) === 1) { + $file = str_replace($moduleLocations[0], '', $file); + } else if (count($moduleLocations) === 2) {//Main View (with public) + $moduleLocation = null; + + foreach ($moduleLocations as $moduleLocation) { + if (str_contains($moduleLocation, 'public/')) { + $file = str_replace($moduleLocation, 'pub-', $file); + } else { + $file = str_replace($moduleLocation, '', $file); + } + } + } else { + $file = str_replace($moduleLocations, '', $file); + } $hash = hash_file('md5', base_path($filePath)); @@ -642,6 +793,12 @@ public function reCalculateFilesHash($module, $remove = false, $viaGenerateRelea } } + if ($releasePending) { + $filesHash['release_pending'] = true; + } else { + $filesHash['release_pending'] = false; + } + if (isset($filesHash['id'])) { $this->update($filesHash); } else { @@ -659,6 +816,7 @@ public function validateFilesHash($module) $module['repoExists'] = false; $module['latestRelease'] = false; + if ($this->localContent->directoryExists($moduleLocation . '.git')) { if ((!isset($module['repo_details']) || !isset($module['repo_details']['latestRelease'])) || @@ -692,12 +850,18 @@ public function validateFilesHash($module) $filesHash = $this->getFilesHash($module); $module['isModified'] = false; + $module['releasePending'] = false; + if (!$filesHash) { $this->reCalculateFilesHash($module, false, false, true); return $module; } + if (isset($filesHash['release_pending']) && $filesHash['release_pending'] == true) { + $module['releasePending'] = true; + } + $moduleLocationFiles['files'] = []; if ($module['module_type'] === 'views' && $module['is_subview'] == false) { @@ -718,7 +882,9 @@ public function validateFilesHash($module) $hashFiles = []; foreach ($filesToHash as $fileToHash) { - if (str_ends_with($fileToHash, '/')) { + if (str_ends_with($fileToHash, '#')) {//For Commenting + continue; + } else if (str_ends_with($fileToHash, '/')) { $fileToHashDirList = $this->basepackages->utils->scanDir($moduleLocation . $fileToHash, true); if ($fileToHashDirList && count($fileToHashDirList['files']) > 0) { @@ -733,6 +899,19 @@ public function validateFilesHash($module) $moduleLocationFiles['files'] = array_merge($moduleLocationFiles['files'], $hashFiles); } } + } else { + $files = $this->basepackages->utils->scanDir( + $moduleLocation, + true, + [ + '.git/', + 'linter-backup/' + ] + ); + + if ($files && count($files['files']) > 0) { + $moduleLocationFiles['files'] = array_merge($moduleLocationFiles['files'], $files['files']); + } } } else { $files = $this->basepackages->utils->scanDir( @@ -752,23 +931,69 @@ public function validateFilesHash($module) if ($moduleLocationFiles && count($moduleLocationFiles['files']) > 0) { $module['modified_files'] = []; + $module['modified_files']['added'] = []; + $module['modified_files']['removed'] = []; + $module['modified_files']['modified'] = []; + + array_walk($filesHash['files_hash'], function($hash, $file) use ($moduleLocations, $moduleLocationFiles, &$module) { + if (count($moduleLocations) === 1) { + $file = $moduleLocations[0] . $file; + } else if (count($moduleLocations) === 2) {//Main View (with public) + $moduleLocation = null; + + foreach ($moduleLocations as $moduleLocation) { + if (str_contains($moduleLocation, 'public') && str_contains($file, 'pub-')) { + $file = str_replace('pub-', $moduleLocation, $file); + } else if (!str_contains($moduleLocation, 'public') && !str_contains($file, 'pub-')) { + $file = $moduleLocation . $file; + } + } + } else { + $file = $moduleLocation . $file; + } + + if (!in_array($file, $moduleLocationFiles['files'])) { + array_push($module['modified_files']['removed'], $file); + } + }); foreach ($moduleLocationFiles['files'] as $file) { $filePath = $file; - $file = str_replace($moduleLocation, '', $file); + if (count($moduleLocations) === 1) { + $file = str_replace($moduleLocations[0], '', $file); + } else if (count($moduleLocations) === 2) {//Main View (with public) + $moduleLocation = null; + + foreach ($moduleLocations as $moduleLocation) { + if (str_contains($moduleLocation, 'public/')) { + $file = str_replace($moduleLocation, 'pub-', $file); + } else { + $file = str_replace($moduleLocation, '', $file); + } + } + } else { + $file = str_replace($moduleLocations, '', $file); + } $hash = hash_file('md5', base_path($filePath)); - if (!isset($filesHash['files_hash'][$file]) || - (isset($filesHash['files_hash'][$file]) && - $filesHash['files_hash'][$file] !== $hash) + if (!isset($filesHash['files_hash'][$file]) ) { - array_push($module['modified_files'], $file); - - $module['isModified'] = true; + array_push($module['modified_files']['added'], $file); + } else if (isset($filesHash['files_hash'][$file]) && + $filesHash['files_hash'][$file] !== $hash + ) { + array_push($module['modified_files']['modified'], $file); } } + + if (count($module['modified_files']['added']) > 0 || + count($module['modified_files']['modified']) > 0 || + count($module['modified_files']['removed']) > 0 + ) { + $module['isModified'] = true; + } } } catch (\throwable | FilesystemException | UnableToCheckExistence $e) { throw $e; @@ -920,7 +1145,7 @@ protected function getModuleFilesLocation($module, $viewPublic = false) return $moduleLocation . $routePath; } - protected function runInstallUninstallTruncateTable($data) + protected function runInstallUninstallTruncateTable($data, $reinstall, $truncate) { $moduleToReinstall = $this->modules->manager->getModuleInfo( [ @@ -955,19 +1180,25 @@ protected function runInstallUninstallTruncateTable($data) if ($data['app_type'] === 'core') { $coreInstall = new CoreInstall; - if ($data['type'] === 'core') { - if (isset($data['run_install_uninstall']) && $data['run_install_uninstall'] == true) { + if (!isset($data['type'])) { + $data['type'] =$moduleToReinstall['module_type']; + } + + if ($data['type'] === 'core' || + ($data['type'] === 'packages' && $data['name'] === 'Core') + ) { + if ($reinstall) { $coreInstall->init()->install(); } } else if ($data['type'] === 'packages') { $moduleModel = $module->useModel(); - if (isset($data['truncate_table']) && $data['truncate_table'] == true) { + if ($truncate) { $coreInstall->init([$moduleModel->getSource()])->truncate(); } - if (isset($data['run_install_uninstall']) && $data['run_install_uninstall'] == true) { - if ($data['installed'] == true) { + if ($reinstall) { + if ((bool) $data['installed'] == true) { $coreInstall->init([$moduleModel->getSource()])->install(); } else { $coreInstall->init([$moduleModel->getSource()])->uninstall(); @@ -975,14 +1206,12 @@ protected function runInstallUninstallTruncateTable($data) } } } else { - $module = new $class(); - - if (isset($data['truncate_table']) && $data['truncate_table'] == true && method_exists($module, 'truncate')) { + if ($truncate && method_exists($module, 'truncate')) { $module->init()->truncate(); } - if (isset($data['run_install_uninstall']) && $data['run_install_uninstall'] == true) { - if ($data['installed'] == true) { + if ($reinstall) { + if ((bool) $data['installed'] == true) { $module->init()->install(); } else { $module->init()->uninstall(); @@ -1027,7 +1256,6 @@ protected function checkAppType($data) if (isset($appType)) { $appType['name'] = $data['name']; $appType['app_type'] = strtolower($data['app_type']); - $appType['dashboards'] = $data['dashboards']; $appType['description'] = $data['description']; $appType['version'] = $data['version']; $appType['api_id'] = $data['api_id']; @@ -1094,7 +1322,6 @@ protected function addUpdateAppTypeFiles($appType) $jsonFile = 'apps/' . ucfirst($appType['app_type']) . '/Install/type.json'; $jsonContent["app_type"] = $appType["app_type"]; - $jsonContent["dashboards"] = $appType["dashboards"]; $jsonContent["name"] = $appType["name"]; $jsonContent["description"] = $appType["description"]; $jsonContent["version"] = $appType["version"]; @@ -1182,6 +1409,13 @@ public function getDefaultSettings() return $this->helper->encode($defaultSettings); } + public function getDefaultFilters() + { + $defaultFilters = []; + + return $this->helper->encode($defaultFilters); + } + public function getDefaultDependencies($type, $isSubView = false) { // For all - core, apptype @@ -1268,6 +1502,7 @@ protected function updateModuleJson($data, $viaGenerateRelease = false, $viewPub $repo = $jsonContent['repo']; } else { $data = $this->jsonData($data, true); + $jsonContent = []; $jsonContent["name"] = $data["name"]; if ($data['module_type'] === 'components') { @@ -1287,6 +1522,8 @@ protected function updateModuleJson($data, $viaGenerateRelease = false, $viewPub $jsonContent["dependencies"] = $data["dependencies"]; if ($data['module_type'] === 'components') { $jsonContent["menu"] = $data["menu"]; + $jsonContent["widgets"] = $data["widgets"]; + $jsonContent["filters"] = $data["filters"]; } if ($data['module_type'] === 'views') { @@ -1299,9 +1536,6 @@ protected function updateModuleJson($data, $viaGenerateRelease = false, $viewPub } $jsonContent["settings"] = $data["settings"]; - if ($data['module_type'] === 'components') { - $jsonContent["widgets"] = $data["widgets"]; - } } $jsonContent = $this->helper->encode($jsonContent, JSON_UNESCAPED_SLASHES); @@ -1720,7 +1954,7 @@ protected function generateNewComponentsFiles($moduleFilesLocation, &$data) protected function generateNewMiddlewaresFiles($moduleFilesLocation, $data) { - //Package File + //Middleware File try { $file = $this->localContent->read('apps/Core/Packages/Devtools/Modules/Files/Middleware.txt'); } catch (FilesystemException | UnableToReadFile $exception) { @@ -2025,8 +2259,14 @@ protected function generateNewViewsFiles($moduleFilesLocation, $data) return true; } - protected function addUpdateComponentMenu(&$data) + protected function addUpdateComponentMenu($data) { + if (strtolower($data['app_type']) !== 'core') { + return true; + } + + $module = $this->modules->{$data['module_type']}->packagesData->last; + if ($data['menu_id'] != '' && $data['menu_id'] != '0') { if (!isset($data['is_clone']) || (isset($data['is_clone']) && $data['is_clone'] == false) @@ -2037,8 +2277,6 @@ protected function addUpdateComponentMenu(&$data) if ($data['menu'] == 'false') { $this->basepackages->menus->remove($data['menu_id']); - $module = $this->modules->{$data['module_type']}->getById($data['id']); - $module['menu_id'] = null; $module['menu'] = null; @@ -2053,21 +2291,215 @@ protected function addUpdateComponentMenu(&$data) if ($data['menu'] != 'false' && $data['menu'] != '') { $data['menu'] = $this->helper->decode($data['menu'], true); - if (isset($menu)) { - $this->basepackages->menus->updateMenu($data['menu_id'], $data); + if (isset($menu) && $menu) { + $this->basepackages->menus->updateMenu($data['menu_id'], $data, $module); + + $module['menu_id'] = $menu['id']; + + $this->modules->{$data['module_type']}->update($module); return; } else { - $menu = $this->basepackages->menus->addMenu($data); + $menu = $this->basepackages->menus->addMenu($data, $module); if ($menu) { - // $module = $this->modules->{$data['module_type']}->packagesData->last; + $module = $this->modules->{$data['module_type']}->packagesData->last; + + $module['menu_id'] = $menu['id']; + + $this->modules->{$data['module_type']}->update($module); + } + } + } + } + + protected function addUpdateComponentWidgets($data) + { + if (strtolower($data['app_type']) !== 'core') { + return true; + } + + if (isset($data['widgets'])) { + if (!is_array($data['widgets']) && $data['widgets'] !== '') { + $data['widgets'] = $this->helper->decode($data['widgets'], true); + } + } + + if (isset($data['widgets']) && + count($data['widgets']) > 0 + ) { + foreach ($data['widgets'] as $widgetArr) { + if (!isset($widgetArr['method'])) { + continue; + } + + $widget = $this->basepackages->widgets->getWidgetByMethodAndAppType($widgetArr['method'], $data['app_type']); + + if ($widget) { + $widgetToUpdate = + [ + 'id' => $widget['id'], + 'name' => $widgetArr['name'], + 'method' => $widgetArr['method'], + 'component_id' => $data['id'], + 'app_type' => $data['app_type'], + 'multiple' => isset($widgetArr['multiple']) && $widgetArr['multiple'] === true ? 1 : 0, + 'max_multiple' => isset($widgetArr['max_multiple']) ? $widgetArr['max_multiple'] : 5,//Max instances of same widget + 'settings' => isset($widgetArr['settings']) ? $this->helper->encode($widgetArr['settings']) : $this->helper->encode([]) + ]; + + if ($this->basepackages->widgets->update($widgetToUpdate)) { + foreach ($data['widgets'] as &$dataWidget) { + if ($dataWidget['method'] === $widgetToUpdate['method']) { + $dataWidget['id'] = $widgetToUpdate['id']; + } + } + + $this->modules->components->update($data); + } + } else { + $widgetToAdd = + [ + 'name' => $widgetArr['name'], + 'method' => $widgetArr['method'], + 'component_id' => $data['id'], + 'app_type' => $data['app_type'], + 'multiple' => isset($widgetArr['multiple']) && $widgetArr['multiple'] === true ? 1 : 0, + 'max_multiple' => isset($widgetArr['max_multiple']) ? $widgetArr['max_multiple'] : 5,//Max instances of same widget + 'settings' => isset($widgetArr['settings']) ? $this->helper->encode($widgetArr['settings']) : $this->helper->encode([]) + ]; + + if ($this->basepackages->widgets->add($widgetToAdd)) { + $newWidget = $this->basepackages->widgets->packagesData->last; + + foreach ($data['widgets'] as &$dataWidget) { + if ($dataWidget['method'] === $newWidget['method']) { + $dataWidget['id'] = $newWidget['id']; + } + } + + $this->modules->components->update($data); + } + } + } + + //Remove widgets that dont exists + $componentWidgets = $this->basepackages->widgets->getWidgetsByComponentId((int) $data['id']); + + if ($componentWidgets && count($componentWidgets) > 0) { + $componentWidgetsKeys = array_keys($componentWidgets); + + $widget = null; + + foreach ($data['widgets'] as $widget) { + if (isset($widget['id'])) { + if (!in_array($widget['id'], $componentWidgetsKeys)) { + $this->basepackages->widgets->remove((int) $widget['id']); + } + } + } + } + } + } + + protected function addUpdateComponentFilters($data) + { + if (strtolower($data['app_type']) !== 'core') { + return true; + } + + if (isset($data['filters'])) { + if (!is_array($data['filters']) && $data['filters'] !== '') { + $data['filters'] = $this->helper->decode($data['filters'], true); + } + } + + if (isset($data['filters']) && + count($data['filters']) > 0 + ) { + $defaultFilter = null; + + foreach ($data['filters'] as $filterArr) { + if (!isset($filterArr['name']) || !isset($filterArr['conditions'])) { + continue; + } + + $filter = $this->basepackages->filters->getFiltersByComponentIdAndCondition($data['id'], $filterArr['conditions']); + + if ($filter) { + $this->basepackages->filters->updateFilter( + [ + 'id' => $filter['id'], + 'name' => $filterArr['name'], + 'app_type' => $data['app_type'], + 'conditions' => $filterArr['conditions'], + 'component_id' => $data['id'], + 'filter_type' => 0,//System + 'is_default' => $filterArr['is_default'] == 'true' ? 1 : 0, + 'auto_generated' => 1, + 'account_id' => 0 + ] + ); + } else { + $this->basepackages->filters->addFilter( + [ + 'name' => $filterArr['name'], + 'app_type' => $data['app_type'], + 'conditions' => $filterArr['conditions'], + 'component_id' => $data['id'], + 'filter_type' => 0,//System + 'is_default' => $filterArr['is_default'] == 'true' ? 1 : 0, + 'auto_generated' => 1, + 'account_id' => 0 + ] + ); - // $module['menu_id'] = $menu['id']; - $data['menu_id'] = $menu['id']; + $filter = $this->basepackages->filters->packagesData->last; } - // $this->modules->{$data['module_type']}->update($module); + if ($filter['is_default'] === 1) { + $defaultFilter = $filter; + } + } + + //Remove filters that dont exists + $componentFilters = $this->basepackages->filters->getFiltersForComponent((int) $data['id'], null, $data['app_type']); + + if ($componentFilters && count($componentFilters) > 0) { + $componentFiltersConditions = []; + + foreach ($data['filters'] as $filter) { + if (!in_array($filter['conditions'], $componentFiltersConditions)) { + array_push($componentFiltersConditions, $filter['conditions']); + } + } + //Default All Filter + array_push($componentFiltersConditions, ''); + + foreach ($componentFilters as $componentFilter) { + if (!in_array($componentFilter['conditions'], $componentFiltersConditions)) { + $this->basepackages->filters->removeFilter($componentFilter['id']); + + continue; + } + + //make sure we only make 1 default. + if ($defaultFilter) { + if ($defaultFilter['id'] === $componentFilter['id']) { + $componentFilter['is_default'] = 1; + } else { + $componentFilter['is_default'] = 0; + } + + $this->basepackages->filters->updateFilter($componentFilter); + } else { + if ($componentFilter['conditions'] === '') { + $componentFilter['is_default'] = 1; + } + + $this->basepackages->filters->updateFilter($componentFilter); + } + } } } } @@ -2237,7 +2669,7 @@ public function getMilestoneLabelIssues($data, $viaGenerateRelease = false) return $issues; } - $this->addResponse('No issues found with selected milestone/label', 1); + $this->addResponse('No closed issues found with selected milestone/label', 1); } catch (\Exception $e) { $this->addResponse($e->getMessage(), 1); @@ -3939,6 +4371,98 @@ public function getRemoteModules($id) return false; } + public function toggleVisibilityRepo($data) + { + if (!isset($data['repo'])) { + $this->addResponse('Repo not set', 1); + + return false; + } + + if (!$this->initApi($data)) { + return false; + } + + if (!isset($data['id']) || (isset($data['id']) && $data['id'] === '')) { + if (strtolower($this->apiClientConfig['provider']) === 'gitea') { + $collection = 'RepositoryApi'; + $method = 'repoGet'; + } else if (strtolower($this->apiClientConfig['provider']) === 'github') { + $collection = 'ReposApi'; + $method = 'reposGet'; + } + + $args = [$this->apiClientConfig['org_user'], $data['repo']]; + + $responseArr = $this->apiClient->useMethod($collection, $method, $args)->getResponse(true); + + if ($responseArr) { + $moduleSync['repo_details']['details'] = $responseArr; + } + } else { + $moduleSync = $this->modules->manager->getModuleInfo( + [ + 'module_type' => $data['module_type'], + 'module_id' => (int) $data['id'], + 'sync' => true, + 'getLatestRelease' => true + ] + ); + } + + $visibility = ['private' => true]; + if ($moduleSync['repo_details']['details']['private'] === true) { + $visibility = ['private' => false]; + } + + $this->apiClientConfig['repo_url'] = rtrim($this->apiClientConfig['repo_url'], '/'); + + if (strtolower($this->apiClientConfig['provider']) === 'gitea') { + $collection = 'RepositoryApi'; + $method = 'repoUpdate'; + $args = [$this->apiClientConfig['org_user']]; + } else if (strtolower($this->apiClientConfig['provider']) === 'github') { + $collection = 'ReposApi'; + $method = 'reposUpdate'; + $args = [$this->apiClientConfig['org_user'], $data['repo'], $visibility]; + } + + try { + $this->apiClient->useMethod($collection, $method, $args)->getResponse(true); + + if (!isset($data['id']) || (isset($data['id']) && $data['id'] === '')) { + //Local Module does not exists, we do not do anything! + } else { + $this->modules->manager->getModuleInfo( + [ + 'module_type' => $data['module_type'], + 'module_id' => $data['id'], + 'sync' => true, + 'getLatestRelease' => true + ] + ); + } + + if ($visibility['private'] === true) { + $this->addResponse('Repo ' . $data['repo'] . ' marked as private'); + } else { + $this->addResponse('Repo ' . $data['repo'] . ' marked as public'); + } + + return true; + } catch (\throwable | ClientException $e) { + $this->addResponse($e->getMessage(), 1); + + if ($e->getCode() === 401) { + $this->addResponse('API Authentication failed.', 1); + } else if (str_contains($e->getMessage(), 'Connection timed out')) { + $this->addResponse('Error connecting to the repository.', 1); + } + + return false; + } + } + public function removeRepo($data) { if (!isset($data['repo'])) { @@ -3952,44 +4476,89 @@ public function removeRepo($data) } $this->apiClientConfig['repo_url'] = rtrim($this->apiClientConfig['repo_url'], '/'); - //Get one or core repo details, no need to loop through all repos in the org. - if (!str_ends_with($this->apiClientConfig['repo_url'], '/' . $this->apiClientConfig['org_user'])) { - $repoUrlArr = explode('/', $this->apiClientConfig['repo_url']); - $remoteModule = $this->getRemoteModule($this->helper->last($repoUrlArr)); + if (strtolower($this->apiClientConfig['provider']) === 'gitea') { + $collection = 'RepositoryApi'; + $method = 'repoDelete'; + $args = [$this->apiClientConfig['org_user']]; + } else if (strtolower($this->apiClientConfig['provider']) === 'github') { + $collection = 'ReposApi'; + $method = 'reposDelete'; + $args = [$this->apiClientConfig['org_user'], $data['repo']]; + } - if (!$remoteModule) { - return false; + try { + $this->apiClient->useMethod($collection, $method, $args)->getResponse(true); + + $this->addResponse('Repo ' . $data['repo'] . ' deleted from remote'); + } catch (\throwable | ClientException $e) { + $this->addResponse($e->getMessage(), 1); + + if ($e->getCode() === 401) { + $this->addResponse('API Authentication failed.', 1); + } else if (str_contains($e->getMessage(), 'Connection timed out')) { + $this->addResponse('Error connecting to the repository.', 1); } - $modulesArr = [$remoteModule]; + return false; + } + } + + public function getDiff($data) + { + $module = $this->modules->{$data['module_type']}->getById($data['id']); + + if (!$module) { + $this->addResponse('Module not found!', 1); + + return false; + } + + if ($module['module_type'] === 'views' && $module['is_subview'] == false) { + $moduleLocations = [$this->getModuleFilesLocation($module), $this->getModuleFilesLocation($module, true)]; } else { - //Process all repositories in the org as repourl and org name is the same - if (strtolower($this->apiClientConfig['provider']) === 'gitea') { - $collection = 'RepositoryApi'; - $method = 'repoDelete'; - $args = [$this->apiClientConfig['org_user']]; - } else if (strtolower($this->apiClientConfig['provider']) === 'github') { - $collection = 'ReposApi'; - $method = 'reposDelete'; - $args = [$this->apiClientConfig['org_user'], $data['repo']]; - } + $moduleLocations = [$this->getModuleFilesLocation($module)]; + } - try { - $this->apiClient->useMethod($collection, $method, $args)->getResponse(true); + if (count($moduleLocations) === 0) { + $this->addResponse('Module location not found!', 1); - $this->addResponse('Repo ' . $data['repo'] . ' deleted from remote'); - } catch (\throwable | ClientException $e) { - $this->addResponse($e->getMessage(), 1); + return false; + } - if ($e->getCode() === 401) { - $this->addResponse('API Authentication failed.', 1); - } else if (str_contains($e->getMessage(), 'Connection timed out')) { - $this->addResponse('Error connecting to the repository.', 1); + $found = false; + $diff = null; + + foreach ($moduleLocations as $moduleLocation) { + if ($this->localContent->fileExists($moduleLocation . $data['file'])) { + exec('cd ' . base_path($moduleLocation) . ' && git diff ' . $data['file'], $output, $result); + + if ($result !== 0 || count($output) === 0) { + $this->addResponse('Error while getting diff', 1, ['output' => $output]); + + return false; } - return false; + if (count($output) > 200) { + $this->addResponse('File diff > 200 lines, please use external app to view diff!', 1); + + return false; + } + + $diff = $output; + + $found = true; + + break; } } + + if (!$found) { + $this->addResponse('File not found at module location!', 1); + + return false; + } + + $this->addResponse('Diff for file', 0, ['diff' => $diff]); } } \ No newline at end of file diff --git a/apps/Core/Packages/Devtools/Modules/Files/Package.txt b/apps/Core/Packages/Devtools/Modules/Files/Package.txt index 83f047854..8d25caaea 100644 --- a/apps/Core/Packages/Devtools/Modules/Files/Package.txt +++ b/apps/Core/Packages/Devtools/Modules/Files/Package.txt @@ -12,6 +12,16 @@ class "PACKAGENAME" extends BasePackage public $"PACKAGENAMELC"; + public function init() + { + //Note: If you want to use init function, you need to run parent::init as well. + //It is used by the use app database feature of the app. + //if you remove the init() function from this class, it is also fine. + parent::init(); + + return $this; + } + public function get"PACKAGENAME"ById($id) { $"PACKAGENAMELC" = $this->getById($id); diff --git a/apps/Core/Packages/Devtools/Modules/Files/PackageInstallInstall.txt b/apps/Core/Packages/Devtools/Modules/Files/PackageInstallInstall.txt index 7d46bcfba..5bf834e38 100644 --- a/apps/Core/Packages/Devtools/Modules/Files/PackageInstallInstall.txt +++ b/apps/Core/Packages/Devtools/Modules/Files/PackageInstallInstall.txt @@ -4,9 +4,33 @@ use "PACKAGESCHEMACLASS" use System\Base\BasePackage; +use System\Base\Providers\ModulesServiceProvider\DbInstaller; class Install extends BasePackage { + protected $databases; + + protected $dbInstaller; + + public function init() + { + $this->databases = + [ + 'db_table_name' => [ + 'schema' => 'new Enter_Scheme_Class', + 'model' => 'new Enter_Model_Class', + 'configParams' => + [ + 'min_index_chars' => 6 + ] + ], + ]; + + $this->dbInstaller = new DbInstaller; + + return $this; + } + public function install() { $this->preInstall(); diff --git a/apps/Core/Packages/Devtools/Modules/Files/ViewsGitignore.txt b/apps/Core/Packages/Devtools/Modules/Files/ViewsGitignore.txt index b6a8b6077..125ab41a8 100644 --- a/apps/Core/Packages/Devtools/Modules/Files/ViewsGitignore.txt +++ b/apps/Core/Packages/Devtools/Modules/Files/ViewsGitignore.txt @@ -1,6 +1,7 @@ #Ignore everything else in the html folder to avoid adding subview. Change file content as needed html/* #Only include the following. Change file content as needed +linter* !html/ !html/layouts/ !html/common/ diff --git a/apps/Core/Packages/Devtools/Modules/Install/Schema/FilesHash.php b/apps/Core/Packages/Devtools/Modules/Install/Schema/FilesHash.php index 3703f01fa..d71cd9da8 100644 --- a/apps/Core/Packages/Devtools/Modules/Install/Schema/FilesHash.php +++ b/apps/Core/Packages/Devtools/Modules/Install/Schema/FilesHash.php @@ -42,6 +42,13 @@ public function columns() 'type' => Column::TYPE_JSON, 'notNull' => true, ] + ), + new Column( + 'release_pending', + [ + 'type' => Column::TYPE_BOOLEAN, + 'notNull' => false, + ] ) ], 'indexes' => [ @@ -59,4 +66,19 @@ public function columns() ] ]; } + + public function indexes() + { + return + [ + new Index( + 'column_INDEX', + [ + 'module_type', + 'module_id' + ], + 'INDEX' + ) + ]; + } } diff --git a/apps/Core/Packages/Devtools/Modules/Model/AppsCoreDevtoolsFilesHash.php b/apps/Core/Packages/Devtools/Modules/Model/AppsCoreDevtoolsFilesHash.php index 6cb53e74a..b2c559c5c 100644 --- a/apps/Core/Packages/Devtools/Modules/Model/AppsCoreDevtoolsFilesHash.php +++ b/apps/Core/Packages/Devtools/Modules/Model/AppsCoreDevtoolsFilesHash.php @@ -13,4 +13,6 @@ class AppsCoreDevtoolsFilesHash extends BaseModel public $module_id; public $files_hash; + + public $release_pending; } \ No newline at end of file diff --git a/apps/Core/Views/Default/html/apps/form.html b/apps/Core/Views/Default/html/apps/form.html index cb4a29ed8..841ea70cb 100644 --- a/apps/Core/Views/Default/html/apps/form.html +++ b/apps/Core/Views/Default/html/apps/form.html @@ -46,6 +46,15 @@ {% set authTabHidden = false %} {% endif %} {% endfor %} + {% set dbTabHidden = false %} + {% if app['id'] is defined and app['id'] == '1' %} + {% set dbTabHidden = true %} + {% endif %} + {% if app['use_app_db'] is defined and app['use_app_db'] == true %} + {% set useAppDb = true %} + {% else %} + {% set useAppDb = false %} + {% endif %}
    @@ -80,6 +89,12 @@ 'tabTitle' : 'IP Filters', 'tabInclude' : 'apps/wizard/filters/form', 'tabHidden' : ipFilterTabHidden + ], + 'db' : + [ + 'tabTitle' : 'Database', + 'tabInclude' : 'apps/wizard/db/form', + 'tabHidden' : dbTabHidden ] ] ] @@ -89,8 +104,8 @@
    \ No newline at end of file diff --git a/apps/Core/Views/Default/html/apps/wizard/db/form.html b/apps/Core/Views/Default/html/apps/wizard/db/form.html new file mode 100644 index 000000000..1bec58757 --- /dev/null +++ b/apps/Core/Views/Default/html/apps/wizard/db/form.html @@ -0,0 +1,25 @@ +{% set tooltip = 'By default, an app uses the database that is shared among all apps that are of same app type. If you enable this option, we will generate a blank database of every package of the app type with prefix : apps_' ~ app['route'] ~ '_ instead of prefix : apps_' ~ app['app_type'] ~ '_' %} +
    +
    + {{adminltetags.useTag('fields', + [ + 'component' : component, + 'componentName' : componentName, + 'componentId' : componentId, + 'sectionId' : sectionId, + 'fieldId' : 'use_app_db', + 'fieldLabel' : 'Use App Database?', + 'fieldType' : 'checkbox', + 'fieldCheckboxType' : 'primary', + 'fieldCheckboxChecked' : useAppDb, + 'fieldCheckboxAdditionClass' : 'text-sm text-uppercase', + 'fieldHelp' : true, + 'fieldHelpTooltipContent' : tooltip, + 'fieldBazScan' : true, + 'fieldBazJstreeSearch' : true, + 'fieldBazPostOnCreate' : true, + 'fieldBazPostOnUpdate' : true + ] + )}} +
    +
    \ No newline at end of file diff --git a/apps/Core/Views/Default/html/apps/wizard/done.html b/apps/Core/Views/Default/html/apps/wizard/done.html index 15e2b2a48..9538fe1ad 100644 --- a/apps/Core/Views/Default/html/apps/wizard/done.html +++ b/apps/Core/Views/Default/html/apps/wizard/done.html @@ -19,46 +19,4 @@ ] )}} - - \ No newline at end of file + \ No newline at end of file diff --git a/apps/Core/Views/Default/html/apps/wizard/info.html b/apps/Core/Views/Default/html/apps/wizard/info.html index 99756f273..8fedf91c1 100644 --- a/apps/Core/Views/Default/html/apps/wizard/info.html +++ b/apps/Core/Views/Default/html/apps/wizard/info.html @@ -4,9 +4,8 @@

    New App setup requires few steps to be completed. The steps are as follows:<

    diff --git a/apps/Core/Views/Default/html/apps/wizard/modules/form/components.html b/apps/Core/Views/Default/html/apps/wizard/modules/form/components.html index 0c736fc78..1e92f00a5 100644 --- a/apps/Core/Views/Default/html/apps/wizard/modules/form/components.html +++ b/apps/Core/Views/Default/html/apps/wizard/modules/form/components.html @@ -1,50 +1,187 @@ {% if components is defined and components|length > 0 %} - {% if app['default_component'] is defined and app['default_component'] != 0 %} - {% set appDefaultComponent = app['default_component'] %} + {% set defaultDashboardHidden = 'hidden' %} + {% set defaultDashboard = 0 %} + {% set defaultGuestsPageHidden = 'hidden' %} + {% set defaultGuestsPage = 0 %} + {% set defaultUsersPageHidden = 'hidden' %} + {% set defaultUsersPage = 0 %} + {% if dashboards is not defined %} + {% set dashboards = [] %} + {% endif %} + {% if pages is not defined %} + {% set pages = [] %} + {% endif %} + {% if app['default_component_guests'] is defined and app['default_component_guests'] != 0 %} + {% set appDefaultComponentGuests = app['default_component_guests'] %} {% else %} - {% set appDefaultComponent = 0 %} + {% set appDefaultComponentGuests = 0 %} + {% endif %} + {% if appDefaultComponentGuests == pageComponentId and pages|length > 0 %} + {% set defaultGuestsPageHidden = '' %} + {% if app['settings']['defaultGuestPage'] is defined %} + {% set defaultGuestsPage = app['settings']['defaultGuestPage'] %} + {% endif %} + {% endif %} + {% if app['default_component_users'] is defined and app['default_component_users'] != 0 %} + {% set appDefaultComponentUsers = app['default_component_users'] %} + {% else %} + {% set appDefaultComponentUsers = 0 %} + {% endif %} + {% if appDefaultComponentUsers == dashboardComponentId and dashboards|length > 0 %} + {% set defaultDashboardHidden = '' %} + {% if app['settings']['defaultDashboard'] is defined %} + {% set defaultDashboard = app['settings']['defaultDashboard'] %} + {% endif %} + {% endif %} + {% if appDefaultComponentUsers == pageComponentId and pages|length > 0 %} + {% set defaultUsersPageHidden = '' %} + {% if app['settings']['defaultUserPage'] is defined %} + {% set defaultUsersPage = app['settings']['defaultUserPage'] %} + {% endif %} {% endif %} {% if app['errors_component'] is defined and app['errors_component'] != 0 %} {% set appErrorsComponent = app['errors_component'] %} {% else %} {% set appErrorsComponent = 0 %} {% endif %} - {% set selectComponents = [] %} - {% for key, selectComponent in components %} - {% if app['app_type'] === 'core' or app['app_type'] === 'dash' %} - {% if selectComponent['route'] != 'home' %} - {% set selectComponents[key] = selectComponent %} - {% endif %} - {% else %} - {% set selectComponents[key] = selectComponent %} - {% endif %} - {% endfor %}
    - {{adminltetags.useTag('fields', - [ - 'component' : component, - 'componentName' : componentName, - 'componentId' : componentId, - 'sectionId' : sectionId, - 'fieldId' : 'default_component', - 'fieldLabel' : 'Default Component', - 'fieldType' : 'select2', - 'fieldHelp' : true, - 'fieldHelpTooltipContent' : 'Select a default component for this app.', - 'fieldBazScan' : true, - 'fieldBazJstreeSearch' : true, - 'fieldBazPostOnCreate' : true, - 'fieldBazPostOnUpdate' : true, - 'fieldRequired' : true, - 'fieldDataSelect2Options' : selectComponents, - 'fieldDataSelect2OptionsKey' : 'id', - 'fieldDataSelect2OptionsValue' : 'name', - 'fieldDataSelect2OptionsArray' : true, - 'fieldDataSelect2OptionsSelected': appDefaultComponent - ] - )}} +
    +
    + {{adminltetags.useTag('fields', + [ + 'component' : component, + 'componentName' : componentName, + 'componentId' : componentId, + 'sectionId' : sectionId, + 'fieldId' : 'default_component_guests', + 'fieldLabel' : 'Default Component (Guests)', + 'fieldType' : 'select2', + 'fieldHelp' : true, + 'fieldHelpTooltipContent' : 'Select a default component for this app for guests.', + 'fieldBazScan' : true, + 'fieldBazJstreeSearch' : true, + 'fieldBazPostOnCreate' : true, + 'fieldBazPostOnUpdate' : true, + 'fieldRequired' : true, + 'fieldDataSelect2Options' : selectGuestComponents, + 'fieldDataSelect2OptionsKey' : 'id', + 'fieldDataSelect2OptionsValue' : 'name', + 'fieldDataSelect2OptionsArray' : true, + 'fieldDataSelect2AddDataAttrFromData' : ['route'], + 'fieldDataSelect2OptionsSelected' : appDefaultComponentGuests + ] + )}} +
    +
    + {{adminltetags.useTag('fields', + [ + 'component' : component, + 'componentName' : componentName, + 'componentId' : componentId, + 'sectionId' : sectionId, + 'fieldId' : 'default_guest_page', + 'fieldLabel' : 'Default Guest Page', + 'fieldType' : 'select2', + 'fieldHelp' : true, + 'fieldHelpTooltipContent' : 'Default guest page for this app.', + 'fieldRequired' : true, + 'fieldBazScan' : true, + 'fieldBazJstreeSearch' : true, + 'fieldBazPostOnCreate' : true, + 'fieldBazPostOnUpdate' : true, + 'fieldDataSelect2Options' : pages, + 'fieldDataSelect2OptionsKey' : 'id', + 'fieldDataSelect2OptionsValue' : 'name', + 'fieldDataSelect2OptionsArray' : true, + 'fieldDataSelect2OptionsSelected' : defaultGuestsPage + ] + )}} +
    +
    +
    +
    +
    + {{adminltetags.useTag('fields', + [ + 'component' : component, + 'componentName' : componentName, + 'componentId' : componentId, + 'sectionId' : sectionId, + 'fieldId' : 'default_component_users', + 'fieldLabel' : 'Default Component (Users)', + 'fieldType' : 'select2', + 'fieldHelp' : true, + 'fieldHelpTooltipContent' : 'Select a default component for this app for logged in users.', + 'fieldBazScan' : true, + 'fieldBazJstreeSearch' : true, + 'fieldBazPostOnCreate' : true, + 'fieldBazPostOnUpdate' : true, + 'fieldRequired' : true, + 'fieldDataSelect2Options' : selectUserComponents, + 'fieldDataSelect2OptionsKey' : 'id', + 'fieldDataSelect2OptionsValue' : 'name', + 'fieldDataSelect2OptionsArray' : true, + 'fieldDataSelect2AddDataAttrFromData' : ['route'], + 'fieldDataSelect2OptionsSelected' : appDefaultComponentUsers + ] + )}} +
    +
    + {{adminltetags.useTag('fields', + [ + 'component' : component, + 'componentName' : componentName, + 'componentId' : componentId, + 'sectionId' : sectionId, + 'fieldId' : 'default_dashboard', + 'fieldLabel' : 'Default Dashboard', + 'fieldType' : 'select2', + 'fieldHelp' : true, + 'fieldHelpTooltipContent' : 'Default dashboard for this app.', + 'fieldRequired' : true, + 'fieldBazScan' : true, + 'fieldBazJstreeSearch' : true, + 'fieldBazPostOnCreate' : true, + 'fieldBazPostOnUpdate' : true, + 'fieldDataSelect2Options' : dashboards, + 'fieldDataSelect2OptionsKey' : 'id', + 'fieldDataSelect2OptionsValue' : 'name', + 'fieldDataSelect2OptionsArray' : true, + 'fieldDataSelect2OptionsSelected' : defaultDashboard + ] + )}} +
    +
    + {{adminltetags.useTag('fields', + [ + 'component' : component, + 'componentName' : componentName, + 'componentId' : componentId, + 'sectionId' : sectionId, + 'fieldId' : 'default_user_page', + 'fieldLabel' : 'Default User Page', + 'fieldType' : 'select2', + 'fieldHelp' : true, + 'fieldHelpTooltipContent' : 'Default user page for this app.', + 'fieldRequired' : true, + 'fieldBazScan' : true, + 'fieldBazJstreeSearch' : true, + 'fieldBazPostOnCreate' : true, + 'fieldBazPostOnUpdate' : true, + 'fieldDataSelect2Options' : pages, + 'fieldDataSelect2OptionsKey' : 'id', + 'fieldDataSelect2OptionsValue' : 'name', + 'fieldDataSelect2OptionsArray' : true, + 'fieldDataSelect2OptionsSelected' : defaultUsersPage + ] + )}} +
    +
    +
    +
    +
    {{adminltetags.useTag('fields', [ @@ -62,7 +199,7 @@ 'fieldBazPostOnCreate' : true, 'fieldBazPostOnUpdate' : true, 'fieldRequired' : true, - 'fieldDataSelect2Options' : selectComponents, + 'fieldDataSelect2Options' : selectGuestComponents, 'fieldDataSelect2OptionsKey' : 'id', 'fieldDataSelect2OptionsValue' : 'name', 'fieldDataSelect2OptionsArray' : true, @@ -127,7 +264,7 @@ {% set needAuthIds = json_encode([]) %} {% endif %} diff --git a/apps/Core/Views/Default/html/auth/agent.html b/apps/Core/Views/Default/html/auth/agent.html index 5a8eb6fa7..6f7593a0e 100644 --- a/apps/Core/Views/Default/html/auth/agent.html +++ b/apps/Core/Views/Default/html/auth/agent.html @@ -12,7 +12,7 @@