从页面中对字段上的VirtualPages列表进行排序

时间:2016-08-04 13:21:50

标签: silverstripe

我有AreaPage $many_many VirtualPage s:

class AreaPage extends Page {

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

    // ...

}

RelatedVirtualPages正在复制来自ContentPage的内容:

class ContentPage extends Page {

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

    // ...

}

RelatedVirtualPages复制的Highlighted数据库字段中对ContentPage进行排序的最佳方法是什么?

4 个答案:

答案 0 :(得分:3)

虚拟页面可以指向不同类型的页面,并且不强制所有这些页面都是ContentPages,或者至少是具有Hightlighted db字段的页面。您可以在创建SiteTree时手动确保此操作,但是用户可能会出现并将其搞砸,请记住这一点。

这是一些可能有助于您入门的伪代码。它假定所有虚拟页面都是ContentPages。如果您有VirtualPages引用的多种AreaPage类型,那么这可能还不够。

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

您可能还可以使用innerJoin,但是您必须处理_Live表格和可能的多个页面表格(如果不仅仅使用ContentPage作为VirtualPage),那么这可能会导致对于一些复杂的场景。

<强>更新

因此,总而言之,您需要一个VirtualContentPages列表,其中列出的AreaPage字段与Highlighted字段中的ContentPage字段相关联VirtualContentPage个链接到。如果此摘要准确无误,那么这是否有效:

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

答案 1 :(得分:1)

我找不到一个非常干净的方法,但确实找到了两种方法来实现这一目标。该功能在课程AreaPage中进行 的第一

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;
}

其次(您在评论中描述的方法)

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;
}

我对这些解决方案并不感到自豪,但我相信它们符合您的标准。

答案 2 :(得分:1)

这是我最终做的事情,我觉得有效:

/**
 * @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
    );

}

然后它可以这样排序:

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

感谢您的所有答案和指示。在标记任何答案之前我会稍等一下。

答案 3 :(得分:0)

你能不能做到

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

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