I've made 3 fields, exposed them via hook_views_data and created 3 handler classes to alter the query and their output:

* Capacity (requires a node_load, so extends views_handler_field_entity)
* Used slots (adds a subquery field to the query)
* Available slots (= Capacity - Used slots)

Capacity and Used slots are very different and don't need each other. Available slots, however, requires both fields. Capacity's value doesn't come from the query, so forget that one. Used slots' value does come from the query (so needs that subquery field).

I could repeat Used slots' query logic in Available slots, but that's stupid. I want Available slots to 'force load' Used slots into the query.

Sounds like views_handler_field->add_additional_fields? Yes, it does! But that's not it, because it doesn't load the field's handler (and its logic to add that subquery).

So my question: how do I auto load a field from another field? (I've tried add_additional_fields with the field's alias, but that results in an SQL error "Unknown column".)

Comments

rudiedirkx’s picture

Title: How to add additional custom fields to use by another field » How to add additional **custom** fields to use by another field
rudiedirkx’s picture

BTW what I've done until now, is call the other handler's query logic statically. (Long live PHP's scope structure!!)

class views_handler_field_node_registration_available_slots extends views_handler_field_entity {
  function query() {
    // PHP's very unnatural scoping allows the other handler to alter this handler's $this
    views_handler_field_node_registration_used_slots::query();
  }
}

Problem is this leads to a "call-time pass-by-reference is deprecated" warning somewhere. I can't pinpoint why or where, but this is the reason.

I'd rather just 'force load' the other field handler's field.

dawehner’s picture

http://drupalcode.org/project/tmgmt.git/blob/refs/heads/7.x-1.x:/sources... is an example how to add multiple other field handlers dynamically, but yeah this is definitive not straightforward.

rudiedirkx’s picture

I don't get it... Is the language part necessary??

If I add a field handler in ->init, that handler doesn't exist anymore in ->query, so it's not saved or not used or something... It must exist before ->query is called though. ->init sounds good in theory, but the query isn't altered.

My init function:

	function init(&$view, &$options) {
		parent::init(&$view, &$options);
		$this->view->init_style();

		$this->additional_fields['nid'] = 'nid';

		$field_handlers = &$this->view->display_handler->handlers['field'];

		$handler_name = 'registration_used_slots';
		$handler = views_get_handler($this->table, $handler_name, 'field');
		$handler_options = array(
			'id' => $handler_name,
			'table' => $this->table,
			'field' => $handler_name,
			'label' => $handler_name,
		) + $options;
		$handler->main_field = $options['id'];
		$handler->init($view, $handler_options);
		$field_handlers[$handler_name] = $handler;
	}

Field 'registration_used_slots' isn't added.

merlinofchaos’s picture

You probably need to add your handler to $view->field[] as well.

rudiedirkx’s picture

There's no field property in $view. Or in a handler or a display...

I've added the field to the display's fields list. (Using display_handler->get_option and display_handler->set_option).

That does the trick. (Initing and attaching the handler etc is still required.)

Not as perfect as I'd hoped. Doing it like this (adding the field to the fields list programmatically) adds the field to the actual field list, which means it's clickable. The field doesn't really exist there, though, so you can't delete or edit it. Editing it opens a blank overlay.

Adding the field explicitly adds it the 'right' way and makes it editable.

This is acceptable for my purposes, but I would love it if this were a feature and not a hack =) Sounds like a sister for ->add_additional_fields.

My ->init:

	function init(&$view, &$options) {
		parent::init(&$view, &$options);
		$this->view->init_style();

		$this->additional_fields['nid'] = 'nid';

		$handler_name = 'registration_used_slots';
		$field_handlers = &$this->view->display_handler->handlers['field'];

		$fields = $this->view->display_handler->get_option('fields');
		if (!isset($fields[$handler_name])) {
			// Create, init and attach handler.
			$handler = views_get_handler($this->table, $handler_name, 'field');
			$handler_options = array(
				'id' => $handler_name,
				'table' => $this->table,
				'field' => $handler_name,
				'label' => 'AUTOMATIC',
				'exclude' => TRUE,
			);
			$handler->main_field = $options['id'];
			$handler->init($view, $handler_options);
			$field_handlers[$handler_name] = $handler;

			// Create and attach fake field.
			$fields[$handler_name] = $handler_options;
			$this->view->display_handler->set_option('fields', $fields);
		}
	}

Thanks @dawehner and @merlinofchaos.

merlinofchaos’s picture

I believe view::add_item() method might work then

rudiedirkx’s picture

Yup. That does exactly the same, but slightly less.

I'd still like to see it as a feature: add temporary custom fields to be reused by other fields. Like add_additional_fields, but slightly more complicated.

Any takers? =)

kars-t’s picture

Status: Active » Fixed

Dear fellow Drupal enthusiasts,

this issue is now lasting for a very long time in the issue queue and was unfortunately never solved. As Drupal is a open source project everyone is helping on voluntary basis. So that this is was not solved is nothing personal and means no harm. But perhaps no one had time to deal with this issue, maybe it is too complex or did not describe the problem comprehensibly.

But this issue is not the only one. There are thousands of issues on Drupal.org that have never been worked on or could not be processed. This means that we are building a wave that is unmanageable and just a problem for the Drupal project as a whole. Please help us keep the issue queue smaller and more manageable.

Please read again, "Making an issue report" and see if you can improve the issue. Test the problem with the current Core and modules. Maybe the problem doesn't exist anymore, is a duplicate or has even been solved within this issue but never closed.

Help can also be found for it on IRC and in the user groups.

In order to remove this issue, I have set this issue to "fixed".

If there is new information, please re-open the issue.

--
This issue was edited with the help of Issue Helper

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.