diff --git a/_build/config.json b/_build/config.json index d40bb1da..57c2259c 100644 --- a/_build/config.json +++ b/_build/config.json @@ -3,7 +3,7 @@ "lowCaseName": "fred", "description": "Frontend Editor", "author": "John Peca", - "version": "3.1.6-pl", + "version": "3.2.0-pl", "package": { "menus": [ { @@ -99,6 +99,11 @@ { "key": "lit", "value": "0" + }, + { + "key": "batch_size", + "value": "10", + "type": "numberfield" } ] }, diff --git a/_build/gpm.json b/_build/gpm.json index 78276d10..b92d7f1e 100644 --- a/_build/gpm.json +++ b/_build/gpm.json @@ -3,7 +3,7 @@ "lowCaseName": "fred", "description": "Frontend Editor", "author": "John Peca", - "version": "3.1.6-pl", + "version": "3.2.0-pl", "menus": [ { "text": "fred.menu.fred", @@ -95,6 +95,11 @@ { "key": "lit", "value": "0" + }, + { + "key": "batch_size", + "value": "10", + "type": "numberfield" } ], "database": { diff --git a/assets/components/fred/mgr/js/home/panel.js b/assets/components/fred/mgr/js/home/panel.js index dae3c810..bb9cb40c 100644 --- a/assets/components/fred/mgr/js/home/panel.js +++ b/assets/components/fred/mgr/js/home/panel.js @@ -228,35 +228,100 @@ Ext.extend(fred.panel.Home, MODx.Panel, { { html: '

' + _('fred.rebuild.rebuild_desc') + '


' }, + { + xtype: 'fred-combo-themes', + id: 'fred-rebuild-theme', + fieldLabel: _('fred.rebuild.theme'), + isUpdate: true, + addAll: 1, + width: 300, + allowBlank: true + }, { xtype: 'button', text: _('fred.rebuild.rebuild'), + style: 'margin-top: 10px', handler: function() { var topic = '/fred/mgr/generate/refresh/'; + var batchSize = MODx.config['fred.batch_size'] || 10; + var offset = 0; + var total = 0; + var themeCombo = Ext.getCmp('fred-rebuild-theme'); + var theme = themeCombo ? (themeCombo.getValue() || 0) : 0; - var console = MODx.load({ + var consoleWin = MODx.load({ xtype: 'modx-console', register: 'mgr', topic: topic, show_filename: 0 }); - console.show(Ext.getBody()); + consoleWin.show(Ext.getBody()); + + function processNextBatch() { + var isLast = (offset + batchSize) >= total; + MODx.Ajax.request({ + url: fred.config.connectorUrl, + params: { + action: 'Fred\\Processors\\Generate\\Refresh', + register: 'mgr', + topic: topic, + offset: offset, + limit: batchSize, + isLast: isLast ? 1 : 0, + theme: theme + }, + listeners: { + success: { + fn: function() { + offset += batchSize; + if (offset < total) { + processNextBatch(); + } else { + consoleWin.fireEvent('complete'); + consoleWin = null; + } + }, + scope: this + }, + failure: { + fn: function() { + consoleWin.fireEvent('complete'); + consoleWin = null; + }, + scope: this + } + } + }); + } MODx.Ajax.request({ url: fred.config.connectorUrl, params: { - action: 'Fred\\Processors\\Generate\\Refresh', + action: 'Fred\\Processors\\Generate\\Count', register: 'mgr', - topic: topic + topic: topic, + theme: theme }, listeners: { success: { + fn: function(r) { + total = r.object.total; + if (total === 0) { + consoleWin.fireEvent('complete'); + consoleWin = null; + return; + } + processNextBatch(); + }, + scope: this + }, + failure: { fn: function() { - console.fireEvent('complete'); - console = null + consoleWin.fireEvent('complete'); + consoleWin = null; }, - scope:this + scope: this } } }); diff --git a/core/components/fred/lexicon/en/default.inc.php b/core/components/fred/lexicon/en/default.inc.php index f060e689..6fdf1f23 100644 --- a/core/components/fred/lexicon/en/default.inc.php +++ b/core/components/fred/lexicon/en/default.inc.php @@ -106,6 +106,7 @@ $_lang['fred.rebuild.rebuild'] = 'Rebuild'; $_lang['fred.rebuild.rebuild_desc'] = 'Click the Rebuild button below to publish the changes in updated Elements to all existing Fred-powerd site pages.'; +$_lang['fred.rebuild.theme'] = 'Theme'; $_lang['fred.element_cateogries.all'] = 'All Categories'; $_lang['fred.element_categories.none'] = 'No Categories were found.'; @@ -272,6 +273,8 @@ $_lang['setting_fred.force_sidebar_desc'] = 'When enabled, user won\'t be able to close the sidebar.'; $_lang['setting_fred.logout_url'] = 'Logout Link'; $_lang['setting_fred.logout_url_desc'] = 'Custom logout link. If filled, users will redirect there instead of to the manager logout after clicking the logout button.'; +$_lang['setting_fred.batch_size'] = 'Regenerate Batch Size'; +$_lang['setting_fred.batch_size_desc'] = 'Maximum number of resources to process in a single batch when regenerating (set to lower values to increase performance).'; $_lang['fred.err.blueprint_categories_ns_name'] = 'Name is required'; $_lang['fred.err.blueprints_ns_name'] = 'Name is required'; diff --git a/core/components/fred/processors/mgr/generate/count.class.php b/core/components/fred/processors/mgr/generate/count.class.php new file mode 100644 index 00000000..44bb3d3a --- /dev/null +++ b/core/components/fred/processors/mgr/generate/count.class.php @@ -0,0 +1,5 @@ +modx->hasPermission('empty_cache'); + } + + public function process() + { + $theme = (int)$this->getProperty('theme', 0); + + $c = $this->modx->newQuery(FredThemedTemplate::class); + $c->select($this->modx->getSelectColumns(FredThemedTemplate::class, 'FredThemedTemplate', '', ['template'])); + if ($theme > 0) { + $c->where(['theme' => $theme]); + } + $c->prepare(); + $c->stmt->execute(); + + $templates = $c->stmt->fetchAll(\PDO::FETCH_COLUMN, 0); + $templates = array_map('intval', $templates); + $templates = array_filter($templates); + + if (empty($templates)) { + return $this->failure($this->modx->lexicon('fred.refresh_fail_template')); + } + + $count = $this->modx->getCount(modResource::class, ['template:IN' => $templates]); + + return $this->success('', ['total' => (int)$count]); + } +} diff --git a/core/components/fred/src/Processors/Generate/Refresh.php b/core/components/fred/src/Processors/Generate/Refresh.php index ed9a465a..c3080860 100644 --- a/core/components/fred/src/Processors/Generate/Refresh.php +++ b/core/components/fred/src/Processors/Generate/Refresh.php @@ -20,16 +20,22 @@ public function checkPermissions() public function process() { - //allow larger sites to rebuild - ini_set('max_execution_time', 300); - /** @var Fred $fred */ - $fred = $this->modx->services->get('fred'); + ini_set('max_execution_time', 30); - //Clear Element Values - $this->modx->removeCollection(FredCache::class, []); + $offset = (int)$this->getProperty('offset', 0); + $limit = (int)$this->getProperty('limit', 10); + $isLast = (bool)$this->getProperty('isLast', false); + $theme = (int)$this->getProperty('theme', 0); + + if ($offset === 0) { + $this->modx->removeCollection(FredCache::class, []); + } $c = $this->modx->newQuery(FredThemedTemplate::class); $c->select($this->modx->getSelectColumns(FredThemedTemplate::class, 'FredThemedTemplate', '', ['template'])); + if ($theme > 0) { + $c->where(['theme' => $theme]); + } $c->prepare(); $c->stmt->execute(); @@ -44,6 +50,7 @@ public function process() $c = $this->modx->newQuery(modResource::class); $c->where(['template:IN' => $templates]); + $c->limit($limit, $offset); $results = $this->modx->getIterator(modResource::class, $c); foreach ($results as $resource) { @@ -86,7 +93,9 @@ public function process() $this->modx->log(modX::LOG_LEVEL_INFO, $this->modx->lexicon('fred.refresh_id', ['id' => $resource->id])); } - $this->modx->log(modX::LOG_LEVEL_INFO, $this->modx->lexicon('fred.refresh_complete')); + if ($isLast) { + $this->modx->log(modX::LOG_LEVEL_INFO, $this->modx->lexicon('fred.refresh_complete')); + } return $this->success(''); } diff --git a/core/components/fred/src/v2/Processors/Generate/Count.php b/core/components/fred/src/v2/Processors/Generate/Count.php new file mode 100644 index 00000000..313b8493 --- /dev/null +++ b/core/components/fred/src/v2/Processors/Generate/Count.php @@ -0,0 +1,40 @@ +modx->hasPermission('empty_cache'); + } + + public function process() + { + $theme = (int)$this->getProperty('theme', 0); + + $c = $this->modx->newQuery('FredThemedTemplate'); + $c->select($this->modx->getSelectColumns('FredThemedTemplate', 'FredThemedTemplate', '', ['template'])); + if ($theme > 0) { + $c->where(['theme' => $theme]); + } + $c->prepare(); + $c->stmt->execute(); + + $templates = $c->stmt->fetchAll(\PDO::FETCH_COLUMN, 0); + $templates = array_map('intval', $templates); + $templates = array_filter($templates); + + if (empty($templates)) { + return $this->failure($this->modx->lexicon('fred.refresh_fail_template')); + } + + $count = $this->modx->getCount('modResource', ['template:IN' => $templates]); + + return $this->success('', ['total' => (int)$count]); + } +} diff --git a/core/components/fred/src/v2/Processors/Generate/Refresh.php b/core/components/fred/src/v2/Processors/Generate/Refresh.php index 65bf5e33..45ab046a 100644 --- a/core/components/fred/src/v2/Processors/Generate/Refresh.php +++ b/core/components/fred/src/v2/Processors/Generate/Refresh.php @@ -15,8 +15,13 @@ public function checkPermissions() public function process() { - //allow larger sites to rebuild - ini_set('max_execution_time', 300); + ini_set('max_execution_time', 30); + + $offset = (int)$this->getProperty('offset', 0); + $limit = (int)$this->getProperty('limit', 10); + $isLast = (bool)$this->getProperty('isLast', false); + $theme = (int)$this->getProperty('theme', 0); + /** @var \Fred $fred */ $corePath = $this->modx->getOption('fred.core_path', null, $this->modx->getOption('core_path', null, MODX_CORE_PATH) . 'components/fred/'); $fred = $this->modx->getService( @@ -28,11 +33,15 @@ public function process() ] ); - //Clear Element Values - $this->modx->removeCollection('FredCache', []); + if ($offset === 0) { + $this->modx->removeCollection('FredCache', []); + } $c = $this->modx->newQuery('FredThemedTemplate'); $c->select($this->modx->getSelectColumns('FredThemedTemplate', 'FredThemedTemplate', '', ['template'])); + if ($theme > 0) { + $c->where(['theme' => $theme]); + } $c->prepare(); $c->stmt->execute(); @@ -47,6 +56,7 @@ public function process() $c = $this->modx->newQuery('modResource'); $c->where(['template:IN' => $templates]); + $c->limit($limit, $offset); $results = $this->modx->getIterator('modResource', $c); foreach ($results as $resource) { @@ -89,7 +99,9 @@ public function process() $this->modx->log(\modX::LOG_LEVEL_INFO, $this->modx->lexicon('fred.refresh_id', ['id' => $resource->id])); } - $this->modx->log(\modX::LOG_LEVEL_INFO, $this->modx->lexicon('fred.refresh_complete')); + if ($isLast) { + $this->modx->log(\modX::LOG_LEVEL_INFO, $this->modx->lexicon('fred.refresh_complete')); + } return $this->success(''); }