2016-05-19 11 views
0

Momentan implementiere ich das friendsofcake Such-Plugin (Version 1.2.3). Alles funktioniert, wie es mit der Ausnahme sein sollte, dass ich zwei Felder so verketten wollen:Concat Felder im Such-Plugin CakePHP 3

$this->searchManager() 
     ->add('id', 'Search.Value') 
     ->add('q', 'Search.Like', [ 
      'before' => true, 
      'after' => true, 
      'field' => [$this->aliasField('username'), $this->aliasField('name')] 
     ]) 
     ->add('q', 'Search.Callback', [ 
      'callback' => function ($query, $args, $manager) { 
       return $query->select(['name' => $query->func()->concat(
        ['first_name' => 'identifier', ' ' , 'last_name' => 'identifier'] 
       )]); 
      } 
     ]); 

Seit meiner Datenbank-Tabelle speichert first_name und last_name zu trennen Ich möchte, dass die Such Plugin sucht nach diesen beiden Feldern kombiniert (der Name). Der obige Code ignoriert die gleiche Klausel und wenn ich die Abfrage innerhalb des Callbacks drucke, scheint es die gleiche Operation zu ignorieren. Weiß jemand, wie ich zwei Felder innerhalb dieses Suchplugins darstellen kann?

Antwort

2

Sie können nicht mehrere Filter mit demselben Namen hinzufügen (q), letztere überschreibt die erstere, sie werden nicht zusammengeführt.

Sie müssen die Bedingungen auch selbst im Callback erstellen, dh Bedingungen für username und name hinzufügen. Außerdem müssen Sie HAVING verwenden, wenn Sie mit aggregierten Spalten aus der SELECT-Klausel übereinstimmen möchten, oder Sie müssen die aggregierte Spalte unter den Bedingungen WHERE auch erstellen - abhängig von dem von Ihnen verwendeten DBMS ist WHERE möglicherweise schneller (obwohl wahrscheinlich nicht bei Verwendung von LIKE, was die Verwendung von Indizes unmöglich macht, dh jede einzelne Zeile wird sowieso berührt).

Hier ist ein einfaches Beispiel mit HAVING:

'callback' => function ($query, $args, $manager) { 
    return $query 
     ->select([ 
      $this->aliasField('username'), 
      'name' => $query->func()->concat([ 
       'first_name' => 'identifier', 
       ' ' , 
       'last_name' => 'identifier' 
      ]) 
     ]) 
     ->having([ 
      'OR' => [ 
       $this->aliasField('username') . ' LIKE' => '%' . $args['q'] . '%', 
       'name LIKE' => '%' . $args['q'] . '%' 
      ] 
     ]); 
} 

* ungetestet Beispiel

+0

Da die Daten tatsächlich in das Ergebnis interpoliert werden, diese Lösung für SQL-Injection-Recht nicht sicher ist? – markvdlaan93

+0

@ markvdlaan93 Nicht sicher, was Sie meinen, die Daten werden getrennt als der Wert in einem Schlüssel festgelegt => Wert gesetzt, und somit ist es sicher, wie in Bedingungen der rechte Wert wird vorbehaltlich zu entkommen, es sei denn sie sind Expression-Objekte (um genau zu sein, werden die Werte als gebundene Parameter in einer vorbereiteten Abfrage gesetzt). – ndm

+0

@ markvdlaan93 Sie können überprüfen, indem Sie '$ query-> sql()' debuggen, die die Platzhalter zeigt, und natürlich könnten Sie es testen, indem Sie versuchen, etwas zu injizieren :) – ndm