/[drupal]/contributions/modules/project_forecast/project_forecast.admin.filters.inc
ViewVC logotype

Contents of /contributions/modules/project_forecast/project_forecast.admin.filters.inc

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


Revision 1.2 - (show annotations) (download) (as text)
Thu Oct 30 14:57:01 2008 UTC (12 months, 4 weeks ago) by jpetso
Branch: MAIN
CVS Tags: DRUPAL-6--1-0-RC3, DRUPAL-6--1-0, HEAD
Changes since 1.1: +11 -44 lines
File MIME type: text/x-php
Yay for usability: Eliminate the "Task filters" page and instead
put the filters next to the view settings on the central admin page.
Less error prone, better overview, outright damn cool.

With this in place, I feel confident to release an 1.0.
(But first, sevi's improved Task Status add-on shall still be merged.)
1 <?php
2 // $Id: project_forecast.admin.filters.inc,v 1.1 2008/07/17 18:42:14 jpetso Exp $
3 /**
4 * @file
5 * Project Forecast - Estimate completion dates for your project's tasks.
6 *
7 * This file contains the "task filters" part of the administrative
8 * user interface. For the largest part, this is a slightly modified copy
9 * of certain functions in Views' admin.inc.
10 *
11 * Copyright 2007, 2008 by Earl Miles ("merlinofchaos", http://drupal.org/user/26979)
12 * Copyright 2008 by Jakob Petsovits ("jpetso", http://drupal.org/user/56020)
13 */
14
15 function project_forecast_admin_task_filters_open_add(&$form_state) {
16 if (empty($form_state['storage']['phase'])) {
17 return project_forecast_admin_task_filters_open_add_select($form_state);
18 }
19 else if ($form_state['storage']['phase'] == 'config-item') {
20 return project_forecast_admin_task_filters_open_edit_item($form_state);
21 }
22 }
23
24 function project_forecast_admin_task_filters_open_add_select(&$form_state) {
25 $form = array();
26
27 $view_settings = _project_forecast_tasks_view();
28 $view = $view_settings['view'];
29 $display_id = $view_settings['display_id'];
30
31 module_load_include('inc', 'views', 'includes/admin');
32
33 if (!empty($view)) {
34 $base_tables = $view->get_base_tables();
35 $options = views_fetch_fields(array_keys($base_tables), 'filter');
36 }
37 if (!empty($options)) {
38 $groups = array('all' => t('<All>'));
39
40 $form['name'] = array(
41 '#prefix' => '<div class="views-radio-box form-checkboxes">',
42 '#suffix' => '</div>',
43 '#tree' => TRUE,
44 '#default_value' => 'all',
45 );
46
47 foreach ($options as $key => $option) {
48 $group = strtr(strtolower($option['group']), '_ ', '--');
49 $groups[$group] = $option['group'];
50 $form['name'][$key] = array(
51 '#prefix' => '<div class="views-dependent-all views-dependent-'. $group .'">',
52 '#suffix' => '</div>',
53 '#type' => 'checkbox',
54 '#title' => t('!group: !field', array('!group' => $option['group'], '!field' => $option['title'])),
55 '#description' => $option['help'],
56 '#return_value' => $key,
57 );
58 }
59 $form['group']['#options'] = $groups;
60
61 $form['buttons'] = array(
62 '#prefix' => '<div class="clear-block"><div class="form-buttons">',
63 '#suffix' => '</div></div>',
64 );
65 // remove default validate handler
66 $form['#validate'] = array();
67
68 $form['buttons']['submit'] = array(
69 '#type' => 'submit',
70 '#value' => t('Add filter'),
71 '#submit' => array('project_forecast_admin_task_filters_open_add_submit'),
72 );
73 $form['buttons']['cancel'] = array(
74 '#type' => 'submit',
75 '#value' => t('Cancel'),
76 '#submit' => array('project_forecast_admin_task_filters_cancel'),
77 '#validate' => array(),
78 );
79 }
80 else {
81 $form['markup'] = array(
82 '#value' => '<div class="form-item">'. t('There are no filters available to add.') .'</div>',
83 );
84 }
85 views_add_css('views-admin');
86
87 $form_state['storage']['filters'] = variable_get('project_forecast_task_filters_open', array());
88 return $form;
89 }
90
91 /**
92 * Submit handler for adding new item(s) to a view.
93 */
94 function project_forecast_admin_task_filters_open_add_submit($form, &$form_state) {
95 if (!empty($form_state['values']['name']) && is_array($form_state['values']['name'])) {
96 // Loop through each of the items that were checked and add them to the view.
97 foreach (array_keys(array_filter($form_state['values']['name'])) as $field) {
98 list($table, $field) = explode('.', $field, 2);
99
100 // Check to see if this type has settings, if so add the settings form first.
101 $handler = views_get_handler($table, $field, 'filter');
102 $form_state['storage']['phase'] = ($handler && $handler->has_extra_options())
103 ? 'config-item-extra'
104 : 'config-item';
105 $form_state['storage']['filter'] = array(
106 'table' => $table,
107 'field' => $field,
108 );
109 }
110 }
111 $form_state['rebuild'] = TRUE;
112 }
113
114 function project_forecast_admin_task_filters_open_edit(&$form_state, $key) {
115 $form = array();
116 $filters = variable_get('project_forecast_task_filters_open', array());
117
118 if (isset($filters[$key])) {
119 $form_state['storage']['filters'] = $filters;
120 $form_state['storage']['filter_key'] = $key;
121 $form_state['storage']['filter'] = $filters[$key];
122 return project_forecast_admin_task_filters_open_edit_item($form_state);
123 }
124 else {
125 $form['error'] = array(
126 '#type' => 'markup',
127 '#value' => t('The specified filter does not exist.'),
128 );
129 }
130 return $form;
131 }
132
133 function project_forecast_admin_task_filters_open_edit_item(&$form_state) {
134 $view_settings = _project_forecast_tasks_view();
135 $view = $view_settings['view'];
136 $display_id = $view_settings['display_id'];
137
138 $filter = $form_state['storage']['filter'];
139
140 $form = array('options' => array('#tree' => TRUE));
141 if (!$view->set_display($display_id)) {
142 views_ajax_render(t('Invalid display id @display', array('@display' => $display_id)));
143 }
144 $id = $view->add_item($display_id, 'filter', $filter['table'], $filter['field']);
145
146 if (isset($form_state['storage']['filter_key']) && !empty($filter['item'])) {
147 $view->set_item($display_id, 'filter', $id, $filter['item']);
148 }
149 $item = $view->get_item($display_id, 'filter', $id);
150
151 if ($item) {
152 $handler = views_get_handler($filter['table'], $filter['field'], 'filter');
153 if (empty($handler)) {
154 $form['markup'] = array('#value' => t("Error: handler for @table > @field doesn't exist!", array('@table' => $filter['table'], '@field' => $filter['field'])));
155 }
156 else {
157 $handler->init($view, $item);
158 $types = views_object_types();
159
160 // A whole bunch of code to figure out what relationships are valid for
161 // this item.
162 $relationships = $view->display_handler->get_option('relationships');
163 $relationship_options = array();
164
165 foreach ($relationships as $relationship) {
166 // relationships can't link back to self. But also, due to ordering,
167 // relationships can only link to prior relationships.
168 if ($type == 'relationship' && $id == $relationship['id']) {
169 break;
170 }
171 $relationship_handler = views_get_handler($relationship['table'], $relationship['field'], 'relationship');
172 // ignore invalid/broken relationships.
173 if (empty($relationship_handler)) {
174 continue;
175 }
176
177 // If this relationship is valid for this type, add it to the list.
178 $data = views_fetch_data($relationship['table']);
179 $base = $data[$relationship['field']]['relationship']['base'];
180 $base_fields = views_fetch_fields($base, 'filter');
181 if (isset($base_fields[$handler->table .'.'. $handler->field])) {
182 $relationship_handler->init($view, $relationship);
183 $relationship_options[$relationship['id']] = $relationship_handler->label();
184 }
185 }
186
187 if (!empty($relationship_options)) {
188 // Make sure the existing relationship is even valid. If not, force
189 // it to none.
190 $base_fields = views_fetch_fields($view->base_table, 'filter');
191 if (isset($base_fields[$handler->table . '.' . $handler->field])) {
192 $relationship_options = array_merge(array('none' => t('Do not use a relationship')), $relationship_options);
193 }
194 $rel = empty($item['relationship']) ? 'none' : $item['relationship'];
195 if (empty($relationship_options[$rel])) {
196 $rel = 'none';
197 }
198
199 $form['options']['relationship'] = array(
200 '#type' => 'select',
201 '#title' => t('Relationship'),
202 '#options' => $relationship_options,
203 '#default_value' => $rel,
204 );
205 }
206 else {
207 $form['options']['relationship'] = array(
208 '#type' => 'value',
209 '#value' => 'none',
210 );
211 }
212
213 // Get form from the handler.
214 $handler->options_form($form['options'], $form_state);
215
216 // We don't want the expose button, doesn't make sense in this context.
217 unset($form['options']['expose_button']);
218 unset($form['options']['expose']);
219
220 $form_state['storage']['handler'] = serialize($handler);
221
222 $form['buttons']['submit'] = array(
223 '#type' => 'submit',
224 '#value' => t('Save'),
225 '#submit' => array('project_forecast_admin_task_filters_open_edit_submit'),
226 '#validate' => array('project_forecast_admin_task_filters_open_edit_validate'),
227 );
228 $form['buttons']['cancel'] = array(
229 '#type' => 'submit',
230 '#value' => t('Cancel'),
231 '#submit' => array('project_forecast_admin_task_filters_cancel'),
232 '#validate' => array(),
233 );
234 }
235 drupal_set_title(t('!title - @filtername', array(
236 '!title' => drupal_get_title(),
237 '@filtername' => $handler->ui_name(),
238 )));
239 }
240 views_add_css('views-admin');
241
242 return $form;
243 }
244
245 function project_forecast_admin_task_filters_open_edit_validate($form, &$form_state) {
246 // Make sure the class definition of the serialized handler is loaded
247 // before unserializing it, otherwise we'll experience a nice fatal error.
248 // The safest way to ensure that is to let Views load the handler itself.
249 $filter = $form_state['storage']['filter'];
250 $handler = views_get_handler($filter['table'], $filter['field'], 'filter');
251
252 // We'd rather have our stateful handler object from before, though.
253 $handler = unserialize($form_state['storage']['handler']);
254 $handler->options_validate($form['options'], $form_state);
255 $form_state['handler'] = $handler;
256 }
257
258 function project_forecast_admin_task_filters_open_edit_submit($form, &$form_state) {
259 // Run it through the handler's submit function.
260 $form_state['handler']->options_submit($form['options'], $form_state);
261 $item = $form_state['handler']->options;
262 $filter = $form_state['storage']['filter'];
263 $filters = $form_state['storage']['filters'];
264 $filter_key = $form_state['storage']['filter_key'];
265
266 // Store the data we're given.
267 foreach ($form_state['values']['options'] as $key => $value) {
268 $item[$key] = $value;
269 }
270 $filter['item'] = $item;
271
272 if (isset($filter_key) && isset($filters[$filter_key])) {
273 $filters[$filter_key] = $filter; // overwrite existing filter
274 }
275 else {
276 $filters[] = $filter; // new filter, add the item instead of replacing one
277 }
278 variable_set('project_forecast_task_filters_open', $filters);
279 project_forecast_recalculate_all();
280 drupal_goto('admin/project/forecast', 'show-view-settings=true');
281 }
282
283 function project_forecast_admin_task_filters_cancel(&$form_state) {
284 drupal_goto('admin/project/forecast', 'show-view-settings=true');
285 }
286
287 /**
288 * Menu callback for deleting an additional filter for the "open tasks" view.
289 */
290 function project_forecast_admin_task_filters_open_delete($key) {
291 $filters = variable_get('project_forecast_task_filters_open', array());
292 if (isset($filters[$key])) {
293 unset($filters[$key]);
294 }
295 variable_set('project_forecast_task_filters_open', $filters);
296 project_forecast_recalculate_all();
297 drupal_goto('admin/project/forecast', 'show-view-settings=true');
298 }

  ViewVC Help
Powered by ViewVC 1.1.2