From 344c293424716cc53eed2fea9eb3a7512e725516 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 4 Jun 2016 15:12:04 -0400 Subject: Wiki and page filenames are abstracted from their displayed names. Special characters do not seem to break things. --- Zotlabs/Module/Wiki.php | 42 +++++++++++++++++++------------------ include/widgets.php | 10 +++++---- include/wiki.php | 50 +++++++++++++++++++++++++++------------------ view/tpl/wiki.tpl | 4 ++-- view/tpl/wiki_page_list.tpl | 2 +- view/tpl/wikilist.tpl | 2 +- 6 files changed, 62 insertions(+), 48 deletions(-) diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index c74fc6c6f..ef42c85cf 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -80,13 +80,13 @@ class Wiki extends \Zotlabs\Web\Controller { break; case 3: // /wiki/channel/wiki -> No page was specified, so redirect to Home.md - goaway('/'.argv(0).'/'.argv(1).'/'.argv(2).'/Home.md'); + goaway('/'.argv(0).'/'.argv(1).'/'.argv(2).'/Home'); case 4: // GET /wiki/channel/wiki/page // Fetch the wiki info and determine observer permissions - $wikiname = argv(2); - $pagename = argv(3); - $w = wiki_exists_by_name($channel['channel_id'], $wikiname); + $wikiUrlName = urlencode(argv(2)); + $pageUrlName = urlencode(argv(3)); + $w = wiki_exists_by_name($channel['channel_id'], $wikiUrlName); if(!$w['resource_id']) { notice('Wiki not found' . EOL); goaway('/'.argv(0).'/'.argv(1)); @@ -102,8 +102,8 @@ class Wiki extends \Zotlabs\Web\Controller { goaway('/'.argv(0).'/'.argv(1)); } } - $wikiheader = rawurldecode($wikiname) . ': ' . rawurldecode($pagename); // show wiki name and page - $p = wiki_get_page_content(array('resource_id' => $resource_id, 'page' => $pagename)); + $wikiheader = urldecode($wikiUrlName) . ': ' . urldecode($pageUrlName); // show wiki name and page + $p = wiki_get_page_content(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName)); if(!$p['success']) { notice('Error retrieving page content' . EOL); goaway('/'.argv(0).'/'.argv(1).'/'.argv(2)); @@ -113,7 +113,7 @@ class Wiki extends \Zotlabs\Web\Controller { $showPageControls = $wiki_owner; $showNewWikiButton = $wiki_owner; $showNewPageButton = $wiki_owner; - $pageHistory = wiki_page_history(array('resource_id' => $resource_id, 'page' => $pagename)); + $pageHistory = wiki_page_history(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName)); break; default: // Strip the extraneous URL components goaway('/'.argv(0).'/'.argv(1).'/'.argv(2).'/'.argv(3)); @@ -129,7 +129,7 @@ class Wiki extends \Zotlabs\Web\Controller { '$showNewPageButton'=> $showNewPageButton, '$channel' => $channel['channel_address'], '$resource_id' => $resource_id, - '$page' => $pagename, + '$page' => $pageUrlName, '$lockstate' => $x['lockstate'], '$acl' => $x['acl'], '$bang' => $x['bang'], @@ -178,7 +178,7 @@ class Wiki extends \Zotlabs\Web\Controller { // Generate new wiki info from input name $wiki['rawName'] = $_POST['wikiName']; $wiki['htmlName'] = escape_tags($_POST['wikiName']); - $wiki['urlName'] = urlencode(escape_tags($_POST['wikiName'])); + $wiki['urlName'] = urlencode($_POST['wikiName']); if($wiki['urlName'] === '') { notice('Error creating wiki. Invalid name.'); goaway('/wiki'); @@ -193,7 +193,7 @@ class Wiki extends \Zotlabs\Web\Controller { notice('Wiki created, but error creating Home page.'); goaway('/wiki/'.$nick.'/'.$wiki['urlName']); } - goaway('/wiki/'.$nick.'/'.$wiki['urlName'].'/'.$homePage['urlName']); + goaway('/wiki/'.$nick.'/'.$wiki['urlName'].'/'.$homePage['page']['urlName']); } else { notice('Error creating wiki'); goaway('/wiki'); @@ -252,13 +252,13 @@ class Wiki extends \Zotlabs\Web\Controller { json_return_and_die(array('success' => false)); } } - $name = escape_tags(urlencode($_POST['name'])); //Get new page name - if($name === '') { + $name = $_POST['name']; //Get new page name + if(urlencode(escape_tags($_POST['name'])) === '') { json_return_and_die(array('message' => 'Error creating page. Invalid name.', 'success' => false)); } - $page = wiki_create_page($name . '.md', $resource_id); + $page = wiki_create_page($name, $resource_id); if ($page['success']) { - json_return_and_die(array('url' => '/'.argv(0).'/'.argv(1).'/'.$page['wiki'].'/'.$name.'.md', 'success' => true)); + json_return_and_die(array('url' => '/'.argv(0).'/'.argv(1).'/'.$page['wiki']['urlName'].'/'.urlencode($page['page']['urlName']), 'success' => true)); } else { logger('Error creating page'); json_return_and_die(array('message' => 'Error creating page.', 'success' => false)); @@ -286,7 +286,9 @@ class Wiki extends \Zotlabs\Web\Controller { if ((argc() === 4) && (argv(2) === 'save') && (argv(3) === 'page')) { $nick = argv(1); $resource_id = $_POST['resource_id']; - $pagename = escape_tags(urlencode($_POST['name'])); + $pageUrlName = $_POST['name']; + logger('pageURLname: ' . $pageUrlName); + $pageHtmlName = escape_tags($_POST['name']); $content = escape_tags($_POST['content']); //Get new content // Determine if observer has permission to save content if (local_channel()) { @@ -308,14 +310,14 @@ class Wiki extends \Zotlabs\Web\Controller { json_return_and_die(array('success' => false)); } } - $saved = wiki_save_page(array('resource_id' => $resource_id, 'name' => $pagename, 'content' => $content)); + $saved = wiki_save_page(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName, 'content' => $content)); if($saved['success']) { $ob = \App::get_observer(); $commit = wiki_git_commit(array( - 'commit_msg' => 'Updated ' . $pagename, + 'commit_msg' => 'Updated ' . $pageHtmlName, 'resource_id' => $resource_id, 'observer' => $ob, - 'files' => array($pagename) + 'files' => array($pageUrlName.'.md') )); if($commit['success']) { json_return_and_die(array('message' => 'Wiki git repo commit made', 'success' => true)); @@ -332,7 +334,7 @@ class Wiki extends \Zotlabs\Web\Controller { if ((argc() === 4) && (argv(2) === 'history') && (argv(3) === 'page')) { $nick = argv(1); $resource_id = $_POST['resource_id']; - $pagename = escape_tags(urlencode($_POST['name'])); + $pageUrlName = $_POST['name']; // Determine if observer has permission to view content if (local_channel()) { $channel = \App::get_channel(); @@ -347,7 +349,7 @@ class Wiki extends \Zotlabs\Web\Controller { } $historyHTML = widget_wiki_page_history(array( 'resource_id' => $resource_id, - 'page' => $pagename + 'pageUrlName' => $pageUrlName )); json_return_and_die(array('historyHTML' => $historyHTML, 'message' => '', 'success' => true)); } diff --git a/include/widgets.php b/include/widgets.php index b5c3b425a..9ea517a2d 100644 --- a/include/widgets.php +++ b/include/widgets.php @@ -897,13 +897,15 @@ function widget_wiki_pages($arr) { $p = wiki_page_list($arr['resource_id']); if ($p['pages']) { $pages = $p['pages']; - $w = wiki_get_wiki($arr['resource_id']); - $wikiname = $w['wiki']['title']; + $w = $p['wiki']; + // Wiki item record is $w['wiki'] + $wikiname = $w['urlName']; if (!$wikiname) { $wikiname = ''; } } } + logger('pages: ' . json_encode($pages)); return replace_macros(get_markup_template('wiki_page_list.tpl'), array( '$hide' => $hide, '$not_refresh' => $not_refresh, @@ -916,9 +918,9 @@ function widget_wiki_pages($arr) { function widget_wiki_page_history($arr) { require_once("include/wiki.php"); - $pagename = ((array_key_exists('page', $arr)) ? $arr['page'] : ''); + $pageUrlName = ((array_key_exists('pageUrlName', $arr)) ? $arr['pageUrlName'] : ''); $resource_id = ((array_key_exists('resource_id', $arr)) ? $arr['resource_id'] : ''); - $pageHistory = wiki_page_history(array('resource_id' => $resource_id, 'page' => $pagename)); + $pageHistory = wiki_page_history(array('resource_id' => $resource_id, 'pageUrlName' => $pageUrlName)); return replace_macros(get_markup_template('wiki_page_history.tpl'), array( '$pageHistory' => $pageHistory['history'] diff --git a/include/wiki.php b/include/wiki.php index 822cb1b88..ccf47ef9a 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -13,6 +13,12 @@ function wiki_list($channel, $observer_hash) { dbesc(WIKI_ITEM_RESOURCE_TYPE), intval($channel['channel_id']) ); + foreach($wikis as &$w) { + $w['rawName'] = get_iconfig($w, 'wiki', 'rawName'); + $w['htmlName'] = get_iconfig($w, 'wiki', 'htmlName'); + $w['urlName'] = get_iconfig($w, 'wiki', 'urlName'); + $w['path'] = get_iconfig($w, 'wiki', 'path'); + } // TODO: query db for wikis the observer can access. Return with two lists, for read and write access return array('wikis' => $wikis); } @@ -21,16 +27,20 @@ function wiki_page_list($resource_id) { // TODO: Create item table records for pages so that metadata like title can be applied $w = wiki_get_wiki($resource_id); if (!$w['path']) { - return array('pages' => null); + return array('pages' => null, 'wiki' => null); } $pages = array(); if (is_dir($w['path']) === true) { $files = array_diff(scandir($w['path']), array('.', '..', '.git')); // TODO: Check that the files are all text files - $pages = $files; + + foreach($files as $file) { + // strip the .md file extension and unwrap URL encoding to leave HTML encoded name + $pages[] = array('title' => urldecode(substr($file, 0, -3)), 'url' => urlencode(substr($file, 0, -3))); + } } - return array('pages' => $pages); + return array('pages' => $pages, 'wiki' => $w); } function wiki_init_wiki($channel, $wiki) { @@ -166,10 +176,10 @@ function wiki_get_wiki($resource_id) { } } -function wiki_exists_by_name($uid, $name) { +function wiki_exists_by_name($uid, $urlName) { $item = q("SELECT id,resource_id FROM item WHERE resource_type = '%s' AND title = '%s' AND uid = '%s' AND item_deleted = 0 limit 1", dbesc(WIKI_ITEM_RESOURCE_TYPE), - dbesc($name), + dbesc(escape_tags(urldecode($urlName))), dbesc($uid) ); if (!$item) { @@ -196,31 +206,31 @@ function wiki_get_permissions($resource_id, $owner_id, $observer_hash) { function wiki_create_page($name, $resource_id) { $w = wiki_get_wiki($resource_id); if (!$w['path']) { - return array('page' => null, 'message' => 'Wiki not found.', 'success' => false); + return array('page' => null, 'wiki' => null, 'message' => 'Wiki not found.', 'success' => false); } - $page = array('rawName' => $name, 'htmlName' => escape_tags($name), 'urlName' => urlencode(escape_tags($name)), 'fileName' => wiki_generate_page_filename($name)); - $page_path = $w['path'] . '/' . $page['urlName']; + $page = array('rawName' => $name, 'htmlName' => escape_tags($name), 'urlName' => urlencode(escape_tags($name)), 'fileName' => urlencode(escape_tags($name)).'.md'); + $page_path = $w['path'] . '/' . $page['fileName']; if (is_file($page_path)) { - return array('page' => null, 'message' => 'Page already exists.', 'success' => false); + return array('page' => null, 'wiki' => null, 'message' => 'Page already exists.', 'success' => false); } // Create the page file in the wiki repo if(!touch($page_path)) { - return array('page' => null, 'message' => 'Page file cannot be created.', 'success' => false); + return array('page' => null, 'wiki' => null, 'message' => 'Page file cannot be created.', 'success' => false); } else { - return array('page' => $page, 'message' => '', 'success' => true); + return array('page' => $page, 'wiki' => $w, 'message' => '', 'success' => true); } } function wiki_get_page_content($arr) { - $page = ((array_key_exists('page',$arr)) ? $arr['page'] : ''); - // TODO: look for page resource_id and retrieve that way alternatively + $pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : ''); $resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : ''); $w = wiki_get_wiki($resource_id); if (!$w['path']) { return array('content' => null, 'message' => 'Error reading wiki', 'success' => false); } - $page_path = $w['path'].'/'.escape_tags(urlencode($page)); + $page_path = $w['path'].'/'.$pageUrlName.'.md'; + logger('$page_path: ' . $page_path); if (is_readable($page_path) === true) { if(filesize($page_path) === 0) { $content = ''; @@ -236,13 +246,13 @@ function wiki_get_page_content($arr) { } function wiki_page_history($arr) { - $pagename = ((array_key_exists('page',$arr)) ? $arr['page'] : ''); + $pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : ''); $resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : ''); $w = wiki_get_wiki($resource_id); if (!$w['path']) { return array('history' => null, 'message' => 'Error reading wiki', 'success' => false); } - $page_path = $w['path'].'/'.$pagename; + $page_path = $w['path'].'/'.$pageUrlName.'.md'; if (!is_readable($page_path) === true) { return array('history' => null, 'message' => 'Cannot read wiki page: ' . $page_path, 'success' => false); } @@ -252,7 +262,7 @@ function wiki_page_history($arr) { } $git = new GitRepo('', null, false, $w['wiki']['title'], $w['path']); try { - $gitlog = $git->git->log('', $page_path , array('limit' => 50)); + $gitlog = $git->git->log('', $page_path , array('limit' => 500)); logger('gitlog: ' . json_encode($gitlog)); return array('history' => $gitlog, 'message' => '', 'success' => true); } catch (\PHPGit\Exception\GitException $e) { @@ -261,14 +271,14 @@ function wiki_page_history($arr) { } function wiki_save_page($arr) { - $pagename = ((array_key_exists('name',$arr)) ? $arr['name'] : ''); + $pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : ''); $content = ((array_key_exists('content',$arr)) ? $arr['content'] : ''); $resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : ''); $w = wiki_get_wiki($resource_id); if (!$w['path']) { return array('message' => 'Error reading wiki', 'success' => false); } - $page_path = $w['path'].'/'.$pagename; + $page_path = $w['path'].'/'.$pageUrlName.'.md'; if (is_writable($page_path) === true) { if(!file_put_contents($page_path, $content)) { return array('message' => 'Error writing to page file', 'success' => false); @@ -288,7 +298,7 @@ function wiki_git_commit($arr) { if (!$w['path']) { return array('message' => 'Error reading wiki', 'success' => false); } - $reponame = ((array_key_exists('title', $w['wiki'])) ? $w['wiki']['title'] : 'repo'); + $reponame = ((array_key_exists('title', $w['wiki'])) ? urlencode($w['wiki']['title']) : 'repo'); if($reponame === '') { $reponame = 'repo'; } diff --git a/view/tpl/wiki.tpl b/view/tpl/wiki.tpl index 86c503bb3..384dc796d 100644 --- a/view/tpl/wiki.tpl +++ b/view/tpl/wiki.tpl @@ -139,8 +139,8 @@ ev.preventDefault(); }); -function wiki_delete_wiki(wikiName, resource_id) { - if(!confirm('Are you sure you want to delete the entire wiki: ' + JSON.stringify(wikiName))) { +function wiki_delete_wiki(wikiHtmlName, resource_id) { + if(!confirm('Are you sure you want to delete the entire wiki: ' + JSON.stringify(wikiHtmlName))) { return; } $.post("wiki/{{$channel}}/delete/wiki", {resource_id: resource_id}, function (data) { diff --git a/view/tpl/wiki_page_list.tpl b/view/tpl/wiki_page_list.tpl index c941e4a08..1c3254465 100644 --- a/view/tpl/wiki_page_list.tpl +++ b/view/tpl/wiki_page_list.tpl @@ -3,7 +3,7 @@

{{$header}}

diff --git a/view/tpl/wikilist.tpl b/view/tpl/wikilist.tpl index 91ac1a7b3..be353ca5e 100644 --- a/view/tpl/wikilist.tpl +++ b/view/tpl/wikilist.tpl @@ -7,7 +7,7 @@ {{$wiki.title}}