danielebarchiesi@0: In order to take advantage of the changes in Drupal 7, Views has gone through several API changes. danielebarchiesi@0: Here's what you should know. danielebarchiesi@0: danielebarchiesi@0:

Handler registry

danielebarchiesi@0: danielebarchiesi@0: Views now uses Drupal's dynamic-loading code registry. danielebarchiesi@0: You can safely remove your implementations of hook_views_handlers(), since they are no longer used. danielebarchiesi@0: danielebarchiesi@0: Please remember to specify the handlers in your module's .info file. For example: danielebarchiesi@0:
danielebarchiesi@0: name = Example module
danielebarchiesi@0: description = "Gives an example of a module."
danielebarchiesi@0: core = 7.x
danielebarchiesi@0: files[] = example.module
danielebarchiesi@0: files[] = example.install
danielebarchiesi@0: 
danielebarchiesi@0: ; Views handlers
danielebarchiesi@0: files[] = includes/views/handlers/example_handler_argument_string.inc
danielebarchiesi@0: 
danielebarchiesi@0: danielebarchiesi@0:

Removed handlers

danielebarchiesi@0: danielebarchiesi@0: Note that views_handler_filter_float has been removed. danielebarchiesi@0: This functionality is now handled by views_handler_filter_numeric. danielebarchiesi@0: There's no need for having a special handler any more, thanks to the new DB layer in Drupal 7. danielebarchiesi@0: danielebarchiesi@0: views_handler_sort_formula has been removed. danielebarchiesi@0: Everyone who used it can extend from views_handler_sort, too. danielebarchiesi@0: danielebarchiesi@0:

Ctools dependency

danielebarchiesi@0: Views requires ctools now, so it can use the dependency system of ctools. danielebarchiesi@0: The only thing you have to do is to remove views_process_dependency. danielebarchiesi@0: danielebarchiesi@0:

Changed add_where api

danielebarchiesi@0: If your field is a plain sql field: danielebarchiesi@0:
danielebarchiesi@0: $this->query->add_where($this->options['group'], "$this->table_alias.$this->real_field " . $this->operator . " '%s'", $this->value);
danielebarchiesi@0: 
danielebarchiesi@0: has to be converted to danielebarchiesi@0:
danielebarchiesi@0: $this->query->add_where($this->options['group'], "$this->table_alias.$this->real_field", $this->value, $this->operator);
danielebarchiesi@0: 
danielebarchiesi@0: If your field is a complex where condition: danielebarchiesi@0:
danielebarchiesi@0: $this->query->add_where($this->options['group'], "$upper($field) NOT LIKE $upper('%%%s')", $this->value);
danielebarchiesi@0: 
danielebarchiesi@0: has to be converted to danielebarchiesi@0:
danielebarchiesi@0: $placeholder = $this->placeholder();
danielebarchiesi@0: $this->query->add_where_expression($this->options['group'], "$field LIKE $placeholder", array($placeholder => '%' . db_like($this->value)));
danielebarchiesi@0: 
danielebarchiesi@0: placeholder() generates a automatic unique placeholder for you. danielebarchiesi@0: danielebarchiesi@0: add_where with operator 'formula' can be converted to add_where_expression. danielebarchiesi@0: add_having with operator 'formula' can be converted to add_having_expression. danielebarchiesi@0: danielebarchiesi@0:

Changed place for display specific settings

danielebarchiesi@0: In the new ui the new place for display settings is at the top of the second column. danielebarchiesi@0: Therefore use something like this code in your display plugin: danielebarchiesi@0:
danielebarchiesi@0: $categories['block'] = array(
danielebarchiesi@0:   'title' => t('Block settings'),
danielebarchiesi@0:   'column' => 'second',
danielebarchiesi@0:   'build' => array(
danielebarchiesi@0:     '#weight' => -10,
danielebarchiesi@0:   ),
danielebarchiesi@0: );
danielebarchiesi@0: 
danielebarchiesi@0: danielebarchiesi@0:

Changed filter settings and associated class variables

danielebarchiesi@0: 'optional' and 'single' are now 'required' and 'multiple', the logic is now opposite. danielebarchiesi@0: Also, the 'no_single' and 'no_optional' class variables (known as "object flags" in the API docs) danielebarchiesi@0: are now 'always_multiple' and 'always_required'. danielebarchiesi@0: danielebarchiesi@0:

Changed argument settings

danielebarchiesi@0: See the init() function in views_handler_argument for an overview of everything danielebarchiesi@0: that changed. danielebarchiesi@0: danielebarchiesi@0: 1. The default actions 'summary asc', 'summary desc', 'summary asc by count', 'summary asc by count' danielebarchiesi@0: have been replaced by a single 'summary' action (which takes the sort order and type as options). danielebarchiesi@0: 2. Wildcards are now called exceptions. danielebarchiesi@0:
danielebarchiesi@0: $this->options['exception']['value'] = $options['wildcard'];
danielebarchiesi@0: $this->options['exception']['title'] = $options['wildcard_substitution'];
danielebarchiesi@0: 
danielebarchiesi@0: 3. Summary plugin options are now stored in 'summary_options' instead of 'style_options' danielebarchiesi@0:
danielebarchiesi@0: $this->options['summary_options'] = $options['style_options'];
danielebarchiesi@0: 
danielebarchiesi@0: 4. The selected summary plugin is no longer stored in 'style_plugin'. danielebarchiesi@0:
danielebarchiesi@0: $this->options['summary']['format'] = $options['style_plugin'];
danielebarchiesi@0: 
danielebarchiesi@0: 5. The validator options have been moved. danielebarchiesi@0:
danielebarchiesi@0: $options['validate']['type'] = $options['validate_type'];
danielebarchiesi@0: $options['validate']['fail'] = $options['validate_fail'];
danielebarchiesi@0: 
danielebarchiesi@0: 6. The validator settings have been moved from $form['argument_validate'] to ['validate_options'] danielebarchiesi@0: This means that dependent code in validate plugins needs to change. danielebarchiesi@0: Example change for views_plugin_argument_validate_user: danielebarchiesi@0:
danielebarchiesi@0:     $form['roles'] = array(
danielebarchiesi@0:        '#dependency' => array(
danielebarchiesi@0: -        'edit-options-argument-validate-user-restrict-roles' => array(1),
danielebarchiesi@0: +        'edit-options-validate-options-user-restrict-roles' => array(1),
danielebarchiesi@0:        ),
danielebarchiesi@0: 
danielebarchiesi@0: danielebarchiesi@0:

The introduction of get_value() and sanitize_value()

danielebarchiesi@0: The views_handler class got two new functions: danielebarchiesi@0:
danielebarchiesi@0: /**
danielebarchiesi@0:  * Get the value that's supposed to be rendered.
danielebarchiesi@0:  *
danielebarchiesi@0:  * @param $values
danielebarchiesi@0:  *   An object containing all retrieved values.
danielebarchiesi@0:  * @param $field
danielebarchiesi@0:  *   Optional name of the field where the value is stored.
danielebarchiesi@0:  */
danielebarchiesi@0: function get_value($values, $field = NULL) {
danielebarchiesi@0:   $alias = isset($field) ? $this->aliases[$field] : $this->field_alias;
danielebarchiesi@0:   if (isset($values->{$alias})) {
danielebarchiesi@0:     return $values->{$alias};
danielebarchiesi@0:   }
danielebarchiesi@0: }
danielebarchiesi@0: 
danielebarchiesi@0: /**
danielebarchiesi@0:  * Sanitize the value for output.
danielebarchiesi@0:  *
danielebarchiesi@0:  * @param $value
danielebarchiesi@0:  *   The value being rendered.
danielebarchiesi@0:  * @param $type
danielebarchiesi@0:  *   The type of sanitization needed. If not provided, check_plain() is used.
danielebarchiesi@0:  */
danielebarchiesi@0: function sanitize_value($value, $type = NULL) {
danielebarchiesi@0:   switch ($type) {
danielebarchiesi@0:     case 'xss':
danielebarchiesi@0:       $value = filter_xss($value);
danielebarchiesi@0:       break;
danielebarchiesi@0:     case 'url':
danielebarchiesi@0:       $value = check_url($value);
danielebarchiesi@0:       break;
danielebarchiesi@0:     default:
danielebarchiesi@0:       $value = check_plain($value);
danielebarchiesi@0:       break;
danielebarchiesi@0:   }
danielebarchiesi@0:   return $value;
danielebarchiesi@0: }
danielebarchiesi@0: 
danielebarchiesi@0: These functions are meant to be used in the render() functions of field handlers, danielebarchiesi@0: for fetching data (usually by alias) from the $values object, and for sanitizing values. danielebarchiesi@0: danielebarchiesi@0: The abstraction of fetching data from rendering data is important because danielebarchiesi@0: different query backends have different ways of storing data in $values, and the field alias danielebarchiesi@0: is a SQL specific thing. So instead of overriding the whole render() function and copying danielebarchiesi@0: all of the logic there (as well as having to constantly keep up with upstream Views changes), danielebarchiesi@0: the backend can just override get_values(), which is significantly less code. danielebarchiesi@0: danielebarchiesi@0: Of course, different ways of fetching and displaying data might require different danielebarchiesi@0: ways of sanitizing it, hence the usage of the sanitize_value() function. danielebarchiesi@0: danielebarchiesi@0: Examples of converting render() field handler implementations: danielebarchiesi@0:
danielebarchiesi@0: // This
danielebarchiesi@0: $value = $values->{$this->field_alias};
danielebarchiesi@0: // Becomes this
danielebarchiesi@0: $value = $this->get_value($values);
danielebarchiesi@0: 
danielebarchiesi@0: // And this
danielebarchiesi@0: $format = $values->{$this->aliases['format']};
danielebarchiesi@0: // Becomes this
danielebarchiesi@0: $format = $this->get_values($values, 'format');
danielebarchiesi@0: 
danielebarchiesi@0: // Instead of this:
danielebarchiesi@0: return check_plain($value);
danielebarchiesi@0: // We write:
danielebarchiesi@0: return $this->sanitize_value($value);
danielebarchiesi@0: 
danielebarchiesi@0: // Since sanitize_value() supports different sanitization functions, this:
danielebarchiesi@0: return filter_xss($value);
danielebarchiesi@0: // Can become:
danielebarchiesi@0: return $this->sanitize_value($value, 'xss');
danielebarchiesi@0: 
danielebarchiesi@0: danielebarchiesi@0: danielebarchiesi@0:

Changed views_get_page_view

danielebarchiesi@0: In contrast to 6.x views_get_page_view now does stores the current view, not the current page display. danielebarchiesi@0: danielebarchiesi@0:

Removed views-view-row-node

danielebarchiesi@0: Due to changes in comment.module there is no extra views-view-row-node template needed to display the comments. If you do some custom stuff there you should now be able to do everything in your node.tpl.php. danielebarchiesi@0: danielebarchiesi@0:

Entity type Key on Base tables

danielebarchiesi@0: During the development of the drupal7 version of views the entity type associated with a table got added to $data['name']['table']['base']['entity type']. It should be moved to $data['name']['table']['entity type']. danielebarchiesi@0: danielebarchiesi@0:

Changed views_plugin_style::render_grouping()

danielebarchiesi@0: The parameters as well as the structure of the methods return have changed. danielebarchiesi@0: The method now accepts a third optional parameter called "$group_rendered". danielebarchiesi@0: This parameter defines whether to use the rendered or the raw field value for grouping. danielebarchiesi@0: Intention for adding the parameter was that the grouping could have been acted danielebarchiesi@0: unexpected if the rendered field contained unique values e.g. by using drupal_html_id(). danielebarchiesi@0:
danielebarchiesi@0:
New return structure
danielebarchiesi@0:
danielebarchiesi@0: {grouping value} is the value affected by the new parameter. danielebarchiesi@0:
danielebarchiesi@0:   array (
danielebarchiesi@0:     {grouping value} => array(
danielebarchiesi@0:       'group' => {rendered_value of the grouping field},
danielebarchiesi@0:       'rows' => array({group rows}),
danielebarchiesi@0:     ),
danielebarchiesi@0:   );
danielebarchiesi@0: 
danielebarchiesi@0:
danielebarchiesi@0:
Old return structure
danielebarchiesi@0:
danielebarchiesi@0: If the new parameter isn't explicitly set or its value is NULL the structure of the return will be the same as in D6! danielebarchiesi@0:
danielebarchiesi@0:   array (
danielebarchiesi@0:     {rendered_value of the grouping field} => array({group rows}),
danielebarchiesi@0:   );
danielebarchiesi@0: 
danielebarchiesi@0:
danielebarchiesi@0: