Put overflow hidden and a fixed width on profile widgets to stop large img coming...
[elgg.git] / mod / widget / lib.php
blobb1e4f8c0c275c7218442dea0c36740b5d0d45246
1 <?php
3 /*
5 Elgg Widgets
6 http://elgg.org/
8 */
10 // Standard page setup function
12 function widget_pagesetup() {
17 // Initialisation function
19 function widget_init() {
21 global $CFG, $function, $db;
23 $function['init'][] = $CFG->dirroot . "mod/widget/init.php";
25 // register the widgets that this module provides
27 $CFG->widgets->list[] = array(
28 'name' => gettext("Text box"),
29 'description' => gettext("Displays the text of your choice."),
30 'type' => "widget::text"
33 $tables = $db->Metatables();
34 if (!in_array($CFG->prefix . "widget_data",$tables) || !in_array($CFG->prefix . "widgets",$tables)) {
35 if (file_exists($CFG->dirroot . "mod/widget/$CFG->dbtype.sql")) {
36 modify_database($CFG->dirroot . "mod/widget/$CFG->dbtype.sql");
37 } else {
38 error("Error: Your database ($CFG->dbtype) is not yet fully supported by the Elgg widgets. See the mod/widget directory.");
40 print_continue("index.php");
41 exit;
45 // Delete users
46 listen_for_event("user","delete","widget_user_delete");
49 // Get widgets for a particular user
51 function widget_for_user_sql($user_id,$location=NULL,$location_id=NULL,$column) {
52 global $CFG;
53 // Get access list for this user
54 $where = run("users:access_level_sql_where",$user_id);
56 $where2 = '';
58 // Get the sql to select a list of widgets
59 if (isset($location)) {
60 $where2 .= " AND location = '$location'";
62 if (isset($location_id)) {
63 $where2 .= " AND location_id = $location_id";
65 if (isset($column)) {
66 $where2 .= " AND wcolumn = $column";
69 $sql = "SELECT * FROM ".$CFG->prefix."widgets WHERE ($where) $where2 AND owner = $user_id ORDER BY display_order ASC";
71 return $sql;
74 function widget_for_user($user_id,$location='',$location_id=0,$column=NULL) {
76 $widgets = get_records_sql(widget_for_user_sql($user_id,$location,$location_id,$column));
78 // Return them
79 return $widgets;
83 function widget_for_user_count($user_id,$location=NULL,$location_id=NULL, $column=NULL) {
85 $count = get_record_sql('SELECT COUNT(*) as count FROM ('.widget_for_user_sql($user_id,$location,$location_id,$column).') AS q1');
87 return $count->count;
90 function widget_for_user_paginated($user_id,$location=NULL,$location_id=NULL,$column=NULL,$offset=0,$count=0) {
91 $widgets = get_records_sql(widget_for_user_sql($user_id,$location,$location_id,$column).sql_paging_limit($offset,$count));
93 // Return them
94 return $widgets;
97 // Gets data with a particular name for a particular widget ID
99 function widget_get_data($name, $ident) {
101 global $db, $CFG;
103 $value = get_record("widget_data", "name", $name, "widget", $ident);
104 if (!empty($value) && !empty($value->value)) {
105 $value = $value->value;
106 } else {
107 $value = '';
110 return $value;
114 // for compatibility - remove ASAP
116 function adash_get_data($name, $ident) {
117 return widget_get_data($name, $ident);
121 // Sets data with a particular name for a particular widget ID
123 function widget_set_data($name, $ident, $value) {
124 $data = new stdClass;
125 $data->name = $name;
126 $data->widget = $ident;
127 $data->value = $value;
128 if ($existing = widget_get_data($name,$ident)) {
129 $data->ident = $existing->ident;
130 return update_record('widget_data',$data);
131 } else {
132 return insert_record('widget_data',$data);
136 // Removes data for a particular widget ID
138 function widget_remove_data($ident) {
139 delete_records('widget_data','widget',$ident);
142 // Removes a widget
144 function widget_destroy($ident) {
145 if ($widget = get_record('widgets','ident',$ident)) {
146 if ($widget = plugin_hook("widget","delete",$widget)) {
147 delete_records('widgets','ident',$ident);
148 widget_remove_data($ident);
153 // Removes all widgets for a user
155 function widget_user_delete($object_type, $event, $object) {
156 global $CFG;
157 if (!empty($object->ident) && $object_type == "user" && $event == "delete") {
158 if ($widgets = get_records("widgets","owner",$object->ident)) {
159 foreach($widgets as $widget) {
160 widget_destroy($widget->ident);
164 return $object;
167 // Creates a widget
169 function widget_create($location,$location_id,$column,$type,$owner=0,$access='PUBLIC',$display_order=0) {
171 $widget = new stdClass;
172 if ($owner) {
173 $widget->owner = $owner;
174 } else {
175 $widget->owner = $_SESSION['userid'];
177 $widget->type = $type;
178 $widget->location = $location;
179 $widget->location_id = $location_id;
180 $widget->wcolumn = $column;
181 $widget->access = $access;
182 $widget->display_order = $display_order;
183 $id = insert_record('widgets',$widget);
184 widget_reorder($widget->owner,$widget->location,$widget->location_id);
186 return $id;
189 // generates the query information to ensure that a widget function returns to a display
190 // page with the correct information
192 function widget_get_display_query() {
193 $q = '';
194 $params = array_merge($_GET,$_POST);
195 if ($params) {
196 foreach($params as $k => $v) {
197 if ((strpos($k,'_widget') !== 0) && (strpos($k,'widget_data') !== 0) && $k != 'wid') {
198 $q .= '&amp;'.$k .'='.$v;
202 if ($q) {
203 $q = substr($q,1);
205 return $q;
208 function widget_get_non_display_query() {
209 $q = '';
210 if ($_GET) {
211 foreach($_GET as $k => $v) {
212 if (strpos($k,'_dwidget') !== 0) {
213 $q .= '&amp;'.$k .'='.$v;
217 if ($q) {
218 $q = substr($q,1);
220 return $q;
223 // asks the appropriate module what URL is used to display this widget
225 function widget_get_display_url($module) {
226 $redirect_url = '';
227 $module_widget_display_url = $module . '_widget_display_url';
228 if ($module && function_exists($module_widget_display_url)) {
229 $redirect_url = $module_widget_display_url();
231 return $redirect_url;
235 // Returns HTML for a particular widget
236 // (Assumes a widget object taken from the database)
238 function widget_display($widget,$collapsed=0) {
240 global $CFG;
241 global $PAGE;
243 $widget_menu_template = '<div class="widget_menu">%s</div>';
245 $widget_template = <<<END
246 <div class="widget_title">%s</div>
248 <div class="widget_content">
250 </div>
251 <div class="widget_bottom">
252 </div>
253 END;
255 $body = '';
256 $title = '';
258 // get module from the widget type
259 $module = '';
260 $mod_pos = strpos($widget->type,"::");
261 if ($mod_pos) {
262 $module = substr($widget->type,0,$mod_pos);
265 // If the handler for displaying this particular widget type exists,
266 // run it - otherwise display nothing
268 if ($collapsed) {
269 $mod_widget_display = $module . '_widget_display_collapsed';
270 } else {
271 $mod_widget_display = $module . '_widget_display';
273 if ($module && function_exists($mod_widget_display)) {
274 $widget_array = $mod_widget_display($widget);
275 if (isset($widget_array['content'])) {
276 $body = $widget_array['content'];
277 } else {
278 $body = '';
280 if (isset($widget_array['title'])) {
281 $title = $widget_array['title'];
282 } else {
283 $title = '';
285 if (isset($widget_array['menu'])) {
286 $menu = $widget_array['menu'];
287 } else {
288 $menu = array();
290 } else {
291 $result = '';
292 $title = '';
293 $menu = array();
294 if (!empty($CFG->widgets->display[$widget->type])) {
295 $body = $CFG->widgets->display[$widget->type]($widget);
296 } else {
297 $body = "";
300 if ($menu) {
301 // menu generation goes here
302 $menu_html = '<ul>'."\n";
303 foreach ($menu as $menu_item) {
304 $menu_html .= '<li><a alt="'.$menu_item['title'].'" title="'.$menu_item['title'].'" href="'.$menu_item['link'].'">'.$menu_item['text'].'</a></li>'."\n";
306 $menu_html .= '</ul>'."\n";
309 if (!empty($menu_html)) {
310 $menu_bit = sprintf($widget_menu_template,$menu_html);
311 } else {
312 $menu_bit = '';
315 $body = sprintf($widget_template,$title,$menu_bit,$body);
317 // If we have permission, display edit buttons
319 if (isloggedin() && run("permissions:check","profile")) {
321 $q = widget_get_display_query($widget);
323 // print("widget_get_display_query: $q");
324 $edit_msg = gettext("Edit widget");
325 $delete_msg = gettext("Delete widget");
326 $moveup_msg = gettext("Move up");
327 $movedown_msg = gettext("Move down");
328 $moveright_msg = gettext("Move right");
329 $moveleft_msg = gettext("Move left");
330 $img_template = '<img border="0" width="16" height="16" alt="%s" title="%s" src="'.$CFG->wwwroot.'mod/widget/images/%s" />';
331 $edit_img = sprintf($img_template,$edit_msg,$edit_msg,"16-em-pencil.png");
332 $delete_img = sprintf($img_template,$delete_msg,$delete_msg,"16-em-cross.png");
333 $moveup_img = sprintf($img_template,$moveup_msg,$moveup_msg,"16-em-open.png");
334 $movedown_img = sprintf($img_template,$movedown_msg,$movedown_msg,"16-em-down.png");
335 $moveright_img = sprintf($img_template,$moveright_msg,$moveright_msg,"16-em-right.png");
336 $moveleft_img = sprintf($img_template,$moveleft_msg,$moveleft_msg,"16-em-left.png");
338 $body .= "<div class=\"widget_admin_menu\">";
339 $body .= "<a href=\"" . $CFG->wwwroot . "mod/widget/edit.php?wid=" . $widget->ident . "&amp;" . $q . "\">" . $edit_img . "</a> ";
340 $body .= "<a href=\"" . $CFG->wwwroot . "mod/widget/delete.php?wid=" . $widget->ident . "&amp;" . $q . "\">" . $delete_img . "</a> ";
342 if (empty($CFG->uses_YUI)) {
343 $body .= "<a href=\"" . $CFG->wwwroot . "mod/widget/move.php?_widget_move=up&amp;wid=" . $widget->ident . "&amp;" . $q . "\">" . $moveup_img . "</a> ";
344 $body .= "<a href=\"" . $CFG->wwwroot . "mod/widget/move.php?_widget_move=down&amp;wid=" . $widget->ident . "&amp;" . $q . "\">" . $movedown_img . "</a> ";
345 if ($widget->wcolumn == 0) {
346 $body .= "<a href=\"" . $CFG->wwwroot . "mod/widget/move.php?_widget_move=2&amp;wid=" . $widget->ident . "&amp;" . $q . "\">" . $moveright_img . "</a> ";
347 } else {
348 $body .= "<a href=\"" . $CFG->wwwroot . "mod/widget/move.php?_widget_move=1&amp;wid=" . $widget->ident . "&amp;" . $q . "\">" . $moveleft_img . "</a> ";
352 $body .= "</div>";
355 // Return HTML
357 return $body;
361 // Create a pagination line with links to first, previous, next and last widgets
363 function widget_get_paginator($url,$owner,$location,$location_id,$offset,$count,$total,$collapsed) {
364 // print("In widget_get_paginator: offset: $offset, count: $count, total: $total\n");
365 $search_template = gettext("Showing %s to %s of %s results");
366 $q = widget_get_non_display_query();
367 if ($q) {
368 $q .= '&amp;';
370 $query_string = "{$q}_dwidget_collapsed=$collapsed&amp;_dwidget_count=$count&amp;_dwidget_total=$total&amp;_dwidget_location=$location&amp;_dwidget_location_id=$location_id&amp;_dwidget_owner=$owner";
371 $paging_url ="$url?$query_string&amp;_dwidget_offset=";
372 $start_paging_link = '<a href="'.$paging_url.'0#results"><b>&lt;&lt;</b></a>';
373 if ($count > $total) {
374 $end_paging_link = '<a href="'.$paging_url.'0#results"><b>&gt;&gt;</b></a>';
375 } else {
376 $end_paging_link = '<b><a href="'.$paging_url.($total-$count).'#results">&gt;&gt;</a></b>';
379 if ($offset + $count < $total) {
380 $new_offset = $offset+$count;
381 $report = sprintf($search_template,$offset+1,$new_offset,$total);
382 $next_link = '<a href="'."$url?$query_string&amp;_dwidget_offset=".($new_offset).'#results">';
383 // $next_link .= gettext('Next');
384 $next_link .= '&gt;</a>';
385 } else {
386 $report = sprintf($search_template,$offset+1,$total,$total);
387 $next_link = '&gt;';
389 if ($offset > 0) {
390 $new_offset = $offset - $count;
391 if ($new_offset < 0) {
392 $new_offset = 0;
394 $previous_link = '<a href="'."$url?$query_string&amp;_dwidget_offset=".($new_offset).'#results">';
395 // $previous_link .= gettext('Previous');
396 $previous_link .= '&lt;</a>';
397 } else {
398 $previous_link = '&lt;';
401 $paging_style = <<<END
402 <style type="text/css">
403 .paging_widget {
404 width:430px;
405 text-align: center;
407 .paging_widget a {
408 font-weight: bold;
409 text-decoration: underline;
411 </style>
412 END;
414 $pagination = "<div class=\"paging_widget\"><p>$start_paging_link $previous_link $report $next_link $end_paging_link</p></div>";
415 return $pagination;
418 // Returns HTML that displays all widgets belonging to a particular user, in the current order
419 // Optionally these widgets can be restricted to a particular location and location_id, displayed
420 // in columns, paginated and/or the widgets collapsed (restricted to one line)
422 function widget_page_display($owner=0,$location='',$location_id=0,$columns=1,$count=0,$collapsed=0) {
423 if (!$owner) {
424 $owner = $_SESSION['userid'];
426 $offset = optional_param('_dwidget_offset',0,PARAM_INT);
427 $total = optional_param('_dwidget_total',0,PARAM_INT);
428 // print("In widget_page_display: offset: $offset, count: $count, total: $total\n");
429 $html = '';
430 if ($count) {
431 // handle pagination
432 if (!$total) {
433 $total = widget_for_user_count($owner,$location, $location_id);
435 $widgets = widget_for_user_paginated($owner,$location, $location_id,NULL,$offset,$count);
436 if ($widgets) {
437 $paginator = widget_get_paginator(widget_get_display_url($location),$owner,$location, $location_id,$offset,$count,$total,$collapsed);
438 $html .= $paginator;
439 $html .= widget_get_html($widgets,$columns,$collapsed);
441 $html .= $paginator;
442 } else {
443 $widgets = widget_for_user($owner,$location, $location_id);
444 if ($widgets) {
445 $html .= widget_get_html($widgets,$columns,$collapsed);
448 return $html;
451 function widget_get_html($widgets,$columns,$collapsed) {
452 if ($columns) {
453 $i = 0;
454 $html_odd = '';
455 $html_even = '';
456 $html = '';
457 foreach ($widgets as $widget) {
458 if ($widget->wcolumn == 0) {
459 $html_even .= "\n".'<div class="widget">';
460 $html_even .= widget_display($widget,$collapsed);
461 $html_even .= '</div>';
462 } elseif ($widget->wcolumn == 1) {
463 $html_odd .= "\n".'<div class="widget">';
464 $html_odd .= widget_display($widget,$collapsed);
465 $html_odd .= '</div>';
467 $i++;
469 $html = '<div class="widgets_even">'."\n".$html_even."\n".'</div>'."\n".'<div class="widgets_odd">'."\n".$html_odd."\n".'</div>'."\n";
470 } else {
471 foreach ($widgets as $widget) {
472 $html .= "\n".'<div class="widget">';
473 $html .= widget_display($widget,$collapsed);
474 $html .= '</div>';
477 return $html;
483 // Reorders widgets for a particular user, location and column
485 function widget_reorder($owner,$location=NULL,$location_id=NULL,$column=NULL) {
487 $widgets = widget_for_user($owner,$location,$location_id,$column);
488 if (is_array($widgets) && !empty($widgets)) {
489 $order = array();
490 $i = 1;
491 foreach($widgets as $widget) {
492 $order[$widget->ident] = $i * 10;
493 $i++;
495 foreach($order as $ident => $display_order) {
496 $widget = new StdClass;
497 $widget->display_order = $display_order;
498 $widget->ident = $ident;
499 update_record('widgets',$widget);
505 // Move a widget up
506 function widget_moveup($widget) {
507 $widget->display_order = $widget->display_order - 11;
508 update_record('widgets',$widget);
509 widget_reorder($widget->owner,$widget->location,$widget->location_id,$widget->wcolumn);
512 // Move a widget down
513 function widget_movedown($widget) {
514 $widget->display_order = $widget->display_order + 11;
515 update_record('widgets',$widget);
516 widget_reorder($widget->owner,$widget->location,$widget->location_id,$widget->wcolumn);
519 // move a widget to specified column and before the specified position
521 function widget_move_before($widget,$display_order,$column) {
522 $widget->display_order = $display_order - 1;
523 $widget->wcolumn = $column;
524 update_record('widgets',$widget);
525 widget_reorder($widget->owner,$widget->location,$widget->location_id,$widget->wcolumn);
528 // move a widget to specified column and after the specified position
530 function widget_move_after($widget,$display_order,$column) {
531 $widget->display_order = $display_order + 1;
532 $widget->wcolumn = $column;
533 update_record('widgets',$widget);
534 widget_reorder($widget->owner,$widget->location,$widget->location_id,$widget->wcolumn);
538 function widget_finish_edit_form($widget,$body,$ajax=0) {
540 global $CFG;
542 $access_bit = '<br />'.gettext("Access: ") . run("display:access_level_select",array("_widget_access",$widget->access));
543 if ($ajax) {
544 $form = "<form id=\"widget_edit_form\" method=\"post\">\n" . $body;
545 $form .= "<input type=\"hidden\" name=\"_widget_action\" value=\"widget:save:ajax\" />\n";
546 } else {
547 $form = "<form action=\"" . $CFG->wwwroot . "mod/widget/edit.php\" method=\"post\">\n" . $body;
548 $form .= "<input type=\"hidden\" name=\"_widget_action\" value=\"widget:save\" />\n";
551 $form .= $access_bit;
553 $form .= "<input type=\"hidden\" name=\"wid\" value=\"" . $widget->ident . "\" />\n";
555 // need to pass this information to the edit form so it redirects to the correct display page
556 $params = array_merge($_GET,$_POST);
557 if ($params) {
558 foreach($params as $k => $v) {
559 if (strpos($k,'_widget') !== 0 && $k != 'wid') {
560 $form .= "<input type=\"hidden\" name=\"$k\" value=\"" . $v . "\" />\n";
565 return $form;
568 // Returns HTML for the edit screen on a particular widget
569 // (Assumes a widget object taken from the database)
571 function widget_edit($widget,$ajax=0) {
573 global $CFG;
574 global $PAGE;
576 // If the handler for displaying this particular widget type exists,
577 // run it - otherwise display nothing
579 $body = '';
581 // get module from the widget type
582 $module = '';
583 $mod_pos = strpos($widget->type,"::");
584 if ($mod_pos) {
585 $module = substr($widget->type,0,$mod_pos);
588 //print 'module:'.$module;
590 if (isloggedin() && run("permissions:check","profile")) {
592 $mod_widget_edit = $module . '_widget_edit';
593 if ($module && function_exists($mod_widget_edit)) {
594 $body = $mod_widget_edit($widget);
595 } else {
596 if (!empty($CFG->widgets->edit[$widget->type])) {
597 $body = $CFG->widgets->edit[$widget->type]($widget);
598 } else {
599 $body = "";
603 // Stick it in an appropriate form for saving
604 $body = widget_finish_edit_form($widget,$body,$ajax);
605 if ($ajax) {
606 $body .= "<input type=\"button\" onClick=\"javascript:handle_widget_edit();return true;\" value=\"" . gettext("Save widget") . "\" />";
607 } else {
608 $body .= "<input type=\"submit\" value=\"" . gettext("Save widget") . "\" />";
610 $body .= "</p>\n</form>\n";
611 // Return HTML
612 return $body;
616 // Functions to display and edit plain text widgets
618 function widget_widget_display($widget) {
619 switch($widget->type) {
620 case 'widget::text':
621 return widget_text_widget_display($widget);
622 break;
626 function widget_widget_edit($widget) {
627 switch($widget->type) {
628 case 'widget::text':
629 return widget_text_widget_edit($widget);
630 break;
634 function widget_text_widget_display($widget) {
636 global $CFG;
638 $text_title = widget_get_data("widget_text_title",$widget->ident);
639 $text_body = widget_get_data("widget_text_body",$widget->ident);
641 if (empty($text_body)) {
642 $text_body = gettext("This text box is undefined. If you are the widget owner, click 'edit widget' to add your own content.");
645 $body = "<p>" . nl2br($text_body) . "</p>";
647 return array('title'=>$text_title,'content'=>$body);
651 function widget_text_widget_edit($widget) {
653 global $CFG, $page_owner;
655 $widget_text_title = widget_get_data("widget_text_title",$widget->ident);
656 $widget_text_body = widget_get_data("widget_text_body",$widget->ident);
659 $body = "<h2>" . gettext("Text box") . "</h2>";
660 $body .= "<p>" . gettext("This widget displays the text content of your choice. All you need to do is enter the title and body below:") . "</p>";
662 $body .= "<p>" . display_input_field(array("widget_data[widget_text_title]",$widget_text_title,"text")) . "</p>";
663 $body .= "<p>" . display_input_field(array("widget_data[widget_text_body]",$widget_text_body,"longtext")) . "</p>";
665 return $body;