From c6aa42773a17d53b4572488967b99666ab97ef97 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 21 May 2016 14:56:42 -0400 Subject: Trying to fix wiki branch starting fresh from dev --- include/wiki.php | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 include/wiki.php (limited to 'include/wiki.php') diff --git a/include/wiki.php b/include/wiki.php new file mode 100644 index 000000000..4f4d978e1 --- /dev/null +++ b/include/wiki.php @@ -0,0 +1,82 @@ + array('wiki1'), 'read' => array('wiki1', 'wiki2')); +} + +function wiki_pages() { + // TODO: scan wiki folder for pages + return array('pages' => array('page1.md', 'page2.md')); +} + +function wiki_create_wiki($channel, $name, $acl) { + + // Generate unique resource_id using the same method as item_message_id() + do { + $dups = false; + $resource_id = random_string(); + $r = q("SELECT mid FROM item WHERE resource_id = '%s' AND resource_type = '%s' AND uid = %d LIMIT 1", + dbesc($resource_id), + dbesc(WIKI_ITEM_RESOURCE_TYPE), + intval($channel['channel_id']) + ); + if (count($r)) + $dups = true; + } while ($dups == true); + $ac = $acl->get(); + $mid = item_message_id(); + $arr = array(); // Initialize the array of parameters for the post + $perms = $acl->get(); + $allow_cid = expand_acl($perms['allow_cid']); + $players = array($channel['channel_hash'], $allow_cid[0]); + + $item_hidden = 0; // TODO: Allow form creator to send post to ACL about new game automatically + $game_url = z_root() . '/chess/' . $channel['channel_address'] . '/' . $resource_id; + $arr['aid'] = $channel['channel_account_id']; + $arr['uid'] = $channel['channel_id']; + $arr['mid'] = $mid; + $arr['parent_mid'] = $mid; + $arr['item_hidden'] = $item_hidden; + $arr['resource_type'] = WIKI_ITEM_RESOURCE_TYPE; + $arr['resource_id'] = $resource_id; + $arr['owner_xchan'] = $channel['channel_hash']; + $arr['author_xchan'] = $channel['channel_hash']; + // Store info about the type of chess item using the "title" field + // Other types include 'move' for children items but may in the future include + // additional types that will determine how the "object" field is interpreted + $arr['title'] = $name; + $arr['allow_cid'] = $ac['allow_cid']; + $arr['item_wall'] = 1; + $arr['item_origin'] = 1; + $arr['item_thread_top'] = 1; + $arr['item_private'] = intval($acl->is_private()); + $arr['verb'] = ACTIVITY_CREATE; + $arr['obj_type'] = ACTIVITY_OBJ_WIKI; + $arr['object'] = $object; + $arr['body'] = '[table][tr][td][h1]New Chess Game[/h1][/td][/tr][tr][td][zrl='.$game_url.']Click here to play[/zrl][/td][/tr][/table]'; + + $post = item_store($arr); + $item_id = $post['item_id']; + + if ($item_id) { + proc_run('php', "include/notifier.php", "activity", $item_id); + return array('item' => $arr, 'status' => true); + } else { + return array('item' => null, 'status' => false); + } +} \ No newline at end of file -- cgit v1.2.3 From 049147a9d78b981482297c3daf48c67f31754259 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 21 May 2016 19:02:23 -0400 Subject: Successful new wiki git repo and item table record --- include/wiki.php | 129 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 75 insertions(+), 54 deletions(-) (limited to 'include/wiki.php') diff --git a/include/wiki.php b/include/wiki.php index 4f4d978e1..32caa98e8 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -4,6 +4,7 @@ * @brief Wiki related functions. */ +use \Zotlabs\Storage\GitRepo as GitRepo; define ( 'WIKI_ITEM_RESOURCE_TYPE', 'wiki' ); function wiki_create() { @@ -24,59 +25,79 @@ function wiki_pages() { return array('pages' => array('page1.md', 'page2.md')); } -function wiki_create_wiki($channel, $name, $acl) { +function wiki_init_wiki($channel, $name) { + // Store the path as a relative path, but pass absolute path to mkdir + $path = 'store/[data]/git/'.$channel['channel_address'].'/wiki/'.$name; + if (!mkdir(__DIR__ . '/../' . $path, 0770, true)) { + logger('Error creating wiki path: ' . $name); + return null; + } + // Create GitRepo object + $git = new GitRepo($channel['channel_address'], null, false, $name, __DIR__ . '/../' . $path); + if(!$git->initRepo()) { + logger('Error creating new git repo in ' . $git->path); + return null; + } + + return array('path' => $path); +} - // Generate unique resource_id using the same method as item_message_id() - do { - $dups = false; - $resource_id = random_string(); - $r = q("SELECT mid FROM item WHERE resource_id = '%s' AND resource_type = '%s' AND uid = %d LIMIT 1", - dbesc($resource_id), - dbesc(WIKI_ITEM_RESOURCE_TYPE), - intval($channel['channel_id']) - ); - if (count($r)) - $dups = true; - } while ($dups == true); - $ac = $acl->get(); - $mid = item_message_id(); - $arr = array(); // Initialize the array of parameters for the post - $perms = $acl->get(); - $allow_cid = expand_acl($perms['allow_cid']); - $players = array($channel['channel_hash'], $allow_cid[0]); - - $item_hidden = 0; // TODO: Allow form creator to send post to ACL about new game automatically - $game_url = z_root() . '/chess/' . $channel['channel_address'] . '/' . $resource_id; - $arr['aid'] = $channel['channel_account_id']; - $arr['uid'] = $channel['channel_id']; - $arr['mid'] = $mid; - $arr['parent_mid'] = $mid; - $arr['item_hidden'] = $item_hidden; - $arr['resource_type'] = WIKI_ITEM_RESOURCE_TYPE; - $arr['resource_id'] = $resource_id; - $arr['owner_xchan'] = $channel['channel_hash']; - $arr['author_xchan'] = $channel['channel_hash']; - // Store info about the type of chess item using the "title" field - // Other types include 'move' for children items but may in the future include - // additional types that will determine how the "object" field is interpreted - $arr['title'] = $name; - $arr['allow_cid'] = $ac['allow_cid']; - $arr['item_wall'] = 1; - $arr['item_origin'] = 1; - $arr['item_thread_top'] = 1; - $arr['item_private'] = intval($acl->is_private()); - $arr['verb'] = ACTIVITY_CREATE; - $arr['obj_type'] = ACTIVITY_OBJ_WIKI; - $arr['object'] = $object; - $arr['body'] = '[table][tr][td][h1]New Chess Game[/h1][/td][/tr][tr][td][zrl='.$game_url.']Click here to play[/zrl][/td][/tr][/table]'; - - $post = item_store($arr); - $item_id = $post['item_id']; +function wiki_create_wiki($channel, $observer_hash, $name, $acl) { + $wikiinit = wiki_init_wiki($channel, $name); + if (!$wikiinit['path']) { + notice('Error creating wiki'); + return array('item' => null, 'success' => false); + } + $path = $wikiinit['path']; + // Generate unique resource_id using the same method as item_message_id() + do { + $dups = false; + $resource_id = random_string(); + $r = q("SELECT mid FROM item WHERE resource_id = '%s' AND resource_type = '%s' AND uid = %d LIMIT 1", + dbesc($resource_id), + dbesc(WIKI_ITEM_RESOURCE_TYPE), + intval($channel['channel_id']) + ); + if (count($r)) + $dups = true; + } while ($dups == true); + $ac = $acl->get(); + $mid = item_message_id(); + $arr = array(); // Initialize the array of parameters for the post + $item_hidden = 0; // TODO: Allow form creator to send post to ACL about new game automatically + $wiki_url = z_root() . '/wiki/' . $channel['channel_address'] . '/' . $name; + $arr['aid'] = $channel['channel_account_id']; + $arr['uid'] = $channel['channel_id']; + $arr['mid'] = $mid; + $arr['parent_mid'] = $mid; + $arr['item_hidden'] = $item_hidden; + $arr['resource_type'] = WIKI_ITEM_RESOURCE_TYPE; + $arr['resource_id'] = $resource_id; + $arr['owner_xchan'] = $channel['channel_hash']; + $arr['author_xchan'] = $observer_hash; + $arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . $arr['mid']; + $arr['llink'] = $arr['plink']; + $arr['title'] = $name; // name of new wiki; + $arr['allow_cid'] = $ac['allow_cid']; + $arr['allow_gid'] = $ac['allow_gid']; + $arr['deny_cid'] = $ac['deny_cid']; + $arr['deny_gid'] = $ac['deny_gid']; + $arr['item_wall'] = 1; + $arr['item_origin'] = 1; + $arr['item_thread_top'] = 1; + $arr['item_private'] = intval($acl->is_private()); + $arr['verb'] = ACTIVITY_CREATE; + $arr['obj_type'] = ACTIVITY_OBJ_WIKI; + $arr['object'] = array('path' => $path); + $arr['body'] = '[table][tr][td][h1]New Wiki[/h1][/td][/tr][tr][td][zrl=' . $wiki_url . ']' . $name . '[/zrl][/td][/tr][/table]'; - if ($item_id) { - proc_run('php', "include/notifier.php", "activity", $item_id); - return array('item' => $arr, 'status' => true); - } else { - return array('item' => null, 'status' => false); - } -} \ No newline at end of file + $post = item_store($arr); + $item_id = $post['item_id']; + + if ($item_id) { + proc_run('php', "include/notifier.php", "activity", $item_id); + return array('item' => $arr, 'success' => true); + } else { + return array('item' => null, 'success' => false); + } +} -- cgit v1.2.3 From a36bef7979aecd72751d319f85b7037991979e35 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 21 May 2016 21:55:09 -0400 Subject: List of wikis populates with links according to observer permissions. --- include/wiki.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'include/wiki.php') diff --git a/include/wiki.php b/include/wiki.php index 32caa98e8..7cd838f95 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -15,9 +15,17 @@ function wiki_delete() { } -function wiki_list($observer_hash) { +function wiki_list($nick, $observer_hash) { + if (local_channel() || remote_channel()) { + $sql_extra = item_permissions_sql(get_channel_by_nick($nick)['channel_id'], $observer_hash); + } else { + $sql_extra = " AND item_private = 0 "; + } + $wikis = q("SELECT * FROM item WHERE resource_type = '%s' AND mid = parent_mid AND item_deleted = 0 $sql_extra", + dbesc(WIKI_ITEM_RESOURCE_TYPE) + ); // TODO: query db for wikis the observer can access. Return with two lists, for read and write access - return array('write' => array('wiki1'), 'read' => array('wiki1', 'wiki2')); + return array('wikis' => $wikis); } function wiki_pages() { -- cgit v1.2.3 From e00b8a70829213a4333a53a097c2c498d529f5d6 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Tue, 24 May 2016 06:15:42 -0400 Subject: Delete wiki (in progress) --- include/wiki.php | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) (limited to 'include/wiki.php') diff --git a/include/wiki.php b/include/wiki.php index 7cd838f95..0f00cd122 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -7,14 +7,6 @@ use \Zotlabs\Storage\GitRepo as GitRepo; define ( 'WIKI_ITEM_RESOURCE_TYPE', 'wiki' ); -function wiki_create() { - -} - -function wiki_delete() { - -} - function wiki_list($nick, $observer_hash) { if (local_channel() || remote_channel()) { $sql_extra = item_permissions_sql(get_channel_by_nick($nick)['channel_id'], $observer_hash); @@ -36,7 +28,7 @@ function wiki_pages() { function wiki_init_wiki($channel, $name) { // Store the path as a relative path, but pass absolute path to mkdir $path = 'store/[data]/git/'.$channel['channel_address'].'/wiki/'.$name; - if (!mkdir(__DIR__ . '/../' . $path, 0770, true)) { + if (!os_mkdir(__DIR__ . '/../' . $path, 0770, true)) { logger('Error creating wiki path: ' . $name); return null; } @@ -109,3 +101,22 @@ function wiki_create_wiki($channel, $observer_hash, $name, $acl) { return array('item' => null, 'success' => false); } } + +function wiki_delete_wiki($resource_id) { + $item = q("SELECT id FROM item WHERE resource_type = '%s' AND resource_id = '%s' AND item_deleted = 0 limit 1", + dbesc(WIKI_ITEM_RESOURCE_TYPE), + dbesc($resource_id) + ); + if (!$item) { + return array('items' => null, 'success' => false); + } else { + $drop = drop_item($item[0]['id'],false,DROPITEM_NORMAL,true); + $object = json_decode($item[0]['object'], true); + $abs_path = __DIR__ . '/../' . $object['path']; + logger('path to delete: ' . $abs_path); + $pathdel = true; + //$pathdel = rrmdir($abs_path); + + return array('item' => $item, 'success' => (($drop === 1 && $pathdel) ? true : false)); + } +} -- cgit v1.2.3 From 97e6b7c4ba1938a46ea18d3ef96eba2d6246dab0 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Fri, 27 May 2016 20:20:33 -0400 Subject: Wiki deletion works --- include/wiki.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'include/wiki.php') diff --git a/include/wiki.php b/include/wiki.php index 0f00cd122..828121ba9 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -103,7 +103,7 @@ function wiki_create_wiki($channel, $observer_hash, $name, $acl) { } function wiki_delete_wiki($resource_id) { - $item = q("SELECT id FROM item WHERE resource_type = '%s' AND resource_id = '%s' AND item_deleted = 0 limit 1", + $item = q("SELECT id, object FROM item WHERE resource_type = '%s' AND resource_id = '%s' AND item_deleted = 0 limit 1", dbesc(WIKI_ITEM_RESOURCE_TYPE), dbesc($resource_id) ); @@ -112,11 +112,15 @@ function wiki_delete_wiki($resource_id) { } else { $drop = drop_item($item[0]['id'],false,DROPITEM_NORMAL,true); $object = json_decode($item[0]['object'], true); - $abs_path = __DIR__ . '/../' . $object['path']; - logger('path to delete: ' . $abs_path); - $pathdel = true; - //$pathdel = rrmdir($abs_path); - + if(!realpath(__DIR__ . '/../' . $object['path'])) { + return array('items' => null, 'success' => false); + } + // Path to wiki exists + $abs_path = realpath(__DIR__ . '/../' . $object['path']); + $pathdel = rrmdir($abs_path); + if($pathdel) { + info('Wiki deleted successfully'); + } return array('item' => $item, 'success' => (($drop === 1 && $pathdel) ? true : false)); } } -- cgit v1.2.3 From ca78ebce6d254f244b4c1fbe25eb3aca40b26952 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Fri, 27 May 2016 20:37:37 -0400 Subject: Check if wiki exists and redirect if it does not --- include/wiki.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'include/wiki.php') diff --git a/include/wiki.php b/include/wiki.php index 828121ba9..90b30d492 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -124,3 +124,16 @@ function wiki_delete_wiki($resource_id) { return array('item' => $item, 'success' => (($drop === 1 && $pathdel) ? true : false)); } } + +function wiki_exists_by_name($name) { + $item = q("SELECT id FROM item WHERE resource_type = '%s' AND title = '%s' AND item_deleted = 0 limit 1", + dbesc(WIKI_ITEM_RESOURCE_TYPE), + dbesc($name) + ); + if (!$item) { + return array('id' => null); + } else { + return array('id' => $item[0]['id']); + } + +} \ No newline at end of file -- cgit v1.2.3 From 4691c3ec01eda972e7b4cae4ec940c8c24d51b5a Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Fri, 27 May 2016 22:19:05 -0400 Subject: Add new page to wiki and redirect to editor page. --- include/wiki.php | 55 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 6 deletions(-) (limited to 'include/wiki.php') diff --git a/include/wiki.php b/include/wiki.php index 90b30d492..317db1239 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -125,15 +125,58 @@ function wiki_delete_wiki($resource_id) { } } -function wiki_exists_by_name($name) { - $item = q("SELECT id FROM item WHERE resource_type = '%s' AND title = '%s' AND item_deleted = 0 limit 1", +function wiki_exists_by_name($uid, $name) { + $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($name), + dbesc($uid) ); if (!$item) { - return array('id' => null); + return array('id' => null, 'resource_id' => null); } else { - return array('id' => $item[0]['id']); + return array('id' => $item[0]['id'], 'resource_id' => $item[0]['resource_id']); } -} \ No newline at end of file +} + +function wiki_get_permissions($resource_id, $owner_id, $observer_hash) { + // TODO: For now, only the owner can edit + $sql_extra = item_permissions_sql($owner_id, $observer_hash); + $r = q("SELECT * FROM item WHERE resource_type = '%s' AND resource_id = '%s' $sql_extra LIMIT 1", + dbesc(WIKI_ITEM_RESOURCE_TYPE), + dbesc($resource_id) + ); + if(!$r) { + return array('read' => false, 'write' => false, 'success' => false); + } else { + return array('read' => true, 'write' => false, 'success' => true); + } +} + +function wiki_create_page($name, $resource_id) { + $item = q("SELECT id,title,object FROM item WHERE resource_type = '%s' AND resource_id = '%s' AND item_deleted = 0 limit 1", + dbesc(WIKI_ITEM_RESOURCE_TYPE), + dbesc($resource_id) + ); + if (!$item) { + return array('page' => null, 'message' => 'Wiki item not found.', 'success' => false); + } + $object = json_decode($item[0]['object'], true); + $wikiname = $item[0]['title']; + if (!realpath(__DIR__ . '/../' . $object['path'])) { + return array('page' => null, 'message' => 'Wiki directory does not exist.', 'success' => false); + } + // Path to wiki exists + $abs_path = realpath(__DIR__ . '/../' . $object['path']); + $page_path = $abs_path . '/' . $name; + if (is_file($page_path)) { + return array('page' => null, 'message' => 'Page already exists.', 'success' => false); + } + // Create file called $name in the path + if(!touch($page_path)) { + return array('page' => null, 'message' => 'Page file cannot be created.', 'success' => false); + } else { + return array('wiki' => $wikiname, 'message' => '', 'success' => true); + } + +} -- cgit v1.2.3 From f884fa66782544cd6fc44a81b978a905d4755cea Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 28 May 2016 07:17:42 -0400 Subject: Wiki page list is fetched and the page widget is updated --- include/wiki.php | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) (limited to 'include/wiki.php') diff --git a/include/wiki.php b/include/wiki.php index 317db1239..c1779e208 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -20,9 +20,20 @@ function wiki_list($nick, $observer_hash) { return array('wikis' => $wikis); } -function wiki_pages() { - // TODO: scan wiki folder for pages - return array('pages' => array('page1.md', 'page2.md')); +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); + } + $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; + } + + return array('pages' => $pages); } function wiki_init_wiki($channel, $name) { @@ -125,6 +136,25 @@ function wiki_delete_wiki($resource_id) { } } +function wiki_get_wiki($resource_id) { + $item = q("SELECT * FROM item WHERE resource_type = '%s' AND resource_id = '%s' AND item_deleted = 0 limit 1", + dbesc(WIKI_ITEM_RESOURCE_TYPE), + dbesc($resource_id) + ); + if (!$item) { + return array('wiki' => null, 'path' => null); + } else { + $w = $item[0]; + $object = json_decode($w['object'], true); + if (!realpath(__DIR__ . '/../' . $object['path'])) { + return array('wiki' => null, 'path' => null); + } + // Path to wiki exists + $abs_path = realpath(__DIR__ . '/../' . $object['path']); + return array('wiki' => $w, 'path' => $abs_path); + } +} + function wiki_exists_by_name($uid, $name) { $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), @@ -147,7 +177,7 @@ function wiki_get_permissions($resource_id, $owner_id, $observer_hash) { dbesc($resource_id) ); if(!$r) { - return array('read' => false, 'write' => false, 'success' => false); + return array('read' => false, 'write' => false, 'success' => true); } else { return array('read' => true, 'write' => false, 'success' => true); } -- cgit v1.2.3 From 7393dccde816bafca2e3efe534fae56339e2c536 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 28 May 2016 12:33:07 -0400 Subject: Page content is loaded from the file on disk --- include/wiki.php | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'include/wiki.php') diff --git a/include/wiki.php b/include/wiki.php index c1779e208..f97036c29 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -210,3 +210,26 @@ function wiki_create_page($name, $resource_id) { } } + +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 + $wiki_resource_id = ((array_key_exists('wiki_resource_id',$arr)) ? $arr['wiki_resource_id'] : ''); + $w = wiki_get_wiki($wiki_resource_id); + if (!$w['path']) { + return array('content' => null, 'message' => 'Error reading wiki', 'success' => false); + } + $page_path = $w['path'].'/'.$page; + if (is_readable($page_path) === true) { + if(filesize($page_path) === 0) { + $content = ''; + } else { + $content = file_get_contents($page_path); + if(!$content) { + return array('content' => null, 'message' => 'Error reading page content', 'success' => false); + } + } + // TODO: Check that the files are all text files + return array('content' => json_encode($content), 'message' => '', 'success' => true); + } +} \ No newline at end of file -- cgit v1.2.3 From ab54bf514921ae3fe0fafcdf154364815ed6375f Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 28 May 2016 15:11:19 -0400 Subject: Wiki pages can be saved. --- include/wiki.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'include/wiki.php') diff --git a/include/wiki.php b/include/wiki.php index f97036c29..e01cc12c3 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -232,4 +232,26 @@ function wiki_get_page_content($arr) { // TODO: Check that the files are all text files return array('content' => json_encode($content), 'message' => '', 'success' => true); } +} + + +function wiki_save_page($arr) { + $pagename = ((array_key_exists('name',$arr)) ? $arr['name'] : ''); + $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; + if (is_writable($page_path) === true) { + if(!file_put_contents($page_path, $content)) { + return array('message' => 'Error writing to page file', 'success' => false); + } + return array('message' => '', 'success' => true); + } else { + return array('message' => 'Page file not writable', 'success' => false); + } + + } \ No newline at end of file -- cgit v1.2.3 From 63a97ff6fc313372d9cb439a621f12fdecc2fac1 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sun, 29 May 2016 10:18:26 -0400 Subject: Git commit made for the page edits when the page is saved. --- include/wiki.php | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) (limited to 'include/wiki.php') diff --git a/include/wiki.php b/include/wiki.php index e01cc12c3..915478da5 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -251,7 +251,44 @@ function wiki_save_page($arr) { return array('message' => '', 'success' => true); } else { return array('message' => 'Page file not writable', 'success' => false); + } +} + +function wiki_git_commit($arr) { + $files = ((array_key_exists('files', $arr)) ? $arr['files'] : null); + $commit_msg = ((array_key_exists('commit_msg', $arr)) ? $arr['commit_msg'] : 'Repo updated'); + $resource_id = ((array_key_exists('resource_id', $arr)) ? $arr['resource_id'] : json_return_and_die(array('message' => 'Wiki resource_id required for git commit', 'success' => false))); + $observer = ((array_key_exists('observer', $arr)) ? $arr['observer'] : json_return_and_die(array('message' => 'Observer required for git commit', 'success' => false))); + $w = wiki_get_wiki($resource_id); + if (!$w['path']) { + return array('message' => 'Error reading wiki', 'success' => false); } - - -} \ No newline at end of file + $reponame = ((array_key_exists('title', $w['wiki'])) ? $w['wiki']['title'] : 'repo'); + if($reponame === '') { + $reponame = 'repo'; + } + $git = new GitRepo('sys', null, false, $w['wiki']['title'], $w['path']); + try { + $git->setIdentity($observer['xchan_name'], $observer['xchan_addr']); + if ($files === null) { + $options = array('all' => true); // git commit option to include all changes + } else { + $options = array(); // git commit options + foreach ($files as $file) { + if (!$git->git->add($file)) { // add specified files to the git repo stage + if (!$git->git->reset->hard()) { + json_return_and_die(array('message' => 'Error adding file to git stage: ' . $file . '. Error resetting git repo.', 'success' => false)); + } + json_return_and_die(array('message' => 'Error adding file to git stage: ' . $file, 'success' => false)); + } + } + } + if ($git->commit($commit_msg, $options)) { + json_return_and_die(array('message' => 'Wiki repo commit succeeded', 'success' => true)); + } else { + json_return_and_die(array('message' => 'Wiki repo commit failed', 'success' => false)); + } + } catch (\PHPGit\Exception\GitException $e) { + json_return_and_die(array('message' => 'GitRepo error thrown', 'success' => false)); + } +} -- cgit v1.2.3 From 75b169f391d7d6a5c140e74603e87897b39e8344 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sun, 29 May 2016 13:50:32 -0400 Subject: Fixed bug where page file was not loaded because of urlencoding/urldecoding --- include/wiki.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/wiki.php') diff --git a/include/wiki.php b/include/wiki.php index 915478da5..e07cda660 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -219,7 +219,7 @@ function wiki_get_page_content($arr) { if (!$w['path']) { return array('content' => null, 'message' => 'Error reading wiki', 'success' => false); } - $page_path = $w['path'].'/'.$page; + $page_path = $w['path'].'/'.escape_tags(urlencode($page)); if (is_readable($page_path) === true) { if(filesize($page_path) === 0) { $content = ''; -- cgit v1.2.3 From 00d32f6b947d10b836cf1a4d59dbff3413517fd5 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sun, 29 May 2016 20:39:19 -0400 Subject: Only show wiki delete control if channel owner --- include/wiki.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/wiki.php') diff --git a/include/wiki.php b/include/wiki.php index e07cda660..54644dd18 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -7,9 +7,9 @@ use \Zotlabs\Storage\GitRepo as GitRepo; define ( 'WIKI_ITEM_RESOURCE_TYPE', 'wiki' ); -function wiki_list($nick, $observer_hash) { +function wiki_list($channel, $observer_hash) { if (local_channel() || remote_channel()) { - $sql_extra = item_permissions_sql(get_channel_by_nick($nick)['channel_id'], $observer_hash); + $sql_extra = item_permissions_sql($channel['channel_id'], $observer_hash); } else { $sql_extra = " AND item_private = 0 "; } -- cgit v1.2.3 From 4b350b909025ba2102d5ad2c5ee32b3c4eecaa48 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sun, 29 May 2016 21:23:56 -0400 Subject: Fixed bug in access control. Hide new wiki/page buttons if not channel owner. --- include/wiki.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'include/wiki.php') diff --git a/include/wiki.php b/include/wiki.php index 54644dd18..70788eed2 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -8,11 +8,7 @@ use \Zotlabs\Storage\GitRepo as GitRepo; define ( 'WIKI_ITEM_RESOURCE_TYPE', 'wiki' ); function wiki_list($channel, $observer_hash) { - if (local_channel() || remote_channel()) { - $sql_extra = item_permissions_sql($channel['channel_id'], $observer_hash); - } else { - $sql_extra = " AND item_private = 0 "; - } + $sql_extra = item_permissions_sql($channel['channel_id'], $observer_hash); $wikis = q("SELECT * FROM item WHERE resource_type = '%s' AND mid = parent_mid AND item_deleted = 0 $sql_extra", dbesc(WIKI_ITEM_RESOURCE_TYPE) ); -- cgit v1.2.3 From a52cdcb2410fc67823a3dab62b413d70ec57cdec Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Mon, 30 May 2016 14:59:33 -0400 Subject: Replaced wiki item record object field with ActivityStreams information. Wiki git repo path is stored in iconfig instead. --- include/wiki.php | 89 +++++++++++++++++++++++++------------------------------- 1 file changed, 40 insertions(+), 49 deletions(-) (limited to 'include/wiki.php') diff --git a/include/wiki.php b/include/wiki.php index 70788eed2..6a94dc111 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -95,9 +95,17 @@ function wiki_create_wiki($channel, $observer_hash, $name, $acl) { $arr['item_private'] = intval($acl->is_private()); $arr['verb'] = ACTIVITY_CREATE; $arr['obj_type'] = ACTIVITY_OBJ_WIKI; - $arr['object'] = array('path' => $path); + $arr['object'] = json_encode(array( + 'type' => $arr['obj_type'], + 'title' => $arr['title'], + 'id' => $arr['resource_id'], + 'url' => $wiki_url + )); $arr['body'] = '[table][tr][td][h1]New Wiki[/h1][/td][/tr][tr][td][zrl=' . $wiki_url . ']' . $name . '[/zrl][/td][/tr][/table]'; - + // Save the path using iconfig. The file path should not be shared with other hubs + if (!set_iconfig($arr, 'wiki', 'path', $path, false)) { + return array('item' => null, 'success' => false); + } $post = item_store($arr); $item_id = $post['item_id']; @@ -110,26 +118,19 @@ function wiki_create_wiki($channel, $observer_hash, $name, $acl) { } function wiki_delete_wiki($resource_id) { - $item = q("SELECT id, object FROM item WHERE resource_type = '%s' AND resource_id = '%s' AND item_deleted = 0 limit 1", - dbesc(WIKI_ITEM_RESOURCE_TYPE), - dbesc($resource_id) - ); - if (!$item) { - return array('items' => null, 'success' => false); - } else { - $drop = drop_item($item[0]['id'],false,DROPITEM_NORMAL,true); - $object = json_decode($item[0]['object'], true); - if(!realpath(__DIR__ . '/../' . $object['path'])) { - return array('items' => null, 'success' => false); - } - // Path to wiki exists - $abs_path = realpath(__DIR__ . '/../' . $object['path']); - $pathdel = rrmdir($abs_path); - if($pathdel) { - info('Wiki deleted successfully'); - } - return array('item' => $item, 'success' => (($drop === 1 && $pathdel) ? true : false)); - } + + $w = wiki_get_wiki($resource_id); + $item = $w['wiki']; + if (!$item || !$w['path']) { + return array('item' => null, 'success' => false); + } else { + $drop = drop_item($item['id'], false, DROPITEM_NORMAL, true); + $pathdel = rrmdir($w['path']); + if ($pathdel) { + info('Wiki files deleted successfully'); + } + return array('item' => $item, 'success' => (($drop === 1 && $pathdel) ? true : false)); + } } function wiki_get_wiki($resource_id) { @@ -141,28 +142,28 @@ function wiki_get_wiki($resource_id) { return array('wiki' => null, 'path' => null); } else { $w = $item[0]; - $object = json_decode($w['object'], true); - if (!realpath(__DIR__ . '/../' . $object['path'])) { + //$object = json_decode($w['object'], true); + $path = get_iconfig($w, 'wiki', 'path'); + if (!realpath(__DIR__ . '/../' . $path)) { return array('wiki' => null, 'path' => null); } // Path to wiki exists - $abs_path = realpath(__DIR__ . '/../' . $object['path']); + $abs_path = realpath(__DIR__ . '/../' . $path); return array('wiki' => $w, 'path' => $abs_path); } } function wiki_exists_by_name($uid, $name) { - $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), + $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($uid) - ); - if (!$item) { - return array('id' => null, 'resource_id' => null); - } else { - return array('id' => $item[0]['id'], 'resource_id' => $item[0]['resource_id']); - } - + ); + if (!$item) { + return array('id' => null, 'resource_id' => null); + } else { + return array('id' => $item[0]['id'], 'resource_id' => $item[0]['resource_id']); + } } function wiki_get_permissions($resource_id, $owner_id, $observer_hash) { @@ -180,21 +181,11 @@ function wiki_get_permissions($resource_id, $owner_id, $observer_hash) { } function wiki_create_page($name, $resource_id) { - $item = q("SELECT id,title,object FROM item WHERE resource_type = '%s' AND resource_id = '%s' AND item_deleted = 0 limit 1", - dbesc(WIKI_ITEM_RESOURCE_TYPE), - dbesc($resource_id) - ); - if (!$item) { - return array('page' => null, 'message' => 'Wiki item not found.', 'success' => false); - } - $object = json_decode($item[0]['object'], true); - $wikiname = $item[0]['title']; - if (!realpath(__DIR__ . '/../' . $object['path'])) { - return array('page' => null, 'message' => 'Wiki directory does not exist.', 'success' => false); + $w = wiki_get_wiki($resource_id); + if (!$w['path']) { + return array('page' => null, 'message' => 'Wiki not found.', 'success' => false); } - // Path to wiki exists - $abs_path = realpath(__DIR__ . '/../' . $object['path']); - $page_path = $abs_path . '/' . $name; + $page_path = $w['path'] . '/' . $name; if (is_file($page_path)) { return array('page' => null, 'message' => 'Page already exists.', 'success' => false); } -- cgit v1.2.3 From 8d284bab474c7e669ae9a639bdb22f7b28b95cc3 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Mon, 30 May 2016 20:59:54 -0400 Subject: Created page history widget to dynamically fetch and display the git commit history for wiki pages. --- include/wiki.php | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'include/wiki.php') diff --git a/include/wiki.php b/include/wiki.php index 6a94dc111..14e8cc53a 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -95,12 +95,6 @@ function wiki_create_wiki($channel, $observer_hash, $name, $acl) { $arr['item_private'] = intval($acl->is_private()); $arr['verb'] = ACTIVITY_CREATE; $arr['obj_type'] = ACTIVITY_OBJ_WIKI; - $arr['object'] = json_encode(array( - 'type' => $arr['obj_type'], - 'title' => $arr['title'], - 'id' => $arr['resource_id'], - 'url' => $wiki_url - )); $arr['body'] = '[table][tr][td][h1]New Wiki[/h1][/td][/tr][tr][td][zrl=' . $wiki_url . ']' . $name . '[/zrl][/td][/tr][/table]'; // Save the path using iconfig. The file path should not be shared with other hubs if (!set_iconfig($arr, 'wiki', 'path', $path, false)) { @@ -221,6 +215,30 @@ function wiki_get_page_content($arr) { } } +function wiki_page_history($arr) { + $pagename = ((array_key_exists('page',$arr)) ? $arr['page'] : ''); + $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; + if (!is_readable($page_path) === true) { + return array('history' => null, 'message' => 'Cannot read wiki page: ' . $page_path, 'success' => false); + } + $reponame = ((array_key_exists('title', $w['wiki'])) ? $w['wiki']['title'] : 'repo'); + if($reponame === '') { + $reponame = 'repo'; + } + $git = new GitRepo('sys', null, false, $w['wiki']['title'], $w['path']); + try { + $gitlog = $git->git->log('', $page_path , array('limit' => 50)); + logger('gitlog: ' . json_encode($gitlog)); + return array('history' => $gitlog, 'message' => '', 'success' => true); + } catch (\PHPGit\Exception\GitException $e) { + return array('history' => null, 'message' => 'GitRepo error thrown', 'success' => false); + } +} function wiki_save_page($arr) { $pagename = ((array_key_exists('name',$arr)) ? $arr['name'] : ''); -- cgit v1.2.3 From b70c6809648bb3c78e5e26f9293727b3a7aa4025 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Thu, 2 Jun 2016 22:27:26 -0400 Subject: Major corrections to access control and page construction. --- include/wiki.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'include/wiki.php') diff --git a/include/wiki.php b/include/wiki.php index 14e8cc53a..84e7d8dfa 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -9,8 +9,9 @@ define ( 'WIKI_ITEM_RESOURCE_TYPE', 'wiki' ); function wiki_list($channel, $observer_hash) { $sql_extra = item_permissions_sql($channel['channel_id'], $observer_hash); - $wikis = q("SELECT * FROM item WHERE resource_type = '%s' AND mid = parent_mid AND item_deleted = 0 $sql_extra", - dbesc(WIKI_ITEM_RESOURCE_TYPE) + $wikis = q("SELECT * FROM item WHERE resource_type = '%s' AND mid = parent_mid AND uid = %d AND item_deleted = 0 $sql_extra", + dbesc(WIKI_ITEM_RESOURCE_TYPE), + intval($channel['channel_id']) ); // TODO: query db for wikis the observer can access. Return with two lists, for read and write access return array('wikis' => $wikis); @@ -195,8 +196,8 @@ function wiki_create_page($name, $resource_id) { 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 - $wiki_resource_id = ((array_key_exists('wiki_resource_id',$arr)) ? $arr['wiki_resource_id'] : ''); - $w = wiki_get_wiki($wiki_resource_id); + $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); } @@ -230,7 +231,7 @@ function wiki_page_history($arr) { if($reponame === '') { $reponame = 'repo'; } - $git = new GitRepo('sys', null, false, $w['wiki']['title'], $w['path']); + $git = new GitRepo('', null, false, $w['wiki']['title'], $w['path']); try { $gitlog = $git->git->log('', $page_path , array('limit' => 50)); logger('gitlog: ' . json_encode($gitlog)); @@ -272,7 +273,7 @@ function wiki_git_commit($arr) { if($reponame === '') { $reponame = 'repo'; } - $git = new GitRepo('sys', null, false, $w['wiki']['title'], $w['path']); + $git = new GitRepo($observer['xchan_addr'], null, false, $w['wiki']['title'], $w['path']); try { $git->setIdentity($observer['xchan_name'], $observer['xchan_addr']); if ($files === null) { -- cgit v1.2.3 From b5d8443f59d96cece2357b6a791fe8ffe854dd95 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 4 Jun 2016 06:26:41 -0400 Subject: Created three distinct names for wiki and page that are suitable for URL, HTML, and raw display. Implemented in new wiki POST activity only so far. --- include/wiki.php | 56 ++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 14 deletions(-) (limited to 'include/wiki.php') diff --git a/include/wiki.php b/include/wiki.php index 84e7d8dfa..822cb1b88 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -33,11 +33,11 @@ function wiki_page_list($resource_id) { return array('pages' => $pages); } -function wiki_init_wiki($channel, $name) { +function wiki_init_wiki($channel, $wiki) { // Store the path as a relative path, but pass absolute path to mkdir - $path = 'store/[data]/git/'.$channel['channel_address'].'/wiki/'.$name; + $path = 'store/[data]/git/'.$channel['channel_address'].'/wiki/'.$wiki['urlName']; if (!os_mkdir(__DIR__ . '/../' . $path, 0770, true)) { - logger('Error creating wiki path: ' . $name); + logger('Error creating wiki path: ' . $path); return null; } // Create GitRepo object @@ -50,8 +50,8 @@ function wiki_init_wiki($channel, $name) { return array('path' => $path); } -function wiki_create_wiki($channel, $observer_hash, $name, $acl) { - $wikiinit = wiki_init_wiki($channel, $name); +function wiki_create_wiki($channel, $observer_hash, $wiki, $acl) { + $wikiinit = wiki_init_wiki($channel, $wiki); if (!$wikiinit['path']) { notice('Error creating wiki'); return array('item' => null, 'success' => false); @@ -73,7 +73,7 @@ function wiki_create_wiki($channel, $observer_hash, $name, $acl) { $mid = item_message_id(); $arr = array(); // Initialize the array of parameters for the post $item_hidden = 0; // TODO: Allow form creator to send post to ACL about new game automatically - $wiki_url = z_root() . '/wiki/' . $channel['channel_address'] . '/' . $name; + $wiki_url = z_root() . '/wiki/' . $channel['channel_address'] . '/' . $wiki['urlName']; $arr['aid'] = $channel['channel_account_id']; $arr['uid'] = $channel['channel_id']; $arr['mid'] = $mid; @@ -85,7 +85,7 @@ function wiki_create_wiki($channel, $observer_hash, $name, $acl) { $arr['author_xchan'] = $observer_hash; $arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . $arr['mid']; $arr['llink'] = $arr['plink']; - $arr['title'] = $name; // name of new wiki; + $arr['title'] = $wiki['htmlName']; // name of new wiki; $arr['allow_cid'] = $ac['allow_cid']; $arr['allow_gid'] = $ac['allow_gid']; $arr['deny_cid'] = $ac['deny_cid']; @@ -96,11 +96,21 @@ function wiki_create_wiki($channel, $observer_hash, $name, $acl) { $arr['item_private'] = intval($acl->is_private()); $arr['verb'] = ACTIVITY_CREATE; $arr['obj_type'] = ACTIVITY_OBJ_WIKI; - $arr['body'] = '[table][tr][td][h1]New Wiki[/h1][/td][/tr][tr][td][zrl=' . $wiki_url . ']' . $name . '[/zrl][/td][/tr][/table]'; + $arr['body'] = '[table][tr][td][h1]New Wiki[/h1][/td][/tr][tr][td][zrl=' . $wiki_url . ']' . $wiki['htmlName'] . '[/zrl][/td][/tr][/table]'; // Save the path using iconfig. The file path should not be shared with other hubs if (!set_iconfig($arr, 'wiki', 'path', $path, false)) { return array('item' => null, 'success' => false); } + // Save the wiki name information using iconfig. This is shareable. + if (!set_iconfig($arr, 'wiki', 'rawName', $wiki['rawName'], true)) { + return array('item' => null, 'success' => false); + } + if (!set_iconfig($arr, 'wiki', 'htmlName', $wiki['htmlName'], true)) { + return array('item' => null, 'success' => false); + } + if (!set_iconfig($arr, 'wiki', 'urlName', $wiki['urlName'], true)) { + return array('item' => null, 'success' => false); + } $post = item_store($arr); $item_id = $post['item_id']; @@ -136,15 +146,23 @@ function wiki_get_wiki($resource_id) { if (!$item) { return array('wiki' => null, 'path' => null); } else { - $w = $item[0]; - //$object = json_decode($w['object'], true); + $w = $item[0]; // wiki item table record + // Get wiki metadata + $rawName = get_iconfig($w, 'wiki', 'rawName'); + $htmlName = get_iconfig($w, 'wiki', 'htmlName'); + $urlName = get_iconfig($w, 'wiki', 'urlName'); $path = get_iconfig($w, 'wiki', 'path'); if (!realpath(__DIR__ . '/../' . $path)) { return array('wiki' => null, 'path' => null); } // Path to wiki exists $abs_path = realpath(__DIR__ . '/../' . $path); - return array('wiki' => $w, 'path' => $abs_path); + return array( 'wiki' => $w, + 'path' => $abs_path, + 'rawName' => $rawName, + 'htmlName' => $htmlName, + 'urlName' => $urlName + ); } } @@ -180,15 +198,16 @@ function wiki_create_page($name, $resource_id) { if (!$w['path']) { return array('page' => null, 'message' => 'Wiki not found.', 'success' => false); } - $page_path = $w['path'] . '/' . $name; + $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']; if (is_file($page_path)) { return array('page' => null, 'message' => 'Page already exists.', 'success' => false); } - // Create file called $name in the path + // Create the page file in the wiki repo if(!touch($page_path)) { return array('page' => null, 'message' => 'Page file cannot be created.', 'success' => false); } else { - return array('wiki' => $wikiname, 'message' => '', 'success' => true); + return array('page' => $page, 'message' => '', 'success' => true); } } @@ -298,3 +317,12 @@ function wiki_git_commit($arr) { json_return_and_die(array('message' => 'GitRepo error thrown', 'success' => false)); } } + +function wiki_generate_page_filename($name) { + $file = urlencode(escape_tags($name)); + if( $file === '') { + return null; + } else { + return $file . '.md'; + } +} \ No newline at end of file -- cgit v1.2.3 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. --- include/wiki.php | 50 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 20 deletions(-) (limited to 'include/wiki.php') 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'; } -- cgit v1.2.3 From 4bc4fd5b7ebd7c5f25cfc9acfbda5b14a38dedb8 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 4 Jun 2016 18:00:32 -0400 Subject: Page deletion implemented. Hide the delete button and disallow for Home page. --- include/wiki.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'include/wiki.php') diff --git a/include/wiki.php b/include/wiki.php index ccf47ef9a..1f90fae1e 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -289,6 +289,24 @@ function wiki_save_page($arr) { } } +function wiki_delete_page($arr) { + $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('message' => 'Error reading wiki', 'success' => false); + } + $page_path = $w['path'].'/'.$pageUrlName.'.md'; + if (is_writable($page_path) === true) { + if(!unlink($page_path)) { + return array('message' => 'Error deleting page file', 'success' => false); + } + return array('message' => '', 'success' => true); + } else { + return array('message' => 'Page file not writable', 'success' => false); + } +} + function wiki_git_commit($arr) { $files = ((array_key_exists('files', $arr)) ? $arr['files'] : null); $commit_msg = ((array_key_exists('commit_msg', $arr)) ? $arr['commit_msg'] : 'Repo updated'); -- cgit v1.2.3 From 0a3fbdd128dd3b80868c93cb93901b501edf576c Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sun, 5 Jun 2016 16:32:03 -0400 Subject: Basic page reversion implemented. The revert button on the history view replaces the editor text but does not save the page. --- include/wiki.php | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) (limited to 'include/wiki.php') diff --git a/include/wiki.php b/include/wiki.php index 1f90fae1e..cc948dee2 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -263,7 +263,6 @@ function wiki_page_history($arr) { $git = new GitRepo('', null, false, $w['wiki']['title'], $w['path']); try { $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) { return array('history' => null, 'message' => 'GitRepo error thrown', 'success' => false); @@ -307,6 +306,44 @@ function wiki_delete_page($arr) { } } +function wiki_revert_page($arr) { + $pageUrlName = ((array_key_exists('pageUrlName',$arr)) ? $arr['pageUrlName'] : ''); + $resource_id = ((array_key_exists('resource_id',$arr)) ? $arr['resource_id'] : ''); + $commitHash = ((array_key_exists('commitHash',$arr)) ? $arr['commitHash'] : null); + if (! $commitHash) { + return array('content' => $content, 'message' => 'No commit has provided', 'success' => false); + } + $w = wiki_get_wiki($resource_id); + if (!$w['path']) { + return array('content' => $content, 'message' => 'Error reading wiki', 'success' => false); + } + $page_path = $w['path'].'/'.$pageUrlName.'.md'; + if (is_writable($page_path) === true) { + + $reponame = ((array_key_exists('title', $w['wiki'])) ? urlencode($w['wiki']['title']) : 'repo'); + if($reponame === '') { + $reponame = 'repo'; + } + $git = new GitRepo($observer['xchan_addr'], null, false, $w['wiki']['title'], $w['path']); + $content = null; + try { + $git->setIdentity($observer['xchan_name'], $observer['xchan_addr']); + foreach ($git->git->tree($commitHash) as $object) { + logger('tree object: ' . json_encode($object)); + if ($object['type'] == 'blob' && $object['file'] === $pageUrlName.'.md' ) { + $content = $git->git->cat->blob($object['hash']); + logger('content: ' . json_encode($content)); + } + } + } catch (\PHPGit\Exception\GitException $e) { + json_return_and_die(array('content' => $content, 'message' => 'GitRepo error thrown', 'success' => false)); + } + return array('content' => $content, 'message' => '', 'success' => true); + } else { + return array('content' => $content, 'message' => 'Page file not writable', 'success' => false); + } +} + function wiki_git_commit($arr) { $files = ((array_key_exists('files', $arr)) ? $arr['files'] : null); $commit_msg = ((array_key_exists('commit_msg', $arr)) ? $arr['commit_msg'] : 'Repo updated'); -- cgit v1.2.3 From 4528becf4ccbeea3d63f729ed643b5fc7d67f1bb Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sun, 5 Jun 2016 20:52:40 -0400 Subject: Remove debugging logger statements --- include/wiki.php | 3 --- 1 file changed, 3 deletions(-) (limited to 'include/wiki.php') diff --git a/include/wiki.php b/include/wiki.php index cc948dee2..23a22007f 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -230,7 +230,6 @@ function wiki_get_page_content($arr) { return array('content' => null, 'message' => 'Error reading wiki', 'success' => false); } $page_path = $w['path'].'/'.$pageUrlName.'.md'; - logger('$page_path: ' . $page_path); if (is_readable($page_path) === true) { if(filesize($page_path) === 0) { $content = ''; @@ -329,10 +328,8 @@ function wiki_revert_page($arr) { try { $git->setIdentity($observer['xchan_name'], $observer['xchan_addr']); foreach ($git->git->tree($commitHash) as $object) { - logger('tree object: ' . json_encode($object)); if ($object['type'] == 'blob' && $object['file'] === $pageUrlName.'.md' ) { $content = $git->git->cat->blob($object['hash']); - logger('content: ' . json_encode($content)); } } } catch (\PHPGit\Exception\GitException $e) { -- cgit v1.2.3 From 9410b63bbc819955964706c876bc2f7ecea10adf Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Wed, 8 Jun 2016 06:26:27 -0400 Subject: Revised permissions checks across API and enabled collaborative editing using the write_pages per-channel permission. --- include/wiki.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'include/wiki.php') diff --git a/include/wiki.php b/include/wiki.php index 23a22007f..f0785d549 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -196,10 +196,19 @@ function wiki_get_permissions($resource_id, $owner_id, $observer_hash) { dbesc(WIKI_ITEM_RESOURCE_TYPE), dbesc($resource_id) ); - if(!$r) { + + if (!$r) { return array('read' => false, 'write' => false, 'success' => true); } else { - return array('read' => true, 'write' => false, 'success' => true); + $perms = get_all_perms($owner_id, $observer_hash); + // TODO: Create a new permission setting for wiki analogous to webpages. Until + // then, use webpage permissions + if (!$perms['write_pages']) { + $write = false; + } else { + $write = true; + } + return array('read' => true, 'write' => $write, 'success' => true); } } -- cgit v1.2.3