/[drupal]/contributions/modules/imagemenu/imagemenu.module
ViewVC logotype

Contents of /contributions/modules/imagemenu/imagemenu.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.7 - (show annotations) (download) (as text)
Fri Mar 21 17:27:28 2008 UTC (20 months ago) by nwilsmir
Branch: MAIN
CVS Tags: DRUPAL-6--1-0-RC1, DRUPAL-6--1-0-RC2, HEAD
Branch point for: DRUPAL-6--1
Changes since 1.6: +333 -516 lines
File MIME type: text/x-php
Initial release for Drupal 6.x
1 <?php
2 // $Id$
3
4 /**
5 * Implementation of hook_help (2008/02/25 updated for Drupal 6.x compatibility)
6 */
7 function imagemenu_help($path, $arg) {
8 switch ($path) {
9 case 'admin/help#imagemenu':
10 $output = '<p>'. t('A simple module which allows you to create menus from image files. Supports title (displayed when hovering over a menu item), alt text, weights and optional mouseover behaviour.') .'</p>';
11 $output = '<p>'. t('This module is loosely based on Drupals own menu module') .'</p>';
12 $output .= '<p>'. t('You\'re not restricted to only displaying an imagemenu within the supplied block, you can also enable a filter in admin/filters and display several different imagemenus within a page/ node without any conflicts for the mouseovers (note that if you display two or more of the same imagemenu on one page then the mouseovers will NOT work as the image name tags will conflict).') .'</p>';
13 return $output;
14 case 'admin/build/menu/imagemenu':
15 return '<p>'. t('A simple module which allows you to create menus from image files. Supports title (displayed when hovering over a menu item), alt text, weights and optional mouseover behaviour.') .'</p>';
16 case 'admin/build/menu/imagemenu/add':
17 return '<p>'. t('Enter the name for your new menu. Remember to enable the newly created block in the <a href="@blocks">blocks administration page</a>.', array('@blocks' => url('admin/build/block'))) .'</p>';
18 case 'admin/build/menu/imagemenu-customize/%':
19 return '<p>'. t('To rearrange menu items, grab a drag-and-drop handle under the <em>Menu item</em> column and drag the items (or group of items) to a new location in the list. (Grab a handle by clicking and holding the mouse while hovering over a handle icon.) Remember that your changes will not be saved until you click the <em>Save configuration</em> button at the bottom of the page.') .'<p>';
20 case 'admin/build/menu/imagemenu-customize/%/add':
21 return '<p>'. t('Enter the title and image path for your new menu item. Leave <em>Path</em> field empty to add menu delimiter.') .'</p>';
22 }
23 }
24
25 /**
26 * Implementation of hook_filter_tips
27 */
28 function imagemenu_filter_tips($delta, $format, $long = false) {
29 if ($long) {
30 return t('You can embed imagemenus into your nodes using the following syntax:<br>
31 [imagemenu:<em>menu_id</em>]<br>
32 Ensure that you don\'t have two of the same menus on the screen at any one
33 time else the rollover links will not work correctly (as the images will have
34 the same name tag).');
35 }
36 else {
37 return t('You can embed imagemenus into your nodes using the following syntax:<br>
38 [imagemenu:<em>menu_id</em>]');
39 }
40 }
41
42 /**
43 * Implementation of hook_filter
44 */
45 function imagemenu_filter($op, $delta = 0, $format = -1, $text = '') {
46 switch ($op) {
47 case 'list':
48 return (array(0 => t('Imagemenu filter')));
49 case 'name':
50 return t('Imagemenu filter');
51 case 'no cache':
52 return TRUE;
53 case 'description':
54 return t('Allows a user to insert an imagemenu into a node.');
55 case 'process':
56 return _imagemenu_process_text($text);
57 default:
58 return $text;
59 }
60 }
61
62 function _imagemenu_process_text($text) {
63 $pattern = "/\[imagemenu:(\d+)\]/i";
64 if (preg_match_all($pattern, $text, $matches)) {
65 foreach ($matches[1] as $no => $match) {
66 $text = str_replace($matches[0][$no], imagemenu_display($matches[1][$no]), $text);
67 }
68 }
69 return $text;
70 }
71
72 /**
73 * Implementation of hook_menu (2008/02/25 updated for Drupal 6.x compatibility)
74 */
75 function imagemenu_menu() {
76 $items = array();
77 $admin_access = array('administer imagemenu');
78
79 $items['admin/build/menu/imagemenu'] = array(
80 'title' => 'Imagemenus',
81 'page callback' => 'imagemenu_overview_page',
82 'access callback' => 'user_access',
83 'access arguments' => $admin_access,
84 'file' => 'imagemenu.admin.inc',
85 'weight' => -1,
86 );
87 $items['admin/build/menu/imagemenu/list'] = array(
88 'title' => 'List menus',
89 'type' => MENU_DEFAULT_LOCAL_TASK,
90 'weight' => -10,
91 'file' => 'imagemenu.admin.inc',
92 );
93 $items['admin/build/menu/imagemenu/add'] = array(
94 'title' => 'Add menu',
95 'page callback' => 'drupal_get_form',
96 'page arguments' => array('imagemenu_edit_menu', 'add'),
97 'type' => MENU_LOCAL_TASK,
98 'file' => 'imagemenu.admin.inc',
99 );
100 $items['admin/build/menu/imagemenu/settings'] = array(
101 'title' => 'Settings',
102 'page callback' => 'drupal_get_form',
103 'page arguments' => array('imagemenu_configure'),
104 'type' => MENU_LOCAL_TASK,
105 'weight' => 5,
106 'file' => 'imagemenu.admin.inc',
107 );
108 $items['admin/build/menu/imagemenu-customize/%imagemenu'] = array(
109 'title' => 'Customize menu',
110 'page callback' => 'drupal_get_form',
111 'page arguments' => array('imagemenu_overview_form', 4),
112 'title callback' => 'imagemenu_overview_title',
113 'title arguments' => array(4),
114 'access arguments' => $admin_access,
115 'type' => MENU_CALLBACK,
116 'file' => 'imagemenu.admin.inc',
117 );
118 $items['admin/build/menu/imagemenu-customize/%imagemenu/list'] = array(
119 'title' => 'List items',
120 'weight' => -10,
121 'type' => MENU_DEFAULT_LOCAL_TASK,
122 'file' => 'imagemenu.admin.inc',
123 );
124 $items['admin/build/menu/imagemenu-customize/%imagemenu/add'] = array(
125 'title' => 'Add item',
126 'page callback' => 'drupal_get_form',
127 'page arguments' => array('imagemenu_edit_item', 'add', NULL, 4),
128 'type' => MENU_LOCAL_TASK,
129 'file' => 'imagemenu.admin.inc',
130 );
131 $items['admin/build/menu/imagemenu-customize/%imagemenu/edit'] = array(
132 'title' => 'Edit menu',
133 'page callback' => 'drupal_get_form',
134 'page arguments' => array('imagemenu_edit_menu', 'edit', 4),
135 'type' => MENU_LOCAL_TASK,
136 'file' => 'imagemenu.admin.inc',
137 );
138 $items['admin/build/menu/imagemenu-customize/%imagemenu/delete'] = array(
139 'title' => 'Delete menu',
140 'page callback' => 'drupal_get_form',
141 'page arguments' => array('imagemenu_delete_menu_confirm', 4),
142 'type' => MENU_CALLBACK,
143 'file' => 'imagemenu.admin.inc',
144 );
145
146
147 $items['admin/build/menu/imagemenu/item/%imagemenu_link/edit'] = array(
148 'title' => 'Edit menu item',
149 'page callback' => 'drupal_get_form',
150 'page arguments' => array('imagemenu_edit_item', 'edit', 5, NULL),
151 'type' => MENU_CALLBACK,
152 'file' => 'imagemenu.admin.inc',
153 );
154 $items['admin/build/menu/imagemenu/item/%imagemenu_link/delete'] = array(
155 'title' => 'Delete menu item',
156 'page callback' => 'drupal_get_form',
157 'page arguments' => array('imagemenu_item_delete_form', 5),
158 'type' => MENU_CALLBACK,
159 'file' => 'imagemenu.admin.inc',
160 );
161
162 return $items;
163 }
164
165 /**
166 * Implementation of hook_perm
167 */
168 function imagemenu_perm() {
169 return array('administer imagemenu');
170 }
171
172 /**
173 * Implementation of hook_block().
174 */
175 function imagemenu_block($op = 'list', $delta = 0) {
176 $menus = imagemenu_base_rows();
177 if ($op == 'list') {
178 $blocks = array();
179 if (!empty($menus)) {
180 foreach ($menus as $mid => $title) {
181 $blocks[$mid]['info'] = check_plain($title);
182 $blocks[$mid]['cache'] = BLOCK_NO_CACHE;
183 }
184 }
185 return $blocks;
186 }
187 else if ($op == 'view') {
188 $data['subject'] = check_plain($menus[$delta]);
189 $data['content'] = imagemenu_display($delta);
190 return $data;
191 }
192 }
193
194 /**
195 * Implemenation of hook_theme().
196 */
197 function imagemenu_theme() {
198 return array(
199 'imagemenu_overview_form' => array(
200 'file' => 'imagemenu.admin.inc',
201 'arguments' => array('form' => NULL),
202 ),
203 'imagemenu_item' => array(
204 'arguments' => array('item', 'has_children', 'prefix' => '', 'layout' => 'vertical', 'menu' => ''),
205 ),
206 'imagemenu_tree' => array(
207 'arguments' => array('tree' => NULL),
208 ),
209 );
210 }
211
212 /**
213 * Title callback for the menu overview page and links.
214 */
215 function imagemenu_overview_title($menu) {
216 return $menu['title'];
217 }
218
219 /**
220 * Load the data for a single menu.
221 */
222 function imagemenu_load($mid) {
223 if (!is_numeric($mid) || (!($menu = imagemenu_display($mid, TRUE)) && !imagemenu_exists($mid))) {
224 drupal_not_found();
225 return;
226 }
227 return db_fetch_array(db_query("SELECT mid, title, description FROM {imagemenu} WHERE mid = %d", $mid));
228 }
229
230 /**
231 * Load the data for a single menu item.
232 */
233 function imagemenu_link_load($mid) {
234 if (!is_numeric($mid) || (!imagemenu_exists($mid))) {
235 drupal_not_found();
236 return;
237 }
238 return db_fetch_array(db_query("SELECT * FROM {imagemenu} WHERE mid = %d", $mid));
239 }
240
241 function imagemenu_base_rows() {
242 $query = db_query('SELECT mid, title FROM {imagemenu} WHERE pid = %d ORDER BY weight, title', 0);
243 while ($menu = db_fetch_object($query)) {
244 $output[$menu->mid] = $menu->title;
245 }
246 return $output;
247 }
248
249 function imagemenu_display($mid, $full = FALSE) {
250 if (!$mid || !is_numeric($mid)) {
251 return FALSE;
252 }
253 $menus = imagemenu_tree_data($mid, FALSE);
254 $output = imagemenu_build_output($menus, variable_get('imagemenu_layout', 'vertical'));
255 return $output;
256 }
257
258 /**
259 * Returns TRUE if menu with given menu id exists.
260 */
261 function imagemenu_exists($mid) {
262 if (!$mid) return FALSE;
263 $query = db_fetch_object(db_query('SELECT mid FROM {imagemenu} WHERE mid = %d', $mid));
264 if ($query) {
265 return TRUE;
266 }
267 else {
268 return FALSE;
269 }
270 }
271
272 function imagemenu_fetch_rows($pid = 0, $full = FALSE, $depth = 0, $output = array()) {
273 $entries = imagemenu_return_row($pid, $depth);
274 $depth++;
275 foreach ($entries as $mid => $entry) {
276 if ($entry['enabled'] || $full) {
277 $output[$mid] = $entry;
278 if (imagemenu_check_children($mid)) {
279 unset($visible_tree);
280 $output[$mid]['has_children'] = TRUE;
281 $visible = imagemenu_show_visible_tree($mid);
282 if (array_key_exists($mid, $visible)) $visible_tree = TRUE;
283 foreach ($visible as $no => $tmp) {
284 if (in_array($mid, $tmp)) $visible_tree = TRUE;
285 }
286 if ($entry['type'] || $full || $visible_tree) {
287 $output = imagemenu_fetch_rows($mid, $full, $depth, $output);
288 }
289 }
290 }
291 }
292 return $output;
293 }
294
295 function imagemenu_return_row($pid, $depth = 0) {
296 $output = array();
297 $query = db_query('SELECT * FROM {imagemenu} WHERE pid = %d ORDER BY weight, title', $pid);
298 while ($item = db_fetch_object($query)) {
299 $output[$item->mid] = array('mid' => $item->mid, 'pid' => $item->pid, 'title' => $item->title, 'alt' => $item->alt, 'mouseover' => $item->mouseover, 'description' => $item->description, 'path' => $item->path, 'imagepath' => $item->imagepath, 'enabled' => $item->enabled, 'type' => $item->type, 'weight' => $item->weight, 'depth' => $depth);
300 }
301 return $output;
302 }
303
304 function imagemenu_check_children($parent) {
305 $query = db_query('SELECT mid FROM {imagemenu} WHERE pid = %d ORDER BY weight, title', $parent);
306 while ($item = db_fetch_object($query)) {
307 return $item->mid;
308 }
309 return FALSE;
310 }
311
312 function imagemenu_show_visible_tree() {
313 $path = $_GET['q'];
314 $output = array();
315 $mids = array();
316 if ($path == 'node' || !$path) $path = '<front>';
317 $query = db_query("SELECT mid FROM {imagemenu} WHERE path = '%s' ORDER BY mid", $path);
318 while ($tmp = db_fetch_object($query)) {
319 $mids[] = $tmp->mid;
320 }
321 foreach ($mids as $mid) {
322 $array = array();
323 $tmp = $mid;
324 while ($item = _imagemenu_return_parent($tmp)) {
325 $tmp = $item;
326 $array[] = $item;
327 }
328 $output[$mid] = $array;
329 }
330 return $output;
331 }
332
333 function _imagemenu_return_parent($mid) {
334 $query = db_fetch_object(db_query("SELECT pid FROM {imagemenu} WHERE mid = %d", $mid));
335 return $query->pid;
336 }
337
338 function imagemenu_parents($mid = 0) {
339 if (arg(6) == "edit") {
340 $mid = imagemenu_find_parent($mid);
341 }
342 elseif (!$mid) {
343 // Okay we're here because we need to show ALL the menus
344 // so here goes;
345 $menus = imagemenu_base_rows();
346 foreach ($menus as $mid => $title) {
347 $output[$mid] = imagemenu_parents($mid);
348 }
349 return $output;
350 }
351 $output[$mid] = '<' . imagemenu_fetch_title($mid) . '>';
352 $menus = imagemenu_fetch_rows($mid, TRUE);
353 // Prefix was updated to look like original menu parents prefix
354 foreach ($menus as $menu) {
355 $temp = imagemenu_fetch_mid($menu['mid']);
356 $prefix = '--';
357 if ($menu['depth']) {
358 $prefix .= '--';
359 for ($i = 1; $i < $menu['depth']; $i++) {
360 $prefix .= '--';
361 }
362 }
363 $prefix .= ' ';
364 $output[$menu['mid']] = $prefix.$temp['title'];
365 }
366 return $output;
367 }
368
369 /**
370 * Load menu by given menu id.
371 */
372 function imagemenu_fetch_mid($mid) {
373 $query = db_query('SELECT * FROM {imagemenu} WHERE mid = %d', $mid);
374 $output = db_fetch_array($query);
375 return $output ? $output : FALSE;
376 }
377
378 /**
379 * Returns menu title by given menu id.
380 */
381 function imagemenu_fetch_title($mid) {
382 $query = db_query('SELECT title FROM {imagemenu} WHERE mid = %d', $mid);
383 $item = db_fetch_object($query);
384 return $item->title;
385 }
386
387 function imagemenu_find_parent($pid) {
388 $query = db_query('SELECT mid FROM {imagemenu} WHERE pid = %d', 0);
389 while ($menus = db_fetch_array($query)) {
390 $menu = imagemenu_fetch_rows($menus['mid']);
391 foreach ($menu as $item) {
392 if ($item['mid'] == $pid || !$pid) return $menus['mid'];
393 }
394 }
395 return FALSE;
396 }
397
398 function imagemenu_build_output($menus, $layout) {
399 foreach ($menus as $menu) {
400 $has_children = empty($menu['link']['has_children']) ? 0 : $menu['link']['has_children'];
401 if ($menu['below']) {
402 $output .= theme('imagemenu_item', $menu['link'], $has_children, $mid, $layout, imagemenu_build_output($menu['below'], $layout));
403 }
404 else {
405 $output .= theme('imagemenu_item', $menu['link'], $has_children, $mid, $layout, '');
406 }
407 }
408 return $output ? theme('imagemenu_tree', $output) : '';
409 }
410
411 /**
412 * Generate the HTML output for a imagemenu item
413 */
414 function theme_imagemenu_item($item, $has_children, $prefix = '', $layout = 'vertical', $menu = '') {
415 $class = ($menu ? 'expanded' : ($has_children ? 'collapsed' : 'leaf'));
416 switch ($layout) {
417 case 'vertical':
418 $listyle = '';
419 break;
420 case 'horizontal':
421 $listyle = ' style="float:left;"';
422 break;
423 }
424 $script = $item['mouseover'] ? ' onMouseOver="document.imagemenu_'.$prefix.'_'.$item['mid'].'.src=\''.base_path().$item['mouseover'].'\'" onMouseOut="document.imagemenu_'.$prefix.'_'.$item['mid'].'.src=\''.base_path().$item['imagepath'].'\'"' : '';
425 if (!empty($item['path'])) {
426 $output = '<li class="'. $class .'"'. $listyle .'><a href="'.url($item['path']).'"><img src="'.base_path().$item['imagepath'].'" alt="'.$item['alt'].'" title="'.$item['title'].'" name="imagemenu_'.$prefix.'_'.$item['mid'].'"'.$script.' /></a>'. $menu .'</li>';
427 }
428 else {
429 $output = '<li class="delimiter"'. $listyle .'><img src="'.base_path().$item['imagepath'].'" />'. $menu .'</li>';
430 }
431 return $output;
432 }
433
434 /**
435 * Generate the HTML output for a imagemenu tree
436 */
437 function theme_imagemenu_tree($tree) {
438 $output = '<ul class="imagemenu">'. $tree .'</ul>';
439 return $output;
440 }
441
442 /**
443 * Build the data representing a menu tree.
444 */
445 function imagemenu_tree_data($mid, $full = TRUE) {
446 $depth = 0;
447 list(, $tree) = _imagemenu_tree_data($mid, $depth, $full);
448 return $tree;
449 }
450
451 /**
452 * Recursive helper function to build the data representing a menu tree.
453 */
454 function _imagemenu_tree_data($mid, $depth, $full = TRUE, $previous_element = '', $parsed = 0) {
455 $remnant = NULL;
456 $tree = array();
457 $menus = imagemenu_fetch_rows($mid, $full);
458 array_splice($menus, 0, $parsed);
459
460 foreach ($menus as $tmid => $item) {
461
462 // The current item is the first in a new submenu.
463 if ($item['depth'] > $depth) {
464 // _menu_tree returns an item and the menu tree structure.
465 list($item, $below) = _imagemenu_tree_data($mid, $item['depth'], $full, $item, $parsed);
466 if ($previous_element) {
467 $tree[$previous_element['mid']] = array(
468 'link' => $previous_element,
469 'below' => $below,
470 );
471 }
472 else {
473 $tree = $below;
474 }
475 // We need to fall back one level.
476 if (!isset($item) || $item['depth'] < $depth) {
477 return array($item, $tree);
478 }
479 // This will be the link to be output in the next iteration.
480 $previous_element = $item;
481 }
482 // We are at the same depth, so we use the previous element.
483 elseif ($item['depth'] == $depth) {
484 if ($previous_element) {
485 // Only the first time.
486 $tree[$previous_element['mid']] = array(
487 'link' => $previous_element,
488 'below' => FALSE,
489 );
490 }
491 // This will be the link to be output in the next iteration.
492 $previous_element = $item;
493 }
494 // The submenu ended with the previous item, so pass back the current item.
495 else {
496 $remnant = $item;
497 break;
498 }
499
500 $parsed++;
501 }
502 if ($previous_element) {
503 // We have one more link dangling.
504 $tree[$previous_element['mid']] = array(
505 'link' => $previous_element,
506 'below' => FALSE,
507 );
508 }
509 return array($remnant, $tree);
510 }

  ViewVC Help
Powered by ViewVC 1.1.2