Page MenuHomePhabricator

No OneTemporary

diff --git a/action.php b/action.php
--- a/action.php
+++ b/action.php
@@ -1,204 +1,210 @@
<?php
/**
* DokuWiki Plugin metaeditor (Action Component)
*
* Simple Meta Data Editor, heavily AJAX/jQuery based.
*
* @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
* @author Andreas Böhler <dev@aboehler.at>
*/
// must be run within Dokuwiki
if(!defined('DOKU_INC')) die();
class action_plugin_metaeditor extends DokuWiki_Action_Plugin {
// Load the helper plugin
public function action_plugin_metaeditor() {
}
// Register our hooks
function register(Doku_Event_Handler $controller) {
$controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handle_ajax_call_unknown');
}
function handle_ajax_call_unknown($event, $param) {
if($event->data != 'plugin_metaeditor') return;
$event->preventDefault();
$event->stopPropagation();
global $INPUT;
$action = trim($INPUT->post->str('q'));
$pageid = trim($INPUT->post->str('r'));
$opts = $INPUT->post->arr('opts');
$data = array();
$useJson = true;
+ if(!checkSecurityToken())
+ {
+ echo "CSRF Attack.";
+ return;
+ }
+
$perm = auth_quickaclcheck($pageid);
if($perm == AUTH_ADMIN)
{
switch($action)
{
case 'getMeta':
$data = $this->getMetaForPage($pageid);
break;
case 'getMetaValue':
$useJson = false;
$data = $this->getMetaValueForPage($pageid, $opts['key']);
break;
case 'setMetaValue':
$data = $this->setMetaValueForPage($pageid, $opts['key'], $opts['oldval'], $opts['newval']);
break;
case 'deleteMetaValue':
$data = $this->deleteMetaValueForPage($pageid, $opts['key']);
break;
case 'createMetaArray':
$data = $this->createMetaArrayForPage($pageid, $opts['key'], $opts['newval']);
break;
case 'createMetaValue':
$data = $this->createMetaValueForPage($pageid, $opts['key'], $opts['newkey'], $opts['newval']);
break;
}
}
else
{
$data = array(false, "You are not an admin");
}
if($useJson)
{
//json library of DokuWiki
require_once DOKU_INC . 'inc/JSON.php';
$json = new JSON();
//set content type
header('Content-Type: application/json');
echo $json->encode($data);
}
else
{
echo $data;
}
}
function createMetaArrayForPage($pageid, $key, $newval)
{
$cache = false;
$meta = p_read_metadata($pageid, $cache);
$m = &$meta;
foreach($key as $k)
{
$m = &$m[$k];
}
$m[$newval] = array();
if(p_save_metadata($pageid, $meta))
return array(true, "Successfully saved: $newval");
else
return array(false, "Error saving value: $newval");
}
function createMetaValueForPage($pageid, $key, $newkey, $newval)
{
$cache = false;
$meta = p_read_metadata($pageid, $cache);
$m = &$meta;
foreach($key as $k)
{
$m = &$m[$k];
}
$m[$newkey] = $newval;
if(p_save_metadata($pageid, $meta))
return array(true, "Successfully saved: $newval");
else
return array(false, "Error saving value: $newval");
}
function setMetaValueForPage($pageid, $key, $oldval, $newval)
{
$cache = false;
$meta = p_read_metadata($pageid, $cache);
$m = &$meta;
foreach($key as $k)
$m = &$m[$k];
if($m == $oldval)
{
$m = $newval;
if(p_save_metadata($pageid, $meta))
return array(true, "Successfully saved: $newval");
else
return array(false, "Error saving value: $newval");
}
else
{
return array(false, "Key has changed in the meantime, expected $oldval but got $m. Nothing was saved!");
}
}
function deleteMetaValueForPage($pageid, $key)
{
$cache = false;
$meta = p_read_metadata($pageid, $cache);
$m = &$meta;
for($i=0;$i<count($key);$i++)
{
if($i == count($key)-1)
unset($m[$key[$i]]);
else
$m = &$m[$key[$i]];
}
if(p_save_metadata($pageid, $meta))
return array(true, "Successfully deleted key: " . join(':', $key));
else
return array(false, "Error deleting key: " . join(':', $key));
}
function parseMetaTree($meta)
{
$out = array();
foreach($meta as $k => $v)
{
$a = array();
$a['text'] = $k;
if(is_array($v))
{
$a['children'] = $this->parseMetaTree($v);
$a['li_attr'] = array('data-type' => 'folder');
}
else
{
$a['li_attr'] = array('data-type' => 'file');
$a['icon'] = DOKU_URL."/lib/images/page.png";
}
$out[] = $a;
}
return $out;
}
function getMetaForPage($pageid)
{
$cache = false;
$meta = p_read_metadata($pageid, $cache);
$out = $this->parseMetaTree($meta);
return $out;
}
function getMetaValueForPage($pageid, $key)
{
$cache = false;
$meta = p_read_metadata($pageid, $cache);
foreach($key as $k)
{
$meta = $meta[$k];
}
return $meta;
}
}
diff --git a/admin/editor.php b/admin/editor.php
--- a/admin/editor.php
+++ b/admin/editor.php
@@ -1,86 +1,86 @@
<?php
/**
* DokuWiki Plugin metaeditor (Admin Component)
*
* Simple Meta Data Editor, heavily AJAX/jQuery based.
*
* @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
* @author Andreas Gohr <gohr@cosmocode.de>
*/
// must be run within Dokuwiki
if (!defined('DOKU_INC')) die();
require_once(DOKU_PLUGIN.'admin.php');
class admin_plugin_metaeditor_editor extends DokuWiki_Admin_Plugin {
/**
* Constructor. Load helper plugin
*/
function admin_plugin_metaeditor_editor(){
}
function getMenuSort() { return 501; }
function forAdminOnly() { return true; }
function getMenuText($language) {
return "Simple Meta Data Editor";
}
function handle() {
if(!is_array($_REQUEST['d']) || !checkSecurityToken()) return;
}
function recurseTree($ns) {
global $conf;
$out = '';
$list = array();
$opts = array(
'depth' => 1,
'listfiles' => true,
'listdirs' => true,
'pagesonly' => true,
'firsthead' => true,
'sneakyacl' => $conf['sneaky_index'],
);
search($list,$conf['datadir'],'search_universal',$opts,$ns);
foreach($list as $item)
{
if($item['type'] == 'f' || $item['type'] == 'd')
{
if($item['type'] == 'd')
{
$out .= '<li>'.$item['id'];
$out .= '<ul>'.$this->recurseTree(str_replace(':', '/', $item['id'])).'</ul>';
}
else
{
$out .= '<li data-jstree=\'{"icon":"'.DOKU_URL.'/lib/images/page.png"}\'>'.$item['id'];
}
$out .= '</li>';
}
}
return $out;
}
function html() {
echo '<h1>Meta Data Editor</h1>';
echo '<table>';
echo '<tr><th width="30\%">Page</th><th width="30\%">Meta Data</th><th width="30\%">Value</th></tr>';
echo '<tr>';
- echo '<td><div id="fileTree">';
+ echo '<td><div id="fileTree" data-sectok="'.getSecurityToken().'">';
echo '<ul>'.$this->recurseTree('/').'</ul>';
echo '</div></td>';
echo '<td><div id="metaTree"></div></td>';
echo '<td><div id="event_path"></div><br><div id="event_result">';
echo '<input type="text" id="event_value" value="..."><br>';
echo '<input type="submit" id="event_save" value="Save">';
echo '</div></td>';
echo '</tr></table>';
}
}
// vim:ts=4:sw=4:et:enc=utf-8:
diff --git a/script.js b/script.js
--- a/script.js
+++ b/script.js
@@ -1,406 +1,415 @@
/* DOKUWIKI:include_once jstree.js */
jQuery(function()
{
var selectedPageId = null;
var selectedNode = null;
var selectedNodePath = null;
var selectedNodeValue = null;
+ var sectok = jQuery('#fileTree').data('sectok');
+ if(!sectok) return;
jqModalManager.init();
jQuery('#event_save').click(function() {
var newVal = jQuery('#event_value').val();
jQuery.post(
DOKU_BASE + 'lib/exe/ajax.php',
{
call: 'plugin_metaeditor',
q: 'setMetaValue',
r: selectedPageId,
+ sectok: sectok,
opts: {
key : selectedNode,
oldval : selectedNodeValue,
newval : newVal
}
},
function(data) {
jqModalManager.msg = data[1];
jqModalManager.showInfoDialog();
selectedNodeValue = newVal;
}
);
});
function refreshMetaTree() {
jQuery.post(
DOKU_BASE + 'lib/exe/ajax.php',
{
call: 'plugin_metaeditor',
q: 'getMeta',
- r: selectedPageId
+ r: selectedPageId,
+ sectok: sectok
},
function(data) {
jQuery('#event_path').html('');
jQuery('#event_value').val('...');
selectedNodePath = null;
selectedNodeValue = null;
selectedNode = null;
jQuery('#metaTree').jstree(true).settings.core.data = data;
jQuery('#metaTree').jstree(true).refresh();
}
);
}
function customMenu(node) {
// The default set of all items
var items = {
/*renameItem: { // The "rename" menu item
label: "Rename",
action: function () {
alert('rename called');
}
},*/
deleteItem: { // The "delete" menu item
label: "Delete",
action: function () {
jqModalManager.data =
{
call : 'plugin_metaeditor',
q: 'deleteMetaValue',
r: selectedPageId,
+ sectok: sectok,
opts: {
key: selectedNodePath,
oldval: selectedNodeValue
}
};
jqModalManager.msg = "Do you really want to delete the selected node?<br>&nbsp;<br>";
jqModalManager.msg += "PageId: " + selectedPageId + "<br>";
jqModalManager.msg += "NodePath: " + selectedNodePath + "<br>";
jqModalManager.msg += "Value: " + selectedNodeValue;
jqModalManager.completeCb = function(data) {
jqModalManager.msg = data[1];
jqModalManager.showInfoDialog();
refreshMetaTree();
};
jqModalManager.showConfirmDialog();
}
},
createFolderItem: { // The "Create folder" menu item
label: "Create Folder",
action: function (data) {
var tree = jQuery("#metaTree").jstree(true);
var nodePath = tree.get_path(node);
if(node.li_attr['data-type'] == 'file')
{
var id = tree.get_parent(node);
var parentNode = tree.get_node(id);
nodePath = tree.get_path(parentNode);
}
jqModalManager.data =
{
call : 'plugin_metaeditor',
q: 'createMetaArray',
r: selectedPageId,
+ sectok: sectok,
opts: {
key : nodePath,
newval: null
}
};
jqModalManager.msg = "Create new folder<br>&nbsp;<br>";
jqModalManager.msg += "Parent: " + nodePath;
jqModalManager.completeCb = function(data) {
jqModalManager.msg = data[1];
jqModalManager.showInfoDialog();
refreshMetaTree();
};
jqModalManager.createValue = false;
jqModalManager.showCreateDialog();
}
},
createItem: { // The "Create" menu item
label: "Create Property",
action: function () {
var tree = jQuery("#metaTree").jstree(true);
var nodePath = tree.get_path(node);
if(node.li_attr['data-type'] == 'file')
{
var id = tree.get_parent(node);
var parentNode = tree.get_node(id);
nodePath = tree.get_path(parentNode);
}
jqModalManager.data =
{
call : 'plugin_metaeditor',
q: 'createMetaValue',
r: selectedPageId,
+ sectok: sectok,
opts: {
key : nodePath,
newkey: null,
newval: null
}
};
jqModalManager.msg = "Create new item<br>&nbsp;<br>";
jqModalManager.msg += "Parent: " + nodePath;
jqModalManager.completeCb = function(data) {
jqModalManager.msg = data[1];
jqModalManager.showInfoDialog();
refreshMetaTree();
};
jqModalManager.createValue = true;
jqModalManager.showCreateDialog();
}
}
};
return items;
}
jQuery('#metaTree').on('changed.jstree', function (e, data) {
var i, j, r;
if(data.selected.length != 1)
return;
var node = data.instance.get_node(data.selected[0]);
r = data.instance.get_path(data.selected[0]);
selectedNodePath = r;
if(node.li_attr['data-type'] == 'folder')
return;
//if(!data.instance.is_leaf(node))
// return;
selectedNode = r;
jQuery.post(
DOKU_BASE + 'lib/exe/ajax.php',
{
call: 'plugin_metaeditor',
q: 'getMetaValue',
r: selectedPageId,
+ sectok: sectok,
opts: {
key: r
}
},
function(data) {
jQuery('#event_path').html(selectedNode.join(':'));
jQuery('#event_value').val(data);
selectedNodeValue = data;
}
);
})
// create the instance
.jstree({
core : {
multiple: false,
},
plugins: ["wholerow", "contextmenu"],
contextmenu: { items: customMenu }
});
jQuery('#fileTree').on('changed.jstree', function (e, data) {
var i, j, r;
if(data.selected.length != 1)
return;
var node = data.instance.get_node(data.selected[0]);
if(!data.instance.is_leaf(node))
return;
r = node.text;
selectedPageId = r;
jQuery.post(
DOKU_BASE + 'lib/exe/ajax.php',
{
call: 'plugin_metaeditor',
q: 'getMeta',
+ sectok: sectok,
r: r
},
function(data) {
jQuery('#metaTree').jstree(true).settings.core.data = data;
jQuery('#metaTree').jstree(true).refresh();
}
);
})
// create the instance
.jstree({
core : {
multiple: false
},
plugins: ["wholerow"]
});
});
var jqModalManager = {
jqConfirmModal : null,
jqCreateModal : null,
jqInfoModal : null,
completeCb : null,
data : null,
msg : null,
createValue: false,
init : function()
{
},
showCreateDialog : function() {
jqModalManager.jqCreateModal = jQuery(document.createElement('div'))
.dialog({
autoOpen: false,
draggable: true,
title: "Create",
resizable: true,
buttons: {
Create: function() {
if(jqModalManager.createValue)
{
jqModalManager.data.opts.newkey = jQuery("#metaeditor__createInput").val();
jqModalManager.data.opts.newval = jQuery("#metaeditor__createValue").val();
}
else
{
jqModalManager.data.opts.newval = jQuery("#metaeditor__createInput").val();
}
jQuery.post(
DOKU_BASE + 'lib/exe/ajax.php',
jqModalManager.data,
function(data) {
jqModalManager.completeCb(data);
}
);
jqModalManager.hideCreateDialog();
},
Cancel: function() {
jqModalManager.hideCreateDialog();
}
}
})
.html(
'<div>' + jqModalManager.msg + '</div>' +
'<div>Name <input type="text" id="metaeditor__createInput"></div>' +
(jqModalManager.createValue ? '<div>Value <input type="text" id="metaeditor__createValue"></div>' : '')
)
.parent()
.attr('id','metaeditor__create')
.show()
.appendTo('.dokuwiki:first');
jQuery('#metaeditor__createInput').focus();
jQuery('#metaeditor__create').position({
my: "center",
at: "center",
of: window
});
// attach event handlers
jQuery('#metaeditor__create .ui-dialog-titlebar-close').click(function(){
jqModalManager.hideCreateDialog();
});
},
showInfoDialog : function() {
jqModalManager.jqInfoModal = jQuery(document.createElement('div'))
.dialog({
autoOpen: false,
draggable: true,
title: "Info",
resizable: true,
buttons: {
OK: function() {
jqModalManager.hideInfoDialog();
}
}
})
.html(
'<div>' + jqModalManager.msg + '</div>'
)
.parent()
.attr('id','metaeditor__info')
.show()
.appendTo('.dokuwiki:first');
jQuery('#metaeditor__info').position({
my: "center",
at: "center",
of: window
});
// attach event handlers
jQuery('#metaeditor__info .ui-dialog-titlebar-close').click(function(){
jqModalManager.hideInfoDialog();
});
},
showConfirmDialog : function() {
jqModalManager.jqConfirmModal = jQuery(document.createElement('div'))
.dialog({
autoOpen: false,
draggable: true,
title: "Confirmation",
resizable: true,
buttons: {
Yes: function() {
jQuery.post(
DOKU_BASE + 'lib/exe/ajax.php',
jqModalManager.data,
function(data) {
jqModalManager.completeCb(data);
}
);
jqModalManager.hideConfirmDialog();
},
Cancel: function() {
jqModalManager.hideConfirmDialog();
}
}
})
.html(
'<div>' + jqModalManager.msg + '</div>'
)
.parent()
.attr('id','metaeditor__confirm')
.show()
.appendTo('.dokuwiki:first');
jQuery('#metaeditor__confirm').position({
my: "center",
at: "center",
of: window
});
// attach event handlers
jQuery('#metaeditor__confirm .ui-dialog-titlebar-close').click(function(){
jqModalManager.hideConfirmDialog();
});
},
hideConfirmDialog : function() {
jqModalManager.jqConfirmModal.empty();
jqModalManager.jqConfirmModal.remove();
jqModalManager.jqConfirmModal = null;
},
hideCreateDialog : function() {
jqModalManager.jqCreateModal.empty();
jqModalManager.jqCreateModal.remove();
jqModalManager.jqCreateModal = null;
},
hideInfoDialog : function() {
jqModalManager.jqInfoModal.empty();
jqModalManager.jqInfoModal.remove();
jqModalManager.jqInfoModal = null;
}
};

File Metadata

Mime Type
text/x-diff
Expires
Sat, Dec 21, 7:23 PM (2 w, 2 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
533769
Default Alt Text
(20 KB)

Event Timeline