Puncte:2

How to create a view filter which display nodes if "field1" - "field2"

drapel sa

I have a content type with 2 fields: field1 and field2

I would like to create a view filter which display node based on a calculation on those two fields.

The filter should display only nodes if field1 - field2 is lower then a given amount.

Here is my try: At the end of the code, I don't know how to create the query

 class Myfilter extends FilterPluginBase implements ContainerFactoryPluginInterface {

  protected ViewsHandlerManager $joinHandler;

  private int $amount;

  public function __construct(array $configuration, $plugin_id, $plugin_definition, RouteMatchInterface $route_match, ViewsHandlerManager $join_handler) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->joinHandler = $join_handler;
    $this->amount = 0;
    if (($node = $route_match->getParameter('node')) && ($node->bundle()=='my_bundle')) {
      $this->amount = $node->get('field_inv_amount')->value;
    }

  }

  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration, $plugin_id, $plugin_definition,
      $container->get('current_route_match'),
      $container->get('plugin.manager.views.join')
    );
  }

  public function query() {
    //parent::query();
    
    $fields = [
      'field1',
      'field2',
    ];
    foreach ($fields as $field) {
      $table_field_name = 'node__' . $field;
      $configuration = [
        'table' => $table_field_name,
        'field' => 'nid',
        'left_table' => 'node_field_data',
        'left_field' => 'nid',
        'operator' => '=',
      ];
      $join = $this->joinHandler->createInstance('standard', $configuration);
      $this->query->addRelationship($table_field_name, $join, 'node_field_data');
    }
    // I am stuck here... field1-field2 should be < $this->amount
    $this->query->addWhere( ???? );
  }

}

Any hint will be appreciated

beltouche avatar
drapel cn
Ca alternativă, ați putea lua în considerare utilizarea https://www.drupal.org/project/computed_field și filtrați pe câmpul calculat.
Baud avatar
drapel sa
@beltouche multumesc. De asemenea, pot popula un câmp normal în timpul node_presave, dar, deoarece am multe cazuri ca acesta, aș prefera să înțeleg cum să creez acest tip de interogare. (Eu sql obișnuit, este ușor, așa că presupun că se poate face cu obiectul $query)
Puncte:1
drapel ua

Ai câteva erori:

The 'field' => 'nid', ar trebui să fie 'field' => 'entity_id',

The $join = trebuie utilizată linia Drupal\views\Views::pluginManager('alăturați-vă')


Puteți folosi addWhereExpression, exemplu de lucru:

  interogare de funcție publică () {

    $câmpuri = [
      'field_num1',
      'field_num2',
    ];

    foreach ($câmpuri ca $câmp) {
      $table_field_name = 'nod__' . $câmp;
      $configurare = [
        'table' => $table_field_name,
        'field' => 'entity_id',
        'left_table' => 'node_field_data',
        'left_field' => 'nid',
        'operator' => '=',
      ];
      $join = $this->joinHandler->createInstance('standard', $configuration);
      $this->query->addRelationship($table_field_name, $join, 'node_field_data');
    }

    // Scade și filtrează la mai puțin de cantitate.
    $this->query->addWhereExpression('ȘI', 'node__field_num1.field_num1_value - node__field_num2.field_num2_value <' . $this->amount);

  }
Baud avatar
drapel sa
Mulțumesc!, funcționează ca un farmec! O mică notă: `$this->joinHandler` nu trebuie înlocuit cu `Drupal\views\Views::pluginManager('join')` deoarece am folosit DI : `$container->get('plugin.manager .views.join')` face aceeași treabă.
No Sssweat avatar
drapel ua
Oh, da [Dependency Injection](https://www.drupal.org/docs/drupal-apis/services-and-dependency-injection/services-and-dependency-injection-in-drupal-8#s-injecting-dependencies -in-controllers-forms-and-blocks), cumva am trecut cu vederea asta.

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.