Issue #1016038 by arrrgh: Avoid "Undefined Index" error.
[project/nitobe.git] / nitobe.utils.inc
1 <?php
2 /**
3 * @file
4 * Various utility functions used by Nitobe.
5 */
6
7 /** The cache variable to store the header list in. */
8 define("NITOBE_CACHE_HDR", "nitobe.headers.list");
9
10 /** The path to the headers in the current theme, falling back to Nitobe if
11 * the headers directory is not present in the sub-theme. */
12 define("NITOBE_HEADER_PATH",
13 (is_dir(path_to_theme() . "/headers") ?
14 path_to_theme() : drupal_get_path("theme", "nitobe")) . "/headers");
15
16 /** The mask to use when listing the headers directory. */
17 define("NITOBE_HEADER_IMG_MASK",
18 "/\\.jpg$|\\.JPG$|\\.jpeg*|\\.JPEG*|\\.gif$|\\.GIF$|\\.png$|\\.PNG$/");
19
20
21 /**
22 * Contextually adds 960 Grid System classes.
23 *
24 * The first parameter passed is the *default class*. All other parameters must
25 * be set in pairs like so: "$variable, 3". The variable can be anything
26 * available within a template file and the integer is the width set for the
27 * adjacent box containing that variable.
28 *
29 * @code
30 * class="<?php print ns('grid-16', $var_a, 6); ?>"
31 * @endcode
32 *
33 * If $var_a contains data, the next parameter (integer) will be subtracted from
34 * the default class. See the README.txt file.
35 */
36 function nitobe_ns() {
37 $args = func_get_args();
38 $default = array_shift($args);
39
40 // -- Get the type of class, i.e., 'grid', 'pull', 'push', etc.
41 // -- Also get the default unit for the type to be procesed and returned.
42 list($type, $return_unit) = explode('-', $default);
43
44 // -- Process the conditions.
45 $flip_states = array('var' => 'int', 'int' => 'var');
46 $state = 'var';
47 $var_state = FALSE;
48
49 foreach ($args as $arg) {
50 if ($state == 'var') {
51 $var_state = !empty($arg);
52 }
53 elseif ($var_state) {
54 $return_unit = $return_unit - $arg;
55 }
56 $state = $flip_states[$state];
57 }
58
59 $output = '';
60 // -- Anything below a value of 1 is not needed.
61 if ($return_unit > 0) {
62 $output = $type . '-' . $return_unit;
63 }
64 return $output;
65 }
66
67
68 /**
69 * Gets the push/pull classes for the various layout options.
70 *
71 * @return array
72 * A nested array of layout and class information. The array's values are
73 * accesed with $push_pull[$placement][$layout][$region] such that:
74 * - $placement is one of left or center and indicates where the
75 * sidebars are placed relative to the content. A 'right' placement is
76 * not provided since this is the natural layout.
77 * - $layout is one of left, right, or both and indicates which sidebars
78 * are present.
79 * - $region is one of content, sidebar_first, sidebar_second and indicates
80 * which region push/pull classes are wanted for.
81 */
82 function _nitobe_get_push_pull() {
83 $push_pull = array(
84 "center" => array(
85 "left" => array(
86 "content" => "push-4",
87 "sidebar_first" => "pull-12",
88 ),
89 "both" => array(
90 "content" => "push-4",
91 "sidebar_first" => "pull-8",
92 ),
93 ),
94 "left" => array(
95 "left" => array(
96 "content" => "push-4",
97 "sidebar_first" => "pull-12",
98 ),
99 "right" => array(
100 "content" => "push-4",
101 "sidebar_second" => "pull-12",
102 ),
103 "both" => array(
104 "content" => "push-8",
105 "sidebar_first" => "pull-8",
106 "sidebar_second" => "pull-8",
107 ),
108 ),
109 );
110
111 return $push_pull;
112 }
113
114
115 /**
116 * Copies selected items from one array to another array by key.
117 *
118 * For each item in $keys, if that key exists in $source, copy the key-value
119 * pair from $source to &$destination. In the event of duplicate keys, the
120 * value of a key in $source will replace the value in &$destination.
121 *
122 * @param array $source
123 * A keyed array of values to copy from.
124 * @param array &$destination
125 * The array to copy to.
126 * @param array $keys
127 * An array of keys to copy from $source to &$destination.
128 */
129 function _nitobe_copy_if_exists($source, &$destination, $keys) {
130 foreach ($keys as $key) {
131 if (array_key_exists($key, $source)) {
132 $destination[$key] = $source[$key];
133 }
134 }
135 }
136
137
138 /**
139 * Retrieves a list of header images.
140 *
141 * Scans the headers directory and generate a "pretty" name for each. Pretty
142 * names are generated from the image's path within the headers directory using
143 * these rules:
144 * -# '/' is replaced with ' / '
145 * -# '_' is replaced with ' '.
146 * -# '.***' extension is removed.
147 *
148 * @param boolean $refresh
149 * If TRUE, reload the image list and flush the cached version.
150 *
151 * @return array
152 * A mapping of the headers' pretty names to their actual names.
153 */
154 function _nitobe_get_header_list($refresh = FALSE) {
155 // -- If caching is disabled, force a refresh.
156 if (!$refresh && (variable_get('cache', 0) == 0)) {
157 $refresh = TRUE;
158 }
159
160 $cached = cache_get(NITOBE_CACHE_HDR);
161 $files = (!empty($cached)) ? $cached->data : NULL;
162
163 if (($files == NULL) OR ($refresh == TRUE)) {
164 $files = file_scan_directory(NITOBE_HEADER_PATH,
165 NITOBE_HEADER_IMG_MASK,
166 array('.', '..', 'CVS', '.svn'));
167 foreach ($files as $filename => $data) {
168 $name = substr($filename, strlen(NITOBE_HEADER_PATH) + 1);
169 $name = preg_replace('/\//', ' / ', $name);
170 $name = preg_replace('/_/', ' ', $name);
171 $name = preg_replace('/\.(\w{3,4}$)/', '', $name);
172
173 $data->pretty_name = $name;
174 }
175
176 // -- Cache the list for a week.
177 cache_set(NITOBE_CACHE_HDR, $files, 'cache', time() + 604800);
178 }
179
180 return $files;
181 }