Merge pull request #113 from creative-commoners/pulls/4.4/make-a-breadcrumb-trail

NEW Allow reports to specify breadcrumbs for child reports
This commit is contained in:
Maxime Rainville 2018-11-23 09:12:59 +13:00 committed by GitHub
commit f074256a16
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 158 additions and 13 deletions

View File

@ -29,6 +29,7 @@ use SilverStripe\ORM\SS_List;
use SilverStripe\Security\Member;
use SilverStripe\Security\Permission;
use SilverStripe\Security\Security;
use SilverStripe\View\ArrayData;
use SilverStripe\View\ViewableData;
/**
@ -345,12 +346,7 @@ class Report extends ViewableData
*/
public function getReportField()
{
$params = [];
if (Injector::inst()->has(HTTPRequest::class)) {
/** @var HTTPRequest $request */
$request = Injector::inst()->get(HTTPRequest::class);
$params = $request->param('filters') ?: $request->requestVar('filters') ?: [];
}
$params = $this->getSourceParams();
$items = $this->sourceRecords($params, null, null);
$gridFieldConfig = GridFieldConfig::create()->addComponents(
@ -464,10 +460,8 @@ class Report extends ViewableData
/**
* Return the name of this report, which
* is used by the templates to render the
* name of the report in the report tree,
* the left hand pane inside ReportAdmin.
* Return the name of this report, which is used by the templates to render the name of the report in the report
* tree, the left hand pane inside ReportAdmin.
*
* @return string
*/
@ -475,4 +469,33 @@ class Report extends ViewableData
{
return $this->title();
}
/**
* Return additional breadcrumbs for this report. Useful when this report is a child of another.
*
* @return ArrayData[]
*/
public function getBreadcrumbs()
{
return [];
}
/**
* Get source params for the report to filter by
*
* @return array
*/
protected function getSourceParams()
{
$params = [];
if (Injector::inst()->has(HTTPRequest::class)) {
/** @var HTTPRequest $request */
$request = Injector::inst()->get(HTTPRequest::class);
$params = $request->param('filters') ?: $request->requestVar('filters') ?: [];
}
$this->extend('updateSourceParams', $params);
return $params;
}
}

View File

@ -172,11 +172,21 @@ class ReportAdmin extends LeftAndMain implements PermissionProvider
// Uses session state for current record otherwise.
$items[0]->Link = singleton('SilverStripe\\Reports\\ReportAdmin')->Link();
if ($this->reportObject) {
if ($report = $this->reportObject) {
$breadcrumbs = $report->getBreadcrumbs();
if (!empty($breadcrumbs)) {
foreach ($breadcrumbs as $crumb) {
$items->push($crumb);
}
}
//build breadcrumb trail to the current report
$items->push(new ArrayData(array(
'Title' => $this->reportObject->title(),
'Link' => Controller::join_links($this->Link(), '?' . http_build_query(array('q' => $this->request->requestVar('q'))))
'Title' => $report->title(),
'Link' => Controller::join_links(
$this->Link(),
'?' . http_build_query(array('q' => $this->request->requestVar('q')))
)
)));
}

75
tests/ReportAdminTest.php Normal file
View File

@ -0,0 +1,75 @@
<?php
namespace SilverStripe\Reports\Tests;
use ReflectionClass;
use SilverStripe\Control\Controller;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\Reports\Report;
use SilverStripe\Reports\ReportAdmin;
use SilverStripe\Reports\Tests\ReportAdminTest\FakeReport;
use SilverStripe\Reports\Tests\ReportAdminTest\FakeReport2;
class ReportAdminTest extends SapphireTest
{
public function testBreadcrumbsAreGenerated()
{
$noExtraCrumbs = FakeReport::create();
$controller = $this->mockController($noExtraCrumbs);
$breadcrumbs = $controller->BreadCrumbs();
$this->assertCount(2, $breadcrumbs);
$this->assertArraySubset([
'Title' => 'Reports',
'Link' => 'admin/reports/',
], $breadcrumbs[0]->toMap(), true, 'Link to top level reports is within breadcrumbs');
$this->assertArraySubset([
'Title' => 'Fake report'
], $breadcrumbs[1]->toMap(), true, 'Current report is within breadcrumbs');
$extraCrumbs = FakeReport2::create();
$controller = $this->mockController($extraCrumbs);
$breadcrumbs = $controller->Breadcrumbs();
$this->assertCount(3, $breadcrumbs);
$this->assertArraySubset([
'Title' => 'Reports',
'Link' => 'admin/reports/',
], $breadcrumbs[0]->toMap(), true, 'Link to top level reports is within breadcrumbs (again)');
$this->assertArraySubset([
'Title' => 'Fake report title',
'Link' => 'admin/reports/show/SilverStripe-Reports-Tests-ReportAdminTest-FakeReport',
], $breadcrumbs[1]->toMap(), true, 'Custom breadcrumb appears');
$this->assertArraySubset([
'Title' => 'Fake report two'
], $breadcrumbs[2]->toMap(), true, 'Current report is still within breadcrumbs');
}
/**
* @param Report $report
* @return ReportAdmin
* @throws \ReflectionException
*/
protected function mockController(Report $report)
{
$reflector = new ReflectionClass($controller = ReportAdmin::create());
$reportClass = $reflector->getProperty('reportClass');
$reportClass->setAccessible(true);
$reportClass->setValue($controller, get_class($report));
$reportObject = $reflector->getProperty('reportObject');
$reportObject->setAccessible(true);
$reportObject->setValue($controller, $report);
$controller->setRequest(Controller::curr()->getRequest());
return $controller;
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace SilverStripe\Reports\Tests\ReportAdminTest;
use SilverStripe\Dev\TestOnly;
use SilverStripe\Reports\Report;
class FakeReport extends Report implements TestOnly
{
public function title()
{
return 'Fake report';
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace SilverStripe\Reports\Tests\ReportAdminTest;
use SilverStripe\Control\Controller;
use SilverStripe\Dev\TestOnly;
use SilverStripe\Reports\Report;
use SilverStripe\Reports\ReportAdmin;
use SilverStripe\View\ArrayData;
class FakeReport2 extends Report implements TestOnly
{
public function title()
{
return 'Fake report two';
}
public function getBreadcrumbs()
{
return [ArrayData::create([
'Title' => 'Fake report title',
'Link' => FakeReport::singleton()->getLink()
])];
}
}