From 3df7c74911dce7c505b2b72d9b7b4c6c924d99a9 Mon Sep 17 00:00:00 2001 From: goldsky Date: Fri, 15 Apr 2016 16:55:12 +0700 Subject: [PATCH] bump 3.0.0-rc1 --- _build/build.transport.php | 172 ++-- _build/data/transport.menu.php | 47 + assets/components/babel/css/cmp.css | 0 assets/components/babel/js/mgr/babel.js | 9 + .../components/babel/js/mgr/sections/index.js | 15 + .../babel/js/mgr/widgets/combo.context.js | 25 + .../js/mgr/widgets/grid.resourcematrix.js | 424 ++++++++ .../babel/js/mgr/widgets/panel.home.js | 80 ++ .../js/ux/LockingGridView/LockingGridView.css | 34 + .../js/ux/LockingGridView/LockingGridView.js | 934 ++++++++++++++++++ .../babel/controllers/default/index.class.php | 48 + core/components/babel/docs/changelog.txt | 4 + core/components/babel/lexicon/en/cmp.inc.php | 43 + .../babel/lexicon/en/default.inc.php | 2 + .../babel/lexicon/nl/default.inc.php | 4 +- .../babel/model/babel/babel.class.php | 2 +- .../processors/mgr/context/getlist.class.php | 73 ++ .../mgr/resource/getmatrixlist.class.php | 88 ++ .../babel/templates/default/index.tpl | 1 + 19 files changed, 1927 insertions(+), 78 deletions(-) create mode 100644 _build/data/transport.menu.php create mode 100644 assets/components/babel/css/cmp.css create mode 100644 assets/components/babel/js/mgr/babel.js create mode 100644 assets/components/babel/js/mgr/sections/index.js create mode 100644 assets/components/babel/js/mgr/widgets/combo.context.js create mode 100644 assets/components/babel/js/mgr/widgets/grid.resourcematrix.js create mode 100644 assets/components/babel/js/mgr/widgets/panel.home.js create mode 100644 assets/components/babel/js/ux/LockingGridView/LockingGridView.css create mode 100644 assets/components/babel/js/ux/LockingGridView/LockingGridView.js create mode 100644 core/components/babel/controllers/default/index.class.php create mode 100644 core/components/babel/lexicon/en/cmp.inc.php create mode 100644 core/components/babel/processors/mgr/context/getlist.class.php create mode 100644 core/components/babel/processors/mgr/resource/getmatrixlist.class.php create mode 100644 core/components/babel/templates/default/index.tpl diff --git a/_build/build.transport.php b/_build/build.transport.php index b93d393..fa4ef05 100644 --- a/_build/build.transport.php +++ b/_build/build.transport.php @@ -1,4 +1,5 @@ * goldsky * * @package babel * @subpackage build */ -$mtime = microtime(); -$mtime = explode(' ', $mtime); -$mtime = $mtime[1] + $mtime[0]; +$mtime = microtime(); +$mtime = explode(' ', $mtime); +$mtime = $mtime[1] + $mtime[0]; $tstart = $mtime; set_time_limit(0); /* define package */ -define('PKG_NAME','Babel'); -define('PKG_NAME_LOWER',strtolower(PKG_NAME)); +define('PKG_NAME', 'Babel'); +define('PKG_NAME_LOWER', strtolower(PKG_NAME)); /* define sources */ -$root = dirname(dirname(__FILE__)).'/'; +$root = dirname(dirname(__FILE__)).'/'; $sources = array( - 'root' => $root, - 'build' => $root . '_build/', - 'resolvers' => $root . '_build/resolvers/', - 'data' => $root . '_build/data/', - 'events' => $root . '_build/data/events/', - 'chunks' => $root.'core/components/'.PKG_NAME_LOWER.'/elements/chunks/', - 'snippets' => $root.'core/components/'.PKG_NAME_LOWER.'/elements/snippets/', - 'plugins' => $root.'core/components/'.PKG_NAME_LOWER.'/elements/plugins/', - 'lexicon' => $root . 'core/components/'.PKG_NAME_LOWER.'/lexicon/', - 'docs' => $root.'core/components/'.PKG_NAME_LOWER.'/docs/', + 'root' => $root, + 'build' => $root.'_build/', + 'resolvers' => $root.'_build/resolvers/', + 'data' => $root.'_build/data/', + 'events' => $root.'_build/data/events/', + 'chunks' => $root.'core/components/'.PKG_NAME_LOWER.'/elements/chunks/', + 'snippets' => $root.'core/components/'.PKG_NAME_LOWER.'/elements/snippets/', + 'plugins' => $root.'core/components/'.PKG_NAME_LOWER.'/elements/plugins/', + 'lexicon' => $root.'core/components/'.PKG_NAME_LOWER.'/lexicon/', + 'docs' => $root.'core/components/'.PKG_NAME_LOWER.'/docs/', 'source_assets' => $root.'assets/components/'.PKG_NAME_LOWER, - 'source_core' => $root.'core/components/'.PKG_NAME_LOWER, + 'source_core' => $root.'core/components/'.PKG_NAME_LOWER, ); unset($root); /* override with your own defines here (see build.config.sample.php) */ -require_once $sources['build'] . '/build.config.php'; -require_once MODX_CORE_PATH . 'model/modx/modx.class.php'; -require_once $sources['build'] . '/includes/functions.php'; +require_once $sources['build'].'/build.config.php'; +require_once MODX_CORE_PATH.'model/modx/modx.class.php'; +require_once $sources['build'].'/includes/functions.php'; -$modx= new modX(); +$modx = new modX(); $modx->initialize('mgr'); echo '
'; /* used for nice formatting of log messages */
 $modx->setLogLevel(modX::LOG_LEVEL_INFO);
 $modx->setLogTarget('ECHO');
 
-$babel = $modx->getService('babel', 'Babel', MODX_CORE_PATH . 'components/babel/model/babel/');
+$babel = $modx->getService('babel', 'Babel', MODX_CORE_PATH.'components/babel/model/babel/');
 
 if (!($babel instanceof Babel)) {
     return '';
@@ -77,43 +78,62 @@
 define('PKG_VERSION', Babel::VERSION);
 define('PKG_RELEASE', Babel::RELEASE);
 
-$modx->loadClass('transport.modPackageBuilder','',false, true);
+$modx->loadClass('transport.modPackageBuilder', '', false, true);
 $builder = new modPackageBuilder($modx);
-$builder->createPackage(PKG_NAME_LOWER,PKG_VERSION,PKG_RELEASE);
-$builder->registerNamespace(PKG_NAME_LOWER,false,true,'{core_path}components/'.PKG_NAME_LOWER.'/');
-$modx->log(modX::LOG_LEVEL_INFO,'Created Transport Package and Namespace.');
+$builder->createPackage(PKG_NAME_LOWER, PKG_VERSION, PKG_RELEASE);
+$builder->registerNamespace(PKG_NAME_LOWER, false, true, '{core_path}components/'.PKG_NAME_LOWER.'/');
+$modx->log(modX::LOG_LEVEL_INFO, 'Created Transport Package and Namespace.');
+
+/**
+ * MENU & ACTION
+ */
+$menu = include $sources['data'].'transport.menu.php';
+if (empty($menu)) {
+    $modx->log(modX::LOG_LEVEL_ERROR, 'Could not package in menu.');
+} else {
+    $menuVehicle = $builder->createVehicle($menu, array(
+        xPDOTransport::PRESERVE_KEYS => true,
+        xPDOTransport::UPDATE_OBJECT => true,
+        xPDOTransport::UNIQUE_KEY    => 'text'
+    ));
+    $builder->putVehicle($menuVehicle);
+    $modx->log(modX::LOG_LEVEL_INFO, 'Packaged in Menu');
+    unset($menuVehicle, $menu);
+}
 
 /* load system settings */
 $settings = include $sources['data'].'transport.settings.php';
 if (!is_array($settings)) {
-    $modx->log(modX::LOG_LEVEL_ERROR,'Could not package in settings.');
+    $modx->log(modX::LOG_LEVEL_ERROR, 'Could not package in settings.');
 } else {
-    $attributes= array(
-        xPDOTransport::UNIQUE_KEY => 'key',
+    $attributes = array(
+        xPDOTransport::UNIQUE_KEY    => 'key',
         xPDOTransport::PRESERVE_KEYS => true,
         xPDOTransport::UPDATE_OBJECT => false,
     );
     foreach ($settings as $setting) {
-        $vehicle = $builder->createVehicle($setting,$attributes);
+        $vehicle = $builder->createVehicle($setting, $attributes);
         $builder->putVehicle($vehicle);
     }
-    $modx->log(modX::LOG_LEVEL_INFO,'Packaged in '.count($settings).' System Settings.');
+    $modx->log(modX::LOG_LEVEL_INFO, 'Packaged in '.count($settings).' System Settings.');
 }
-unset($settings,$setting,$attributes);
+unset($settings, $setting, $attributes);
 
 /* add plugins */
 $plugins = include $sources['data'].'transport.plugins.php';
-if (!is_array($plugins)) { $modx->log(modX::LOG_LEVEL_FATAL,'Adding plugins failed.'); }
-$attributes= array(
-    xPDOTransport::UNIQUE_KEY => 'name',
-    xPDOTransport::PRESERVE_KEYS => false,
-    xPDOTransport::UPDATE_OBJECT => true,
-    xPDOTransport::RELATED_OBJECTS => true,
-    xPDOTransport::RELATED_OBJECT_ATTRIBUTES => array (
+if (!is_array($plugins)) {
+    $modx->log(modX::LOG_LEVEL_FATAL, 'Adding plugins failed.');
+}
+$attributes = array(
+    xPDOTransport::UNIQUE_KEY                => 'name',
+    xPDOTransport::PRESERVE_KEYS             => false,
+    xPDOTransport::UPDATE_OBJECT             => true,
+    xPDOTransport::RELATED_OBJECTS           => true,
+    xPDOTransport::RELATED_OBJECT_ATTRIBUTES => array(
         'PluginEvents' => array(
             xPDOTransport::PRESERVE_KEYS => true,
             xPDOTransport::UPDATE_OBJECT => false,
-            xPDOTransport::UNIQUE_KEY => array('pluginid','event'),
+            xPDOTransport::UNIQUE_KEY    => array('pluginid', 'event'),
         ),
     ),
 );
@@ -121,76 +141,78 @@
     $vehicle = $builder->createVehicle($plugin, $attributes);
     $builder->putVehicle($vehicle);
 }
-$modx->log(modX::LOG_LEVEL_INFO,'Packaged in '.count($plugins).' plugins.'); flush();
-unset($plugins,$plugin,$attributes);
+$modx->log(modX::LOG_LEVEL_INFO, 'Packaged in '.count($plugins).' plugins.');
+flush();
+unset($plugins, $plugin, $attributes);
 
 /* create category */
-$category= $modx->newObject('modCategory');
-$category->set('id',1);
-$category->set('category',PKG_NAME);
-$modx->log(modX::LOG_LEVEL_INFO,'Packaged in category.'); flush();
+$category = $modx->newObject('modCategory');
+$category->set('id', 1);
+$category->set('category', PKG_NAME);
+$modx->log(modX::LOG_LEVEL_INFO, 'Packaged in category.');
+flush();
 
 /* add snippets */
 $snippets = include $sources['data'].'transport.snippets.php';
 if (!is_array($snippets)) {
-    $modx->log(modX::LOG_LEVEL_ERROR,'Could not package in snippets.');
+    $modx->log(modX::LOG_LEVEL_ERROR, 'Could not package in snippets.');
 } else {
     $category->addMany($snippets);
-    $modx->log(modX::LOG_LEVEL_INFO,'Packaged in '.count($snippets).' snippets.');
+    $modx->log(modX::LOG_LEVEL_INFO, 'Packaged in '.count($snippets).' snippets.');
 }
 
 /* create category vehicle */
-$attr = array(
-    xPDOTransport::UNIQUE_KEY => 'category',
-    xPDOTransport::PRESERVE_KEYS => false,
-    xPDOTransport::UPDATE_OBJECT => true,
-    xPDOTransport::RELATED_OBJECTS => true,
-    xPDOTransport::RELATED_OBJECT_ATTRIBUTES => array (
+$attr    = array(
+    xPDOTransport::UNIQUE_KEY                => 'category',
+    xPDOTransport::PRESERVE_KEYS             => false,
+    xPDOTransport::UPDATE_OBJECT             => true,
+    xPDOTransport::RELATED_OBJECTS           => true,
+    xPDOTransport::RELATED_OBJECT_ATTRIBUTES => array(
         'Snippets' => array(
             xPDOTransport::PRESERVE_KEYS => false,
             xPDOTransport::UPDATE_OBJECT => true,
-            xPDOTransport::UNIQUE_KEY => 'name',
+            xPDOTransport::UNIQUE_KEY    => 'name',
         ),
     ),
 );
-$vehicle = $builder->createVehicle($category,$attr);
+$vehicle = $builder->createVehicle($category, $attr);
 
-$modx->log(modX::LOG_LEVEL_INFO,'Adding file resolvers to category...');
-$vehicle->resolve('file',array(
+$modx->log(modX::LOG_LEVEL_INFO, 'Adding file resolvers to category...');
+$vehicle->resolve('file', array(
     'source' => $sources['source_assets'],
     'target' => "return MODX_ASSETS_PATH . 'components/';",
 ));
-$vehicle->resolve('file',array(
+$vehicle->resolve('file', array(
     'source' => $sources['source_core'],
     'target' => "return MODX_CORE_PATH . 'components/';",
 ));
-$vehicle->resolve('php',array(
-    'source' => $sources['resolvers'] . 'setupoptions.resolver.php',
+$vehicle->resolve('php', array(
+    'source' => $sources['resolvers'].'setupoptions.resolver.php',
 ));
 $builder->putVehicle($vehicle);
 
 /* now pack in the license file, readme and setup options */
 $builder->setPackageAttributes(array(
-    'license' => file_get_contents($sources['docs'] . 'license.txt'),
-	'changelog' => file_get_contents($sources['docs'] . 'changelog.txt'),
-    'readme' => file_get_contents($sources['docs'] . 'readme.txt'),
+    'license'       => file_get_contents($sources['docs'].'license.txt'),
+    'changelog'     => file_get_contents($sources['docs'].'changelog.txt'),
+    'readme'        => file_get_contents($sources['docs'].'readme.txt'),
     'setup-options' => array(
         'source' => $sources['build'].'setup.options.php',
     ),
 ));
-$modx->log(modX::LOG_LEVEL_INFO,'Added package attributes and setup options.');
+$modx->log(modX::LOG_LEVEL_INFO, 'Added package attributes and setup options.');
 
 /* zip up package */
-$modx->log(modX::LOG_LEVEL_INFO,'Packing up transport package zip...');
+$modx->log(modX::LOG_LEVEL_INFO, 'Packing up transport package zip...');
 $builder->pack();
 
-$mtime= microtime();
-$mtime= explode(" ", $mtime);
-$mtime= $mtime[1] + $mtime[0];
-$tend= $mtime;
-$totalTime= ($tend - $tstart);
-$totalTime= sprintf("%2.4f s", $totalTime);
+$mtime     = microtime();
+$mtime     = explode(" ", $mtime);
+$mtime     = $mtime[1] + $mtime[0];
+$tend      = $mtime;
+$totalTime = ($tend - $tstart);
+$totalTime = sprintf("%2.4f s", $totalTime);
 
-$modx->log(modX::LOG_LEVEL_INFO,"\n
Package Built.
\nExecution time: {$totalTime}\n"); +$modx->log(modX::LOG_LEVEL_INFO, "\n
Package Built.
\nExecution time: {$totalTime}\n"); -exit (); \ No newline at end of file +exit(); diff --git a/_build/data/transport.menu.php b/_build/data/transport.menu.php new file mode 100644 index 0000000..7c28e3c --- /dev/null +++ b/_build/data/transport.menu.php @@ -0,0 +1,47 @@ + + * + * This file is part of Babel. + * + * Babel is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Babel is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * Babel; if not, write to the Free Software Foundation, Inc., 59 Temple Place, + * Suite 330, Boston, MA 02111-1307 USA + * + * @package babel + */ +/** + * Add menu to build + * + * @author Jakob Class + * goldsky + * @package babel + * @subpackage build + */ + +$menu = $modx->newObject('modMenu'); +$menu->fromArray(array( + 'text' => 'babel', + 'parent' => 'components', + 'action' => 'index', + 'description' => 'babel.desc', + 'icon' => 'images/icons/plugin.gif', + 'menuindex' => 0, + 'params' => '', + 'handler' => '', + 'pemission' => '', + 'namespace' => 'babel', + ), '', true, true); + +return $menu; \ No newline at end of file diff --git a/assets/components/babel/css/cmp.css b/assets/components/babel/css/cmp.css new file mode 100644 index 0000000..e69de29 diff --git a/assets/components/babel/js/mgr/babel.js b/assets/components/babel/js/mgr/babel.js new file mode 100644 index 0000000..20bef8b --- /dev/null +++ b/assets/components/babel/js/mgr/babel.js @@ -0,0 +1,9 @@ +var Babel = function (config) { + config = config || {}; + Babel.superclass.constructor.call(this, config); +}; +Ext.extend(Babel, Ext.Component, { + page: {}, window: {}, grid: {}, tree: {}, panel: {}, combo: {}, config: {} +}); +Ext.reg('babel', Babel); +Babel = new Babel(); \ No newline at end of file diff --git a/assets/components/babel/js/mgr/sections/index.js b/assets/components/babel/js/mgr/sections/index.js new file mode 100644 index 0000000..fa2e7ca --- /dev/null +++ b/assets/components/babel/js/mgr/sections/index.js @@ -0,0 +1,15 @@ +Ext.onReady(function () { + MODx.load({xtype: 'babel-page-home'}); +}); +Babel.page.Home = function (config) { + config = config || {}; + Ext.applyIf(config, { + components: [{ + xtype: 'babel-panel-home' + , renderTo: 'babel-panel-home-div' + }] + }); + Babel.page.Home.superclass.constructor.call(this, config); +}; +Ext.extend(Babel.page.Home, MODx.Component); +Ext.reg('babel-page-home', Babel.page.Home); \ No newline at end of file diff --git a/assets/components/babel/js/mgr/widgets/combo.context.js b/assets/components/babel/js/mgr/widgets/combo.context.js new file mode 100644 index 0000000..2d4073c --- /dev/null +++ b/assets/components/babel/js/mgr/widgets/combo.context.js @@ -0,0 +1,25 @@ +Babel.combo.Context = function (config) { + config = config || {}; + Ext.applyIf(config, { + url: Babel.config.connectorUrl, + baseParams: { + action: 'mgr/context/getlist', + combo: true, + exclude: 'mgr' + } + }); + Babel.combo.Context.superclass.constructor.call(this, config); + + this.on('select', function (comp, record, index){ + if (comp.getValue() === "" || comp.getValue() === " ") { + comp.setValue(null); + } + }); + this.on('change', function (comp, newValue, oldValue){ + if (newValue === "" || newValue === " ") { + comp.setValue(null); + } + }); +}; +Ext.extend(Babel.combo.Context, MODx.combo.Context); +Ext.reg('babel-combo-context', Babel.combo.Context); diff --git a/assets/components/babel/js/mgr/widgets/grid.resourcematrix.js b/assets/components/babel/js/mgr/widgets/grid.resourcematrix.js new file mode 100644 index 0000000..627cbd2 --- /dev/null +++ b/assets/components/babel/js/mgr/widgets/grid.resourcematrix.js @@ -0,0 +1,424 @@ +Babel.grid.ResourceMatrix = function (config) { + config = config || {}; + + var columns = []; + var fields = []; + var contexts = []; + var _this = this; + + columns.push({ + header: _('id'), + dataIndex: 'id', + sortable: true, + width: 80, + fixed: true, + locked: true, + id: 'res_id' + }); + columns.push({ + header: _('context'), + dataIndex: 'context_key', + sortable: true, + width: 80, + fixed: true, + locked: true, + id: 'context_key' + }); + columns.push({ + header: _('pagetitle'), + dataIndex: 'pagetitle', + sortable: true, + width: 200, + locked: true, + id: 'pagetitle' + }); + fields.push('id'); + fields.push('context_key'); + fields.push('pagetitle'); + fields.push('parent'); + + if (config.record) { + Ext.each(config.record, function (item, index) { + fields.push('linkedres_id_' + item.key); + fields.push('linkedres_pagetitle_' + item.key); + contexts.push(item.key); + + var actionItems = []; + actionItems.push({ + handler: function (grid, row, col) { + var sel_model = grid.getSelectionModel(); + sel_model.selectRow(row); + var rec = grid.getStore().getAt(row); + var colName = grid.getColumnModel().getDataIndex(col); + var ctx = colName.substr('linkedres_id_'.length); + var cellvalue = rec.data[colName]; + if (cellvalue.length === 0) { + grid.createTranslation(ctx, rec.get('id')); + } else { + MODx.loadPage(MODx.action['resource/update'], 'id=' + cellvalue); + } + }, + getClass: function (v, meta, rec) { + if (meta.id === 'linkedres_id_' + rec.get('context_key')) { + return ''; + } + if (rec.get(meta.id) === '') { + this.items[0].tooltip = _('babel.create_translation'); + this.items[0].altText = _('babel.create_translation'); + return 'icon-pencil-go icon-babel-actioncolumn-img'; + } else { + var ctx = meta.id.substr('linkedres_id_'.length); + var pagetitle = rec.get('linkedres_pagetitle_' + ctx); + this.items[0].tooltip = _('edit') + ': ' + pagetitle; + this.items[0].altText = _('edit') + ': ' + pagetitle; + return 'icon-page-go icon-babel-actioncolumn-img'; + } + } + }); + actionItems.push({ + handler: function (grid, row, col) { + var sel_model = grid.getSelectionModel(); + sel_model.selectRow(row); + var rec = grid.getStore().getAt(row); + var colName = grid.getColumnModel().getDataIndex(col); + var ctx = colName.substr('linkedres_id_'.length); + var cellvalue = rec.data[colName]; + if (cellvalue.length === 0) { + grid.linkTranslation(ctx, rec.get('id')); + } else { + grid.unlinkTranslation(ctx, rec.get('id'), cellvalue); + } + }, + getClass: function (v, meta, rec) { + if (meta.id === 'linkedres_id_' + rec.get('context_key')) { + return ''; + } + if (rec.get(meta.id) === '') { + this.items[1].tooltip = _('babel.link_translation'); + this.items[1].altText = _('babel.link_translation'); + return 'icon-link icon-babel-actioncolumn-img'; + } else { + var ctx = meta.id.substr('linkedres_id_'.length); + var pagetitle = rec.get('linkedres_pagetitle_' + ctx); + this.items[1].tooltip = _('babel.unlink') + ': ' + pagetitle; + this.items[1].altText = _('babel.unlink') + ': ' + pagetitle; + return 'icon-unlink icon-babel-actioncolumn-img'; + } + } + }); + + columns.push({ + header: item.key, + width: 70, + sortable: false, + id: 'linkedres_id_' + item.key, + dataIndex: 'linkedres_id_' + item.key, // 'id' conflicts with Indonesian's ISO code 'id' + xtype: 'actioncolumn', + items: actionItems + }); + }); + } + + var cm = new Ext.ux.grid.LockingColumnModel({ + columns: columns + }); + + Ext.applyIf(config, { + id: 'babel-grid-resourcematrix', + url: Babel.config.connectorUrl, + baseParams: { + action: 'mgr/resource/getMatrixList', + contexts: contexts.toString() + }, + fields: fields, + paging: true, + remoteSort: true, + anchor: '97%', + autoExpandColumn: 'pagetitle', + colModel: cm, + view: new Ext.ux.grid.LockingGridView(), + height: 595, + autoHeight: false, + tbar: [ + { + xtype: 'babel-combo-context', + id: 'babel-combo-context' + }, { + xtype: 'textfield', + id: 'babel-search-resource', + width: 300, + emptyText: _('babel.search...') + }, { + text: _('babel.filter'), + handler: function () { + var ctx = Ext.getCmp('babel-combo-context').getValue(); + var qry = Ext.getCmp('babel-search-resource').getValue(); + this.baseParams.context = ctx; + this.baseParams.query = qry; + this.getBottomToolbar().changePage(1); + this.refresh(); + }, + scope: this + }, { + text: _('babel.reset'), + handler: function () { + Ext.getCmp('babel-combo-context').reset(); + Ext.getCmp('babel-combo-context').setValue(null); + Ext.getCmp('babel-search-resource').reset(); + this.baseParams.context = ''; + this.baseParams.query = ''; + this.getBottomToolbar().changePage(1); + this.refresh(); + } + } + ] + }); + + Babel.grid.ResourceMatrix.superclass.constructor.call(this, config); + +}; +Ext.extend(Babel.grid.ResourceMatrix, MODx.grid.Grid, { + linkTranslation: function (ctx, id) { + var win = MODx.load({ + xtype: 'modx-window', + title: _('babel.link_translation'), + url: Babel.config.connectorUrl, + baseParams: { + action: 'mgr/resource/link', + context: ctx, + id: id + }, + listeners: { + success: { + fn: function (r) { + MODx.msg.status({ + title: _('success'), + message: r.message || _('save_successful') + }); + this.hideGridMask(); + this.refresh(); + }, + scope: this + }, + failure: { + fn: function (r) { + this.hideGridMask(); + }, + scope: this + }, + beforeSubmit: { + fn: function (r) { + this.loadGridMask(); + }, + scope: this + } + }, + fields: [ + { + xtype: 'textfield', + fieldLabel: _('context'), + disabled: true, + emptyText: ctx + }, { + xtype: 'hidden', + name: 'target' + }, { + xtype: 'modx-field-parent-change', + fieldLabel: _('babel.id_of_target'), + id: '', + anchor: '100%', + name: 'target-combo', + end: function (p) { + var t = Ext.getCmp('modx-resource-tree'); + if (!t) + return; + p.d = p.d || p.v; + if (p.c !== ctx) { + return; + } + t.removeListener('click', this.handleChangeParent, this); + t.on('click', t._handleClick, t); + t.disableHref = false; + + win.fp.getForm().findField('target').setValue(p.v); + win.fp.getForm().findField('page_id').setValue(null); + this.setValue(p.d); + this.oldValue = false; + }, + disableTreeClick: function () { + MODx.debug('Disabling tree click'); + var t = Ext.getCmp('modx-resource-tree'); + if (!t) { + MODx.debug('No tree found in disableTreeClick!'); + return false; + } + this.oldDisplayValue = this.getValue(); + this.oldValue = win.fp.getForm().findField('target').getValue(); + + this.setValue(_('resource_parent_select_node')); + + t.expand(); + t.removeListener('click', t._handleClick); + t.on('click', this.handleChangeParent, this); + t.disableHref = true; + + return true; + }, + handleChangeParent: function (node, e) { + var t = Ext.getCmp('modx-resource-tree'); + if (!t) { + return false; + } + t.disableHref = true; + + var id = node.id.split('_'); + id = id[1]; + if (id == this.config.currentid) { + MODx.msg.alert('', _('resource_err_own_parent')); + return false; + } + + this.fireEvent('end', { + v: node.attributes.type !== 'modContext' ? id : node.attributes.pk, + d: Ext.util.Format.stripTags(node.text), + c: node.attributes.ctx + }); + e.preventDefault(); + e.stopEvent(); + return true; + } + }, { + xtype: 'modx-combo', + fieldLabel: _('babel....or') + ' ' + _('babel.pagetitle_of_target'), + name: 'page_id', + anchor: '100%', + url: Babel.config.connectorUrl, + baseParams: { + action: 'mgr/resource/getlist', + context: ctx, + combo: true + }, + displayField: 'pagetitle', + valueField: 'id', + fields: ['id', 'pagetitle'], + editable: true, + typeAhead: true, + forceSelection: false, + listeners: { + select: { + fn: function (combo, record, index) { + var val = combo.getValue(); + if (val === "" || val === 0 || val === " ") { + combo.setValue(null); + } else { + win.fp.getForm().findField('target').setValue(record.id); + } + win.fp.getForm().findField('target-combo').reset(); + }, + scope: this + }, + blur: { + fn: function (combo) { + var val = combo.getValue(); + if (val === "" || val === 0 || val === " ") { + combo.setValue(null); + } + }, + scope: this + } + } + }, { + xtype: 'xcheckbox', + boxLabel: _('babel.copy_tv_values'), + name: 'copy-tv-values' + } + ] + }); + win.reset(); + win.show(); + }, + unlinkTranslation: function (ctx, id, target) { + var _this = Ext.getCmp('babel-grid-resourcematrix'); + _this.loadGridMask(); + return MODx.msg.confirm({ + title: _('confirm'), + text: _('babel.unlink_translation_confirm', {context: ctx, id: id}), + url: Babel.config.connectorUrl, + params: { + action: 'mgr/resource/unlink', + context: ctx, + id: id, + target: target + }, + listeners: { + success: { + fn: function (r) { + MODx.msg.status({ + title: _('success'), + message: r.message || _('save_successful') + }); + _this.hideGridMask(); + _this.refresh(); + } + }, + failure: { + fn: function (r) { + _this.hideGridMask(); + } + }, + cancel: { + fn: function (r) { + _this.hideGridMask(); + } + } + } + }); + }, + createTranslation: function (ctx, id) { + var _this = Ext.getCmp('babel-grid-resourcematrix'); + _this.loadGridMask(); + return MODx.msg.confirm({ + title: _('confirm'), + text: _('babel.create_translation_confirm', {context: ctx, id: id}), + url: Babel.config.connectorUrl, + params: { + action: 'mgr/resource/duplicate', + context_key: ctx, + id: id + }, + listeners: { + success: { + fn: function (r) { + _this.hideGridMask(); + MODx.loadPage(MODx.action['resource/update'], 'id=' + r.object.id); + } + }, + failure: { + fn: function (r) { + _this.hideGridMask(); + } + }, + cancel: { + fn: function (r) { + _this.hideGridMask(); + } + } + } + }); + }, + loadGridMask: function () { + if (!this.overlayMask) { + var domHandler = Ext.getBody().dom; + this.overlayMask = new Ext.LoadMask(domHandler, { + msg: _('babel.please_wait') + }); + } + this.overlayMask.show(); + }, + hideGridMask: function () { + if (this.overlayMask) { + this.overlayMask.hide(); + } + } +}); +Ext.reg('babel-grid-resourcematrix', Babel.grid.ResourceMatrix); diff --git a/assets/components/babel/js/mgr/widgets/panel.home.js b/assets/components/babel/js/mgr/widgets/panel.home.js new file mode 100644 index 0000000..1d337a3 --- /dev/null +++ b/assets/components/babel/js/mgr/widgets/panel.home.js @@ -0,0 +1,80 @@ +Babel.panel.Home = function (config) { + config = config || {}; + Ext.applyIf(config, { + border: false, + baseCls: 'modx-formpanel', + cls: 'container', + items: [ + { + html: '

' + _('babel') + '

', + border: false, + cls: 'modx-page-header' + }, { + html: _('babel.icon_descriptions'), + cls: 'panel-desc' + }, { + id: 'babel-grid-resourcematrix-holder', + preventRender: true, + border: false, + listeners: { + 'afterrender': { + fn: function (tabPanel) { + this.getContexts('getResourceGrid'); + }, + scope: this + } + } +// xtype: 'babel-grid-resourcematrix', +// cls: 'main-wrapper', +// preventRender: true + } + ] + }); + Babel.panel.Home.superclass.constructor.call(this, config); + +}; +Ext.extend(Babel.panel.Home, MODx.Panel, { + contexts: [], + getContexts: function(callback) { + if (this.contexts.length > 0) { + if (typeof(this[callback]) === 'function') { + return this[callback].call(this, this.config); + } + return this.contexts; + } + return MODx.Ajax.request({ + url: Babel.config.connectorUrl, + params: { + action: 'mgr/context/getlist', + exclude: 'mgr' + }, + listeners: { + 'success': { + fn: function (r) { + if (r.success) { + this.contexts = r.results; + if (this.contexts.length > 0 && typeof(this[callback]) === 'function') { + return this[callback].call(this, this.config); + } + } + }, + scope: this + } + } + }); + }, + getResourceGrid: function() { + if (this.contexts.length < 1) { + return; + } + MODx.load({ + xtype: 'babel-grid-resourcematrix', + record: this.contexts, + cls: 'main-wrapper', + preventRender: true, + applyTo: 'babel-grid-resourcematrix-holder' + }); + } +}); + +Ext.reg('babel-panel-home', Babel.panel.Home); \ No newline at end of file diff --git a/assets/components/babel/js/ux/LockingGridView/LockingGridView.css b/assets/components/babel/js/ux/LockingGridView/LockingGridView.css new file mode 100644 index 0000000..e66250d --- /dev/null +++ b/assets/components/babel/js/ux/LockingGridView/LockingGridView.css @@ -0,0 +1,34 @@ +/*! + * Ext JS Library 3.4.0 + * Copyright(c) 2006-2011 Sencha Inc. + * licensing@sencha.com + * http://www.sencha.com/license + */ +.x-grid3-locked, .x-grid3-unlocked { + overflow: hidden; + position: absolute; +} + +.x-grid3-locked { + border-right: 1px solid #99BBE8; +} + +.x-grid3-locked .x-grid3-scroller { + overflow: hidden; +} + +.x-grid3-locked .x-grid3-row { + border-right: 0; +} + +.x-grid3-scroll-spacer { + height: 19px; +} + +.x-grid3-unlocked .x-grid3-header-offset { + padding-left: 0; +} + +.x-grid3-unlocked .x-grid3-row { + border-left: 0; +} diff --git a/assets/components/babel/js/ux/LockingGridView/LockingGridView.js b/assets/components/babel/js/ux/LockingGridView/LockingGridView.js new file mode 100644 index 0000000..09f9c3e --- /dev/null +++ b/assets/components/babel/js/ux/LockingGridView/LockingGridView.js @@ -0,0 +1,934 @@ +/*! + * Ext JS Library 3.4.0 + * Copyright(c) 2006-2011 Sencha Inc. + * licensing@sencha.com + * http://www.sencha.com/license + */ +/*! + * Ext JS Library 3.4.0 + * Copyright(c) 2006-2010 Ext JS, Inc. + * licensing@extjs.com + * http://www.extjs.com/license + */ +Ext.ns('Ext.ux.grid'); + +Ext.ux.grid.LockingGridView = Ext.extend(Ext.grid.GridView, { + lockText : 'Lock', + unlockText : 'Unlock', + rowBorderWidth : 1, + lockedBorderWidth : 1, + + /* + * This option ensures that height between the rows is synchronized + * between the locked and unlocked sides. This option only needs to be used + * when the row heights aren't predictable. + */ + syncHeights: false, + + initTemplates : function(){ + var ts = this.templates || {}; + + if (!ts.masterTpl) { + ts.masterTpl = new Ext.Template( + '
', + '
', + '
{lockedHeader}
', + '
{lockedBody}
', + '
', + '
', + '
{header}
', + '
{body}
', + '
', + '
 
', + '
 
', + '
' + ); + } + + this.templates = ts; + + Ext.ux.grid.LockingGridView.superclass.initTemplates.call(this); + }, + + getEditorParent : function(ed){ + return this.el.dom; + }, + + initElements : function(){ + var el = Ext.get(this.grid.getGridEl().dom.firstChild), + lockedWrap = el.child('div.x-grid3-locked'), + lockedHd = lockedWrap.child('div.x-grid3-header'), + lockedScroller = lockedWrap.child('div.x-grid3-scroller'), + mainWrap = el.child('div.x-grid3-viewport'), + mainHd = mainWrap.child('div.x-grid3-header'), + scroller = mainWrap.child('div.x-grid3-scroller'); + + if (this.grid.hideHeaders) { + lockedHd.setDisplayed(false); + mainHd.setDisplayed(false); + } + + if(this.forceFit){ + scroller.setStyle('overflow-x', 'hidden'); + } + + Ext.apply(this, { + el : el, + mainWrap: mainWrap, + mainHd : mainHd, + innerHd : mainHd.dom.firstChild, + scroller: scroller, + mainBody: scroller.child('div.x-grid3-body'), + focusEl : scroller.child('a'), + resizeMarker: el.child('div.x-grid3-resize-marker'), + resizeProxy : el.child('div.x-grid3-resize-proxy'), + lockedWrap: lockedWrap, + lockedHd: lockedHd, + lockedScroller: lockedScroller, + lockedBody: lockedScroller.child('div.x-grid3-body'), + lockedInnerHd: lockedHd.child('div.x-grid3-header-inner', true) + }); + + this.focusEl.swallowEvent('click', true); + }, + + getLockedRows : function(){ + return this.hasRows() ? this.lockedBody.dom.childNodes : []; + }, + + getLockedRow : function(row){ + return this.getLockedRows()[row]; + }, + + getCell : function(row, col){ + var lockedLen = this.cm.getLockedCount(); + if(col < lockedLen){ + return this.getLockedRow(row).getElementsByTagName('td')[col]; + } + return Ext.ux.grid.LockingGridView.superclass.getCell.call(this, row, col - lockedLen); + }, + + getHeaderCell : function(index){ + var lockedLen = this.cm.getLockedCount(); + if(index < lockedLen){ + return this.lockedHd.dom.getElementsByTagName('td')[index]; + } + return Ext.ux.grid.LockingGridView.superclass.getHeaderCell.call(this, index - lockedLen); + }, + + addRowClass : function(row, cls){ + var lockedRow = this.getLockedRow(row); + if(lockedRow){ + this.fly(lockedRow).addClass(cls); + } + Ext.ux.grid.LockingGridView.superclass.addRowClass.call(this, row, cls); + }, + + removeRowClass : function(row, cls){ + var lockedRow = this.getLockedRow(row); + if(lockedRow){ + this.fly(lockedRow).removeClass(cls); + } + Ext.ux.grid.LockingGridView.superclass.removeRowClass.call(this, row, cls); + }, + + removeRow : function(row) { + Ext.removeNode(this.getLockedRow(row)); + Ext.ux.grid.LockingGridView.superclass.removeRow.call(this, row); + }, + + removeRows : function(firstRow, lastRow){ + var lockedBody = this.lockedBody.dom, + rowIndex = firstRow; + for(; rowIndex <= lastRow; rowIndex++){ + Ext.removeNode(lockedBody.childNodes[firstRow]); + } + Ext.ux.grid.LockingGridView.superclass.removeRows.call(this, firstRow, lastRow); + }, + + syncScroll : function(e){ + this.lockedScroller.dom.scrollTop = this.scroller.dom.scrollTop; + Ext.ux.grid.LockingGridView.superclass.syncScroll.call(this, e); + }, + + updateSortIcon : function(col, dir){ + var sortClasses = this.sortClasses, + lockedHeaders = this.lockedHd.select('td').removeClass(sortClasses), + headers = this.mainHd.select('td').removeClass(sortClasses), + lockedLen = this.cm.getLockedCount(), + cls = sortClasses[dir == 'DESC' ? 1 : 0]; + + if(col < lockedLen){ + lockedHeaders.item(col).addClass(cls); + }else{ + headers.item(col - lockedLen).addClass(cls); + } + }, + + updateAllColumnWidths : function(){ + var tw = this.getTotalWidth(), + clen = this.cm.getColumnCount(), + lw = this.getLockedWidth(), + llen = this.cm.getLockedCount(), + ws = [], len, i; + this.updateLockedWidth(); + for(i = 0; i < clen; i++){ + ws[i] = this.getColumnWidth(i); + var hd = this.getHeaderCell(i); + hd.style.width = ws[i]; + } + var lns = this.getLockedRows(), ns = this.getRows(), row, trow, j; + for(i = 0, len = ns.length; i < len; i++){ + row = lns[i]; + row.style.width = lw; + if(row.firstChild){ + row.firstChild.style.width = lw; + trow = row.firstChild.rows[0]; + for (j = 0; j < llen; j++) { + trow.childNodes[j].style.width = ws[j]; + } + } + row = ns[i]; + row.style.width = tw; + if(row.firstChild){ + row.firstChild.style.width = tw; + trow = row.firstChild.rows[0]; + for (j = llen; j < clen; j++) { + trow.childNodes[j - llen].style.width = ws[j]; + } + } + } + this.onAllColumnWidthsUpdated(ws, tw); + this.syncHeaderHeight(); + }, + + updateColumnWidth : function(col, width){ + var w = this.getColumnWidth(col), + llen = this.cm.getLockedCount(), + ns, rw, c, row; + this.updateLockedWidth(); + if(col < llen){ + ns = this.getLockedRows(); + rw = this.getLockedWidth(); + c = col; + }else{ + ns = this.getRows(); + rw = this.getTotalWidth(); + c = col - llen; + } + var hd = this.getHeaderCell(col); + hd.style.width = w; + for(var i = 0, len = ns.length; i < len; i++){ + row = ns[i]; + row.style.width = rw; + if(row.firstChild){ + row.firstChild.style.width = rw; + row.firstChild.rows[0].childNodes[c].style.width = w; + } + } + this.onColumnWidthUpdated(col, w, this.getTotalWidth()); + this.syncHeaderHeight(); + }, + + updateColumnHidden : function(col, hidden){ + var llen = this.cm.getLockedCount(), + ns, rw, c, row, + display = hidden ? 'none' : ''; + this.updateLockedWidth(); + if(col < llen){ + ns = this.getLockedRows(); + rw = this.getLockedWidth(); + c = col; + }else{ + ns = this.getRows(); + rw = this.getTotalWidth(); + c = col - llen; + } + var hd = this.getHeaderCell(col); + hd.style.display = display; + for(var i = 0, len = ns.length; i < len; i++){ + row = ns[i]; + row.style.width = rw; + if(row.firstChild){ + row.firstChild.style.width = rw; + row.firstChild.rows[0].childNodes[c].style.display = display; + } + } + this.onColumnHiddenUpdated(col, hidden, this.getTotalWidth()); + delete this.lastViewWidth; + this.layout(); + }, + + doRender : function(cs, rs, ds, startRow, colCount, stripe){ + var ts = this.templates, ct = ts.cell, rt = ts.row, last = colCount-1, + tstyle = 'width:'+this.getTotalWidth()+';', + lstyle = 'width:'+this.getLockedWidth()+';', + buf = [], lbuf = [], cb, lcb, c, p = {}, rp = {}, r; + for(var j = 0, len = rs.length; j < len; j++){ + r = rs[j]; cb = []; lcb = []; + var rowIndex = (j+startRow); + for(var i = 0; i < colCount; i++){ + c = cs[i]; + p.id = c.id; + p.css = (i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '')) + + (this.cm.config[i].cellCls ? ' ' + this.cm.config[i].cellCls : ''); + p.attr = p.cellAttr = ''; + p.value = c.renderer(r.data[c.name], p, r, rowIndex, i, ds); + p.style = c.style; + if(Ext.isEmpty(p.value)){ + p.value = ' '; + } + if(this.markDirty && r.dirty && Ext.isDefined(r.modified[c.name])){ + p.css += ' x-grid3-dirty-cell'; + } + if(c.locked){ + lcb[lcb.length] = ct.apply(p); + }else{ + cb[cb.length] = ct.apply(p); + } + } + var alt = []; + if(stripe && ((rowIndex+1) % 2 === 0)){ + alt[0] = 'x-grid3-row-alt'; + } + if(r.dirty){ + alt[1] = ' x-grid3-dirty-row'; + } + rp.cols = colCount; + if(this.getRowClass){ + alt[2] = this.getRowClass(r, rowIndex, rp, ds); + } + rp.alt = alt.join(' '); + rp.cells = cb.join(''); + rp.tstyle = tstyle; + buf[buf.length] = rt.apply(rp); + rp.cells = lcb.join(''); + rp.tstyle = lstyle; + lbuf[lbuf.length] = rt.apply(rp); + } + return [buf.join(''), lbuf.join('')]; + }, + processRows : function(startRow, skipStripe){ + if(!this.ds || this.ds.getCount() < 1){ + return; + } + var rows = this.getRows(), + lrows = this.getLockedRows(), + row, lrow; + skipStripe = skipStripe || !this.grid.stripeRows; + startRow = startRow || 0; + for(var i = 0, len = rows.length; i < len; ++i){ + row = rows[i]; + lrow = lrows[i]; + row.rowIndex = i; + lrow.rowIndex = i; + if(!skipStripe){ + row.className = row.className.replace(this.rowClsRe, ' '); + lrow.className = lrow.className.replace(this.rowClsRe, ' '); + if ((i + 1) % 2 === 0){ + row.className += ' x-grid3-row-alt'; + lrow.className += ' x-grid3-row-alt'; + } + } + this.syncRowHeights(row, lrow); + } + if(startRow === 0){ + Ext.fly(rows[0]).addClass(this.firstRowCls); + Ext.fly(lrows[0]).addClass(this.firstRowCls); + } + Ext.fly(rows[rows.length - 1]).addClass(this.lastRowCls); + Ext.fly(lrows[lrows.length - 1]).addClass(this.lastRowCls); + }, + + syncRowHeights: function(row1, row2){ + if(this.syncHeights){ + var el1 = Ext.get(row1), + el2 = Ext.get(row2), + h1 = el1.getHeight(), + h2 = el2.getHeight(); + + if(h1 > h2){ + el2.setHeight(h1); + }else if(h2 > h1){ + el1.setHeight(h2); + } + } + }, + + afterRender : function(){ + if(!this.ds || !this.cm){ + return; + } + var bd = this.renderRows() || [' ', ' ']; + this.mainBody.dom.innerHTML = bd[0]; + this.lockedBody.dom.innerHTML = bd[1]; + this.processRows(0, true); + if(this.deferEmptyText !== true){ + this.applyEmptyText(); + } + this.grid.fireEvent('viewready', this.grid); + }, + + renderUI : function(){ + var templates = this.templates, + header = this.renderHeaders(), + body = templates.body.apply({rows:' '}); + + return templates.masterTpl.apply({ + body : body, + header: header[0], + ostyle: 'width:' + this.getOffsetWidth() + ';', + bstyle: 'width:' + this.getTotalWidth() + ';', + lockedBody: body, + lockedHeader: header[1], + lstyle: 'width:'+this.getLockedWidth()+';' + }); + }, + + afterRenderUI: function(){ + var g = this.grid; + this.initElements(); + Ext.fly(this.innerHd).on('click', this.handleHdDown, this); + Ext.fly(this.lockedInnerHd).on('click', this.handleHdDown, this); + this.mainHd.on({ + scope: this, + mouseover: this.handleHdOver, + mouseout: this.handleHdOut, + mousemove: this.handleHdMove + }); + this.lockedHd.on({ + scope: this, + mouseover: this.handleHdOver, + mouseout: this.handleHdOut, + mousemove: this.handleHdMove + }); + this.scroller.on('scroll', this.syncScroll, this); + if(g.enableColumnResize !== false){ + this.splitZone = new Ext.grid.GridView.SplitDragZone(g, this.mainHd.dom); + this.splitZone.setOuterHandleElId(Ext.id(this.lockedHd.dom)); + this.splitZone.setOuterHandleElId(Ext.id(this.mainHd.dom)); + } + if(g.enableColumnMove){ + this.columnDrag = new Ext.grid.GridView.ColumnDragZone(g, this.innerHd); + this.columnDrag.setOuterHandleElId(Ext.id(this.lockedInnerHd)); + this.columnDrag.setOuterHandleElId(Ext.id(this.innerHd)); + this.columnDrop = new Ext.grid.HeaderDropZone(g, this.mainHd.dom); + } + if(g.enableHdMenu !== false){ + this.hmenu = new Ext.menu.Menu({id: g.id + '-hctx'}); + this.hmenu.add( + {itemId: 'asc', text: this.sortAscText, cls: 'xg-hmenu-sort-asc'}, + {itemId: 'desc', text: this.sortDescText, cls: 'xg-hmenu-sort-desc'} + ); + if(this.grid.enableColLock !== false){ + this.hmenu.add('-', + {itemId: 'lock', text: this.lockText, cls: 'xg-hmenu-lock'}, + {itemId: 'unlock', text: this.unlockText, cls: 'xg-hmenu-unlock'} + ); + } + if(g.enableColumnHide !== false){ + this.colMenu = new Ext.menu.Menu({id:g.id + '-hcols-menu'}); + this.colMenu.on({ + scope: this, + beforeshow: this.beforeColMenuShow, + itemclick: this.handleHdMenuClick + }); + this.hmenu.add('-', { + itemId:'columns', + hideOnClick: false, + text: this.columnsText, + menu: this.colMenu, + iconCls: 'x-cols-icon' + }); + } + this.hmenu.on('itemclick', this.handleHdMenuClick, this); + } + if(g.trackMouseOver){ + this.mainBody.on({ + scope: this, + mouseover: this.onRowOver, + mouseout: this.onRowOut + }); + this.lockedBody.on({ + scope: this, + mouseover: this.onRowOver, + mouseout: this.onRowOut + }); + } + + if(g.enableDragDrop || g.enableDrag){ + this.dragZone = new Ext.grid.GridDragZone(g, { + ddGroup : g.ddGroup || 'GridDD' + }); + } + this.updateHeaderSortState(); + }, + + layout : function(){ + if(!this.mainBody){ + return; + } + var g = this.grid; + var c = g.getGridEl(); + var csize = c.getSize(true); + var vw = csize.width; + if(!g.hideHeaders && (vw < 20 || csize.height < 20)){ + return; + } + this.syncHeaderHeight(); + if(g.autoHeight){ + this.scroller.dom.style.overflow = 'visible'; + this.lockedScroller.dom.style.overflow = 'visible'; + if(Ext.isWebKit){ + this.scroller.dom.style.position = 'static'; + this.lockedScroller.dom.style.position = 'static'; + } + }else{ + this.el.setSize(csize.width, csize.height); + var hdHeight = this.mainHd.getHeight(); + var vh = csize.height - (hdHeight); + } + this.updateLockedWidth(); + if(this.forceFit){ + if(this.lastViewWidth != vw){ + this.fitColumns(false, false); + this.lastViewWidth = vw; + } + }else { + this.autoExpand(); + this.syncHeaderScroll(); + } + this.onLayout(vw, vh); + }, + + getOffsetWidth : function() { + return (this.cm.getTotalWidth() - this.cm.getTotalLockedWidth() + this.getScrollOffset()) + 'px'; + }, + + renderHeaders : function(){ + var cm = this.cm, + ts = this.templates, + ct = ts.hcell, + cb = [], lcb = [], + p = {}, + len = cm.getColumnCount(), + last = len - 1; + for(var i = 0; i < len; i++){ + p.id = cm.getColumnId(i); + p.value = cm.getColumnHeader(i) || ''; + p.style = this.getColumnStyle(i, true); + p.tooltip = this.getColumnTooltip(i); + p.css = (i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '')) + + (cm.config[i].headerCls ? ' ' + cm.config[i].headerCls : ''); + if(cm.config[i].align == 'right'){ + p.istyle = 'padding-right:16px'; + } else { + delete p.istyle; + } + if(cm.isLocked(i)){ + lcb[lcb.length] = ct.apply(p); + }else{ + cb[cb.length] = ct.apply(p); + } + } + return [ts.header.apply({cells: cb.join(''), tstyle:'width:'+this.getTotalWidth()+';'}), + ts.header.apply({cells: lcb.join(''), tstyle:'width:'+this.getLockedWidth()+';'})]; + }, + + updateHeaders : function(){ + var hd = this.renderHeaders(); + this.innerHd.firstChild.innerHTML = hd[0]; + this.innerHd.firstChild.style.width = this.getOffsetWidth(); + this.innerHd.firstChild.firstChild.style.width = this.getTotalWidth(); + this.lockedInnerHd.firstChild.innerHTML = hd[1]; + var lw = this.getLockedWidth(); + this.lockedInnerHd.firstChild.style.width = lw; + this.lockedInnerHd.firstChild.firstChild.style.width = lw; + }, + + getResolvedXY : function(resolved){ + if(!resolved){ + return null; + } + var c = resolved.cell, r = resolved.row; + return c ? Ext.fly(c).getXY() : [this.scroller.getX(), Ext.fly(r).getY()]; + }, + + syncFocusEl : function(row, col, hscroll){ + Ext.ux.grid.LockingGridView.superclass.syncFocusEl.call(this, row, col, col < this.cm.getLockedCount() ? false : hscroll); + }, + + ensureVisible : function(row, col, hscroll){ + return Ext.ux.grid.LockingGridView.superclass.ensureVisible.call(this, row, col, col < this.cm.getLockedCount() ? false : hscroll); + }, + + insertRows : function(dm, firstRow, lastRow, isUpdate){ + var last = dm.getCount() - 1; + if(!isUpdate && firstRow === 0 && lastRow >= last){ + this.refresh(); + }else{ + if(!isUpdate){ + this.fireEvent('beforerowsinserted', this, firstRow, lastRow); + } + var html = this.renderRows(firstRow, lastRow), + before = this.getRow(firstRow); + if(before){ + if(firstRow === 0){ + this.removeRowClass(0, this.firstRowCls); + } + Ext.DomHelper.insertHtml('beforeBegin', before, html[0]); + before = this.getLockedRow(firstRow); + Ext.DomHelper.insertHtml('beforeBegin', before, html[1]); + }else{ + this.removeRowClass(last - 1, this.lastRowCls); + Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html[0]); + Ext.DomHelper.insertHtml('beforeEnd', this.lockedBody.dom, html[1]); + } + if(!isUpdate){ + this.fireEvent('rowsinserted', this, firstRow, lastRow); + this.processRows(firstRow); + }else if(firstRow === 0 || firstRow >= last){ + this.addRowClass(firstRow, firstRow === 0 ? this.firstRowCls : this.lastRowCls); + } + } + this.syncFocusEl(firstRow); + }, + + getColumnStyle : function(col, isHeader){ + var style = !isHeader ? this.cm.config[col].cellStyle || this.cm.config[col].css || '' : this.cm.config[col].headerStyle || ''; + style += 'width:'+this.getColumnWidth(col)+';'; + if(this.cm.isHidden(col)){ + style += 'display:none;'; + } + var align = this.cm.config[col].align; + if(align){ + style += 'text-align:'+align+';'; + } + return style; + }, + + getLockedWidth : function() { + return this.cm.getTotalLockedWidth() + 'px'; + }, + + getTotalWidth : function() { + return (this.cm.getTotalWidth() - this.cm.getTotalLockedWidth()) + 'px'; + }, + + getColumnData : function(){ + var cs = [], cm = this.cm, colCount = cm.getColumnCount(); + for(var i = 0; i < colCount; i++){ + var name = cm.getDataIndex(i); + cs[i] = { + name : (!Ext.isDefined(name) ? this.ds.fields.get(i).name : name), + renderer : cm.getRenderer(i), + scope : cm.getRendererScope(i), + id : cm.getColumnId(i), + style : this.getColumnStyle(i), + locked : cm.isLocked(i) + }; + } + return cs; + }, + + renderBody : function(){ + var markup = this.renderRows() || [' ', ' ']; + return [this.templates.body.apply({rows: markup[0]}), this.templates.body.apply({rows: markup[1]})]; + }, + + refreshRow: function(record){ + var store = this.ds, + colCount = this.cm.getColumnCount(), + columns = this.getColumnData(), + last = colCount - 1, + cls = ['x-grid3-row'], + rowParams = { + tstyle: String.format("width: {0};", this.getTotalWidth()) + }, + lockedRowParams = { + tstyle: String.format("width: {0};", this.getLockedWidth()) + }, + colBuffer = [], + lockedColBuffer = [], + cellTpl = this.templates.cell, + rowIndex, + row, + lockedRow, + column, + meta, + css, + i; + + if (Ext.isNumber(record)) { + rowIndex = record; + record = store.getAt(rowIndex); + } else { + rowIndex = store.indexOf(record); + } + + if (!record || rowIndex < 0) { + return; + } + + for (i = 0; i < colCount; i++) { + column = columns[i]; + + if (i == 0) { + css = 'x-grid3-cell-first'; + } else { + css = (i == last) ? 'x-grid3-cell-last ' : ''; + } + + meta = { + id: column.id, + style: column.style, + css: css, + attr: "", + cellAttr: "" + }; + + meta.value = column.renderer.call(column.scope, record.data[column.name], meta, record, rowIndex, i, store); + + if (Ext.isEmpty(meta.value)) { + meta.value = ' '; + } + + if (this.markDirty && record.dirty && typeof record.modified[column.name] != 'undefined') { + meta.css += ' x-grid3-dirty-cell'; + } + + if (column.locked) { + lockedColBuffer[i] = cellTpl.apply(meta); + } else { + colBuffer[i] = cellTpl.apply(meta); + } + } + + row = this.getRow(rowIndex); + row.className = ''; + lockedRow = this.getLockedRow(rowIndex); + lockedRow.className = ''; + + if (this.grid.stripeRows && ((rowIndex + 1) % 2 === 0)) { + cls.push('x-grid3-row-alt'); + } + + if (this.getRowClass) { + rowParams.cols = colCount; + cls.push(this.getRowClass(record, rowIndex, rowParams, store)); + } + + // Unlocked rows + this.fly(row).addClass(cls).setStyle(rowParams.tstyle); + rowParams.cells = colBuffer.join(""); + row.innerHTML = this.templates.rowInner.apply(rowParams); + + // Locked rows + this.fly(lockedRow).addClass(cls).setStyle(lockedRowParams.tstyle); + lockedRowParams.cells = lockedColBuffer.join(""); + lockedRow.innerHTML = this.templates.rowInner.apply(lockedRowParams); + lockedRow.rowIndex = rowIndex; + this.syncRowHeights(row, lockedRow); + this.fireEvent('rowupdated', this, rowIndex, record); + }, + + refresh : function(headersToo){ + this.fireEvent('beforerefresh', this); + this.grid.stopEditing(true); + var result = this.renderBody(); + this.mainBody.update(result[0]).setWidth(this.getTotalWidth()); + this.lockedBody.update(result[1]).setWidth(this.getLockedWidth()); + if(headersToo === true){ + this.updateHeaders(); + this.updateHeaderSortState(); + } + this.processRows(0, true); + this.layout(); + this.applyEmptyText(); + this.fireEvent('refresh', this); + }, + + onDenyColumnLock : function(){ + + }, + + initData : function(ds, cm){ + if(this.cm){ + this.cm.un('columnlockchange', this.onColumnLock, this); + } + Ext.ux.grid.LockingGridView.superclass.initData.call(this, ds, cm); + if(this.cm){ + this.cm.on('columnlockchange', this.onColumnLock, this); + } + }, + + onColumnLock : function(){ + this.refresh(true); + }, + + handleHdMenuClick : function(item){ + var index = this.hdCtxIndex, + cm = this.cm, + id = item.getItemId(), + llen = cm.getLockedCount(); + switch(id){ + case 'lock': + if(cm.getColumnCount(true) <= llen + 1){ + this.onDenyColumnLock(); + return undefined; + } + cm.setLocked(index, true, llen != index); + if(llen != index){ + cm.moveColumn(index, llen); + this.grid.fireEvent('columnmove', index, llen); + } + break; + case 'unlock': + if(llen - 1 != index){ + cm.setLocked(index, false, true); + cm.moveColumn(index, llen - 1); + this.grid.fireEvent('columnmove', index, llen - 1); + }else{ + cm.setLocked(index, false); + } + break; + default: + return Ext.ux.grid.LockingGridView.superclass.handleHdMenuClick.call(this, item); + } + return true; + }, + + handleHdDown : function(e, t){ + Ext.ux.grid.LockingGridView.superclass.handleHdDown.call(this, e, t); + if(this.grid.enableColLock !== false){ + if(Ext.fly(t).hasClass('x-grid3-hd-btn')){ + var hd = this.findHeaderCell(t), + index = this.getCellIndex(hd), + ms = this.hmenu.items, cm = this.cm; + ms.get('lock').setDisabled(cm.isLocked(index)); + ms.get('unlock').setDisabled(!cm.isLocked(index)); + } + } + }, + + syncHeaderHeight: function(){ + var hrow = Ext.fly(this.innerHd).child('tr', true), + lhrow = Ext.fly(this.lockedInnerHd).child('tr', true); + + hrow.style.height = 'auto'; + lhrow.style.height = 'auto'; + var hd = hrow.offsetHeight, + lhd = lhrow.offsetHeight, + height = Math.max(lhd, hd) + 'px'; + + hrow.style.height = height; + lhrow.style.height = height; + + }, + + updateLockedWidth: function(){ + var lw = this.cm.getTotalLockedWidth(), + tw = this.cm.getTotalWidth() - lw, + csize = this.grid.getGridEl().getSize(true), + lp = Ext.isBorderBox ? 0 : this.lockedBorderWidth, + rp = Ext.isBorderBox ? 0 : this.rowBorderWidth, + vw = Math.max(csize.width - lw - lp - rp, 0) + 'px', + so = this.getScrollOffset(); + if(!this.grid.autoHeight){ + var vh = Math.max(csize.height - this.mainHd.getHeight(), 0) + 'px'; + this.lockedScroller.dom.style.height = vh; + this.scroller.dom.style.height = vh; + } + this.lockedWrap.dom.style.width = (lw + rp) + 'px'; + this.scroller.dom.style.width = vw; + this.mainWrap.dom.style.left = (lw + lp + rp) + 'px'; + if(this.innerHd){ + this.lockedInnerHd.firstChild.style.width = lw + 'px'; + this.lockedInnerHd.firstChild.firstChild.style.width = lw + 'px'; + this.innerHd.style.width = vw; + this.innerHd.firstChild.style.width = (tw + rp + so) + 'px'; + this.innerHd.firstChild.firstChild.style.width = tw + 'px'; + } + if(this.mainBody){ + this.lockedBody.dom.style.width = (lw + rp) + 'px'; + this.mainBody.dom.style.width = (tw + rp) + 'px'; + } + } +}); + +Ext.ux.grid.LockingColumnModel = Ext.extend(Ext.grid.ColumnModel, { + /** + * Returns true if the given column index is currently locked + * @param {Number} colIndex The column index + * @return {Boolean} True if the column is locked + */ + isLocked : function(colIndex){ + return this.config[colIndex].locked === true; + }, + + /** + * Locks or unlocks a given column + * @param {Number} colIndex The column index + * @param {Boolean} value True to lock, false to unlock + * @param {Boolean} suppressEvent Pass false to cause the columnlockchange event not to fire + */ + setLocked : function(colIndex, value, suppressEvent){ + if (this.isLocked(colIndex) == value) { + return; + } + this.config[colIndex].locked = value; + if (!suppressEvent) { + this.fireEvent('columnlockchange', this, colIndex, value); + } + }, + + /** + * Returns the total width of all locked columns + * @return {Number} The width of all locked columns + */ + getTotalLockedWidth : function(){ + var totalWidth = 0; + for (var i = 0, len = this.config.length; i < len; i++) { + if (this.isLocked(i) && !this.isHidden(i)) { + totalWidth += this.getColumnWidth(i); + } + } + + return totalWidth; + }, + + /** + * Returns the total number of locked columns + * @return {Number} The number of locked columns + */ + getLockedCount : function() { + var len = this.config.length; + + for (var i = 0; i < len; i++) { + if (!this.isLocked(i)) { + return i; + } + } + + //if we get to this point all of the columns are locked so we return the total + return len; + }, + + /** + * Moves a column from one position to another + * @param {Number} oldIndex The current column index + * @param {Number} newIndex The destination column index + */ + moveColumn : function(oldIndex, newIndex){ + var oldLocked = this.isLocked(oldIndex), + newLocked = this.isLocked(newIndex); + + if (oldIndex < newIndex && oldLocked && !newLocked) { + this.setLocked(oldIndex, false, true); + } else if (oldIndex > newIndex && !oldLocked && newLocked) { + this.setLocked(oldIndex, true, true); + } + + Ext.ux.grid.LockingColumnModel.superclass.moveColumn.apply(this, arguments); + } +}); diff --git a/core/components/babel/controllers/default/index.class.php b/core/components/babel/controllers/default/index.class.php new file mode 100644 index 0000000..15551e7 --- /dev/null +++ b/core/components/babel/controllers/default/index.class.php @@ -0,0 +1,48 @@ +babel = new Babel($this->modx); + $this->addCss($this->babel->config['cssUrl'] . 'babel.css'); + $this->addJavascript($this->babel->config['jsUrl'] . 'mgr/babel.js'); + $this->addHtml(''); + return parent::initialize(); + + } + + public function getLanguageTopics() { + return array('babel:default', 'babel:cmp'); + } + + public function loadCustomCssJs() { + $this->addJavascript($this->babel->config['jsUrl'] . 'mgr/widgets/combo.context.js'); + $this->addCss($this->babel->config['jsUrl'] . 'ux/LockingGridView/LockingGridView.css'); + $this->addJavascript($this->babel->config['jsUrl'] . 'ux/LockingGridView/LockingGridView.js'); + $this->addJavascript($this->babel->config['jsUrl'] . 'mgr/widgets/grid.resourcematrix.js'); + $this->addJavascript($this->babel->config['jsUrl'] . 'mgr/widgets/panel.home.js'); + $this->addLastJavascript($this->babel->config['jsUrl'] . 'mgr/sections/index.js'); + } + + public function process(array $scriptProperties = array()) { + + } + + public function getPageTitle() { + return $this->modx->lexicon('babel'); + } + + public function getTemplateFile() { + return 'index.tpl'; + } + +} diff --git a/core/components/babel/docs/changelog.txt b/core/components/babel/docs/changelog.txt index 33384fa..f6bedf4 100644 --- a/core/components/babel/docs/changelog.txt +++ b/core/components/babel/docs/changelog.txt @@ -1,5 +1,9 @@ Changelog for Babel. +Babel 3.0.0-rc1 (April 15, 2016) +===================================== +- added Custom Manager Page for resources matrix, supported by Steven Morgan of Waterlogic + Babel 3.0.0-beta5 (March 22, 2016) ===================================== - updated plugin to ignore menu if the current context key is not included "babel.contextKeys" in System Settings diff --git a/core/components/babel/lexicon/en/cmp.inc.php b/core/components/babel/lexicon/en/cmp.inc.php new file mode 100644 index 0000000..c90e6e5 --- /dev/null +++ b/core/components/babel/lexicon/en/cmp.inc.php @@ -0,0 +1,43 @@ + + * + * This file is part of Babel. + * + * Babel is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Babel is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * Babel; if not, write to the Free Software Foundation, Inc., 59 Temple Place, + * Suite 330, Boston, MA 02111-1307 USA + * + * @package babel + */ +/** + * Babel English language file + * + * @author Jakob Class + * goldsky + * + * @package babel + * @subpackage lexicon + * + */ + +$_lang['babel'] = 'Babel'; +$_lang['babel.desc'] = 'Managing multilingual system'; +$_lang['babel.search...'] = 'Search...'; +$_lang['babel.filter'] = 'Filter'; +$_lang['babel.reset'] = 'Reset'; +$_lang['babel.icon_descriptions'] = ' Link to this resource and its linked resources
' + . ' Break all links
' + . ' Edit this linked resource
' + . ' Create a new resource to be linked
'; diff --git a/core/components/babel/lexicon/en/default.inc.php b/core/components/babel/lexicon/en/default.inc.php index 4c1d8b9..e3f26a1 100644 --- a/core/components/babel/lexicon/en/default.inc.php +++ b/core/components/babel/lexicon/en/default.inc.php @@ -33,6 +33,8 @@ * @todo complete babel.language_xx entries for every language */ +$_lang['babel'] = 'Babel'; +$_lang['babel.desc'] = 'Managing multilingual system'; $_lang['babel.tv_caption'] = 'Babel Translation Links'; $_lang['babel.tv_description'] = 'Maintained by Babel plugin. Please do not change!'; $_lang['babel.create_translation'] = 'Create translation'; diff --git a/core/components/babel/lexicon/nl/default.inc.php b/core/components/babel/lexicon/nl/default.inc.php index 6aa5182..9213037 100755 --- a/core/components/babel/lexicon/nl/default.inc.php +++ b/core/components/babel/lexicon/nl/default.inc.php @@ -1,7 +1,7 @@ * @author Wieger Sloot * @@ -62,7 +62,7 @@ $_lang['babel.language_tr'] = 'Turks'; $_lang['babel.language_uk'] = 'Oekraïens'; $_lang['babel.language_vi'] = 'Vietnamees'; -$_lang['babel.language_zh'] = 'Chinees'; +$_lang['babel.language_zh'] = 'Chinees'; /* error messages */ $_lang['error.invalid_context_key'] = '[[+context]] is geen geldige channel key.'; diff --git a/core/components/babel/model/babel/babel.class.php b/core/components/babel/model/babel/babel.class.php index 0053856..895684b 100644 --- a/core/components/babel/model/babel/babel.class.php +++ b/core/components/babel/model/babel/babel.class.php @@ -34,7 +34,7 @@ class Babel { const VERSION = '3.0.0'; - const RELEASE = 'beta5'; + const RELEASE = 'rc1'; /** * @access protected diff --git a/core/components/babel/processors/mgr/context/getlist.class.php b/core/components/babel/processors/mgr/context/getlist.class.php new file mode 100644 index 0000000..ff33714 --- /dev/null +++ b/core/components/babel/processors/mgr/context/getlist.class.php @@ -0,0 +1,73 @@ + + * + * This file is part of Babel. + * + * Babel is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Babel is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * Babel; if not, write to the Free Software Foundation, Inc., 59 Temple Place, + * Suite 330, Boston, MA 02111-1307 USA + * + * @package babel + */ +/** + * Processor file for Babel. + * + * @author goldsky + * + * @package babel + */ +include_once MODX_CORE_PATH . 'model/modx/processors/context/getlist.class.php'; + +class BabelContextGetListProcessor extends modContextGetListProcessor { + + public function initialize() { + $initialized = parent::initialize(); + $this->setDefaultProperties(array( + 'search' => '', + 'exclude' => 'mgr', + )); + $this->canEdit = false; + $this->canRemove = false; + return $initialized; + } + + public function beforeIteration(array $list) { + if ($this->getProperty('combo', false)) { + $empty = array( + 'key' => '', + 'name' => ' ', + ); + $list[] = $empty; + } + + return $list; + } + + public function prepareRow(xPDOObject $object) { + $objectArray = parent::prepareRow($object); + if ($this->getProperty('combo', false)) { + $objectArray = array( + 'key' => $objectArray['key'], + 'name' => $objectArray['name'], + ); + } + + return $objectArray; + } + +} + +return 'BabelContextGetListProcessor'; diff --git a/core/components/babel/processors/mgr/resource/getmatrixlist.class.php b/core/components/babel/processors/mgr/resource/getmatrixlist.class.php new file mode 100644 index 0000000..158d16c --- /dev/null +++ b/core/components/babel/processors/mgr/resource/getmatrixlist.class.php @@ -0,0 +1,88 @@ + + * + * This file is part of Babel. + * + * Babel is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Babel is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * Babel; if not, write to the Free Software Foundation, Inc., 59 Temple Place, + * Suite 330, Boston, MA 02111-1307 USA + * + * @package babel + */ +/** + * Processor file for Babel. + * + * @author goldsky + * + * @package babel + */ +include_once MODX_CORE_PATH . 'model/modx/processors/resource/getlist.class.php'; + +class BabelResourceGetMatrixListProcessor extends modResourceGetListProcessor { + public $defaultSortField = 'id'; + private $_contexts = array(); + + public function initialize() { + $this->_contexts = array_map('trim', @explode(',', $this->getProperty('contexts'))); + + return parent::initialize(); + } + + public function prepareQueryBeforeCount(xPDOQuery $c) { + $query = $this->getProperty('query'); + if (!empty($query)) { + $c->where(array( + 'pagetitle:LIKE' => "$query%" + )); + } + $ctx = $this->getProperty('context'); + if (!empty($ctx)) { + $c->where(array( + 'context_key:=' => $ctx + )); + } + return $c; + } + + public function prepareRow(xPDOObject $object) { + $objectArray = $object->toArray(); + // 'id' conflicts with Indonesian's ISO code 'id' + + $linkedResources = $this->modx->babel->getLinkedResources($objectArray['id']); + foreach ($this->_contexts as $ctx) { + // 'id' conflicts with Indonesian's ISO code 'id' + // prepend with a suffix + $objectArray['linkedres_id_' . $ctx] = ''; + $objectArray['linkedres_pagetitle_' . $ctx] = ''; + if ($objectArray['context_key'] === $ctx) { + $objectArray['linkedres_id_' . $ctx] = 'x'; + $objectArray['linkedres_pagetitle_' . $ctx] = 'x'; + } else { + if (isset($linkedResources[$ctx]) && !empty($linkedResources[$ctx])) { + $objectArray['linkedres_id_' . $ctx] = $linkedResources[$ctx]; + $resource = $this->modx->getObject('modResource', $linkedResources[$ctx]); + if ($resource) { + $objectArray['linkedres_pagetitle_' . $ctx] = $resource->get('pagetitle'); + } + } + } + } + + return $objectArray; + } +} + +return 'BabelResourceGetMatrixListProcessor'; diff --git a/core/components/babel/templates/default/index.tpl b/core/components/babel/templates/default/index.tpl new file mode 100644 index 0000000..1cbd957 --- /dev/null +++ b/core/components/babel/templates/default/index.tpl @@ -0,0 +1 @@ +
\ No newline at end of file