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