Skip to content

Commit 6a7a40d

Browse files
committed
[RELEASE] Version 12.6.1
Related: https://projekte.in2code.de/issues/73927
2 parents b57eebb + f6c019b commit 6a7a40d

File tree

5 files changed

+145
-22
lines changed

5 files changed

+145
-22
lines changed

CHANGELOG.md

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

3+
12.6.1:
4+
- [META] Set the EM conf version number to 12.6.1
5+
- [DOCS] Update Changelog.md
6+
- [TEST] Fix PublisherServiceTest
7+
- [BUGFIX] Avoid sql error when updating with empty values
8+
- [TASK] Add method publishAllPublishable for usage in publishAll mode
9+
310
12.6.0:
411
- [DOCS] Update Changelog.md
512
- [META] Set the EM conf version number to 12.6.0

Classes/Component/Core/Publisher/DatabaseRecordPublisher.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ 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+
}
4244
}
4345

4446
public function start(): void

Classes/Component/Core/Publisher/PublisherService.php

Lines changed: 132 additions & 18 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,130 @@ 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()) {
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) {
121170
// deprecated, remove in v13
122171
$this->eventDispatcher->dispatch(new PublishingOfOneRecordBegan($record));
123-
if ($record->getState() !== Record::S_UNCHANGED) {
124-
$this->publisherCollection->publish($record);
125-
}
172+
173+
$this->publisherCollection->publish($record);
174+
126175
// deprecated, remove in v13
127176
$this->eventDispatcher->dispatch(new PublishingOfOneRecordEnded($record));
128177
$this->eventDispatcher->dispatch(new RecordWasPublished($record));
178+
179+
return true;
129180
}
130181

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

134-
if ($translationEvent->shouldProcessTranslations()) {
135-
foreach ($record->getTranslations() as $translatedRecords) {
136-
foreach ($translatedRecords as $translatedRecord) {
137-
$this->publishRecord($translatedRecord, $includeChildPages);
138-
}
209+
if (!$translationEvent->shouldProcessTranslations()) {
210+
return;
211+
}
212+
213+
foreach ($record->getTranslations() as $translatedRecords) {
214+
foreach ($translatedRecords as $translatedRecord) {
215+
// Translations are never top-level calls
216+
$this->publishRecord($translatedRecord, $includeChildPages, false);
139217
}
140218
}
219+
}
141220

221+
private function processChildPagesIndependently(Record $record, bool $includeChildPages): void
222+
{
142223
foreach ($record->getChildren() as $table => $children) {
143-
if ('pages' === $table && !$includeChildPages) {
144-
continue;
224+
if ($table !== 'pages') {
225+
continue; // Only process child pages independently
145226
}
227+
146228
foreach ($children as $child) {
147-
$this->publishRecord($child, $includeChildPages);
229+
// Child pages evaluated independently with strict checking
230+
$this->publishRecord($child, $includeChildPages, true);
231+
}
232+
}
233+
}
234+
235+
private function processChildRecords(Record $record, bool $includeChildPages, bool $parentWasPublished = false): void
236+
{
237+
foreach ($record->getChildren() as $table => $children) {
238+
// Handle child pages based on mode and settings
239+
if ($table === 'pages') {
240+
if (!$includeChildPages && !$this->isPublishAllMode) {
241+
// Skip child pages only if not including them AND not in publishAll mode
242+
continue;
243+
}
244+
}
245+
246+
foreach ($children as $child) {
247+
// Determine if child should be treated as top-level for dependency checking
248+
$isChildTopLevelCall = false;
249+
250+
if ($table === 'pages') {
251+
if ($this->isPublishAllMode) {
252+
// In publishAll mode: child pages get strict checking ONLY if their parent
253+
// was not published in the current run (independent evaluation)
254+
$isChildTopLevelCall = !$parentWasPublished;
255+
} elseif ($includeChildPages && !$this->isPublishAllMode) {
256+
// Child pages in regular mode with includeChildPages always get strict checking
257+
$isChildTopLevelCall = true;
258+
}
259+
}
260+
261+
$this->publishRecord($child, $includeChildPages, $isChildTopLevelCall);
148262
}
149263
}
150264
}
151-
}
265+
}

Tests/Unit/Component/Core/Publisher/PublisherServiceTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public function testPublishRecordTreePublishesAllUnchangedRecordsInTree(): void
3838
$databaseRecordPublisher = $this->createMock(DatabaseRecordPublisher::class);
3939
$databaseRecordPublisher->method('canPublish')->willReturn(true);
4040

41-
// assertion: publish all unchanged db records in tree
41+
// assertion: publish all changed db records in tree
4242
$databaseRecordPublisher->expects($this->exactly(2))->method('publish');
4343
$publisherService->addPublisher($databaseRecordPublisher);
4444

@@ -142,7 +142,7 @@ protected function createDatabaseRecord(
142142
$record->method('getLocalProps')->willReturn(['foo' => 'bar']);
143143
$record->method('getId')->willReturn($uid);
144144
$record->method('getClassification')->willReturn($table);
145-
$record->method('getState')->willReturn($state);
145+
$record->method('getStateRecursive')->willReturn($state);
146146
return $record;
147147
}
148148

ext_emconf.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
'title' => 'in2publish Core',
1010
'description' => 'Content publishing extension to connect stage and production server',
1111
'category' => 'plugin',
12-
'version' => '12.6.0',
12+
'version' => '12.6.1',
1313
'state' => 'stable',
1414
'clearCacheOnLoad' => true,
1515
'author' => 'Alex Kellner, Oliver Eglseder, Thomas Scheibitz, Stefan Busemann',

0 commit comments

Comments
 (0)