%frosh_view_snapshots.plugin_dir%
diff --git a/Resources/sql/install.sql b/Resources/sql/install.sql
index a6bb226..eebabb7 100644
--- a/Resources/sql/install.sql
+++ b/Resources/sql/install.sql
@@ -2,6 +2,7 @@ CREATE TABLE IF NOT EXISTS `view_snapshots` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`sessionID` VARCHAR(255) NOT NULL,
`template` VARCHAR(255) NOT NULL,
+ `requestURI` varchar(255) NOT NULL,
`step` INT(11) NOT NULL,
`variables` LONGTEXT NULL,
`params` LONGTEXT NULL,
diff --git a/Resources/sql/update.1.1.0.sql b/Resources/sql/update.1.1.0.sql
new file mode 100644
index 0000000..715bb8d
--- /dev/null
+++ b/Resources/sql/update.1.1.0.sql
@@ -0,0 +1 @@
+ALTER TABLE `view_snapshots` ADD `requestURI` varchar(255) COLLATE 'utf8_unicode_ci' NOT NULL AFTER `template`;
\ No newline at end of file
diff --git a/Resources/views/backend/view_snapshots/controller/main.js b/Resources/views/backend/view_snapshots/controller/main.js
index b634f3b..2b53cb6 100644
--- a/Resources/views/backend/view_snapshots/controller/main.js
+++ b/Resources/views/backend/view_snapshots/controller/main.js
@@ -18,6 +18,121 @@ Ext.define('Shopware.apps.ViewSnapshots.controller.Main', {
me.callParent(arguments);
+ me.control({
+ 'view-snapshot-window': {
+ 'select': me.onGridSelect,
+ 'delete': me.onSnapshotDelete
+ }
+ });
+
+ },
+
+ onGridSelect: function(selectionModel, rec) {
+ var selection = selectionModel.getSelection();
+
+ if (selection.length > 2) {
+ selectionModel.deselectAll();
+ selectionModel.select(rec);
+
+ return;
+ }
+
+ if (selection.length === 2) {
+ var me = this,
+ firstRecord = selection[0],
+ secondRecord = selection[1],
+ loadMask = new Ext.LoadMask(me.mainWindow);
+
+ loadMask.show();
+
+ Ext.Ajax.request({
+ url: '{url action="diff"}',
+ method: 'GET',
+ params: {
+ sessionFrom: firstRecord.get('sessionID'),
+ stepFrom: firstRecord.get('step'),
+ sessionTo: secondRecord.get('sessionID'),
+ stepTo: secondRecord.get('step')
+ },
+ success: function(response){
+ var responseObj = Ext.JSON.decode(response.responseText);
+
+ Ext.create('Ext.window.Window', {
+ title: 'Diff',
+ height: 600,
+ width: 800,
+ modal: true,
+ layout: {
+ type: 'vbox',
+ align: 'stretch',
+ pack : 'start'
+ },
+ items: [{
+ xtype: 'panel',
+ title: 'Session ID',
+ html: '{literal}{/literal}' +
+ responseObj.data.sessionID
+ }, {
+ xtype: 'panel',
+ title: 'Step',
+ html: responseObj.data.step
+ }, {
+ xtype: 'panel',
+ title: 'Template',
+ html: responseObj.data.template
+ }, {
+ xtype: 'panel',
+ title: 'URI',
+ html: responseObj.data.requestURI
+ }, {
+ xtype: 'panel',
+ title: 'Params',
+ flex: 1,
+ autoScroll: true,
+ collapsible: true,
+ html: '' +
+ responseObj.data.params +
+ '
'
+ }, {
+ xtype: 'panel',
+ title: 'Variables',
+ flex: 2,
+ autoScroll: true,
+ html: '' +
+ responseObj.data.variables +
+ '
'
+ }]
+ }).show();
+
+ loadMask.hide();
+ },
+ failure: function(response){
+ console.log(response);
+
+ loadMask.hide();
+ }
+ });
+ }
+ },
+
+ onSnapshotDelete: function (view, rowIndex) {
+ var me = this,
+ store = me.getStore('Snapshot');
+
+ me.record = store.getAt(rowIndex);
+
+ if (me.record instanceof Ext.data.Model && me.record.get('id') > 0) {
+ Ext.MessageBox.confirm('Delete?', 'Are you sure you want to delete the snapshot?', function (response) {
+ if (response !== 'yes') {
+ return;
+ }
+ me.record.destroy({
+ callback: function() {
+ store.load();
+ }
+ });
+ });
+ }
}
});
diff --git a/Resources/views/backend/view_snapshots/model/snapshot.js b/Resources/views/backend/view_snapshots/model/snapshot.js
index b66bbab..dd1a3a7 100644
--- a/Resources/views/backend/view_snapshots/model/snapshot.js
+++ b/Resources/views/backend/view_snapshots/model/snapshot.js
@@ -1,8 +1,11 @@
Ext.define('Shopware.apps.ViewSnapshots.model.Snapshot', {
extend : 'Ext.data.Model',
- fields : [ 'sessionID', 'template', 'step', 'url' ],
+ fields : [ 'sessionID', 'template', 'step', 'url', 'requestURI' ],
proxy: {
type : 'ajax',
+ api : {
+ destroy : '{url action="delete"}'
+ },
reader : {
type : 'json',
root : 'data',
diff --git a/Resources/views/backend/view_snapshots/view/grid.js b/Resources/views/backend/view_snapshots/view/grid.js
index 82f2de8..f8984d7 100644
--- a/Resources/views/backend/view_snapshots/view/grid.js
+++ b/Resources/views/backend/view_snapshots/view/grid.js
@@ -27,6 +27,11 @@ Ext.define('Shopware.apps.ViewSnapshots.view.Grid', {
flex: 1,
dataIndex: 'template'
},
+ {
+ header: 'URI',
+ flex: 1,
+ dataIndex: 'requestURI'
+ },
{
header: 'Step',
dataIndex: 'step',
@@ -34,12 +39,14 @@ Ext.define('Shopware.apps.ViewSnapshots.view.Grid', {
},
{
xtype: 'actioncolumn',
- width: 30,
+ width: 60,
items: me.getActionColumnItems()
}
];
},
getActionColumnItems: function () {
+ var me = this;
+
return [
{
iconCls: 'x-action-col-icon sprite-globe--arrow',
@@ -50,6 +57,13 @@ Ext.define('Shopware.apps.ViewSnapshots.view.Grid', {
window.open(record.get('url'), '_blank');
}
+ },
+ {
+ iconCls: 'x-action-col-icon sprite-minus-circle-frame',
+ tooltip: 'Delete',
+ handler: function (view, rowIndex, colIndex, item) {
+ me.fireEvent('delete', view, rowIndex, colIndex, item);
+ }
}
];
},
diff --git a/Resources/views/backend/view_snapshots/view/window.js b/Resources/views/backend/view_snapshots/view/window.js
index be00851..7ee6c16 100644
--- a/Resources/views/backend/view_snapshots/view/window.js
+++ b/Resources/views/backend/view_snapshots/view/window.js
@@ -14,7 +14,10 @@ Ext.define('Shopware.apps.ViewSnapshots.view.Window', {
{
xtype: 'view-snapshot-window',
store: me.store,
- flex: 1
+ flex: 1,
+ selModel: new Ext.selection.CheckboxModel({
+ checkOnly: true
+ })
}
];
diff --git a/Services/Diff.php b/Services/Diff.php
new file mode 100644
index 0000000..c302e20
--- /dev/null
+++ b/Services/Diff.php
@@ -0,0 +1,90 @@
+diffPlain($this->prettyPrintSerialized($from), $this->prettyPrintSerialized($to));
+ }
+
+ /**
+ * @param string $from
+ * @param string $to
+ *
+ * @return FineDiff
+ */
+ public function diffJson($from, $to)
+ {
+ $fromData = json_decode($from, true);
+ $toData = json_decode($to, true);
+
+ if (is_array($fromData) && is_array($toData)) {
+ return $this->diffArray($fromData, $toData);
+ }
+
+ return $this->diffPlain($from, $to);
+ }
+
+ /**
+ * @param array $from
+ * @param array $to
+ *
+ * @return FineDiff
+ */
+ public function diffArray(array $from, array $to)
+ {
+ return $this->diffPlain(
+ json_encode($this->sortArrayRecursive($from), JSON_PRETTY_PRINT),
+ json_encode($this->sortArrayRecursive($to), JSON_PRETTY_PRINT)
+ );
+ }
+
+ /**
+ * @param array $data
+ *
+ * @return array
+ */
+ protected function sortArrayRecursive(array $data)
+ {
+ foreach ($data as &$value) {
+ if (is_array($value)) {
+ $value = $this->sortArrayRecursive($value);
+ }
+ }
+
+ ksort($data);
+
+ return $data;
+ }
+
+ /**
+ * @param string $serialized
+ *
+ * @return string
+ */
+ protected function prettyPrintSerialized($serialized)
+ {
+ return print_r(unserialize($serialized), true);
+ }
+}
diff --git a/Subscriber/Dispatch.php b/Subscriber/Dispatch.php
index 278b8f2..f16661b 100644
--- a/Subscriber/Dispatch.php
+++ b/Subscriber/Dispatch.php
@@ -111,6 +111,7 @@ public function onPostDispatchSecureFrontend(\Enlight_Controller_ActionEventArgs
'variables' => $variables,
'params' => $params,
'step' => $step,
+ 'requestURI' => $request->getPathInfo(),
]
);
}
diff --git a/composer.json b/composer.json
index 54119a1..ad2bf8f 100644
--- a/composer.json
+++ b/composer.json
@@ -8,6 +8,7 @@
"installer-name": "FroshViewSnapshots"
},
"require": {
+ "php": "^5.6 || ^7.0",
"composer/installers": "~1.0"
},
"scripts": {
diff --git a/plugin.xml b/plugin.xml
index 5d6c566..0bbbf67 100644
--- a/plugin.xml
+++ b/plugin.xml
@@ -3,13 +3,36 @@
- 1.0.0
+ 1.1.0
Friends of Shopware
MIT
https://friendsofshopware.github.io/
Friends of Shopware
+
+
+
+ Spalte hinzugefügt zur Aufnahme von Snapshot Request URIs
+ Funktionalität hinzugefügt zur Ansicht eines Diff von Rohdaten zweier Snapshots
+ Funktionalität hinzugefügt zum Löschen von Snapshot-Einträgen über die Backend App
+ Functional Tests hinzugefügt
+
+ ]]>
+
+
+
+ Added column and recording of snapshot request URIs
+ Added functionality to view diff of raw snapshot data from backend app
+ Added functionality to delete snapshot entries from backend app
+ Added functional tests
+
+ ]]>
+
+
+
Initial Release
Initial Release
diff --git a/tests/Functional/ViewportSnapshotsTest.php b/tests/Functional/ViewportSnapshotsTest.php
new file mode 100644
index 0000000..cb02bd2
--- /dev/null
+++ b/tests/Functional/ViewportSnapshotsTest.php
@@ -0,0 +1,35 @@
+Template()->disableSecurity();
+ }
+
+ public function testSnapshotRecording()
+ {
+ Shopware()->Session()->offsetSet('isSessionRecorded', true);
+
+ $this->dispatch('/');
+
+ $sql = 'SELECT * FROM view_snapshots WHERE sessionID = ? AND requestURI = ?';
+ $snapshot = Shopware()->Db()->fetchRow($sql, [
+ Shopware()->Session()->get('sessionId'),
+ '/',
+ ]);
+
+ $variables = unserialize($snapshot['variables']);
+
+ $this->assertTrue(is_array($variables) && !empty($variables));
+ }
+
+ public function testSnapshotReplay()
+ {
+ $this->dispatch('/snapshots/load/session/' . Shopware()->Session()->get('sessionId'));
+
+ $this->assertTrue(strpos($this->Response()->getBody(), 'is--ctl-index') !== false);
+ }
+}
\ No newline at end of file
diff --git a/tests/phpunit.xml b/tests/phpunit.xml
index 4fcdc64..b1c4e2f 100644
--- a/tests/phpunit.xml
+++ b/tests/phpunit.xml
@@ -11,7 +11,7 @@
verbose="true">
-
+
./Functional