1<?php
2/**
3 * @package tikiwiki
4 */
5// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
6//
7// All Rights Reserved. See copyright.txt for details and a complete list of authors.
8// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
9// $Id$
10
11$auto_query_args = ['page_ref_id', 'offset', 'find_objects'];
12require_once('tiki-setup.php');
13
14$structlib = TikiLib::lib('struct');
15$access->check_feature(['feature_wiki','feature_wiki_structure']);
16if (! isset($_REQUEST["page_ref_id"])) {
17	$smarty->assign('msg', tra("No structure indicated"));
18	$smarty->display("error.tpl");
19	die;
20}
21
22$page_info = $structlib->s_get_page_info($_REQUEST["page_ref_id"]);
23
24$access->check_permission('tiki_p_view', tra('View this wiki page'), 'wiki page', $page_info['pageName']);
25
26if (isset($_REQUEST['move_to'])) {
27	check_ticket('edit-structure');
28	$structlib->move_to_structure($_REQUEST['page_ref_id'], $_REQUEST['structure_id'], $_REQUEST['begin']);
29}
30
31$structure_info = $structlib->s_get_structure_info($_REQUEST["page_ref_id"]);
32
33$smarty->assign('page_ref_id', $_REQUEST["page_ref_id"]);
34$smarty->assign('structure_id', $structure_info["page_ref_id"]);
35$smarty->assign('structure_name', $structure_info["pageName"]);
36
37$perms = Perms::get((['type' => 'wiki page', 'object' => $structure_info["pageName"]]));
38$tikilib->get_perm_object($structure_info["pageName"], 'wiki page', $page_info);	// global perms still needed for logic in categorize.tpl
39
40if (! $perms->view) {
41	$smarty->assign('errortype', 401);
42	$smarty->assign('msg', tra('You do not have permission to view this page.'));
43	$smarty->display("error.tpl");
44	die;
45}
46
47if ($perms->edit_structures) {
48	if ($prefs['lock_wiki_structures'] === 'y') {
49		$lockedby = TikiLib::lib('attribute')->get_attribute('wiki structure', $structure_info['pageName'], 'tiki.object.lock');
50		if ($lockedby && $lockedby === $user && $perms->lock_structures || ! $lockedby || $perms->admin_structures) {
51			$editable = 'y';
52		} else {
53			$editable = 'n';
54		}
55	} else {
56		$editable = 'y';
57	}
58} else {
59	$editable = 'n';
60}
61$smarty->assign('editable', $editable);
62
63
64$alert_categorized = [];
65$alert_in_st = [];
66$alert_to_remove_cats = [];
67$alert_to_remove_extra_cats = [];
68
69// start security hardened section
70if ($editable === 'y') {
71	$smarty->assign('remove', 'n');
72
73	if (isset($_REQUEST["remove"])) {
74		check_ticket('edit-structure');
75		$smarty->assign('remove', 'y');
76		$remove_info = $structlib->s_get_page_info($_REQUEST["remove"]);
77		  $structs = $structlib->get_page_structures($remove_info['pageName'], $structure);
78		//If page is member of more than one structure, do not give option to remove page
79		$single_struct = (count($structs) == 1);
80		if ($single_struct && $perms->remove) {
81			$smarty->assign('page_removable', 'y');
82		} else {
83			$smarty->assign('page_removable', 'n');
84		}
85		$smarty->assign('removepage', $_REQUEST["remove"]);
86		$smarty->assign('removePageName', $remove_info["pageName"]);
87	}
88
89	if (isset($_REQUEST["rremove"])) {
90		$access->check_authenticity();
91		$structlib->s_remove_page($_REQUEST["rremove"], false, empty($_REQUEST['page']) ? '' : $_REQUEST['page']);
92		$_REQUEST["page_ref_id"] = $page_info["parent_id"];
93	}
94	# TODO : Case where the index page of the structure is removed seems to be unexpected, leaving a corrupted structure
95	if (isset($_REQUEST["sremove"])) {
96		$access->check_authenticity();
97		$page = $page_info["pageName"];
98		$delete = $tikilib->user_has_perm_on_object($user, $page_info['pageName'], 'wiki page', 'tiki_p_remove');
99		$structlib->s_remove_page($_REQUEST["sremove"], $delete, empty($_REQUEST['page']) ? '' : $_REQUEST['page']);
100		$_REQUEST["page_ref_id"] = $page_info["parent_id"];
101	}
102
103	if ($prefs['feature_user_watches'] == 'y' && $tiki_p_watch_structure == 'y' && $user && ! empty($_REQUEST['watch_object']) && ! empty($_REQUEST['watch_action'])) {
104		check_ticket('edit-structure');
105		if ($_REQUEST['watch_action'] == 'add' && ! empty($_REQUEST['page'])) {
106			$tikilib->add_user_watch($user, 'structure_changed', $_REQUEST['watch_object'], 'structure', $page, "tiki-index.php?page_ref_id=" . $_REQUEST['watch_object']);
107		} elseif ($_REQUEST['watch_action'] == 'remove') {
108			$tikilib->remove_user_watch($user, 'structure_changed', $_REQUEST['watch_object'], 'structure');
109		}
110	}
111
112	if (! isset($structure_info) or ! isset($page_info)) {
113		$smarty->assign('msg', tra("Invalid structure_id or page_ref_id"));
114
115		$smarty->display("error.tpl");
116		die;
117	}
118
119	$smarty->assign('alert_exists', 'n');
120	if (isset($_REQUEST["create"])) {
121		check_ticket('edit-structure');
122		if (isset($_REQUEST["pageAlias"])) {
123			$structlib->set_page_alias($_REQUEST["page_ref_id"], $_REQUEST["pageAlias"]);
124		}
125
126		$after = null;
127		if (isset($_REQUEST['after_ref_id'])) {
128			$after = $_REQUEST['after_ref_id'];
129		}
130		if (! (empty($_REQUEST['name']))) {
131			if ($tikilib->page_exists($_REQUEST["name"])) {
132				$smarty->assign('alert_exists', 'y');
133			}
134			$structlib->s_create_page($_REQUEST['page_ref_id'], $after, $_REQUEST['name'], '', $structure_info['page_ref_id']);
135			$userlib->copy_object_permissions($page_info["pageName"], $_REQUEST["name"], 'wiki page');
136		} elseif (! empty($_REQUEST['name2'])) {
137			foreach ($_REQUEST['name2'] as $name) {
138				$new_page_ref_id = $structlib->s_create_page($_REQUEST['page_ref_id'], $after, $name, '', $structure_info['page_ref_id']);
139				$after = $new_page_ref_id;
140			}
141		}
142
143		if ($prefs['feature_wiki_categorize_structure'] == 'y') {
144			$categlib = TikiLib::lib('categ');
145			$pages_added = [];
146			if (! (empty($_REQUEST['name']))) {
147				$pages_added[] = $_REQUEST['name'];
148			} elseif (! empty($_REQUEST['name2'])) {
149				foreach ($_REQUEST['name2'] as $name) {
150					$pages_added[] = $name;
151				}
152			}
153			$cat_type = 'wiki page';
154			foreach ($pages_added as $name) {
155				$structlib->categorizeNewStructurePage($name, $structure_info);
156			}
157		}
158	}
159
160	if (isset($_REQUEST["move_node"])) {
161		if ($_REQUEST["move_node"] == '1') {
162			$structlib->promote_node($_REQUEST["page_ref_id"]);
163		} elseif ($_REQUEST["move_node"] == '2') {
164			$structlib->move_before_previous_node($_REQUEST["page_ref_id"]);
165		} elseif ($_REQUEST["move_node"] == '3') {
166			$structlib->move_after_next_node($_REQUEST["page_ref_id"]);
167		} elseif ($_REQUEST["move_node"] == '4') {
168			$structlib->demote_node($_REQUEST["page_ref_id"]);
169		}
170	}
171	if (isset($_REQUEST["find_objects"])) {
172		$find_objects = $_REQUEST["find_objects"];
173	} else {
174		$find_objects = '';
175	}
176	$smarty->assign('find_objects', $find_objects);
177
178	$filter = [];
179	if (! empty($_REQUEST['categId'])) {
180		$filter['categId'] = $_REQUEST['categId'];
181		$smarty->assign('find_categId', $_REQUEST['categId']);
182	} else {
183		$smarty->assign('find_categId', '');
184	}
185
186	if (! isset($_REQUEST["offset"])) {
187		$offset = 0;
188	} else {
189		$offset = $_REQUEST["offset"];
190	}
191	$smarty->assign_by_ref('offset', $offset);
192
193	// Get all wiki pages for the dropdown menu
194	$listpages = $tikilib->list_pages(
195		$offset, $prefs['maxRecords'], 'pageName_asc', $find_objects, '', false, true,
196		false, false, $filter
197	);
198	$smarty->assign_by_ref('listpages', $listpages);
199
200} // end of security hardening
201
202$page_info = $structlib->s_get_page_info($_REQUEST["page_ref_id"]);
203$smarty->assign('pageName', $page_info["pageName"]);
204$smarty->assign('pageAlias', $page_info["page_alias"]);
205$smarty->assign('topPageAlias', $structure_info["page_alias"]);
206
207$subpages = $structlib->s_get_pages($_REQUEST["page_ref_id"]);
208$max = count($subpages);
209$smarty->assign_by_ref('subpages', $subpages);
210if ($max != 0) {
211	$last_child = $subpages[$max - 1];
212	$smarty->assign('insert_after', $last_child["page_ref_id"]);
213}
214
215$structures = $structlib->list_structures(0, -1, 'pageName_asc');
216$structures_filtered = array_filter($structures['data'], function ($struct) {
217	return $struct['editable'] === 'y';
218});
219$smarty->assign_by_ref('structures', $structures_filtered);
220
221$subtree = $structlib->get_subtree($structure_info["page_ref_id"]);
222foreach ($subtree as $i => $s) { // dammed recursivite - acn not do a left join
223	if ($tikilib->user_watches($user, 'structure_changed', $s['page_ref_id'], 'structure')) {
224		$subtree[$i]['event'] = true;
225	}
226}
227$smarty->assign('subtree', $subtree);
228
229if ($tikilib->user_watches($user, 'structure_changed', $structure_info['page_ref_id'], 'structure')) {
230	$page_info['watching'] = true;
231}
232$smarty->assign('page_info', $page_info);
233
234
235// Re-categorize
236if ($editable === 'y') {
237	$all_editable = 'y';
238	foreach ($subtree as $k => $st) {
239		if ($st['editable'] != 'y' && $k > 0) {
240			$all_editable = 'n';
241			 break;
242		}
243	}
244} else {
245	$all_editable = 'n';
246}
247$smarty->assign('all_editable', $all_editable);
248
249if (isset($_REQUEST["recategorize"]) && $prefs['feature_wiki_categorize_structure'] == 'y' && $all_editable == 'y') {
250	$cat_name = $structure_info["pageName"];
251	$cat_objid = $cat_name;
252	$cat_href = "tiki-index.php?page=" . urlencode($cat_name);
253	 $cat_desc = '';
254	 $cat_type = 'wiki page';
255	include_once("categorize.php");
256	$categories = []; // needed to prevent double entering (the first time when page is being categorized in categorize.php)
257	//include_once("categorize_list.php"); // needs to be up here to avoid picking up selection of cats from other existing sub-pages
258	//get array of pages in structure
259	$othobjid = $structlib->s_get_structure_pages($structure_info["page_ref_id"]);
260	foreach ($othobjid as $othobjs) {
261		if ($othobjs["parent_id"] > 0) {
262			// check for page being in other structure.
263			$strucs = $structlib->get_page_structures($othobjs["pageName"]);
264			if (count($strucs) > 1) {
265				$alert_in_st[] = $othobjs["pageName"];
266			}
267			$cat_objid = $othobjs["pageName"];
268			$cat_name = $cat_objid;
269			$cat_href = "tiki-index.php?page=" . urlencode($cat_objid);
270
271			$catObjectId = $categlib->is_categorized($cat_type, $cat_objid);
272			if (! $catObjectId) {
273				// page that is added is not categorized -> categorize it if necessary
274				if (isset($_REQUEST["cat_categorize"]) && $_REQUEST["cat_categorize"] == 'on' && isset($_REQUEST["cat_categories"])) {
275					$catObjectId = $categlib->add_categorized_object($cat_type, $cat_objid, $cat_desc, $cat_name, $cat_href);
276					foreach ($_REQUEST["cat_categories"] as $cat_acat) {
277						$categlib->categorize($catObjectId, $cat_acat);
278					}
279				}
280			} else {
281				// page that is added is categorized
282				if (! isset($_REQUEST["cat_categories"]) || ! isset($_REQUEST["cat_categorize"]) || isset($_REQUEST["cat_categorize"]) && $_REQUEST["cat_categorize"] != 'on') {
283					if ($_REQUEST["cat_override"] == "on") {
284						$categlib->uncategorize_object($cat_type, $cat_objid);
285					} else {
286						$alert_to_remove_cats[] = $cat_name;
287					}
288				} else {
289					if ($_REQUEST["cat_override"] == "on") {
290						$categlib->uncategorize_object($cat_type, $cat_objid);
291						foreach ($_REQUEST["cat_categories"] as $cat_acat) {
292							$catObjectId = $categlib->is_categorized($cat_type, $cat_objid);
293							if (! $catObjectId) {
294								// The object is not categorized
295								$catObjectId = $categlib->add_categorized_object($cat_type, $cat_objid, $cat_desc, $cat_name, $cat_href);
296							}
297							$categlib->categorize($catObjectId, $cat_acat);
298						}
299					} else {
300						$cats = $categlib->get_object_categories($cat_type, $cat_objid);
301						$numberofcats = count($cats);
302						foreach ($_REQUEST["cat_categories"] as $cat_acat) {
303							if (! in_array($cat_acat, $cats, true)) {
304								$categlib->categorize($catObjectId, $cat_acat);
305								$numberofcats += 1;
306							}
307						}
308						if ($numberofcats > count($_REQUEST["cat_categories"])) {
309							$alert_to_remove_extra_cats[] = $cat_name;
310						}
311					}
312				}
313			}
314		}
315	}
316}
317$smarty->assign('alert_in_st', $alert_in_st);
318$smarty->assign('alert_categorized', $alert_categorized);
319$smarty->assign('alert_to_remove_cats', $alert_to_remove_cats);
320$smarty->assign('alert_to_remove_extra_cats', $alert_to_remove_extra_cats);
321
322if ($prefs['feature_wiki_categorize_structure'] == 'y' && $all_editable == 'y') {
323	$cat_name = $structure_info["pageName"];
324	$cat_objid = $cat_name;
325	$cat_href = "tiki-index.php?page=" . urlencode($cat_name);
326	 $cat_desc = '';
327	 $cat_type = 'wiki page';
328	include_once("categorize_list.php");
329} elseif ($prefs['feature_categories'] == 'y') {
330	$categlib = TikiLib::lib('categ');
331	$categories = $categlib->getCategories();
332	$smarty->assign_by_ref('categories', $categories);
333}
334
335ask_ticket('edit-structure');
336
337include_once('tiki-section_options.php');
338
339if ($prefs['feature_jquery_ui'] === 'y') {
340	$headerlib->add_jsfile('lib/structures/tiki-edit_structure.js');
341	$headerlib->add_jsfile('vendor_bundled/vendor/jquery-plugins/nestedsortable/jquery.ui.nestedSortable.js');
342	$structlib = TikiLib::lib('struct');
343
344	$structure_id = $structure_info['structure_id'];
345	if (! $structure_id) {
346		$structure_id = $structure_info['page_ref_id'];
347	}
348	$smarty->assign('nodelist', $structlib->get_toc($structure_id, 'asc', false, false, '', 'admin', $page_info['page_ref_id'], 0, 0, 'struct', ''));
349				// $page_ref_id,$order='asc',$showdesc=false,$numbering=true,$numberPrefix='',$type='plain',$page='',$maxdepth=0,$mindepth=0, $structurePageName=''
350	$smarty->assign('structure_id', $structure_id);
351}
352// disallow robots to index page:
353$smarty->assign('metatag_robots', 'NOINDEX, NOFOLLOW');
354
355// Display the template
356$smarty->assign('mid', 'tiki-edit_structure.tpl');
357$smarty->display("tiki.tpl");
358