common.php 9.48 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php

function unl_load_zend_framework() {
  static $isLoaded = FALSE;

  if ($isLoaded) {
    return;
  }

  set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/../../../libraries');
  require_once 'Zend/Loader/Autoloader.php';
  $autoloader = Zend_Loader_Autoloader::getInstance();
  $autoloader->registerNamespace('Unl_');
  $isLoaded = TRUE;
}

/**
18
19
 * Custom function to get the db settings for the 'main' site.
 * @return array
20
 */
21
function unl_get_shared_db_settings() {
22
23
24
25
  if (file_exists(DRUPAL_ROOT . '/sites/all/settings.php')) {
    require DRUPAL_ROOT . '/sites/all/settings.php';
  }
  require DRUPAL_ROOT . '/sites/default/settings.php';
26
27
28
29
30
31
32
33
34
  
  return $databases;
}

/**
 * Custom function to get the db prefix of the 'main' site.
 */
function unl_get_shared_db_prefix() {
  $databases = unl_get_shared_db_settings();
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
  $shared_prefix = $databases['default']['default']['prefix'];

  return $shared_prefix;
}

/**
 * Custom function.
 */
function unl_shared_variable_get($name, $default = NULL) {
  $shared_prefix = unl_get_shared_db_prefix();
  $data = db_query(
    "SELECT * "
    . "FROM {$shared_prefix}variable "
    . "WHERE name = :name",
    array(':name' => $name)
  )->fetchAll();

  if (count($data) == 0) {
    return $default;
  }

  return unserialize($data[0]->value);
}
58

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
function unl_site_variable_get($db_prefix, $name, $default = NULL) {
  $shared_prefix = unl_get_shared_db_prefix();
  $data = db_query(
    "SELECT * "
    . "FROM {$db_prefix}_{$shared_prefix}variable "
    . "WHERE name = :name",
    array(':name' => $name)
  )->fetchAll();

  if (count($data) == 0) {
    return $default;
  }

  return unserialize($data[0]->value);
}

75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/**
 * Given a URI, will return the name of the directory for that site in the sites directory.
 */
function unl_get_sites_subdir($uri, $trim_subdomain = TRUE) {
  $path_parts = parse_url($uri);
  if ($trim_subdomain && substr($path_parts['host'], -7) == 'unl.edu') {
    $path_parts['host'] = 'unl.edu';
  }
  $sites_subdir = $path_parts['host'] . $path_parts['path'];
  $sites_subdir = strtr($sites_subdir, array('/' => '.'));

  while (substr($sites_subdir, 0, 1) == '.') {
    $sites_subdir = substr($sites_subdir, 1);
  }
  while (substr($sites_subdir, -1) == '.') {
    $sites_subdir = substr($sites_subdir, 0, -1);
  }

  return $sites_subdir;
}

/**
 * Given a URI of an existing site, will return settings defined in that site's settings.php
 */
function unl_get_site_settings($uri) {
  $settings_file = DRUPAL_ROOT . '/sites/' . unl_get_sites_subdir($uri) . '/settings.php';
  if (!is_readable($settings_file)) {
    throw new Exception('No settings.php exists for site at ' . $uri);
  }
104

105
106
107
  if (is_readable(DRUPAL_ROOT . '/sites/all/settings.php')) {
    require DRUPAL_ROOT . '/sites/all/settings.php';
  }
108

109
110
111
  require $settings_file;
  unset($uri);
  unset($settings_file);
112

113
  return get_defined_vars();
114
}
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129

/**
 * Custom function that returns TRUE if the given table is shared with another site.
 * @param string $table_name
 */
function unl_table_is_shared($table_name) {
  $db_config = $GLOBALS['databases']['default']['default'];
  if (is_array($db_config['prefix']) &&
      isset($db_config['prefix']['role']) &&
      $db_config['prefix']['default'] != $db_config['prefix'][$table_name]) {
    return TRUE;
  }
  return FALSE;
}

130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/**
 * Custom function that formats a string of HTML using Tidy
 * @param string $string
 */
function unl_tidy($string) {
  if (class_exists('Tidy') && variable_get('unl_tidy')) {
    $tidy = new Tidy();

    // Tidy options: http://tidy.sourceforge.net/docs/quickref.html
    $options = array(
      // HTML, XHTML, XML Options
      'doctype' => 'omit',
      'new-blocklevel-tags' => 'article,aside,header,footer,section,nav,hgroup,address,figure,figcaption,output',
      'new-inline-tags' => 'video,audio,canvas,ruby,rt,rp,time,code,kbd,samp,var,mark,bdi,bdo,wbr,details,datalist,source,summary',
      'output-xhtml' => true,
      'show-body-only' => true,
      // Pretty Print
      'indent' => true,
      'indent-spaces' => 2,
      'vertical-space' => false,
      'wrap' => 140,
      'wrap-attributes' => false,
      // Misc
      'force-output' => true,
      'quiet' => true,
      'tidy-mark' => false,
    );

158
159
    // Add &nbsp; to prevent Tidy from removing script or comment if it is the first thing
    if (strtolower(substr(trim($string), 0, 7)) == '<script' || substr(trim($string), 0, 4) == '<!--') {
160
161
      $statement = '';
      if (substr(trim($string), 0, 9) !== '<!-- Tidy') {
162
        $statement = "<!-- Tidy: Start field with something other than script or comment to remove this -->\n";
163
164
      }
      $string = "&nbsp;" . $statement . $string;
165
166
167
168
169
170
171
172
173
174
175
    }

    $tidy->parseString($string, $options, 'utf8');
    if ($tidy->cleanRepair()) {
      return $tidy;
    }
  }

  return $string;
}

176
177
178
179
180
/**
 * A shared-table safe method that returns TRUE if the user is a member of the super-admin role.
 */
function unl_user_is_administrator() {
  $user = $GLOBALS['user'];
181

182
183
184
185
  // If the role table is shared, use parent site's user_admin role, otherwise use the local value.
  if (unl_table_is_shared('role')) {
    $admin_role_id = unl_shared_variable_get('user_admin_role');
  }
186
187
188
189
  else {
    $admin_role_id = variable_get('user_admin_role');
  }

190
191
192
  if ($user && in_array($admin_role_id, array_keys($user->roles))) {
    return TRUE;
  }
193

194
195
  return FALSE;
}
196
197
198
199
200
201
202

/**
 * Fetch the contents at the given URL and cache the result using
 * drupal's cache for as long as the response headers allow.
 * @param string $url
 * @param resource $context
 */
203
function unl_url_get_contents($url, $context = NULL, &$headers = array())
204
{
205
206
  unl_load_zend_framework();
  if (!Zend_Uri::check($url)) {
207
    watchdog('unl', 'A non-url was passed to %func().', array('%func' => __FUNCTION__), WATCHDOG_WARNING);
208
209
210
    return FALSE;
  }
  
211
212
213
214
215
216
217
218
  // get some per-request static storage
  $static = &drupal_static(__FUNCTION__);
  if (!isset($static)) {
    $static = array();
  }
  
  // If cached in the static array, return it.
  if (array_key_exists($url, $static)) {
219
    $headers = $static[$url]['headers'];
220
221
222
223

    // Don't let this page be cached since it contains uncacheable content.
    $GLOBALS['conf']['cache'] = FALSE;

224
    return $static[$url]['body'];
225
226
  }
  
227
  // If cached in the drupal cache, return it.
228
229
  $data = cache_get(__FUNCTION__ . $url);
  if ($data && time() < $data->data['expires']) {
230
    $headers = $data->data['headers'];
231
232
233
234

    // Don't let this page be cached any longer than the retrieved content.
    $GLOBALS['conf']['page_cache_maximum_age'] = min(variable_get('page_cache_maximum_age', 0), $data->data['expires'] - time());

235
236
237
    return $data->data['body'];
  }

238
239
240
241
242
  if (!$context) {
    // Set a 5 second timeout
    $context = stream_context_create(array('http' => array('timeout' => 5)));
  }

243
244
245
  // Make the request
  $http_response_header = array();
  $body = file_get_contents($url, NULL, $context);
246
247
248
249
250
251
252
  
  // If an error occured, just return it now.
  if ($body === FALSE) {
    $static[$url] = $body;
    return $body;
  }
  
253
254
  $headers = array();
  foreach ($http_response_header as $rawHeader) {
255
    $headerName = trim(substr($rawHeader, 0, strpos($rawHeader, ':')));
256
257
258
259
260
    $headerValue = trim(substr($rawHeader, strpos($rawHeader, ':') + 1));
    if ($headerName && $headerValue) {
      $headers[$headerName] = $headerValue;
    }
  }
261
  $lowercaseHeaders = array_change_key_case($headers);
262
263
264
265
266
  
  $cacheable = NULL;
  $expires = 0;
  
  // Check for a Cache-Control header and the max-age and/or private headers.
267
268
  if (array_key_exists('cache-control', $lowercaseHeaders)) {
    $cacheControl = strtolower($lowercaseHeaders['cache-control']);
269
270
271
    $matches = array();
    if (preg_match('/max-age=([0-9]+)/', $cacheControl, $matches)) {
      $expires = time() + $matches[1];
272
273
274
275
276
277
278
      if (array_key_exists('age', $lowercaseHeaders)) {
        $expires -= $lowercaseHeaders['age'];
      }

      if ($expires > time()) {
        $cacheable = TRUE;
      }
279
280
281
282
283
284
285
286
287
    }
    if (strpos($cacheControl, 'private') !== FALSE) {
      $cacheable = FALSE;
    }
    if (strpos($cacheControl, 'no-cache') !== FALSE) {
      $cacheable = FALSE;
    }
  }
  // If there was no Cache-Control header, or if it wasn't helpful, check for an Expires header.
288
  if ($cacheable === NULL && array_key_exists('expires', $lowercaseHeaders)) {
289
    $cacheable = TRUE;
290
    $expires = DateTime::createFromFormat(DateTime::RFC1123, $lowercaseHeaders['expires'])->getTimestamp();
291
292
293
294
295
296
  }
  
  // Save to the drupal cache if caching is ok
  if ($cacheable && time() < $expires) {
    $data = array(
      'body' => $body,
297
      'headers' => $headers,
298
299
300
      'expires' => $expires,
    );
    cache_set(__FUNCTION__ . $url, $data, 'cache', $expires);
301
302
303

    // Don't let this page be cached any longer than the retrieved content.
    $GLOBALS['conf']['page_cache_maximum_age'] = min(variable_get('page_cache_maximum_age', 0), $expires - time());
304
305
306
  }
  // Otherwise just save to the static per-request cache
  else {
307
308
309
310
    $static[$url] = array(
        'body' => $body,
        'headers' => $headers,
    );
311
312
313

    // Don't let this page be cached since it contains uncacheable content.
    $GLOBALS['conf']['cache'] = FALSE;
314
315
316
317
  }
  
  return $body;
}
318
319
320
321
322
323
324
325
326
327
328
329
330

/**
 * Drop-in replacement for db_select that creates a query on default site's database.
 * @see db_select
 * @return SelectQuery
 */
function unl_shared_db_select($table, $alias = NULL, array $options = array()) {
  $databases = unl_get_shared_db_settings();
  Database::addConnectionInfo('default', 'unl_parent_site', $databases['default']['default']);
  $options['target'] = 'unl_parent_site';
  
  return db_select($table, $alias, $options);
}