aboutsummaryrefslogtreecommitdiff
path: root/engine/lib/pagehandler.php
blob: 0d5e5f89bb90cd83d54703fd5fba801cae15d2e9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
<?php
/**
 * Elgg page handler functions
 *
 * @package Elgg.Core
 * @subpackage Routing
 */

/**
 * Turns the current page over to the page handler, allowing registered handlers to take over.
 *
 * If a page handler returns FALSE, the request is handed over to the default_page_handler.
 *
 * @param string $handler The name of the handler type (eg 'blog')
 * @param array  $page    The parameters to the page, as an array (exploded by '/' slashes)
 *
 * @return true|false Depending on whether a registered page handler was found
 * @access private
 */
function page_handler($handler, $page) {
	global $CONFIG;

	elgg_set_context($handler);

	$page = explode('/', $page);
	// remove empty array element when page url ends in a / (see #1480)
	if ($page[count($page) - 1] === '') {
		array_pop($page);
	}

	// return false to stop processing the request (because you handled it)
	// return a new $params array if you want to route the request differently
	$params = array(
		'handler' => $handler,
		'segments' => $page,
	);
	$params = elgg_trigger_plugin_hook('route', $handler, NULL, $params);
	if ($params === false) {
		return true;
	}

	$handler = $params['handler'];
	$page = $params['segments'];

	if (!isset($CONFIG->pagehandler) || empty($handler)) {
		$result = false;
	} else if (isset($CONFIG->pagehandler[$handler]) && is_callable($CONFIG->pagehandler[$handler])) {
		$function = $CONFIG->pagehandler[$handler];
		$result = call_user_func($function, $page, $handler);
		if ($result !== false) {
			$result = true;
		}
	} else {
		$result = false;
	}

	if (!$result) {
		$result = default_page_handler($page, $handler);
	}
	if ($result !== false) {
		$result = true;
	}

	return $result;
}

/**
 * Registers a page handler for a particular identifier
 *
 * For example, you can register a function called 'blog_page_handler' for handler type 'blog'
 * For all URLs  http://yoururl/blog/*, the blog_page_handler() function will be called.
 * The part of the URL marked with * above will be exploded on '/' characters and passed as an
 * array to that function.
 * For example, the URL http://yoururl/blog/username/friends/ would result in the call:
 * blog_page_handler(array('username','friends'), blog);
 *
 * Page handler functions should return true or the default page handler will be called.
 *
 * A request to register a page handler with the same identifier as previously registered
 * handler will replace the previous one.
 *
 * The context is set to the page handler identifier before the registered
 * page handler function is called. For the above example, the context is set to 'blog'.
 *
 * @param string $handler  The page type to handle
 * @param string $function Your function name
 *
 * @return true|false Depending on success
 */
function elgg_register_page_handler($handler, $function) {
	global $CONFIG;
	if (!isset($CONFIG->pagehandler)) {
		$CONFIG->pagehandler = array();
	}
	if (is_callable($function)) {
		$CONFIG->pagehandler[$handler] = $function;
		return true;
	}

	return false;
}

/**
 * Unregister a page handler for an identifier
 *
 * Note: to replace a page handler, call elgg_register_page_handler()
 *
 * @param string $handler The page type identifier
 *
 * @since 1.7.2
 * @return void
 */
function elgg_unregister_page_handler($handler) {
	global $CONFIG;

	if (!isset($CONFIG->pagehandler)) {
		return;
	}

	unset($CONFIG->pagehandler[$handler]);
}

/**
 * A default page handler
 * Tries to locate a suitable file to include. Only works for core pages, not plugins.
 *
 * @param array  $page    The page URL elements
 * @param string $handler The base handler
 *
 * @return true|false Depending on success
 * @access private
 */
function default_page_handler($page, $handler) {
	global $CONFIG;

	$page = implode('/', $page);

	// protect against including arbitary files
	$page = str_replace("..", "", $page);

	$callpath = $CONFIG->path . $handler . "/" . $page;
	if (is_dir($callpath)) {
		$callpath = sanitise_filepath($callpath);
		$callpath .= "index.php";
		if (file_exists($callpath)) {
			if (include($callpath)) {
				return TRUE;
			}
		}
	} else if (file_exists($callpath)) {
		include($callpath);
		return TRUE;
	}

	return FALSE;
}