b08febc915c4d3cbe2b2bdb37ca5e6ce5e27b732
[project/gallery.git] / gallery_base.inc
1 <?php
2 // $Id$
3
4 /**
5 * gallery.module : gallery_base.inc
6 * Base functions
7 */
8
9 define(GALLERY_NO_EMBED_THEME, -1);
10
11 define(GALLERY_ERROR_WATCHDOG, 1);
12 define(GALLERY_ERROR_BROWSER, 2);
13 define(GALLERY_ERROR_VERBOSE, 3);
14
15 define(GALLERY_PLUGIN_ENABLED, 1);
16 define(GALLERY_PLUGIN_DISABLED, 0);
17 define(GALLERY_PLUGIN_STATUS_UNKNOWN, -1);
18 define(GALLERY_PLUGIN_NOT_ACTIVE, -2);
19 define(GALLERY_PLUGIN_NOT_INSTALLED, -3);
20 define(GALLERY_PLUGIN_MISSING, -4);
21
22 /**
23 * Login user into embedded gallery
24 */
25 function gallery_login() {
26 _gallery_init();
27 }
28
29 /**
30 * End user session
31 */
32 function gallery_logout() {
33 if (variable_get('gallery_valid', FALSE)) {
34 require_once(variable_get('gallery_dir', './gallery2/') .'embed.php');
35 GalleryEmbed::logout();
36 }
37 }
38
39 /**
40 * Initialize embedded gallery
41 */
42 function _gallery_init($full = FALSE, $vars = NULL) {
43 global $user;
44 static $ready = FALSE;
45
46 // initialize only once
47 if ($ready) {
48 return $ready;
49 }
50
51 if (!$vars) {
52 $embed_path = variable_get('gallery_dir', './gallery2/') .'embed.php';
53 $g2_uri = variable_get('gallery_uri', '/gallery2/');
54 $embed_uri = variable_get('gallery_embed_uri', '?q=gallery');
55 $gallery_valid = variable_get('gallery_valid', 0);
56 $uid = ($user->uid > 0) ? $user->uid : '';
57 }
58 else {
59 $embed_path = $vars['gallery_dir'] .'embed.php';
60 $g2_uri = $vars['gallery_uri'];
61 $embed_uri = $vars['gallery_embed_uri'];
62 $gallery_valid = $vars['gallery_valid'];
63 $uid = '';
64 }
65
66 $init_err_msg = t('Unable to initialize embedded Gallery. You need to <a href="@link"> configure your embedded Gallery</a>.', array('@link' => url('admin/settings/gallery/install')));
67
68 if ((!$gallery_valid) || (!is_readable($embed_path))) {
69 gallery_error($init_err_msg, NULL, TRUE);
70 return $ready;
71 }
72
73 include_once($embed_path);
74
75 $params = array('embedUri' => $embed_uri,
76 'g2Uri' => $g2_uri,
77 'loginRedirect' => url('user/login', NULL, NULL, TRUE),
78 'activeUserId' => $uid,
79 'activeLanguage' => gallery_get_language($user),
80 'fullInit' => $full,
81 'apiVersion' => array(1, 2));
82
83 $ret = GalleryEmbed::init($params);
84 if ($ret) {
85 if ($ret->getErrorCode() & ERROR_PLUGIN_VERSION_MISMATCH) {
86 gallery_error($vars ? t('Embedding API version is incompatible.') : $init_err_msg, $ret, TRUE);
87 return $ready;
88 }
89 else {
90 gallery_error($init_err_msg, $ret, TRUE);
91 return $ready;
92 }
93 }
94
95 $ready = TRUE;
96
97 return $ready;
98 }
99
100 /**
101 * handleRequest extension with error handling
102 */
103 function gallery_handle_request() {
104 ob_start();
105 $result = GalleryEmbed::handleRequest();
106 $output = ob_get_contents();
107 ob_end_clean();
108
109 if ($output) {
110 preg_match('%<div id="giStackTrace" [^>]*>(.*?)</div>%is', $output, $matches);
111 gallery_error(t('Error handling request (invalid request)<br />or the requested Gallery URL does not exist.'), $matches[1], TRUE);
112 return NULL;
113 }
114
115 /*
116 // switch theme
117 $themeid = variable_get('gallery_theme', GALLERY_NO_EMBED_THEME);
118 if ($themeid != GALLERY_NO_EMBED_THEME) {
119 list($ret, $theme) = GalleryCoreApi::loadPlugin('theme', $themeid, false, true);
120 if ($ret) {
121 gallery_error(t('Error switching theme'), $ret);
122 return NULL;
123 }
124 }
125 //////
126 $ret = GalleryCoreApi::setPluginParameter('module', 'core', 'theme', $themeid);
127 if ($ret) {
128 gallery_error(t('Error switching theme'), $ret);
129 return NULL;
130 }
131 */
132
133 return $result;
134 }
135
136 /**
137 * Get the language for $user
138 */
139 function gallery_get_language($user) {
140 $language = $user->language;
141 if ($user->uid == 0 || empty($language)) {
142 if (module_exists('i18n')) {
143 $language = i18n_get_lang();
144 }
145 elseif (module_exists('locale')) {
146 $result = db_query('SELECT locale FROM {locales_meta} WHERE isdefault = 1');
147 $row = db_fetch_object($result);
148 $language = $row->locale;
149 }
150 }
151 // convert certain lang codes, e.g. 'esl/spa es' => 'es' or 'fr-ca' => 'fr'
152 $language = preg_replace(array('/([\w\/]+) ([a-z]{2,3})/i', '/([a-z]{2,3})-(\w+)/i'), array('${2}', '${1}'), $language);
153 }
154
155 /**
156 * Include head information with check made for uniqueness (see drupal_add_js)
157 */
158 function gallery_set_html_head($info, $unique = TRUE) {
159 static $sent = array();
160 // only set head once
161 if ($unique) {
162 $hash = md5($info);
163 if (!isset($sent[$hash])) {
164 drupal_set_html_head($info);
165 $sent[$hash] = TRUE;
166 }
167 }
168 else {
169 drupal_set_html_head($info);
170 }
171 }
172
173 /**
174 * Retrieve all (active) themes from Gallery2
175 */
176 function gallery_get_themes($all = FALSE) {
177 // list of themes
178 list($ret, $g2_themes) = GalleryCoreApi::fetchPluginStatus('theme', TRUE);
179 if ($ret) {
180 gallery_error(t('Error retrieving theme list'), $ret);
181 return array();
182 }
183
184 $themes = array();
185 foreach (array_keys($g2_themes) as $themeid) {
186 // only active themes
187 if (!empty($g2_themes[$themeid]['active']) || $all) {
188 // get theme details
189 list($ret, $theme) = GalleryCoreApi::loadPlugin('theme', $themeid, TRUE);
190 if ($ret) {
191 gallery_error(t('Error getting theme (:themeid) details',
192 array(':themeid' => $themeid)), $ret);
193 return array();
194 }
195 $themes[$themeid] = $theme->getName();
196 }
197 }
198
199 return $themes;
200 }
201
202 /**
203 * Retrieve all image frames from Gallery2
204 */
205 function gallery_get_image_frames() {
206 _gallery_init();
207 list($ret, $imageframe) = GalleryCoreApi::newFactoryInstance('ImageFrameInterface_1_1');
208 if ($ret || !isset($imageframe)) {
209 return array('none' => t('None'));
210 }
211 list($ret, $list) = $imageframe->getImageFrameList();
212 if ($ret) {
213 return array('none' => t('None'));
214 }
215
216 return $list;
217 }
218
219 /**
220 * Implementation of gallery_generate_url
221 */
222 function gallery_generate_url($params, $html = TRUE, $full = TRUE) {
223 $options = array();
224 $options['forceFullUrl'] = $full;
225 $options['htmlEntities'] = $html;
226
227 $url_generator =& $GLOBALS['gallery']->getUrlGenerator();
228 if (!$url_generator) {
229 gallery_error(t('Error: UrlGenerator not available'));
230 return '';
231 }
232
233 return $url_generator->generateUrl($params, $options);
234 }
235
236 /**
237 * Implementation of gallery_item_details
238 */
239 function gallery_item_details($id, $verbose = FALSE) {
240 $details = array();
241 // load entity
242 list($ret, $entity) = GalleryCoreApi::loadEntitiesById($id);
243 if ($ret) {
244 gallery_error(t('Error fetching album details (entityId: :id)',
245 array(':id' => $id)), $ret);
246 return $details;
247 }
248 // extract details
249 $details['type'] = $entity->entityType;
250 $details['title'] = $entity->title;
251 $details['owner'] = $entity->ownerId;
252 $details['parent'] = $entity->parentId;
253
254 if ($verbose) {
255 $details['description'] = $entity->description;
256 $details['summary'] = $entity->summary;
257 $details['keywords'] = $entity->keywords;
258 }
259
260 return $details;
261 }
262
263 /**
264 * Split an image block result into individual images
265 */
266 function _gallery_split_imageblock($html) {
267 /**
268 * From http://uk.php.net/manual/en/function.preg-split.php
269 * Split the html from image block into <...> parts
270 */
271 $pattern = '/(<(?:[^<>]+(?:"[^"]*"|\'[^\']*\')?)+>)/';
272 $html_array = preg_split($pattern, trim($html), -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
273
274 $ndx = 0;
275 $images = array();
276 $image_html = '';
277 // iterate through this array and combine again, but on a per-image basis
278 foreach ($html_array as $value) {
279 $value = trim($value);
280 $image_html .= $value;
281 if (!strcmp($value, '<div class="one-image">')) {
282 // found the opening <div> for the image
283 $open_divs = 0;
284 }
285 elseif (!strncmp($value, '<div', 4)) {
286 // found a <div> but not the main image one (eg a frame)
287 $open_divs++;
288 }
289 elseif (!strcmp($value, '</div>')) {
290 // found a </div> but check if it's for the main image or a subcomponent (eg frame)
291 if ($open_divs > 0) {
292 $open_divs--;
293 }
294 else {
295 // this must be the closing div for "one-image" so move to next image
296 $images[] = $image_html;
297 $image_html = '';
298 }
299 }
300 }
301
302 return $images;
303 }
304
305 /*
306 * --------------------------------------------------------------------------
307 * Error, Debug and Status Functions
308 * --------------------------------------------------------------------------
309 */
310
311 function gallery_error($msg, $ret = NULL, $force = FALSE) {
312 $error_mode = variable_get('gallery_error_mode', array(GALLERY_ERROR_WATCHDOG));
313 $admin = user_access('administer site configuration');
314 $report = $admin && variable_get('gallery_report', 1);
315 // verbose error messages
316 $debug_info = array();
317 if (in_array(GALLERY_ERROR_VERBOSE, $error_mode) || variable_get('gallery_debug', 0) || $admin) {
318 $msg = $ret ? (is_object($ret) ? ($msg .'<br />'. $ret->getAsHtml()) : $ret) : $msg;
319 if (function_exists('debug_backtrace')) {
320 $trace = debug_backtrace();
321 $source = t('Error in function \':func()\' (:file::line):<br />',
322 array(':func' => $trace[1]['function'], ':file' => basename($trace[0]['file']), ':line' => $trace[0]['line']));
323 $message = $source .'<ul><li>'. $msg .'</li></ul>';
324 $debug_info = array('Debug Trace' => $trace);
325 }
326 }
327 $message = !empty($message) ? $message : $msg;
328 // debug output (skip watchdog)
329 if (variable_get('gallery_debug', 0) && $admin) {
330 if ($report) {
331 _gallery_report_error($debug_info);
332 }
333 drupal_set_message($message, 'error');
334 return;
335 }
336 // error output to browser
337 if (in_array(GALLERY_ERROR_BROWSER, $error_mode)) {
338 if ($report) {
339 _gallery_report_error($debug_info);
340 }
341 drupal_set_message($message, 'error');
342 }
343 elseif ($force) {
344 if ($report) {
345 _gallery_report_error($debug_info);
346 }
347 drupal_set_message($admin ? $message : t('Embedded Gallery2 is not available or requested Gallery URL does not exist.'), 'error');
348 }
349 // error output to watchdog
350 if (in_array(GALLERY_ERROR_WATCHDOG, $error_mode)) {
351 watchdog('gallery', $message, WATCHDOG_ERROR);
352 }
353 }
354
355 function _gallery_report_error($report = array()) {
356 require_once(drupal_get_path('module', 'gallery') .'/gallery_help.inc');
357 require_once(drupal_get_path('module', 'gallery') .'/gallery_report.inc');
358
359 drupal_set_message(_gallery_report_help(), 'error');
360 _gallery_report(FALSE, $report, TRUE);
361 }
362
363 function gallery_debug($array, $label = 'Gallery Debug') {
364 if (variable_get('gallery_debug', 0) && user_access('administer site configuration')) {
365 drupal_set_message('<strong>'. $label .':</strong><br />'. nl2br(htmlspecialchars(print_r($array, TRUE))), 'error');
366 }
367 }
368
369 function gallery_set_status($status = array(), $reset = FALSE) {
370 $status_array = $status;
371 if (!$reset) {
372 $status_array = unserialize(variable_get('gallery_status', serialize(array())));
373 foreach ($status as $key => $value) {
374 if (!empty($value)) {
375 $status_array[$key] = $value;
376 }
377 elseif (isset($status_array[$key])) {
378 unset($status_array[$key]);
379 }
380 }
381 }
382
383 variable_set('gallery_status', serialize($status_array));
384 }
385
386 function gallery_get_status() {
387 return unserialize(variable_get('gallery_status', serialize(array())));
388 }
389
390 function gallery_format_status($status = array(), $title = 'Gallery message(s):') {
391 $message = $title .'<ul>';
392 if (count($status)) {
393 foreach ($status as $item) {
394 $message .= '<li>'. t($item['title']);
395 if (isset($item['success']) && $item['success']) {
396 $message .= ' <span class=\'g2_embed_success\'>'. t('Success') .'</span>';
397 }
398 elseif (isset($item['warning']) && $item['warning']) {
399 $message .= ' <span class=\'g2_embed_warning\'>'. t('Warning') .'</span>';
400 $message .= empty($item['notice']) ? '' : '<ul><li>'. t($item['notice']) .'</li></ul>';
401 }
402 elseif (isset($item['error']) && $item['error']) {
403 $message .= ' <span class=\'g2_embed_error\'>'. t('Error') .'</span>';
404 $message .= empty($item['notice']) ? '' : '<ul><li>'. t($item['notice']) .'</li></ul>';
405 }
406 elseif (isset($item['advise']) && $item['advise']) {
407 $message .= ' <span class=\'g2_embed_warning\'>'. t('Advisory') .'</span>';
408 $message .= empty($item['notice']) ? '' : '<ul><li>'. t($item['notice']) .'</li></ul>';
409 }
410 elseif (isset($item['message']) && $item['message']) {
411 $message .= ': '. t($item['message']);
412 }
413 }
414 }
415 else {
416 $message = t('Status not available');
417 }
418 $message .= '</ul>';
419
420 return $message;
421 }
422
423 function gallery_version() {
424 if (!_gallery_init(FALSE)) {
425 return '';
426 }
427
428 list($core_major, $core_minor) = GalleryCoreApi::getApiVersion();
429 list($embed_major, $embed_minor) = GalleryEmbed::getApiVersion();
430 $version = array(
431 'core' => array('major' => $core_major, 'minor' => $core_minor),
432 'embed' => array('major' => $embed_major, 'minor' => $embed_minor)
433 );
434
435 // update version in status messages
436 $status = array('version' => array(
437 'title' => t('Gallery2 API version'),
438 'message' => "$core_major.$core_minor / $embed_major.$embed_minor")
439 );
440 gallery_set_status($status);
441
442 return $version;
443 }
444
445 function gallery_plugin_status($plugin_names, $setstatus = FALSE) {
446 static $all_plugins_status = array();
447 $plugins_status = array();
448 if (!_gallery_init(FALSE)) {
449 gallery_error(t('Unable to get Gallery2 plugin status.'), $ret);
450 foreach ($plugin_names as $plugin) {
451 $plugins_status[$plugin] = GALLERY_PLUGIN_STATUS_UNKNOWN;
452 }
453 return $plugins_status;
454 }
455 // Fetch status of G2 modules
456 if (empty($all_plugins_status)) {
457 list($ret, $all_plugins_status) = GalleryCoreApi::fetchPluginStatus('module');
458 if ($ret) {
459 gallery_error(t('Unable to get Gallery2 module status.'), $ret);
460 foreach ($plugin_names as $plugin) {
461 $plugins_status[$plugin] = GALLERY_PLUGIN_STATUS_UNKNOWN;
462 }
463 return $plugins_status;
464 }
465 }
466 // Generate array containing module status
467 foreach ($plugin_names as $plugin) {
468 if (isset($all_plugins_status[$plugin])) {
469 if ($all_plugins_status[$plugin]['active'] && $all_plugins_status[$plugin]['available']) {
470 $plugins_status[$plugin] = GALLERY_PLUGIN_ENABLED;
471 }
472 elseif (!isset($all_plugins_status[$plugin]['active']) && $all_plugins_status[$plugin]['available']) {
473 $plugins_status[$plugin] = GALLERY_PLUGIN_NOT_INSTALLED;
474 }
475 elseif (($all_plugins_status[$plugin]['active'] == 0) && $all_plugins_status[$plugin]['available']) {
476 $plugins_status[$plugin] = GALLERY_PLUGIN_NOT_ACTIVE;
477 }
478 else {
479 $plugins_status[$plugin] = GALLERY_PLUGIN_DISABLED;
480 }
481 }
482 else {
483 $plugins_status[$plugin] = GALLERY_PLUGIN_MISSING;
484 }
485 }
486 // Generate array containing module status
487 if ($setstatus) {
488 $status = array();
489 $plugin_info = array(
490 'imageblock' => array('title' => 'Image Block', 'severity' => 'error'),
491 'imageframe' => array('title' => 'ImageFrame', 'severity' => 'warning'),
492 'search' => array('title' => 'Search', 'severity' => 'warning'),
493 );
494 foreach ($plugins_status as $plugin => $plugin_status) {
495 if ($plugin_status == GALLERY_PLUGIN_ENABLED) {
496 $status[$plugin] = '';
497 }
498 else {
499 $status[$plugin]['title'] = t('Gallery2 plugin \'@plugin\' is not available: ',
500 array('@plugin' => isset($plugin_info[$plugin]) ? $plugin_info[$plugin]['title'] : drupal_ucfirst($plugin)));
501 $status[$plugin][isset($plugin_info[$plugin]) ? $plugin_info[$plugin]['severity'] : 'warning'] = TRUE;
502 }
503 }
504 gallery_set_status($status);
505 }
506
507 return $plugins_status;
508 }
509
510 function gallery_single_plugin_status($plugin_name, $setstatus = FALSE) {
511 $status = gallery_plugin_status(array($plugin_name), $setstatus);
512 return $status[$plugin_name];
513 }
514
515 function theme_gallery_plugin_status_message($status, $invert = FALSE) {
516 if ($invert) {
517 $enabled_class = 'admin-disabled';
518 $disabled_class = 'admin-enabled';
519 }
520 else {
521 $enabled_class = 'admin-enabled';
522 $disabled_class = 'admin-disabled';
523 }
524 // Unknown is always bad as it means that the link to Gallery2 is lost
525 // so also display as in disabled class (normally red).
526 $unknown_class = 'admin-disabled';
527
528 switch ($status) {
529 case GALLERY_PLUGIN_ENABLED:
530 return '<span class="'. $enabled_class .'">activated</span>';
531 case GALLERY_PLUGIN_DISABLED:
532 return '<span class="'. $disabled_class .'">disabled</span>';
533 case GALLERY_PLUGIN_NOT_ACTIVE:
534 return '<span class="'. $disabled_class .'">deactivated</span>';
535 case GALLERY_PLUGIN_NOT_INSTALLED:
536 return '<span class="'. $disabled_class .'">not installed</span>';
537 case GALLERY_PLUGIN_MISSING:
538 return '<span class="'. $disabled_class .'">missing</span>';
539 case GALLERY_PLUGIN_STATUS_UNKNOWN:
540 default:
541 return '<span class="'. $unknown_class .'">unknown</span>';
542 }
543 }
544
545 function theme_gallery_module_status_message($status) {
546 if ($status) {
547 return '<span class="admin-enabled">enabled</span>';
548 }
549 else {
550 return '<span class="admin-disabled">disabled</span>';
551 }
552 }
553
554 ?>