$end) { continue; } elseif ($i < (1 << $length)) { --$length; } $current = ''; for ($j = $length; $j >= 0; $j--) { if ($i & (1 << $j)) { $current .= $parts[$length - $j]; } else { $current .= is_numeric($parts[$length - $j]) ? '#' : '%'; } if ($j) { $current .= '/'; } } $placeholders[] = "'%s'"; $ancestors[] = $current; if (stristr($current, '#') !== FALSE) { $placeholders[] = "'%s'"; $ancestors[] = str_replace('#', '%', $current); } } return array($ancestors, $placeholders); } /** * Function _themekey_match_paths(). */ function _themekey_match_paths($path) { // $parts = explode('/', $path, MENU_MAX_PARTS); list($ancestors, $placeholders) = _themekey_get_path_ancestors($parts); // $result = db_query('SELECT * FROM {themekey_paths} WHERE path IN ('. implode(',', $placeholders) .') ORDER BY fit DESC, weight DESC, custom DESC', $ancestors); while ($item = db_fetch_array($result)) { $parameters = module_invoke_all('themekey_global'); $conditions = unserialize($item['conditions']); // $wildcards = unserialize($item['wildcards']); foreach ($wildcards as $index => $wildcard) { $parameters[$wildcard] = arg($index, $path); } // if (!_themekey_match_conditions($conditions, $parameters)) { continue; } // $callbacks = unserialize($item['callbacks']); if (count($callbacks)) { foreach ($callbacks as $callback) { $callback($item, $parameters); } } // if (!$item['theme']) { $item['theme'] = _themekey_match_properties($parameters); } return $item['theme']; } return NULL; } /* Property-based */ /** * Function _themkey_prepare_object(). */ function _themkey_prepare_object($object) { $parameters = array('#raw' => $object); $properties = variable_get('themekey_properties', array()); foreach ($properties as $property => $details) { if (($value = _themekey_property_field($object, $details['path'])) != NULL) { $parameters[$property] = $value; } } return $parameters; } /** * Function _themekey_property_field(). */ function _themekey_property_field($value, $path) { // $parts = explode('/', $path); foreach ($parts as $part) { if (is_array($value) && isset($value[$part])) { $value = (array)$value[$part]; } else { return NULL; } } return is_array($value) ? array_keys($value) : $value; } /** * Function _themekey_match_properties(). */ function _themekey_match_properties($parameters, $object = NULL) { // if (isset($object)) { $parameters = _themkey_prepare_object(array_merge($parameters, (array)drupal_clone($object))); } // $properties = variable_get('themekey_properties', array()); foreach (array_keys($properties) as $property) { $value = _themekey_property_value($parameters, $property); if (!empty($value) || count($value)) { $query = 'SELECT * FROM {themekey_properties} WHERE property = \''. $property .'\' AND value '; $query .= is_array($value) ? ('IN ('. db_placeholders($value, 'varchar') .') ORDER BY weight') : '= \'%s\''; $result = db_query($query, $value); while ($item = db_fetch_array($result)) { // $item['conditions'] = unserialize($item['conditions']); if (_themekey_match_conditions($item['conditions'], $parameters)) { // $callbacks = unserialize($item['callbacks']); if (is_array($callbacks) && count($callbacks)) { foreach ($callbacks as $callback) { $callback($item, $parameters); } } // return $item['theme']; } } } } return NULL; } /** * Function _themekey_match_conditions(). */ function _themekey_match_conditions($conditions, $parameters) { if (is_array($conditions) && count($conditions)) { foreach ($conditions as $condition) { // $value = _themekey_property_value($parameters, $condition['property']); if (is_array($value)) { // if (!in_array($condition['value'], $value)) { return FALSE; } } else { // Default operator is 'equal' if (!isset($condition['operator'])) { $condition['operator'] = '='; } // Supported operators for condition check: // smaller ('<'), greater ('>'), equal ('='), not equal ('!') if ($condition['operator'] == '<' && $value >= $condition['value']) { return FALSE; } else if ($condition['operator'] == '>' && $value <= $condition['value']) { return FALSE; } else if ($condition['operator'] == '=' && $value != $condition['value']) { return FALSE; } else if ($condition['operator'] == '!' && $value == $condition['value']) { return FALSE; } } } } return TRUE; } /** * Function _themekey_property_value(). */ function _themekey_property_value($parameters, $property) { // Property value is available directly if (isset($parameters[$property])) { return $parameters[$property]; } // Try to get property value utilizing mapped properties $nidmap = array('src' => FALSE, 'dst' => FALSE); $uidmap = array('src' => FALSE, 'dst' => FALSE); $maps = variable_get('themekey_maps', array()); foreach ($maps as $pos => $map) { if (isset($parameters[$map['src']]) && $map['dst'] == 'node:nid') { $nidmap['src'] = $pos; } if (isset($parameters[$map['src']]) && $map['dst'] == 'user:uid') { $uidmap['src'] = $pos; } if ($map['src'] == 'node:nid' && $map['dst'] == $property) { $nidmap['dst'] = $pos; } if ($map['src'] == 'user:uid' && $map['dst'] == $property) { $uidmap['dst'] = $pos; } if (isset($parameters[$map['src']]) && $map['dst'] == $property) { $map_func = $map['callback']; return $map_func($parameters[$map['src']], $parameters); } } // Support mapping via node id (src -> node:nid -> dst) if ($nidmap['src'] !== FALSE && $nidmap['dst'] !== FALSE) { $src_func = $maps[$nidmap['src']]['callback']; $dst_func = $maps[$nidmap['dst']]['callback']; return $dst_func($src_func($parameters[$maps[$nidmap['src']]['src']], $parameters), $parameters); } // Support mapping via user id (src -> user:uid -> dst) if ($uidmap['src'] !== FALSE && $uidmap['dst'] !== FALSE) { $src_func = $maps[$uidmap['src']]['callback']; $dst_func = $maps[$uidmap['dst']]['callback']; return $dst_func($src_func($parameters[$maps[$uidmap['src']]['src']], $parameters), $parameters); } return NULL; }