/[drupal]/contributions/modules/mysite/mysite.module
ViewVC logotype

Contents of /contributions/modules/mysite/mysite.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.98 - (show annotations) (download) (as text)
Wed Oct 1 14:01:37 2008 UTC (13 months, 3 weeks ago) by agentken
Branch: MAIN
CVS Tags: DRUPAL-5--3-3, HEAD
Changes since 1.97: +2 -2 lines
File MIME type: text/x-php
  -- #309218 fixes error in calculating collection limits.
  -- Creates the 5.x.3.3 release.
1 <?php
2 // $Id: mysite.module,v 1.97 2008/04/27 18:47:05 agentken Exp $
3
4
5 /**
6 * @defgroup mysite Mysite: Allows users to create custom pages of site content.
7 *
8 * Before reading the API, you should refer to http://drupal.org/node/119576,
9 * which offers a short tutorial on MySite plugins.
10 *
11 * Please be sure to also read http://drupal.org/node/318 for Drupal coding standards and refer to
12 * http://api.drupal.org for core Drupal documentation.
13 *
14 * The best starting point for this API is probably http://therickards.com/api/group/hooks/MySite.
15 * This section shows you the common functions used by MySite plugins.
16 *
17 * If you find errors in the documentation, please file an issue at http://drupal.org/project/issues/mysite.
18 *
19 * -- agentrickard
20 */
21
22 /**
23 * @file
24 * Core module file for the MySite module.
25 *
26 * @ingroup mysite
27 */
28
29 /**
30 * Implementation of hook_help().
31 */
32 function mysite_help($section) {
33 switch ($section) {
34 case 'admin/help#mysite':
35 include_once('mysite_help.inc');
36 $output = mysite_helptext();
37 return $output;
38 break;
39 case 'admin/settings/mysite':
40 $output = t('<p>The MySite module gives users a customized view of site data,
41 arranged in the order they prefer. The behavior and presentation of the MySite
42 module can be controlled through the following settings. For detailed instructions,
43 see the README.txt file in your MySite folder.</p>');
44 return $output;
45 break;
46 }
47 }
48
49 /**
50 * Implementation of hook_menu().
51 */
52 function mysite_menu($may_cache) {
53 global $user;
54 $items = array();
55 // Run access checks once for the entire menu.
56 $admin = FALSE;
57 $view = user_access('view mysite');
58 if (user_access('administer mysite')) {
59 $admin = TRUE;
60 $owner = TRUE;
61 $create = TRUE;
62 }
63 else {
64 $create = user_access('edit mysite');
65 $owner = FALSE;
66 if ($create && $user->uid == arg(1)) {
67 $owner = TRUE;
68 }
69 }
70
71 // Load the MySite data for the menu, if needed
72 $show_pages = FALSE;
73 if (arg(0) == 'mysite') {
74 $uid = arg(1);
75 $mysite = mysite_get($uid);
76 $show_pages = TRUE;
77 $access = mysite_menu_check($mysite->status, $owner, $view);
78 // conditional functions needed by MySite's user interface
79 // add the css to override form-item and format icons
80 drupal_add_css(drupal_get_path('module', 'mysite') .'/mysite.css');
81 // we use the collapse feature in the interface, so make sure it loads.
82 if (function_exists('jquery_interface_add') && ($admin || $owner)) {
83 drupal_add_js(drupal_get_path('module', 'mysite') .'/mysite.js', 'module');
84 // add interface support
85 jquery_interface_add();
86 }
87 }
88 if ($may_cache) {
89 $items[] = array('path' => 'admin/settings/mysite',
90 'title' => t('MySite'),
91 'description' => t('Adjust the features and settings for the MySite module.'),
92 'callback' => 'mysite_configure',
93 'access' => $admin);
94 // menu items for default settings
95 $items[] = array('path' => 'admin/settings/mysite/edit',
96 'title' => t('Default page settings'),
97 'description' => t('Edit the default MySite content settings.'),
98 'callback' => 'drupal_goto',
99 'weight' => -8,
100 'type' => MENU_LOCAL_TASK,
101 'callback arguments' => array('mysite/0/edit'),
102 'access' => $admin);
103 $items[] = array('path' => 'admin/settings/mysite/content',
104 'title' => t('Default page content'),
105 'description' => t('Edit the default MySite content settings.'),
106 'weight' => -6,
107 'callback' => 'drupal_goto',
108 'type' => MENU_LOCAL_TASK,
109 'callback arguments' => array('mysite/0/content'),
110 'access' => $admin);
111 // activate a plugin
112 $items[] = array('path' => 'admin/settings/mysite/type/activate',
113 'title' => mysite_sitename(),
114 'callback' => 'mysite_activate',
115 'type' => MENU_CALLBACK,
116 'access' => $admin);
117 // default page view items
118 $items[] = array('path' => 'mysite',
119 'title' => mysite_sitename(),
120 'callback' => 'mysite_view',
121 'access' => $view);
122 // admin tasks
123 $items[] = array('path' => 'mysite/0/admin',
124 'title' => t('Settings'),
125 'callback' => 'drupal_goto',
126 'type' => MENU_LOCAL_TASK,
127 'callback arguments' => array('admin/settings/mysite'),
128 'weight' => -5,
129 'access' => $admin);
130 $items[] = array('path' => 'mysite/0/view',
131 'title' => t('Default pages'),
132 'callback' => 'mysite_view',
133 'type' => MENU_LOCAL_TASK,
134 'weight' => -3,
135 'access' => $admin);
136 $items[] = array('path' => 'mysite/0/edit',
137 'title' => t('Default settings'),
138 'callback' => 'mysite_edit',
139 'type' => MENU_LOCAL_TASK,
140 'access' => $admin);
141 $items[] = array('path' => 'mysite/0/content',
142 'title' => t('Default content'),
143 'callback' => 'mysite_content',
144 'type' => MENU_LOCAL_TASK,
145 'access' => $admin);
146 $items[] = array('path' => 'mysite-all',
147 'title' => t('View all personal sites'),
148 'callback' => 'mysite_view_all',
149 'access' => $view);
150 $items[] = array('path' => 'mysite-default',
151 'title' => mysite_sitename(),
152 'callback' => 'mysite_view_default',
153 'type' => MENU_CALLBACK,
154 'access' => $view);
155 $items[] = array('path' => 'autocomplete/mysite',
156 'title' => t('MySite autocomplete'),
157 'callback' => 'mysite_autocomplete',
158 'type' => MENU_CALLBACK,
159 'access' => $create);
160 }
161 else {
162 // add a tab to the user page
163 if (arg(0) == 'user' && is_numeric(arg(1))) {
164 $items[] = array('path' => 'user/'. arg(1) .'/mysite',
165 'title' => mysite_sitename(),
166 'access' => $owner,
167 'callback' => 'mysite_page',
168 'callback arguments' => array(arg(1)),
169 'type' => MENU_LOCAL_TASK, 'weight' => 10);
170 }
171 // Ajax handling items
172 $items[] = array('path' => 'ajax/mysite/'. arg(2) .'/'. arg(3),
173 'title' => t('Ajax MySite'),
174 'callback' => 'mysite_ajax',
175 'callback arguments' => array(arg(2), arg(3)),
176 'type' => MENU_CALLBACK,
177 'access' => $create);
178 $items[] = array('path' => 'ajax/mysite-sort',
179 'title' => t('Ajax MySite'),
180 'callback' => 'mysite_ajax_sort',
181 'type' => MENU_CALLBACK,
182 'access' => $create);
183 if (arg(0) == 'mysite' && is_numeric(arg(1))) {
184 $items[] = array(
185 'title' => $mysite->title,
186 'path' => 'mysite/'. arg(1),
187 'type' => MENU_NORMAL_ITEM,
188 'weight' => -10,
189 'callback' => 'mysite_view',
190 'callback arguments' => array(arg(1)),
191 'access' => $access);
192 $items[] = array('path' => 'mysite/'. arg(1) .'/delete',
193 'title' => t('Delete'),
194 'callback' => 'drupal_get_form',
195 'callback arguments' => array('mysite_delete_form', arg(1)),
196 'access' => $owner,
197 'weight' => 10,
198 'type' => MENU_LOCAL_TASK);
199 $items[] = array('path' => 'mysite/'. arg(1) .'/reset',
200 'title' => t('Reset'),
201 'callback' => 'drupal_get_form',
202 'callback arguments' => array('mysite_reset_form'),
203 'access' => $owner,
204 'type' => MENU_CALLBACK);
205 if ($show_pages) {
206 // Load data for sub-pages.
207 $pages = mysite_get_pages($uid);
208 // Menu actions to implement
209 $actions = array(
210 'view' => array('title' => t('View'), 'weight' => -10, 'path' => 'view', 'callback' => 'mysite_page'),
211 'edit' => array('title' => t('Settings'), 'weight' => -8, 'path' => 'edit', 'callback' => 'mysite_edit'),
212 'content' => array('title' => t('Content'), 'weight' => -6, 'path' => 'content', 'callback' => 'mysite_content')
213 );
214 // prep the submenu tasks
215 $weight = -10;
216 $test = arg(2);
217 $arg = (empty($test)) ? 'view' : $test;
218 $i = arg(3);
219 $page = (empty($i)) ? 0 : $i;
220 $page = ($page == 'add-page') ? 0 : $page;
221 // We can only remove pages if it is not the default page.
222 if ($page > 0 && count($pages) > 0) {
223 $actions['remove'] = array('title' => t('Remove page'), 'weight' => -4, 'path' => 'remove-page', 'callback' => 'mysite_remove_page');
224 }
225 if ($arg == 'view') {
226 $items[] = array(
227 'title' => t('View'),
228 'path' => 'mysite/'. arg(1) .'/view',
229 'type' => MENU_DEFAULT_LOCAL_TASK,
230 'weight' => -10,
231 'callback' => 'mysite_view',
232 'callback arguments' => array(arg(1)),
233 'access' => $access
234 );
235 if (count($pages) < variable_get('mysite_pages', 5)) {
236 $items[] = array(
237 'title' => t('Add new page'),
238 'path' => 'mysite/'. arg(1) .'/view/add-page',
239 'type' => MENU_LOCAL_TASK,
240 'weight' => 100,
241 'callback' => 'mysite_add_page',
242 'callback arguments' => array(arg(1)),
243 'access' => $owner
244 );
245 }
246 }
247 $content_set = MENU_CALLBACK;
248 if ($test == 'settings') {
249 $content_set = MENU_LOCAL_TASK;
250 }
251 $items[] = array('path' => 'mysite/'. arg(1) .'/settings/'. arg(3) .'/'. arg(4),
252 'title' => t('Customize'),
253 'callback' => 'mysite_content_settings',
254 'callback arguments' => array(arg(1), arg(4)),
255 'access' => $owner,
256 'weight' => 10,
257 'type' => $content_set
258 );
259 foreach ($actions as $action => $settings) {
260 if ($action == $arg && !empty($pages)) {
261 $items[] = array(
262 'title' => $settings['title'],
263 'path' => 'mysite/'. arg(1) .'/'. $settings['path'],
264 'type' => MENU_LOCAL_TASK,
265 'weight' => $settings['weight'],
266 'callback' => $settings['callback'],
267 'callback arguments' => array(arg(1)),
268 'access' => ($arg == 'view') ? $access : $owner
269 );
270 foreach ($pages as $key => $value) {
271 $type = MENU_LOCAL_TASK;
272 $page_access = $owner;
273 if ($settings['path'] == 'view') {
274 $page_access = mysite_menu_check($value['status'], $owner, $view);
275 if ($key == 0) {
276 $type = MENU_DEFAULT_LOCAL_TASK;
277 }
278 }
279 $items[] = array(
280 'title' => $value['title'],
281 'path' => 'mysite/'. arg(1) .'/'. $settings['path'] .'/'. $key,
282 'type' => $type,
283 'weight' => (-10 + $value['page']),
284 'callback' => $settings['callback'],
285 'callback arguments' => array(arg(1), arg(3)),
286 'access' => $page_access
287 );
288 $weight++;
289 }
290 }
291 $items[] = array(
292 'title' => $settings['title'],
293 'path' => 'mysite/'. arg(1) .'/'. $settings['path'] .'/'. $page,
294 'type' => MENU_LOCAL_TASK,
295 'weight' => $settings['weight'],
296 'callback' => $settings['callback'],
297 'callback arguments' => array(arg(1), arg(3)),
298 'access' => $owner
299 );
300 if ($arg == 'edit') {
301 $_mysite_edit = mysite_edit_menu();
302 foreach ($_mysite_edit as $key => $value) {
303 foreach ($value as $path => $element) {
304 $items[] = array('path' => 'mysite/'. arg(1) .'/edit/'. $key .'/'. $path,
305 'title' => $element['label'],
306 'callback' => 'mysite_edit',
307 'callback arguments' => array(arg(1), arg(3), arg(4)),
308 'access' => $owner,
309 'type' => MENU_LOCAL_TASK
310 );
311 }
312 }
313 }
314 }
315 }
316 // theme switching check
317 if (arg(0) == 'mysite' && is_numeric(arg(1))) {
318 $types = variable_get('mysite_content', NULL);
319 $themes = variable_get('mysite_theme_settings', array());
320 if (!empty($pages[$page]['theme']) && !empty($types['theme']) && !empty($themes[$mysite->theme])) {
321 global $custom_theme;
322 $custom_theme = $pages[$page]['theme'];
323 }
324 }
325 $items[] = array('path' => 'mysite/'. arg(1) .'/remove/'. arg(3),
326 'title' => t('Remove item'),
327 'callback' => 'mysite_content_remove',
328 'callback arguments' => array(arg(1), arg(3)),
329 'access' => $owner,
330 'weight' => 10,
331 'type' => MENU_CALLBACK);
332 $items[] = array('path' => 'mysite/'. arg(1) .'/promote/'. arg(3) .'/'. arg(4),
333 'title' => t('Promote item'),
334 'callback' => 'mysite_content_promote',
335 'callback arguments' => array(arg(1), arg(3), arg(4)),
336 'access' => $owner,
337 'weight' => 10,
338 'type' => MENU_CALLBACK);
339 $items[] = array('path' => 'mysite/'. arg(1) .'/add',
340 'title' => t('Add item'),
341 'callback' => 'mysite_content_add',
342 'callback arguments' => array(arg(1)),
343 'access' => $owner,
344 'weight' => 10,
345 'type' => MENU_CALLBACK);
346 }
347 if ($admin && arg(0) == 'admin' && arg(2) == 'mysite') {
348 $types = mysite_load_includes('types', NULL, $load_all = TRUE);
349 $items[] = array('path' => 'admin/settings/mysite/type',
350 'title' => t('Settings'),
351 'description' => t('Adjust the features and settings for the MySite module.'),
352 'type' => MENU_DEFAULT_LOCAL_TASK,
353 'access' => $admin,
354 'weight' => -10);
355 $items[] = array('path' => 'admin/settings/mysite/type/settings',
356 'title' => t('MySite'),
357 'description' => t('Adjust the features and settings for the MySite module.'),
358 'type' => MENU_DEFAULT_LOCAL_TASK,
359 'access' => $admin,
360 'weight' => -10);
361 if (is_array($types)) {
362 foreach ($types as $type) {
363 $check = module_invoke('mysite_type', $type, FALSE);
364 if ((function_exists('mysite_type_'. $type .'_title') || function_exists('mysite_type_'. $type .'_settings')) && is_array($check)) {
365 $items[] = array('path' => 'admin/settings/mysite/type/'. $type,
366 'title' => t('@type', array('@type' => ucwords($type))),
367 'description' => t('Settings for the @type plugin', array('@type' => ucwords($type))),
368 'callback' => 'mysite_type_settings',
369 'callback arguments' => array($type),
370 'type' => MENU_LOCAL_TASK,
371 'access' => $admin,
372 'weight' => 0);
373 }
374 }
375 }
376 }
377 }
378 return $items;
379 }
380
381 /**
382 * Installer function that sets MySite pages to show on all domains.
383 *
384 */
385 function mysite_enable() {
386 $pages = variable_get('domain_grant_all', "user/*/track");
387 if (strpos($pages, 'mysite/*') == 0) {
388 $pages .= "\r\nmysite/*";
389 variable_set('domain_grant_all', $pages);
390 }
391 }
392
393 /**
394 * Implementation of hook_perm().
395 */
396 function mysite_perm() {
397 $array = array('administer mysite', 'edit mysite', 'view mysite');
398 // if using aggregator, we have an additional permission
399 if (module_exists('aggregator')) {
400 $array[] = 'add mysite feeds';
401 }
402 return $array;
403 }
404
405 /**
406 * Implementation of hook_user().
407 */
408 function mysite_user($type, &$edit, &$user) {
409 if ($type == 'view' && user_access('edit mysite', $user)) {
410 $mysite = mysite_get($user->uid);
411 if ($mysite->uid > 0 && user_access('administer mysite') || $mysite->status == 1) {
412 $items['mysite'] = array('title' => mysite_sitename(),
413 'value' => l($mysite->title, "mysite/$user->uid/view", array('title' => t("Read @username's personal page.", array('@username' => $user->name)))),
414 'class' => 'mysite',
415 );
416 return array(t('History') => $items);
417 }
418 }
419 }
420
421 /**
422 * Implementation of hook_block(). Calls mysite_type_hook_block().
423 *
424 * @param $nid
425 * We invoke this hook from mysite_link as well, so this variable lets us
426 * make minor changes to the output call, as needed. Passing the node id
427 * gives us both the data and the logic necessary to invoke the MySite hooks.
428 */
429 function mysite_block($op = 'list', $delta = 0, $nid = NULL) {
430 global $user;
431 if ($op == 'list') {
432 $blocks[0]['info'] = t('MySite');
433 return $blocks;
434 }
435 else if ($op == 'view' && user_access('edit mysite')) {
436 // Each of the type includes must check the path. No point in calling arg() more than once.
437 for ($i = 0; $i < 5; $i++) {
438 $arg[$i] = arg($i);
439 }
440 $content = '';
441 // if the user has a mysite, generate a link to it.
442 $mysite = mysite_get($user->uid);
443 if ($mysite->uid > 0) {
444 $content .= '<ul>';
445 $content .= '<li>'. l($mysite->title, 'mysite/'. $mysite->uid .'/view') .'</li>';
446 if (user_access('view all mysites') && empty($nid)) {
447 $content .= '<li>'. l(t('View custom sites'), 'mysite-all') .'</li>';
448 }
449 $content .= '</ul>';
450 }
451 // if not, help them create a mysite.
452 else {
453 $content = theme_mysite_block_help();
454 }
455 // load the type includes and check for block content. See the README for more.
456 if (user_access('edit mysite')) {
457 static $result, $pages, $page_count, $page, $check = FALSE;
458 if (!isset($page)) {
459 $page = mysite_find_empty_page($user->uid);
460 }
461 if ($page >= 0) {
462 $types = mysite_load_includes('types');
463 foreach ($types as $key => $value) {
464 $content .= module_invoke('mysite_type', $value .'_block', $arg, $op);
465 }
466 // universal handler for nodes, where $nid may be passed from mysite_link()
467 // or inferred from the path when viewing a node
468 if (!empty($nid) || ($arg[0] == 'node' && is_numeric($arg[1]))) {
469 if (!$nid) {
470 $nid = $arg[1];
471 }
472 $query = db_fetch_object(db_query("SELECT n.type, n.nid FROM {node} n WHERE n.nid = %d", $nid));
473 if ($query->nid > 0) {
474 foreach ($types as $key => $value) {
475 $content .= module_invoke('mysite_type', $value .'_block_node', $query->nid, $query->type);
476 }
477 }
478 }
479 }
480 else {
481 if (count($pages) < variable_get('mysite_pages', 5)) {
482 $content .= l(t('Create new personal page'), 'mysite/'. $user->uid .'view/add-page');
483 }
484 else {
485 $content .= t('Your personal page is currently full. Go to <a href="@url">add or remove content</a> to delete an item.', array('@url' => url("mysite/$user->uid/content")));
486 }
487 }
488 }
489 }
490 // if we returned $content, then print the block.
491 if (!empty($content)) {
492 $block['subject'] = mysite_sitename();
493 $block['content'] = $content;
494 }
495 return $block;
496 }
497
498 /**
499 * Implementation of hook_link()
500 */
501 function mysite_link($type, $node = NULL, $teaser = FALSE) {
502 if ($type == 'node' && $node->nid) {
503 $show = variable_get('mysite_links', 1);
504 // 0 == no; 1 == always, 2 == page view only
505 if ($show == 1 || ($show == 2 && !$teaser)) {
506 global $user;
507 if ($user->uid > 0 && user_access('edit mysite')) {
508 $link = l(mysite_sitename(), 'mysite/'. $user->uid .'/view', array('class' => 'mysite-anchor'));
509 drupal_add_js(drupal_get_path('module', 'mysite') .'/mysite_links.js', 'module');
510 drupal_add_css(drupal_get_path('module', 'mysite') .'/mysite_links.css');
511 $links = array();
512 // we already prepare the links in hook_block, so get them and theme them.
513 $data = mysite_block('view', 0, $node->nid);
514 $string = str_replace('<ul>', '', $data['content']);
515 $content = str_replace('</ul>', '', $string);
516 $links['mysite'] = array(
517 'title' => theme('mysite_links', $link, $content),
518 'html' => TRUE
519 );
520 return $links;
521 }
522 }
523 }
524 }
525
526 /**
527 * Menu callback; presents general configuration options.
528 */
529 function mysite_configure() {
530 // run the cron hook if cron isn't configured properly.
531 mysite_cron();
532 // set the interface variable
533 if (!function_exists('jquery_interface_add') && !$_POST) {
534 drupal_set_message(t('To enable drag-and-drop sorting of content, you must install and enable the <a href="!jq">jQuery Update</a> and <a href="!ji">jQuery Interface</a> modules.', array('!jq' => 'http://drupal.org/project/jquery_update', '!ji' => 'http://drupal.org/project/jquery_interface')));
535 }
536 return drupal_get_form('mysite_configure_form');
537 }
538
539 /**
540 * Cron hook for cleaning out bad data
541 * We use this routine to remove MySite references
542 * to deleted content containers.
543 */
544 function mysite_cron() {
545 // run this once per day, if cron is disabled, it runs from the settings page
546 $cron= variable_get('mysite_cron', '0');
547 $date = date("Ymd", time() - (3600 * 24)); // get yesterday's date
548 if ($date != $cron) {
549 variable_set('mysite_cron', $date);
550 $types = mysite_load_includes('types');
551 foreach ($types as $type) {
552 $data[$type] = module_invoke('mysite_type', $type .'_clear', $type);
553 }
554 // iterate through the returns and set user messages
555 if (!empty($data)) {
556 foreach ($data as $key => $value) {
557 if (is_array($value) && !empty($value)) {
558 foreach ($value as $item) {
559 $sql = "DELETE FROM {mysite_data} WHERE mid = %d";
560 db_query($sql, $item['mid']);
561 $sql = "SELECT message FROM {mysite} WHERE uid = %d";
562 $obj = db_fetch_object(db_query($sql, $uid));
563 $message = $obj->message;
564 $message .= t('<p>@title content is no longer available and has been removed from your personal page.</p>', array('@title' => $item['title']));
565 $sql = "UPDATE {mysite} SET message = '%s' WHERE uid = %d";
566 db_query($sql, $message, $item['uid']);
567 }
568 }
569 }
570 }
571 }
572 }
573
574 /**** PAGE VIEW FUNCTIONS ****/
575
576 /**
577 * Take user to the correct MySite page, based on mysite_configure().
578 */
579 function mysite_view($uid = NULL) {
580 global $user;
581 if (is_null($uid)) {
582 $list = variable_get('mysite_list', 0);
583 if ($list) {
584 drupal_goto('mysite-all');
585 }
586 $uid = arg(1);
587 }
588 $mysite = mysite_get($uid);
589 if ($mysite->uid > 0 && user_access('view mysite')) {
590 drupal_goto('mysite/'. $mysite->uid .'/view');
591 }
592 else if ($user->uid > 0) {
593 return theme('mysite_create_help', $user);
594 }
595 else {
596 return theme('mysite_anonymous_help');
597 }
598 }
599
600 /**
601 * View all active MySite users
602 */
603 function mysite_view_all() {
604 $output = '';
605 $header = array(
606 array('data' => t('Name'), 'field' => 'name'),
607 array('data' => t('Collection Title'), 'field' => 'title'),
608 array('data' => t('Updated'), 'field' => 'updated')
609 );
610 $sql = 'SELECT m.uid, m.title, m.created, m.updated, u.name, u.picture FROM {mysite} m INNER JOIN {users} u ON m.uid = u.uid WHERE u.status = 1 AND m.status = 1'. tablesort_sql($header);
611 if (user_access('administer mysite')) {
612 $sql = 'SELECT m.uid, m.title, m.created, m.updated, u.name, u.picture FROM {mysite} m INNER JOIN {users} u ON m.uid = u.uid WHERE u.status = 1'. tablesort_sql($header);
613 }
614 $result = pager_query($sql, 25);
615 $rows = array();
616 while ($owner = db_fetch_object($result)) {
617 $updated = $owner->created;
618 if (!empty($owner->updated)) {
619 $updated = $owner->updated;
620 }
621 $rows[] = array('data' => array($owner->name, l($owner->title, 'mysite/'. $owner->uid .'/view'), format_date($updated, $type = 'medium', $format = '', $timezone = NULL)));
622 if ($owner->uid == $user->uid) {
623 $nopage = FALSE;
624 }
625 }
626 // no users found
627 if (!empty($rows)) {
628 $output .= theme_table($header, $rows);
629 $output .= theme('pager', NULL, 25, 0);
630 }
631 else {
632 $top_output .= l(t('There are no publicly viewable personal collections.'), "mysite/". $user->uid);
633 }
634 // can this user create a mysite?
635 $mysite = mysite_get($user->uid);
636 if (user_access('edit mysite') && empty($mysite)) {
637 $top_output .= l(t('Create your own personal collection.'), "mysite/". $user->uid .'/edit');
638 }
639 $output = $top_output . $output;
640 return $output;
641 }
642
643 /**
644 * Show the default user page
645 */
646 function mysite_view_default() {
647 // show the default mysite
648 $default = (int) variable_get('mysite_default_user', 0);
649 drupal_goto('mysite/'. $default .'/view');
650 }
651
652 /**
653 * The default MySite page view.
654 *
655 * @param $uid
656 * The user id of the owner of the mysite.
657 * @param $page
658 * The current page of the mysite collection.
659 * @param $pageview
660 * Boolean flag that indicates the data will be viewed using theme_page.
661 * If you want to access this data externally, set $pageview = FALSE.
662 * @return
663 * $content array.
664 * If $pageview = FALSE, the function will return a $content array with three elements.
665 * $content['owner'] = the $user object of the MySite page's owner.
666 * $content['mysite'] = MySite data for the page's owner.
667 * $content['data'] = MySite data as defined by mysite_type_{name}_data().
668 * If the user does not have a MySite page, $content will return an empty array().
669 */
670 function mysite_page($uid = NULL, $page = 0, $pageview = TRUE) {
671 global $user;
672
673 // get the $owner of this mysite, use as a $user surrogate
674 if (is_null($uid)) {
675 $uid = arg(1);
676 }
677 if (is_numeric($uid)) {
678 $owner = user_load(array('uid' => $uid));
679 }
680 if (!isset($owner->uid)) {
681 $owner = $user;
682 }
683 // Load the settings for this page.
684 $mysite = mysite_load_page($owner->uid, $page);
685
686 // access control set by the user 'status' flag
687 $show = FALSE;
688 // if the user is looking at the MySite data
689 if ($user->uid == $owner->uid) {
690 $show = TRUE;
691 if ($pageview) {
692 // get any system messages waiting for this user
693 mysite_message($owner->uid);
694
695 // this user has no page, give them help making one
696 if (user_access('edit mysite')) {
697 if (!isset($mysite->uid)) {
698 $output = theme('mysite_create_help', $owner);
699 return $output;
700 }
701 }
702 else {
703 return drupal_access_denied();
704 }
705 }
706 }
707 // access checks: can this user view this data?
708 // these checks are here for external use of this function
709 else if (user_access('administer mysite') || $mysite->uid == 0 || $mysite->status == 1) {
710 $show = TRUE;
711 }
712 // show the page or return the data
713 if ($show) {
714 mysite_load($mysite, $pageview);
715 // the cache wrapper
716 $content = NULL;
717 $cache_set = variable_get('mysite_cache', 0);
718 if ($cache_set > 0) {
719 $expire = db_result(db_query("SELECT expire FROM {cache} WHERE cid = '%s'", 'mysite:'. $mysite->uid .':'. $mysite->page));
720 if (time() < $expire) {
721 $data = cache_get('mysite:'. $mysite->uid .':'. $mysite->page, 'cache');
722 $content = unserialize($data->data);
723 }
724 if (isset($content['owner']) && empty($content['data'])) {
725 // This page is blank in the cache, so just render the approprate message.
726 return mysite_output($owner, $mysite, $content = array(), $pageview);
727 }
728 }
729 if (empty($content)) {
730 $data = array();
731 /* get the data for this user
732 for each type of content listed in the user's mysite_data set
733 run the appropriate include / theme function
734 append the themed data to the $data array
735 using the order value as the key
736 */
737 $sql = 'SELECT mid, uid, page, title, type, type_id, sort, position, format, settings, locked FROM {mysite_data} WHERE (uid = %d OR (uid = 0 AND locked = 1)) AND page = %d ORDER BY position ASC, sort ASC';
738 $result = db_query($sql, $owner->uid, $page);
739 $i = 0;
740 $allowed = variable_get('mysite_content', array());
741 while ($item = db_fetch_object($result)) {
742 // check to see if the content option is still valid
743 if (!empty($allowed[$item->type])) {
744 mysite_load_includes('types', $item->type);
745 // enable the format files
746 mysite_load_includes('formats', $item->format);
747 $data[$item->position][$i]['title'] = check_plain($item->title);
748 $data[$item->position][$i]['mid'] = $item->mid;
749 $data[$item->position][$i]['format'] = $item->format;
750 $data[$item->position][$i]['locked'] = $item->locked;
751 $settings = unserialize($item->settings);
752 $data[$item->position][$i]['output'] = module_invoke('mysite_type', $item->type .'_data', $item->type_id, $settings);
753 $data[$item->position][$i]['link'] = $data[$i]['output']['base'];
754 if (!$item->locked && (user_access('edit mysite') && $user->uid == $uid) || user_access('administer mysite')) {
755 $data[$item->position][$i]['actions'] = theme('mysite_actions', $item->uid, $item->mid, $page);
756 }
757 $i++;
758 }
759 else {
760 $sql = "DELETE FROM {mysite_data} WHERE mid = %d";
761 db_query($sql, $item->mid);
762 drupal_set_message(t('The %title item is no longer available.', array('%title' => $item->title)));
763 }
764 }
765 // cast the data sets as a single array so they can be passed
766 $content['owner'] = $owner;
767 $content['mysite'] = $mysite;
768 $content['data'] = $data;
769 if ($cache_set > 0) {
770 cache_set('mysite:'. $mysite->uid .':'. $mysite->page, 'cache', serialize($content), time() + $cache_set);
771 }
772 }
773 else {
774 // if reading from cache, we must load all the format includes
775 mysite_load_includes('formats', NULL, TRUE);
776 }
777 return mysite_output($owner, $mysite, $content, $pageview);
778 }
779 else if ($user->uid > 0 && user_access('edit mysite')) {
780 drupal_goto('mysite/'. $user->uid .'/view');
781 }
782 else {
783 return drupal_access_denied();
784 }
785 }
786
787 /**
788 * Return the proper content based on the request.
789 *
790 * @param $owner
791 * The $user object for the owner of this page.
792 * @param $mysite
793 * Information about this MySite collection, taken from mysite_get().
794 * @param $content
795 * The content elements to render for this page.
796 * @param $pageview
797 * Boolean flag that indicates the data will be viewed using theme_page.
798 * If you want to access this data externally, set $pageview = FALSE.
799 * @return
800 * Normally returns a themed HTML page. If accessed from an external
801 * function, may return the $content array.
802 */
803 function mysite_output($owner, $mysite, $content = array(), $pageview = TRUE) {
804 if ($pageview) {
805 if (!empty($content['data'])) {
806 print theme('mysite_'. $mysite->layout .'_layout', $content);
807 }
808 else {
809 global $user;
810 $output = '';
811 $_mysite_menu = mysite_content_menu();
812 if ($user->uid == $owner->uid) {
813 drupal_set_message(t('%name, you have no content saved.', array('%name' => $owner->name)));
814 }
815 else {
816 drupal_set_message(t('%name has no content saved.', array('%name' => $owner->name)));
817 }
818 $output .= theme('mysite_content_help', $owner);
819 print theme('page', $output, variable_get('mysite_fullscreen', 1));
820 }
821 return;
822 }
823 else {
824 return $content;
825 }
826 }
827
828 /**
829 * Prepare the output into the proper column for the layout.
830 *
831 * If a column is empty or does not exist, this function will collapse the data
832 * into the nearest available column. For example, if the user had a three-column
833 * layout, with items assigned $position 1, 2, and 3, and switches to a one-column
834 * layout, this function will collapse items in positions 2 and 3 into position 1.
835 *
836 * The function does not save position changes to the database.
837 *
838 * All layout functions must call this function to prepare data for presentation.
839 *
840 * @param $mysite
841 * Data object for this user's MySite page taken from the {mysite} table.
842 * @param $data
843 * The $data array passed to the layout function by mysite_page().
844 * @param $cols
845 * The number of columns (or regions) on the layout.
846 * @return
847 * $data array
848 * An array of data as defined by mysite_page(), but with empty regions collapsed
849 * and filled with a message to the user.
850 */
851 function mysite_prepare_columns($mysite, $data = array(), $cols = 1) {
852 global $user;
853 // reset the key to zero if there is only one column
854 if (count($data) == 1) {
855 sort($data);
856 $new = $data;
857 }
858 else {
859 // otherwise, slide existing data to a new array and unset the old
860 $new = array();
861 for ($i = 0; $i < $cols; $i++) {
862 $new[$i] = $data[$i];
863 unset($data[$i]);
864 }
865 // if there is leftover data, merge it into the last element of the new array;
866 if (!empty($data)) {
867 // set the columns correctly for the new keys
868 $set = $cols - 1;
869 if (empty($new[$set])) {
870 $new[$set] = array();
871 }
872 // loop the remaining data and merge it to the last region
873 foreach ($data as $array) {
874 if (!empty($array)) {
875 $new[$set] = array_merge($new[$set], $array);
876 }
877 }
878 }
879 }
880 if ($cols > 1) {
881 // handles empty regions gracefully
882 for ($i = 0; $i < $cols; $i++) {
883 if (empty($new[$i])) {
884 if (user_access('administer mysite') || (user_access('edit mysite') && $user->uid == $mysite->uid)) {
885 $new[$i][0]['title'] = t('Add content');
886 $new[$i][0]['mid'] = NULL;
887 $new[$i][0]['format'] = $mysite->format;
888 $new[$i][0]['output']['items'][0]['content'] = theme('mysite_empty_column', $mysite);
889 }
890 else {
891 // this should probably be themed
892 $new[$i][0] = array();
893 }
894 }
895 }
896 }
897 // We only have one column, so return it.
898 else {
899 $new = $new[0];
900 }
901 return $new;
902 }
903
904 /**
905 * Edit a MySite page using a multi-stage form.
906 *
907 * @param $uid
908 * The user id of the owner of the MySite.
909 * @param $page
910 * The current page of the mysite collection.
911 * @param $action
912 * The MySite settings form stage defined by mysite_edit_menu().
913 */
914 function mysite_edit($uid = NULL, $page = 0, $action = NULL) {
915 global $user;
916
917 $check = FALSE;
918 // get the $owner of this mysite, use as a $user surrogate
919 if (is_numeric($uid) && $uid > 0) {
920 $owner = user_load(array('uid' => $uid));
921 }
922 // set values if we are updating the admin settings
923 if ($uid == 0 && user_access('administer mysite')) {
924 $owner->uid = 0;
925 $check = TRUE;
926 }
927
928 // must have a valid uid to continue
929 if ($owner->uid > 0 || $check) {
930 // Create an account, if needed. mysite_get() will return -1 if no account exists.
931 $mysite = mysite_get($owner->uid, TRUE);
932 if ($mysite == -1) {
933 $edit['uid'] = $owner->uid;
934 // create a new account
935 $mysite = mysite_create_account($owner);
936 }
937 // get the user's current settings
938 $data = mysite_load_page($uid, $page);
939 $edit = (array) $data;
940 // add user styles
941 $inc = mysite_load_includes('styles', $edit['style']);
942
943 // print the submenu
944 $_submenu = mysite_edit_menu();
945 $submenu = $_submenu[$page];
946
947 if (is_string($action) && array_key_exists($action, $submenu)) {
948 $only = $action;
949 }
950 else {
951 drupal_goto('mysite/'. $owner->uid .'/edit/'. $page .'/'. key($submenu));
952 }
953
954 $output = theme('mysite_submenu', $submenu, $page, FALSE);
955 $output .= '<div class="mysite-mainmenu">';
956 $output .= '<h3>'. filter_xss_admin($submenu[$only]['label']) .'</h3>';
957 $output .= '<p>'. filter_xss_admin($submenu[$only]['help']) .'</p>';
958
959 // get any system messages waiting for this user
960 mysite_message($owner->uid);
961 if (!isset($edit['status'])) {
962 $edit['status'] = variable_get('mysite_private_status', 1);
963 }
964 if (empty($edit['theme'])) {
965 $edit['theme'] = variable_get('theme_default', 'garland');
966 }
967 if (empty($edit['layout'])) {
968 $edit['layout'] ='default';
969 }
970 if (empty($edit['style'])) {
971 $edit['style'] ='default';
972 }
973 if (empty($edit['format'])) {
974 $edit['format'] ='default';
975 }
976 if (empty($edit['title'])) {
977 $edit['title'] = $owner->name;
978 }
979 drupal_set_title(check_plain($edit['title']) .' : '. mysite_sitename());
980 $output .= drupal_get_form('mysite_edit_form', $edit, $page, $only);
981 $output .= '</div>';
982 print theme('page', $output, variable_get('mysite_fullscreen', 1));
983 }
984 else {
985 drupal_not_found();
986 return;
987 }
988 }
989
990 /**
991 * Page for adding content to a MySite page.
992 *
993 * @param $uid
994 * The user id of the owner of the mysite.
995 * @param $page
996 * The current page of the MySite collection.
997 * @param $type
998 * The type of content options to display.
999 */
1000 function mysite_content($uid = NULL, $page = 0, $type = NULL) {
1001 global $user;
1002 $submenu = mysite_content_menu();
1003 $check = FALSE;
1004
1005 // get the $owner of this MySite page, use as a $user surrogate
1006 $uid = arg(1);
1007 if (is_numeric($uid) && $uid > 0) {
1008 $owner = user_load(array('uid' => $uid));
1009 }
1010
1011 // Make sure the $type is valid and active.
1012 $type = arg(4);
1013 $allowed = variable_get('mysite_content', array());
1014 if ($type === $allowed[$type]) {
1015 $only = $type;
1016 }
1017 else {
1018 drupal_goto('mysite/'. $uid .'/content/'. $page);
1019 }
1020
1021 // set values if we are updating the admin settings
1022 if ($uid == 0 && user_access('administer mysite')) {
1023 $owner->uid = 0;
1024 $check = TRUE;
1025 }
1026
1027 // must have a valid uid to continue
1028 if ($owner->uid > 0 || $check) {
1029 // get any system messages waiting for this user
1030 mysite_message($owner->uid);
1031
1032 // create a new account, if needed.
1033 $mysite = mysite_get($owner->uid, TRUE);
1034 if (!isset($mysite->uid)) {
1035 $mysite = mysite_create_account($owner);
1036 }
1037
1038