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 * Gallery core module. 23 * @package GalleryCore 24 * @author Bharat Mediratta <bharat@menalto.com> 25 * @version $Revision: 20996 $ 26 */ 27class CoreModule extends GalleryModule { 28 29 function CoreModule() { 30 global $gallery; 31 32 $this->setId('core'); 33 $this->setName($gallery->i18n('Core')); 34 $this->setGalleryVersion('2.3.2'); 35 36 /* Don't forget to update CoreModuleExtras::upgrade and _prepareConfigUpgrade too! */ 37 $this->setVersion('1.3.0.2'); 38 $this->_templateVersion = 1; 39 40 $this->setDescription($gallery->i18n('Gallery 2 Core Module')); 41 $this->setGroup('gallery', $gallery->i18n('Gallery')); 42 $this->setCallbacks( 43 'getItemLinks|getSystemLinks|getItemAdminViews|getSiteAdminViews|getUserAdminViews'); 44 $this->setRequiredCoreApi(array(7, 53)); 45 $this->setRequiredModuleApi(array(3, 8)); 46 } 47 48 /** 49 * @see GalleryModule::getItemLinks 50 */ 51 function getItemLinks($items, $wantsDetailedLinks, $permissions, $userId) { 52 global $gallery; 53 $urlGenerator =& $gallery->getUrlGenerator(); 54 55 list ($ret, $rootId) = GalleryCoreApi::getPluginParameter('module', 'core', 'id.rootAlbum'); 56 if ($ret) { 57 return array($ret, null); 58 } 59 60 /* Fetch child counts */ 61 $itemIds = array(); 62 foreach ($items as $item) { 63 $itemIds[] = $item->getId(); 64 } 65 66 /* 67 * We're not doing this as the acting user id, but that's OK because we're not displaying 68 * the result; we're only using it as a gating factor for whether or not we show a link, and 69 * that'll also be gated by the permissions we receive which *will* be for the acting user. 70 */ 71 list ($ret, $childCounts) = GalleryCoreApi::fetchChildCounts($itemIds); 72 if ($ret) { 73 return array($ret, null); 74 } 75 76 /* Fetch thumbnail ids */ 77 list ($ret, $thumbTable) = GalleryCoreApi::fetchThumbnailsByItemIds($itemIds); 78 if ($ret) { 79 return array($ret, null); 80 } 81 82 $links = array(); 83 foreach ($items as $item) { 84 $itemId = $item->getId(); 85 $isRoot = ($itemId == $rootId); 86 $isAlbum = $item->getCanContainChildren(); 87 88 /* Permissions for its parent */ 89 list ($ret, $parentPermissions) = 90 GalleryCoreApi::getPermissions($item->getParentId(), $userId); 91 if ($ret) { 92 return array($ret, null); 93 } 94 95 if (isset($wantsDetailedLinks[$itemId]) && $isAlbum && 96 isset($permissions[$itemId]['core.addDataItem'])) { 97 $links[$itemId][] = 98 array('text' => $this->_translate('Add Items'), 99 'params' => array('view' => 'core.ItemAdmin', 100 'subView' => 'core.ItemAdd', 101 'itemId' => $itemId, 102 'return' => 1)); 103 } 104 105 $itemTypeNames = array_merge($item->itemTypeName(), $item->itemTypeName(false)); 106 if (isset($permissions[$itemId]['core.edit'])) { 107 if (false) { 108 /* Specific translations: */ _('Edit Album'); _('Edit Photo'); _('Edit Movie'); 109 } 110 $links[$itemId][] = 111 array('text' => $this->_translate( 112 array('text' => 'Edit %s', 'arg1' => $itemTypeNames[0]), 113 $itemTypeNames[2]), 114 'params' => array('view' => 'core.ItemAdmin', 115 'subView' => 'core.ItemEdit', 116 'itemId' => $itemId, 117 'return' => 1)); 118 } 119 120 if (isset($wantsDetailedLinks[$itemId]) && $isAlbum 121 && isset($permissions[$itemId]['core.addAlbumItem'])) { 122 $links[$itemId][] = 123 array('text' => $this->_translate('Add Album'), 124 'params' => array('view' => 'core.ItemAdmin', 125 'subView' => 'core.ItemAddAlbum', 126 'itemId' => $itemId, 127 'return' => 1)); 128 } 129 130 if (isset($permissions[$itemId]['core.edit'])) { 131 $links[$itemId][] = 132 array('text' => isset($permissions[$itemId]['core.changePermissions']) 133 ? $this->_translate('Edit Permissions') 134 : $this->_translate('View Permissions'), 135 'params' => array('view' => 'core.ItemAdmin', 136 'subView' => 'core.ItemPermissions', 137 'itemId' => $itemId, 138 'return' => 1)); 139 } 140 141 if (!$isRoot && isset($permissions[$itemId]['core.delete'])) { 142 if (false) { 143 /* Specific translations: */ 144 _('Delete Album'); _('Delete Photo'); _('Delete Movie'); 145 } 146 if (!function_exists('smarty_modifier_escape')) { 147 GalleryCoreApi::requireOnce('lib/smarty/plugins/modifier.escape.php'); 148 } 149 $title = smarty_modifier_escape(GalleryUtilities::markup( 150 $item->getTitle(), 'strip'), 'javascript', 'UTF-8'); 151 list ($thisItemId, $page) = GalleryUtilities::getRequestVariables('itemId', 'page'); 152 /* If no page item defined, we will navigate to the parent of the deleted item */ 153 if (empty($thisItemId)) { 154 $thisItemId = $itemId; 155 } 156 $urlParams = array('controller' => 'core.ItemDeleteSingle', 'itemId' => $itemId, 157 'pageId' => $thisItemId); 158 if (!empty($page)) { 159 $urlParams['page'] = $page; 160 } 161 $url = $urlGenerator->generateUrl($urlParams); 162 $moreUrl = $isAlbum ? '' : $urlGenerator->generateUrl( 163 array('view' => 'core.ItemAdmin', 'subView' => 'core.ItemDelete', 164 'itemId' => $item->getParentId(), 165 'selectedId' => $itemId, 'return' => 1)); 166 $links[$itemId][] = 167 array('text' => $this->_translate( 168 array('text' => 'Delete %s', 'arg1' => $itemTypeNames[0]), 169 $itemTypeNames[2]), 170 /* Params are for g->linkId used by icons, or themes ignoring 'script' */ 171 'params' => array('view' => 'core.ItemAdmin', 172 'subView' => 'core.ItemDelete', 173 'itemId' => $item->getParentId(), 174 'selectedId' => $itemId), 175 'script' => "core_confirmDelete('$url', '$moreUrl', '$title')"); 176 } 177 178 if (!$isRoot && isset($permissions[$itemId]['core.delete'])) { 179 if (false) { 180 /* Specific translations: */ _('Move Album'); _('Move Photo'); _('Move Movie'); 181 } 182 $links[$itemId][] = 183 array('text' => $this->_translate( 184 array('text' => 'Move %s', 'arg1' => $itemTypeNames[0]), 185 $itemTypeNames[2]), 186 'params' => array('view' => 'core.ItemAdmin', 187 'subView' => 'core.ItemMove', 188 'itemId' => $item->getParentId(), 189 'selectedId' => $itemId, 190 'return' => 1)); 191 } 192 193 if (isset($wantsDetailedLinks[$itemId]) && $isAlbum 194 && isset($permissions[$itemId]['core.edit']) && !empty($childCounts[$itemId]) 195 && $childCounts[$itemId] > 0) { 196 $link = array('text' => $this->_translate('Edit Captions'), 197 'params' => array('view' => 'core.ItemAdmin', 198 'subView' => 'core.ItemEditCaptions', 199 'itemId' => $itemId, 200 'return' => 1)); 201 list ($thisItemId, $thisPage) = 202 GalleryUtilities::getRequestVariables('itemId', 'page'); 203 if (!empty($thisItemId) && !empty($thisPage) && $thisItemId == $item->getId()) { 204 $link['params']['albumPage'] = $thisPage; 205 } 206 $links[$itemId][] = $link; 207 } 208 209 if (!$isRoot && isset($thumbTable[$itemId]) && isset($parentPermissions['core.edit'])) { 210 $links[$itemId][] = 211 array('text' => $this->_translate('Make Highlight'), 212 'params' => array('view' => 'core.ItemAdmin', 213 'subView' => 'core.ItemMakeHighlight', 214 'itemId' => $itemId, 215 'return' => 1)); 216 } 217 218 if ($isAlbum && isset($permissions[$itemId]['core.edit']) 219 && !empty($childCounts[$itemId]) && $childCounts[$itemId] > 1) { 220 $links[$itemId][] = 221 array('text' => $this->_translate('Reorder Items'), 222 'params' => array('view' => 'core.ItemAdmin', 223 'subView' => 'core.ItemReorder', 224 'itemId' => $itemId, 225 'return' => 1)); 226 } 227 228 if (isset($wantsDetailedLinks[$itemId]) && $isAlbum 229 && isset($permissions[$itemId]['core.edit']) && !empty($childCounts[$itemId]) 230 && $childCounts[$itemId] > 0) { 231 $next = next($items); 232 $params = array('view' => 'core.ItemAdmin', 233 'subView' => 'core.ItemDelete', 234 'itemId' => $itemId, 235 'return' => 1); 236 /* First item on the page will be in the list for deletion */ 237 if ($next) { 238 $params['anchorId'] = $next->getId(); 239 } 240 241 $links[$itemId][] = array('text' => $this->_translate('Delete Items'), 242 'params' => $params); 243 } 244 } 245 246 return array(null, $links); 247 } 248 249 /** 250 * @see GalleryModule::getSystemLinks 251 */ 252 function getSystemLinks() { 253 global $gallery; 254 255 list ($ret, $param) = GalleryCoreApi::fetchAllPluginParameters('module', 'core'); 256 if ($ret) { 257 return array($ret, null); 258 } 259 260 $links = array(); 261 list ($ret, $isAdmin) = GalleryCoreApi::isUserInSiteAdminGroup(); 262 if ($ret) { 263 return array($ret, null); 264 } 265 266 if ($isAdmin) { 267 $links['SiteAdmin'] = array('text' => $this->translate('Site Admin'), 268 'params' => array('view' => 'core.SiteAdmin', 269 'return' => 1)); 270 } 271 272 if ($gallery->getConfig('login')) { 273 list ($ret, $isAnonymous) = GalleryCoreApi::isAnonymousUser(); 274 if ($ret) { 275 return array($ret, null); 276 } 277 if ($isAnonymous) { 278 $links['Login'] = array('text' => $this->translate('Login'), 279 'params' => array('view' => 'core.UserAdmin', 280 'subView' => 'core.UserLogin', 281 'return' => 1)); 282 } else { 283 $user = $gallery->getActiveUser(); 284 $links['YourAccount'] = array('text' => $this->translate('Your Account'), 285 'params' => array('view' => 'core.UserAdmin', 286 'subView' => 'core.UserPreferences', 287 'return' => 1)); 288 $links['Logout'] = array('text' => $this->translate('Logout'), 289 'params' => array('controller' => 'core.Logout', 290 'return' => 1)); 291 } 292 } 293 294 return array(null, $links); 295 } 296 297 /** 298 * @see GalleryModule::getSiteAdminViews 299 */ 300 function getSiteAdminViews() { 301 $data = array(array('name' => $this->translate('General'), 302 'view' => 'core.AdminCore'), 303 array('name' => $this->translate('Plugins'), 304 'view' => 'core.AdminPlugins'), 305 array('name' => $this->translate('Users'), 306 'view' => 'core.AdminUsers'), 307 array('name' => $this->translate('Groups'), 308 'view' => 'core.AdminGroups'), 309 array('name' => $this->translate('Maintenance'), 310 'view' => 'core.AdminMaintenance'), 311 array('name' => $this->translate('Themes'), 312 'view' => 'core.AdminThemes'), 313 array('name' => $this->translate('Performance'), 314 'view' => 'core.AdminPerformance'), 315 array('name' => $this->translate('Event Logs'), 316 'view' => 'core.AdminEventLogViewer'), 317 array('name' => $this->translate('Language Settings'), 318 'view' => 'core.AdminLanguageManager'), 319 ); 320 321 list ($ret, $list) = GalleryCoreApi::getRedundantToolkitPriorities(); 322 if ($ret) { 323 return array($ret, null); 324 } 325 if (!empty($list)) { 326 $data[] = array('name' => $this->translate('Toolkit Priority'), 327 'view' => 'core.AdminToolkitPriority', 328 'group' => 'toolkits', 329 'groupLabel' => $this->translate('Graphics Toolkits')); 330 } 331 332 return array(null, $data); 333 } 334 335 /** 336 * @see GalleryModule::getUserAdminViews 337 */ 338 function getUserAdminViews($user) { 339 global $gallery; 340 $views = array(); 341 342 if ($gallery->getConfig('login')) { 343 list ($ret, $isAnonymous) = GalleryCoreApi::isAnonymousUser($user->getId()); 344 if ($ret) { 345 return array($ret, null); 346 } 347 348 if (!$isAnonymous) { 349 if (!$user->isLocked()) { 350 $views[] = array('name' => $this->translate('Account Settings'), 351 'view' => 'core.UserPreferences'); 352 $views[] = array('name' => $this->translate('Change Password'), 353 'view' => 'core.UserChangePassword'); 354 } 355 } else { 356 $views[] = array('name' => $this->translate('Login'), 357 'view' => 'core.UserLogin'); 358 } 359 } 360 361 return array(null, $views); 362 } 363 364 /** 365 * @see GalleryModule::getItemAdminViews 366 */ 367 function getItemAdminViews($item) { 368 global $gallery; 369 370 $views = array(); 371 list ($ret, $permissions) = GalleryCoreApi::getPermissions($item->getId()); 372 if ($ret) { 373 return array($ret, null); 374 } 375 376 $childCount = 0; 377 $isAlbum = $item->getCanContainChildren(); 378 if ($isAlbum) { 379 list ($ret, $childCounts) = GalleryCoreApi::fetchChildCounts(array($item->getId())); 380 if ($ret) { 381 return array($ret, null); 382 } 383 $childCount = empty($childCounts[$item->getId()]) ? 0 : $childCounts[$item->getId()]; 384 } 385 386 /* Fetch thumbnail ids */ 387 list ($ret, $thumbTable) = 388 GalleryCoreApi::fetchThumbnailsByItemIds(array($item->getId())); 389 if ($ret) { 390 return array($ret, null); 391 } 392 $hasThumb = !empty($thumbTable[$item->getId()]); 393 394 $parentId = $item->getParentId(); 395 list ($ret, $parentPermissions) = GalleryCoreApi::getPermissions($parentId); 396 if ($ret) { 397 return array($ret, null); 398 } 399 400 list ($ret, $rootId) = GalleryCoreApi::getPluginParameter('module', 'core', 'id.rootAlbum'); 401 if ($ret) { 402 return array($ret, null); 403 } 404 405 $itemTypeNames = array_merge($item->itemTypeName(), $item->itemTypeName(false)); 406 if (isset($permissions['core.edit'])) { 407 if ($isAlbum && $childCount > 1) { 408 $views[] = array('name' => $this->_translate('Reorder Items'), 409 'view' => 'core.ItemReorder'); 410 } 411 if ($isAlbum && $childCount > 0) { 412 $views[] = array('name' => $this->_translate('Edit Captions'), 413 'view' => 'core.ItemEditCaptions'); 414 } 415 416 /* Edit view for all item types */ 417 $views[] = array('name' => $this->_translate( 418 array('text' => 'Edit %s', 'arg1' => $itemTypeNames[0]), 419 $itemTypeNames[2]), 420 'view' => 'core.ItemEdit'); 421 $views[] = array('name' => isset($permissions['core.changePermissions']) 422 ? $this->_translate('Edit Permissions') 423 : $this->_translate('View Permissions'), 424 'view' => 'core.ItemPermissions'); 425 } 426 427 if (!empty($parentId) && $hasThumb && isset($parentPermissions['core.edit'])) { 428 $views[] = array('name' => $this->_translate('Make Highlight'), 429 'view' => 'core.ItemMakeHighlight'); 430 } 431 432 if (isset($permissions['core.delete'])) { 433 $itemId = $item->getId(); 434 if ($itemId != $rootId) { 435 if (!function_exists('smarty_modifier_escape')) { 436 GalleryCoreApi::requireOnce('lib/smarty/plugins/modifier.escape.php'); 437 } 438 $title = smarty_modifier_escape(GalleryUtilities::markup( 439 $item->getTitle(), 'strip'), 'javascript', 'UTF-8'); 440 /* This is ItemAdmin view, hence page item is the one we are deleting */ 441 $thisItemId = $itemId; 442 $urlGenerator =& $gallery->getUrlGenerator(); 443 $url = $urlGenerator->generateUrl( 444 array('controller' => 'core.ItemDeleteSingle', 'itemId' => $itemId, 445 'pageId' => $thisItemId)); 446 $moreUrl = $isAlbum ? '' : $urlGenerator->generateUrl( 447 array('view' => 'core.ItemAdmin', 'subView' => 'core.ItemDelete', 448 'itemId' => $item->getParentId(), 449 'selectedId' => $itemId)); 450 $views[] = array('name' => $this->_translate( 451 array('text' => 'Delete %s', 'arg1' => $itemTypeNames[0]), $itemTypeNames[2]), 452 'view' => 'core.ItemDeleteSingle', /* just for g->linkId used by icons */ 453 'script' => "core_confirmDelete('$url', '$moreUrl', '$title');return false"); 454 455 $views[] = array('name' => $this->_translate( 456 array('text' => 'Move %s', 'arg1' => $itemTypeNames[0]), 457 $itemTypeNames[2]), 'view' => 'core.ItemMoveSingle'); 458 } 459 if ($isAlbum && $childCount > 0) { 460 $views[] = array('name' => $this->_translate('Delete Items'), 461 'view' => 'core.ItemDelete'); 462 } 463 } 464 465 if (isset($permissions['core.addDataItem']) && $isAlbum) { 466 $views[] = array('name' => $this->_translate('Add Items'), 467 'view' => 'core.ItemAdd'); 468 } 469 470 if (isset($permissions['core.addAlbumItem']) && $isAlbum) { 471 $views[] = array('name' => $this->_translate('Add Album'), 472 'view' => 'core.ItemAddAlbum'); 473 } 474 475 return array(null, $views); 476 } 477 478 /** 479 * We pushed all this code into its own file since we need it very rarely so it doesn't make 480 * sense to load it every single time. 481 * 482 * @see GalleryModule::install 483 */ 484 function upgrade($currentVersion, $statusMonitor) { 485 GalleryCoreApi::requireOnce('modules/core/CoreModuleExtras.inc'); 486 $ret = CoreModuleExtras::upgrade($this, $currentVersion, $statusMonitor); 487 if ($ret) { 488 return $ret; 489 } 490 return null; 491 } 492 493 /** 494 * Set the current version of Gallery. 495 */ 496 function setGalleryVersion($version) { 497 $this->_galleryVersion = $version; 498 } 499 500 /** 501 * Get the current version of Gallery. 502 */ 503 function getGalleryVersion() { 504 return $this->_galleryVersion; 505 } 506 507 /** 508 * Get the version of the core module and of Gallery itself. We store this on disk to avoid 509 * having to load up the database (which can be problematic if we're doing an upgrade and don't 510 * want to count a specific database schema). If the versions.dat file indicates that Gallery 511 * is in maintenance mode, then set the configuration value to indicate this. 512 * 513 * @return array 'core' => core module version, 'gallery' => gallery version 514 * @static 515 */ 516 function getInstalledVersions() { 517 global $gallery; 518 519 if (GalleryDataCache::containsKey('CoreModule::installedVersions')) { 520 $versions = GalleryDataCache::get('CoreModule::installedVersions'); 521 } else { 522 $platform =& $gallery->getPlatform(); 523 $versionFile = $gallery->getConfig('data.gallery.version'); 524 525 if ($platform->file_exists($versionFile)) { 526 $versionArray = $platform->file($versionFile); 527 if (count($versionArray) >= 2) { 528 $versions['core'] = rtrim($versionArray[0]); 529 $versions['gallery'] = rtrim($versionArray[1]); 530 GalleryDataCache::put('CoreModule::installedVersions', $versions, true); 531 if (isset($versionArray[2])) { 532 $maintenanceMode = explode(':', rtrim($versionArray[2]), 2); 533 if ($maintenanceMode[0] == 'maintenance-mode') { 534 $newMode = empty($maintenanceMode[1]) ? true : $maintenanceMode[1]; 535 $gallery->setConfig('mode.maintenance', $newMode); 536 } 537 } 538 } 539 } else { 540 /* 541 * If we get here we are probably doing a fresh install so just return 0, 0 and 542 * the rest of the install should work properly. 543 */ 544 $versions = array('core' => 0, 'gallery' => 0); 545 } 546 } 547 548 return $versions; 549 } 550 551 /** 552 * @see GalleryModule::performFactoryRegistrations 553 */ 554 function performFactoryRegistrations() { 555 GalleryCoreApi::requireOnce('modules/core/CoreModuleExtras.inc'); 556 $ret = CoreModuleExtras::performFactoryRegistrations($this); 557 if ($ret) { 558 return $ret; 559 } 560 return null; 561 } 562} 563?> 564