| [ Index ] |
PHP Cross Reference of Drupal 6 (gatewave) |
[Summary view] [Print] [Text view]
1 <?php 2 // $Id: date_api_argument_handler.inc,v 1.1.2.48 2011/01/03 02:39:15 karens Exp $ 3 /** 4 * Date API argument handler. 5 */ 6 class date_api_argument_handler extends views_handler_argument_date { 7 function construct() { 8 parent::construct(); 9 require_once('./'. drupal_get_path('module', 'date_api') .'/date_api_sql.inc'); 10 $this->date_handler = new date_sql_handler(); 11 $this->date_handler->construct(); 12 } 13 14 /** 15 * Get granularity and use it to create the formula and a format 16 * for the results. 17 */ 18 function init(&$view, $options) { 19 parent::init($view, $options); 20 21 // Identify the type of display we're using. 22 $this->display_handler = $view->display_handler->definition['handler']; 23 24 // Add a date handler to the display. 25 $date_handler = $this->date_handler; 26 $date_handler->granularity = $this->options['granularity']; 27 $this->format = $date_handler->views_formats($date_handler->granularity, 'display'); 28 $this->sql_format = $date_handler->views_formats($date_handler->granularity, 'sql'); 29 30 if (empty($this->view->date_info)) $this->view->date_info = new stdClass(); 31 32 // Set the view range, do this only if not already set in case there are multiple date arguments. 33 if (empty($this->view->date_info->min_allowed_year)) { 34 $range = date_range_years($this->options['year_range']); 35 $this->view->date_info->min_allowed_year = !empty($range) && is_array($range) ? $range[0] : variable_get('min_allowed_year', 100); 36 $this->view->date_info->max_allowed_year = !empty($range) && is_array($range) ? $range[1] : variable_get('max_allowed_year', 4000); 37 } 38 if (empty($this->view->date_info->date_fields)) { 39 $this->view->date_info->date_fields = array(); 40 } 41 $this->view->date_info->date_fields = array_merge($this->view->date_info->date_fields, $this->options['date_fields']); 42 } 43 44 /** 45 * Default value for the date_fields option. 46 */ 47 function option_definition() { 48 $options = parent::option_definition(); 49 $options['date_fields'] = array('default' => array()); 50 $options['year_range'] = array('default' => '-3:+3'); 51 $options['date_method'] = array('default' => 'OR'); 52 $options['granularity'] = array('default' => 'month'); 53 54 return $options; 55 } 56 57 /** 58 * Add a form element to select date_fields for this argument. 59 */ 60 function options_form(&$form, &$form_state) { 61 parent::options_form($form, $form_state); 62 $options = $this->date_handler->date_parts(); 63 unset($options['second'], $options['minute']); 64 $options += array('week' => date_t('Week', 'datetime')); 65 $form['granularity'] = array( 66 '#title' => t('Granularity'), 67 '#type' => 'radios', 68 '#options' => $options, 69 '#default_value' => $this->options['granularity'], 70 '#multiple' => TRUE, 71 '#description' => t("Select the type of date value to be used in defaults, summaries, and navigation. For example, a granularity of 'month' will set the default date to the current month, summarize by month in summary views, and link to the next and previous month when using date navigation."), 72 ); 73 74 $form['year_range'] = array( 75 '#title' => t('Date year range'), 76 '#type' => 'textfield', 77 '#default_value' => $this->options['year_range'], 78 '#description' => t("Set the allowable minimum and maximum year range for this argument, either a -X:+X offset from the current year, like '-3:+3' or an absolute minimum and maximum year, like '2005:2010'. When the argument is set to a date outside the range, the page will be returned as 'Page not found (404)'."), 79 ); 80 81 $fields = date_api_fields($this->definition['base']); 82 $options = array(); 83 foreach ($fields['name'] as $name => $field) { 84 $options[$name] = $field['label']; 85 } 86 87 // If this argument was added as a CCK field argument and no other date field 88 // has been chosen, update the default with the right date. 89 if (empty($this->options['date_fields']) && $this->field != 'date_argument') { 90 $this->options['date_fields'] = array($this->table .'.'. $this->field); 91 } 92 93 $form['date_fields'] = array( 94 '#title' => t('Date field(s)'), 95 '#type' => 'checkboxes', 96 '#options' => $options, 97 '#default_value' => $this->options['date_fields'], 98 '#multiple' => TRUE, 99 '#description' => t("Select one or more date fields to filter with this argument. Do not select both the 'From date' and 'To date' for CCK date fields, only one of them is needed."), 100 ); 101 $form['date_method'] = array( 102 '#title' => t('Method'), 103 '#type' => 'radios', 104 '#options' => array('OR' => t('OR'), 'AND' => t('AND')), 105 '#default_value' => $this->options['date_method'], 106 '#description' => t('Method of handling multiple date fields in the same query. Return items that have any matching date field (date = field_1 OR field_2), or only those with matches in all selected date fields (date = field_1 AND field_2).'), 107 ); 108 109 } 110 111 function options_validate($form, &$form_state) { 112 // It is very important to call the parent function here: 113 parent::options_validate($form, $form_state); 114 115 if ($form_state['values']['form_id'] == 'views_ui_config_item_form') { 116 $check_fields = array_filter($form_state['values']['options']['date_fields']); 117 if (empty($check_fields)) { 118 form_error($form['date_fields'], t('You must select at least one date field for this argument.')); 119 } 120 if (!preg_match('/^(?:\-[0-9]{1,4}|[0-9]{4}):(?:[\+|\-][0-9]{1,4}|[0-9]{4})$/', $form_state['values']['options']['year_range'])) { 121 form_error($form['year_range'], t('Date year range must be in the format -9:+9, 2005:2010, -9:2010, or 2005:+9')); 122 } 123 } 124 } 125 126 function options_submit($form, &$form_state) { 127 // It is very important to call the parent function here: 128 parent::options_submit($form, $form_state); 129 130 if ($form_state['values']['form_id'] == 'views_ui_config_item_form') { 131 $form_state['values']['options']['date_fields'] = array_filter($form_state['values']['options']['date_fields']); 132 } 133 } 134 135 // Update the summary values to show selected granularity. 136 function admin_summary() { 137 $fields = date_api_fields($this->definition['base']); 138 if (!empty($this->options['date_fields'])) { 139 $output = array(); 140 foreach ($this->options['date_fields'] as $field) { 141 $output[] = $fields['name'][$field]['label']; 142 } 143 return implode('<br />'. $this->options['date_method'] .' ', $output); 144 } 145 else { 146 return parent::admin_summary(); 147 } 148 } 149 150 /** 151 * Set the empty argument value to the current date, 152 * formatted appropriately for this argument. 153 */ 154 function get_default_argument($raw = FALSE) { 155 if (!$raw && $this->options['default_argument_type'] == 'date') { 156 return date($this->format(), time()); 157 } 158 else { 159 return parent::get_default_argument($raw); 160 } 161 } 162 163 function format() { 164 if (!empty($this->options['granularity'])) { 165 $date_handler = new date_sql_handler(); 166 return $date_handler->views_formats($this->options['granularity']); 167 } 168 else { 169 return !empty($this->options[$this->option_name]) ? $this->options[$this->option_name] : 'Y-m'; 170 } 171 } 172 173 /** 174 * Provide a link to the next level of the view from the summary. 175 */ 176 function summary_name($data) { 177 $format = $this->date_handler->views_formats($this->options['granularity'], 'display'); 178 $value = $data->{$this->name_alias}; 179 $range = $this->date_handler->arg_range($value); 180 return date_format_date($range[0], 'custom', $format); 181 } 182 183 /** 184 * Provide the argument to use to link from the summary to the next level; 185 * this will be called once per row of a summary, and used as part of 186 * $view->get_url(). 187 * 188 * @param $data 189 * The query results for the row. 190 */ 191 function summary_argument($data) { 192 $format = $this->date_handler->views_formats($this->options['granularity'], 'sql'); 193 $value = $data->{$this->name_alias}; 194 $range = $this->date_handler->arg_range($value); 195 return date_format_date($range[0], 'custom', $format); 196 } 197 198 /** 199 * Provide a link to the next level of the view from the argument. 200 */ 201 function title() { 202 $format = $this->date_handler->views_formats($this->options['granularity'], 'display'); 203 $range = $this->date_handler->arg_range($this->argument); 204 return date_format_date($range[0], 'custom', $format); 205 } 206 207 /** 208 * Create a summary query that matches the granularity. 209 * 210 * Needed or Views will do a groupby on the complete date instead 211 * of only the part of the date actually used in the argument. 212 */ 213 function summary_query() { 214 $this->get_query_fields(); 215 216 // No way to do summaries on more than one field at a time. 217 if (count($this->query_fields) > 1) { 218 return; 219 } 220 221 $field = $this->query_fields[0]['field']; 222 $date_handler = $this->query_fields[0]['date_handler']; 223 224 // Get the SQL format for this granularity, like Y-m, 225 // and use that as the grouping value. 226 $format = $date_handler->views_formats($this->options['granularity'], 'sql'); 227 $this->formula = $date_handler->sql_format($format, $date_handler->sql_field($field['fullname'])); 228 229 // Add the computed field. 230 $this->base_alias = $this->name_alias = $this->query->add_field(NULL, $this->formula, $field['query_name']); 231 232 return $this->summary_basics(FALSE); 233 } 234 235 function get_query_fields() { 236 $fields = date_api_fields($this->definition['base']); 237 $fields = $fields['name']; 238 $min_date = isset($this->min_date) ? $this->min_date : NULL; 239 $min_utc = isset($this->min_utc) ? $this->min_utc : NULL; 240 $max_date = isset($this->max_date) ? $this->max_date : NULL; 241 $max_utc = isset($this->max_utc) ? $this->max_utc : NULL; 242 $this->query_fields = array(); 243 foreach ($this->options['date_fields'] as $delta => $name) { 244 if (array_key_exists($name, $fields) && $field = $fields[$name]) { 245 $date_handler = new date_sql_handler(); 246 $date_handler->construct($field['sql_type'], date_default_timezone_name()); 247 $date_handler->granularity = $this->options['granularity']; 248 date_views_set_timezone($date_handler, $this, $field); 249 $this->query_fields[] = array('field' => $field, 'date_handler' => $date_handler); 250 } 251 } 252 } 253 254 /** 255 * Make sure the date field is added to the query. 256 * 257 * Do this in pre_query() so it will get done even if the argument 258 * is the wildcard, since query() is skipped when the wildcard is used. 259 */ 260 function pre_query() { 261 // Unset invalid date values before the query runs. 262 if (!empty($this->view->args) && count($this->view->args) > $this->position) { 263 $argument = $this->view->args[$this->position]; 264 $parts = $this->date_handler->arg_parts($argument); 265 if (empty($parts[0]['date']) && empty($parts[0]['period'])) { 266 unset($this->view->args[$this->position]); 267 } 268 } 269 } 270 271 /** 272 * Called just prior to query(), this lets us set up table aliases for 273 * relationships. This can't be done in pre_query(), because the relationship 274 * isn't defined yet. 275 */ 276 function set_relationship() { 277 parent::set_relationship(); 278 $this->get_query_fields(); 279 if (!empty($this->relationship)) { 280 if (!empty($this->query_fields)) { 281 foreach ($this->query_fields as $query_field) { 282 $field = $query_field['field']; 283 $this->related_table_alias = $this->query->queue_table($field['table_name'], $this->relationship); 284 } 285 } 286 } 287 } 288 289 /** 290 * Set up the query for this argument. 291 * 292 * The argument sent may be found at $this->argument. 293 */ 294 function query() { 295 $block_identifier = date_block_identifier($this->view); 296 if (!empty($this->view->block_identifier) || isset($_GET[$block_identifier])) { 297 // Retrieve the block arguments in a way that will work for 298 // urls like user/%/calendar/2009-04. 299 if (!empty($_GET[$block_identifier])) { 300 $path_args = explode('/', $this->view->get_path()); 301 $mini_args = explode('/', $_GET[$block_identifier]); 302 foreach ($path_args as $pos => $key) { 303 if ($path_args[$pos] != '%') { 304 unset($mini_args[$pos]); 305 } 306 } 307 // Get rid of gaps in the array caused by embedded args. 308 $mini_args = array_values($mini_args); 309 $this->view->args = $mini_args; 310 } 311 $i = 0; 312 foreach ($this->view->argument as $argument) { 313 if ($argument->field == 'date_argument') { 314 $this->argument = $this->view->args[$argument->position]; 315 break; 316 } 317 $i++; 318 } 319 } 320 $parts = $this->date_handler->arg_parts($this->argument); 321 322 foreach ($parts as $type) { 323 foreach ($type as $part) { 324 foreach ($part as $key => $value) { 325 if (!empty($value)) { 326 // The last part evaluated is the one that will 'stick' 327 // as the date type. 328 $this->granularity = $key; 329 $this->$key = $value; 330 } 331 } 332 } 333 } 334 335 $range = $this->date_handler->arg_range($this->argument); 336 $min_date = $range[0]; 337 $max_date = $range[1]; 338 $this->min_date = $min_date; 339 $this->max_date = $max_date; 340 341 // See if we're outside the allowed date range for our argument. 342 if (date_format($min_date, 'Y') < $this->view->date_info->min_allowed_year || date_format($max_date, 'Y') > $this->view->date_info->max_allowed_year) { 343 $this->forbid = TRUE; 344 $this->query->add_where('date', "0=1"); 345 return; 346 } 347 348 // The second option seems to work better in the block view if 349 // set to something other than the original value. 350 // Need to keep an eye on this to be sure nothing else breaks. 351 //$format = $this->date_handler->views_formats($this->options['granularity'], 'sql'); 352 $format = $this->date_handler->views_formats($this->granularity, 'sql'); 353 $this->get_query_fields(); 354 if (!empty($this->query_fields)) { 355 // Use set_where_group() with the selected date_method 356 // of 'AND' or 'OR' to create the where clause. 357 $this->query->set_where_group($this->options['date_method'], 'date'); 358 foreach ($this->query_fields as $query_field) { 359 $field = $query_field['field']; 360 $date_handler = $query_field['date_handler']; 361 $table_alias = !empty($this->related_table_alias) ? $this->related_table_alias : $field['table_name']; 362 $from_field = str_replace($field['table_name'] .'_', $table_alias .'.', $field['fromto'][0]); 363 $to_field = str_replace($field['table_name'] .'_', $table_alias .'.', $field['fromto'][1]); 364 365 if ($this->granularity != 'week') { 366 $from = $date_handler->sql_where_format($format, $from_field, '<=', date_format($max_date, $format)); 367 $to = $date_handler->sql_where_format($format, $to_field, '>=', date_format($min_date, $format)); 368 } 369 else { 370 $format = DATE_FORMAT_DATETIME; 371 $from = $date_handler->sql_where_date('DATE', $from_field, '<=', date_format($max_date, $format)); 372 $to = $date_handler->sql_where_date('DATE', $to_field, '>=', date_format($min_date, $format)); 373 } 374 $sql = str_replace('***table***', $field['table_name'], "($from AND $to)"); 375 if ($sql) { 376 $this->query->add_where('date', $sql); 377 } 378 } 379 } 380 } 381 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Thu Mar 24 11:18:33 2011 | Cross-referenced by PHPXref 0.7 |