Skip to content

Commit 206f23b

Browse files
committed
[RELEASE] Version 13.1.0 with new UI
Related: https://projekte.in2code.de/issues/73866
2 parents cbf0918 + 4a9a4a8 commit 206f23b

File tree

104 files changed

+10855
-630
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

104 files changed

+10855
-630
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,4 @@ Build/.phpunit.result.cache
2424
.php-cs-fixer.cache
2525
composer.lock
2626
docker-compose.yaml
27+
node_modules/

.project/data/dumps/local/pages.csv

Lines changed: 10 additions & 10 deletions
Large diffs are not rendered by default.

CHANGELOG.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,47 @@
11
# In2publish Core Change Log
22

3+
13.1.0
4+
5+
- [META] Set the EM conf version number to 13.1.0
6+
- [DOCS] Update Changelog.md
7+
- [META] Update branch-alias in composer.json
8+
- [DOCS] Update documentation and add upgrade documentation
9+
- [BUGFIX] Remove additional level filter in doc header
10+
- [BUGFIX] Fix filtering for level in overview module
11+
- [TEST] Fix PublishTranslationTest
12+
- [TEST] Fix acceptance tests
13+
- [TASK] Provide css class in dirty property list to be used in acceptance tests
14+
- [TEST] Fix PublishTranslationTest
15+
- [TEST] Fix PublishFilesModuleTest
16+
- [TEST] Fix UidClashTest
17+
- [TEST] Fix PublishChangedPagePropertiesTest
18+
- [TEST] Fix RecordTreeDisplayTest
19+
- [TEST] Fix PublishChangedContentTest
20+
- [DEV] Add make task for running single acceptance tests
21+
- [BUGFIX] Display state of soft deleted records in overview module
22+
- [TEST] Fix PublishingRecordWithDependencyTest
23+
- [TEST] Fix PublishFilesModuleTest
24+
- [TEST] Fix unit tests
25+
- [CLEANUP] Remove deprecated events
26+
- [BUGFIX] Fix problems with publication of unpublishable records in publishAll
27+
- [BUGFIX] Restore PublishButtonWithWarning
28+
- [BUGFIX] Avoid sql error when updating with empty values
29+
- [TASK] Show filter button in Redirects Module
30+
- [BUGFIX] Restore display of previews for comparison in overview module
31+
- [TASK] final implementation of language filter in the overview module
32+
- [WIP] Add language filter to OverviewModule
33+
- [TASK] migrate InformationModal from requireJs to ES6
34+
- [TASK] Add language filtering to publish overview
35+
- [TASK] Display reasons why record is not publishable in OverviewModule using a new InformationModal without publish buttons
36+
- [WIP][FEATURE] Forward-port new publish overview UI from v12
37+
- [BUGFIX] Restore start of SimpleStopwatch
38+
- [BUGFIX] Fix implicit nullable in PublishingContext and TestResult
39+
- [BUGFIX] Allow deserialization of site settings
40+
- [TASK] add support for pre TYPO3 V12 backend module names
41+
- [BUGFIX] remove StopwatchAlreadyStartedException keep the startTime if already set
42+
- [BUGFIX] Fix implicit nullable in Builder
43+
- [BUGFIX] Prevent exception if request is not set in LanguageAugmentations
44+
-
345
13.0.1
446

547
- [META] Set the EM conf version number to 13.0.1

Classes/Component/ConfigContainer/Builder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public function addString(string $key, string $default, array $validators = []):
7575
public function addOptionalArray(
7676
string $name,
7777
Builder $nodes,
78-
array $default = null,
78+
?array $default = null,
7979
array $validators = []
8080
): Builder {
8181
$this->addNode(Node::T_OPTIONAL_ARRAY, $name, $default, $validators, $nodes);

Classes/Component/Core/Demand/Augmentation/LanguageAugmentation.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ class LanguageAugmentation implements SingletonInterface
2424

2525
public function __invoke(DemandsWereCollected $event): void
2626
{
27-
$languages = $this->request->getLanguages();
28-
if (null === $this->request || empty($languages)) {
27+
if (null === $this->request?->getLanguages()) {
2928
return;
3029
}
30+
$languages = $this->request->getLanguages();
3131
$demands = $event->getDemands();
3232
$allDemands = $demands->getAll();
3333

Classes/Component/Core/Publisher/DatabaseRecordPublisher.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,10 @@ public function publish(Record $record)
3838

3939
$foreignProps = $record->getForeignProps();
4040
$newValues = array_diff_assoc($localProps, $foreignProps);
41-
$this->foreignDatabase->update($table, $newValues, $foreignIdentificationProps);
41+
if (!empty($newValues)) {
42+
$this->foreignDatabase->update($table, $newValues, $foreignIdentificationProps);
43+
}
44+
4245
}
4346

4447
public function start(): void

Classes/Component/Core/Publisher/PublisherService.php

Lines changed: 130 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class PublisherService
3333
protected PublisherCollection $publisherCollection;
3434
/** @var array<string, array<int, true>> */
3535
protected array $visitedRecords = [];
36+
protected bool $isPublishAllMode = false;
3637

3738
public function __construct()
3839
{
@@ -56,6 +57,20 @@ public function publish(PublishingContext $publishingContext): void
5657
$this->publishRecordTree($recordTree, $publishingContext->publishChildPages);
5758
}
5859

60+
/**
61+
* Publishes all PUBLISHABLE records (dependencies must NOT be ignored during publishAll)
62+
* @throws Throwable
63+
*/
64+
public function publishAllPublishable(PublishingContext $publishingContext): void
65+
{
66+
$this->isPublishAllMode = true;
67+
try {
68+
$this->publish($publishingContext);
69+
} finally {
70+
$this->isPublishAllMode = false;
71+
}
72+
}
73+
5974
/**
6075
* @throws Throwable
6176
* @internal This method will be made non-public in in2publish_core v13. Use publish() with PublishingContext
@@ -76,10 +91,13 @@ public function publishRecordTree(RecordTree $recordTree, bool $includeChildPage
7691

7792
$this->publisherCollection->start();
7893

94+
// this is set for the first call to publishRecord, because
95+
$isTopLevelCall = true;
96+
7997
try {
8098
foreach ($recordTree->getChildren() as $records) {
8199
foreach ($records as $record) {
82-
$this->publishRecord($record, $includeChildPages);
100+
$this->publishRecord($record, $includeChildPages, $isTopLevelCall);
83101
}
84102
}
85103
} catch (Throwable $exception) {
@@ -103,8 +121,11 @@ public function publishRecordTree(RecordTree $recordTree, bool $includeChildPage
103121
/**
104122
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
105123
*/
106-
protected function publishRecord(Record $record, bool $includeChildPages = false): void
107-
{
124+
protected function publishRecord(
125+
Record $record,
126+
bool $includeChildPages = false,
127+
bool $isTopLevelCall = false
128+
): void {
108129
$classification = $record->getClassification();
109130
$id = $record->getId();
110131

@@ -115,37 +136,124 @@ protected function publishRecord(Record $record, bool $includeChildPages = false
115136

116137
$this->eventDispatcher->dispatch(new RecordWasSelectedForPublishing($record));
117138

118-
// Do not use Record::isPublishable(). Check only the record's reasons but not dependencies.
119-
// Dependencies might have been fulfilled during publishing or ignored by the user by choice.
120-
if (!$record->hasReasonsWhyTheRecordIsNotPublishable()) {
121-
// deprecated, remove in v13
122-
$this->eventDispatcher->dispatch(new PublishingOfOneRecordBegan($record));
123-
if ($record->getState() !== Record::S_UNCHANGED) {
124-
$this->publisherCollection->publish($record);
125-
}
126-
// deprecated, remove in v13
127-
$this->eventDispatcher->dispatch(new PublishingOfOneRecordEnded($record));
139+
$wasPublished = $this->publishRecordIfPublishable($record, $isTopLevelCall);
140+
141+
// Always process children if record was published
142+
// Also process children if we're not in publishAll mode (individual publishing)
143+
// In publishAll mode: only process child pages if includeChildPages is true AND parent was published
144+
// Always process non-page children if parent was published
145+
$shouldProcessChildren = $wasPublished || !$this->isPublishAllMode;
146+
147+
if ($shouldProcessChildren) {
148+
$this->processTranslations($record, $includeChildPages, $wasPublished);
149+
$this->processChildRecords($record, $includeChildPages, $wasPublished);
150+
} elseif ($this->isPublishAllMode && $includeChildPages) {
151+
// in publishAll mode child pages need to be evaluated independently even if parent wasn't published
152+
$this->processChildPagesIndependently($record, $includeChildPages);
153+
}
154+
}
155+
156+
private function publishRecordIfPublishable(Record $record, bool $isTopLevelCall): bool
157+
{
158+
if ($record->hasReasonsWhyTheRecordIsNotPublishable()) {
159+
return false;
160+
}
161+
162+
if ($record->getStateRecursive() === Record::S_UNCHANGED) {
163+
return false;
164+
}
165+
166+
// Determine if record is publishable based on context
167+
$shouldPublish = $this->shouldRecordBePublished($record, $isTopLevelCall);
168+
169+
if ($shouldPublish) {
170+
$this->publisherCollection->publish($record);
128171
$this->eventDispatcher->dispatch(new RecordWasPublished($record));
172+
173+
return true;
129174
}
130175

176+
return false;
177+
}
178+
179+
private function shouldRecordBePublished(Record $record, bool $isTopLevelCall): bool
180+
{
181+
// If not in publishAll mode, use the less strict check
182+
if (!$this->isPublishAllMode) {
183+
return true;
184+
}
185+
186+
if ($isTopLevelCall && $record->getClassification() === 'pages') {
187+
// Top-level pages and independent child pages must pass strict dependency check
188+
return $record->isPublishable();
189+
}
190+
191+
// For all other cases in publishAll mode use the less strict check since parent context provides validity
192+
// - Child pages whose parent was published in current run
193+
// - Non-page records (content elements, etc.)
194+
// - Translations
195+
return true;
196+
}
197+
198+
private function processTranslations(Record $record, bool $includeChildPages, bool $parentWasPublished = false): void
199+
{
131200
$translationEvent = new BeforePublishingTranslationsEvent($record, $includeChildPages);
132201
$this->eventDispatcher->dispatch($translationEvent);
133202

134-
if ($translationEvent->shouldProcessTranslations()) {
135-
foreach ($record->getTranslations() as $translatedRecords) {
136-
foreach ($translatedRecords as $translatedRecord) {
137-
$this->publishRecord($translatedRecord, $includeChildPages);
138-
}
203+
if (!$translationEvent->shouldProcessTranslations()) {
204+
return;
205+
}
206+
207+
foreach ($record->getTranslations() as $translatedRecords) {
208+
foreach ($translatedRecords as $translatedRecord) {
209+
// Translations are never top-level calls
210+
$this->publishRecord($translatedRecord, $includeChildPages, false);
211+
}
212+
}
213+
}
214+
215+
private function processChildPagesIndependently(Record $record, bool $includeChildPages): void
216+
{
217+
foreach ($record->getChildren() as $table => $children) {
218+
if ($table !== 'pages') {
219+
continue; // Only process child pages independently
220+
}
221+
222+
foreach ($children as $child) {
223+
// Child pages evaluated independently with strict checking
224+
$this->publishRecord($child, $includeChildPages, true);
139225
}
140226
}
227+
}
141228

229+
private function processChildRecords(Record $record, bool $includeChildPages, bool $parentWasPublished = false): void
230+
{
142231
foreach ($record->getChildren() as $table => $children) {
143-
if ('pages' === $table && !$includeChildPages) {
144-
continue;
232+
// Handle child pages based on mode and settings
233+
if ($table === 'pages') {
234+
if (!$includeChildPages && !$this->isPublishAllMode) {
235+
// Skip child pages only if not including them AND not in publishAll mode
236+
continue;
237+
}
145238
}
239+
146240
foreach ($children as $child) {
147-
$this->publishRecord($child, $includeChildPages);
241+
// Determine if child should be treated as top-level for dependency checking
242+
$isChildTopLevelCall = false;
243+
244+
if ($table === 'pages') {
245+
if ($this->isPublishAllMode) {
246+
// In publishAll mode: child pages get strict checking ONLY if their parent
247+
// was not published in the current run (independent evaluation)
248+
$isChildTopLevelCall = !$parentWasPublished;
249+
} elseif ($includeChildPages && !$this->isPublishAllMode) {
250+
// Child pages in regular mode with includeChildPages always get strict checking
251+
$isChildTopLevelCall = true;
252+
}
253+
}
254+
255+
$this->publishRecord($child, $includeChildPages, $isChildTopLevelCall);
148256
}
149257
}
150258
}
151-
}
259+
}

Classes/Component/Core/Publisher/PublishingContext.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class PublishingContext
1313

1414
public function __construct(
1515
RecordTree $recordTree,
16-
bool $publishChildPages = null
16+
?bool $publishChildPages = null
1717
) {
1818
$this->recordTree = $recordTree;
1919
if (null !== $publishChildPages) {

Classes/Component/Core/RecordTree/RecordTreeBuildRequest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class RecordTreeBuildRequest
1717
public function __construct(
1818
string $table,
1919
int $id,
20-
int $pageRecursionLimit,
20+
int $pageRecursionLimit = 0,
2121
int $dependencyRecursionLimit = 3,
2222
int $contentRecursionLimit = 8,
2323
?array $languages = null

Classes/Controller/RecordController.php

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
use In2code\In2publishCore\In2publishCoreException;
4747
use In2code\In2publishCore\Service\Database\RawRecordService;
4848
use In2code\In2publishCore\Service\Error\FailureCollectorInjection;
49+
use In2code\In2publishCore\Service\Language\SiteLanguageServiceInjection;
4950
use In2code\In2publishCore\Service\Permission\PermissionServiceInjection;
5051
use In2code\In2publishCore\Utility\BackendUtility;
5152
use In2code\In2publishCore\Utility\DatabaseUtility;
@@ -86,6 +87,7 @@ class RecordController extends ActionController
8687
use PublisherServiceInjection;
8788
use PermissionServiceInjection;
8889
use SimpleStopwatchInjection;
90+
use SiteLanguageServiceInjection;
8991

9092
/**
9193
* @codeCoverageIgnore
@@ -120,24 +122,6 @@ public function initializeIndexAction(): void
120122
}
121123

122124
$this->moduleTemplate->setModuleClass('in2publish_core_m1');
123-
124-
$menuRegistry = $this->moduleTemplate->getDocHeaderComponent()->getMenuRegistry();
125-
$menu = $menuRegistry->makeMenu();
126-
$menu->setIdentifier('depth');
127-
$menu->setLabel(LocalizationUtility::translate('m1.page_recursion', 'In2publishCore'));
128-
for ($i = 0; $i <= 10; $i++) {
129-
$menuItem = $menu->makeMenuItem();
130-
$menuItem->setActive($i === $data['pageRecursionLimit']);
131-
if ($i > 1) {
132-
$title = LocalizationUtility::translate('m1.page_recursion.depths', 'In2publishCore', [$i]);
133-
} else {
134-
$title = LocalizationUtility::translate('m1.page_recursion.depth', 'In2publishCore', [$i]);
135-
}
136-
$menuItem->setTitle($title);
137-
$menuItem->setHref($this->uriBuilder->uriFor('index', ['pageRecursionLimit' => $i]));
138-
$menu->addMenuItem($menuItem);
139-
}
140-
$menuRegistry->addMenu($menu);
141125
}
142126

143127
/**
@@ -160,12 +144,15 @@ public function indexAction(int $pageRecursionLimit): ResponseInterface
160144
} catch (Throwable $exception) {
161145
$foreignDbAvailable = false;
162146
}
147+
$languages = $this->siteLanguageService->getAllowedLanguages($pid);
163148

164149
$this->moduleTemplate->assignMultiple([
165150
'recordTree' => $recordTree,
166151
'localDatabaseConnectionAvailable' => $localDbAvailable,
167152
'foreignDatabaseConnectionAvailable' => $foreignDbAvailable,
168153
'publishingAvailable' => $localDbAvailable && $foreignDbAvailable,
154+
'pageRecursionLimit' => $pageRecursionLimit,
155+
'languages' => $languages,
169156
]);
170157
return $this->htmlResponse();
171158
}

0 commit comments

Comments
 (0)