5 * Utility and wrapper functions for the advagg module.
9 * Given path output uri to that file
11 function advagg_build_uri($path) {
12 static
$hook_file_url_alter = array();
14 // If the current path is an absolute path, return immediately.
15 $fragments = parse_url($path);
16 if (isset($fragments['host'])) {
20 $original_path = $path;
22 if (module_exists('cdn')) {
23 $status = variable_get(CDN_STATUS_VARIABLE
, CDN_DISABLED
);
24 if ($status == CDN_ENABLED
|| ($status == CDN_TESTING
&& user_access(CDN_PERM_ACCESS_TESTING
))) {
25 // Alter URL when the file_create_url() patch is not there.
26 if (variable_get(CDN_THEME_LAYER_FALLBACK_VARIABLE
, FALSE
)) {
27 cdn_file_url_alter($path);
29 // Use the patched version of file_create_url().
31 $path = file_create_url($path);
33 // Return here if the path was changed above.
34 if (strcmp($original_path, $path) != 0) {
40 // Other modules besides CDN might want to use hook_file_url_alter.
41 if (empty($hook_file_url_alter)) {
42 $hook_file_url_alter = module_implements('file_url_alter');
44 if (!empty($hook_file_url_alter)) {
45 $path = file_create_url($path);
46 // Return here if the path was changed above.
47 if (strcmp($original_path, $path) != 0) {
52 // If nothing was altered then use the drupal default.
53 return base_path() .
$path;
57 * Helper function to build an URL for asynchronous requests.
60 * Path to a URI excluding everything to the left and including the base path.
62 function _advagg_build_url($filepath = '') {
67 if (isset($_SERVER['AUTH_TYPE']) && $_SERVER['AUTH_TYPE'] == 'Basic') {
68 $auth = $_SERVER['PHP_AUTH_USER'] .
':' .
$_SERVER['PHP_AUTH_PW'] .
'@';
72 $ip = variable_get('advagg_server_addr', FALSE
);
74 $ip = $_SERVER['HTTP_HOST'];
77 $ip = empty($_SERVER['SERVER_ADDR']) ?
'127.0.0.1' : $_SERVER['SERVER_ADDR'];
82 // if ( isset($_SERVER['SERVER_PORT'])
83 // && is_numeric($_SERVER['SERVER_PORT'])
84 // && ($_SERVER['SERVER_PORT'] != 80 || $_SERVER['SERVER_PORT'] != 443)
86 // $port = ':' . $_SERVER['SERVER_PORT'];
88 return 'http://' .
$auth .
$ip .
$port .
$base_path .
$filepath;
92 * Wrapper around clearstatcache so it can use php 5.3's new features.
94 * @param $clear_realpath_cache
99 * value from clearstatcache().
101 function advagg_clearstatcache($clear_realpath_cache = FALSE
, $filename = NULL
) {
103 if (!isset($php530)) {
104 $php530 = version_compare(PHP_VERSION
, '5.3.0', '>=');
108 return clearstatcache($clear_realpath_cache, $filename);
111 return clearstatcache();
116 * Helper function to determine if the cookie to bypass aggregation is active.
119 * TRUE if enabled, FALSE otherwise.
121 function advagg_cookie_bypass() {
122 return !empty($_COOKIE[ADVAGG_COOKIE_NAME
]) && $_COOKIE[ADVAGG_COOKIE_NAME
] === md5(drupal_get_private_key()) ? TRUE
: FALSE
;
126 * Select records in the database matching where IN(...).
128 * NOTE Be aware of the servers max_packet_size variable.
131 * The name of the table.
133 * field name to be compared to
134 * @param $placeholder
135 * db_query placeholders; like %d or '%s'
137 * array of values you wish to compare to
139 * array of db fields you return
141 * returns db_query() result.
143 function advagg_db_multi_select_in($table, $field, $placeholder, $data, $returns = array(), $groupby = '') {
144 // Set returns if empty
145 if (empty($returns)) {
148 // Get the number of rows that will be inserted
149 $rows = count($data);
150 // Create what goes in the IN ()
152 // Add the rest of the place holders
153 for ($i = 1; $i < $rows; $i++) {
154 $in .
= ', ' .
$placeholder;
157 $query = "SELECT " .
implode(', ', $returns) .
" FROM {" .
$table .
"} WHERE $field IN ($in) $groupby";
159 // TODO Please convert this statement to the D7 database API syntax.
160 return db_query($query, $data);
164 * Get the CSS & JS path for advagg.
170 * public://advagg_css,
171 * sites/default/files/advagg_css,
174 * public://advagg_js,
175 * sites/default/files/advagg_js,
179 function advagg_get_root_files_dir() {
182 // Make sure directories are available and writable.
183 if (empty($css_path) || empty($js_path)) {
184 $css_path = 'public://advagg_css';
185 $js_path = 'public://advagg_js';
186 file_prepare_directory($css_path, FILE_CREATE_DIRECTORY
);
187 file_prepare_directory($js_path, FILE_CREATE_DIRECTORY
);
188 $css_path = parse_url(file_create_url($css_path));
189 $js_path = parse_url(file_create_url($js_path));
191 return array(ltrim($css_path['path'], '/'), ltrim($js_path['path'], '/'));
195 * Return the server schema (http or https).
199 * @TODO: We probably should use relative references instead of trying to
200 * determine it based on the $_SERVER array.
201 * @see: http://tools.ietf.org/html/rfc3986#section-4.2
202 * @see: http://paulirish.com/2010/the-protocol-relative-url
203 * @see: http://www.stevesouders.com/blog/2010/02/10/5a-missing-schema-double-download/
205 function advagg_get_server_schema() {
206 return ( (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on')
207 || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
208 || (isset($_SERVER['HTTP_HTTPS']) && $_SERVER['HTTP_HTTPS'] == 'on')
209 ) ?
'https' : 'http';
213 * Always return TRUE, used for array_map in advagg_css_js_file_builder().
215 function advagg_return_true() {
220 * See if a string ends with a substring.
223 * The main string being compared.
225 * The secondary string being compared.
229 function advagg_string_ends_with($haystack, $needle) {
230 // Define substr_compare if it doesn't exist (PHP 4 fix).
231 if (!function_exists('substr_compare')) {
233 * Binary safe comparison of two strings from an offset, up to length
236 * Compares main_str from position offset with str up to length characters.
237 * @see http://php.net/substr-compare#53084
240 * The main string being compared.
242 * The secondary string being compared.
244 * The start position for the comparison. If negative, it starts counting
245 * from the end of the string.
247 * The length of the comparison. The default value is the largest of the
248 * length of the str compared to the length of main_str less the offset.
249 * @param $case_insensitivity
250 * If TRUE, comparison is case insensitive.
252 * Returns < 0 if main_str from position offset is less than str, > 0 if
253 * it is greater than str, and 0 if they are equal. If offset is equal to
254 * or greater than the length of main_str or length is set and is less than
255 * 1, substr_compare() prints a warning and returns FALSE.
257 function substr_compare($main_str, $str, $offset, $length = NULL
, $case_insensitivity = FALSE
) {
258 $offset = (int) $offset;
260 // Throw a warning because the offset is invalid
261 if ($offset >= strlen($main_str)) {
262 trigger_error('The start position cannot exceed initial string length.', E_USER_WARNING
);
266 // We are comparing the first n-characters of each string, so let's use the PHP function to do it
267 if ($offset == 0 && is_int($length) && $case_insensitivity === TRUE
) {
268 return strncasecmp($main_str, $str, $length);
271 // Get the substring that we are comparing
272 if (is_int($length)) {
273 $main_substr = substr($main_str, $offset, $length);
274 $str_substr = substr($str, 0, $length);
277 $main_substr = substr($main_str, $offset);
281 // Return a case-insensitive comparison of the two strings
282 if ($case_insensitivity === TRUE
) {
283 return strcasecmp($main_substr, $str_substr);
286 // Return a case-sensitive comparison of the two strings
287 return strcmp($main_substr, $str_substr);
291 $haystack_len = strlen($haystack);
292 $needle_len = strlen($needle);
293 if ($needle_len > $haystack_len) {
296 return substr_compare($haystack, $needle, $haystack_len -$needle_len, $needle_len, TRUE
) === 0;
299 if (!function_exists('array_merge_recursive_distinct')) {
301 * Merges any number of arrays / parameters recursively, replacing
302 * entries with string keys with values from latter arrays.
303 * If the entry or the next value to be assigned is an array, then it
304 * automagically treats both arguments as an array.
305 * Numeric entries are appended, not replaced, but only if they are
308 * calling: result = array_merge_recursive_distinct(a1, a2, ... aN)
311 function array_merge_recursive_distinct () {
312 $arrays = func_get_args();
313 $base = array_shift($arrays);
314 if(!is_array($base)) $base = empty($base) ?
array() : array($base);
315 foreach($arrays as
$append) {
316 if(!is_array($append)) $append = array($append);
317 foreach($append as
$key => $value) {
318 if(!array_key_exists($key, $base) and
!is_numeric($key)) {
319 $base[$key] = $append[$key];
322 if(is_array($value) or
is_array($base[$key])) {
323 $base[$key] = array_merge_recursive_distinct($base[$key], $append[$key]);
324 } else if(is_numeric($key)) {
325 if(!in_array($value, $base)) $base[] = $value;
327 $base[$key] = $value;