-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement feature to allow for banner on specific page
- Loading branch information
Showing
7 changed files
with
243 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
<?php | ||
|
||
namespace NZTA\SiteBanner\Extensions; | ||
|
||
use NZTA\SiteBanner\Models\SiteBanner; | ||
use SilverStripe\CMS\Model\SiteTree; | ||
use SilverStripe\Core\Config\Configurable; | ||
use SilverStripe\Forms\FieldList; | ||
use SilverStripe\Forms\GridField\GridField; | ||
use SilverStripe\ORM\DataExtension; | ||
use SilverStripe\ORM\DataList; | ||
use SilverStripe\ORM\DataObject; | ||
|
||
/** | ||
* Extend site banner functionality to allow for limiting banner to selected pages | ||
* | ||
* @method SiteBanner getOwner() | ||
*/ | ||
class PageSelectionExtension extends DataExtension | ||
{ | ||
|
||
use Configurable; | ||
|
||
/** | ||
* Whether or not this extension is enabled | ||
* | ||
* @config | ||
*/ | ||
private static bool $enabled = false; | ||
|
||
private static array $many_many = [ | ||
'Pages' => SiteTree::class, | ||
]; | ||
|
||
private static array $cascade_duplicates = [ | ||
'Pages', | ||
]; | ||
|
||
public function updateCMSFields(FieldList $fields): void | ||
{ | ||
$fields->removeByName('Pages'); | ||
|
||
if (!$this->getOwner()->isInDB() || !self::config()->get('enabled')) { | ||
return; | ||
} | ||
|
||
$pagesField = GridField::create('Pages', $this->getOwner()->fieldLabel('Pages')); | ||
$pagesField->setDescription( | ||
'Select pages that you would like the banner to be visible in. ' . | ||
'If none selected, then visible in all pages.', | ||
); | ||
$fields->addFieldToTab('Root.Pages', $pagesField); | ||
} | ||
|
||
/** | ||
* Modify the query that returns the banner to be visible to the public user | ||
*/ | ||
public function onFrontendQuery(DataList $query, ?int $pageId = null): DataList | ||
{ | ||
// Skip implementation if no page is provided or extension disabled | ||
if (!$pageId || !self::config()->get('enabled')) { | ||
return $query; | ||
} | ||
|
||
$rightTable = DataObject::getSchema()->tableName(SiteBanner::class); | ||
$pagesRelation = DataObject::getSchema()->manyManyComponent(SiteBanner::class, 'Pages'); | ||
$leftTable = $pagesRelation['join']; | ||
|
||
// Search for banners that must be visible in current page only | ||
$query1 = $query->innerJoin( | ||
$leftTable, | ||
sprintf('%s.%s = "%s"."ID"', $leftTable, $pagesRelation['parentField'], $rightTable), | ||
$leftTable, | ||
)->where([ | ||
'"' . $pagesRelation['join'] . '"."SiteTreeID" = ?' => $pageId, | ||
]); | ||
|
||
if ($query1->count()) { | ||
return $query1; | ||
} | ||
|
||
// If no banner selected for current page, then return banners not defined to specific page | ||
return $query->leftJoin( | ||
$leftTable, | ||
sprintf('%s.%s = "%s"."ID"', $leftTable, $pagesRelation['parentField'], $rightTable), | ||
$leftTable, | ||
)->where([ | ||
['"' . $pagesRelation['join'] . '"."SiteTreeID" IS NULL',], | ||
]); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
<?php | ||
|
||
namespace NZTA\SiteBanner\Tests; | ||
|
||
use NZTA\SiteBanner\Extensions\PageSelectionExtension; | ||
use NZTA\SiteBanner\Models\SiteBanner; | ||
use NZTA\SiteBanner\Templates\TemplateProvider; | ||
use SilverStripe\Dev\SapphireTest; | ||
use SilverStripe\Forms\GridField\GridField; | ||
use SilverStripe\ORM\DataObject; | ||
use SilverStripe\ORM\Queries\SQLInsert; | ||
|
||
/** | ||
* @phpcs:disable SlevomatCodingStandard.TypeHints.PropertyTypeHint.MissingAnyTypeHint | ||
* @phpcs:disable SlevomatCodingStandard.TypeHints.PropertyTypeHint.MissingAnyTypeHint | ||
* @phpcs:disable SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingAnyTypeHint | ||
* @phpcs:disable SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingAnyTypeHint | ||
*/ | ||
class PageSelectionTest extends SapphireTest | ||
{ | ||
protected static $fixture_file = 'PageSelectionTest.yml'; | ||
|
||
public function testVisibleInHomepageOnly(): void | ||
{ | ||
PageSelectionExtension::config()->set('enabled', true); | ||
|
||
// All banners - we have 3 | ||
$banners = TemplateProvider::getSiteBanners(); | ||
|
||
// Pick a banner | ||
$first = $banners->first(); | ||
|
||
// Fake page ID | ||
$pageId = 3; | ||
|
||
// Add the picked banner to be visible in $pageId | ||
$pagesRelation = DataObject::getSchema()->manyManyComponent(SiteBanner::class, 'Pages'); | ||
SQLInsert::create($pagesRelation['join'], [ | ||
'SiteBannerID' => $first->ID, | ||
'SiteTreeID' => $pageId, | ||
])->execute(); | ||
|
||
// Assert on a page we see 2 banners as one visible in $pageId only | ||
self::assertEquals(2, TemplateProvider::getSiteBanners(4)->count()); | ||
|
||
// Assert one banner visible in $pageId | ||
self::assertEquals(1, TemplateProvider::getSiteBanners($pageId)->count()); | ||
|
||
// Assert banners other than the picked one are visible in other pages | ||
self::assertEquals( | ||
$banners->exclude('ID', $first->ID)->column('ID'), | ||
TemplateProvider::getSiteBanners(4)->column('ID'), | ||
); | ||
|
||
// Move banners to $pageId | ||
foreach ($banners as $banner) { | ||
SQLInsert::create($pagesRelation['join'], [ | ||
'SiteBannerID' => $banner->ID, | ||
'SiteTreeID' => $pageId, | ||
])->execute(); | ||
} | ||
|
||
// No banner to display | ||
self::assertEquals(0, TemplateProvider::getSiteBanners(4)->count()); | ||
|
||
// All banners visible in $pageId | ||
self::assertEquals($banners->count(), TemplateProvider::getSiteBanners($pageId)->count()); | ||
|
||
// Disable extension | ||
PageSelectionExtension::config()->set('enabled', false); | ||
|
||
// banners visible in all pages | ||
self::assertEquals(3, TemplateProvider::getSiteBanners(4)->count()); | ||
} | ||
|
||
public function testPagesField(): void | ||
{ | ||
PageSelectionExtension::config()->set('enabled', false); | ||
|
||
// Assert new records does not show grid field for pages | ||
$siteBanner1 = SiteBanner::create(); | ||
$this->assertNull($siteBanner1->getCMSFields()->dataFieldByName('Pages')); | ||
|
||
// Assert existing records does not show grid field for pages if extension not added | ||
$siteBanner2 = $this->objFromFixture(SiteBanner::class, 'banner1'); | ||
$this->assertTrue($siteBanner2->exists()); | ||
$this->assertNull($siteBanner2->getCMSFields()->dataFieldByName('Pages')); | ||
|
||
// Assert existing records does show grid field for pages if extension added | ||
PageSelectionExtension::config()->set('enabled', true); | ||
$this->assertInstanceOf(GridField::class, $siteBanner2->getCMSFields()->dataFieldByName('Pages')); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
NZTA\SiteBanner\Models\SiteBanner: | ||
banner1: | ||
Sort: 1 | ||
Type: alert | ||
Content: | | ||
<p>Bold message text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean sodales posuere sed sit amet nibh.</p> | ||
banner2: | ||
Sort: 2 | ||
Type: info | ||
Dismiss: 1 | ||
Content: | | ||
<p><strong>Bold message text.</strong> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean sodales posuere sed sit <a href="/">amet nibh</a>.</p> | ||
banner3: | ||
Sort: 3 | ||
Type: warning | ||
Content: | | ||
<p><strong>Bold message text.</strong> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean sodales posuere sed sit <a href="/">amet nibh</a>.</p> |