Skip to content

Commit 95dda91

Browse files
committed
First commit of the magical preview
There are hardcoded paths and debugging things here and there that still need to be corrected, but wanted to share the current progress with excited people.
0 parents  commit 95dda91

File tree

8 files changed

+281
-0
lines changed

8 files changed

+281
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.idea
2+
config.core.php

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# PreviewResource for MODX
2+
3+
PreviewResource adds a _Magical_ Preview button to the resources panel which will show you, without actually saving the resource, a real preview of a resource.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
require_once dirname(dirname(dirname(dirname(__FILE__)))).'/config.core.php';
3+
require_once MODX_CORE_PATH.'config/'.MODX_CONFIG_KEY.'.inc.php';
4+
require_once MODX_CONNECTORS_PATH . 'index.php';
5+
6+
//$corePath = $modx->getOption('contentblocks.core_path',null,$modx->getOption('core_path').'components/contentblocks/');
7+
//$modx->getService('contentblocks', 'ContentBlocks', $corePath . 'model/contentblocks/');
8+
//$modx->lexicon->load('contentblocks:default');
9+
10+
11+
/* handle request */
12+
$path = '/Users/mhamstra/Sites/premium.local/PreviewResource/core/components/previewresource/processors/'; //$modx->getOption('processorsPath',$modx->contentblocks->config,$corePath.'processors/');
13+
$modx->request->handleRequest(array(
14+
'processors_path' => $path,
15+
'location' => '',
16+
));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
(function() {
2+
Ext.onReady(function() {
3+
Ext.override(MODx.page.UpdateResource, {
4+
_originals: {
5+
getButtons: MODx.page.UpdateResource.prototype.getButtons
6+
},
7+
getButtons: function(config) {
8+
console.log('gotcha');
9+
var btns = this._originals.getButtons.call(this, config);
10+
btns.splice(2, 0, {
11+
text: 'Preview',
12+
id: 'modx-abtn-real-preview',
13+
handler: this.prPreview,
14+
scope: this
15+
});
16+
return btns;
17+
},
18+
19+
prPreview: function() {
20+
var o = this.config;
21+
if (!o.formpanel) return false;
22+
23+
MODx.util.Progress.reset();
24+
o.form = Ext.getCmp(o.formpanel);
25+
if (!o.form) return false;
26+
27+
if (!o.previewWindow) {
28+
o.previewWindow = window.open('/PreviewResource/assets/components/previewresource/preview.html#loading', 'PreviewResource')
29+
}
30+
31+
var f = o.form.getForm ? o.form.getForm() : o.form;
32+
var isv = true;
33+
if (f.items && f.items.items) {
34+
for (var fld in f.items.items) {
35+
if (f.items.items[fld] && f.items.items[fld].validate) {
36+
var fisv = f.items.items[fld].validate();
37+
if (!fisv) {
38+
f.items.items[fld].markInvalid();
39+
isv = false;
40+
}
41+
}
42+
}
43+
}
44+
45+
if (isv) {
46+
o.previewWindow.location.hash = 'loading';
47+
o.previewWindow = window.open(o.previewWindow.location.href, o.previewWindow.name);
48+
49+
var originalAction = o.form.baseParams['action'],
50+
originalUrl = o.form.url;
51+
f.baseParams['action'] = 'resource/preview';
52+
f.url = '/PreviewResource/assets/components/previewresource/connector.php';
53+
54+
o.form.on('success', function (r) {
55+
f.baseParams['action'] = originalAction;
56+
f.url = originalUrl;
57+
58+
if (r.result && r.result.object && r.result.object.preview_url) {
59+
o.previewWindow.location.hash = r.result.object.preview_url;
60+
}
61+
62+
}, this);
63+
o.form.submit({
64+
headers: {
65+
'Powered-By': 'MODx'
66+
, 'modAuth': MODx.siteId
67+
}
68+
});
69+
}
70+
}
71+
72+
});
73+
console.log('Overridden MODx.page.UpdateResource with custom getButtons')
74+
});
75+
76+
// MODx.on('ready', function() {
77+
// console.log('MODX Ready!');
78+
// });
79+
80+
})();
81+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport"
6+
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
7+
<meta http-equiv="X-UA-Compatible" content="ie=edge">
8+
<title>Resource Preview</title>
9+
10+
<style type="text/css">
11+
body {
12+
height: 100vh;
13+
margin: 0;
14+
font-family: -apple-system,sans-serif;
15+
}
16+
#container {
17+
display: flex;
18+
flex-direction: column;
19+
height: 100%;
20+
}
21+
22+
#info {
23+
margin: 0 auto;
24+
padding-bottom: 1em;
25+
box-shadow: 0 4px 6px rgba(0,0,0,0.1), 0 5px 15px rgba(0,0,0,0.1);
26+
width: 100%;
27+
z-index: 1;
28+
}
29+
30+
h1 {
31+
margin-bottom: 0;
32+
font-weight: normal;
33+
text-align: center;
34+
}
35+
36+
#frame-wrapper, #loading-wrapper {
37+
display: flex;
38+
flex: 1;
39+
}
40+
41+
#frame, #loading-wrapper p {
42+
width: 100%;
43+
height: 100%;
44+
border: none;
45+
}
46+
47+
#loading-wrapper {
48+
text-align: center;
49+
}
50+
#loading-wrapper p {
51+
padding-top: 5em;
52+
height: auto;
53+
}
54+
</style>
55+
</head>
56+
<body>
57+
<div id="container">
58+
<div id="info">
59+
<h1>Resource Preview</h1>
60+
</div>
61+
<div id="frame-wrapper">
62+
<iframe id="frame"></iframe>
63+
</div>
64+
<div id="loading-wrapper">
65+
<p>Preparing your preview...</p>
66+
</div>
67+
68+
</div>
69+
<script>
70+
(function() {
71+
var frame = document.getElementById('frame'),
72+
frameWrapper = document.getElementById('frame-wrapper'),
73+
loadingWrapper = document.getElementById('loading-wrapper');
74+
window.onhashchange = refreshFrame;
75+
refreshFrame();
76+
77+
function refreshFrame() {
78+
console.log(location.hash);
79+
if (location.hash === '' || location.hash === '#loading') {
80+
frameWrapper.style.display = 'none';
81+
loadingWrapper.style.display = 'initial';
82+
frame.src = '';
83+
}
84+
else {
85+
loadingWrapper.style.display = 'none';
86+
frameWrapper.style.display = 'initial';
87+
frame.src = location.hash.substring(1);
88+
}
89+
}
90+
})()
91+
</script>
92+
</body>
93+
</html>

config.core.sample.php

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<?php
2+
define('MODX_CORE_PATH', dirname(dirname(__FILE__)).'/modx/core/');
3+
define('MODX_CONFIG_KEY', 'config');
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
/**
3+
* @var modX $modx
4+
*/
5+
6+
switch ($modx->event->name) {
7+
case 'OnDocFormRender':
8+
$modx->controller->addJavascript('/PreviewResource/assets/components/previewresource/js/preview.js');
9+
break;
10+
11+
case 'OnLoadWebDocument':
12+
if (!array_key_exists('show_preview', $_GET)) {
13+
return;
14+
}
15+
if (!$modx->user->hasSessionContext('mgr')) {
16+
$modx->log(modX::LOG_LEVEL_WARN, 'User without mgr session tried to access preview for resource ' . $modx->resource->get('id'));
17+
return;
18+
}
19+
$key = $_GET['show_preview'];
20+
$data = $modx->cacheManager->get($modx->resource->get('id') . '/' . $key, [
21+
xPDO::OPT_CACHE_KEY => 'previewresource'
22+
]);
23+
if (is_array($data)) {
24+
$modx->resource->fromArray($data, '', true, true);
25+
$modx->resource->set('cacheable', false);
26+
$modx->resource->setProcessed(false);
27+
}
28+
break;
29+
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
require MODX_PROCESSORS_PATH . 'resource/update.class.php';
4+
5+
class PreviewResourcePreviewProcessor extends modResourceUpdateProcessor {
6+
private $previewUrl;
7+
private $failedSuccessfully = false;
8+
9+
public function fireBeforeSaveEvent() {
10+
$this->failedSuccessfully = true;
11+
12+
if ($tvs = $this->object->getMany('TemplateVars', 'all')) {
13+
/** @var modTemplateVar $tv */
14+
foreach ($tvs as $tv) {
15+
$this->object->set($tv->get('name'), array(
16+
$tv->get('name'),
17+
$this->object->get('tv' . $tv->get('id')),//$tv->getValue($resource->get('id')),
18+
$tv->get('display'),
19+
$tv->get('display_params'),
20+
$tv->get('type'),
21+
));
22+
}
23+
}
24+
$data = $this->object->toArray('', true);
25+
26+
$key = bin2hex(random_bytes(12));
27+
$this->modx->cacheManager->set($this->object->get('id') . '/' . $key, $data, 3600, [
28+
xPDO::OPT_CACHE_KEY => 'previewresource'
29+
]);
30+
$this->previewUrl = $this->modx->makeUrl($this->object->get('id'), '', ['show_preview' => $key]);
31+
32+
return false;
33+
}
34+
public function failure($msg = '',$object = null) {
35+
if ($this->failedSuccessfully) {
36+
return $this->success('Failed successfully', [
37+
'preview_url' => $this->previewUrl,
38+
]);
39+
}
40+
return parent::failure($msg, $object);
41+
}
42+
43+
/**
44+
* Always prevent actual saving
45+
* @return bool
46+
*/
47+
public function saveObject()
48+
{
49+
return false;
50+
}
51+
}
52+
53+
return 'PreviewResourcePreviewProcessor';

0 commit comments

Comments
 (0)