如何为报表中的记录设置自定义值?

How to set a custom value for records in a Report?

下面的代码是我使用 SilverStripe 3.1 编写的自定义报告。

Title 和 ClassName 值工作正常,但虽然我可以获得每个页面的状态,但我不确定如何针对 DataList 中的每个页面设置状态值。我该怎么做?

完成后,应填充“状态”列。

class PageListByType extends SS_Report {

    function title() {
        return 'Page List by Type';
    }

    function description() {
        return 'List all the pages in the site, along with their page type';
    }

    public function sourceRecords($params = array(), $sort = null, $limit = null) {
        $pages = Page::get()->sort($sort);
        foreach ($pages as $pagenum=>$page) {
            $flags = $page->getStatusFlags();
            if ($flags) {
                foreach ($flags as $status) {
//                    if (isset($pages[$pagenum]->Status)) die(array($pages[$pagenum]->Status, $status)); #detect multiple statuses; not sure if this will happen
                    /////////////////////////
                    // The following line needs fixing:
                    /////////////////////////
                    $pages[$pagenum]->Status = "{$status['text']} ({$status['title']})";
                }
            }
        }
//        die($pages->debug());
        return $pages;
    }

    public function columns() {
        return array(
            'Title' => _t('PageListByTypeReport.PageName', 'Page name'),
            'ClassName' => _t('PageListByTypeReport.ClassName', 'Page type'),
            'Status' => _t('PageListByTypeReport.Status', 'Status')
        );
    }
}

编辑:感谢@Turnerj 的回答!我最终的工作代码如下:

class PageListByType extends SS_Report {

    function title() {
        return 'Page List by Type';
    }

    function description() {
        return 'List all the pages in the site, along with their page type';
    }

    public function sourceRecords($params = array(), $sort = null, $limit = null) {
        $pages = DataObject::get("SiteTree", "", "");
        return $pages;
    }

    public function columns() {
        return array(
            'Title' => _t('PageListByTypeReport.PageName', 'Page name'),
            'ClassName' => _t('PageListByTypeReport.ClassName', 'Page type'),
            'Status' => _t('PageListByTypeReport.Status', 'Status')
        );
    }
}

并在 Page.php 中:

public function getStatus() {
    $flags = $this->getStatusFlags();
    $result = array();
    if ($flags) {
        foreach ($flags as $status) {
            $result[] = "{$status['text']} ({$status['title']})";
        }
    } else {
        $result[] = 'Published';
    }
    return implode(', ', $result);
}

您是否尝试过在 columns() 中使用匿名函数?

class PageListByType extends SS_Report {

  function title() {
      return 'Page List by Type';
  }

  function description() {
      return 'List all the pages in the site, along with their page type';
  }

  public function sourceRecords($params = array(), $sort = null, $limit = null) {
      return Page::get()->sort($sort);
  }

  public function columns() {
      return array(
          'Title' => _t('PageListByTypeReport.PageName', 'Page name'),
          'ClassName' => _t('PageListByTypeReport.ClassName', 'Page type'),
          'Status' => array(
             'title'=>_t('PageListByTypeReport.Status', 'Status'),
             'formatting' => function($value, $item) {
                $flags = $item->getStatusFlags();
                $status = '';
                if ($flags) {
                  foreach ($flags as $status) {
                    $status = "{$status['text']} ({$status['title']})";
                  }
                }
                return $status ? : _t('PageListByTypeReport.PagePublished', 'Page published');
             }
          )
      );
  }
}

经过进一步调查,我重新创建了问题并找到了解决方案。

总的来说,我的解决方案涉及我在评论中提出的关于通过添加 getStatus 函数将状态提取带到实际 Page 中的建议。

我基本上描述了以下内容:

public function getStatus()
{
    return $this->getStatusFlags();
}

技术上是正确的,它会得到状态标志,但你是对的,它不会在报告中显示它们。这是由于此函数 returning 了一个报表无法呈现的数组。

我的解决方案是将此函数更改为 return 一个字符串,因此通过一些简单的编辑将您所写的内容与我所写的内容结合起来,我们得到以下内容:

public function getStatus()
{
    $flags = $this->getStatusFlags();
    $result = array();
    if ($flags)
    {
        foreach ($flags as $status)
        {
            $result[] = "{$status['text']} ({$status['title']})";
        }
    }
    return implode(', ', $result);
}

我有一个独特的方法来组合我们的代码,我将每个状态添加到一个数组中,并在数组中添加 implode it back to a single string. This can seem a little excessive, by default getStatusFlag will return one key。但是,如果您有一个具有 updateStatusFlags 方法的 DataExtension,您可以向结果添加额外的键。

基本上,如果将来您确实有与状态标志混淆的代码,我会保留 implode 处理。

现在,您可以使用 Page 上的 $casting 属性 执行类似的操作,但考虑到您实际上只是为了报告而添加此功能,它更简洁直接更新它。


我确实注意到,如果页面已发布,状态标志数组实际上是空的,这意味着您的报告在已发布页面旁边没有任何内容。如果这是你的意图,那就太好了!

如果没有,你可以再做一点小改动:

public function getStatus()
{
    $flags = $this->getStatusFlags();
    $result = array();
    if ($flags)
    {
        foreach ($flags as $status)
        {
            $result[] = "{$status['text']} ({$status['title']})";
        }
    }
    else
    {
        $result[] = 'Published (The page has been published)';
    }
    return implode(', ', $result);
}

当没有当前状态(即页面已发布)时,if ($flags) 将评估为 false due to automatic casting