2016-08-04 19 views
1

Ich habe eine AreaPage mit $many_manyVirtualPage s:Liste sortieren von VirtualPages auf einem Feld von seiner Seite

class AreaPage extends Page { 

    /** 
    * @var array 
    */ 
    private static $many_many = [ 
     'RelatedVirtualPages' => 'VirtualPage' 
    ]; 

    // ... 

} 

Die RelatedVirtualPages sind das Kopieren von Inhalten aus ContentPage s:

class ContentPage extends Page { 

    /** 
    * @var array 
    */ 
    private static $db = [ 
     'Highlighted' => 'Boolean' 
    ]; 

    // ... 

} 

Was ist der beste Möglichkeit, RelatedVirtualPages auf dem Highlighted db-Feld der ContentPage zu sortieren, die es kopiert?

+1

Sollte nicht 'RelatedVirtualPages' => 'VirtualPages' sollte 'RelatedVirtualPages' => 'VirtualPage' sein? – jberculo

+0

Ja, du hast recht :-) Aktualisierte Frage –

Antwort

3

Virtuelle Seiten können auf Seiten unterschiedlicher Typen zeigen, und es gibt keine Durchsetzung, dass alle diese Seiten ContentPages sind, oder zumindest Seiten, die ein Hightlighted db-Feld haben. Sie können dies manuell sicherstellen, wenn Sie Ihre SiteTree erstellen, aber Benutzer könnten mitkommen und es vermasseln, also denken Sie daran.

Hier ist ein Pseudo-Code, der Ihnen den Einstieg erleichtern könnte. Es wird davon ausgegangen, dass alle virtuellen Seiten ContentPages sind. Wenn Sie mehrere Typen von VirtualPages haben, die von einem AreaPage referenziert werden, ist dies wahrscheinlich nicht ausreichend.

$virtualPages = $myAreaPage->RelatedVirtualPages(); 
$contentSourcePages = ContentPage::get()->byIDs($virtualPage->column('CopyContentFromID')); 
$sortedSourcePages = $contentSourcePages->sort('Highlighted','ASC'); 

möglicherweise könnte Sie auch ein innerJoin verwenden, aber dann muss man mit _Live Tabellen behandeln und möglicherweise mehr Seitentabellen (auch hier nur, wenn nicht ContentPage als VirtualPage mit), die mit einigen komplizierten Szenarien führen könnte.

aktualisieren

Also, in meinen eigenen Worten zusammenfassen, müssen Sie eine Liste der zu einem bestimmten AreaPage verknüpft VirtualContentPages auf dem Highlighted sortiert Feld aus der ContentPage, die jeder VirtualContentPage Links zu. Wenn diese Zusammenfassung genau ist, würde diese Arbeit:

$sortedVirtualPages = $myAreaPage->RelatedVirtualPages() 
->innerJoin('ContentPage', '"ContentPage"."ID" = "VirtualContentPage"."CopyContentFromID"') 
->sort('Highlighted DESC'); 
+0

Danke für deine Antwort und zeig mir in eine Richtung. Der Pseudocode gibt mir eine sortierte Liste der 'ContentPage's, aber ich brauche eine Liste der tatsächlichen' VirtualPages'. Ich denke, ich mache so etwas wie "VirtualPages", dann über sie zu iterieren, jedem Objekt eine "Highlighted" -Eigenschaft hinzuzufügen (ohne zu schreiben, kopiere den Wert von der Seite, die kopiert wird) und füge sie dann zu einer ArrayList hinzu, Sortieren Sie dann die ArrayList auf 'Highlighted'. Gedanken? –

+0

Um den Seitentyp als "ContentPage" durchzusetzen, habe ich diese Teile weggelassen, um eine einfache Demonstration des Problems zu ermöglichen. Im eigentlichen Code wird dies durch die Tatsache bewirkt, dass ich VirtualPage ('VirtualContentPage',' [VCP] ') erweitere, und' VCP' kann nur unter 'AreaPage' existieren, die nur' VCP' und 'ContentPage' hosten kann '. Wenn ein Editor 'VCP' ändert, um Inhalt von einer' AreaPage' zu ​​kopieren, wird ein Validierungsfehler ausgelöst (~ 'AreaPage' ist nicht als Kind von' AreaPage' erlaubt). –

+1

Danke! Ihre Zusammenfassung ist genau und die innere Verbindungslösung ist definitiv die effizienteste und sauberste Lösung. –

0

Könnten Sie nicht tun, nur

//just get one areapage 
$AreaPageItem = AreaPage::get()->First(); 

//now get the RelatedVirtualPages sorted 
$related_pages = $AreaPageItem->RelatedVirtualPages()->sort("Highlighted","ASC"); 
+0

Dies funktioniert leider nicht, da die Spalte 'Highlighted' auf VirtualPage nicht existiert und einen MySQL-Fehler verursacht. –

1

ich nicht eine sehr saubere Methode finden konnte, aber haben zwei Wege finden, um dies zu erreichen. Die Funktion geht in der Klasse AreaPage
Erste

public function getRelatedVirtualPages() 
{ 

    $items = $this->getManyManyComponents('RelatedVirtualPages'); 

    $highlighted = $items->filterByCallback(function($record, $list) { 
     if($record->CopyContentFrom() instanceOf ContentPage) { 
      //return ! $record->CopyContentFrom()->Highlighted; // ASC 
      return $record->CopyContentFrom()->Highlighted; // DESC 
     } 
    }); 

    $highlighted->merge($items); 
    $highlighted->removeDuplicates(); 

    return $highlighted; 
} 

Sekunde (die Methode, die Sie in den Kommentaren beschrieben)

public function getRelatedVirtualPages() 
{ 
    $items = $this->getManyManyComponents('RelatedVirtualPages'); 

    $arrayList = new ArrayList(); 

    foreach($items as $virtualPage) 
    { 
     if($virtualPage->CopyContentFrom() instanceOf ContentPage) { 
      $virtualPage->Highlighted = $virtualPage->CopyContentFrom()->Highlighted; 
      $arrayList->push($virtualPage); 
     } 
    } 

    $arrayList = $arrayList->sort('Highlighted DESC'); 

    return $arrayList; 
} 

Ich bin nicht sehr stolz auf eine dieser Lösungen, aber ich glaube, dass sie Ihren Kriterien entsprechen.

+1

Danke! Interessante Lösung 1. Ich würde mich dafür entscheiden, wenn ich nicht nach einem anderen Feld suchen müsste, welches ein 'Date' und kein' Boolean' ist. Lösung 2. ist das, was ich zuerst gemacht habe, aber ich fand, dass es in Bezug auf die Leistung teuer war - Abfragen der Datenbank für jede Iteration (?). Ich habe es mit der Inspiration von AlphaCactus ein wenig modifiziert, um nur zwei Abfragen auszuführen und die Ergebnisse zu speichern. Siehe meine Antwort –

1

Hier ist, was ich tun gelandet, die ich Werke denken:

/** 
* @return ArrayList 
*/ 
public function VirtualPages() 
{ 

    $result  = []; 
    $virtualPages = $this->RelatedVirtualPages(); 
    $contentPages = ContentPage::get() 
     ->byIDs($virtualPages->column('CopyContentFromID')) 
     ->map('ID', 'Highlighted') 
     ->toArray(); 

    foreach($virtualPages as $virtualPage) { 
     $highlighted = $contentPages[$virtualPage->CopyContentFromID]; 
     $virtualPage->Highlighted = $highlighted; 
     $result[] = $virtualPage; 
    } 

    return ArrayList::create(
     $result 
    ); 

} 

Und dann sortierbar es ist wie so:

$areaPage->VirtualPages()->sort('Highlighted DESC'); 

Danke für alle Antworten und Zeiger. Ich warte ein bisschen, bevor ich irgendeine Antwort ankreuze.