Silverstripe:$ has_many汇总字段问题

时间:2017-03-22 05:24:48

标签: php silverstripe

我正在尝试使用Has_many关系作为DataObject的摘要字段,但似乎无法使其正常工作。

基本上:

  • 我有一个表单
  • 每个表单都有许多提交/条目
  • 每个表单都有多个字段
  • 每个字段都有许多答案

我正在尝试在每个表单的后端管理区域中创建一个网格字段,该字段显示每个表单的条目。

在条目的摘要字段中,我想显示创建的日期,以及该表单的前3个字段。

因此,例如,如果我们有一个带有姓名,电子邮件和电话字段的表单,汇总字段将如下所示:

  • 创建日期
  • 名称
  • 电子邮件
  • 电话

将相关条目数据/响应作为条目的摘要信息。

这是我到目前为止所拥有的。这是表单

<?php

class ContactBlock extends Block {
    private static $db = array(
        // Fields for the form/block go here
    );

    private static $has_many = array(
        'ContactBlockFields' => 'ContactBlockField',
        'ContactBlockEntries' => 'ContactBlockEntry' 
    );

    public function getCMSFields() {

       // Irrelevant code goes here!


        // CONTACT BLOCK ENTRIES
        $entriesInfo = new GridFieldDataColumns();
        $entriesInfo->setDisplayFields(singleton('ContactBlockEntry')->summaryFields());

        $entriesConfig = GridFieldConfig::create();
        $entriesConfig->addComponents(
            new GridFieldToolbarHeader(),
            new GridFieldAddNewButton('toolbar-header-right'),
            $entriesInfo,
            new GridFieldSortableHeader(),
            new GridFieldPaginator(50),
            new GridFieldEditButton(),
            new GridFieldDeleteAction(),
            new GridFieldDetailForm()
        );

        $entriesGrid = GridField::create('ContactBlockEntries', 'Form Entries', $this->ContactBlockEntries(), $entriesConfig);
        $fields->addFieldToTab('Root.FormEntries', $entriesGrid);

        return $fields;
    }

}

这是条目 DataObject:

<?php

class ContactBlockEntry extends DataObject {

    private static $has_one = array(
        'ContactBlock' => 'ContactBlock'
    );

    private static $has_many = array(
        'ContactBlockFieldAnswers' => 'ContactBlockFieldAnswer',
    );

    private static $many_many = array(
        'FormFields' => 'ContactBlockField'
    );

    static $summary_fields = array(
        'Date'
    );

    public function getCMSFields() {
        $fields = parent::getCMSFields();

        //=== REMOVE FIELDS ====
        $fields->removeFieldFromTab('Root','FormFields');
        $fields->removeFieldFromTab('Root','ContactBlockFieldAnswers');
        $fields->removeFieldFromTab('Root.Main','ContactBlockID');
        //=== REMOVE FIELDS ====

        return $fields;
    }

    public function onBeforeDelete() {
        parent::onBeforeDelete();

        // Delete answers that are associated with this block.
        $data = ContactBlockFieldAnswer::get()
           ->filter('ContactBlockEntry', $this->ID);

        foreach( $data as $d) {
            $d->delete();
        }

    }

    public function getDate() {
        $date = date('d/m/Y',strtotime($this->Created));
        return $date;
    }

}

这是字段代码:

<?php

class ContactBlockField extends DataObject {
    private static $db = array(
        'SortOrder' => 'Int',
        'FieldName' => 'Varchar',
        'FieldType' => 'Varchar',
        'DropdownValues' => 'Varchar(255)',
        'Label' => 'Varchar',
        'Placeholder' => 'Varchar',
        'Required' => 'Boolean'
    );

    private static $has_one = array(
        'ContactBlock' => 'ContactBlock',
    );

    private static $has_many = array(
        'ContactBlockFieldAnswer' => 'ContactBlockFieldAnswer',
    );

    private static $belongs_many_many = array(
        'Entries' => 'ContactBlockEntry'
    );

    static $searchable_fields = array(
        'FieldType',
        'FieldLabel',
        'Required'
    );

    static $summary_fields = array(
        'FieldType' => 'Field Type',
        'Label' => 'Field Label',
        'Required'  => 'Required Field?'
    );

    public function getCMSFields() {
        $fields = parent::getCMSFields();

          // Unrelated stuff here

        return $fields;
    }

}

我似乎无法弄清楚如何获取列标签,以及它们在gridfield上显示的相关数据。任何帮助或建议将不胜感激。

更新24/3/17:

好的,我还有一点这个。在ContactBlockEntry DataObject上,在实现UncleCheese建议的更改后,我发现了以下内容:

public function getFirstField() {
        return $this->FormFields()->first();
    }

    public function getSecondField() {
        return $this->FormFields()->offsetGet(1);
    }

    public function getThirdField() {
        return $this->FormFields()->offsetGet(2);
    }

    public function summaryFields() {
        return [
            'Date'                      => 'Submitted',
            'Answers.First.Value'       => $this->getFirstField()->Label,
            'Answers.Second.Value'      => $this->getSecondField()->Label,
            'Answers.Third.Value'       => $this->getThirdField()->Label,
        ];
    }

$this->getFirstField()->Label正在返回[Notice] Trying to get property of non-object但是,当我在getCMSFields()中回显/打印此函数时,我可以看到标签值。

Answers.First.Value有效。它返回在第一个字段中提交的值/答案。问题是,我似乎无法获得第二个和第三个值,因为我无法找出检索它们的方法。我尝试了offsetGet(),它说方法不可用。

1 个答案:

答案 0 :(得分:5)

在这种情况下,您可以定义summaryFields()方法来代替静态数组。这将允许您返回标题的计算值。

让事情变得复杂的是获得价值观。前三个字段不是Entry对象的属性,因此您需要为Entry数据对象提供getter,以便将它们即时计算为“虚拟”属性。它有点笨重,但这样的事情应该有效。

public function getFirstField()
{
    return $this->FormFields()->first();
}

public function getSecondField()
{
    return $this->FormFields()->offsetGet(1);
}

public function getThirdField()
{
    return $this->FormFields()->offsetGet(2);
}

public function summaryFields()
{
    return [
        'Created' => 'Created',
        'FirstField.Answer' => $this->getFirstField()->FieldName,
        'SecondField.Answer' => $this->getSecondField()->FieldName,
        'ThirdField.Answer' => $this->getThirdField()->FieldName,
    ];
}
但是,我对你的数据模型不太了解。您的字段对象的答案有has_many。在这种情况下,您必须在AnswerLabel的Field对象上创建另一个getter,它以某种方式将所有答案连接成一个字符串,或者可能只是获得第一个。无论您选择何种业务逻辑。只需在数组中使用FirstField.AnswerLabel等,或者您选择调用该方法的任何内容。关键是,您需要将多个关系解析为单个可读值。你是怎么做到的,取决于你。