Skip to content

Commit

Permalink
Merge pull request silverstripe#260 from creative-commoners/pulls/3.0…
Browse files Browse the repository at this point in the history
…/lazy-loaded-report

FIX Elements in use report source list is now lazy loaded allowing for larger data sets
  • Loading branch information
ScopeyNZ authored Jul 18, 2018
2 parents 540a757 + 785b50f commit 81037f1
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 44 deletions.
67 changes: 38 additions & 29 deletions src/Reports/ElementsInUseReport.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@
namespace DNADesign\Elemental\Reports;

use DNADesign\Elemental\Models\BaseElement;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\DataList;
use SilverStripe\Reports\Report;
use SilverStripe\View\ArrayData;
use SilverStripe\View\Requirements;

class ElementsInUseReport extends Report
Expand All @@ -19,42 +17,33 @@ public function title()

public function sourceRecords($params = [])
{
/** @var BaseElement[] $elements */
$elements = BaseElement::get();
/** @var DataList $elements */
$elements = BaseElement::get()->exclude(['ClassName' => BaseElement::class]);

$output = ArrayList::create();

foreach ($elements as $element) {
// Skip if filtering and looking at a different record
if (isset($params['ClassName']) && $params['ClassName'] !== $element->sanitiseClassName($element)) {
continue;
}

$output->push(ArrayData::create([
'Icon' => $element->getIcon(),
'Title' => $element->Title,
'EditLink' => $element->CMSEditLink(),
'Summary' => $element->getSummary(),
'Type' => $element->getTypeNice(),
'ClassName' => $element->sanitiseClassName(get_class($element)),
'Page' => $element->getPageTitle(),
]));
if (isset($params['ClassName'])) {
$className = $this->unsanitiseClassName($params['ClassName']);
$elements = $elements->filter(['ClassName' => $className]);
}

return $output;
return $elements;
}

public function columns()
{
return [
'Icon' => [
'title' => '',
'formatting' => function ($value, BaseElement $item) {
return $item->getIcon();
},
],
'Title' => [
'title' => _t(__CLASS__ . '.Title', 'Title'),
'formatting' => function ($value, $item) {
'formatting' => function ($value, BaseElement $item) {
$value = $item->Title;

if (!empty($value)) {
if ($item->EditLink) {
if ($item->CMSEditLink()) {
return $this->getEditLink($value, $item);
}
return $value;
Expand All @@ -65,16 +54,23 @@ public function columns()
'Summary' => [
'title' => _t(__CLASS__ . '.Summary', 'Summary'),
'casting' => 'HTMLText->RAW',
'formatting' => function ($value, BaseElement $item) {
return $item->getSummary();
},
],
'Type' => [
'title' => _t(__CLASS__ . '.Type', 'Type'),
'formatting' => function ($value, BaseElement $item) {
return $item->getTypeNice();
},
],
'Page' => [
'Page.Title' => [
'title' => _t(__CLASS__ . '.Page', 'Page'),
'formatting' => function ($value, $item) {
'formatting' => function ($value, BaseElement $item) {
if ($value) {
return $this->getEditLink($value, $item);
}
return $item->getPageTitle();
},
],
];
Expand All @@ -84,14 +80,14 @@ public function columns()
* Helper method to return the link to edit an element
*
* @param string $value
* @param ArrayData $item
* @param BaseElement $item
* @return string
*/
protected function getEditLink($value, $item)
{
return sprintf(
'<a class="grid-field__link" href="%s" title="%s">%s</a>',
$item->EditLink,
$item->CMSEditLink(),
$value,
$value
);
Expand All @@ -112,4 +108,17 @@ public function getReportField()

return $field;
}

/**
* Unsanitise a model class' name from a URL param
*
* See {@link \SilverStripe\Admin\ModelAdmin::unsanitiseClassName}
*
* @param string $class
* @return string
*/
protected function unsanitiseClassName($class)
{
return str_replace('-', '\\', $class);
}
}
27 changes: 12 additions & 15 deletions tests/Reports/ElementsInUseReportTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

namespace DNADesign\Elemental\Tests\Reports;

use DNADesign\Elemental\Models\BaseElement;
use DNADesign\Elemental\Models\ElementContent;
use DNADesign\Elemental\Reports\ElementsInUseReport;
use DNADesign\Elemental\Tests\Src\TestElement;
use DNADesign\Elemental\Tests\Src\TestPage;
use SilverStripe\Dev\FunctionalTest;
use SilverStripe\ORM\ArrayList;
use SilverStripe\View\ArrayData;
use SilverStripe\ORM\DataList;

class ElementsInUseReportTest extends FunctionalTest
{
Expand All @@ -27,7 +28,7 @@ public function testReportShowsElementsInUse()
$this->assertContains('Content blocks in use', $result, 'Title is displayed');

$this->assertContains(
'data-class="DNADesign-Elemental-Models-ElementContent"',
'data-class="DNADesign\\Elemental\\Models\\ElementContent"',
$result,
'Report contains content elements (bundled with elemental)'
);
Expand All @@ -42,14 +43,12 @@ public function testSourceRecords()
{
$records = (new ElementsInUseReport)->sourceRecords();

$this->assertInstanceOf(ArrayList::class, $records);
$this->assertNotContains(BaseElement::class, $records->toArray(), 'BaseElement is excluded');

$this->assertContainsOnlyInstancesOf(ArrayData::class, $records);
$this->assertInstanceOf(DataList::class, $records);
$this->assertNotEmpty($records);
$this->assertContainsOnlyInstancesOf(BaseElement::class, $records, 'Report contains elements');

foreach ($records as $record) {
$this->assertNotNull($record->Icon, 'Fields have an icon');
$this->assertNotNull($record->Type, 'Fields have a type');
$this->assertNotEquals(BaseElement::class, get_class($record), 'BaseElement does not exist in the report');
}
}

Expand All @@ -73,13 +72,11 @@ public function testSourceRecordsFilteredByClassName()
'ClassName' => 'DNADesign-Elemental-Models-ElementContent',
]);

$this->assertInstanceOf(ArrayList::class, $records);
$this->assertInstanceOf(DataList::class, $records);
$this->assertNotEmpty($records->toArray(), 'Results are returned when filtered');
$this->assertEquals(
[
'DNADesign-Elemental-Models-ElementContent'
],
array_unique($records->column('ClassName')),
$this->assertContainsOnlyInstancesOf(
ElementContent::class,
$records->toArray(),
'Only contains filtered element type'
);
}
Expand Down

0 comments on commit 81037f1

Please sign in to comment.