Hi,
I want to know if ther is any chance to use weight on "products" (from drupal commerce) that are in cart.
The problem is it's not nodes.

Thanks.

Comments

davisben’s picture

Version: 7.x-2.0-beta1 » 7.x-2.x-dev
Status: Active » Postponed

It is not currently possible, but I've been thinking about extending the module to handle all entities, but would like to get a stable release of the 7.x-2.x branch first.

davisben’s picture

Status: Postponed » Active

As we're nearing a stable 7.x-2.0 release, it's time to start thinking about this. We'll need to decide on how to determine if an entity can be weighted. Anyone have any suggestions?

NancyDru’s picture

Title: use weight for cart items » Entity weighting
Issue tags: +Roadmap

The concept of "nodes" is evolving and possibly going away eventually (probably D9). As such, I wonder about the future need of Weight at all, but switching to entity weighting may have value. I suspect it would require pretty much a re-write along with the re-purpose.

It would be good to collect use cases here to see whether or not Weight should live on in a Fields-world.

davisben’s picture

The 2.x rewrite was done with entities in mind, so it shouldn't be to hard to extend Weight to handle them if there are appropriate use cases.

OnkelTem’s picture

As far as I understand, now a generic code for retrieving entities can't accomplish the task of sorting them by Weight, for example:

$entity_type = 'node';
$bundle = 'project';
$query = new EntityFieldQuery();
$result = $query
    ->entityCondition('entity_type', $entity_type)
    ->entityCondition('bundle', $bundle)
    ->fieldCondition('field_some_reference', 'nid', $nid, '=')
    ->execute();
if (!empty($result[$entity_type])) {
  $nids = array_keys($result[$entity_type]);
}

From the other hand, the code which can sort by Weight, is unable to filter by fields. For example:

$select = db_select('node', 'n');
$select->join('weight_weights', 'w', 'w.entity_id = n.nid');
$select->fields('n', array('nid'))
    ->condition('n.type', 'project')
    ->orderBy('w.weight', 'ASC');
$nids = $select->execute()->fetchCol();

Which way to go?

davisben’s picture

You should be able to do something like this:

<?php
$select = db_select('node', 'n');
$select->join('field_some_reference', 'fsr', 'fsr.entity_id = n.nid');
$select->join('weight_weights', 'w', 'w.entity_id = n.nid');
$select->fields('n', array('nid'))
    ->condition('n.type', 'project')
    ->orderBy('w.weight', 'ASC');
$nids = $select->execute()->fetchCol();
?>

This is untested and off the top of my head, so it's likely that it will need to be tweaked.

OnkelTem’s picture

You should be able to do something like this:...

I believe we can't expect and relay on some specific storage configuration. And you know that too :)
Is there way to declare Weight as a field somehow?

daniel.nitsche’s picture

Here's how I did it (in this way, you don't have to revert entirely to using db_select):

// When creating your EFQ
$query->addTag('sort_by_weight');

function yourmodule_query_sort_by_weight_alter(QueryAlterableInterface $query) {
  $query->join('weight_weights', 'w', 'node.nid = w.entity_id');
  $query->fields('w', array('weight'));
  $query->orderBy('w.weight', 'ASC');
  // var_dump($query->getOrderBy());
}

Credit to:
http://drupal.stackexchange.com/questions/34454
http://drupal.org/node/1157006#comment-5465034

Summit’s picture

Hi,
Could anyone eleborate how to use this within Drupal Commerce product views?
It would be great to be able to set a weight field on my products and order them by this within the product views.

Thanks a lot in advance for your reply!
greetings,
Martijn

Summit’s picture

Hi, I also asked the Commerce Guru http://drupal.org/node/1930290, he points me back to here.
I would very much like to use the weight field as in nodes for product entities!
Greetings, Martijn

sanguis’s picture

I think a a WeightEntityField query class extention would be worth it. I am woring on the hook_query_tag_alter now.

sanguis’s picture

I created a sandbox module that will allow you to create an efq to sort NODE entiies. here it is in action.

$query = new WeightEntityFieldQuery();
  $result = $query
    ->propertyCondition('status', 1)
    ->entityCondition('bundle', 'page_header')
    ->range(0,3)
    ->execute()
  ;

I think it should be a weight patch. But if that is not in the vision for this project let me know and I will promote it to its own project.
http://drupal.org/sandbox/sanguis/1943932

Alan D.’s picture

Interesting discussion. Picked the best bits for a custom module for a project that I am working on.

Note 1

The sand box is now a full project, https://drupal.org/project/weight_efq (I'm not associated with this project).

Note 2
I'm not so sure on the fairly generic 'weight' tag that the project uses, preferring a much more verbose 'node_weight_order' to avoid potential clashes.

class GloNodeFieldQuery extends EntityFieldQuery {

  /**
   * Integrates with the weight module to order by weight.
   */
  public function orderByWeight() {
    $this->addTag('node_weight_order');
    return $this;
  }

}

and the alter.

/**
 * Implements hook_query_TAG_alter().
 */
function HOOK_query_node_weight_order_alter(QueryAlterableInterface $query) {
  if (module_exists('weight')) {
    $query->join('weight_weights', 'w', 'node.nid = w.entity_id');
    $query->fields('w', array('weight'));
    $query->orderBy('w.weight', 'ASC');
  }
}

Note 3

The join alias w could potentially be used, messier, but it is best to use the returned alias from the join ;)

  $join_alias = $select_query->join('weight_weights', 'w', 'node.nid = %alias.entity_id');

Note 4

This assumes that there are values in the table, and if weight is not enabled on the content type, no results will ever be returned from that type. This may or may not be the desire behavior, in my use-case only one of the two types being queried was associated with weight.

$join_alias = $select_query->leftJoin('weight_weights', 'w', 'node.nid = %alias.entity_id');
$query->addExpression('COALESCE(' . $join_alias . '.weight, 0)', 'weight');
$query->orderBy('weight', 'ASC');

But since it was a custom project with an overridden EntityFieldQuery::finishQuery() method already, I handled things there to avoid the query alter hook.

class GloNodeFieldQuery extends EntityFieldQuery {

  protected $orderByWeight = FALSE;

  /**
   * Integrates with the weight module to order by weight.
   */
  public function orderByWeight() {
    $this->orderByWeight = TRUE;
    return $this;
  }

  function finishQuery($select_query, $id_key = 'entity_id') {
    ....
    // Handle the join here rather than a new hook_query_alter().
    $weight_alias = 'weight';
    if ($this->orderByWeight && module_exists('weight')) {
      $join_alias = $select_query->leftJoin('weight_weights', 'w', 'node.nid = %alias.entity_id');
      $weight_alias = $select_query->addExpression('COALESCE(' . $join_alias . '.weight, 0)', $weight_alias);
      $select_query->orderBy($weight_alias, 'ASC');
    }
    ....
    // [EDIT]
    // The reason why we were overriding finishQuery()
    $select_query->addField('node', 'title', 'entity_label');
    $return = array();
    foreach ($select_query->execute() as $partial_entity) {
      // Should never happen as nodes have bundles...
      $bundle = isset($partial_entity->bundle) ? $partial_entity->bundle : NULL;
      $entity = entity_create_stub_entity($partial_entity->entity_type, array($partial_entity->entity_id, $partial_entity->revision_id, $bundle));
      // The next override, pull out the title and weight fields to return.
      $entity->title = $partial_entity->entity_label;
      if ($this->orderByWeight) {
        $entity->weight = $partial_entity->{$weight_alias};
      }
      $return[$partial_entity->entity_type][$partial_entity->$id_key] = $entity;
      $this->ordered_results[] = $partial_entity;
    }
    return $return;
    // [/EDIT]
  }
}

This allows a single entity field query to order by weight and pull out the node title and weight without having to do a resource hungry node_load_multiple()

davisben’s picture

Issue summary: View changes

Coming soon! I'll have a Field API based dev version of the module posted by the end of the week.

Ludo.R’s picture

Nice, looking for it! :)

OnkelTem’s picture

Coming soon! I'll have a Field API based dev version of the module posted by the end of the week.

Is it ready?

davisben’s picture

Status: Active » Closed (fixed)

There is now a beta release posted. I'm closing this issue in favor of individual issues going forward.

davisben’s picture

Status: Closed (fixed) » Fixed

Status: Fixed » Closed (fixed)

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