diff --git a/UPGRADE.md b/UPGRADE.md index e4a4fa8f..c255b2d5 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -8,6 +8,7 @@ Just click the "update" button or execute the migration command to finish the bu #### Update from Version 2.6.x to Version 2.7.0 - **[ATTENTION]**: Installer has moved to the [MigrationBundle](https://github.com/dachcom-digital/pimcore-toolbox/issues/89). After updating to this version you need to enable this extension again! +- **[NEW FEATURE]**: Parameter for video elements (e.g. youtube api parameters) - ([Milestone for 2.7.0](https://github.com/dachcom-digital/pimcore-toolbox/milestone/12?closed=1)) #### Update from Version 2.6.4 to Version 2.6.5 diff --git a/src/ToolboxBundle/Document/Areabrick/Video/Video.php b/src/ToolboxBundle/Document/Areabrick/Video/Video.php index 8e47518b..4c885cf9 100644 --- a/src/ToolboxBundle/Document/Areabrick/Video/Video.php +++ b/src/ToolboxBundle/Document/Areabrick/Video/Video.php @@ -22,7 +22,9 @@ public function action(Info $info) /** @var \ToolboxBundle\Model\Document\Tag\Vhs $videoTag */ $videoTag = $this->getDocumentTag($info->getDocument(), 'vhs', 'video'); - $playInLightBox = $videoTag->getShowAsLightbox() === true ? 'true' : 'false'; + $videoParameter = $videoTag->getVideoParameter(); + + $playInLightBox = $videoTag->getShowAsLightBox() === true ? 'true' : 'false'; /** @var \Pimcore\Model\Document\Tag\Checkbox $autoPlayElement */ $autoPlayElement = $this->getDocumentTag($info->getDocument(), 'checkbox', 'autoplay'); $autoPlay = $autoPlayElement->isChecked() === true && !$view->get('editmode'); @@ -42,6 +44,7 @@ public function action(Info $info) 'posterPath' => $posterPath, 'videoType' => $videoType, 'playInLightbox' => $playInLightBox, + 'videoParameter' => $videoParameter, 'videoId' => $videoId ]); } diff --git a/src/ToolboxBundle/Model/Document/Tag/Vhs.php b/src/ToolboxBundle/Model/Document/Tag/Vhs.php index e116050b..e16e6d75 100644 --- a/src/ToolboxBundle/Model/Document/Tag/Vhs.php +++ b/src/ToolboxBundle/Model/Document/Tag/Vhs.php @@ -10,14 +10,19 @@ class Vhs extends Model\Document\Tag\Video /** * @var bool */ - public $showAsLightbox = false; + public $showAsLightBox = false; /** * Enum: [asset, youtube, vimeo, dailymotion]. * * @var string */ - public $type = ''; + public $type; + + /** + * @var array + */ + public $videoParameter; /** * Return the type of the element. @@ -30,42 +35,52 @@ public function getType() } /** - * @param bool $showAsLightbox - * - * @return $this + * @return string */ - public function setShowAsLightbox($showAsLightbox) + public function getShowAsLightBox() { - $this->showAsLightbox = $showAsLightbox; - - return $this; + return $this->showAsLightBox; } /** - * @return string + * @return array */ - public function getShowAsLightbox() + public function getVideoParameter() { - return $this->showAsLightbox; + if (!is_array($this->videoParameter)) { + return []; + } + + $parsedParameter = []; + foreach ($this->videoParameter as $parameter) { + $parsedParameter[$parameter['key']] = $parameter['value']; + } + + return $parsedParameter; } /** * @see Document\Tag\TagInterface::getData * - * @return mixed + * @return array */ public function getData() { $data = parent::getData(); - $data['showAsLightbox'] = $this->showAsLightbox; + $data['showAsLightbox'] = $this->showAsLightBox; + $data['videoParameter'] = $this->videoParameter; return $data; } + /** + * @return array + */ public function getDataForResource() { $data = parent::getDataForResource(); - $data['showAsLightbox'] = $this->showAsLightbox; + $data['showAsLightbox'] = $this->showAsLightBox; + $data['videoParameter'] = $this->videoParameter; return $data; } @@ -85,7 +100,8 @@ public function setDataFromResource($data) $data = \Pimcore\Tool\Serialize::unserialize($data); } - $this->showAsLightbox = $data['showAsLightbox']; + $this->showAsLightBox = $data['showAsLightbox']; + $this->videoParameter = $data['videoParameter']; return $this; } @@ -102,7 +118,11 @@ public function setDataFromEditmode($data) parent::setDataFromEditmode($data); if ($data['showAsLightbox']) { - $this->showAsLightbox = $data['showAsLightbox']; + $this->showAsLightBox = $data['showAsLightbox']; + } + + if ($data['videoParameter']) { + $this->videoParameter = $data['videoParameter']; } return $this; diff --git a/src/ToolboxBundle/Resources/public/js/document/helpers.js b/src/ToolboxBundle/Resources/public/js/document/helpers.js deleted file mode 100644 index cf306894..00000000 --- a/src/ToolboxBundle/Resources/public/js/document/helpers.js +++ /dev/null @@ -1,270 +0,0 @@ -/** - * Pimcore - * - * This source file is available under two different licenses: - * - GNU General Public License version 3 (GPLv3) - * - Pimcore Enterprise License (PEL) - * Full copyright and license information is available in - * LICENSE.md which is distributed with this source code. - * - * @copyright Copyright (c) 2009-2016 pimcore GmbH (http://www.pimcore.org) - * @license http://www.pimcore.org/license GPLv3 and PEL - */ - -/*global localStorage */ -pimcore.registerNS("pimcore.helpers.x"); - -pimcore.helpers.editmode.openVhsEditPanel = function (data, callback) { - - var form = null; - var fieldPath = new Ext.form.TextField({ - fieldLabel: t('path'), - itemId: "path", - value: data.path, - name: "path", - width: 420, - fieldCls: "pimcore_droptarget_input", - enableKeyEvents: true, - listeners: { - keyup: function (el) { - if((el.getValue().indexOf("youtu.be") >= 0 || el.getValue().indexOf("youtube.com") >= 0) && el.getValue().indexOf("http") >= 0) { - form.getComponent("type").setValue("youtube"); - } else if (el.getValue().indexOf("vimeo") >= 0 && el.getValue().indexOf("http") >= 0) { - form.getComponent("type").setValue("vimeo"); - } else if ((el.getValue().indexOf("dai.ly") >= 0 || el.getValue().indexOf("dailymotion") >= 0) && el.getValue().indexOf("http") >= 0) { - form.getComponent("type").setValue("dailymotion"); - } - }.bind(this) - } - }); - - var poster = new Ext.form.TextField({ - fieldLabel: t('poster_image'), - value: data.poster, - name: "poster", - width: 420, - fieldCls: "pimcore_droptarget_input", - enableKeyEvents: true, - listeners: { - keyup: function (el) { - //el.setValue(data.poster) - }.bind(this) - } - }); - - var initDD = function (el) { - // register at global DnD manager - new Ext.dd.DropZone(el.getEl(), { - reference: this, - ddGroup: "element", - getTargetFromEvent: function(e) { - return el.getEl(); - }, - - onNodeOver : function(target, dd, e, data) { - data = data.records[0].data; - if (target && target.getId() == poster.getId()) { - if (data.elementType == "asset" && data.type == "image") { - return Ext.dd.DropZone.prototype.dropAllowed; - } - } else { - if (data.elementType == "asset" && data.type == "video") { - return Ext.dd.DropZone.prototype.dropAllowed; - } - } - return Ext.dd.DropZone.prototype.dropNotAllowed; - }.bind(this), - - onNodeDrop : function (target, dd, e, data) { - if(target) { - data = data.records[0].data; - - if(target.getId() == fieldPath.getId()) { - if (data.elementType == "asset" && data.type == "video") { - fieldPath.setValue(data.path); - form.getComponent("type").setValue("asset"); - return true; - } - } else if (target.getId() == poster.getId()) { - if (data.elementType == "asset" && data.type == "image") { - poster.setValue(data.path); - return true; - } - } - } - - return false; - }.bind(this) - }); - }; - - fieldPath.on("render", initDD); - poster.on("render", initDD); - - var searchButton = new Ext.Button({ - iconCls: "pimcore_icon_search", - handler: function () { - pimcore.helpers.itemselector(false, function (item) { - if (item) { - fieldPath.setValue(item.fullpath); - return true; - } - }, { - type: ["asset"], - subtype: { - asset: ["video"] - } - }); - } - }); - - var updateType = function (type, typeInfo) { - - var typeConfig = typeInfo.get('config'); - - searchButton.enable(); - - var labelEl = form.getComponent("pathContainer").getComponent("path").labelEl, - lightboxEl = form.getComponent("showAsLightbox"); - - labelEl.update(t("path")); - - if(type != "asset") { - searchButton.disable(); - } - - if(type == "youtube") { - labelEl.update("ID"); - } - - if(type == "vimeo") { - labelEl.update("ID"); - } - - if(type == "dailymotion") { - labelEl.update("ID"); - } - - if ( !typeConfig.allow_lightbox ) { - lightboxEl.hide(); - } else { - lightboxEl.show(); - } - - if (typeConfig.id_label) { - labelEl.update(typeConfig.id_label); - } - - }; - - var videoTypeStore = new Ext.data.JsonStore({ - autoLoad: true, - fields: ['name', 'value', 'config'], - proxy: { - type: 'ajax', - url: '/toolbox/ajax/video-allowed-video-types', - reader: { - type: 'json' - } - } - }); - - form = new Ext.FormPanel({ - itemId: "form", - bodyStyle: "padding:10px;", - items: - [ - { - xtype: "combo", - itemId: "type", - fieldLabel: t('type'), - displayField: 'name', - name: 'type', - triggerAction: 'all', - editable: false, - width: 270, - mode: "local", - store: videoTypeStore, - value: data.type, - listeners: { - select: function (combo) { - var type = combo.getValue(); - updateType(type, videoTypeStore.findRecord('name', type)); - }.bind(this) - } - }, - { - xtype: "fieldcontainer", - layout: 'hbox', - border: false, - itemId: "pathContainer", - items: [fieldPath, searchButton] - }, - poster, - { - xtype: "checkbox", - itemId: "showAsLightbox", - checked: false, - name: "showAsLightbox", - fieldLabel: t('show in lightbox'), - value: data.showAsLightbox - }, - { - xtype: "textfield", - name: "title", - itemId: "title", - fieldLabel: t('title'), - width: 420, - value: data.title - }, - { - xtype: "textarea", - itemId: "description", - name: "description", - fieldLabel: t('description'), - width: 420, - height: 50, - value: data.description - } - ], - buttons: [ - { - text: t("cancel"), - listeners: { - "click": callback["cancel"] - } - }, - { - text: t("save"), - listeners: { - "click": callback["save"] - }, - iconCls: "pimcore_icon_save" - } - ] - }); - - - var window = new Ext.Window({ - width: 500, - height: 450, - scrollable: true, - title: t("video"), - items: [form], - layout: "fit", - listeners: { - afterrender: function () { - videoTypeStore.load({ - scope: this, - callback: function(records, operation, success) { - updateType(data.type, videoTypeStore.findRecord('name', data.type)); - } - }); - - }.bind(this) - } - }); - window.show(); - - return window; -}; \ No newline at end of file diff --git a/src/ToolboxBundle/Resources/public/js/document/tags/vhs.js b/src/ToolboxBundle/Resources/public/js/document/tags/vhs.js index f0a5ece1..348009ed 100644 --- a/src/ToolboxBundle/Resources/public/js/document/tags/vhs.js +++ b/src/ToolboxBundle/Resources/public/js/document/tags/vhs.js @@ -1,12 +1,11 @@ pimcore.registerNS('pimcore.document.tags.vhs'); pimcore.document.tags.vhs = Class.create(pimcore.document.tags.video, { - initialize: function(id, name, options, data, inherited) { + initialize: function(id, name, options, data) { this.id = id; this.name = name; - this.data = {}; - + this.videoEditor = {}; this.options = this.parseOptions(options); this.data = data; @@ -33,14 +32,22 @@ pimcore.document.tags.vhs = Class.create(pimcore.document.tags.video, { }, openEditor: function () { - - // disable the global dnd handler in this editmode/frame - window.dndManager.disable(); - - this.window = pimcore.helpers.editmode.openVhsEditPanel(this.data, { + this.videoEditor = new pimcore.plugin.toolbox.vhs.editor(this.data, { save: this.save.bind(this), cancel: this.cancel.bind(this) }); + + this.videoEditor.loadWindow(); + }, + + save: function () { + this.data = this.videoEditor.getFieldValues(); + this.videoEditor.hideWindow(); + this.reloadDocument(); + }, + + cancel: function () { + this.videoEditor.hideWindow(); }, getType: function () { diff --git a/src/ToolboxBundle/Resources/public/js/document/tags/vhs/editor.js b/src/ToolboxBundle/Resources/public/js/document/tags/vhs/editor.js new file mode 100644 index 00000000..03f04cd1 --- /dev/null +++ b/src/ToolboxBundle/Resources/public/js/document/tags/vhs/editor.js @@ -0,0 +1,397 @@ +pimcore.registerNS('pimcore.plugin.toolbox.vhs.editor'); +pimcore.plugin.toolbox.vhs.editor = Class.create({ + + data: null, + callbacks: {}, + window: {}, + form: {}, + videoTypeStore: {}, + videoParameterStore: {}, + + initialize: function (data, callbacks) { + this.data = data; + this.callbacks = callbacks; + + this.initVideoTypesStore(); + }, + + loadWindow: function () { + + document.body.classList.add('toolbox-modal-open'); + + this.loadForm(); + + this.window = new Ext.Window({ + width: 500, + maxHeight: 650, + scrollable: 'y', + modal: false, + resizable: true, + closable: false, + title: t('video'), + items: [this.form], + listeners: { + afterrender: function () { + this.videoTypeStore.load({ + scope: this, + callback: function () { + this.updateVideoType(this.data.type, this.videoTypeStore.findRecord('name', this.data.type)); + this.form.updateLayout(); + }.bind(this) + }); + + }.bind(this) + } + }); + + this.window.show(); + }, + + loadForm: function () { + + this.form = new Ext.FormPanel({ + itemId: 'form', + bodyStyle: 'padding:10px;', + items: + [ + { + xtype: 'combo', + itemId: 'type', + fieldLabel: t('type'), + displayField: 'name', + name: 'type', + triggerAction: 'all', + editable: false, + width: 270, + mode: 'local', + store: this.videoTypeStore, + value: this.data.type, + listeners: { + select: function (combo) { + this.updateVideoType(combo.getValue(), this.videoTypeStore.findRecord('name', combo.getValue())); + }.bind(this) + } + }, + { + xtype: 'fieldcontainer', + layout: 'hbox', + border: false, + itemId: 'pathContainer', + items: [ + { + xtype: 'textfield', + fieldLabel: t('path'), + itemId: 'path', + name: 'path', + width: 420, + fieldCls: 'pimcore_droptarget_input', + enableKeyEvents: true, + value: this.data.path, + listeners: { + render: function (el) { + dndManager.addDropTarget(el.getEl(), this.onNodeOver.bind(this), this.onNodeDrop.bind(this)); + }.bind(this), + keyup: function (el) { + if ((el.getValue().indexOf('youtu.be') >= 0 || el.getValue().indexOf('youtube.com') >= 0) && el.getValue().indexOf('http') >= 0) { + this.up('form').getComponent('type').setValue('youtube'); + } else if (el.getValue().indexOf('vimeo') >= 0 && el.getValue().indexOf('http') >= 0) { + this.up('form').getComponent('type').setValue('vimeo'); + } else if ((el.getValue().indexOf('dai.ly') >= 0 || el.getValue().indexOf('dailymotion') >= 0) && el.getValue().indexOf('http') >= 0) { + this.up('form').getComponent('type').setValue('dailymotion'); + } + }.bind(this) + } + }, + { + xtype: 'button', + iconCls: 'pimcore_icon_search', + itemId: 'searchButton', + handler: function () { + pimcore.helpers.itemselector(false, function (item) { + if (item) { + this.up('form').getComponent('path').setValue(item.fullpath); + return true; + } + }, { + type: ['asset'], + subtype: { + asset: ['video'] + } + }); + } + } + ] + }, + { + xtype: 'textfield', + itemId: 'poster', + fieldLabel: t('poster_image'), + name: 'poster', + width: 420, + fieldCls: 'pimcore_droptarget_input', + enableKeyEvents: true, + value: this.data.poster, + listeners: { + render: function (el) { + dndManager.addDropTarget(el.getEl(), this.onNodeOver.bind(this), this.onNodeDrop.bind(this)); + }.bind(this) + }, + }, + { + xtype: 'checkbox', + itemId: 'showAsLightbox', + checked: false, + name: 'showAsLightbox', + fieldLabel: t('vhs_show_in_lightbox'), + value: this.data.showAsLightbox + }, + { + xtype: 'textfield', + name: 'title', + itemId: 'title', + fieldLabel: t('title'), + width: 420, + value: this.data.title + }, + { + xtype: 'textarea', + itemId: 'description', + name: 'description', + fieldLabel: t('description'), + width: 420, + height: 50, + value: this.data.description + }, + ], + buttons: [ + { + text: t('cancel'), + listeners: { + 'click': this.callbacks['cancel'] + }, + iconCls: 'pimcore_icon_cancel', + margin: '0 10px 15px 0' + }, + { + text: t('save'), + listeners: { + 'click': this.callbacks['save'] + }, + iconCls: 'pimcore_icon_save', + margin: '0 20px 15px 0' + } + ] + }); + + this.form.add(this.getVideoParameterField()); + }, + + getVideoParameterField: function () { + + this.videoParameterStore = new Ext.data.Store({ + data: this.data.videoParameter + }); + + return Ext.create('Ext.grid.Panel', { + store: this.videoParameterStore, + flex: 1, + border: false, + width: 460, + title: t('vhs_video_parameter'), + columns: [ + { + flex: 1, + sortable: false, + dataIndex: 'key', + editor: new Ext.form.TextField({ + allowBlank: true + }) + }, + { + flex: 1, + sortable: false, + dataIndex: 'value', + editor: new Ext.form.TextField({ + allowBlank: true + }) + }, + { + xtype: 'actioncolumn', + menuText: t('delete'), + width: 40, + items: [{ + tooltip: t('delete'), + icon: '/bundles/pimcoreadmin/img/flat-color-icons/delete.svg', + handler: function (grid, rowIndex) { + grid.getStore().removeAt(rowIndex); + grid.up('grid').getView().refresh(); + }.bind(this) + }] + } + ], + stripeRows: true, + columnLines: true, + selModel: Ext.create('Ext.selection.CellModel'), + autoHeight: true, + valueField: 'key', + displayField: 'value', + plugins: [ + Ext.create('Ext.grid.plugin.CellEditing', { + clicksToEdit: 1 + }) + ], + tbar: [ + { + iconCls: 'pimcore_icon_table_row pimcore_icon_overlay_add', + handler: function (btn) { + var newRow, + grid = btn.up('grid'), + modelClass = grid.getStore().getModel(); + + newRow = new modelClass({ + key: null, + value: null + }); + + this.videoParameterStore.add(newRow); + }.bind(this), + } + ] + }); + + }, + + initVideoTypesStore: function () { + this.videoTypeStore = new Ext.data.JsonStore({ + autoLoad: true, + fields: ['name', 'value', 'config'], + proxy: { + type: 'ajax', + url: '/toolbox/ajax/video-allowed-video-types', + reader: { + type: 'json' + } + } + }); + }, + + updateVideoType: function (type, typeInfo) { + + if (typeInfo === null) { + return; + } + + var lightBoxEl = this.form.getComponent('showAsLightbox'), + pathContainer = this.form.getComponent('pathContainer'), + searchButton = pathContainer.query('button')[0], + pathEl = pathContainer.getComponent('path'), + typeConfig = typeInfo.get('config'); + + pathEl.labelEl.update(t('path')); + + searchButton.enable(); + if (type !== 'asset') { + searchButton.disable(); + } + + if (type === 'youtube') { + pathEl.labelEl.update('ID'); + } + + if (type === 'vimeo') { + pathEl.labelEl.update('ID'); + } + + if (type === 'dailymotion') { + pathEl.labelEl.update('ID'); + } + + if (!typeConfig.allow_lightbox) { + lightBoxEl.hide(); + } else { + lightBoxEl.show(); + } + + if (typeConfig.id_label) { + pathEl.labelEl.update(typeConfig.id_label); + } + }, + + getFieldValues: function () { + + var videoParameter = [], + values = this.window.getComponent('form').getForm().getFieldValues(); + + this.videoParameterStore.each(function (record) { + if (record.get('key') !== null && record.get('value') !== null) { + videoParameter.push({ + 'key': record.get('key'), + 'value': record.get('value') + }) + } + }); + + values['videoParameter'] = videoParameter; + + return values; + + }, + + hideWindow: function () { + this.window.hide(); + this.window.destroy(); + this.window = {}; + this.form = {}; + + document.body.classList.remove('toolbox-modal-open'); + + }, + + onNodeOver: function (target, dd, e, data) { + + var form = this.form, + poster = form.getComponent('poster'); + + data = data.records[0].data; + if (target && target.getId() === poster.getId()) { + if (data.elementType === 'asset' && data.type === 'image') { + return Ext.dd.DropZone.prototype.dropAllowed; + } + } else { + if (data.elementType === 'asset' && data.type === 'video') { + return Ext.dd.DropZone.prototype.dropAllowed; + } + } + return Ext.dd.DropZone.prototype.dropNotAllowed; + }, + + onNodeDrop: function (target, dd, e, data) { + + var recordData, + form = this.form, + pathContainer = form.getComponent('pathContainer'), + path = pathContainer.getComponent('path'), + poster = form.getComponent('poster'); + + if (!target) { + return false; + } + + recordData = data.records[0].data; + + if (target.getId() === path.getId()) { + if (recordData.elementType === 'asset' && recordData.type === 'video') { + path.setValue(recordData.path); + form.getComponent('type').setValue('asset'); + return true; + } + } else if (target.getId() === poster.getId()) { + if (recordData.elementType === 'asset' && recordData.type === 'image') { + poster.setValue(recordData.path); + return true; + } + } + + return false; + } +}); \ No newline at end of file diff --git a/src/ToolboxBundle/Resources/public/js/frontend/plugins/jquery.tb.ext.video.js b/src/ToolboxBundle/Resources/public/js/frontend/plugins/jquery.tb.ext.video.js index e851a7bb..d3a56f73 100644 --- a/src/ToolboxBundle/Resources/public/js/frontend/plugins/jquery.tb.ext.video.js +++ b/src/ToolboxBundle/Resources/public/js/frontend/plugins/jquery.tb.ext.video.js @@ -81,6 +81,7 @@ playerEngine: null, autoPlay: false, playInLightBox: false, + videoParameter: {}, hasPoster: false, posterPath: null, @@ -103,8 +104,6 @@ setupVideoElement: function () { - var _ = this; - this.elementId = this.$element.data('tb-ext-video-index'); this.videoType = this.$element.data('type'); @@ -121,6 +120,10 @@ this.playInLightBox = this.$player.data('play-in-lightbox'); this.posterPath = this.$player.data('poster-path'); + if (this.$player.data('video-parameter') !== undefined) { + this.videoParameter = this.$player.data('video-parameter'); + } + if (this.posterPath) { this.hasPoster = true; } @@ -257,23 +260,24 @@ } else { var initPlayer = function ($el, autostart) { - - var options = { - videoId: _.videoId, - events: { - 'onReady': function () { - _.isReady = true; - _.playerEngine = player; - _.$element.addClass('player-ready'); - if (autostart === true) { - _.playVideo(); + var player, + playerVars = $.extend({}, _.options.apiParameter.youtube, _.videoParameter), + options = { + videoId: _.videoId, + events: { + 'onReady': function () { + _.isReady = true; + _.playerEngine = player; + _.$element.addClass('player-ready'); + if (autostart === true) { + _.playVideo(); + } } } - } - }; + }; - var player = new window.YT.Player( - $el, $.extend({}, {playerVars: _.options.apiParameter.youtube}, options) + player = new window.YT.Player( + $el, $.extend({}, {playerVars: playerVars}, options) ); }; @@ -354,12 +358,13 @@ var initPlayer = function (el, autostart) { - var options = { - id: _.videoId - }; + var player, + options = { + id: _.videoId + }; - var player = new Vimeo.Player( - el, $.extend({}, _.options.apiParameter.vimeo, options) + player = new Vimeo.Player( + el, $.extend({}, _.options.apiParameter.vimeo, _.videoParameter, options) ); player.on('loaded', function () { @@ -492,7 +497,6 @@ } else { _.pauseVideo(); } - } }); diff --git a/src/ToolboxBundle/Resources/translations/admin.de.yml b/src/ToolboxBundle/Resources/translations/admin.de.yml index 629fbef3..c64186a2 100644 --- a/src/ToolboxBundle/Resources/translations/admin.de.yml +++ b/src/ToolboxBundle/Resources/translations/admin.de.yml @@ -19,4 +19,6 @@ grid_configuration_for: "Spaltenkonfiguration für" grid_adjuster_column: "Spalte" grid_adjuster_columns: "Spalten" toolbox_column_offset: "Offset" -invalid_column_configuration: "Ungültige Spaltenkonfiguration. Meldung: " \ No newline at end of file +invalid_column_configuration: "Ungültige Spaltenkonfiguration. Meldung: " +vhs_show_in_lightbox: "In Lightbox anzeigen" +vhs_video_parameter: "Video Parameter" \ No newline at end of file diff --git a/src/ToolboxBundle/Resources/translations/admin.en.yml b/src/ToolboxBundle/Resources/translations/admin.en.yml index 0588fef5..2e70eb4a 100644 --- a/src/ToolboxBundle/Resources/translations/admin.en.yml +++ b/src/ToolboxBundle/Resources/translations/admin.en.yml @@ -19,4 +19,6 @@ grid_configuration_for: "Column Configuration for" grid_adjuster_column: "Column" grid_adjuster_columns: "Columns" toolbox_column_offset: "Offset" -invalid_column_configuration: "Invalid Column Configuration. Message: " \ No newline at end of file +invalid_column_configuration: "Invalid Column Configuration. Message: " +vhs_show_in_lightbox: "Show in Lightbox" +vhs_video_parameter: "Video Parameter" \ No newline at end of file diff --git a/src/ToolboxBundle/Resources/views/Toolbox/Bootstrap4/Video/type-asset.html.twig b/src/ToolboxBundle/Resources/views/Toolbox/Bootstrap4/Video/type-asset.html.twig index 55e784d3..435ea2f9 100644 --- a/src/ToolboxBundle/Resources/views/Toolbox/Bootstrap4/Video/type-asset.html.twig +++ b/src/ToolboxBundle/Resources/views/Toolbox/Bootstrap4/Video/type-asset.html.twig @@ -1,4 +1,4 @@ -
+
{{ pimcore_vhs('video', { 'attributes': { 'class': 'video-js vjs-default-skin vjs-big-play-centered', diff --git a/src/ToolboxBundle/Resources/views/Toolbox/Bootstrap4/Video/type-vimeo.html.twig b/src/ToolboxBundle/Resources/views/Toolbox/Bootstrap4/Video/type-vimeo.html.twig index 6271ac9a..609137e2 100644 --- a/src/ToolboxBundle/Resources/views/Toolbox/Bootstrap4/Video/type-vimeo.html.twig +++ b/src/ToolboxBundle/Resources/views/Toolbox/Bootstrap4/Video/type-vimeo.html.twig @@ -1,4 +1,4 @@ -
+
{% if posterPath is not empty %} {% include toolbox_area_path(areaId, '/Partial/overlay') with {'posterPath' : posterPath, 'playInLightbox' : playInLightbox} %} {% endif %} \ No newline at end of file diff --git a/src/ToolboxBundle/Resources/views/Toolbox/Bootstrap4/Video/type-youtube.html.twig b/src/ToolboxBundle/Resources/views/Toolbox/Bootstrap4/Video/type-youtube.html.twig index f652ae37..4126637d 100644 --- a/src/ToolboxBundle/Resources/views/Toolbox/Bootstrap4/Video/type-youtube.html.twig +++ b/src/ToolboxBundle/Resources/views/Toolbox/Bootstrap4/Video/type-youtube.html.twig @@ -1,4 +1,4 @@ -
+
{% if posterPath is not empty %} {% include toolbox_area_path(areaId, '/Partial/overlay') with {'posterPath' : posterPath, 'playInLightbox' : playInLightbox} %} diff --git a/src/ToolboxBundle/ToolboxBundle.php b/src/ToolboxBundle/ToolboxBundle.php index 0fe59959..7067b395 100644 --- a/src/ToolboxBundle/ToolboxBundle.php +++ b/src/ToolboxBundle/ToolboxBundle.php @@ -41,7 +41,6 @@ public function getJsPaths() '/admin/toolbox-ckeditor-object-style.js', '/bundles/toolbox/js/toolbox-ckeditor-plugins.js', '/bundles/toolbox/js/document/edit.js', - '/bundles/toolbox/js/document/helpers.js', '/bundles/toolbox/js/startup.js', ]; } @@ -58,8 +57,9 @@ public function getEditmodeJsPaths() '/bundles/toolbox/js/document/tags/dynamiclink.js', '/bundles/toolbox/js/document/tags/googlemap.js', '/bundles/toolbox/js/document/tags/parallaximage.js', + '/bundles/toolbox/js/document/tags/columnadjuster.js', '/bundles/toolbox/js/document/tags/vhs.js', - '/bundles/toolbox/js/document/tags/columnadjuster.js' + '/bundles/toolbox/js/document/tags/vhs/editor.js', ]; } diff --git a/src/ToolboxBundle/Twig/Extension/DataAttributesExtension.php b/src/ToolboxBundle/Twig/Extension/DataAttributesExtension.php index 1999ce47..8a370fa5 100644 --- a/src/ToolboxBundle/Twig/Extension/DataAttributesExtension.php +++ b/src/ToolboxBundle/Twig/Extension/DataAttributesExtension.php @@ -34,20 +34,25 @@ public function getFunctions() /** * @param string $node * @param array $overrides + * @param bool $ignoreNonExistingCoreAttributes * * @return string * * @throws \Exception */ - public function generateDataAttributes($node, $overrides = []) + public function generateDataAttributes($node, $overrides = [], $ignoreNonExistingCoreAttributes = false) { $attributesNode = $this->configManager->getConfig('data_attributes'); - if (!isset($attributesNode[$node]['values']) || empty($attributesNode[$node]['values'])) { + $coreAttributesAvailable = isset($attributesNode[$node]['values']) && is_array($attributesNode[$node]['values']) && !empty($attributesNode[$node]['values']); + + if ($ignoreNonExistingCoreAttributes === false && $coreAttributesAvailable === false) { return ''; } - $values = array_merge($attributesNode[$node]['values'], $overrides); + $coreAttributes = $coreAttributesAvailable === false ? [] : $attributesNode[$node]['values']; + + $values = array_merge($coreAttributes, $overrides); return $this->parseValues($values); } diff --git a/tests/unit.default/Areas/VideoTest.php b/tests/unit.default/Areas/VideoTest.php index 897ffe8d..b564fc4c 100644 --- a/tests/unit.default/Areas/VideoTest.php +++ b/tests/unit.default/Areas/VideoTest.php @@ -149,6 +149,45 @@ public function testVideoWithAutoplay() ); } + public function testVideoWithVideoParameter() + { + $this->setupRequest(); + + $asset = TestHelper::createImageAsset('', true); + + $videoParameter = [ + ['key' => 'color', 'value' => 'red'], + ['key' => 'rel', 'value' => '0'] + ]; + + $parsedVideoParameters = [ + 'color' => 'red', + 'rel' => '0' + ]; + + $video = new Vhs(); + $video->setDataFromEditmode([ + 'type' => 'youtube', + 'path' => 'https://www.youtube.com/watch?v=EhhGzxhtx48', + 'poster' => $asset->getFullPath(), + 'showAsLightbox' => true, + 'videoParameter' => $videoParameter + ]); + + $autoplay = new Checkbox(); + $autoplay->setDataFromEditmode(1); + + $elements = [ + 'video' => $video, + 'autoplay' => $autoplay + ]; + + $this->assertEquals( + $this->filter($this->getCompareWithVideoParameter($asset->getFullPath(), $parsedVideoParameters)), + $this->filter($this->generateRenderedArea(self::TYPE, $elements)) + ); + } + public function testVideoWithAdditionalClass() { $this->setupRequest(); @@ -180,7 +219,7 @@ private function getCompare($path) { return '
-
+
@@ -192,7 +231,7 @@ private function getCompareVimeo($path) { return '
-
+
@@ -204,7 +243,7 @@ private function getCompareWithLightBox($path) { return '
-
+
@@ -216,7 +255,20 @@ private function getCompareWithAutoplay($path) { return '
-
+
+ +
+
'; + } + + private function getCompareWithVideoParameter($path, $attributes) + { + $safeAttributes = htmlspecialchars(json_encode($attributes)); + return '
+
+
@@ -228,7 +280,7 @@ private function getCompareWithAdditionalClass($path) { return '
-
+