ILIAS  trunk Revision v13.0_alpha-62-g3b72d83f2e5
ILIAS\Language\ComponentTranslation\LocalChangeComments Class Reference

Tracks per overlay entry whether the current value still matches the value of the shipped .po (the distinction of lng_data.local_change), carried on the entry itself. More...

+ Collaboration diagram for ILIAS\Language\ComponentTranslation\LocalChangeComments:

Static Public Member Functions

static setOriginal (TranslationEntry $entry, string $value, ?int $form=null)
 Does not touch "local_change": refresh() recomputes it right after. More...
 
static removeOriginal (TranslationEntry $entry, ?int $form=null)
 With $form null the "original" of a singular message, otherwise the one of that plural form. More...
 
static removeFormOriginals (TranslationEntry $entry)
 Removes the "original" of every plural form (original[<form>]:) - e.g. More...
 
static getOriginal (TranslationEntry $entry, ?int $form=null)
 The decoded "original" value as passed to setOriginal(). More...
 
static setRemark (TranslationEntry $entry, ?string $remark)
 Sets the remark of $entry - null or '' removes it; cut to MAX_REMARK_LENGTH characters. More...
 
static setMergedIntoShipped (TranslationEntry $entry, bool $merged)
 Marks $entry as taken over into the shipped .po by "merge" (see ShippedPoMerger) - or removes the mark. More...
 
static isMergedIntoShipped (TranslationEntry $entry)
 
static getRemark (TranslationEntry $entry)
 The decoded remark of $entry, exactly as it was passed to setRemark(), null without one. More...
 
static getLocalChange (TranslationEntry $entry)
 
static getLocalChangeAsDatabaseTimestamp (TranslationEntry $entry)
 getLocalChange() in the database's "Y-m-d H:i:s" (UTC) format, as used by lng_data.local_change, or null if unmodified or unparsable. More...
 
static refresh (TranslationEntry $entry, string $previous_value, string $value, DateTimeImmutable $now)
 Called by MigratedLanguageFileSync::sync() for every entry it writes, after the new value was set. More...
 
static refreshForms (TranslationEntry $entry, array $previous_forms, array $forms, DateTimeImmutable $now)
 refresh() for a plural message: $forms are its new forms, $previous_forms the ones before this write. More...
 

Data Fields

const int MAX_REMARK_LENGTH = 250
 How many characters of a remark are kept - like lng_data.remarks. More...
 

Static Private Member Functions

static originalPrefix (bool $escaped, ?int $form)
 The comment prefix of an "original": "original: "/"original_escaped: " of a singular message, "original[<form>]: "/"original_escaped[<form>]: " of a plural form. More...
 
static setEscapable (TranslationEntry $entry, string $prefix, string $escaped_prefix, string $value)
 Stores $value under $prefix, or under $escaped_prefix if it needs escaping (see needsEscaping()) - used by setOriginal() and setRemark(), which only differ in their prefixes. More...
 
static getEscapable (TranslationEntry $entry, string $prefix, string $escaped_prefix)
 The value stored under $escaped_prefix (decoded) or $prefix, null if neither is present - the read side of setEscapable(). More...
 
static find (TranslationEntry $entry, string $prefix)
 
static replace (TranslationEntry $entry, string $prefix, ?string $value)
 
static needsEscaping (string $value)
 
static escape (string $value)
 Reversible single-line encoding: a backslash is doubled, a line feed becomes backslash + "n" and a carriage return becomes backslash + "r". More...
 
static unescape (string $value)
 

Private Attributes

const string ORIGINAL_PREFIX = 'original: '
 
const string ESCAPED_ORIGINAL_PREFIX = 'original_escaped: '
 
const string LOCAL_CHANGE_PREFIX = 'local_change: '
 
const string REMARK_PREFIX = 'remark: '
 
const string ESCAPED_REMARK_PREFIX = 'remark_escaped: '
 
const string MERGED_COMMENT = 'merged_into_shipped'
 

Detailed Description

Tracks per overlay entry whether the current value still matches the value of the shipped .po (the distinction of lng_data.local_change), carried on the entry itself.

Stored as gettext translator comments (# ...): the compiled .mo has no comment section, so this metadata is .po-only (like lng_data has metadata and lng_modules has none).

  • "original" is written once by MigratedLanguageFileSync::sync() when the overlay is first created, from the shipped .po value of that moment. Ordinary writes never touch it, so an admin edit cannot move the baseline - except via sync()'s $refresh_original_from_shipped, for callers that vouch that $entries reflect the current shipped content: it is updated if the shipped value changed.
  • "local_change" is maintained solely by refresh() (called by sync() on every write): present with the write's timestamp whenever the value differs from "original" (or there is none, e.g. a key added after migration), absent otherwise. Saving the original value again therefore clears it, like "local_change IS NULL" in _deleteLangData().
  • A plural message keeps one "original" per form (original[<form>]:, or original_escaped[<form>]:) and one "local_change" for the whole message, present if any form differs (see refreshForms()).
  • "remark" is the administrator's remark (counterpart of lng_data.remarks, one per identifier, also for plural messages), stored like "original": verbatim as remark:, or encoded as remark_escaped: if it contains a line break or a backslash.

Definition at line 47 of file LocalChangeComments.php.

Member Function Documentation

◆ escape()

static ILIAS\Language\ComponentTranslation\LocalChangeComments::escape ( string  $value)
staticprivate

Reversible single-line encoding: a backslash is doubled, a line feed becomes backslash + "n" and a carriage return becomes backslash + "r".

Definition at line 304 of file LocalChangeComments.php.

304 : string
305 {
306 return strtr($value, ['\\' => '\\\\', "\n" => '\\n', "\r" => '\\r']);
307 }

◆ find()

static ILIAS\Language\ComponentTranslation\LocalChangeComments::find ( TranslationEntry  $entry,
string  $prefix 
)
staticprivate

Definition at line 276 of file LocalChangeComments.php.

276 : ?string
277 {
278 foreach ($entry->getTranslatorComments() as $comment) {
279 if (str_starts_with($comment, $prefix)) {
280 return substr($comment, strlen($prefix));
281 }
282 }
283
284 return null;
285 }
$comment
Definition: buildRTE.php:72

References $comment, and ILIAS\Language\ComponentTranslation\Catalog\TranslationEntry\getTranslatorComments().

Referenced by ILIAS\Language\ComponentTranslation\LocalChangeComments\getLocalChange().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getEscapable()

static ILIAS\Language\ComponentTranslation\LocalChangeComments::getEscapable ( TranslationEntry  $entry,
string  $prefix,
string  $escaped_prefix 
)
staticprivate

The value stored under $escaped_prefix (decoded) or $prefix, null if neither is present - the read side of setEscapable().

Definition at line 266 of file LocalChangeComments.php.

266 : ?string
267 {
268 $escaped = self::find($entry, $escaped_prefix);
269 if ($escaped !== null) {
270 return self::unescape($escaped);
271 }
272
273 return self::find($entry, $prefix);
274 }
static find(TranslationEntry $entry, string $prefix)

Referenced by ILIAS\Language\ComponentTranslation\LocalChangeComments\getOriginal(), and ILIAS\Language\ComponentTranslation\LocalChangeComments\getRemark().

+ Here is the caller graph for this function:

◆ getLocalChange()

static ILIAS\Language\ComponentTranslation\LocalChangeComments::getLocalChange ( TranslationEntry  $entry)
static
Returns
string|null ISO-8601 UTC ('Y-m-d\TH:i:s\Z') or null if the entry is unmodified

Definition at line 154 of file LocalChangeComments.php.

154 : ?string
155 {
156 return self::find($entry, self::LOCAL_CHANGE_PREFIX);
157 }

References ILIAS\Language\ComponentTranslation\LocalChangeComments\find().

Referenced by ILIAS\Language\ComponentTranslation\LocalChangeComments\getLocalChangeAsDatabaseTimestamp(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testALegacyCommentWithABackslashIsMigratedToTheEscapedPrefixWithoutALocalChange(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testAnEmptyOriginalIsDistinctFromNoOriginal(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testANewlyMigratedEntryHasNoLocalChangeRightAfterOriginalIsSet(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testGetLocalChangeAsDatabaseTimestampIsNullForAnUnparsableTimestamp(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testOriginalKeepsLeadingAndTrailingWhitespaceExactly(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRefreshClearsTheLocalChangeWhenTheValueIsSetBackToTheOriginal(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRefreshComparesAMultiLineValueAgainstTheDecodedOriginal(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRefreshDoesNotBumpAnAlreadyCurrentTimestampOnAnIdempotentResave(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRefreshSetsALocalChangeTimestampWhenTheValueDiffersFromTheOriginal(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRefreshTreatsAMissingOriginalAsAlwaysLocallyChanged(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRefreshUpdatesAnExistingTimestampWhenTheValueChangesAgain(), and ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRemarkCoexistsWithOriginalAndLocalChangeOnTheSameEntry().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getLocalChangeAsDatabaseTimestamp()

static ILIAS\Language\ComponentTranslation\LocalChangeComments::getLocalChangeAsDatabaseTimestamp ( TranslationEntry  $entry)
static

getLocalChange() in the database's "Y-m-d H:i:s" (UTC) format, as used by lng_data.local_change, or null if unmodified or unparsable.

Definition at line 163 of file LocalChangeComments.php.

163 : ?string
164 {
165 $change = self::getLocalChange($entry);
166 if ($change === null) {
167 return null;
168 }
169 $date = DateTimeImmutable::createFromFormat('Y-m-d\TH:i:s\Z', $change, new \DateTimeZone('UTC'));
170
171 return $date === false ? null : $date->format('Y-m-d H:i:s');
172 }

References ILIAS\Language\ComponentTranslation\LocalChangeComments\getLocalChange().

Referenced by ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testGetLocalChangeAsDatabaseTimestampConvertsTheIsoFormat(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testGetLocalChangeAsDatabaseTimestampIsNullForAnUnparsableTimestamp(), and ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testGetLocalChangeAsDatabaseTimestampIsNullWithoutALocalChange().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getOriginal()

static ILIAS\Language\ComponentTranslation\LocalChangeComments::getOriginal ( TranslationEntry  $entry,
?int  $form = null 
)
static

The decoded "original" value as passed to setOriginal().

One written by an earlier version that flattened line breaks into spaces is returned as stored (the loss is permanent); the next reconciling sync rewrites it from the shipped value.

Definition at line 95 of file LocalChangeComments.php.

95 : ?string
96 {
97 return self::getEscapable($entry, self::originalPrefix(false, $form), self::originalPrefix(true, $form));
98 }
static getEscapable(TranslationEntry $entry, string $prefix, string $escaped_prefix)
The value stored under $escaped_prefix (decoded) or $prefix, null if neither is present - the read si...

References ILIAS\Language\ComponentTranslation\LocalChangeComments\getEscapable().

Referenced by ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testALegacyCommentWithABackslashIsMigratedToTheEscapedPrefixWithoutALocalChange(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testALegacyOriginalCommentIsReadVerbatim(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testAnEmptyOriginalIsDistinctFromNoOriginal(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testANewlyMigratedEntryHasNoLocalChangeRightAfterOriginalIsSet(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testOriginalKeepsLeadingAndTrailingWhitespaceExactly(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRefreshClearsTheLocalChangeWhenTheValueIsSetBackToTheOriginal(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRefreshTreatsAMissingOriginalAsAlwaysLocallyChanged(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRemarkCoexistsWithOriginalAndLocalChangeOnTheSameEntry(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRemarkCoexistsWithPerFormOriginalsOfAPluralMessage(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRemoveOriginalLeavesOtherCommentsAlone(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRemoveOriginalRemovesBothTheLegacyAndTheEscapedPrefix(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testSetOriginalRemovesAStaleCommentOfTheOtherPrefix(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testSetOriginalWithADifferentValueReplacesTheOldOriginalInsteadOfAddingASecondOne(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testSwitchingBetweenEscapedAndVerbatimValuesKeepsExactlyOneOriginalComment(), and ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testTheOriginalSurvivesAPoFileRoundTrip().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getRemark()

static ILIAS\Language\ComponentTranslation\LocalChangeComments::getRemark ( TranslationEntry  $entry)
static

The decoded remark of $entry, exactly as it was passed to setRemark(), null without one.

Definition at line 146 of file LocalChangeComments.php.

146 : ?string
147 {
148 return self::getEscapable($entry, self::REMARK_PREFIX, self::ESCAPED_REMARK_PREFIX);
149 }

References ILIAS\Language\ComponentTranslation\LocalChangeComments\getEscapable().

Referenced by ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testGetRemarkIsNullWithoutOneSet(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRemarkCoexistsWithOriginalAndLocalChangeOnTheSameEntry(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRemarkCoexistsWithPerFormOriginalsOfAPluralMessage(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testSetRemarkAndGetRemarkRoundTripAPlainValueVerbatim(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testSetRemarkAtExactlyMaxRemarkLengthIsNotCut(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testSetRemarkEscapesALineBreakOrBackslashLikeSetOriginalDoes(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testSetRemarkIsCutToMaxRemarkLengthCharactersNotBytes(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testSetRemarkKeepsLeadingAndTrailingWhitespaceExactly(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testSetRemarkSwitchingBetweenEscapedAndPlainKeepsExactlyOneComment(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testSetRemarkWithAnEmptyStringRemovesIt(), and ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testSetRemarkWithNullRemovesAnExistingOne().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ isMergedIntoShipped()

static ILIAS\Language\ComponentTranslation\LocalChangeComments::isMergedIntoShipped ( TranslationEntry  $entry)
static

Definition at line 138 of file LocalChangeComments.php.

138 : bool
139 {
140 return in_array(self::MERGED_COMMENT, $entry->getTranslatorComments(), true);
141 }

References ILIAS\Language\ComponentTranslation\Catalog\TranslationEntry\getTranslatorComments().

+ Here is the call graph for this function:

◆ needsEscaping()

static ILIAS\Language\ComponentTranslation\LocalChangeComments::needsEscaping ( string  $value)
staticprivate

Definition at line 295 of file LocalChangeComments.php.

295 : bool
296 {
297 return strpbrk($value, "\\\n\r") !== false;
298 }

◆ originalPrefix()

static ILIAS\Language\ComponentTranslation\LocalChangeComments::originalPrefix ( bool  $escaped,
?int  $form 
)
staticprivate

The comment prefix of an "original": "original: "/"original_escaped: " of a singular message, "original[<form>]: "/"original_escaped[<form>]: " of a plural form.

Definition at line 237 of file LocalChangeComments.php.

237 : string
238 {
240
241 return $form === null ? $prefix : substr($prefix, 0, -2) . '[' . $form . ']: ';
242 }

◆ refresh()

static ILIAS\Language\ComponentTranslation\LocalChangeComments::refresh ( TranslationEntry  $entry,
string  $previous_value,
string  $value,
DateTimeImmutable  $now 
)
static

Called by MigratedLanguageFileSync::sync() for every entry it writes, after the new value was set.

$previous_value avoids bumping the timestamp on an idempotent re-save of an already changed value.

Definition at line 178 of file LocalChangeComments.php.

183 : void {
184 $original = self::getOriginal($entry);
185 $is_local_change = $original === null || $original !== $value;
186
187 if (!$is_local_change) {
188 self::replace($entry, self::LOCAL_CHANGE_PREFIX, null);
189 return;
190 }
191
192 if ($previous_value === $value && self::getLocalChange($entry) !== null) {
193 return;
194 }
195
196 self::replace($entry, self::LOCAL_CHANGE_PREFIX, $now->format('Y-m-d\TH:i:s\Z'));
197 }
static replace(TranslationEntry $entry, string $prefix, ?string $value)
static getOriginal(TranslationEntry $entry, ?int $form=null)
The decoded "original" value as passed to setOriginal().

References ILIAS\Language\ComponentTranslation\LocalChangeComments\replace().

Referenced by ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testALegacyCommentWithABackslashIsMigratedToTheEscapedPrefixWithoutALocalChange(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testAnEmptyOriginalIsDistinctFromNoOriginal(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testGetLocalChangeAsDatabaseTimestampConvertsTheIsoFormat(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testOriginalKeepsLeadingAndTrailingWhitespaceExactly(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRefreshClearsTheLocalChangeWhenTheValueIsSetBackToTheOriginal(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRefreshComparesAMultiLineValueAgainstTheDecodedOriginal(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRefreshDoesNotBumpAnAlreadyCurrentTimestampOnAnIdempotentResave(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRefreshNeverLeavesMoreThanOneLocalChangeCommentBehind(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRefreshSetsALocalChangeTimestampWhenTheValueDiffersFromTheOriginal(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRefreshTreatsAMissingOriginalAsAlwaysLocallyChanged(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRefreshUpdatesAnExistingTimestampWhenTheValueChangesAgain(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRemarkCoexistsWithOriginalAndLocalChangeOnTheSameEntry(), and ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRemoveOriginalLeavesOtherCommentsAlone().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ refreshForms()

static ILIAS\Language\ComponentTranslation\LocalChangeComments::refreshForms ( TranslationEntry  $entry,
array  $previous_forms,
array  $forms,
DateTimeImmutable  $now 
)
static

refresh() for a plural message: $forms are its new forms, $previous_forms the ones before this write.

"local_change" is present whenever any form differs from its "original" (or has none).

Parameters
list<string>$previous_forms
list<string>$forms

Definition at line 206 of file LocalChangeComments.php.

211 : void {
212 $is_local_change = false;
213 foreach ($forms as $form => $value) {
214 $original = self::getOriginal($entry, $form);
215 if ($original === null || $original !== $value) {
216 $is_local_change = true;
217 break;
218 }
219 }
220
221 if (!$is_local_change) {
222 self::replace($entry, self::LOCAL_CHANGE_PREFIX, null);
223 return;
224 }
225
226 if ($previous_forms === $forms && self::getLocalChange($entry) !== null) {
227 return;
228 }
229
230 self::replace($entry, self::LOCAL_CHANGE_PREFIX, $now->format('Y-m-d\TH:i:s\Z'));
231 }

◆ removeFormOriginals()

static ILIAS\Language\ComponentTranslation\LocalChangeComments::removeFormOriginals ( TranslationEntry  $entry)
static

Removes the "original" of every plural form (original[<form>]:) - e.g.

when a plural message becomes a singular one.

Definition at line 81 of file LocalChangeComments.php.

81 : void
82 {
83 foreach ($entry->getTranslatorComments() as $comment) {
84 if (preg_match('/\Aoriginal(?:_escaped)?\[\d+\]: /', $comment, $matches) === 1) {
85 $entry->removeTranslatorCommentsStartingWith($matches[0]);
86 }
87 }
88 }

References $comment, ILIAS\Language\ComponentTranslation\Catalog\TranslationEntry\getTranslatorComments(), and ILIAS\Language\ComponentTranslation\Catalog\TranslationEntry\removeTranslatorCommentsStartingWith().

Referenced by ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRemarkCoexistsWithPerFormOriginalsOfAPluralMessage().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ removeOriginal()

static ILIAS\Language\ComponentTranslation\LocalChangeComments::removeOriginal ( TranslationEntry  $entry,
?int  $form = null 
)
static

With $form null the "original" of a singular message, otherwise the one of that plural form.

Definition at line 71 of file LocalChangeComments.php.

71 : void
72 {
73 self::replace($entry, self::originalPrefix(false, $form), null);
74 self::replace($entry, self::originalPrefix(true, $form), null);
75 }

References ILIAS\Language\ComponentTranslation\LocalChangeComments\replace().

Referenced by ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRemoveOriginalLeavesOtherCommentsAlone(), and ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRemoveOriginalRemovesBothTheLegacyAndTheEscapedPrefix().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ replace()

static ILIAS\Language\ComponentTranslation\LocalChangeComments::replace ( TranslationEntry  $entry,
string  $prefix,
?string  $value 
)
staticprivate

◆ setEscapable()

static ILIAS\Language\ComponentTranslation\LocalChangeComments::setEscapable ( TranslationEntry  $entry,
string  $prefix,
string  $escaped_prefix,
string  $value 
)
staticprivate

Stores $value under $prefix, or under $escaped_prefix if it needs escaping (see needsEscaping()) - used by setOriginal() and setRemark(), which only differ in their prefixes.

Definition at line 248 of file LocalChangeComments.php.

248 : void
249 {
250 [$prefix, $other_prefix, $stored] = self::needsEscaping($value)
251 ? [$escaped_prefix, $prefix, self::escape($value)]
252 : [$prefix, $escaped_prefix, $value];
253
254 // Unchanged: keep the comment where it is, so re-running a sync produces identical output
255 if (self::find($entry, $prefix) === $stored && self::find($entry, $other_prefix) === null) {
256 return;
257 }
258 self::replace($entry, $other_prefix, null);
259 self::replace($entry, $prefix, $stored);
260 }
static escape(string $value)
Reversible single-line encoding: a backslash is doubled, a line feed becomes backslash + "n" and a ca...

Referenced by ILIAS\Language\ComponentTranslation\LocalChangeComments\setOriginal(), and ILIAS\Language\ComponentTranslation\LocalChangeComments\setRemark().

+ Here is the caller graph for this function:

◆ setMergedIntoShipped()

static ILIAS\Language\ComponentTranslation\LocalChangeComments::setMergedIntoShipped ( TranslationEntry  $entry,
bool  $merged 
)
static

Marks $entry as taken over into the shipped .po by "merge" (see ShippedPoMerger) - or removes the mark.

While the build does not serve that .po yet, MigratedLanguageFileSync::sync() keeps a marked entry in the overlay even though its value equals the shipped one.

Definition at line 130 of file LocalChangeComments.php.

130 : void
131 {
132 $entry->removeTranslatorCommentsStartingWith(self::MERGED_COMMENT);
133 if ($merged) {
134 $entry->addTranslatorComment(self::MERGED_COMMENT);
135 }
136 }

References ILIAS\Language\ComponentTranslation\Catalog\TranslationEntry\addTranslatorComment(), and ILIAS\Language\ComponentTranslation\Catalog\TranslationEntry\removeTranslatorCommentsStartingWith().

+ Here is the call graph for this function:

◆ setOriginal()

static ILIAS\Language\ComponentTranslation\LocalChangeComments::setOriginal ( TranslationEntry  $entry,
string  $value,
?int  $form = null 
)
static

Does not touch "local_change": refresh() recomputes it right after.

A comment is one PO line, so a value with a line break or a backslash is stored escaped ("original_escaped: ", see escape()); every other value verbatim under "original: ", as earlier versions wrote it.

Definition at line 63 of file LocalChangeComments.php.

63 : void
64 {
65 self::setEscapable($entry, self::originalPrefix(false, $form), self::originalPrefix(true, $form), $value);
66 }
static setEscapable(TranslationEntry $entry, string $prefix, string $escaped_prefix, string $value)
Stores $value under $prefix, or under $escaped_prefix if it needs escaping (see needsEscaping()) - us...

References ILIAS\Language\ComponentTranslation\LocalChangeComments\setEscapable().

Referenced by ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testALegacyCommentWithABackslashIsMigratedToTheEscapedPrefixWithoutALocalChange(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testAnEmptyOriginalIsDistinctFromNoOriginal(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testANewlyMigratedEntryHasNoLocalChangeRightAfterOriginalIsSet(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testAValueWithoutLineBreakOrBackslashIsStoredVerbatimUnderTheLegacyPrefix(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testGetLocalChangeAsDatabaseTimestampIsNullWithoutALocalChange(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testOriginalKeepsLeadingAndTrailingWhitespaceExactly(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRefreshClearsTheLocalChangeWhenTheValueIsSetBackToTheOriginal(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRefreshComparesAMultiLineValueAgainstTheDecodedOriginal(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRefreshDoesNotBumpAnAlreadyCurrentTimestampOnAnIdempotentResave(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRefreshNeverLeavesMoreThanOneLocalChangeCommentBehind(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRefreshSetsALocalChangeTimestampWhenTheValueDiffersFromTheOriginal(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRefreshUpdatesAnExistingTimestampWhenTheValueChangesAgain(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRemarkCoexistsWithOriginalAndLocalChangeOnTheSameEntry(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRemarkCoexistsWithPerFormOriginalsOfAPluralMessage(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRemoveOriginalLeavesOtherCommentsAlone(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testSetOriginalRemovesAStaleCommentOfTheOtherPrefix(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testSetOriginalWithADifferentValueReplacesTheOldOriginalInsteadOfAddingASecondOne(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testSetOriginalWithTheSameEscapedValueKeepsTheCommentOrderStable(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testSetOriginalWithTheSameValueKeepsTheCommentOrderStable(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testSwitchingBetweenEscapedAndVerbatimValuesKeepsExactlyOneOriginalComment(), and ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testTheOriginalSurvivesAPoFileRoundTrip().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setRemark()

static ILIAS\Language\ComponentTranslation\LocalChangeComments::setRemark ( TranslationEntry  $entry,
?string  $remark 
)
static

Sets the remark of $entry - null or '' removes it; cut to MAX_REMARK_LENGTH characters.

Exceptions

InvalidArgumentException for a remark that is not valid UTF-8 (the overlay would become unreadable)

Definition at line 111 of file LocalChangeComments.php.

111 : void
112 {
113 if ($remark !== null && !mb_check_encoding($remark, 'UTF-8')) {
114 throw new \InvalidArgumentException(sprintf('The remark of "%s" is not valid UTF-8.', $entry->getId()));
115 }
116 $remark = $remark === null ? null : mb_substr($remark, 0, self::MAX_REMARK_LENGTH);
117 if ($remark === null || $remark === '') {
118 self::replace($entry, self::REMARK_PREFIX, null);
119 self::replace($entry, self::ESCAPED_REMARK_PREFIX, null);
120 return;
121 }
122 self::setEscapable($entry, self::REMARK_PREFIX, self::ESCAPED_REMARK_PREFIX, $remark);
123 }

References ILIAS\Language\ComponentTranslation\Catalog\TranslationEntry\getId(), ILIAS\Language\ComponentTranslation\LocalChangeComments\replace(), and ILIAS\Language\ComponentTranslation\LocalChangeComments\setEscapable().

Referenced by ImportUsesShippedValuesOfMigratedModulesTest\testAnEmptyRemarkRemovesTheLocalRemarkAndOtherwiseWritesNothing(), ImportUsesShippedValuesOfMigratedModulesTest\testDeleteModeImportDropsTheFormerOverlayRemarksAndKeepsTheImportedOnes(), ImportUsesShippedValuesOfMigratedModulesTest\testDeleteModeImportReplacesTheOverlayRemarkOfAPluralMessage(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRemarkCoexistsWithOriginalAndLocalChangeOnTheSameEntry(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testRemarkCoexistsWithPerFormOriginalsOfAPluralMessage(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testSetRemarkAndGetRemarkRoundTripAPlainValueVerbatim(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testSetRemarkAtExactlyMaxRemarkLengthIsNotCut(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testSetRemarkEscapesALineBreakOrBackslashLikeSetOriginalDoes(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testSetRemarkIsCutToMaxRemarkLengthCharactersNotBytes(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testSetRemarkKeepsLeadingAndTrailingWhitespaceExactly(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testSetRemarkSwitchingBetweenEscapedAndPlainKeepsExactlyOneComment(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testSetRemarkThrowsForInvalidUtf8(), ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testSetRemarkWithAnEmptyStringRemovesIt(), and ILIAS\Language\ComponentTranslation\LocalChangeCommentsTest\testSetRemarkWithNullRemovesAnExistingOne().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ unescape()

static ILIAS\Language\ComponentTranslation\LocalChangeComments::unescape ( string  $value)
staticprivate

Definition at line 309 of file LocalChangeComments.php.

309 : string
310 {
311 return strtr($value, ['\\\\' => '\\', '\\n' => "\n", '\\r' => "\r"]);
312 }

Field Documentation

◆ ESCAPED_ORIGINAL_PREFIX

const string ILIAS\Language\ComponentTranslation\LocalChangeComments::ESCAPED_ORIGINAL_PREFIX = 'original_escaped: '
private

Definition at line 50 of file LocalChangeComments.php.

◆ ESCAPED_REMARK_PREFIX

const string ILIAS\Language\ComponentTranslation\LocalChangeComments::ESCAPED_REMARK_PREFIX = 'remark_escaped: '
private

Definition at line 53 of file LocalChangeComments.php.

◆ LOCAL_CHANGE_PREFIX

const string ILIAS\Language\ComponentTranslation\LocalChangeComments::LOCAL_CHANGE_PREFIX = 'local_change: '
private

Definition at line 51 of file LocalChangeComments.php.

◆ MAX_REMARK_LENGTH

const int ILIAS\Language\ComponentTranslation\LocalChangeComments::MAX_REMARK_LENGTH = 250

◆ MERGED_COMMENT

const string ILIAS\Language\ComponentTranslation\LocalChangeComments::MERGED_COMMENT = 'merged_into_shipped'
private

Definition at line 54 of file LocalChangeComments.php.

◆ ORIGINAL_PREFIX

const string ILIAS\Language\ComponentTranslation\LocalChangeComments::ORIGINAL_PREFIX = 'original: '
private

Definition at line 49 of file LocalChangeComments.php.

◆ REMARK_PREFIX

const string ILIAS\Language\ComponentTranslation\LocalChangeComments::REMARK_PREFIX = 'remark: '
private

Definition at line 52 of file LocalChangeComments.php.


The documentation for this class was generated from the following file: