3 * Copyright (c) Xerox Corporation, Codendi Team, 2001-2009. All rights reserved
4 * Copyright (C) 2011 Alain Peyrat - Alcatel-Lucent
6 * This file is a part of Codendi.
8 * Codendi is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * Codendi is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with Codendi. If not, see <http://www.gnu.org/licenses/>.
22 require_once('common/widget/WidgetLayout.class.php');
23 require_once('common/widget/Widget.class.php');
24 require_once $gfcommon.'include/preplugins.php';
28 * Manage layouts for users, groups and homepage
30 class WidgetLayoutManager {
31 const OWNER_TYPE_USER = 'u';
32 const OWNER_TYPE_GROUP = 'g';
33 const OWNER_TYPE_HOME = 'h';
38 * Display the default layout for the "owner". It my be the home page, the project summary page or /my/ page.
43 function displayLayout($owner_id, $owner_type) {
44 $sql = "SELECT * from owner_layouts where owner_id=$1 and owner_type=$2";
45 $res = db_query_params($sql,array($owner_id,$owner_type));
46 if($res && db_numrows($res)<1) {
47 if($owner_type==self::OWNER_TYPE_USER) {
48 $this->createDefaultLayoutForUser($owner_id);
49 $this->displayLayout($owner_id,$owner_type);
52 $this->createDefaultLayoutForProject($owner_id,1);
53 $this->displayLayout($owner_id,$owner_type);
58 FROM layouts AS l INNER JOIN owner_layouts AS o ON(l.id = o.layout_id)
59 WHERE o.owner_type = $1
63 $req = db_query_params($sql,array($owner_type,$owner_id));
64 if ($data = db_fetch_array($req)) {
65 $readonly = !$this->_currentUserCanUpdateLayout($owner_id, $owner_type);
67 // echo '<p class="customize"><a href="/widgets/widgets.php?owner='. $owner_type.$owner_id .'&layout_id='. $data['id'] .'">'. _("Customize") .'</a></p>';
68 // } else if ($owner_type === self::OWNER_TYPE_GROUP) {
71 $layout = new WidgetLayout($data['id'], $data['name'], $data['description'], $data['scope']);
72 $sql = 'SELECT * FROM layouts_rows WHERE layout_id = $1 ORDER BY rank';
73 $req_rows = db_query_params($sql,array($layout->id));
74 while ($data = db_fetch_array($req_rows)) {
75 $row = new WidgetLayout_Row($data['id'], $data['rank']);
76 $sql = 'SELECT * FROM layouts_rows_columns WHERE layout_row_id = $1';
77 $req_cols = db_query_params($sql,array($row->id));
78 while ($data = db_fetch_array($req_cols)) {
79 $col = new WidgetLayout_Row_Column($data['id'], $data['width']);
80 $sql = "SELECT * FROM layouts_contents WHERE owner_type = $1 AND owner_id = $2 AND column_id = $3 ORDER BY rank";
81 $req_content = db_query_params($sql,array($owner_type, $owner_id, $col->id));
82 while ($data = db_fetch_array($req_content)) {
83 $c = Widget::getInstance($data['name']);
84 if ($c && $c->isAvailable()) {
85 $c->loadContent($data['content_id']);
86 $col->add($c, $data['is_minimized'], $data['display_preferences']);
96 $layout->display($readonly, $owner_id, $owner_type);
102 * _currentUserCanUpdateLayout
104 * @return boolean true if the user dan uppdate the layout (add/remove widget, collapse, set preferences, ...)
108 function _currentUserCanUpdateLayout($owner_id, $owner_type) {
110 $request =& HTTPRequest::instance();
111 switch ($owner_type) {
112 case self::OWNER_TYPE_USER:
113 if (user_getid() == $owner_id) { //Current user can only update its own /my/ page
117 case self::OWNER_TYPE_GROUP:
118 if (UserManager::instance()->getCurrentUser()->is_super_user==true || user_ismember($request->get('group_id'), 'A')) { //Only project admin
122 case self::OWNER_TYPE_HOME:
131 * createDefaultLayoutForUser
133 * Create the first layout for the user and add some initial widgets:
139 * - MyMonitoredForums
140 * - and widgets of plugins if they want to listen to the event default_widgets_for_new_owner
142 * @param owner_id The id of the newly created user
144 function createDefaultLayoutForUser($owner_id) {
145 $owner_type = self::OWNER_TYPE_USER;
146 $sql = "INSERT INTO owner_layouts(layout_id, is_default, owner_id, owner_type) VALUES (1, 1, $1, $2)";
147 if (db_query_params($sql,array($owner_id,$owner_type))) {
149 $sql = "INSERT INTO layouts_contents(owner_id, owner_type, layout_id, column_id, name, rank) VALUES ";
151 $args[] = "($1, $2, 1, 1, 'myprojects', 0)";
152 $args[] = "($1, $2, 1, 1, 'mybookmarks', 1)";
153 $args[] = "($1, $2, 1, 1, 'mymonitoredforums', 2)";
154 $args[] = "($1, $2, 1, 1, 'mysurveys', 4)";
155 $args[] = "($1, $2, 1, 2, 'myartifacts', 0)";
156 $args[] = "($1, $2, 1, 2, 'mymonitoredfp', 1)";
158 foreach($args as $a) {
159 db_query_params($sql.$a,array($owner_id,$owner_type));
162 /* $em =& EventManager::instance();
164 $em->processEvent('default_widgets_for_new_owner', array('widgets' => &$widgets, 'owner_type' => $owner_type));
165 foreach($widgets as $widget) {
166 $sql .= ",($13, $14, 1, $15, $16, $17)";
173 * createDefaultLayoutForProject
175 * Create the first layout for a new project, based on its parent template.
176 * Add some widgets based also on its parent configuration and on its service configuration.
178 * @param group_id the id of the newly created project
179 * @param template_id the id of the project template
181 function createDefaultLayoutForProject($group_id, $template_id) {
182 $pm = ProjectManager::instance();
183 $project = $pm->getProject($group_id);
184 $sql = "INSERT INTO owner_layouts(layout_id, is_default, owner_id, owner_type)
185 SELECT layout_id, is_default, $1, owner_type
187 WHERE owner_type = $2
190 if (db_query_params($sql,array($group_id, self::OWNER_TYPE_GROUP,$template_id))) {
191 $sql = "SELECT layout_id, column_id, name, rank, is_minimized, is_removed, display_preferences, content_id
192 FROM layouts_contents
193 WHERE owner_type = $1
196 if ($req = db_query_params($sql,array( self::OWNER_TYPE_GROUP,$template_id))) {
197 while($data = db_fetch_array($req)) {
198 $w = Widget::getInstance($data['name']);
200 $w->setOwner($template_id, self::OWNER_TYPE_GROUP);
201 if ($w->canBeUsedByProject($project)) {
202 $content_id = $w->cloneContent($w->content_id, $group_id, self::OWNER_TYPE_GROUP);
203 $sql = "INSERT INTO layouts_contents(owner_id, owner_type, content_id, layout_id, column_id, name, rank, is_minimized, is_removed, display_preferences)
204 VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10);
206 db_query_params($sql,array($group_id , self::OWNER_TYPE_GROUP , $content_id , $data['layout_id'] , $data['column_id'] , $data['name'] , $data['rank'] , $data['is_minimized'] , $data['is_removed'] , $data['display_preferences'] ));
217 * displayAvailableWidgets
219 * Display all widget that the user can add to the layout
225 function displayAvailableWidgets($owner_id, $owner_type, $layout_id) {
226 $used_widgets = array();
228 FROM layouts_contents
229 WHERE owner_type = $1
232 AND content_id = 0 AND column_id <> 0";
233 $res = db_query_params($sql,array($owner_type,$owner_id,$layout_id));
234 while($data = db_fetch_array($res)) {
235 $used_widgets[] = $data['name'];
237 echo '<ul class="widget_toolbar">';
238 $url = "/widgets/widgets.php?owner=".HTTPRequest::instance()->get('owner').
239 "&layout_id=".HTTPRequest::instance()->get('layout_id');
241 if ($update_layout = HTTPRequest::instance()->get('update') == 'layout') {
242 echo '<li><a href="'. $url .'">'. _("Add widgets") .'</a></li>';
243 echo '<li class="current"><a href="'. $url.'&update=layout' .'">'. _("Customize layout") .'</a></li>';
246 echo '<li class="current"><a href="'. $url .'">'. _("Add widgets") .'</a></li>';
247 echo '<li><a href="'. $url.'&update=layout' .'">'. _("Customize layout") .'</a></li>';
251 echo '<form action="/widgets/updatelayout.php?owner='. $owner_type.$owner_id .'&action='. $action .'&layout_id='. $layout_id .'" method="post">';
252 if ($update_layout) {
253 $sql = "SELECT * FROM layouts WHERE scope='S' ORDER BY id ";
254 $req_layouts = db_query_params($sql,array());
255 echo '<table cellspacing="0" cellpadding="0">';
257 while ($data = db_fetch_array($req_layouts)) {
258 $checked = $layout_id == $data['id'] ? 'checked="checked"' : '';
259 $is_custom = $is_custom && !$checked;
260 echo '<tr class="layout-manager-chooser '. ($checked ? 'layout-manager-chooser_selected' : '') .'" ><td>';
261 echo '<input type="radio" name="layout_id" value="'. $data['id'] .'" id="layout_'. $data['id'] .'" '. $checked .'/>';
263 echo '<label for="layout_'. $data['id'] .'">';
264 echo html_image('layout/'. strtolower(preg_replace('/(\W+)/', '-', $data['name'])) .'.png');
267 echo '<label for="layout_'. $data['id'] .'"><strong>'. $data['name'] .'</strong><br />';
268 echo $data['description'];
272 /* Custom layout are not available yet */
273 $checked = $is_custom ? 'checked="checked"' : '';
274 echo '<tr class="layout-manager-chooser '. ($checked ? 'layout-manager-chooser_selected' : '') .'"><td>';
275 echo '<input type="radio" name="layout_id" value="-1" id="layout_custom" '. $checked .'/>';
277 echo '<label for="layout_custom">';
278 echo html_image('layout/custom.png', array('style' => 'vertical-align:top;float:left;'));
281 echo '<label for="layout_custom"><strong>'. 'Custom' .'</strong><br />';
282 echo 'Define your own layout:';
284 echo '<table id="layout-manager" cellpadding="0" cellspacing="0">
287 <div class="layout-manager-row-add">+</div>';
288 $sql = 'SELECT * FROM layouts_rows WHERE layout_id = $1 ORDER BY rank';
289 $req_rows = db_query_params($sql,array($layout_id));
290 while ($data = db_fetch_array($req_rows)) {
291 echo '<table class="layout-manager-row" cellspacing="5" cellpadding="2" border="0">
293 <td class="layout-manager-column-add">+</td>';
294 $sql = 'SELECT * FROM layouts_rows_columns WHERE layout_row_id = $1';
295 $req_cols = db_query_params($sql,array($data['id']));
296 while ($data = db_fetch_array($req_cols)) {
297 echo '<td class="layout-manager-column">
298 <div class="layout-manager-column-remove">x</div>
299 <div class="layout-manager-column-width">
300 <input type="text" value="'. $data['width'] .'" size="1" maxlength="3" />%
303 <td class="layout-manager-column-add">+</td>';
307 <div class="layout-manager-row-add">+</div>';
314 echo '<input type="submit" id="save" value="'. _("Submit") .'" />';
317 echo '<table cellpadding="0" cellspacing="0">
321 echo '<table cellpadding="2" cellspacing="0">
323 $after .= $this->_displayWidgetsSelectionForm(sprintf(_("%s Widgets"), forge_get_config('forge_name')), Widget::getCodendiWidgets($owner_type), $used_widgets);
327 <td id="widget-content-categ">'. $after .'</td>
335 function updateLayout($owner_id, $owner_type, $layout, $custom_layout) {
337 FROM layouts AS l INNER JOIN owner_layouts AS o ON(l.id = o.layout_id)
338 WHERE o.owner_type = $1
342 $req = db_query_params($sql,array($owner_type,$owner_id));
343 if ($data = db_fetch_array($req)) {
344 if ($this->_currentUserCanUpdateLayout($owner_id, $owner_type)) {
345 $old_scope = $data['scope'];
346 $old_layout_id = $data['id'];
347 $new_layout_id = null;
348 if ($layout == '-1' && is_array($custom_layout)) {
349 //Create a new layout based on the custom layout structure defined by the user
351 foreach($custom_layout as $widths) {
353 $cols = explode(',', $widths);
354 foreach($cols as $col) {
355 if ($width = (int)$col) {
363 //If the structure contains at least one column, create a new layout
365 $sql = "INSERT INTO layouts(name, description, scope)
366 VALUES ('custom', '', 'P')";
367 if ($res = db_query_params($sql,array())) {
368 if ($new_layout_id = db_insertid($res,'layouts', 'id')) {
369 //Create rows & columns
371 foreach($rows as $cols) {
372 $sql = "INSERT INTO layouts_rows(layout_id, rank)
374 if ($res = db_query_params($sql,array($new_layout_id,$rank++))) {
375 if ($row_id = db_insertid($res,'layouts_rows', 'id')) {
376 foreach($cols as $width) {
377 $sql = "INSERT INTO layouts_rows_columns(layout_row_id, width)
379 db_query_params($sql,array($row_id,$width));
388 $new_layout_id = $layout;
391 if ($new_layout_id) {
392 //Retrieve columns of old layout
393 $old = $this->_retrieveStructureOfLayout($old_layout_id);
395 //Retrieve columns of new layout
396 $new = $this->_retrieveStructureOfLayout($new_layout_id);
398 // Switch content from old columns to new columns
399 $last_new_col_id = null;
400 reset($new['columns']);
401 foreach($old['columns'] as $old_col) {
402 if (list(,$new_col) = each($new['columns'])) {
403 $last_new_col_id = $new_col['id'];
405 $sql = "UPDATE layouts_contents
412 db_query_params($sql,array($new_layout_id,$last_new_col_id,$owner_type,$owner_id,$old_layout_id,$old_col['id']));
414 $sql = "UPDATE owner_layouts
416 WHERE owner_type = $2
419 db_query_params($sql,array($new_layout_id,$owner_type,$owner_id,$old_layout_id));
421 //If the old layout is custom remove it
422 if ($old_scope != 'S') {
423 $structure = $this->_retrieveStructureOfLayout($old_layout_id);
424 foreach($structure['rows'] as $row) {
425 $sql = "DELETE FROM layouts_rows
427 db_query_params($sql,array($row['id']));
428 $sql = "DELETE FROM layouts_rows_columns
429 WHERE layout_row_id = $1";
430 db_query_params($sql,array($row['id']));
432 $sql = "DELETE FROM layouts
434 db_query_params($sql,array($old_layout_id));
440 $this->feedback($owner_id, $owner_type);
443 function _retrieveStructureOfLayout($layout_id) {
444 $structure = array('rows' => array(), 'columns' => array());
445 $sql = 'SELECT * FROM layouts_rows WHERE layout_id = $1 ORDER BY rank';
446 $req_rows = db_query_params($sql,array($layout_id));
447 while ($row = db_fetch_array($req_rows)) {
448 $structure['rows'][] = $row;
449 $sql = 'SELECT * FROM layouts_rows_columns WHERE layout_row_id =$1 ORDER BY id';
450 $req_cols = db_query_params($sql,array($row['id']));
451 while ($col = db_fetch_array($req_cols)) {
452 $structure['columns'][] = $col;
459 * _displayWidgetsSelectionForm
463 * @param used_widgets
465 function _displayWidgetsSelectionForm($title, $widgets, $used_widgets) {
466 $hp = Codendi_HTMLPurifier::instance();
467 $additionnal_html = '';
468 if (count($widgets)) {
469 echo '<tr><td colspan="2">';
470 $categs = $this->getCategories($widgets);
471 $widget_rows = array();
472 if (count($categs)) {
473 foreach($categs as $c => $ws) {
474 $widget_rows[$c] = '<a class="widget-categ-switcher" href="#widget-categ-'. $c .'"><span>'. str_replace('-',' ', $hp->purify($c, CODENDI_PURIFIER_CONVERT_HTML)) .'</span></a>';
476 uksort($widget_rows, 'strnatcasecmp');
477 echo '<ul id="widget-categories">';
478 foreach($widget_rows as $row) {
479 echo '<li>'. $row .'</li>';
485 foreach($widgets as $widget_name) {
486 if ($widget = Widget::getInstance($widget_name)) {
487 if ($widget->isAvailable()) {
489 $row .= '<td>'. $widget->getTitle() . $widget->getInstallPreferences() .'</td>';
490 $row .= '<td align="right">';
491 if ($widget->isUnique() && in_array($widget_name, $used_widgets)) {
492 $row .= '<em>'. _("Already used") .'</em>';
494 $row .= '<input type="submit" name="name['. $widget_name .'][add]" value="'. _("Add") .'" />';
497 $widget_rows[$widget->getTitle()] = $row;
502 foreach($widget_rows as $row) {
503 echo '<tr class="'. (count($widget_rows) ? '' : util_get_alt_row_color($i++)) .'">'. $row .'</tr>';
506 if (count($categs)) {
507 foreach($categs as $c => $ws) {
509 $widget_rows = array();
510 foreach($ws as $widget_name => $widget) {
512 $row .= '<div class="widget-preview '. $widget->getPreviewCssClass() .'">';
513 $row .= '<strong>'. $widget->getTitle() .'</strong>';
514 $row .= '<p>'. $widget->getDescription() .'</p>';
515 $row .= $widget->getInstallPreferences();
516 $row .= '</div><div style="text-align:right; border-bottom:1px solid #ddd; padding-bottom:10px; margin-bottom:20px;">';
517 if ($widget->isUnique() && in_array($widget_name, $used_widgets)) {
518 $row .= '<em>'. _("Already used") .'</em>';
520 $row .= '<input type="submit" name="name['. $widget_name .'][add]" value="'. _("Add") .'" />';
523 $widget_rows[$widget->getTitle()] = $row;
525 uksort($widget_rows, 'strnatcasecmp');
526 $additionnal_html .= '<div id="widget-categ-'. $c .'"><h4 class="boxtitle">'. $hp->purify($c, CODENDI_PURIFIER_CONVERT_HTML) .'</h4>';
527 foreach($widget_rows as $row) {
528 $additionnal_html .= $row;
530 $additionnal_html .= '</div>';
534 return $additionnal_html;
536 function getCategories($widgets) {
538 foreach($widgets as $widget_name) {
539 if ($widget = Widget::getInstance($widget_name)) {
540 if ($widget->isAvailable()) {
541 $cs = explode(',', $widget->getCategory());
544 if (!isset($categ[$c])) {
545 $categ[$c] = array();
547 $categ[$c][$widget_name] = $widget;
565 function addWidget($owner_id, $owner_type, $layout_id, $name, &$widget, &$request) {
566 //Search for the right column. (The first used)
567 $sql = "SELECT u.column_id AS id
568 FROM layouts_contents AS u
569 LEFT JOIN (SELECT r.rank AS rank, c.id as id
570 FROM layouts_rows AS r INNER JOIN layouts_rows_columns AS c
571 ON (c.layout_row_id = r.id)
572 WHERE r.layout_id = $1) AS col
573 ON (u.column_id = col.id)
574 WHERE u.owner_type = $2
578 ORDER BY col.rank, col.id";
579 $res = db_query_params($sql,array($layout_id,$owner_type,$owner_id,$layout_id));
581 $column_id = db_result($res, 0, 'id');
583 $sql = "SELECT r.rank AS rank, c.id as id
584 FROM layouts_rows AS r
585 INNER JOIN layouts_rows_columns AS c
586 ON (c.layout_row_id = r.id)
587 WHERE r.layout_id = $1
589 $res = db_query_params($sql,array($layout_id));
590 $column_id = db_result($res, 0, 'id');
594 if ($widget->isUnique()) {
595 //unique widgets do not have content_id
598 $content_id = $widget->create($request);
601 //See if it already exists but not used
602 $sql = "SELECT column_id FROM layouts_contents
607 $res = db_query_params($sql,array($owner_type,$owner_id,$layout_id, $name));
609 if (db_numrows($res) && !$widget->isUnique() && db_result($res, 0, 'column_id') == 0) {
611 $sql = "SELECT min(rank) - 1 AS rank FROM layouts_contents WHERE owner_type =$1 AND owner_id = $2 AND layout_id = $3 AND column_id = $4 ";
612 $res = db_query_params($sql,array($owner_type, $owner_id, $layout_id,$column_id));
614 $rank = db_result($res, 0, 'rank');
617 $sql = "UPDATE layouts_contents
618 SET column_id = $1, rank = $2
619 WHERE owner_type = $3
623 $res = db_query_params($sql,array($column_id,$rank,$owner_type, $owner_id,$name, $layout_id));
627 $sql = "INSERT INTO layouts_contents(owner_type, owner_id, layout_id, column_id, name, content_id, rank)
628 SELECT R1.owner_type, R1.owner_id, R1.layout_id, R1.column_id, $1, $2, coalesce(R2.rank, 1) - 1
629 FROM ( SELECT $3::character varying(1) AS owner_type, $4::integer AS owner_id, $5::integer AS layout_id, $6::integer AS column_id ) AS R1
630 LEFT JOIN layouts_contents AS R2 USING ( owner_type, owner_id, layout_id, column_id )
633 $myfile=fopen('/tmp/debug','a');
634 $params = array($name,$content_id,$owner_type,$owner_id,$layout_id,$column_id);
635 fwrite($myfile, $sql." devient:\n");
636 fwrite($myfile, str_replace(array("$1","$2","$3","$4","$5","$6"),$params,$sql));
637 fwrite($myfile, "\n request content=".$request->get('content_id'));
638 db_query_params($sql,array($name,$content_id,$owner_type,$owner_id,$layout_id,$column_id));
641 $this->feedback($owner_id, $owner_type);
644 protected function feedback($owner_id, $owner_type) {
646 if ($owner_type == self::OWNER_TYPE_GROUP) {
647 //retrieve the short name of the project
648 if ($project = ProjectManager::instance()->getProject($owner_id)) {
649 $hp = Codendi_HTMLPurifier::instance();
650 $link = '/projects/'. $hp->purify($project->getUnixName(), CODENDI_PURIFIER_CONVERT_HTML) ;
652 } else if ($owner_type == self::OWNER_TYPE_USER) {
655 $GLOBALS['feedback'] .= vsprintf(_('Your <a href="%s">dashboard</a> has been updated.'), $link);
667 function removeWidget($owner_id, $owner_type, $layout_id, $name, $instance_id, &$widget) {
668 $sql = "DELETE FROM layouts_contents WHERE owner_type =$1 AND owner_id = $2 AND layout_id = $3 AND name = $4 AND content_id = $5";
669 db_query_params($sql,array($owner_type,$owner_id,$layout_id,$name,$instance_id));
671 $widget->destroy($instance_id);
684 function mimizeWidget($owner_id, $owner_type, $layout_id, $name, $instance_id) {
685 $sql = "UPDATE layouts_contents SET is_minimized = 1 WHERE owner_type = $1 AND owner_id = $2 AND layout_id = $3 AND name = $4 AND content_id = $5";
686 db_query_params($sql,array($owner_type,$owner_id,$layout_id,$name,$instance_id));
699 function maximizeWidget($owner_id, $owner_type, $layout_id, $name, $instance_id) {
700 $sql = "UPDATE layouts_contents SET is_minimized = 0 WHERE owner_type =$1 AND owner_id =$2 AND layout_id = $3 AND name = $4 AND content_id = $5";
701 db_query_params($sql,array($owner_type,$owner_id,$layout_id,$name,$instance_id));
706 * displayWidgetPreferences
714 function displayWidgetPreferences($owner_id, $owner_type, $layout_id, $name, $instance_id) {
715 $sql = "UPDATE layouts_contents SET display_preferences = 1, is_minimized = 0 WHERE owner_type = $1 AND owner_id = $2 AND layout_id = $3 AND name = $4 AND content_id = $5";
716 db_query_params($sql,array($owner_type,$owner_id,$layout_id,$name,$instance_id));
721 * hideWidgetPreferences
729 function hideWidgetPreferences($owner_id, $owner_type, $layout_id, $name, $instance_id) {
730 $sql = "UPDATE layouts_contents SET display_preferences = 0 WHERE owner_type = $1 AND owner_id = $2 AND layout_id = $3 AND name = $4 AND content_id = $5";
731 db_query_params($sql,array($owner_type,$owner_id,$layout_id,$name,$instance_id));
744 function reorderLayout($owner_id, $owner_type, $layout_id, &$request) {
745 $keys = array_keys($_REQUEST);
746 foreach($keys as $key) {
747 if (preg_match('`widgetlayout_col_\d+`', $key)) {
750 $split = explode('_', $key);
751 $column_id = (int)$split[count($split)-1];
754 foreach($request->get($key) as $name) {
755 list($name, $id) = explode('-', $name);
756 $names[] = array($id, $name);
759 //Compute differences
760 $originals = array();
761 $sql = "SELECT * FROM layouts_contents WHERE owner_type = $1 AND owner_id = $2 AND column_id = $3 ORDER BY rank";
762 $res = db_query_params($sql,array($owner_type, $owner_id, $column_id));
764 while($data = db_fetch_array($res)) {
765 $originals[] = array($data['content_id'], $data['name']);
768 //delete removed contents
769 $deleted_names = $this->_array_diff_names($originals, $names);
770 if (count($deleted_names)) {
772 foreach($deleted_names as $id => $name) {
778 $_and .= " (name = '".$name[1]."' AND content_id = ". $name[0] .") ";
781 $sql = "UPDATE layouts_contents
783 WHERE owner_type = $1
787 $res = db_query_params($sql,array($owner_type, $owner_id, $column_id));
791 //Insert new contents
792 $added_names = $this->_array_diff_names($names, $originals);
793 if (count($added_names)) {
795 foreach($added_names as $name) {
801 $_and .= " (name = '".$name[1]."' AND content_id = ". $name[0] .") ";
804 //old and new column must be part of the same layout
805 $sql = 'UPDATE layouts_contents
807 WHERE owner_type = $2
811 $res = db_query_params($sql,array($column_id,$owner_type,$owner_id,$layout_id));
819 foreach($names as $name) {
820 $sql = 'UPDATE layouts_contents SET rank = $1 WHERE owner_type =$2 AND owner_id = $3 AND column_id = $4 AND name = $5 AND content_id = $6';
821 db_query_params($sql, array($rank++,$owner_type,$owner_id,$column_id,$name[1],$name[0]));
829 * compute the differences between two arrays
831 function _array_diff_names($tab1, $tab2) {
833 foreach($tab1 as $e1) {
836 while(!$found && list(,$e2) = each($tab2)) {
837 $found = !count(array_diff($e1, $e2));