1<?php 2/* 3 * Gallery - a web based photo album viewer and editor 4 * Copyright (C) 2000-2008 Bharat Mediratta 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or (at 9 * your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. 19 */ 20 21/** 22 * This controller will handle changing the order of items in an album. 23 * @package GalleryCore 24 * @subpackage UserInterface 25 * @author Bharat Mediratta <bharat@menalto.com> 26 * @version $Revision: 17580 $ 27 */ 28class ItemReorderController extends GalleryController { 29 30 /** 31 * @see GalleryController::handleRequest 32 */ 33 function handleRequest($form) { 34 global $gallery; 35 36 list ($ret, $item) = $this->getItem(); 37 if ($ret) { 38 return array($ret, null); 39 } 40 $itemId = $item->getId(); 41 42 /* Check permissions */ 43 $ret = GalleryCoreApi::assertHasItemPermission($itemId, 'core.edit'); 44 if ($ret) { 45 return array($ret, null); 46 } 47 48 $status = $error = array(); 49 if (isset($form['action']['reorder'])) { 50 51 /* Verify that we've got what we need */ 52 if (empty($form['selectedId'])) { 53 $error[] = 'form[error][selectedId][missing]'; 54 } 55 56 if (empty($form['targetId'])) { 57 $error[] = 'form[error][targetId][missing]'; 58 } 59 60 $before = 0; 61 if (empty($form['placement']) || $form['placement'] == 'before') { 62 $before = 1; 63 } 64 65 /* 66 * Make sure that the selectedId and targetId are children of the album 67 */ 68 if (empty($error)) { 69 $selectedId = (int)$form['selectedId']; 70 $targetId = (int)$form['targetId']; 71 list ($ret, $entities) = 72 GalleryCoreApi::loadEntitiesById(array($selectedId, $targetId), 'GalleryItem'); 73 if ($ret) { 74 return array($ret, null); 75 } 76 77 list ($ret, $permissions) = 78 GalleryCoreApi::fetchPermissionsForItems(array($selectedId, $targetId)); 79 if ($ret) { 80 return array($ret, null); 81 } 82 if (!isset($permissions[$selectedId]['core.view']) 83 || !isset($permissions[$selectedId]['core.view'])) { 84 /* Avoid information disclosure, act as if the items didn't exist. */ 85 return array(GalleryCoreApi::error(ERROR_MISSING_OBJECT), null); 86 } 87 88 if ($entities[0]->getParentId() != $itemId || 89 $entities[1]->getParentId() != $itemId) { 90 return array(GalleryCoreApi::error(ERROR_PERMISSION_DENIED), null); 91 } 92 } 93 94 if (empty($error)) { 95 $loopCount = 0; 96 while (true) { 97 /* 98 * Get the current and target order weights (have to do 99 * this after every rebalance, too) 100 */ 101 list ($ret, $orderWeights) = 102 GalleryCoreApi::fetchItemOrderWeights(array($selectedId, $targetId)); 103 if ($ret) { 104 return array($ret, null); 105 } 106 107 list ($ret, $next) = GalleryCoreApi::fetchNextItemWeight($targetId, 108 $before ? LOWER_WEIGHT : HIGHER_WEIGHT); 109 if ($ret) { 110 return array($ret, null); 111 } 112 113 if (isset($next)) { 114 /* Floor rounds down, so separate the sign and the magnitude */ 115 $delta = (int)(($next - $orderWeights[$targetId]) / 2); 116 } else { 117 /* 118 * We couldn't get a weight, which means that the 119 * target is at the edge. So go beyond the edge 120 */ 121 $delta = $before ? -1000 : 1000; 122 } 123 124 if (abs($delta) > 0) { 125 break; 126 } 127 128 if ($loopCount++ > 0) { 129 /* 130 * If we have to rebalance more than once then something went wrong! 131 */ 132 return array(GalleryCoreApi::error(ERROR_UNKNOWN), null); 133 } 134 135 /* A delta of 0 means that we don't have room, so rebalance */ 136 $ret = GalleryCoreApi::rebalanceChildOrderWeights($itemId); 137 if ($ret) { 138 return array($ret, null); 139 } 140 } 141 $newWeight = $orderWeights[$targetId] + $delta; 142 143 $ret = GalleryCoreApi::setItemOrderWeight($selectedId, $newWeight); 144 if ($ret) { 145 return array($ret, null); 146 } 147 148 $event = GalleryCoreApi::newEvent('Gallery::ItemOrder'); 149 $event->setData($itemId); 150 list ($ret) = GalleryCoreApi::postEvent($event); 151 if ($ret) { 152 return array($ret, null); 153 } 154 155 /* Redirect back to the same page so that we can do more reordering */ 156 $redirect['view'] = 'core.ItemAdmin'; 157 $redirect['subView'] = 'core.ItemReorder'; 158 $redirect['itemId'] = $itemId; 159 $status['saved'] = 1; 160 } 161 } else if (isset($form['action']['cancel'])) { 162 $redirect['return'] = true; 163 } 164 165 if (!empty($redirect)) { 166 $results['redirect'] = $redirect; 167 } else { 168 $results['delegate']['view'] = 'core.ItemAdmin'; 169 $results['delegate']['subView'] = 'core.ItemReorder'; 170 } 171 $results['status'] = $status; 172 $results['error'] = $error; 173 174 return array(null, $results); 175 } 176} 177 178/** 179 * This view will prompt for how to change the order of items in the album 180 */ 181class ItemReorderView extends GalleryView { 182 183 /** 184 * @see GalleryView::loadTemplate 185 */ 186 function loadTemplate(&$template, &$form) { 187 global $gallery; 188 189 /* itemId is the album where we want to move items from */ 190 list ($ret, $item) = $this->getItem(); 191 if ($ret) { 192 return array($ret, null); 193 } 194 $itemId = $item->getId(); 195 196 if ($form['formName'] == 'ItemReorder') { 197 /* No validation at the moment */ 198 } else { 199 /* First time around, load the form with item data */ 200 $form['formName'] = 'ItemReorder'; 201 } 202 203 $show = array(); 204 $ItemReorder = array(); 205 $orderBy = $item->getOrderBy(); 206 if (empty($orderBy)) { 207 list ($ret, $orderBy) = 208 GalleryCoreApi::getPluginParameter('module', 'core', 'default.orderBy'); 209 if ($ret) { 210 return array($ret, null); 211 } 212 } 213 if ($orderBy != 'orderWeight') { 214 $show['automaticOrderMessage'] = 1; 215 } else { 216 217 /* Get all peers that we can see */ 218 list ($ret, $peerIds) = GalleryCoreApi::fetchChildItemIds($item); 219 if ($ret) { 220 return array($ret, null); 221 } 222 223 /* Load all the peers */ 224 list ($ret, $peerItems) = GalleryCoreApi::loadEntitiesById($peerIds, 'GalleryItem'); 225 if ($ret) { 226 return array($ret, null); 227 } 228 229 /* Build our peers table */ 230 $peers = array(); 231 foreach ($peerItems as $peerItem) { 232 $peers[$peerItem->getId()] = (array)$peerItem; 233 if (GalleryUtilities::isA($peerItem, 'GalleryAlbumItem')) { 234 $peerTypes['album'][$peerItem->getId()] = 1; 235 } else { 236 $peerTypes['data'][$peerItem->getId()] = 1; 237 } 238 $peers[$peerItem->getId()]['selected'] = 239 isset($form['selectedIds'][$peerItem->getId()]); 240 } 241 $ItemReorder['peers'] = $peers; 242 $ItemReorder['peerTypes'] = $peerTypes; 243 } 244 245 $ItemReorder['show'] = $show; 246 247 $template->setVariable('ItemReorder', $ItemReorder); 248 $template->setVariable('controller', 'core.ItemReorder'); 249 return array(null, array('body' => 'modules/core/templates/ItemReorder.tpl')); 250 } 251 252 /** 253 * @see GalleryView::getViewDescription 254 */ 255 function getViewDescription() { 256 list ($ret, $core) = GalleryCoreApi::loadPlugin('module', 'core'); 257 if ($ret) { 258 return array($ret, null); 259 } 260 261 return array(null, $core->translate('reorder items')); 262 } 263} 264?> 265