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

Contents of /contributions/modules/netforum_views/netforum_views.module

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


Revision 1.10 - (show annotations) (download) (as text)
Mon Jan 7 04:44:34 2008 UTC (22 months, 2 weeks ago) by jamesmichaelhill
Branch: MAIN
CVS Tags: DRUPAL-5--0-8-2, HEAD
Changes since 1.9: +4 -1 lines
File MIME type: text/x-php
fixed small javascript bug
1 <?php
2 // $Id: netforum_views.module,v 1.9 2007/12/14 05:10:38 jamesmichaelhill Exp $
3
4 /**
5 * @file
6 * The netFORUM Views module
7 *
8 * Uses the netFORUM xWeb module to fetch a list of Objects from netFORUM and
9 * turn them into a page or a block for viewing. It integrates tightly with the netFORUM
10 * Dynamic Facade Nodes module and uses the same syntax, but provides a different user interface
11 * and means of viewing a list.
12 *
13 * Many functions and behavior of this module is patterend, copied, or adapted from the Views module
14 *
15 */
16
17
18 /*
19 * Implementation of hook_help()
20 */
21 function netforum_views_help($section) {
22 switch ($section) {
23 case 'admin/help#netforum_views':
24 return _netforum_views_help_add();
25 case 'admin/build/netforum_views':
26 return t('This screen shows all of the netFORUM views that are currently defined in your system.');
27 }
28 }
29
30 /*
31 * Because the add/edit page is kind of complicated.
32 */
33 function _netforum_views_help_add() {
34 $output = t('<p>A netforum view retrieves some information from netFORUM and displays it in a variety of formats, much like the Views module.</p>');
35 $output .= t("<p>netFORUM views uses the same template format as !nfn.</p>\n", array("!nfn" => l(t('netFORUM nodes'), 'admin/help/netforum_node')));
36 $output .= t("<p>Here's an example to show a list of ten upcoming meetings</p>");
37 $output .= t("<pre>
38 {BeginList}
39 {BeginObjectName}Event @TOP 10{EndObjectName}
40 {BeginWhere}evt_start_date > '{currentdate}' {EndWhere}
41 {BeginColumns}evt_title, evt_start_date{EndColumns}
42 {BeginOrderBy}evt_start_date desc {EndOrderBy}
43 {BeginDetail}{ListRowNumber} - {BeginLink}{evt_title}{EndLink} - {evt_start_date}{EndDetail}
44 {EndList}
45 There are {ListRowCount} upcoming events!
46 </pre>");
47 $output .= t("<p>Blocks and pages can also accept parameters and turn them into curly brackets to use with queries. Since text between {BeginWhere} and {EndWhere}
48 is checked for conditional statements and curly brackets, clever use of parameters and links can be used to create a searchable directory of content. For example, if you had a view
49 that provided a page, and the url was www.example.com/individuals, then if you allowed get arguments and an argument called first_name_starts_with you could write a list with this where clause:
50 <pre>{BeginWhere}
51 ind_delete_flag = 0
52 {?first_name_starts_with!=''? AND ind_first_name like '{first_name_starts_with}%'??}
53 {EndWhere}</pre>
54 when someone went to www.example.com/individuals&fist_name_starts_with=jim the where clause would expand to
55 <pre>ind_delete_flag = 0 and ind_first_name like 'jim%'</pre>
56 and only people who's first name started with jim would be returned from netFORUM.</p><br><br>");
57 return $output;
58 }
59
60 /*
61 * Implementation of hook_perm()
62 */
63 function netforum_views_perm() {
64 return array('administer netFORUM views', 'access all netFORUM views');
65 }
66
67 /*
68 * Implementation of hook_menu()
69 */
70 function netforum_views_menu($may_cache) {
71 $items = array();
72
73 if ($may_cache) {
74 $items[] = array('path' => 'admin/build/netforum_views',
75 'title' => t('netFORUM views'),
76 'callback' => 'netforum_views_admin_page',
77 'access' => user_access('administer netFORUM views'),
78 'description' => t('Views are customized lists of content on your system; they are highly configurable and give you control over how lists of content are presented.'),
79 'type' => MENU_NORMAL_ITEM);
80 $items[] = array('path' => 'admin/build/netforum_views/list',
81 'title' => t('List'),
82 'callback' => 'netforum_views_admin_page',
83 'access' => user_access('administer netFORUM views'),
84 'type' => MENU_DEFAULT_LOCAL_TASK,
85 'weight' => '-1');
86 $items[] = array('path' => 'admin/build/netforum_views/add',
87 'title' => t('Add'),
88 'callback' => 'netforum_views_admin_add_page',
89 'access' => user_access('administer netFORUM views'),
90 'type' => MENU_LOCAL_TASK);
91 $items[] = array('path' => 'admin/build/netforum_views/delete',
92 'title' => t('Edit view'),
93 'callback' => 'drupal_get_form',
94 'callback arguments' => array('netforum_views_admin_delete_confirm'),
95 'access' => user_access('administer netFORUM views'),
96 'type' => MENU_CALLBACK);
97 $items[] = array('path' => 'admin/build/netforum_views/refresh',
98 'title' => t('Refresh View'),
99 'callback' => 'netforum_views_refresh_data',
100 'access' => user_access('administer netFORUM views'),
101 'type' => MENU_CALLBACK);
102 netforum_views_menu_standard_items($items);
103 }
104 else {
105 if (user_access('administer netFORUM views') &&
106 arg(0) == 'admin' &&
107 arg(1) == 'build' &&
108 arg(2) == 'netforum_views') {
109 $view = _netforum_views_load_view(arg(3));
110 if ($view) {
111 netforum_views_add_menu_items($items, $view, 'admin/build/netforum_views/' . arg(3), TRUE);
112 }
113 }
114 netforum_views_menu_inline_items($items);
115 }
116 return $items;
117 }
118
119 function netforum_views_add_menu_items(&$items, $view, $url, $base = TRUE, $args = array()) {
120 if (user_access('administer netFORUM views')) {
121 if ($base) {
122 // we also have to add the administrative 'view' of the view in some
123 // cases
124 $items[] = array('path' => $url,
125 'title' => t('View'),
126 'callback' => 'netforum_views_view_page',
127 'callback arguments' => array_merge(array($view->name), $args),
128 'access' => user_access('administer netFORUM views'),
129 'type' => MENU_CALLBACK);
130 }
131 $items[] = array('path' => "$url/view",
132 'title' => t('View'),
133 'callback' => 'netforum_views_view_page',
134 'callback arguments' => array_merge(array($view->name), $args),
135 'access' => user_access('administer netFORUM views'),
136 'weight' => -10,
137 'type' => MENU_DEFAULT_LOCAL_TASK);
138 $items[] = array('path' => "$url/edit",
139 'title' => t('Edit'),
140 'callback' => 'netforum_views_admin_edit_page',
141 'callback arguments' => array($view->name),
142 'access' => user_access('administer netFORUM views'),
143 'weight' => -5,
144 'type' => MENU_LOCAL_TASK);
145 $items[] = array('path' => "$url/refresh",
146 'title' => t('Refresh netFORUM data'),
147 'callback' => 'netforum_views_refresh_data',
148 'callback arguments' => array($view->vid, false),
149 'access' => user_access('administer netFORUM views'),
150 'weight' => 0,
151 'type' => MENU_LOCAL_TASK);
152 }
153 }
154
155 /**
156 * Add the menu items for all non-inline views to the menu
157 */
158 function netforum_views_menu_standard_items(&$items) {
159 $result = db_query("SELECT * FROM {netforum_view} WHERE page = 1");
160
161 while ($view = db_fetch_object($result)) {
162 // unpack the array
163 $view->access = ($view->access ? explode(', ', $view->access) : array());
164
165 _netforum_views_create_menu_item($items, $view, $view->url);
166 }
167 }
168
169 /**
170 * Helper function to add a menu item for a view.
171 */
172 function _netforum_views_create_menu_item(&$items, $view, $path, $local_task_type = MENU_NORMAL_ITEM, $args = array()) {
173 $title = filter_xss_admin(netforum_views_get_title($view, 'menu'));
174 $type = _netforum_views_menu_type($view);
175 if ($type == MENU_LOCAL_TASK || $type == MENU_DEFAULT_LOCAL_TASK) {
176 $weight = $view->menu_tab_weight;
177 }
178 $access = netforum_views_access($view);
179 $items[] = _netforum_views_menu_item($path, $title, $view, $args, $access, $type, $weight);
180
181 if ($type == MENU_DEFAULT_LOCAL_TASK) {
182 switch ($view->menu_tab_default_parent_type) {
183 case 'tab':
184 $parent_type = MENU_LOCAL_TASK;
185 break;
186 case 'normal':
187 $parent_type = MENU_NORMAL_ITEM;
188 break;
189 case 'existing':
190 $parent_type = 0;
191 break;
192 }
193 if ($parent_type) {
194 $title = filter_xss_admin(netforum_views_get_title($view, 'menu-parent'));
195 $weight = $view->menu_parent_tab_weight;
196 $items[] = _netforum_views_menu_item(dirname($path), $title, $view, $args, $access, $parent_type, $weight);
197 }
198 }
199 }
200
201 /**
202 * Helper function to create a menu item for a view.
203 */
204 function _netforum_views_menu_item($path, $title, $view, $args, $access, $type, $weight = NULL) {
205 array_unshift($args, $view->name);
206 $retval = array('path' => $path,
207 'title' => $title,
208 'callback' => 'netforum_views_view_page',
209 'callback arguments' => $args,
210 'access' => user_access('access content') && $access,
211 'type' => $type,
212 );
213 if ($weight !== NULL) {
214 $retval['weight'] = $weight;
215 }
216 return $retval;
217 }
218
219 function _netforum_views_menu_type($view) {
220 if ($view->menu) {
221 if ($view->menu_tab_default) {
222 $type = MENU_DEFAULT_LOCAL_TASK;
223 }
224 else if ($view->menu_tab) {
225 $type = MENU_LOCAL_TASK;
226 }
227 else {
228 $type = MENU_NORMAL_ITEM;
229 }
230 }
231 else {
232 $type = MENU_CALLBACK;
233 }
234 return $type;
235 }
236
237
238 function netforum_views_menu_inline_items(&$items) {
239 $args = explode('/', $_GET['q']);
240 $urls = netforum_views_get_all_urls();
241 foreach ($urls as $view_name => $url) {
242 if ($url{0} != '$' && strpos($url, '/$') === FALSE) {
243 if (user_access('administer netFORUM views')) {
244 $view_args = $args;
245
246 foreach (explode('/', $url) as $num => $element) {
247 if ($element != $args[$num]) {
248 continue 2;
249 }
250 unset($view_args[$num]);
251 }
252 netforum_views_menu_admin_items($items, $view_name, $view_args, $args);
253 }
254 }
255 else {
256 // Do substitution on args.
257 $use_view = $use_menu = FALSE;
258 $menu_args = $view_args = $menu_path = array();
259
260 foreach (explode('/', $url) as $num => $element) {
261 if ($element{0} == '$') {
262 // If we pass the token check, this view is definitely being used.
263 list($token, $argument) = explode('-', $element);
264 if ($tokens[$token] && function_exists($tokens[$token])) {
265 if (!($use_view = $use_menu = $tokens[$token]($element, $argument, arg($num)))) {
266 break;
267 }
268 }
269 $menu_path[] = $view_args[] = arg($num);
270 }
271 else {
272 unset($menu_args[$num]);
273 $menu_path[] = $element;
274 if ($element != arg($num)) {
275 $use_menu = FALSE;
276 }
277 }
278 // we are only using views that match our URL, up to the
279 // point where we hit an inline arg.
280 if (!$use_view && $element != arg($num)) {
281 break;
282 }
283 }
284 if ($use_view) {
285 $path = implode('/', $menu_path);
286 $view = netforum_views_get_view($view_name);
287 $view->args = $view_args;
288 _netforum_views_create_menu_item($items, $view, $path, MENU_CALLBACK, $view_args);
289 }
290
291 if (user_access('administer netFORUM views') && $use_menu) {
292 netforum_views_menu_admin_items($items, $view_name, $menu_args, $args);
293 }
294 }
295 }
296 }
297
298 /**
299 * Load all of the URLs we use; this is cached in a special manner
300 * in an attempt to make the menu system both flexible and yet not
301 * overly intensive.
302 */
303 function netforum_views_get_all_urls() {
304 $cache = cache_get("netforum_views_urls");
305 if ($cache == 0) {
306 $views = array();
307 $used = array();
308 // avoid creating empty path items by requiring an URL to be set
309 $result = db_query("SELECT name, url FROM {netforum_view} WHERE page = 1 AND LENGTH(url) > 0");
310
311 while ($view = db_fetch_object($result)) {
312 $views[$view->name] = $view->url;
313 }
314
315 cache_set("netforum_views_urls", 'cache', serialize($views));
316 }
317 else {
318 $views = unserialize($cache->data);
319 }
320
321 return $views;
322 }
323
324 /**
325 * Add the adminstrative items to a view.
326 */
327 function netforum_views_menu_admin_items(&$items, $view_name, $view_args, $args) {
328 // Remove args that are tabs from $args.
329 $tabs = array('edit', 'view', 'add', 'refresh');
330 // See what the last arg is.
331 $last_arg = array_pop($args);
332 if (in_array($last_arg, $tabs)) {
333 array_pop($view_args);
334 }
335 else {
336 $args[] = $last_arg;
337 }
338 $view = netforum_views_get_view($view_name);
339 $path = implode('/', $args);
340 netforum_views_add_menu_items($items, $view, $path, $path != $_GET['q'] && !empty($view_args), $view_args);
341 }
342
343 // ---------------------------------------------------------------------------
344 // Administrative Pages
345
346 /*
347 * This page lists all system views and provides links to edit them.
348 */
349 function netforum_views_admin_page() {
350
351 $numViews = 25;
352
353 drupal_set_title(t('administer netFORUM views'));
354
355 $result = pager_query("SELECT vid, name, description, menu_title, page_title, block_title, url, page, menu, block FROM {netforum_view} ORDER BY name", $numViews);
356
357 while ($view = db_fetch_object($result)) {
358 $url = ($view->page ? l($view->url, $view->url) : t('No Page View'));
359 $provides = array();
360 if ($view->page) {
361 $provides[] = 'Page';
362 }
363 if ($view->block) {
364 $provides[] = 'Block';
365 }
366 if ($view->menu) {
367 $provides[] = 'Menu';
368 }
369
370 $items[] = array(
371 $view->name,
372 filter_xss_admin(netforum_views_get_title($view, 'admin')),
373 $view->description,
374 implode(', ', $provides),
375 $url,
376 theme('links', array(
377 array('title' => t('Edit'), 'href' => "admin/build/netforum_views/$view->name/edit"),
378 array('title' => t('Refresh'), 'href' => "admin/build/netforum_views/refresh/$view->vid"),
379 array('title' => t('Delete'), 'href' => "admin/build/netforum_views/delete/$view->vid"),
380 ))
381 );
382 }
383
384 if ($items) {
385 $output = theme('table', array(t('View'), t('Title'), t('Description'), t('Provides'), t('URL'), t('Actions')), $items, array("cellpadding" => "4"), t('Existing Views'));
386 $output .= theme('pager', NULL, $numViews);
387 }
388 else {
389 $output .= t('<p>No views have currently been defined.</p>');
390 }
391
392 return $output;
393 }
394
395 /*
396 * Provide a form to add a view. Allow adding a view from default templates.
397 */
398 function netforum_views_admin_add_page($template = NULL) {
399
400 $op = $_POST['op'];
401 if ($op == t('Cancel')) {
402 drupal_goto('admin/build/netforum_views');
403 }
404
405 drupal_set_title(t('Add a netFORUM View'));
406
407 return drupal_get_form('netforum_views_edit_view', $view, $op);
408 }
409
410 /*
411 * Provide a form to edit a view.
412 */
413 function netforum_views_admin_edit_page($vid = '') {
414
415 $op = $_POST['op'];
416 if ($op == t('Cancel')) {
417 drupal_goto('admin/build/netforum_views');
418 }
419
420 if ($op == t('Delete')) {
421 drupal_goto("admin/build/netforum_views/delete/$vid");
422 }
423
424 if (!($view = _netforum_views_load_view($vid))) {
425 drupal_goto('admin/build/netforum_views');
426 }
427
428 drupal_set_title(t('Edit view %n', array('%n' => $view->name)));
429 return drupal_get_form('netforum_views_edit_view', $view, $op);
430 }
431
432 /*
433 * Provide a form to confirm deletion of a view.
434 */
435 function netforum_views_admin_delete_confirm($vid = '') {
436 $view = _netforum_views_load_view($vid);
437
438 if (!$view) {
439 return drupal_goto('admin/build/netforum_views');
440 }
441
442 $form['vid'] = array('#type' => 'value', '#value' => $view->vid);
443 // bdragon note: Did you mean to drop the above line on the floor with this?
444 $form = confirm_form($form,
445 t('Are you sure you want to delete %title?', array('%title' => $view->name)),
446 $_GET['destination'] ? $_GET['destination'] : 'admin/build/netforum_views',
447 t('This action cannot be undone.'),
448 t('Delete'), t('Cancel')
449 );
450 return $form;
451 }
452
453 /*
454 * Handle the submit button to delete a view.
455 */
456 function netforum_views_admin_delete_confirm_submit($form_id, $form) {
457 _netforum_views_delete_view((object) $form);
458 menu_rebuild();
459 }
460
461 /*
462 * Get an empty view with basic defaults.
463 */
464 function _netforum_views_get_default_view() {
465 $view = new stdClass();
466 $view->use_pager = true;
467 $view->nodes_per_page = variable_get('default_nodes_main', 10);
468 $view->page_header_format = variable_get('filter_default_format', 1);
469 $view->page_footer_format = variable_get('filter_default_format', 1);
470 $view->page_header_format = variable_get('filter_default_format', 1);
471 $view->block_header_format = variable_get('filter_default_format', 1);
472 $view->block_footer_format = variable_get('filter_default_format', 1);
473 $view->block_header_format = variable_get('filter_default_format', 1);
474 $view->vid = 0;
475
476 return _views_check_arrays($view);
477 }
478
479 function netforum_views_build_list($view) {
480 //cheat a bunch.
481 $list_content = '';
482 if (! empty($_POST['obj_type_name'])) {
483 $list_content .= "{BeginList}\n";
484 $list_content .= "{BeginObjectName}". filter_xss_admin($_POST['obj_type_name']) ."{EndObjectName}\n";
485 if (! empty($_POST['query_name'])) {
486 $list_content .= "{BeginQueryName}". filter_xss_admin($_POST['query_name']) ."{EndQueryName}\n";
487 }
488 else if (! empty($_POST['query_where']) && !empty($_POST['query_columns'])) {
489 $list_content .= "{BeginColumns} ". filter_xss_admin($_POST['query_columns']) ." {EndColumns}\n";
490 $list_content .= "{BeginWhere} ". filter_xss_admin($_POST['query_where']) ." {EndWhere}\n";
491 if (!empty($_POST['query_orderby'])) {
492 $list_content .= "{BeginOrderBy} ". filter_xss_admin($_POST['query_orderby']) ."{EndOrderBy}\n";
493 }
494 }
495 $list_content .= "{BeginDetail} Everything in this section will be displayed for each result {EndDetail}\n";
496 $list_content .= "{EndList}\n";
497 }
498 return $list_content;
499 }
500
501 /**
502 * Determines if there is enough information to build a view query.
503 *
504 * This helps cut down on problems of people accidentally overwriting their view
505 *
506 */
507 function netforum_views_valid_build_request($view) {
508 if (! empty($_POST['obj_type_name'])) {
509 if (! empty($_POST['query_name'])) {
510 return true;
511 }
512 else if (! empty($_POST['query_where']) && !empty($_POST['query_columns'])) {
513 return true;
514 }
515 }
516 return false;
517 }
518
519 /**
520 * Display all the guts of a view in a form for editing.
521 */
522 function netforum_views_edit_view($view, $op = '') {
523 drupal_add_js(drupal_get_path('module', 'netforum_views') .'/jquery.netforum_views.js');
524 drupal_set_html_head("<script type=\"text/javascript\">
525 var BASE_URL = '". base_path() ."';
526 </script>");
527
528 // Put in all our add buttons, then process them to see if they've been hit.
529 $form = array();
530
531 if ($_POST['edit'] && $op != t('Save')) {
532 drupal_set_message(t('You have modified this view; changes will not be recorded until you Save the form.'));
533 }
534
535
536 $form['vid'] = array(
537 '#type' => 'value',
538 '#value' => $view->vid,
539 );
540 $form['allbut'] = array(
541 '#type' => 'value',
542 '#value' => $allbut,
543 );
544 $form['changed'] = array(
545 '#type' => 'hidden',
546 '#value' => $view->changed,
547 );
548
549 $form['basic-info'] = array(
550 '#type' => 'fieldset',
551 '#collapsible' => true,
552 '#collapsed' => ($allbut != NULL),
553 '#title' => t('Basic Information'),
554 );
555
556 $form['basic-info']['name'] = array(
557 '#type' => 'textfield',
558 '#title' => t('Name'),
559 '#default_value' => $view->name,
560 '#size' => 20,
561 '#maxlength' => 32,
562 '#description' => t('The unique identifier of the view; it is only important for overridden views and views that modules or themes will need to use. Only alphanumeric and _ allowed here'),
563 '#required' => true,
564 );
565
566 $form['basic-info']['access'] = array(
567 '#type' => 'checkboxes',
568 '#title' => t('Access'),
569 '#default_value' => $view->access,
570 '#options' => netforum_views_handler_filter_role(),
571 '#description' => t('Only the checked roles will be able to see this view in any form; if no roles are checked, access will not be restricted.'),
572 );
573
574 $form['basic-info']['description'] = array(
575 '#type' => 'textfield',
576 '#title' => t('Description'),
577 '#default_value' => $view->description,
578 '#size' => 60,
579 '#maxlength' => 255,
580 '#description' => t('A description of the view for the admin list.'),
581 );
582
583 // page info
584
585 $form['page-info'] = array(
586 '#type' => 'fieldset',
587 '#collapsible' => true,
588 '#collapsed' => ($allbut != NULL || !$view->page),
589 '#title' => t('Page'),
590 );
591
592 $form['page-info']['page'] = array(
593 '#type' => 'checkbox',
594 '#title' => t('Provide Page View'),
595 '#return_value' => 1,
596 '#default_value' => $view->page,
597 '#description' => t('If checked this view will be provided as a page. If not checked, the fields in this group will be ignored.'),
598 );
599
600 $form['page-info']['url'] = array(
601 '#type' => 'textfield',
602 '#title' => t('URL'),
603 '#default_value' => $view->url,
604 '#size' => 60,
605 '#maxlength' => 255,
606 '#description' => t('Enter the URL to use for this view in the form of \'dir/dir\'. Do not begin or end the URL with a /. Example: \'view/tracker\'. This is required if providing a page view. You can also add $arg as a placeholder for arguments passed in the URL, for example \'user/$arg/tracker\' or \'node/$arg/related\'. Note that any arguments listed here will be required, even if they are listed as optional below. You do not need to list arguments at the end of the path. Do not try to use URLs such as taxonomy/term/$arg.'),
607 );
608
609 $form['page-info']['page_title'] = array(
610 '#type' => 'textfield',
611 '#title' => t('Title'),
612 '#default_value' => $view->page_title,
613 '#size' => 60,
614 '#maxlength' => 255,
615 '#description' => t('The title that be shown at the top of the view. May be blank. This title ignores arguments; if you want your title to take arguments into account, use the "title" field in the arguments section.'),
616 );
617
618 $form['page-info']['breadcrumb_no_home'] = array(
619 '#type' => 'checkbox',
620 '#title' => t('Breadcrumb trail should not include "Home"'),
621 '#return_value' => 1,
622 '#default_value' => $view->breadcrumb_no_home,
623 '#description' => t('If checked the breadcrumb trail for this page will discard "Home". Usually you will not set this, but this is used for the Front Page View, where it IS Home and should not leave a trail to itself.'),
624 );
625 $form['page-info']['page_header_fieldset'] = array(
626 '#type' => 'fieldset',
627 '#collapsible' => TRUE,
628 '#collapsed' => TRUE,
629 '#title' => t('Header'),
630 );
631 $form['page-info']['page_header_fieldset']['page_header'] = array(
632 '#type' => 'textarea',
633 '#default_value' => $view->page_header,
634 '#cols' => 60,
635 '#rows' => 6,
636 '#description' => t('Text to display at the top of the view. May contain an explanation or links or whatever you like. Optional.'),
637 );
638
639 $form['page-info']['page_header_fieldset']['page_header_format'] = filter_form($view->page_header_format, 1, array('page_header_format'));
640
641 $form['page-info']['page_footer_fieldset'] = array(
642 '#type' => 'fieldset',
643 '#collapsible' => TRUE,
644 '#collapsed' => TRUE,
645 '#title' => t('Footer'),
646 );
647 $form['page-info']['page_footer_fieldset']['page_footer'] = array(
648 '#type' => 'textarea',
649 '#default_value' => $view->page_footer,
650 '#cols' => 60,
651 '#rows' => 6,
652 '#description' => t('Text to display at the bottom of the view. May contain an explanation or links or whatever you like. Optional.'),
653 );
654
655 $form['page-info']['page_footer_fieldset']['page_footer_format'] = filter_form($view->page_footer_format, 1, array('page_footer_format'));
656
657 $form['page-info']['page_empty_fieldset'] = array(
658 '#type' => 'fieldset',
659 '#collapsible' => TRUE,
660 '#collapsed' => TRUE,
661 '#title' => t('Empty Text'),
662 );
663 $form['page-info']['page_empty_fieldset']['page_empty'] = array(
664 '#type' => 'textarea',
665 '#default_value' => $view->page_empty,
666 '#cols' => 60,
667 '#rows' => 6,
668 '#description' => t('Text to display if a view returns no nodes. Optional.'),
669 );
670
671 $form['page-info']['page_empty_fieldset']['page_empty_format'] = filter_form($view->page_empty_format, 1, array('page_empty_format'));
672
673 $form['page-info']['menu-info'] = array(
674 '#type' => 'fieldset',
675 '#collapsible' => TRUE,
676 '#collapsed' => TRUE,
677 '#title' => t('Menu'),
678 );
679
680 $form['page-info']['menu-info']['menu'] = array(
681 '#type' => 'checkbox',
682 '#title' => t('Provide Menu'),
683 '#return_value' => 1,
684 '#default_value' => $view->menu,
685 '#description' => t('If checked this view be given a menu entry in the Drupal menu system. If not checked the data in this group will be ignored.'),
686 );
687
688 $form['page-info']['menu-info']['menu_tab'] = array(
689 '#type' => 'checkbox',
690 '#title' => t('Provide Menu as Tab'),
691 '#return_value' => 1,
692 '#default_value' => $view->menu_tab,
693 '#description' => t("If checked this view's menu entry will be provided as a tab rather than in the main menu system."),
694 );
695
696 $form['page-info']['menu-info']['menu_tab_weight'] = array(
697 '#type' => 'textfield',
698 '#title' => t('Tab Weight'),
699 '#default_value' => $view->menu_tab_weight,
700 '#width' => 10,
701 '#description' => t('If this is a menu tab, select the weight; lower numbers will be further to the left.'),
702 );
703
704 $form['page-info']['menu-info']['menu_title'] = array(
705 '#type' => 'textfield',
706 '#title' => t('Menu Title'),
707 '#default_value' => $view->menu_title,
708 '#size' => 60,
709 '#maxlength' => 255,
710 '#description' => t('Enter the title to use for the menu entry or tab. If blank, the page title will be used.'),
711 );
712
713 $form['page-info']['menu-info']['default-tab'] = array(
714 '#type' => 'fieldset',
715 '#collapsible' => TRUE,
716 '#collapsed' => TRUE,
717 '#title' => t('Default Menu Tab'),
718 );
719
720 $form['page-info']['menu-info']['default-tab']['menu_tab_default'] = array(
721 '#type' => 'checkbox',
722 '#title' => t('Make Default Menu Tab'),
723 '#return_value' => 1,
724 '#default_value' => $view->menu_tab_default,
725 '#description' => t("If checked this view's menu entry will be provided as a tab, and will be the default tab for that URL path. For example, if the URL is 'tracker/all' and it is set as the default menu tab, it will be put into the menu as 'tracker' and 'tracker/all' will be the default tab. The following settings allow you to customize the parent item, for example 'tracker'. For tabs to work properly, one tab in the group must be set as the default."),
726 );
727
728 $form['page-info']['menu-info']['default-tab']['menu_tab_default_parent_type'] = array(
729 '#type' => 'select',
730 '#title' => t('Parent Menu Item Type'),
731 '#default_value' => $view->menu_tab_default_parent_type,
732 '#options' => array(
733 'tab' => t("Tab"),
734 'normal' => t("Normal menu item"),
735 'existing' => t("Already exists (don't create)"),
736 ),
737 '#description' => t("Select type of parent item to use for this default menu tab. You can either specify the parent should be a tab (the default), a normal menu item, or to use the menu item that already exists at the specified URL. For example, if the URL for the default tab is 'tracker/all', then 'tracker' would already have to be a valid menu item to use this final choice."),
738 );
739
740 $form['page-info']['menu-info']['default-tab']['menu_parent_tab_weight'] = array(
741 '#type' => 'textfield',
742 '#title' => t('Tab Weight'),
743 '#default_value' => $view->menu_parent_tab_weight,
744 '#width' => 10,
745 '#description' => t('If the parent menu item is a tab, select the weight; lower numbers will be further to the left.'),
746 );
747
748 $form['page-info']['menu-info']['default-tab']['menu_parent_title'] = array(
749 '#type' => 'textfield',
750 '#title' => t('Parent Menu Item Title'),
751 '#default_value' => $view->menu_parent_title,
752 '#size' => 60,
753 '#maxlength' => 255,
754 '#description' => t('If the Parent Menu Item is being defined by this view (if you set the %type_field to either %tab or %menu), you can specify its title here. If blank, the menu title will be used if that is defined, or the page title if not.', array('%type_field' => t('Parent Menu Item Type'), '%tab' => t('Tab'), '%menu' => t('Normal menu item'))),
755 );
756
757 // block info
758
759 $form['block-info'] = array(
760 '#type' => 'fieldset',
761 '#collapsible' => true,
762 '#collapsed' => ($allbut != NULL || !$view->block),
763 '#title' => t('Block'),
764 );
765
766 $form['block-info']['block'] = array(
767 '#type' => 'checkbox',
768 '#title' => t('Provide Block'),
769 '#return_value' => 1,
770 '#default_value' => $view->block,
771 '#description' => t('If checked this view will be provided as a block. If checked title may not be blank.'),
772 );
773
774 $form['block-info']['block_title'] = array(
775 '#type' => 'textfield',
776 '#title' => t('Title'),
777 '#default_value' => $view->block_title,
778 '#size' => 60,
779 '#maxlength' => 255,
780 '#description' => t('The title that will be shown at the top of the block. May be blank.'),
781 );
782
783 $form['block-info']['block_header_fieldset'] = array(
784 '#type' => 'fieldset',
785 '#collapsible' => TRUE,
786 '#collapsed' => TRUE,
787 '#title' => t('Header'),
788 );
789 $form['block-info']['block_header_fieldset']['block_use_page_header'] = array(
790 '#type' => 'checkbox',
791 '#title' => t('Use Page Header'),
792 '#return_value' => 1,
793 '#default_value' => $view->block_use_page_header,
794 '#description' => t('If checked, use the Page Header for block view instead. If so, you should leave the Block Header blank.'),
795 );
796
797 $form['block-info']['block_header_fieldset']['block_header'] = array(
798 '#type' => 'textarea',
799 '#title' => t('Header'),
800 '#default_value' => $view->block_header,
801 '#cols' => 60,
802 '#rows' => 6,
803 '#description' => t('Text to display at the top of the view. May contain an explanation or links or whatever you like. Optional.'),
804 );
805
806 $form['block-info']['block_header_fieldset']['block_header_format'] = filter_form($view->block_header_format, 1, array( 'block_header_format'));
807
808 $form['block-info']['block_footer_fieldset'] = array(
809 '#type' => 'fieldset',
810 '#collapsible' => TRUE,
811 '#collapsed' => TRUE,
812 '#title' => t('Footer'),
813 );
814 $form['block-info']['block_footer_fieldset']['block_use_page_footer'] = array(
815 '#type' => 'checkbox',
816 '#title' => t('Use Page Footer'),
817 '#return_value' => 1,
818 '#default_value' => $view->block_use_page_footer,
819 '#description' => t('If checked, use the page footer for block view instead. If so, you should leave the block footer blank.'),
820 );
821
822 $form['block-info']['block_footer_fieldset']['block_footer'] = array(
823 '#type' => 'textarea',
824 '#title' => t('Footer'),
825 '#default_value' => $view->block_footer,
826 '#cols' => 60,
827 '#rows' => 6,
828 '#description' => t('Text to display at the bottom of the view. May contain an explanation or links or whatever you like. Optional.'),
829 );
830
831 $form['block-info']['block_footer_fieldset']['block_footer_format'] = filter_form($view->block_footer_format, 1, array( 'block_footer_format'));
832
833 $form['block-info']['block_empty_fieldset'] = array(
834 '#type' => 'fieldset',
835 '#collapsible' => TRUE,
836 '#collapsed' => TRUE,
837 '#title' => t('Empty text'),
838 );
839 $form['block-info']['block_empty_fieldset']['block_use_page_empty'] = array(
840 '#type' => 'checkbox',
841 '#title' => t('Use Page empty'),
842 '#return_value' => 1,
843 '#default_value' => $view->block_use_page_empty,
844 '#description' => t('If checked, use the Page Empty Text for block view instead. If so, you should leave the block empty text blank.'),
845 );
846
847 $form['block-info']['block_empty_fieldset']['block_empty'] = array(
848 '#type' => 'textarea',
849 '#title' => t('Empty text'),
850 '#default_value' => $view->block_empty,
851 '#cols' => 60,
852 '#rows' => 6,
853 '#description' => t('Text to display if a view results in no nodes. Optional.'),
854 );
855
856 $form['block-info']['block_empty_fieldset']['block_empty_format'] = filter_form($view->block_empty_format, 1, array( 'block_empty_format'));
857
858
859 // arguments
860 $form['argument-info'] = array(
861 '#type' => 'fieldset',
862 '#title' => t('View arguments'),
863 '#collapsed' => !($view->argument_from_get || $view->argument_from_post),
864 '#collapsible' => true,
865 );
866
867 $form['argument-info']['argument_list'] = array(
868 '#type' => 'textfield',
869 '#title' => t('Argument list'),
870 '#size' => 70,
871 '#default_value' => $view->argument_list,
872 '#description' => t("Type the names of any arguments you want to use in your view here, separated by commas, spaces, or semicolons. For example: start_date, meeting_type"),
873 );
874
875 $form['argument-info']['argument_from_get'] = array(
876 '#type' => 'checkbox',
877 '#title' => t('Accept arguments from GET parameters'),
878 '#default_value' => $view->argument_from_get,
879 '#description' => t('If this is checked, then when visiting the view page any arguments above put on the end of the url will become curly bracket codes in the list. For example, http://www.example.com/upcoming_meetings&start_date=2007-10-10&meeting_type=webinar would make {start_date} equal to 2007-10-10 and {meeting_type} equal to webinar in the view body below.'),
880 );
881
882 $form['argument-info']['argument_from_post'] = array(
883 '#type' => 'checkbox',
884 '#title' => t('Accept arguments from POST parameters'),
885 '#default_value' => $view->argument_from_post,
886 '#description' => t('If this is checked, then any html forms that use the view page url as the action parameter will pass along the values to the list, much like the arguments from GET parameters option above.'),
887 );
888
889
890 // netFORUM details
891 $form['netforum-info'] = array(
892 '#type' => 'fieldset',
893 '#collapsible' => true,
894 '#title' => t('netFORUM Details'),
895 );
896
897 $form['netforum-info']['obj_type_name'] = array(
898 '#type' => 'textfield',
899 '#title' => t('Object Name'),
900 '#size' => 50,
901 '#autocomplete_path' => 'admin/content/netforum-object-autocomplete',
902 '#description' => t("The name of the netFORUM object to list."),
903 );
904
905 $form['netforum-info']['query_name'] = array(
906 '#type' => 'textfield',
907 '#title' => t('Query Name'),
908 '#size' => 50,
909 '#description' => t("To use a pre-built query from iWeb, paste or type the name of the query here. You can also define a query below."),
910 );
911
912 $form['netforum-info']['custom-query'] = array(
913 '#type' => 'fieldset',
914 '#title' => t('Define a query'),
915 '#collapsible' => true,
916 '#collapsed' => true,
917 );
918
919 $form['netforum-info']['custom-query']['query_columns'] = array(
920 '#type' => 'textfield',
921 '#title' => t('Query Columns'),
922 '#size' => 50,
923 '#description' => t("The list of columns to use in your list, separated by commas."),
924 );
925
926 $form['netforum-info']['custom-query']['query_where'] = array(
927 '#type' => 'textfield',
928 '#title' => t('Query Where'),
929 '#size' => 50,
930 '#description' => t("The criteria of the list, like start date or name"),
931 );
932
933 $form['netforum-info']['custom-query']['query_orderby'] = array(
934 '#type' => 'textfield',
935 '#title' => t('Query Order By'),
936 '#size' => 50,
937 '#description' => t("The list of fields to order the results by"),
938 );
939
940 $form['netforum-info']['build_list'] = array(
941 '#type' => 'button',
942 '#value' => t('Build View Body'),
943 );
944
945 $form['netforum-info']['obj_field_help'] = array(
946 '#type' => 'textfield',
947 '#title' => t('Find object fields'),
948 '#size' => 70,
949 '#autocomplete_path' => 'admin/content/netforum-object-fields-autocomplete/',
950 '#default_value' => '',
951 '#description' => t("Type the first few letters of what you're looking for to find the code."),
952 );
953
954 $form['netforum-info']['view_body'] = array(
955 '#type' => 'textarea',
956 '#title' => t('netFORUM view body'),
957 '#cols' => 60,
958 '#rows' => 15,
959 '#default_value' => $view->view_body,
960 '#description' => t('Use this area to define the content of the view. Most likely it should contain a {BeginList} and {EndList}. [!help]', array('!help' => l(t('help'), 'admin/help/netforum_views'))),
961 );
962
963 $form['netforum-info']['view_body_format'] = filter_form($view->view_body_format, 1, array('view_body_format'));
964
965
966 if ($op == t('Build View Body') && netforum_views_valid_build_request($view) ) {
967 $form['netforum-info']['view_body']['#value'] = netforum_views_build_list($view);
968 $form['netforum-info']['custom-query']['#collapsed'] = false;
969 }
970
971 $form['save'] = array(
972 '#type' => 'submit',
973 '#value' => t('Save'),
974 );
975 if ($view->vid) {
976 $form['delete'] = array(
977 '#type' => 'submit',
978 '#value' => t('Delete'),
979 );
980 }
981 $form['cancel'] = array(
982 '#type' => 'submit',
983 '#value' => t('Cancel'),
984 );
985
986 return $form;
987 }
988
989 /**
990 * separately build a piece of the form
991 */
992 function netforum_views_build_form(&$form) { //TODO: Delete this?
993 // NOT REALLY SURE WHY THIS SORT OF WORKS. IT'S MAGIC THAT CHX POINTED ME TO
994 // IN THE POLL MODULE.
995 $form['#post'] = $_POST;
996 $form = form_builder('netforum_views_edit_view', $form);
997 }
998
999
1000 /**
1001 * Display the form built by _views_view_form()
1002 */
1003 function theme_netforum_views_edit_view($form) {
1004
1005 $output .= drupal_render($form['basic-info'], false);
1006 $output .= drupal_render($form['page-info'], false);
1007 $output .= drupal_render($form['block-info'], false);
1008
1009 $allbut = $form['allbut']['#value'];
1010
1011 // drupal_render wants a reference so use full array notation.
1012
1013 // fields
1014 $collapsed = $allbut && $allbut != 'field';
1015
1016 $output .= drupal_render($form, false);
1017 return $output;
1018 }
1019
1020 /**
1021 * Validate that a view sent via form is OK.
1022 */
1023 function netforum_views_edit_view_validate($form_id, $view, $form) {
1024 $op = $view['op'];
1025
1026 if ($op != t('Save')) {
1027 return; // only validate on saving!
1028 }
1029
1030 if ($view['vid']) {
1031 $changed = db_result(db_query("SELECT changed FROM {netforum_view} WHERE vid = %d", $view['vid']));
1032 if ($changed && $view['changed'] != $changed) {
1033 form_set_error('', t('Another user has modified this view, unable to save. You can get this error by using the Back button to re-edit a view after saving one; if you do this, be sure to Reload before making any changes!'));
1034 return;
1035 }
1036 }
1037
1038 if (!$view['name']) {
1039 form_error($form['basic-info']['name'], t('View name is required.'));
1040 }
1041
1042 // view name must be alphanumeric or underscores, no other punctuation.
1043 if (preg_match('/[^a-zA-Z0-9_]/', $view['name'])) {
1044 form_error($form['basic-info']['name'], t('View name must be alphanumeric or underscores only.'));
1045 }
1046
1047 // test uniqueness of name
1048 $vid = db_result(db_query("SELECT vid FROM {netforum_view} WHERE name='%s'", $view['name']));
1049 if ($vid && $vid != $view['vid']) {
1050 form_error($form['basic-info']['name'], t('View name already in use.'));
1051 }
1052
1053 }
1054
1055 /**
1056 * Handle submit buttons on a view form.
1057 */
1058 function netforum_views_edit_view_submit($form_id, $form) {
1059 $view = (object) $form;
1060
1061 // Transform any data that requires it here.
1062 $view->access = array_keys(array_filter($view->access));
1063
1064 // ensure for MYSQL 5 irritation reasons.
1065 $view->menu_tab_weight = intval($view->menu_tab_weight);
1066
1067 $view_is_new = !$view->vid;
1068
1069 $vid = _netforum_views_save_view($view);
1070 menu_rebuild();
1071
1072 if ($form['vid']) {
1073 drupal_set_message(t('netFORUM view successfully saved.'));
1074 }
1075 else {
1076 drupal_set_message(t('netFORUM view successfully added.'));
1077 }
1078
1079 if ($form['op'] == t('Save')) {
1080 $args = explode('/', $_GET['q']);
1081 if ($args[0] == 'admin' && $args[1] == 'build' && $args [2] == 'netforum_views') {
1082 return 'admin/build/netforum_views';
1083 }
1084 array_pop($args);
1085 return implode('/', $args);
1086 }
1087 }
1088
1089 /*
1090 * Create a list of roles.
1091 */
1092 function netforum_views_handler_filter_role() {
1093 $rids = array();
1094 $result = db_query("SELECT r.rid, r.name FROM {role} r ORDER BY r.name");
1095 while ($obj = db_fetch_object($result)) {
1096 $rids[$obj->rid] = $obj->name;
1097 }
1098 return $rids;
1099 }
1100
1101 /**
1102 * Save a view to the database.
1103 */
1104