-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add FluentVersioned Extension for Versioned collector
- Loading branch information
Showing
4 changed files
with
266 additions
and
9 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
<?php | ||
|
||
namespace SilverStripe\GarbageCollector\Extensions; | ||
|
||
use SilverStripe\Core\Extension; | ||
use SilverStripe\ORM\Queries\SQLDelete; | ||
use SilverStripe\ORM\Queries\SQLSelect; | ||
use SilverStripe\GarbageCollector\Collectors\VersionedCollector; | ||
use TractorCow\Fluent\Extension\FluentExtension; | ||
use TractorCow\Fluent\Extension\FluentVersionedExtension; | ||
|
||
class FluentVersionedCollectorExtension extends Extension | ||
{ | ||
/** | ||
* Modify getRecordsQuery to join with Localised tables | ||
* | ||
* @param SQLSelect $query | ||
* @param string $class | ||
*/ | ||
public function modifyGetRecordsQuery(SQLSelect $query, string $class): void | ||
{ | ||
if ($this->isLocalised($class)) { | ||
$mainTable = $this->owner->getTableNameForClass($class); | ||
$baseTable = sprintf('"%s"', $this->owner->getVersionTableName($mainTable)); | ||
|
||
$localisedTableRaw = $this->getVersionLocalisedTableName($mainTable); | ||
$localisedTable = sprintf('"%s"', $localisedTableRaw); | ||
$query | ||
// Join through to the localised table | ||
// Version numbers map one to one | ||
->addInnerJoin( | ||
$localisedTableRaw, | ||
sprintf( | ||
'%1$s."RecordID" = %2$s."RecordID" AND %1$s."Version" = %2$s."Version"', | ||
$baseTable, | ||
$localisedTable | ||
) | ||
) | ||
->addSelect([ | ||
// We will need the locale information as well later on | ||
$localisedTable . '."Locale"', | ||
]) | ||
->addGroupBy([ | ||
// Grouping has to be extended to locales | ||
// as we want to keep the minimum number of versions per locale | ||
$localisedTable . '."Locale"', | ||
]) | ||
->addOrderBy([ | ||
// Extends consistent ordering to locales | ||
$localisedTable . '."Locale"', | ||
]); | ||
} | ||
} | ||
|
||
/** | ||
* Modify getRecords return data to include Locale data | ||
* | ||
* @param string $class Classname of records being modified | ||
* @param array $item Item details for returning | ||
* @param array $result Query result data | ||
*/ | ||
public function modifyRecordsData(string $class, array $item, array $result): void | ||
{ | ||
if ($this->isLocalised($class)) { | ||
// Add additional locale data for localised records | ||
$item['locale'] = $result['Locale']; | ||
} | ||
} | ||
|
||
/** | ||
* Modify getRecords return data to include Locale data | ||
* | ||
* @param SQLSelect $query Select query for Versions records | ||
* @param string $class Classname of records | ||
* @param array $item Item details | ||
*/ | ||
public function modifyGetVersionsQuery(SQLSelect $query, string $class, array $item): void | ||
{ | ||
$locale = array_key_exists('locale', $item) | ||
? $item['locale'] | ||
: null; | ||
|
||
$mainTable = $this->owner->getTableNameForClass($class); | ||
$baseTable = sprintf('"%s"', $this->owner->getVersionTableName($mainTable)); | ||
|
||
if ($locale) { | ||
$localisedTableRaw = $this->getVersionLocalisedTableName($mainTable); | ||
$localisedTable = sprintf('"%s"', $localisedTableRaw); | ||
$query | ||
// Join through to the localised table | ||
// Version numbers map one to one | ||
->addInnerJoin( | ||
$localisedTableRaw, | ||
sprintf( | ||
'%1$s."RecordID" = %2$s."RecordID" AND %1$s."Version" = %2$s."Version"', | ||
$baseTable, | ||
$localisedTable | ||
) | ||
) | ||
->addWhere([ | ||
// Narrow down the search to specific locale, this ensures that we keep minimum | ||
// required versions per locale | ||
$localisedTable . '."Locale"' => $locale, | ||
]); | ||
} | ||
|
||
} | ||
|
||
/** | ||
* Modify getRecords return data to include Locale data | ||
* | ||
* @param SQLDelete $query Delete query for Version records | ||
* @param string $class Classname of records | ||
* @param array $item Item details | ||
*/ | ||
public function modifyDeleteVersionsQuery(SQLDelete $query, string $class, array $item): void | ||
{ | ||
$tables = $this->owner->getTablesListForClass($class); | ||
$baseTables = $tables['base']; | ||
$localisedTables = $tables['localised']; | ||
|
||
// Add localised table to the join and deletion | ||
if (count($localisedTables) > 0) { | ||
$localisedTablesRaw = $localisedTables; | ||
|
||
array_walk($localisedTables, static function (&$item): void { | ||
$item = sprintf('"%s"', $item); | ||
}); | ||
|
||
// Register localised tables for deletion so we delete records from it | ||
$query->addDelete($localisedTables); | ||
|
||
foreach ($localisedTablesRaw as $table) { | ||
$query->addLeftJoin( | ||
$table, | ||
sprintf( | ||
'%1$s."RecordID" = "%2$s"."RecordID" AND %1$s."Version" = "%2$s"."Version"', | ||
$baseTable, | ||
$table | ||
) | ||
); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Modify getRecords return data to include Locale data | ||
* | ||
* @param string $class Classname of records | ||
* @param array $tables Tables list data for class | ||
*/ | ||
public function modifyTablesListForClass(string $class, array $tables) | ||
{ | ||
// Include localised tables if needed | ||
if ($singleton->hasExtension(FluentVersionedExtension::class)) { | ||
$localisedTables = []; | ||
$localisedDataTables = array_keys($singleton->getLocalisedTables()); | ||
|
||
foreach ($tables as $table) { | ||
if (!in_array($table, $localisedDataTables)) { | ||
// Skip any tables that do not contain localised data | ||
continue; | ||
} | ||
|
||
$localisedTables[] = $this->getVersionLocalisedTableName($table); | ||
} | ||
|
||
// Add localised Table data to Tables List | ||
$tables['localised'] = $localisedTables; | ||
} | ||
} | ||
|
||
/** | ||
* Check if Class is Localised (Has Fluent extension and Localised fields) | ||
* | ||
* @param string $class | ||
* @return bool | ||
*/ | ||
protected function isLocalised(string $class): bool | ||
{ | ||
/** @var DataObject|FluentExtension $singleton */ | ||
$singleton = DataObject::singleton($class); | ||
return $singleton->hasExtension(FluentVersionedExtension::class) | ||
&& count($singleton->getLocalisedFields()) > 0; | ||
} | ||
|
||
/** | ||
* Determine the name of localised version table | ||
* | ||
* @param string $table | ||
* @return string | ||
*/ | ||
protected function getVersionLocalisedTableName(string $table): string | ||
{ | ||
return $table . '_Localised_Versions'; | ||
} | ||
} |
41 changes: 41 additions & 0 deletions
41
tests/php/Extensions/FluentVersionedCollectorExtensionTest.php
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,41 @@ | ||
<?php | ||
|
||
namespace SilverStripe\GarbageCollector\Tests\Extensions; | ||
|
||
use SilverStripe\Dev\SapphireTest; | ||
use SilverStripe\GarbageCollector\Tests\Ship; | ||
use SilverStripe\Versioned\Versioned; | ||
use TractorCow\Fluent\Extension\FluentVersionedExtension; | ||
|
||
class FluentVersionedCollectorExtensionTest extends SapphireTest | ||
{ | ||
/** | ||
* @var string | ||
*/ | ||
protected static $fixture_file = [ | ||
'tests/php/Models.yml', | ||
'tests/php/Fluent.yml' | ||
]; | ||
|
||
/** | ||
* @var string[] | ||
*/ | ||
protected static $extra_dataobjects = [ | ||
Ship::class, | ||
]; | ||
|
||
/** | ||
* @var string[][] | ||
*/ | ||
protected static $required_extensions = [ | ||
Ship::class => [ | ||
Versioned::class, | ||
FluentVersionedExtension::class | ||
], | ||
]; | ||
|
||
public function testModifyRecordsExtension() | ||
{ | ||
|
||
} | ||
} |
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,14 @@ | ||
TractorCow\Fluent\Model\Locale: | ||
nz: | ||
Locale: en_001 | ||
APIURLSegment: en | ||
Title: 'International' | ||
URLSegment: int | ||
AlacrityMarket: en | ||
us: | ||
Locale: en_US | ||
Title: 'United States' | ||
URLSegment: us | ||
AlacrityMarket: us | ||
Fallbacks: | ||
- =>TractorCow\Fluent\Model\Locale.nz |