715e9e77a4c57e7455f38df7447f8a354d541449
[project/panels.git] / panels_page / panels_page.read.inc
1 <?php
2 // $Id$
3
4 /**
5 * @file panels_page.write.inc
6 *
7 * Functions responsible for writing panels_page data to the database.
8 */
9
10 /**
11 * Fetch all panel pages in the system.
12 *
13 * For the moment, this function does not cache. It may be integrated into the
14 * panels_page_loaded_cache() caching mechanism at some point, but its utility
15 * in D6 is significantly lessened vs. D5, so there is much less need to do so.
16 */
17 function panels_page_load_all($names = array(), $page_size = 0) {
18 $pages = $dids = array();
19 $query = "SELECT * FROM {panels_page}";
20
21 if (!empty($names)) {
22 $query .= " WHERE name IN (" . implode(', ', array_fill(0, count($names), "'%s'")) . ")";
23 }
24
25 if ($page_size) {
26 $result = pager_query($query, $page_size, 0, $names);
27 }
28 else {
29 $result = db_query($query, $names);
30 }
31
32 while ($page = db_fetch_object($result)) {
33 $page->access = ($page->access ? explode(', ', $page->access) : array());
34 $page->arguments = (!empty($page->arguments)) ? unserialize($page->arguments) : array();
35 $page->displays = (!empty($page->displays)) ? unserialize($page->displays) : array();
36 $page->contexts = (!empty($page->contexts)) ? unserialize($page->contexts) : array();
37 $page->relationships = (!empty($page->relationships)) ? unserialize($page->relationships) : array();
38 $page->switcher_options = (!empty($page->switcher_options)) ? unserialize($page->switcher_options) : array();
39 $page->type = t('Local');
40 $page->loader_flags = (int) $page->loader_flags;
41
42 $pages[$page->name] = panels_page_sanitize($page);
43 }
44
45 $status = variable_get('panel_page_defaults', array());
46 foreach (panels_page_default_panels() as $page) {
47 // Determine if default panel is enabled or disabled.
48 if (isset($status[$page->name])) {
49 $page->disabled = $status[$page->name];
50 }
51
52 if (!empty($pages[$page->name])) {
53 $pages[$page->name]->type = t('Overridden');
54 }
55 else {
56 $page->type = t('Default');
57 $pages[$page->name] = $page;
58 }
59 }
60 return $pages;
61 }
62
63 /**
64 * Load a panel page.
65 */
66 function panels_page_load($id, $load_display = FALSE) {
67 $cache = panels_page_loaded_cache($id);
68
69 if ($cache) {
70 // This is deprecated; ideally the fetcher should be called directly
71 if ($load_display && empty($cache->primary)) {
72 panels_page_fetch_primary_display($cache);
73 }
74 return $cache;
75 }
76
77 if (!is_numeric($id)) {
78 $where = "name = '%s'";
79 }
80 else {
81 $where = 'pid = %d';
82 }
83 $page = db_fetch_object(db_query("SELECT * FROM {panels_page} WHERE $where", $id));
84 if (!$page) {
85 $defaults = panels_page_default_panels();
86 if (isset($defaults[$id])) {
87 // Default panel pages will always only be identified by name, so no need
88 // for the both-ids-point-to-same-object trick. And, they're in code, so
89 // no real need to statically cache them, either.
90 $page = $defaults[$id];
91 return $page;
92 }
93 return;
94 }
95
96 $page->access = ($page->access ? explode(', ', $page->access) : array());
97 $page->arguments = (!empty($page->arguments)) ? unserialize($page->arguments) : array();
98 $page->displays = (!empty($page->displays)) ? unserialize($page->displays) : array();
99 $page->contexts = (!empty($page->contexts)) ? unserialize($page->contexts) : array();
100 $page->relationships = (!empty($page->relationships)) ? unserialize($page->relationships) : array();
101 $page->switcher_options = (!empty($page->switcher_options)) ? unserialize($page->switcher_options) : array();
102 $page->loader_flags = (int) $page->loader_flags;
103
104 if ($load_display) {
105 $page->primary = panels_load_display($page->did);
106 // By default, we set the primary display as the current display.
107 $page->display = &$page->primary;
108 }
109
110 panels_page_loaded_cache($id, $page);
111 return $page;
112 }
113
114 function panels_page_loaded_cache($id, $panel_page = NULL) {
115 static $cache = array();
116 if (is_object($panel_page)) {
117 $cache[$id] = $panel_page;
118 // Make sure that we've statically cached the loaded page for both possible
119 // unique identifiers - $page->pid AND $page->name.
120 $other_id = is_numeric($id) ? $panel_page->name : $panel_page->pid;
121 $cache[$other_id] = &$cache[$id];
122 }
123 return array_key_exists($id, $cache) ? $cache[$id] : FALSE;
124 }
125
126 /**
127 * Get all 'default' panels.
128 *
129 * @ingroup HookInvokers
130 */
131 function panels_page_default_panels() {
132 $panels = module_invoke_all('default_panel_pages');
133 if (!is_array($panels)) {
134 $panels = array();
135 }
136
137 return $panels;
138 }
139
140
141 function panels_page_set_current(&$panel_page) {
142 static $cache = NULL;
143 // Only allow it to be set once per request.
144 if (!isset($cache) && isset($panel_page)) {
145 $cache = &$panel_page;
146 }
147 return $cache;
148 }
149
150 /**
151 * Load a display into the 'current display' position, $panel_page->current.
152 *
153 * The family of panels_page_fetch*() functions are specifically dedicated to
154 * retrieving a particular display and placing them in $panels_page->display,
155 * which is the 'current' display upon which all other operations act.
156 * via reference to its permanent home in the $panels_page object. The
157 * permanent homes vary:
158 *
159 * -# For the primary display, that location is $panels_page->primary.
160 * -# For alternate default displays, that location is in
161 * $panels_page->alternates['defaults'][$did]. TODO this isn't true right now
162 * -# For alternate non-default displays, that location is in
163 * $panels_page->alternates['all'][$did].
164 *
165 * The structure of this function family essentially means that no other
166 * panels_page function should ever act on anything except $panel_page->display.
167 *
168 * @param object $panel_page
169 * @param string $id
170 * A string of the format generated by panels_argument_get_display().
171 * @return mixed
172 * Can return NULL or TRUE. Most of the substantial operations are performed
173 * by reference. NULL returns indicate that the fetched display corresponds
174 * exactly to the one requested by $id; TRUE return values indicate that the
175 * requested $id does not have its own display associated with it, and so
176 * a default (either an alternate default or the primary display) were
177 * returned in its stead.
178 */
179 function panels_page_fetch_display(&$panel_page, $id = NULL) {
180 $which = empty($id) ? 'primary' : 'alternate';
181 $function = "panels_page_fetch_{$which}_display";
182 // Redirect to the appropriate fetcher depending on whether $id is provided
183 $function($panel_page, $id);
184 }
185
186 /**
187 * Internal panels_page API function; directs the current display
188 * ($panel_page->display) to the primary display ($panel_page->primary),
189 * loading the primary display if necessary.
190 *
191 * @param object $panel_page
192 */
193 function panels_page_fetch_primary_display(&$panel_page) {
194 // Commented out is a more precise way of telling, but it's probably moot.
195 // if (empty($panel_page->primary) || !is_a($panel_page->primary, 'panels_display')) {
196 if (empty($panel_page->primary) || !is_object($panel_page->primary)) {
197 $panel_page->primary = panels_load_display($panel_page->did);
198 }
199 $panel_page->display = &$panel_page->primary;
200 $panel_page->current = 'primary';
201 // Update the cache.
202 panels_page_loaded_cache($panel_page->name, $panel_page);
203 }
204
205 function panels_page_fetch_alternate_display(&$panel_page, $id) {
206 $info = $panel_page->displays[$id];
207 $requested_display_exists = panels_page_fetch_display_from_info($panel_page, $info, $id);
208 if (!$requested_display_exists) {
209 // The requested display does not exist. First, we try to fall back to the
210 // default display for the context we're switching on.
211 if (!empty($info['default']) && !empty($panel_page->displays[$info['default']])) {
212 panels_page_fetch_display_from_info($panel_page, $panel_page->displays[$info['default']], $id);
213 }
214 // Otherwise, use the primary display. Load it if it's not already loaded.
215 else {
216 panels_page_fetch_primary_display($panel_page);
217 }
218 }
219 return TRUE;
220 }
221
222 /**
223 * Get a display based on whether it's already in code or needs to be loaded.
224 */
225 function panels_page_fetch_display_from_info(&$panel_page, $info, $id) {
226 $ret = NULL;
227 // If the 'display' is set it's the result of an export/default
228 if (isset($info['display'])) {
229 $panel_page->display = $info['display'];
230 $panel_page->current = $id;
231 return TRUE;
232 }
233
234 if (is_numeric($info['did'])) {
235 $panel_page->display = panels_load_display($info['did']);
236 $panel_page->current = $id;
237 return TRUE;
238 }
239 return FALSE;
240 }
241
242 /**
243 * Determine if the specified user has access to a panel.
244 */
245 function panels_page_access($panel_page, $account = NULL) {
246 if (!$account) {
247 global $user;
248 $account = $user;
249 }
250
251 // Administrator privileges
252 if (user_access('access all panel-pages', $account)) {
253 return TRUE;
254 }
255
256 // All panels displays with an empty access setting are available to all roles.
257 if (empty($panel_page->access) || !is_array($panel_page->access)) {
258 return TRUE;
259 }
260
261 // Otherwise, check roles
262 static $roles = array();
263 if (!isset($roles[$account->uid])) {
264 $roles[$account->uid] = array_keys($account->roles);
265 $roles[$account->uid][] = $account->uid ? DRUPAL_AUTHENTICATED_RID : DRUPAL_ANONYMOUS_RID;
266 }
267
268 return array_intersect($panel_page->access, $roles[$account->uid]);
269 }
270