Skip to content

Commit d86b4b4

Browse files
committed
Migrate the Language Restriction feature to SiteLanguage
TYPO3 introduced the SiteConfiguration together with the SiteLanguage feature and moves away from using `sys_language` table. The impact: When creating a new language this won't be stored in `sys_language` anymore but in the SiteConfiguration in a file on the drive. As the extension uses the table to populate its language selectors, this will be empty or incomplete. This PR will change the TCA in a way to get the languages from the SIteConfiguration and using the languageID to generate the RestrictionCollection.
1 parent 3ee7172 commit d86b4b4

4 files changed

Lines changed: 131 additions & 207 deletions

File tree

Classes/Constants.php

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,5 @@ class Constants
1717

1818
public const L10NMGR_CONFIGURATION_INCLUDE = 3;
1919

20-
public const L10NMGR_LANGUAGE_RESTRICTION_FOREIGN_TABLENAME = 'sys_language';
21-
22-
public const L10NMGR_LANGUAGE_RESTRICTION_MM_TABLENAME = 'sys_language_l10nmgr_language_restricted_record_mm';
23-
2420
public const L10NMGR_LANGUAGE_RESTRICTION_FIELDNAME = 'l10nmgr_language_restriction';
2521
}

Classes/LanguageRestriction/Collection/LanguageRestrictionCollection.php

Lines changed: 60 additions & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,22 @@
1717
* The TYPO3 project - inspiring people to share!
1818
*/
1919

20+
use Doctrine\DBAL\DBALException;
21+
use Doctrine\DBAL\Driver\Exception as DBALDriverException;
2022
use Localizationteam\L10nmgr\Constants;
2123
use PDO;
22-
use RuntimeException;
2324
use SplDoublyLinkedList;
2425
use TYPO3\CMS\Core\Collection\AbstractRecordCollection;
2526
use TYPO3\CMS\Core\Collection\CollectionInterface;
2627
use TYPO3\CMS\Core\Collection\EditableCollectionInterface;
2728
use TYPO3\CMS\Core\Database\ConnectionPool;
2829
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
2930
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
31+
use TYPO3\CMS\Core\Exception\SiteNotFoundException;
32+
use TYPO3\CMS\Core\Site\Entity\NullSite;
33+
use TYPO3\CMS\Core\Site\Entity\Site;
34+
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
35+
use TYPO3\CMS\Core\Site\SiteFinder;
3036
use TYPO3\CMS\Core\Utility\GeneralUtility;
3137

3238
/**
@@ -35,104 +41,49 @@
3541
class LanguageRestrictionCollection extends AbstractRecordCollection implements EditableCollectionInterface
3642
{
3743
/**
38-
* The table name collections are stored to
44+
* The table name collections are stored to, must be defined in the subclass
3945
*
4046
* @var string
4147
*/
42-
protected static $storageTableName = Constants::L10NMGR_LANGUAGE_RESTRICTION_FOREIGN_TABLENAME;
48+
protected static $storageTableName = 'pages';
4349

4450
/**
45-
* Name of the language-restrictions-relation field (used in the MM_match_fields/fieldname property of the TCA)
51+
* Contrary to the originally idea of collections, we do not load a record from the database here.
52+
* Instead we get the language by its ID. This is the key for our restriction collection
4653
*
47-
* @var string
48-
*/
49-
protected string $relationFieldName = Constants::L10NMGR_LANGUAGE_RESTRICTION_FIELDNAME;
50-
51-
/**
52-
* Creates this object.
53-
*
54-
* @param string|null $tableName Name of the table to be working on
55-
* @param string|null $fieldName Name of the field where the language restriction relations are defined
56-
* @throws RuntimeException
57-
*/
58-
public function __construct(string $tableName = null, string $fieldName = null)
59-
{
60-
parent::__construct();
61-
if (!empty($tableName)) {
62-
$this->setItemTableName($tableName);
63-
} elseif (empty($this->itemTableName)) {
64-
throw new RuntimeException(self::class . ' needs a valid itemTableName.', 1341826168);
65-
}
66-
if (!empty($fieldName)) {
67-
$this->setRelationFieldName($fieldName);
68-
}
69-
}
70-
71-
/**
72-
* Loads the collections with the given id from persistence
73-
* For memory reasons, per default only f.e. title, database-table,
74-
* identifier (what ever static data is defined) is loaded.
75-
* Entries can be load on first access.
76-
*
77-
* @param int $id Id of database record to be loaded
54+
* @param int $languageId Id of the language to be loaded
7855
* @param bool $fillItems Populates the entries directly on load, might be bad for memory on large collections
7956
* @param string $tableName Name of table from which entries should be loaded
80-
* @param string $fieldName Name of the language restrictions relation field
57+
* @param string $pageId ID of the page
8158
* @return CollectionInterface
8259
* @throws \Doctrine\DBAL\DBALException
8360
*/
84-
public static function load($id, $fillItems = false, string $tableName = '', string $fieldName = ''): CollectionInterface
61+
public static function load($languageId, $fillItems = false, string $tableName = '', int $pageId = 0): CollectionInterface
8562
{
86-
/** @var QueryBuilder $queryBuilder */
87-
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
88-
->getQueryBuilderForTable(static::$storageTableName);
89-
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
90-
91-
$collectionRecord = $queryBuilder->select('*')
92-
->from(static::$storageTableName)
93-
->where(
94-
$queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($id, PDO::PARAM_INT))
95-
)
96-
->setMaxResults(1)
97-
->execute()
98-
->fetch();
63+
try {
64+
$language = self::getLanguage($pageId, $languageId);
65+
$collectionRecord['uid'] = $language->getLanguageId();
66+
$collectionRecord['title'] = $language->getTitle();
67+
} catch (\RuntimeException $exception) {
68+
$collectionRecord['uid'] = 0;
69+
$collectionRecord['title'] = '';
70+
}
9971

72+
$collectionRecord['description'] = 'Restriction Collection';
10073
$collectionRecord['table_name'] = $tableName;
101-
$collectionRecord['field_name'] = $fieldName;
10274

10375
return self::create($collectionRecord, $fillItems);
10476
}
10577

106-
/**
107-
* Creates a new collection objects and reconstitutes the
108-
* given database record to the new object.
109-
*
110-
* @param array $collectionRecord Database record
111-
* @param bool $fillItems Populates the entries directly on load, might be bad for memory on large collections
112-
* @return LanguageRestrictionCollection
113-
*/
114-
public static function create(array $collectionRecord, $fillItems = false): LanguageRestrictionCollection
115-
{
116-
/** @var LanguageRestrictionCollection $collection */
117-
$collection = GeneralUtility::makeInstance(
118-
self::class,
119-
$collectionRecord['table_name'],
120-
$collectionRecord['field_name']
121-
);
122-
$collection->fromArray($collectionRecord);
123-
if ($fillItems) {
124-
$collection->loadContents();
125-
}
126-
return $collection;
127-
}
128-
12978
/**
13079
* Populates the content-entries of the storage
13180
* Queries the underlying storage for entries of the collection
13281
* and adds them to the collection data.
13382
* If the content entries of the storage had not been loaded on creation
13483
* ($fillItems = false) this function is to be used for loading the contents
13584
* afterwards.
85+
*
86+
* @throws DBALException|DBALDriverException
13687
*/
13788
public function loadContents()
13889
{
@@ -144,96 +95,27 @@ public function loadContents()
14495
}
14596

14697
/**
147-
* Gets the collected records in this collection, by
148-
* using <getCollectedRecordsQueryBuilder>.
98+
* Gets the collected records in this collection
14999
*
150100
* @return array
151-
* @throws \Doctrine\DBAL\DBALException
101+
* @throws DBALException|DBALDriverException
152102
*/
153103
protected function getCollectedRecords(): array
154-
{
155-
$relatedRecords = [];
156-
157-
$queryBuilder = $this->getCollectedRecordsQueryBuilder();
158-
$result = $queryBuilder->execute();
159-
160-
while ($record = $result->fetch()) {
161-
$relatedRecords[] = $record;
162-
}
163-
164-
return $relatedRecords;
165-
}
166-
167-
/**
168-
* Selects the collected records in this collection, by
169-
* looking up the MM relations of this record to the
170-
* table name defined in the local field 'table_name'.
171-
*
172-
* @return QueryBuilder
173-
*/
174-
protected function getCollectedRecordsQueryBuilder(): QueryBuilder
175104
{
176105
/** @var QueryBuilder $queryBuilder */
177-
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
178-
->getQueryBuilderForTable(static::$storageTableName);
106+
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(self::getCollectionDatabaseTable());
179107
$queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
180108

181-
$queryBuilder->select($this->getItemTableName() . '.*')
182-
->from(static::$storageTableName)
183-
->join(
184-
static::$storageTableName,
185-
Constants::L10NMGR_LANGUAGE_RESTRICTION_MM_TABLENAME,
186-
Constants::L10NMGR_LANGUAGE_RESTRICTION_MM_TABLENAME,
187-
$queryBuilder->expr()->eq(
188-
'sys_language_l10nmgr_language_restricted_record_mm.uid_local',
189-
$queryBuilder->quoteIdentifier(static::$storageTableName . '.uid')
190-
)
191-
)
192-
->join(
193-
Constants::L10NMGR_LANGUAGE_RESTRICTION_MM_TABLENAME,
194-
$this->getItemTableName(),
195-
$this->getItemTableName(),
196-
$queryBuilder->expr()->eq(
197-
Constants::L10NMGR_LANGUAGE_RESTRICTION_MM_TABLENAME . '.uid_foreign',
198-
$queryBuilder->quoteIdentifier($this->getItemTableName() . '.uid')
199-
)
200-
)
109+
$result = $queryBuilder->select('*')
110+
->from(self::getCollectionDatabaseTable())
201111
->where(
202-
$queryBuilder->expr()->eq(
203-
static::$storageTableName . '.uid',
204-
$queryBuilder->createNamedParameter($this->getIdentifier(), PDO::PARAM_INT)
205-
),
206-
$queryBuilder->expr()->eq(
207-
Constants::L10NMGR_LANGUAGE_RESTRICTION_MM_TABLENAME . '.tablenames',
208-
$queryBuilder->createNamedParameter($this->getItemTableName())
209-
),
210-
$queryBuilder->expr()->eq(
211-
Constants::L10NMGR_LANGUAGE_RESTRICTION_MM_TABLENAME . '.fieldname',
212-
$queryBuilder->createNamedParameter($this->getRelationFieldName())
112+
$queryBuilder->expr()->inSet(
113+
Constants::L10NMGR_LANGUAGE_RESTRICTION_FIELDNAME,
114+
$queryBuilder->createNamedParameter($this->uid, PDO::PARAM_INT)
213115
)
214-
);
116+
)->execute();
215117

216-
return $queryBuilder;
217-
}
218-
219-
/**
220-
* Gets the name of the language restrictions relation field
221-
*
222-
* @return string
223-
*/
224-
public function getRelationFieldName(): string
225-
{
226-
return $this->relationFieldName;
227-
}
228-
229-
/**
230-
* Sets the name of the language restrictions relation field
231-
*
232-
* @param string $field
233-
*/
234-
public function setRelationFieldName(string $field)
235-
{
236-
$this->relationFieldName = $field;
118+
return $result->fetchAllAssociative();
237119
}
238120

239121
/**
@@ -255,26 +137,6 @@ public function add($data)
255137
$this->storage->push($data);
256138
}
257139

258-
/**
259-
* Getter for the storage table name
260-
*
261-
* @return string
262-
*/
263-
public static function getStorageTableName(): string
264-
{
265-
return self::$storageTableName;
266-
}
267-
268-
/**
269-
* Getter for the storage items field
270-
*
271-
* @return string
272-
*/
273-
public static function getStorageItemsField(): string
274-
{
275-
return self::$storageItemsField;
276-
}
277-
278140
/**
279141
* Adds a set of entries to the collection
280142
*
@@ -350,4 +212,29 @@ protected function getPersistableDataArray(): array
350212
'items' => $this->getItemUidList(),
351213
];
352214
}
215+
216+
/**
217+
* @param int $pageId
218+
* @return Site|NullSite
219+
*/
220+
protected static function getSiteByPageId(int $pageId)
221+
{
222+
try {
223+
$site = GeneralUtility::makeInstance(SiteFinder::class)->getSiteByPageId($pageId);
224+
} catch (SiteNotFoundException $exception) {
225+
$site = new NullSite();
226+
}
227+
228+
return $site;
229+
}
230+
231+
protected static function getLanguage(int $pageId, $languageId): SiteLanguage
232+
{
233+
$site = self::getSiteByPageId($pageId);
234+
if ($site instanceof Site) {
235+
return $site->getLanguageById($languageId);
236+
}
237+
238+
throw new \RuntimeException();
239+
}
353240
}

0 commit comments

Comments
 (0)