Skip to content

Commit

Permalink
ENH: Explicit configuration API properties.
Browse files Browse the repository at this point in the history
  • Loading branch information
mfendeksilverstripe committed Apr 8, 2024
1 parent 7bf314a commit 973526e
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 146 deletions.
22 changes: 19 additions & 3 deletions src/Extension/FluentExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
use SilverStripe\ORM\Queries\SQLConditionGroup;
use SilverStripe\ORM\Queries\SQLSelect;
use SilverStripe\ORM\ValidationException;
use SilverStripe\Security\Permission;
use SilverStripe\Versioned\Versioned;
use SilverStripe\View\HTML;
use TractorCow\Fluent\Extension\Traits\FluentObjectTrait;
Expand All @@ -48,6 +47,7 @@
*
* @template T of DataObject
* @extends DataExtension<T&static>
* @property DataObject|$this $owner
*/
class FluentExtension extends DataExtension
{
Expand Down Expand Up @@ -85,6 +85,22 @@ class FluentExtension extends DataExtension
*/
const INHERITANCE_MODE_ANY = 'any';

/**
* Fluent inheritance mode for CMS context
*
* @var string
* @config
*/
private static string $cms_localisation_required = self::INHERITANCE_MODE_ANY;

/**
* Fluent inheritance mode for frontend context
*
* @var string
* @config
*/
private static string $frontend_publish_required = self::INHERITANCE_MODE_FALLBACK;

/**
* DB fields to be used added in when creating a localised version of the owner's table
*
Expand Down Expand Up @@ -582,11 +598,11 @@ public function augmentSQL(SQLSelect $query, DataQuery $dataQuery = null)

// Apply substitutions
$localisedPredicate = str_replace($conditionSearch, $conditionReplace, $predicate);

if (empty($localisedPredicate)) {
continue;
}

$where[$index] = [
$localisedPredicate => $parameters
];
Expand Down
8 changes: 8 additions & 0 deletions src/Extension/FluentFilteredExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ class FluentFilteredExtension extends DataExtension
*/
const SUFFIX = 'FilteredLocales';

/**
* Allow the filtered locale behaviour to be skipped for draft stage only
*
* @var bool
* @config
*/
private static bool $apply_filtered_locales_to_stage = false;

private static $many_many = [
'FilteredLocales' => Locale::class,
];
Expand Down
20 changes: 9 additions & 11 deletions tests/php/Extension/FluentFilteredExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@

use Page;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\Core\Config\Config;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\ORM\DataObject;
use SilverStripe\Versioned\Versioned;
use TractorCow\Fluent\Extension\FluentFilteredExtension;
use TractorCow\Fluent\Extension\FluentSiteTreeExtension;
Expand Down Expand Up @@ -44,14 +42,14 @@ protected function setUp(): void
public function testAugmentSQLFrontend()
{
// Specifically set this config value so that filtered locales ARE required in stage=Stage.
Config::modify()->set(DataObject::class, 'apply_filtered_locales_to_stage', true);
SiteTree::config()->set('apply_filtered_locales_to_stage', true);

$currentStage = Versioned::get_stage();

Versioned::set_stage(Versioned::DRAFT);

FluentState::singleton()->withState(function (FluentState $newState) {
$newState
FluentState::singleton()->withState(function (FluentState $state) {
$state
->setLocale('en_NZ')
->setIsFrontend(true)
->setIsDomainMode(false);
Expand All @@ -72,14 +70,14 @@ public function testAugmentSQLFrontend()
public function testAugmentSQLFrontendLive()
{
// Specifically set this config value so that filtered locales ARE required in stage=Stage.
Config::modify()->set(DataObject::class, 'apply_filtered_locales_to_stage', true);
SiteTree::config()->set('apply_filtered_locales_to_stage', true);

$currentStage = Versioned::get_stage();

Versioned::set_stage(Versioned::LIVE);

FluentState::singleton()->withState(function (FluentState $newState) {
$newState
FluentState::singleton()->withState(function (FluentState $state) {
$state
->setLocale('en_NZ')
->setIsFrontend(true);

Expand All @@ -99,15 +97,15 @@ public function testAugmentSQLFrontendLive()
public function testAugmentSQLStage()
{
// Specifically set this config value so that filtered locales are NOT required in stage=Stage.
Config::modify()->set(DataObject::class, 'apply_filtered_locales_to_stage', false);
SiteTree::config()->set('apply_filtered_locales_to_stage', false);

$currentStage = Versioned::get_stage();

Versioned::set_stage(Versioned::DRAFT);

// Run test
FluentState::singleton()->withState(function (FluentState $newState) {
$newState
FluentState::singleton()->withState(function (FluentState $state) {
$state
->setLocale('en_NZ')
->setIsFrontend(true);

Expand Down
218 changes: 87 additions & 131 deletions tests/php/Extension/FluentSiteTreeExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@
use SilverStripe\Core\Config\Config;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\Forms\CompositeField;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\LiteralField;
use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\ValidationException;
use SilverStripe\Versioned\Versioned;
use TractorCow\Fluent\Extension\FluentDirectorExtension;
Expand Down Expand Up @@ -334,140 +332,94 @@ function (FluentState $newState) use ($localeCode, $fixture, $expected) {
);
}

public function testHomeVisibleOnFrontendBothConfigAny()
{
Config::modify()->set(DataObject::class, 'cms_localisation_required', FluentExtension::INHERITANCE_MODE_ANY);
Config::modify()->set(DataObject::class, 'frontend_publish_required', FluentExtension::INHERITANCE_MODE_ANY);

FluentState::singleton()->withState(function (FluentState $newState) {
$newState
->setLocale('de_DE')
->setIsDomainMode(false)
->setIsFrontend(true);

$page = Page::get()->filter('URLSegment', 'home')->first();

$this->assertNotNull($page);
});
}

public function testHomeVisibleOnFrontendOneConfigAny()
{
Config::modify()->set(DataObject::class, 'cms_localisation_required', FluentExtension::INHERITANCE_MODE_EXACT);
Config::modify()->set(DataObject::class, 'frontend_publish_required', FluentExtension::INHERITANCE_MODE_ANY);

FluentState::singleton()->withState(function (FluentState $newState) {
$newState
->setLocale('de_DE')
->setIsDomainMode(false)
->setIsFrontend(true);

$page = Page::get()->filter('URLSegment', 'home')->first();

$this->assertNotNull($page);
});
}

public function testHomeNotVisibleOnFrontendBothConfigExact()
{
Config::modify()->set(DataObject::class, 'cms_localisation_required', FluentExtension::INHERITANCE_MODE_EXACT);
Config::modify()->set(DataObject::class, 'frontend_publish_required', FluentExtension::INHERITANCE_MODE_EXACT);

FluentState::singleton()->withState(function (FluentState $newState) {
$newState
->setLocale('de_DE')
->setIsDomainMode(false)
->setIsFrontend(true);

$page = Page::get()->filter('URLSegment', 'home')->first();

$this->assertNull($page);
});
}

public function testHomeNotVisibleOnFrontendOneConfigExact()
{
Config::modify()->set(DataObject::class, 'cms_localisation_required', FluentExtension::INHERITANCE_MODE_ANY);
Config::modify()->set(DataObject::class, 'frontend_publish_required', FluentExtension::INHERITANCE_MODE_EXACT);

FluentState::singleton()->withState(function (FluentState $newState) {
$newState
->setLocale('de_DE')
->setIsDomainMode(false)
->setIsFrontend(true);

$page = Page::get()->filter('URLSegment', 'home')->first();

$this->assertNull($page);
});
}

public function testHomeVisibleInCMSBothConfigAny()
{
Config::modify()->set(DataObject::class, 'cms_localisation_required', FluentExtension::INHERITANCE_MODE_ANY);
Config::modify()->set(DataObject::class, 'frontend_publish_required', FluentExtension::INHERITANCE_MODE_ANY);

FluentState::singleton()->withState(function (FluentState $newState) {
$newState
->setLocale('de_DE')
->setIsDomainMode(false)
->setIsFrontend(false);

$page = Page::get()->filter('URLSegment', 'home')->first();

$this->assertNotNull($page);
});
}

public function testHomeVisibleInCMSOneConfigAny()
{
Config::modify()->set(DataObject::class, 'cms_localisation_required', FluentExtension::INHERITANCE_MODE_ANY);
Config::modify()->set(DataObject::class, 'frontend_publish_required', FluentExtension::INHERITANCE_MODE_EXACT);

FluentState::singleton()->withState(function (FluentState $newState) {
$newState
/**
* @param string $cmsInheritanceMode
* @param string $frontendInheritanceMode
* @param bool $frontendContext
* @param bool $expected
* @return void
* @dataProvider localeInheritanceModeCasesProvider
*/
public function testLocaleInheritanceMode(
string $cmsInheritanceMode,
string $frontendInheritanceMode,
bool $frontendContext,
bool $expected
): void {
Page::config()
->set('cms_localisation_required', $cmsInheritanceMode)
->set('frontend_publish_required', $frontendInheritanceMode);

FluentState::singleton()->withState(function (FluentState $state) use ($frontendContext, $expected) {
$state
->setLocale('de_DE')
->setIsDomainMode(false)
->setIsFrontend(false);
->setIsFrontend($frontendContext);

$page = Page::get()->filter('URLSegment', 'home')->first();
$page = Page::get()->find('URLSegment', 'home');

$this->assertNotNull($page);
});
}

public function testHomeNotVisibleInCMSBothConfigExact()
{
Config::modify()->set(DataObject::class, 'cms_localisation_required', FluentExtension::INHERITANCE_MODE_EXACT);
Config::modify()->set(DataObject::class, 'frontend_publish_required', FluentExtension::INHERITANCE_MODE_EXACT);
if ($expected) {
$this->assertNotNull($page, 'We expect the page model to have content available');

FluentState::singleton()->withState(function (FluentState $newState) {
$newState
->setLocale('de_DE')
->setIsDomainMode(false)
->setIsFrontend(false);

$page = Page::get()->filter('URLSegment', 'home')->first();
return;
}

$this->assertNull($page);
$this->assertNull($page, 'We expect the page model to not have any content available');
});
}

public function testHomeNotVisibleInCMSOneConfigExact()
public function localeInheritanceModeCasesProvider(): array
{
Config::modify()->set(DataObject::class, 'cms_localisation_required', FluentExtension::INHERITANCE_MODE_EXACT);
Config::modify()->set(DataObject::class, 'frontend_publish_required', FluentExtension::INHERITANCE_MODE_ANY);

FluentState::singleton()->withState(function (FluentState $newState) {
$newState
->setLocale('de_DE')
->setIsDomainMode(false)
->setIsFrontend(false);

$page = Page::get()->filter('URLSegment', 'home')->first();

$this->assertNull($page);
});
return [
'cms with any mode, frontend with any mode, frontend context' => [
FluentExtension::INHERITANCE_MODE_ANY,
FluentExtension::INHERITANCE_MODE_ANY,
true,
true,
],
'cms with exact mode, frontend with any mode, frontend context' => [
FluentExtension::INHERITANCE_MODE_EXACT,
FluentExtension::INHERITANCE_MODE_ANY,
true,
true,
],
'cms with exact mode, frontend with exact mode, frontend context' => [
FluentExtension::INHERITANCE_MODE_EXACT,
FluentExtension::INHERITANCE_MODE_EXACT,
true,
false,
],
'cms with any mode, frontend with exact mode, frontend context' => [
FluentExtension::INHERITANCE_MODE_ANY,
FluentExtension::INHERITANCE_MODE_EXACT,
true,
false,
],
'cms with any mode, frontend with any mode, cms context' => [
FluentExtension::INHERITANCE_MODE_ANY,
FluentExtension::INHERITANCE_MODE_ANY,
false,
true,
],
'cms with any mode, frontend with exact mode, cms context' => [
FluentExtension::INHERITANCE_MODE_ANY,
FluentExtension::INHERITANCE_MODE_EXACT,
false,
true,
],
'cms with exact mode, frontend with exact mode, cms context' => [
FluentExtension::INHERITANCE_MODE_EXACT,
FluentExtension::INHERITANCE_MODE_EXACT,
false,
false,
],
'cms with exact mode, frontend with any mode, cms context' => [
FluentExtension::INHERITANCE_MODE_EXACT,
FluentExtension::INHERITANCE_MODE_ANY,
false,
false,
],
];
}

/**
Expand All @@ -490,11 +442,15 @@ public function localePrefixUrlProvider()
* @throws ValidationException
* @dataProvider localeFallbackProvider
*/
public function testPageVisibilityWithFallback($cmsMode, $frontendMode, bool $isFrontend, int $expected)
{
Config::modify()
->set(DataObject::class, 'cms_localisation_required', $cmsMode)
->set(DataObject::class, 'frontend_publish_required', $frontendMode);
public function testPageVisibilityWithFallback(
string|bool $cmsMode,
string|bool $frontendMode,
bool $isFrontend,
int $expected
): void {
Page::config()
->set('cms_localisation_required', $cmsMode)
->set('frontend_publish_required', $frontendMode);

$pageId = FluentState::singleton()->withState(function (FluentState $state): int {
$state
Expand Down
2 changes: 1 addition & 1 deletion tests/php/Extension/FluentVersionedExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public function testSourceLocaleIsCurrentWhenPageExistsInIt()
->setIsDomainMode(false);

// Read from the locale that the page exists in already
/** @var Page $page */
/** @var Page|FluentSiteTreeExtension $page */
$page = $this->objFromFixture(Page::class, 'home');

$this->assertEquals('en_NZ', $page->getSourceLocale()->Locale);
Expand Down

0 comments on commit 973526e

Please sign in to comment.