From 1b1428bff93d4c1f0866015d1ed5549939058d9d Mon Sep 17 00:00:00 2001 From: Ryan Mitchell Date: Sat, 18 Sep 2021 08:36:18 +0100 Subject: [PATCH 01/24] Allow extension of scopeListFrontEnd query through events (#863) * Allow extension of scopeListFrontEnd query through events * Remove model param * Use local event to isolate * wip Co-authored-by: Sam Poyigi <6567634+sampoyigi@users.noreply.github.com> --- app/admin/models/Addresses_model.php | 2 ++ app/admin/models/Categories_model.php | 2 ++ app/admin/models/Locations_model.php | 2 ++ app/admin/models/Menus_model.php | 2 ++ app/admin/models/Orders_model.php | 2 ++ app/admin/models/Reservations_model.php | 2 ++ app/admin/models/Reviews_model.php | 2 ++ app/system/models/Currencies_model.php | 2 ++ 8 files changed, 16 insertions(+) diff --git a/app/admin/models/Addresses_model.php b/app/admin/models/Addresses_model.php index 9fdcc8894f..82b8fc8195 100644 --- a/app/admin/models/Addresses_model.php +++ b/app/admin/models/Addresses_model.php @@ -80,6 +80,8 @@ public function scopeListFrontEnd($query, $options = []) } } + $this->fireEvent('model.extendListFrontEndQuery', [$query]); + return $query->paginate($pageLimit, $page); } diff --git a/app/admin/models/Categories_model.php b/app/admin/models/Categories_model.php index bd0448bd07..9382ce3777 100644 --- a/app/admin/models/Categories_model.php +++ b/app/admin/models/Categories_model.php @@ -151,6 +151,8 @@ public function scopeListFrontEnd($query, $options = []) $query->isEnabled(); } + $this->fireEvent('model.extendListFrontEndQuery', [$query]); + return $query->paginate($pageLimit, $page); } } diff --git a/app/admin/models/Locations_model.php b/app/admin/models/Locations_model.php index 8016c76050..d111ea7c66 100644 --- a/app/admin/models/Locations_model.php +++ b/app/admin/models/Locations_model.php @@ -171,6 +171,8 @@ public function scopeListFrontEnd($query, array $options = []) $query->search($search, $searchableFields); } + $this->fireEvent('model.extendListFrontEndQuery', [$query]); + return $query->paginate($pageLimit, $page); } diff --git a/app/admin/models/Menus_model.php b/app/admin/models/Menus_model.php index f0bc3f964e..d13d8b6868 100644 --- a/app/admin/models/Menus_model.php +++ b/app/admin/models/Menus_model.php @@ -159,6 +159,8 @@ public function scopeListFrontEnd($query, $options = []) }); } + $this->fireEvent('model.extendListFrontEndQuery', [$query]); + return $query->paginate($pageLimit, $page); } diff --git a/app/admin/models/Orders_model.php b/app/admin/models/Orders_model.php index 2ab8345407..7a9f67b8d0 100644 --- a/app/admin/models/Orders_model.php +++ b/app/admin/models/Orders_model.php @@ -164,6 +164,8 @@ public function scopeListFrontEnd($query, $options = []) $query = $this->scopeWhereBetweenOrderDateTime($query, Carbon::parse($startDateTime)->format('Y-m-d H:i:s'), Carbon::parse($endDateTime)->format('Y-m-d H:i:s')); } + $this->fireEvent('model.extendListFrontEndQuery', [$query]); + return $query->paginate($pageLimit, $page); } diff --git a/app/admin/models/Reservations_model.php b/app/admin/models/Reservations_model.php index eca4983096..9353097440 100644 --- a/app/admin/models/Reservations_model.php +++ b/app/admin/models/Reservations_model.php @@ -160,6 +160,8 @@ public function scopeListFrontEnd($query, $options = []) $query = $this->scopeWhereBetweenReservationDateTime($query, Carbon::parse($startDateTime)->format('Y-m-d H:i:s'), Carbon::parse($endDateTime)->format('Y-m-d H:i:s')); } + $this->fireEvent('model.extendListFrontEndQuery', [$query]); + return $query->paginate($pageLimit, $page); } diff --git a/app/admin/models/Reviews_model.php b/app/admin/models/Reviews_model.php index 5f831fbb04..f9f3af1ad0 100644 --- a/app/admin/models/Reviews_model.php +++ b/app/admin/models/Reviews_model.php @@ -122,6 +122,8 @@ public function scopeListFrontEnd($query, $options = []) } } + $this->fireEvent('model.extendListFrontEndQuery', [$query]); + return $query->paginate($pageLimit, $page); } diff --git a/app/system/models/Currencies_model.php b/app/system/models/Currencies_model.php index f22f251d25..2b24b478c4 100644 --- a/app/system/models/Currencies_model.php +++ b/app/system/models/Currencies_model.php @@ -81,6 +81,8 @@ public function scopeListFrontEnd($query, $options = []) $query->isEnabled(); } + $this->fireEvent('model.extendListFrontEndQuery', [$query]); + return $query->paginate($pageLimit, $page); } From 86a15711b45476b7ee7299f04c44fbbfd8913bde Mon Sep 17 00:00:00 2001 From: Sam Poyigi <6567634+sampoyigi@users.noreply.github.com> Date: Thu, 23 Sep 2021 00:01:28 +0100 Subject: [PATCH 02/24] Auto ignore other updates when core is available --- app/system/classes/UpdateManager.php | 5 +- app/system/controllers/Updates.php | 6 -- app/system/language/en/lang.php | 2 +- app/system/views/updates/list.blade.php | 2 - app/system/views/updates/list_items.blade.php | 100 ++++++++++++------ 5 files changed, 72 insertions(+), 43 deletions(-) diff --git a/app/system/classes/UpdateManager.php b/app/system/classes/UpdateManager.php index 7224f0b28b..615bbc5aeb 100644 --- a/app/system/classes/UpdateManager.php +++ b/app/system/classes/UpdateManager.php @@ -362,6 +362,8 @@ public function requestUpdateList($force = FALSE) $installedItems = collect($installedItems)->keyBy('name')->all(); + $coreUpdate = collect(array_get($updates, 'data', []))->firstWhere('type', 'core'); + $updateCount = 0; foreach (array_get($updates, 'data', []) as $update) { $updateCount++; @@ -370,13 +372,12 @@ public function requestUpdateList($force = FALSE) $update = $this->parseTagDescription($update); if (array_get($update, 'type') == 'core') { - $update['icon'] = 'logo-icon icon-ti-logo'; $update['installedVer'] = params('ti_version'); if ($this->disableCoreUpdates) continue; } - if ($this->isMarkedAsIgnored($update['code'])) { + if ((array_get($update, 'type') !== 'core' AND $coreUpdate) OR $this->isMarkedAsIgnored($update['code'])) { $ignoredItems[] = $update; continue; } diff --git a/app/system/controllers/Updates.php b/app/system/controllers/Updates.php index 460e41bcb8..04bafe0ec2 100644 --- a/app/system/controllers/Updates.php +++ b/app/system/controllers/Updates.php @@ -208,14 +208,8 @@ protected function applyCarte() protected function applyInstallOrUpdate($context) { - $error = null; - $items = input('items') ?? []; -// Uncomment this block to require carte key -// if (!params()->has('carte_key')) -// throw new ApplicationException(lang('system::lang.missing.carte_key')); - if (!count($items)) throw new ApplicationException(lang('system::lang.updates.alert_no_items')); diff --git a/app/system/language/en/lang.php b/app/system/language/en/lang.php index e96bd42f14..8511737b5e 100644 --- a/app/system/language/en/lang.php +++ b/app/system/language/en/lang.php @@ -615,7 +615,7 @@ 'text_update_ignored' => '%s update(s) ignored', 'text_item_update_summary' => 'Update from version %s to %s', - 'text_maintenance_mode' => 'While your site is being updated, maintenance mode will be enabled then disabled as soon as your updates are complete.', + 'text_core_update' => '  After the core has been updated, other updates will be available.', 'progress_download' => '   Downloading %s…', 'progress_extract' => '   Extracting %s…', diff --git a/app/system/views/updates/list.blade.php b/app/system/views/updates/list.blade.php index 28df76a157..26105bc184 100644 --- a/app/system/views/updates/list.blade.php +++ b/app/system/views/updates/list.blade.php @@ -11,8 +11,6 @@ -
@lang('system::lang.updates.text_maintenance_mode')
- {!! $this->makePartial('updates/list_items', ['items' => $updates['items'], 'ignored' => FALSE]) !!} @endif diff --git a/app/system/views/updates/list_items.blade.php b/app/system/views/updates/list_items.blade.php index a97e0a7cd2..8c7c821d6d 100644 --- a/app/system/views/updates/list_items.blade.php +++ b/app/system/views/updates/list_items.blade.php @@ -1,11 +1,35 @@
@foreach ($items as $item)
-
- +
+ @if ($item['type'] === 'core') + + + + + + + + + + + + + + + + + @else + + @endif
{{ $item['name'] }} @@ -17,34 +41,46 @@ class="extension-icon rounded" @endif
-
- @if ($ignored) - - @else - - @endif -
+ @if ($item['type'] === 'core') +
+ @else +
+ @if ($ignored) + + @else + + @endif +
+ @endif
+ @if ($item['type'] === 'core') +
@lang('system::lang.updates.text_core_update')
+ @endif @endforeach
From 80c657b5b5781ba6840f45ff4fdc3dc70151c1a6 Mon Sep 17 00:00:00 2001 From: Sam Poyigi <6567634+sampoyigi@users.noreply.github.com> Date: Thu, 23 Sep 2021 00:02:22 +0100 Subject: [PATCH 03/24] Drop support for PHP 7.3 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 84eabbd04e..7ac0fbca0d 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ "source": "https://github.com/tastyigniter/TastyIgniter" }, "require": { - "php": ">=7.3", + "php": ">=7.4", "tastyigniter/flame": "~1.2", "laravel/framework": "~8.0" }, From 26989a6ae838f94a2267661469b5d493124df42d Mon Sep 17 00:00:00 2001 From: Sam Poyigi <6567634+sampoyigi@users.noreply.github.com> Date: Thu, 23 Sep 2021 00:09:24 +0100 Subject: [PATCH 04/24] Drop support for PHP 7.3 --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b005d7e0d8..7874cac470 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -16,7 +16,7 @@ jobs: max-parallel: 6 matrix: # os: [ubuntu-latest, windows-latest] - php: ['7.3', '7.4'] + php: ['7.4', '8.0'] db: ['mysql:5.7', mariadb] include: - db: 'mysql:5.7' From 46949b34f9ec31008fd85568610293b1635919e9 Mon Sep 17 00:00:00 2001 From: Ryan Mitchell Date: Thu, 23 Sep 2021 13:32:38 +0100 Subject: [PATCH 05/24] Allow filtering by location status, hasDelivery or hasCollection (#853) * Allow filtering by order type and delivery area If orderTypes param is passed then make sure the locations offer it. If searchDeliveryAreas is passed then filter locations by whether they deliver to those coordinates * Move filter logic to localList component Co-authored-by: Sam Poyigi <6567634+sampoyigi@users.noreply.github.com> --- app/admin/models/Locations_model.php | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/app/admin/models/Locations_model.php b/app/admin/models/Locations_model.php index d111ea7c66..435f50503a 100644 --- a/app/admin/models/Locations_model.php +++ b/app/admin/models/Locations_model.php @@ -131,13 +131,17 @@ public function scopeIsEnabled($query) public function scopeListFrontEnd($query, array $options = []) { - extract(array_merge([ + extract($options = array_merge([ 'page' => 1, 'pageLimit' => 20, 'sort' => null, 'search' => null, + 'enabled' => null, 'latitude' => null, 'longitude' => null, + 'paginate' => TRUE, + 'hasDelivery' => null, + 'hasCollection' => null, ], $options)); if ($latitude AND $longitude) { @@ -171,8 +175,20 @@ public function scopeListFrontEnd($query, array $options = []) $query->search($search, $searchableFields); } + if (!is_null($enabled)) + $query->where('location_status', $enabled); + + if (!is_null($hasDelivery)) + $query->where('options->offer_delivery', $hasDelivery); + + if (!is_null($hasCollection)) + $query->where('options->offer_collection', $hasCollection); + $this->fireEvent('model.extendListFrontEndQuery', [$query]); + if (is_null($pageLimit)) + return $query; + return $query->paginate($pageLimit, $page); } From fd399d8fef4f934eff35268a890c30ed29925ca8 Mon Sep 17 00:00:00 2001 From: Sam Poyigi <6567634+sampoyigi@users.noreply.github.com> Date: Thu, 23 Sep 2021 13:30:04 +0100 Subject: [PATCH 06/24] Bring back getAction and getClass methods on AdminController Signed-off-by: Sam Poyigi <6567634+sampoyigi@users.noreply.github.com> --- app/admin/classes/AdminController.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/admin/classes/AdminController.php b/app/admin/classes/AdminController.php index 9eb05f0ec8..cc529eeed0 100644 --- a/app/admin/classes/AdminController.php +++ b/app/admin/classes/AdminController.php @@ -256,6 +256,16 @@ public function pageAction() $this->execPageAction($this->action, $this->params); } + public function getClass() + { + return $this->class; + } + + public function getAction() + { + return $this->action; + } + protected function execPageAction($action, $params) { $result = null; From 464943bf09eee80fd5562b2af3c6d43b217b0cf0 Mon Sep 17 00:00:00 2001 From: Sam Poyigi <6567634+sampoyigi@users.noreply.github.com> Date: Fri, 24 Sep 2021 08:18:08 +0100 Subject: [PATCH 07/24] Improved password reset flow by no longer throwing an error if the provided email address doesn't exist. Signed-off-by: Sam Poyigi <6567634+sampoyigi@users.noreply.github.com> --- app/admin/controllers/Login.php | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/app/admin/controllers/Login.php b/app/admin/controllers/Login.php index 846dd8aaec..f91b3f47f4 100644 --- a/app/admin/controllers/Login.php +++ b/app/admin/controllers/Login.php @@ -85,24 +85,21 @@ public function onRequestResetPassword() $data = post(); $this->validate($data, [ - ['email', 'lang:admin::lang.label_email', 'required|email:filter|max:96|exists:staffs,staff_email'], + ['email', 'lang:admin::lang.label_email', 'required|email:filter|max:96'], ]); $staff = Staffs_model::whereStaffEmail(post('email'))->first(); - if (!$staff OR !$user = $staff->user) - throw new ValidationException(['email' => lang('admin::lang.login.alert_email_not_sent')]); - - if (!$user->resetPassword()) - throw new ValidationException(['email' => lang('admin::lang.login.alert_failed_reset')]); - - $data = [ - 'staff_name' => $staff->staff_name, - 'reset_link' => admin_url('login/reset?code='.$user->reset_code), - ]; - - Mail::queue('admin::_mail.password_reset_request', $data, function ($message) use ($staff) { - $message->to($staff->staff_email, $staff->staff_name); - }); + if ($staff AND $user = $staff->user) { + if (!$user->resetPassword()) + throw new ValidationException(['email' => lang('admin::lang.login.alert_failed_reset')]); + $data = [ + 'staff_name' => $staff->staff_name, + 'reset_link' => admin_url('login/reset?code='.$user->reset_code), + ]; + Mail::queue('admin::_mail.password_reset_request', $data, function ($message) use ($staff) { + $message->to($staff->staff_email, $staff->staff_name); + }); + } flash()->success(lang('admin::lang.login.alert_email_sent')); From ae0a53295bbfd956ec539810989d6a1b1c9b2aeb Mon Sep 17 00:00:00 2001 From: Sam Poyigi <6567634+sampoyigi@users.noreply.github.com> Date: Fri, 24 Sep 2021 08:51:29 +0100 Subject: [PATCH 08/24] Enable "Customize" button for only the currently active theme Signed-off-by: Sam Poyigi <6567634+sampoyigi@users.noreply.github.com> --- app/system/views/themes/lists/list_buttons.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/system/views/themes/lists/list_buttons.blade.php b/app/system/views/themes/lists/list_buttons.blade.php index d497b103d7..2b2c21fd04 100644 --- a/app/system/views/themes/lists/list_buttons.blade.php +++ b/app/system/views/themes/lists/list_buttons.blade.php @@ -1,6 +1,6 @@ {!! $this->makePartial('lists/list_button', ['record' => $theme, 'column' => $this->getColumn('source')]) !!} -@if ($theme->getTheme()->hasCustomData()) +@if ($theme->getTheme()->isActive() AND $theme->getTheme()->hasCustomData()) {!! $this->makePartial('lists/list_button', ['record' => $theme, 'column' => $this->getColumn('edit')]) !!} @endif From 205576113bbf233b37fc6213a3cfcceb818122b5 Mon Sep 17 00:00:00 2001 From: Sam Poyigi <6567634+sampoyigi@users.noreply.github.com> Date: Sat, 25 Sep 2021 09:13:59 +0100 Subject: [PATCH 09/24] Move search/browse marketplace feature to themes and extension controllers --- app/admin/assets/css/admin.css | 15 +- .../assets/scss/components/_toolbar.scss | 3 + app/system/assets/ui/js/updates.js | 28 +- app/system/controllers/Extensions.php | 4 + app/system/controllers/Themes.php | 4 + app/system/controllers/Updates.php | 329 +----------------- app/system/language/en/lang.php | 18 +- app/system/models/config/extensions_model.php | 7 +- app/system/models/config/themes_model.php | 5 +- app/system/traits/ManagesUpdates.php | 308 ++++++++++++++++ app/system/views/extensions/index.blade.php | 9 +- .../views/extensions/lists/list.blade.php | 4 +- app/system/views/themes/index.blade.php | 6 +- app/system/views/themes/lists/list.blade.php | 2 + .../views/updates/browse/extension.blade.php | 35 -- .../views/updates/browse/index.blade.php | 25 -- .../views/updates/browse/list.blade.php | 9 - .../views/updates/browse/theme.blade.php | 32 -- .../views/updates/list_recommended.blade.php | 63 ++++ .../views/updates/recommended.blade.php | 16 + app/system/views/updates/search.blade.php | 35 +- 21 files changed, 478 insertions(+), 479 deletions(-) create mode 100644 app/system/traits/ManagesUpdates.php delete mode 100644 app/system/views/updates/browse/extension.blade.php delete mode 100644 app/system/views/updates/browse/index.blade.php delete mode 100644 app/system/views/updates/browse/list.blade.php delete mode 100644 app/system/views/updates/browse/theme.blade.php create mode 100644 app/system/views/updates/list_recommended.blade.php create mode 100644 app/system/views/updates/recommended.blade.php diff --git a/app/admin/assets/css/admin.css b/app/admin/assets/css/admin.css index 719b847406..5e1b775440 100644 --- a/app/admin/assets/css/admin.css +++ b/app/admin/assets/css/admin.css @@ -1,8 +1,8 @@ +@charset "UTF-8"; /*! * Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) */ -@charset "UTF-8"; .fa, .fas, .far, .fa-star-o, .fal, .fad, .fab { -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; @@ -10755,12 +10755,12 @@ a.btn.disabled, fieldset:disabled a.btn { } .btn-info:hover { color: #FFFFFF; - background-color: #3b4bd1; + background-color: #3b4ad1; border-color: #3141ce; } .btn-info:focus, .btn-info.focus { color: #FFFFFF; - background-color: #3b4bd1; + background-color: #3b4ad1; border-color: #3141ce; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 3, 41, 0.075) 0 0 0 0.2rem rgba(115, 126, 222, 0.5); } @@ -16561,7 +16561,7 @@ a.text-success:hover, a.panel-success:hover, a.text-success:focus, a.panel-succe color: #5A67D8 !important; } a.text-info:hover, a.panel-info:hover, a.text-info:focus, a.panel-info:focus { - color: #2c3bba !important; + color: #2c3aba !important; } .text-warning, .panel-warning { color: #FD7E14 !important; @@ -18317,12 +18317,12 @@ body.dragging .dragged { } .toolbar-action .btn-info:hover { color: #FFFFFF; - background-color: #3b4bd1; + background-color: #3b4ad1; border-color: #3141ce; } .toolbar-action .btn-info:focus, .toolbar-action .btn-info.focus { color: #FFFFFF; - background-color: #3b4bd1; + background-color: #3b4ad1; border-color: #3141ce; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 3, 41, 0.075) 0 0 0 0.2rem rgba(133, 143, 171, 0.5); } @@ -18735,6 +18735,9 @@ body.dragging .dragged { .toolbar-action .btn-outline-white:not(:disabled):not(.disabled):active:focus, .toolbar-action .btn-outline-white:not(:disabled):not(.disabled).active:focus, .show > .toolbar-action .btn-outline-white.dropdown-toggle:focus { box-shadow: 0 0 0 0.2rem rgba(111, 123, 156, 0.5); } +.toolbar-search { + background-color: #D2D4DF; +} .list-table .table thead, .list-table .markdown table thead, .markdown .list-table table thead { position: relative; } diff --git a/app/admin/assets/scss/components/_toolbar.scss b/app/admin/assets/scss/components/_toolbar.scss index c65c3cd2b5..5c432bd631 100644 --- a/app/admin/assets/scss/components/_toolbar.scss +++ b/app/admin/assets/scss/components/_toolbar.scss @@ -104,3 +104,6 @@ } } } +.toolbar-search { + background-color: $gray-300; +} diff --git a/app/system/assets/ui/js/updates.js b/app/system/assets/ui/js/updates.js index 745f5deab6..d86237f2e7 100644 --- a/app/system/assets/ui/js/updates.js +++ b/app/system/assets/ui/js/updates.js @@ -40,6 +40,8 @@ $(document).on('click', '#update-carte', $.proxy(this.onUpdateCarteClick, this)) + $(document).on('click', '[data-control="apply-recommended"]', $.proxy(this.onApplyRecommended, this)) + $(document).on('click', '#apply-updates', $.proxy(this.onApplyUpdateClick, this)) $(document).on('click', '[data-control="apply-install"]', $.proxy(this.onApplyInstallClick, this)) @@ -65,7 +67,7 @@ requestChain.push(function () { var deferred = $.Deferred() - $.request('onProcess', { + $.request('onProcessItems', { data: {step: group, meta: step}, beforeSend: self.setProgressBar(step.label, 'primary'), success: function (json) { @@ -257,7 +259,7 @@ $button.attr('disable', true).addClass('disabled') - $.request('onApply', { + $.request('onApplyItems', { data: {items: this.options.itemsToApply} }).always(function () { $button.attr('disable', false).removeClass('disabled') @@ -290,7 +292,7 @@ }) }) - $.request('onApply', { + $.request('onApplyUpdate', { data: {items: this.options.itemsToApply} }).always(function () { $button.attr('disable', false).removeClass('disabled') @@ -324,6 +326,22 @@ }) } + Updates.prototype.onApplyRecommended = function (event) { + var self = this, + $button = $(event.currentTarget), + $modal = $button.closest('.modal'), + $form = $button.closest('form') + + $button.attr('disabled', true) + + $form.request('onApplyItems').always(function () { + $modal.modal('hide') + }).done(function (json) { + if (json['steps']) + self.executeSteps(json['steps']) + }) + } + Updates.prototype.bindSearch = function (field) { var self = this, $field = $(field), @@ -491,7 +509,7 @@ $.fn.updates.Constructor = Updates $(document).render(function () { - $('#list-items').updates() + $('.page-content').updates() }) -}(jQuery) \ No newline at end of file +}(jQuery) diff --git a/app/system/controllers/Extensions.php b/app/system/controllers/Extensions.php index aca5109960..5ed48a1897 100644 --- a/app/system/controllers/Extensions.php +++ b/app/system/controllers/Extensions.php @@ -9,6 +9,7 @@ use Igniter\Flame\Exception\ApplicationException; use Igniter\Flame\Exception\SystemException; use Illuminate\Support\Facades\Request; +use System\Traits\ManagesUpdates; use System\Classes\ExtensionManager; use System\Models\Extensions_model; use System\Models\Settings_model; @@ -16,6 +17,7 @@ class Extensions extends \Admin\Classes\AdminController { use WidgetMaker; + use ManagesUpdates; public $implement = [ 'Admin\Actions\ListController', @@ -59,6 +61,8 @@ public function index() Extensions_model::syncAll(); + $this->initUpdate('extension'); + $this->asExtension('ListController')->index(); } diff --git a/app/system/controllers/Themes.php b/app/system/controllers/Themes.php index 583ec53843..fd9ecdfcc9 100644 --- a/app/system/controllers/Themes.php +++ b/app/system/controllers/Themes.php @@ -15,6 +15,7 @@ use System\Libraries\Assets as AssetsManager; use System\Models\Themes_model; use System\Traits\ConfigMaker; +use System\Traits\ManagesUpdates; use System\Traits\SessionMaker; class Themes extends \Admin\Classes\AdminController @@ -22,6 +23,7 @@ class Themes extends \Admin\Classes\AdminController use WidgetMaker; use ConfigMaker; use SessionMaker; + use ManagesUpdates; public $implement = [ 'Admin\Actions\ListController', @@ -71,6 +73,8 @@ public function index() { Themes_model::syncAll(); + $this->initUpdate('theme'); + $this->asExtension('ListController')->index(); } diff --git a/app/system/controllers/Updates.php b/app/system/controllers/Updates.php index 04bafe0ec2..476cd73534 100644 --- a/app/system/controllers/Updates.php +++ b/app/system/controllers/Updates.php @@ -5,15 +5,15 @@ use Admin\Facades\AdminMenu; use Admin\Facades\Template; use Exception; -use Igniter\Flame\Exception\ApplicationException; -use Main\Classes\ThemeManager; -use System\Classes\ExtensionManager; use System\Classes\UpdateManager; use System\Models\Extensions_model; use System\Models\Themes_model; +use System\Traits\ManagesUpdates; class Updates extends \Admin\Classes\AdminController { + use ManagesUpdates; + public $checkUrl = 'updates'; public $browseUrl = 'updates/browse'; @@ -36,7 +36,6 @@ public function index() Template::setTitle($pageTitle); Template::setHeading($pageTitle); - Template::setButton(sprintf(lang('system::lang.updates.button_browse'), 'extensions'), ['class' => 'btn btn-primary', 'href' => admin_url($this->browseUrl.'/extensions')]); Template::setButton(lang('system::lang.updates.button_check'), ['class' => 'btn btn-success', 'data-request' => 'onCheckUpdates']); Template::setButton(lang('system::lang.updates.button_carte'), ['class' => 'btn btn-default pull-right', 'role' => 'button', 'data-target' => '#carte-modal', 'data-toggle' => 'modal']); @@ -71,332 +70,10 @@ public function index() } } - public function browse($context, $itemType = null) - { - if (!in_array($itemType, ['themes', 'extensions'])) - return $this->redirectBack(); - - $updateManager = UpdateManager::instance(); - - $pageTitle = lang('system::lang.updates.text_tab_title_'.$itemType); - Template::setTitle(sprintf(lang('system::lang.updates.text_browse_title'), $pageTitle)); - Template::setHeading(sprintf(lang('system::lang.updates.text_browse_title'), $pageTitle)); - - $buttonType = ($itemType == 'extensions') ? 'themes' : 'extensions'; - $buttonTitle = lang('system::lang.updates.text_tab_title_'.$buttonType); - - Template::setButton(sprintf(lang('system::lang.updates.button_browse'), $buttonTitle), ['class' => 'btn btn-primary', 'href' => admin_url($this->browseUrl.'/'.$buttonType)]); - Template::setButton(lang('system::lang.updates.button_updates'), ['class' => 'btn btn-success', 'href' => admin_url($this->checkUrl)]); - Template::setButton(lang('system::lang.updates.button_carte'), ['class' => 'btn btn-default pull-right', 'role' => 'button', 'data-target' => '#carte-modal', 'data-toggle' => 'modal']); - - $this->prepareAssets(); - - $this->vars['searchActionUrl'] = admin_url('updates/search'); - $this->vars['itemType'] = str_singular($itemType); - $this->vars['carteInfo'] = $updateManager->getSiteDetail(); - $this->vars['installedItems'] = $updateManager->getInstalledItems(); - - return $this->makeView('browse/index'); - } - - public function search() - { - $json = []; - - if ($filter = input('filter') AND is_array($filter)) { - $itemType = $filter['type'] ?? 'extension'; - $searchQuery = isset($filter['search']) ? strtolower($filter['search']) : ''; - - try { - $json = UpdateManager::instance()->searchItems($itemType, $searchQuery); - } - catch (Exception $ex) { - $json = $ex->getMessage(); - } - } - - return $json; - } - protected function prepareAssets() { $this->addJs('ui/js/vendor/mustache.js', 'mustache-js'); $this->addJs('ui/js/vendor/typeahead.js', 'typeahead-js'); $this->addJs('ui/js/updates.js', 'updates-js'); } - - public function index_onCheckUpdates() - { - $updateManager = UpdateManager::instance(); - $updateManager->requestUpdateList(TRUE); - - return $this->redirect($this->checkUrl); - } - - public function index_onApplyCarte() - { - return $this->applyCarte(); - } - - public function index_onApply($context = null) - { - return $this->applyInstallOrUpdate($context); - } - - public function index_onIgnoreUpdate() - { - $items = post('items'); - if (!$items OR count($items) < 1) - throw new ApplicationException(lang('system::lang.updates.alert_item_to_ignore')); - - $updateManager = UpdateManager::instance(); - - $updateManager->ignoreUpdates($items); - - $updates = $updateManager->requestUpdateList(input('check') == 'force'); - - return [ - '#updates' => $this->makePartial('updates/list', ['updates' => $updates]), - ]; - } - - public function index_onProcess() - { - return $this->processInstallOrUpdate(); - } - - public function browse_onFetchItems() - { - $itemType = post('type'); - $items = UpdateManager::instance()->listItems($itemType); - - return [ - '#list-items' => $this->makePartial('browse/list', [ - 'items' => $items, - 'itemType' => $itemType, - ]), - ]; - } - - public function browse_onApplyCarte() - { - return $this->applyCarte(); - } - - public function browse_onApply($context = null) - { - return $this->applyInstallOrUpdate($context); - } - - public function browse_onProcess() - { - return $this->processInstallOrUpdate(); - } - - protected function applyCarte() - { - $carteKey = post('carte_key'); - if (!strlen($carteKey)) - throw new ApplicationException(lang('system::lang.updates.alert_no_carte_key')); - - $response = UpdateManager::instance()->applySiteDetail($carteKey); - - return [ - '#carte-details' => $this->makePartial('updates/carte_info', ['carteInfo' => $response]), - ]; - } - - protected function applyInstallOrUpdate($context) - { - $items = input('items') ?? []; - - if (!count($items)) - throw new ApplicationException(lang('system::lang.updates.alert_no_items')); - - $this->validateItems(); - - if ($context == 'index') { - $updates = UpdateManager::instance()->requestUpdateList(input('check') == 'force'); - $response['data'] = array_get($updates, 'items'); - } - else { - $response = UpdateManager::instance()->requestApplyItems($items); - } - - return [ - 'steps' => $this->buildProcessSteps($response, $items), - ]; - } - - protected function buildProcessSteps($meta, $params = []) - { - $processSteps = []; - if (!count($meta['data'])) - return $processSteps; - - foreach (['download', 'extract', 'complete'] as $step) { - // Silly way to sort the process - $applySteps = [ - 'core' => [], - 'extensions' => [], - 'themes' => [], - 'translations' => [], - ]; - - if ($step == 'complete') { - $processSteps[$step][] = [ - 'items' => $meta['data'], - 'process' => $step, - 'label' => lang("system::lang.updates.progress_{$step}"), - 'success' => sprintf(lang('system::lang.updates.progress_success'), rtrim($step, 'e').'ing', ''), - ]; - - continue; - } - - foreach (array_get($meta, 'data') as $item) { - if ($item['type'] == 'core') { - $applySteps['core'][] = array_merge([ - 'action' => 'update', - 'process' => "{$step}Core", - 'label' => sprintf(lang("system::lang.updates.progress_{$step}"), $item['name'].' update'), - 'success' => sprintf(lang('system::lang.updates.progress_success'), $step.'ing', $item['name']), - ], $item); - } - else { - $singularType = str_singular($item['type']); - $pluralType = str_plural($item['type']); - - $action = $this->getActionFromItems($item['code'], $params); - $applySteps[$pluralType][] = array_merge([ - 'action' => $action, - 'process' => $step.ucfirst($singularType), - 'label' => sprintf(lang("system::lang.updates.progress_{$step}"), "{$item['name']} {$singularType}"), - 'success' => sprintf(lang('system::lang.updates.progress_success'), $step.'ing', $item['name']), - ], $item); - } - } - - $processSteps[$step] = array_collapse(array_values($applySteps)); - } - - return $processSteps; - } - - protected function processInstallOrUpdate() - { - $json = []; - - $this->validateProcess(); - - $meta = post('meta'); - - $params = []; - if (post('step') != 'complete') { - $params = !isset($meta['code']) ? [] : [ - 'name' => $meta['code'], - 'type' => $meta['type'], - 'ver' => $meta['version'], - 'action' => $meta['action'], - ]; - } - - $updateManager = UpdateManager::instance(); - - $processMeta = $meta['process']; - switch ($processMeta) { - case 'downloadCore': - case 'downloadExtension': - case 'downloadTheme': - $result = $updateManager->downloadFile($meta['code'], $meta['hash'], $params); - if ($result) $json['result'] = 'success'; - break; - - case 'extractCore': - $response = $updateManager->extractCore($meta['code']); - if ($response) $json['result'] = 'success'; - break; - - case 'extractExtension': - $response = $updateManager->extractFile($meta['code'], extension_path('/')); - if ($response) $json['result'] = 'success'; - break; - case 'extractTheme': - $response = $updateManager->extractFile($meta['code'], theme_path('/')); - if ($response) $json['result'] = 'success'; - break; - - case 'complete': - $response = $this->completeProcess($meta['items']); - if ($response) $json['result'] = 'success'; - break; - } - - return $json; - } - - protected function completeProcess($items) - { - if (!count($items)) - return FALSE; - - $updateManager = UpdateManager::instance(); - - foreach ($items as $item) { - switch ($item['type']) { - case 'core': - $updateManager->update(); - $updateManager->setCoreVersion($item['version'], $item['hash']); - break; - case 'extension': - ExtensionManager::instance()->installExtension($item['code'], $item['version']); - break; - case 'theme': - ThemeManager::instance()->installTheme($item['code'], $item['version']); - break; - } - } - - return TRUE; - } - - protected function getActionFromItems($code, $itemNames) - { - foreach ($itemNames as $itemName) { - if ($code == $itemName['name']) - return $itemName['action']; - } - } - - protected function validateItems() - { - $rules = [ - ['items.*.name', 'lang:system::lang.updates.label_meta_code', 'required'], - ['items.*.type', 'lang:system::lang.updates.label_meta_type', 'required|in:extension,theme,language'], - ['items.*.ver', 'lang:system::lang.updates.label_meta_version', 'required'], - ['items.*.action', 'lang:system::lang.updates.label_meta_action', 'required|in:install,update'], - ]; - - return $this->validatePasses(post(), $rules); - } - - protected function validateProcess() - { - $rules = []; - if (post('step') != 'complete') { - $rules[] = ['meta.code', 'lang:system::lang.updates.label_meta_code', 'required']; - $rules[] = ['meta.type', 'lang:system::lang.updates.label_meta_type', 'required']; - $rules[] = ['meta.version', 'lang:system::lang.updates.label_meta_version', 'required']; - $rules[] = ['meta.hash', 'lang:system::lang.updates.label_meta_hash', 'required']; - $rules[] = ['meta.description', 'lang:system::lang.updates.label_meta_description', 'sometimes']; - $rules[] = ['meta.action', 'lang:system::lang.updates.label_meta_action', 'required|in:install,update']; - } - else { - $rules[] = ['meta.items', 'lang:system::lang.updates.label_meta_items', 'required|array']; - } - - $rules[] = ['step', 'lang:system::lang.updates.label_meta_step', 'required|in:download,extract,complete']; - - return $this->validatePasses(post(), $rules); - } } diff --git a/app/system/language/en/lang.php b/app/system/language/en/lang.php index 8511737b5e..6a7e5fd517 100644 --- a/app/system/language/en/lang.php +++ b/app/system/language/en/lang.php @@ -126,8 +126,7 @@ 'text_settings' => 'Settings', 'text_author' => 'Author', - 'button_browse' => '  Browse more extensions', - 'button_check' => '  Updates', + 'button_browse' => '  Browse more extensions  ', 'button_delete' => 'Delete', 'button_payments' => 'Manage Payments', 'button_settings' => 'Manage Settings', @@ -570,9 +569,8 @@ 'label_type_layout' => 'Layouts', 'label_type_content' => 'Contents', - 'button_browse' => '  Browse more themes', + 'button_browse' => '  Browse more themes  ', 'button_source' => '  Edit template files', - 'button_check' => '  Updates', 'button_customize' => '  Customize', 'button_child' => '  Create child theme', 'button_choose' => 'Choose', @@ -605,7 +603,7 @@ 'text_tab_title_extensions' => 'Extensions', 'text_tab_title_themes' => 'Themes', 'text_ignore' => 'Ignore', - 'text_search' => 'Search the marketplace for %s to install', + 'text_search' => 'Search the TastyIgniter marketplace for %s to install', 'text_popular_title' => 'Recommended %s', 'text_last_checked' => 'Last checked: %s', @@ -636,13 +634,15 @@ 'progress_disable_maintenance' => 'Restoring/Disabling Maintenance mode…', 'button_browse' => '  Browse %s', - 'button_carte' => '  Carté', - 'button_check' => '  Check Again', + 'button_carte' => '  Attach Carté Key', + 'button_check' => '  Check Updates', 'button_updates' => '  Updates', 'button_update' => '  Update', - 'button_marketplace' => 'Open TastyIgniter Marketplace  ', + 'button_recommended_extension' => 'Install recommended extensions...', + 'button_recommended_theme' => 'Install a recommended theme...', + 'button_install' => 'Install Selected...', - 'help_carte_key' => 'A Carte key is required to add and update item from the TastyIgniter Marketplace. Get one by creating a site from your TastyIgniter Account, if you haven\'t already. For more information, see the Carté Key Guide', + 'help_carte_key' => 'A Carte key is required to add and update item from the TastyIgniter Marketplace.
Get one by creating a site from your TastyIgniter Account, if you haven\'t already. For more information, see the Carté Key Guide', 'alert_item_to_ignore' => 'Select item(s) to ignore.', 'alert_no_carte_key' => 'No carte key specified.', 'alert_no_items' => 'No item(s) specified.', diff --git a/app/system/models/config/extensions_model.php b/app/system/models/config/extensions_model.php index 0a156c8e2a..d6e1a9f7e5 100644 --- a/app/system/models/config/extensions_model.php +++ b/app/system/models/config/extensions_model.php @@ -11,16 +11,17 @@ 'browse' => [ 'label' => 'lang:system::lang.extensions.button_browse', 'class' => 'btn btn-primary', - 'href' => 'updates/browse/extensions', + 'href' => 'https://tastyigniter.com/marketplace', + 'target' => '_blank', ], 'check' => [ - 'label' => 'lang:system::lang.extensions.button_check', + 'label' => 'lang:system::lang.updates.button_check', 'class' => 'btn btn-success', 'href' => 'updates', ], 'filter' => [ 'label' => 'lang:admin::lang.button_icon_filter', - 'class' => 'btn btn-default btn-filter', + 'class' => 'btn btn-default btn-filter pull-right', 'data-toggle' => 'list-filter', 'data-target' => '.list-filter', ], diff --git a/app/system/models/config/themes_model.php b/app/system/models/config/themes_model.php index 68fff0a573..82855f779a 100644 --- a/app/system/models/config/themes_model.php +++ b/app/system/models/config/themes_model.php @@ -4,10 +4,11 @@ 'browse' => [ 'label' => 'lang:system::lang.themes.button_browse', 'class' => 'btn btn-primary', - 'href' => 'updates/browse/themes', + 'href' => 'https://tastyigniter.com/marketplace', + 'target' => '_blank', ], 'check' => [ - 'label' => 'lang:system::lang.themes.button_check', + 'label' => 'lang:system::lang.updates.button_check', 'class' => 'btn btn-success', 'href' => 'updates', ], diff --git a/app/system/traits/ManagesUpdates.php b/app/system/traits/ManagesUpdates.php new file mode 100644 index 0000000000..9ac98bd4b0 --- /dev/null +++ b/app/system/traits/ManagesUpdates.php @@ -0,0 +1,308 @@ +searchItems($itemType, $searchQuery); + } + catch (Exception $ex) { + $json = $ex->getMessage(); + } + } + + return $json; + } + + public function onApplyItems() + { + $items = post('items') ?? []; + $itemsCodes = post('install_items') ?? []; + if (!count($items) OR !count($itemsCodes)) + throw new ApplicationException(lang('system::lang.updates.alert_no_items')); + + $this->validateItems(); + + $items = collect($items)->whereIn('name', $itemsCodes)->all(); + + $response = UpdateManager::instance()->requestApplyItems($items); + $response = array_get($response, 'data', []); + + return [ + 'steps' => $this->buildProcessSteps($response, $items), + ]; + } + + public function onApplyUpdate() + { + $items = post('items') ?? []; + if (!count($items)) + throw new ApplicationException(lang('system::lang.updates.alert_no_items')); + + $this->validateItems(); + + $updates = UpdateManager::instance()->requestUpdateList(input('check') == 'force'); + $response = array_get($updates, 'items'); + + return [ + 'steps' => $this->buildProcessSteps($response, $items), + ]; + } + + public function onLoadRecommended() + { + $itemType = post('itemType'); + $items = (in_array($itemType, ['theme', 'extension'])) + ? UpdateManager::instance()->listItems($itemType) + : []; + + return $this->makePartial('updates/list_recommended', [ + 'items' => $items, + 'itemType' => $itemType, + ]); + } + + public function onCheckUpdates() + { + $updateManager = UpdateManager::instance(); + $updateManager->requestUpdateList(TRUE); + + return $this->redirect($this->checkUrl); + } + + public function onIgnoreUpdate() + { + $items = post('items'); + if (!$items OR count($items) < 1) + throw new ApplicationException(lang('system::lang.updates.alert_item_to_ignore')); + + $updateManager = UpdateManager::instance(); + + $updateManager->ignoreUpdates($items); + + $updates = $updateManager->requestUpdateList(input('check') == 'force'); + + return [ + '#updates' => $this->makePartial('updates/list', ['updates' => $updates]), + ]; + } + + public function onApplyCarte() + { + $carteKey = post('carte_key'); + if (!strlen($carteKey)) + throw new ApplicationException(lang('system::lang.updates.alert_no_carte_key')); + + $response = UpdateManager::instance()->applySiteDetail($carteKey); + + return [ + '#carte-details' => $this->makePartial('updates/carte_info', ['carteInfo' => $response]), + ]; + } + + public function onProcessItems() + { + return $this->processInstallOrUpdate(); + } + + // + // + // + + protected function initUpdate($itemType) + { + $this->addJs('ui/js/vendor/mustache.js', 'mustache-js'); + $this->addJs('ui/js/vendor/typeahead.js', 'typeahead-js'); + $this->addJs('ui/js/updates.js', 'updates-js'); + $this->addJs('~/app/admin/formwidgets/recordeditor/assets/js/recordeditor.modal.js', 'recordeditor-modal-js'); + + $updateManager = UpdateManager::instance(); + + $this->vars['itemType'] = $itemType; + $this->vars['carteInfo'] = $updateManager->getSiteDetail(); + $this->vars['installedItems'] = $updateManager->getInstalledItems(); + } + + protected function buildProcessSteps($response, $params = []) + { + $processSteps = []; + foreach (['download', 'extract', 'complete'] as $step) { + // Silly way to sort the process + $applySteps = [ + 'core' => [], + 'extensions' => [], + 'themes' => [], + 'translations' => [], + ]; + + if ($step == 'complete') { + $processSteps[$step][] = [ + 'items' => $response, + 'process' => $step, + 'label' => lang("system::lang.updates.progress_{$step}"), + 'success' => sprintf(lang('system::lang.updates.progress_success'), rtrim($step, 'e').'ing', ''), + ]; + + continue; + } + + foreach ($response as $item) { + if ($item['type'] == 'core') { + $applySteps['core'][] = array_merge([ + 'action' => 'update', + 'process' => "{$step}Core", + 'label' => sprintf(lang("system::lang.updates.progress_{$step}"), $item['name'].' update'), + 'success' => sprintf(lang('system::lang.updates.progress_success'), $step.'ing', $item['name']), + ], $item); + } + else { + $singularType = str_singular($item['type']); + $pluralType = str_plural($item['type']); + + $action = $this->getActionFromItems($item['code'], $params); + $applySteps[$pluralType][] = array_merge([ + 'action' => $action ?? 'install', + 'process' => $step.ucfirst($singularType), + 'label' => sprintf(lang("system::lang.updates.progress_{$step}"), "{$item['name']} {$singularType}"), + 'success' => sprintf(lang('system::lang.updates.progress_success'), $step.'ing', $item['name']), + ], $item); + } + } + + $processSteps[$step] = array_collapse(array_values($applySteps)); + } + + return $processSteps; + } + + protected function processInstallOrUpdate() + { + $json = []; + + $this->validateProcess(); + + $meta = post('meta'); + + $params = []; + if (post('step') != 'complete') { + $params = !isset($meta['code']) ? [] : [ + 'name' => $meta['code'], + 'type' => $meta['type'], + 'ver' => $meta['version'], + 'action' => $meta['action'], + ]; + } + + $updateManager = UpdateManager::instance(); + + $processMeta = $meta['process']; + switch ($processMeta) { + case 'downloadCore': + case 'downloadExtension': + case 'downloadTheme': + $result = $updateManager->downloadFile($meta['code'], $meta['hash'], $params); + if ($result) $json['result'] = 'success'; + break; + + case 'extractCore': + $response = $updateManager->extractCore($meta['code']); + if ($response) $json['result'] = 'success'; + break; + + case 'extractExtension': + $response = $updateManager->extractFile($meta['code'], extension_path('/')); + if ($response) $json['result'] = 'success'; + break; + case 'extractTheme': + $response = $updateManager->extractFile($meta['code'], theme_path('/')); + if ($response) $json['result'] = 'success'; + break; + + case 'complete': + $response = $this->completeProcess($meta['items']); + if ($response) $json['result'] = 'success'; + break; + } + + return $json; + } + + protected function completeProcess($items) + { + if (!count($items)) + return FALSE; + + foreach ($items as $item) { + switch ($item['type']) { + case 'core': + $updateManager = UpdateManager::instance(); + $updateManager->update(); + $updateManager->setCoreVersion($item['version'], $item['hash']); + break; + case 'extension': + ExtensionManager::instance()->installExtension($item['code'], $item['version']); + break; + case 'theme': + ThemeManager::instance()->installTheme($item['code'], $item['version']); + break; + } + } + + return TRUE; + } + + protected function getActionFromItems($code, $itemNames) + { + foreach ($itemNames as $itemName) { + if ($code == $itemName['name']) + return $itemName['action']; + } + } + + protected function validateItems() + { + $rules = [ + ['items.*.name', 'lang:system::lang.updates.label_meta_code', 'required'], + ['items.*.type', 'lang:system::lang.updates.label_meta_type', 'required|in:extension,theme,language'], + ['items.*.ver', 'lang:system::lang.updates.label_meta_version', 'required'], + ['items.*.action', 'lang:system::lang.updates.label_meta_action', 'required|in:install,update'], + ]; + + return $this->validate(post(), $rules); + } + + protected function validateProcess() + { + $rules = []; + if (post('step') != 'complete') { + $rules[] = ['meta.code', 'lang:system::lang.updates.label_meta_code', 'required']; + $rules[] = ['meta.type', 'lang:system::lang.updates.label_meta_type', 'required']; + $rules[] = ['meta.version', 'lang:system::lang.updates.label_meta_version', 'required']; + $rules[] = ['meta.hash', 'lang:system::lang.updates.label_meta_hash', 'required']; + $rules[] = ['meta.description', 'lang:system::lang.updates.label_meta_description', 'sometimes']; + $rules[] = ['meta.action', 'lang:system::lang.updates.label_meta_action', 'required|in:install,update']; + } + else { + $rules[] = ['meta.items', 'lang:system::lang.updates.label_meta_items', 'required|array']; + } + + $rules[] = ['step', 'lang:system::lang.updates.label_meta_step', 'required|in:download,extract,complete']; + + return $this->validate(post(), $rules); + } +} diff --git a/app/system/views/extensions/index.blade.php b/app/system/views/extensions/index.blade.php index 998ed6303e..fa884621c4 100644 --- a/app/system/views/extensions/index.blade.php +++ b/app/system/views/extensions/index.blade.php @@ -1,4 +1,9 @@
- {!! $this->renderList() !!} -
+ {!! $this->widgets['toolbar']->render() !!} + + {!! $this->makePartial('updates/search', ['itemType' => 'extension']) !!} + {!! $this->widgets['list_filter']->render() !!} + + {!! $this->widgets['list']->render() !!} +
diff --git a/app/system/views/extensions/lists/list.blade.php b/app/system/views/extensions/lists/list.blade.php index 8e0ac0a332..6b2f452b8b 100644 --- a/app/system/views/extensions/lists/list.blade.php +++ b/app/system/views/extensions/lists/list.blade.php @@ -6,7 +6,7 @@ ] ) !!} -
+
@if (count($records)) {!! $this->makePartial('lists/list_body') !!} @else @@ -19,3 +19,5 @@ {!! form_close() !!} {!! $this->makePartial('lists/list_pagination') !!} + +{!! $this->makePartial('updates/recommended', ['itemType' => 'extension']) !!} diff --git a/app/system/views/themes/index.blade.php b/app/system/views/themes/index.blade.php index 5dbd03bd48..9c815a3266 100644 --- a/app/system/views/themes/index.blade.php +++ b/app/system/views/themes/index.blade.php @@ -1,3 +1,7 @@
- {!! $this->renderList() !!} + {!! $this->widgets['toolbar']->render() !!} + + {!! $this->makePartial('updates/search', ['itemType' => 'theme']) !!} + + {!! $this->widgets['list']->render() !!}
diff --git a/app/system/views/themes/lists/list.blade.php b/app/system/views/themes/lists/list.blade.php index 4a79139434..3fdb990663 100644 --- a/app/system/views/themes/lists/list.blade.php +++ b/app/system/views/themes/lists/list.blade.php @@ -14,4 +14,6 @@ {!! form_close() !!} {!! $this->makePartial('lists/list_pagination') !!} + + {!! $this->makePartial('updates/recommended', ['itemType' => 'theme']) !!}
diff --git a/app/system/views/updates/browse/extension.blade.php b/app/system/views/updates/browse/extension.blade.php deleted file mode 100644 index 032b363693..0000000000 --- a/app/system/views/updates/browse/extension.blade.php +++ /dev/null @@ -1,35 +0,0 @@ - -
-
-
- @if (!empty($item['thumb'])) - No Image - @else - - @endif -
-
- {{ str_limit($item['name'], 22) }} -

{{ str_limit($item['description'], 128) }}

-
-
-
-
diff --git a/app/system/views/updates/browse/index.blade.php b/app/system/views/updates/browse/index.blade.php deleted file mode 100644 index f22c0d33cc..0000000000 --- a/app/system/views/updates/browse/index.blade.php +++ /dev/null @@ -1,25 +0,0 @@ -
- - {!! $this->widgets['toolbar']->render() !!} - - {!! $this->makePartial('updates/search') !!} - -
-
-
{{ sprintf(lang('system::lang.updates.text_popular_title'), ucwords(str_plural($itemType))) }}
-
- -
-

- -

-
-
-
- -{!! $this->makePartial('updates/carte') !!} diff --git a/app/system/views/updates/browse/list.blade.php b/app/system/views/updates/browse/list.blade.php deleted file mode 100644 index b1e73906ba..0000000000 --- a/app/system/views/updates/browse/list.blade.php +++ /dev/null @@ -1,9 +0,0 @@ -@if (isset($items) AND count($items)) -
- @foreach ($items['data'] as $item) -
- {!! $this->makePartial('updates/browse/'.$itemType, ['item' => $item]) !!} -
- @endforeach -
-@endif diff --git a/app/system/views/updates/browse/theme.blade.php b/app/system/views/updates/browse/theme.blade.php deleted file mode 100644 index f43ec26d53..0000000000 --- a/app/system/views/updates/browse/theme.blade.php +++ /dev/null @@ -1,32 +0,0 @@ -
- No Image -
- {{ str_limit($item['name'], 22) }} -

{{ str_limit($item['description'], 72) }}

-
-
- @if (!empty($item['installed'])) - - @else - - @endif -
-
diff --git a/app/system/views/updates/list_recommended.blade.php b/app/system/views/updates/list_recommended.blade.php new file mode 100644 index 0000000000..e9eab94d82 --- /dev/null +++ b/app/system/views/updates/list_recommended.blade.php @@ -0,0 +1,63 @@ + diff --git a/app/system/views/updates/recommended.blade.php b/app/system/views/updates/recommended.blade.php new file mode 100644 index 0000000000..c964f6664b --- /dev/null +++ b/app/system/views/updates/recommended.blade.php @@ -0,0 +1,16 @@ +
+
+ +
{!! sprintf(lang('system::lang.updates.help_carte_key'), 'https://tastyigniter.com/signin', 'https://tastyigniter.com/support/articles/carte-key') !!} +
+
+
diff --git a/app/system/views/updates/search.blade.php b/app/system/views/updates/search.blade.php index 38ed9b6496..5387bad94c 100644 --- a/app/system/views/updates/search.blade.php +++ b/app/system/views/updates/search.blade.php @@ -1,25 +1,14 @@ -