39
39
* @param string the plugin type (eg, module, theme, etc)
40
40
* @param string the plugin id
41
41
* @param bool should we ignore version mismatches (default: no)
42
* @param bool should we return an error on version mismatches instead of redirecting
43
* to the upgrader? (default: false)
42
44
* @param int the depth of recursion (don't set this- it's used internally)
43
45
* @return array object GalleryStatus a status code
44
46
* object the plugin
47
function loadPlugin($pluginType, $pluginId, $ignoreVersionMismatch=false, $depth=0) {
49
function loadPlugin($pluginType, $pluginId, $ignoreVersionMismatch=false,
50
$errorOnVersionMismatch=false, $depth=0) {
50
53
if ($gallery->getDebug()) {
75
78
$gallery->debug('Class not defined, trying to include it.');
78
$pluginBaseDir = dirname(__FILE__) . '/../../../../';
81
$pluginBaseDir = GalleryCoreApi::getPluginBaseDir($pluginType, $pluginId);
79
82
$pluginFile = sprintf('%ss/%s/%s.inc', $pluginType, $pluginId, $pluginType);
81
GalleryCoreApi::relativeRequireOnce(
84
GalleryCoreApi::requireOnce(
82
85
sprintf('modules/core/classes/%s.class', $pluginSuperClass));
84
$platform = $gallery->getPlatform();
87
$platform =& $gallery->getPlatform();
85
88
if (!$platform->file_exists($pluginBaseDir . $pluginFile)) {
87
90
* If we have a bad path, it may be because our cached plugin list is out of
94
97
array('type' => $pluginType,
95
98
'itemId' => 'GalleryPluginHelper_fetchPluginStatus',
97
list ($ret, $plugin) =
98
GalleryPluginHelper_simple::loadPlugin($pluginType, $pluginId,
99
$ignoreVersionMismatch, $depth + 1);
100
if ($ret->isError()) {
100
list ($ret, $plugin) = GalleryPluginHelper_simple::loadPlugin(
101
$pluginType, $pluginId, $ignoreVersionMismatch,
102
$errorOnVersionMismatch, $depth + 1);
101
104
return array($ret->wrap(__FILE__, __LINE__), null);
104
return array(GalleryStatus::error(ERROR_BAD_PARAMETER, __FILE__, __LINE__,
105
$pluginBaseDir . $pluginFile), null);
107
return array(GalleryCoreApi::error(ERROR_BAD_PARAMETER, __FILE__, __LINE__,
108
$pluginBaseDir . $pluginFile), null);
109
GalleryCoreApi::relativeRequireOnce($pluginFile);
112
GalleryCoreApi::requireOnce($pluginFile);
111
114
if (!class_exists($pluginClass)) {
112
return array(GalleryStatus::error(ERROR_BAD_PLUGIN, __FILE__, __LINE__,
115
return array(GalleryCoreApi::error(ERROR_BAD_PLUGIN, __FILE__, __LINE__,
113
116
"Class $pluginClass does not exist"), null);
148
151
/* Try to deactivate the plugin */
149
152
list ($ret, $redirectInfo) = $plugin->deactivate();
150
if ($ret->isError()) {
151
154
return array($ret->wrap(__FILE__, __LINE__), null);
154
if (!empty($redirectInfo)) {
157
if (!empty($redirectInfo) && !$errorOnVersionMismatch) {
156
159
* We were unable to automatically deactivate the plugin!
157
160
* Forcibly abort this request and jump to the upgrader so this
158
161
* module can be upgraded.
160
$gallery->debug("Unable to deactivate $pluginId, jumping to upgrader.");
161
$gallery->debug_r($redirectInfo);
163
if ($gallery->getDebug()) {
164
$gallery->debug("Unable to deactivate $pluginId, jumping to upgrader.");
165
$gallery->debug_r($redirectInfo);
162
167
$urlGenerator =& $gallery->getUrlGenerator();
163
168
header('Location: ' .
164
169
$urlGenerator->getCurrentUrlDir(true) . 'upgrade/index.php');
240
245
list ($ret, $params) =
241
GalleryPluginHelper_simple::fetchAllParameters($pluginType, $pluginId, $itemId);
242
if ($ret->isError()) {
246
GalleryPluginHelper_simple::_fetchAllParameters($pluginType, $pluginId, $itemId);
243
248
return array($ret->wrap(__FILE__, __LINE__), null);
246
251
/* Return the value, or null if the param doesn't exist */
247
if (!isset($params[$parameterName])) {
248
return array(GalleryStatus::success(), null);
252
if (!isset($params[$itemId][$parameterName])) {
253
return array(null, null);
250
return array(GalleryStatus::success(), $params[$parameterName]);
255
return array(null, $params[$itemId][$parameterName]);
257
262
* @param string the type of the plugin
258
263
* @param string the id of the plugin
259
* @param integer the id of item (or null for a global setting)
264
* @param integer the id of item (or null/zero for a global setting)
260
265
* @return array object GalleryStatus a status code
261
266
* array (parameterName => parameterValue)
264
269
function fetchAllParameters($pluginType, $pluginId, $itemId=0) {
270
/* Convert null to 0, just in case */
271
if ($itemId == null) {
274
list ($ret, $params) =
275
GalleryPluginHelper_simple::_fetchAllParameters($pluginType, $pluginId, $itemId);
277
return array($ret->wrap(__FILE__, __LINE__), null);
279
return array(null, $params[$itemId]);
283
* Get all the parameters for this plugin
285
* @param string the type of the plugin
286
* @param string the id of the plugin
287
* @param mixed int id of item (or null/zero for a global setting) or array of ids
288
* @return array object GalleryStatus a status code
289
* array (itemId/zero => array(parameterName => parameterValue), ..)
292
function _fetchAllParameters($pluginType, $pluginId, $itemId) {
266
294
if (empty($pluginType) || empty($pluginId)) {
267
return array(GalleryStatus::error(ERROR_BAD_PARAMETER, __FILE__, __LINE__,
295
return array(GalleryCoreApi::error(ERROR_BAD_PARAMETER, __FILE__, __LINE__,
268
296
sprintf("Missing pluginType [%s] or pluginId [%s]",
297
$pluginType, $pluginId)),
279
$cacheKey = "GalleryPluginHelper::fetchAllParameters($pluginType, $pluginId, $itemId)";
280
if (!GalleryDataCache::containsKey($cacheKey)) {
281
$data =& GalleryDataCache::getFromDisk(array('type' => $pluginType,
287
[GalleryPluginParameterMap::parameterName],
288
[GalleryPluginParameterMap::parameterValue]
290
[GalleryPluginParameterMap]
292
[GalleryPluginParameterMap::pluginType] = ?
294
[GalleryPluginParameterMap::pluginId] = ?
296
[GalleryPluginParameterMap::itemId] = ?
299
list ($ret, $searchResults) =
300
$gallery->search($query, array($pluginType, $pluginId, $itemId));
301
if ($ret->isError()) {
302
return array($ret->wrap(__FILE__, __LINE__), null);
306
while ($result = $searchResults->nextResult()) {
307
$data[$result[0]] = $result[1];
310
GalleryDataCache::putToDisk(array('type' => $pluginType,
315
GalleryDataCache::put($cacheKey, $data);
317
$data = GalleryDataCache::get($cacheKey);
320
return array(GalleryStatus::success(), $data);
307
$data = $queryIds = array();
308
$itemIds = is_array($itemId) ? $itemId : array($itemId);
309
$cacheBase = "GalleryPluginHelper::fetchAllParameters($pluginType, $pluginId, ";
310
foreach ($itemIds as $itemId) {
311
$cacheKey = $cacheBase . $itemId . ')';
312
if (GalleryDataCache::containsKey($cacheKey)) {
313
$data[$itemId] = GalleryDataCache::get($cacheKey);
316
$cacheData =& GalleryDataCache::getFromDisk(
317
array('type' => $pluginType, 'itemId' => $itemId, 'id' => $pluginId));
318
if (isset($cacheData)) {
319
$data[$itemId] = $cacheData;
320
GalleryDataCache::put($cacheKey, $cacheData);
323
$queryIds[] = (int)$itemId;
325
if (empty($queryIds)) {
326
return array(null, $data);
329
$whereId = count($queryIds) > 1 ? 'IN (' . GalleryUtilities::makeMarkers($queryIds) . ')'
333
[GalleryPluginParameterMap::itemId],
334
[GalleryPluginParameterMap::parameterName],
335
[GalleryPluginParameterMap::parameterValue]
337
[GalleryPluginParameterMap]
339
[GalleryPluginParameterMap::pluginType] = ?
341
[GalleryPluginParameterMap::pluginId] = ?
343
[GalleryPluginParameterMap::itemId] ' . $whereId;
344
array_unshift($queryIds, $pluginType, $pluginId);
346
list ($ret, $searchResults) = $gallery->search($query, $queryIds);
348
return array($ret->wrap(__FILE__, __LINE__), null);
351
while ($result = $searchResults->nextResult()) {
352
$data[$result[0]][$result[1]] = (string)$result[2];
355
foreach (array_slice($queryIds, 2) as $itemId) {
356
if (!isset($data[$itemId])) {
357
$data[$itemId] = array();
359
GalleryDataCache::putToDisk(array('type' => $pluginType,
363
GalleryDataCache::put($cacheBase . $itemId . ')', $data[$itemId]);
366
return array(null, $data);
344
390
if (!isset($plugins)) {
345
391
list ($ret, $plugins) = GalleryPluginHelper_simple::fetchPluginList($pluginType);
346
if ($ret->isError()) {
347
393
return array($ret->wrap(__FILE__, __LINE__), null);
350
$platform = $gallery->getPlatform();
396
$platform =& $gallery->getPlatform();
398
$pluginBaseDirs = GalleryCoreApi::getPluginBaseDirs();
399
$pluginBaseIndexFile = sprintf(
400
'%sindex.%ss', $gallery->getConfig('data.gallery.plugins'), $pluginType);
352
402
/* Scan modules directory for installed modules */
353
403
switch ($pluginType) {
355
$pluginsDir = dirname(__FILE__) . '/../../../../modules/';
405
$pluginsDir = 'modules/';
356
406
$pluginFile = 'module.inc';
360
$pluginsDir = dirname(__FILE__) . '/../../../../themes/';
410
$pluginsDir = 'themes/';
361
411
$pluginFile = 'theme.inc';
365
return array(GalleryStatus::error(ERROR_BAD_PARAMETER, __FILE__, __LINE__,
415
return array(GalleryCoreApi::error(ERROR_BAD_PARAMETER, __FILE__, __LINE__,
366
416
sprintf("Wrong pluginType [%s]",
371
if ($dir = $platform->opendir($pluginsDir)) {
372
while ($pluginId = $platform->readdir($dir)) {
373
if ($pluginId{0} == '.') {
376
if (!$platform->is_dir($pluginsDir . $pluginId)) {
380
$path = $pluginsDir . $pluginId . '/' . $pluginFile;
381
if ($platform->file_exists($path)) {
382
$plugins[$pluginId]['available'] = 1;
384
$frameworkParams = array('version', 'callbacks', 'requiredCoreApi');
385
if ($pluginType == 'module') {
386
$frameworkParams[] = 'requiredModuleApi';
388
$frameworkParams[] = 'requiredThemeApi';
391
foreach ($frameworkParams as $paramName) {
392
list ($ret, $plugins[$pluginId][$paramName]) =
393
GalleryPluginHelper_simple::getParameter(
394
$pluginType, $pluginId, '_' . $paramName);
395
if ($ret->isError()) {
396
return array($ret->wrap(__FILE__, __LINE__), null);
399
/* Separate out the major/minor version. */
400
if (!strncmp($paramName, 'required', 8)) {
401
$tmp = split(',', $plugins[$pluginId][$paramName]);
402
// DEBUG: remove these lines below when we
403
// commit; make sure that we bump all module
404
// versions instead so that the module
405
// version reqs aren't empty
406
if (empty($tmp) || count($tmp) < 2) {
407
$tmp = array(-1, -1);
409
$plugins[$pluginId][$paramName] =
410
array((int)$tmp[0], (int)$tmp[1]);
421
$frameworkParams = array('version', 'callbacks', 'requiredCoreApi');
423
($pluginType == 'module') ? 'requiredModuleApi' : 'requiredThemeApi';
425
foreach ($pluginBaseDirs as $pluginBaseDir) {
426
if ($dir = $platform->opendir($pluginBaseDir . $pluginsDir)) {
427
while ($pluginId = $platform->readdir($dir)) {
428
if ($pluginId{0} == '.') {
431
if (!$platform->is_dir($pluginBaseDir . $pluginsDir . $pluginId)) {
435
$path = $pluginBaseDir . $pluginsDir . $pluginId . '/' . $pluginFile;
436
if ($platform->file_exists($path)) {
437
$plugins[$pluginId]['available'] = 1;
439
foreach ($frameworkParams as $paramName) {
440
list ($ret, $plugins[$pluginId][$paramName]) =
441
GalleryPluginHelper_simple::getParameter(
442
$pluginType, $pluginId, '_' . $paramName);
444
return array($ret->wrap(__FILE__, __LINE__), null);
447
/* Separate out the major/minor version. */
448
if (!strncmp($paramName, 'required', 8)) {
449
$tmp = explode(',', $plugins[$pluginId][$paramName]);
450
$plugins[$pluginId][$paramName] = (count($tmp) < 2)
451
? array(-1, -1) : array((int)$tmp[0], (int)$tmp[1]);
456
$platform->closedir($dir);
415
$platform->closedir($dir);
418
460
/* Find and remove plugins that are active, but not installed */
419
461
foreach ($plugins as $pluginId => $pluginStatus) {
420
462
if (!isset($pluginStatus['available'])) {
421
$gallery->debug("Plugin $pluginId no longer installed");
463
if ($gallery->getDebug()) {
464
$gallery->debug("Plugin $pluginId no longer installed");
422
466
unset($plugins[$pluginId]);
485
530
$data = GalleryDataCache::get($cacheKey);
488
return array(GalleryStatus::success(), $data);
533
return array(null, $data);
537
* Returns an array of directories that can contain plugins.
539
* This function should only be used in special circumstances,
540
* for example when a list of all plugins needs to be made.
541
* Currently it returns gallery2/ and gallery2/plugins/.
543
function getPluginBaseDirs() {
548
$data['base'] = dirname(dirname(dirname(dirname(dirname(__FILE__))))) . '/';
550
$pluginsPath = $gallery->getConfig('data.gallery.plugins');
551
if (file_exists($pluginsPath)) {
552
$data['g2data'] = $pluginsPath;
559
* Returns the base directory of the specified plugin.
561
* Modules should never assume the filesystem location of any module, not
562
* even the core module. Use this function to get the base directory of a
563
* module. Possible base directories are usually gallery2/ and gallery2/plugins.
564
* The complete list can be read with GalleryCoreApi::getPluginBaseDirs().
566
* @param string 'module' or 'theme'
567
* @param string the plugin ID
568
* @param bool force index to be reread from the filesystem
569
* @return string plugin base directory
571
function getPluginBaseDir($pluginType, $pluginId, $clearCache=false) {
573
if (!isset($baseDirs[$pluginId . $pluginType]) || $clearCache) {
575
$defaultPluginBasePath = dirname(__FILE__) . '/../../../../';
576
$pluginDataDir = $defaultPluginBasePath . $gallery->getConfig('plugins.dirname') . '/';
578
if (GalleryCoreApi::isPluginInDefaultLocation($pluginType, $pluginId, $clearCache)) {
579
$baseDirs[$pluginId . $pluginType] = $defaultPluginBasePath;
581
$baseDirs[$pluginId . $pluginType] = $pluginDataDir;
584
return $baseDirs[$pluginId . $pluginType];
588
* Indicates whether the specified plugin is in the default plugin directory.
590
* Sometimes it's useful to know just whether a plugin is in its default
591
* directory or not, without actually getting any information about its path.
592
* It is used for rewriting URLs in the UrlGenerator.
594
* @param string 'module' or 'theme'
595
* @param string the plugin ID
596
* @param bool force index to be reread from the filesystem
599
function isPluginInDefaultLocation($pluginType, $pluginId, $clearCache=false) {
602
/* Don't we need to know if the index file has changed to keep the cache updated? */
603
if (!isset($pluginIndex[$pluginType]) || $clearCache) {
605
$platform =& $gallery->getPlatform();
607
dirname(__FILE__) . '/../../../../' . $gallery->getConfig('plugins.dirname');
608
$pluginIndexFile = sprintf('%s/index.%ss', $pluginDataDir, $pluginType);
609
$pluginIndex[$pluginType] = array();
612
* If the config file doesn't exist, install is in progress. In that
613
* case we assume that all plugins are in their default directories.
615
if (!$platform->file_exists(dirname(__FILE__) . '/../../../../config.php')
616
|| !$platform->file_exists($pluginIndexFile)) {
619
$dataDirPluginList = $platform->file($pluginIndexFile);
621
foreach($dataDirPluginList as $line) {
622
$pluginIndex[$pluginType][rtrim($line)] = 1;
626
if (isset($pluginIndex[$pluginType][$pluginId])) {