Skip to content

Commit 55012fa

Browse files
committed
Ensuring altering field methods clone object
1 parent 65708d8 commit 55012fa

File tree

1 file changed

+57
-81
lines changed

1 file changed

+57
-81
lines changed

Diff for: src/Content/Field.php

+57-81
Original file line numberDiff line numberDiff line change
@@ -121,27 +121,27 @@ public function callback(Closure $callback): mixed
121121
* templates without the risk of XSS attacks
122122
*
123123
* @param string $context Location of output (`html`, `attr`, `js`, `css`, `url` or `xml`)
124-
* @return $this
125124
*/
126125
public function escape(string $context = 'html'): static
127126
{
128-
$this->value = Str::esc($this->value ?? '', $context);
129-
return $this;
127+
return $this->value(fn ($value) => Str::esc($value ?? '', $context));
130128
}
131129

132130
/**
133131
* Creates an excerpt of the field value without html
134132
* or any other formatting.
135-
* @return $this
136133
*/
137134
public function excerpt(
138135
int $chars = 0,
139136
bool $strip = true,
140137
string $rep = ''
141138
): static {
142-
$value = $this->kirbytext()->value();
143-
$this->value = Str::excerpt($value, $chars, $strip, $rep);
144-
return $this;
139+
return $this->value(Str::excerpt(
140+
string: $this->kirbytext()->value(),
141+
chars: $chars,
142+
strip: $strip,
143+
rep: $rep
144+
));
145145
}
146146

147147
/**
@@ -154,20 +154,17 @@ public function exists(): bool
154154

155155
/**
156156
* Converts the field content to valid HTML
157-
* @return $this
158157
*/
159158
public function html(): static
160159
{
161-
$this->value = Html::encode($this->value);
162-
return $this;
160+
return $this->value(fn ($value) => Html::encode($value));
163161
}
164162

165163
/**
166164
* Strips all block-level HTML elements from the field value,
167165
* it can be safely placed inside of other inline elements
168166
* without the risk of breaking the HTML structure.
169167
* @since 3.3.0
170-
* @return $this
171168
*/
172169
public function inline(): static
173170
{
@@ -176,8 +173,9 @@ public function inline(): static
176173
// Obsolete elements, script tags, image maps and form elements have
177174
// been excluded for safety reasons and as they are most likely not
178175
// needed in most cases.
179-
$this->value = strip_tags($this->value ?? '', Html::$inlineList);
180-
return $this;
176+
return $this->value(
177+
fn ($value) => strip_tags($value ?? '', Html::$inlineList)
178+
);
181179
}
182180

183181
/**
@@ -249,44 +247,37 @@ public function kirby(): App
249247

250248
/**
251249
* Parses all KirbyTags without also parsing Markdown
252-
* @return $this
253250
*/
254251
public function kirbytags(): static
255252
{
256-
$this->value = $this->kirby()->kirbytags(
257-
text: $this->value,
253+
return $this->value(fn ($value, $field) => $field->kirby()->kirbytags(
254+
text: $value,
258255
data: [
259-
'parent' => $this->parent(),
260-
'field' => $this
256+
'parent' => $field->parent(),
257+
'field' => $field
261258
]
262-
);
263-
264-
return $this;
259+
));
265260
}
266261

267262
/**
268263
* Converts the field content from Markdown/Kirbytext to valid HTML
269-
* @return $this
270264
*/
271265
public function kirbytext(array $options = []): static
272266
{
273-
$this->value = $this->kirby()->kirbytext(
274-
text: $this->value,
267+
return $this->value(fn ($value, $field) => $field->kirby()->kirbytext(
268+
text: $value,
275269
options: [
276270
...$options,
277-
'parent' => $this->parent(),
278-
'field' => $this
271+
'parent' => $field->parent(),
272+
'field' => $field
279273
]
280-
);
281-
282-
return $this;
274+
));
283275
}
284276

285277
/**
286278
* Converts the field content from inline Markdown/Kirbytext
287279
* to valid HTML
288280
* @since 3.1.0
289-
* @return $this
290281
*/
291282
public function kirbytextInline(array $options = []): static
292283
{
@@ -305,25 +296,21 @@ public function length(): int
305296

306297
/**
307298
* Converts the field content to lowercase
308-
* @return $this
309299
*/
310300
public function lower(): static
311301
{
312-
$this->value = Str::lower($this->value);
313-
return $this;
302+
return $this->value(fn ($value) => Str::lower($value));
314303
}
315304

316305
/**
317306
* Converts markdown to valid HTML
318-
* @return $this
319307
*/
320308
public function markdown(array $options = []): static
321309
{
322-
$this->value = $this->kirby()->markdown(
323-
text: $this->value,
310+
return $this->value(fn ($value) => $this->kirby()->markdown(
311+
text: $value,
324312
options: $options
325-
);
326-
return $this;
313+
));
327314
}
328315

329316
/**
@@ -337,12 +324,10 @@ public function model(): ModelWithContent|null
337324
/**
338325
* Converts all line breaks in the field content to `<br>` tags.
339326
* @since 3.3.0
340-
* @return $this
341327
*/
342328
public function nl2br(): static
343329
{
344-
$this->value = nl2br($this->value ?? '', false);
345-
return $this;
330+
return $this->value(fn ($value) => nl2br($value ?? '', false));
346331
}
347332

348333
/**
@@ -360,9 +345,7 @@ public function or(mixed $fallback = null): static
360345
return $fallback;
361346
}
362347

363-
$field = clone $this;
364-
$field->value = $fallback;
365-
return $field;
348+
return $this->value($fallback);
366349
}
367350

368351
/**
@@ -381,13 +364,13 @@ public function parent(): ModelWithContent|null
381364
* This method is still experimental! You can use
382365
* it to solve potential problems with permalinks
383366
* already, but it might change in the future.
384-
*
385-
* @return $this
386367
*/
387368
public function permalinksToUrls(): static
388369
{
389-
if ($this->isNotEmpty() === true) {
390-
$dom = new Dom($this->value);
370+
$field = clone $this;
371+
372+
if ($field->isNotEmpty() === true) {
373+
$dom = new Dom($field->value);
391374
$attributes = ['href', 'src'];
392375
$elements = $dom->query('//*[' . implode(' | ', A::map($attributes, fn ($attribute) => '@' . $attribute)) . ']');
393376

@@ -405,10 +388,10 @@ public function permalinksToUrls(): static
405388
}
406389
}
407390

408-
$this->value = $dom->toString();
391+
$field->value = $dom->toString();
409392
}
410393

411-
return $this;
394+
return $field;
412395
}
413396

414397
/**
@@ -432,7 +415,6 @@ public function query(
432415
* It parses any queries found in the field value.
433416
*
434417
* @param string|null $fallback Fallback for tokens in the template that cannot be replaced (`null` to keep the original token)
435-
* @return $this
436418
*/
437419
public function replace(
438420
array $data = [],
@@ -441,20 +423,23 @@ public function replace(
441423
if ($parent = $this->parent()) {
442424
// Never pass `null` as the $template
443425
// to avoid the fallback to the model ID
444-
$this->value = $parent->toString(
445-
$this->value ?? '',
426+
return $this->value(fn ($value) => $parent->toString(
427+
$value ?? '',
446428
$data,
447429
$fallback
448-
);
449-
} else {
450-
$this->value = Str::template($this->value, array_replace([
451-
'kirby' => $app = $this->kirby(),
452-
'site' => $app->site(),
453-
'page' => $app->page()
454-
], $data), ['fallback' => $fallback]);
430+
));
455431
}
456432

457-
return $this;
433+
return $this->value(fn ($value) => Str::template(
434+
$value,
435+
[
436+
'kirby' => $app = $this->kirby(),
437+
'site' => $app->site(),
438+
'page' => $app->page(),
439+
...$data
440+
],
441+
['fallback' => $fallback]
442+
));
458443
}
459444

460445
/**
@@ -463,34 +448,30 @@ public function replace(
463448
*
464449
* @param int $length The number of characters in the string
465450
* @param string $appendix An optional replacement for the missing rest
466-
* @return $this
467451
*/
468452
public function short(
469453
int $length,
470454
string $appendix = ''
471455
): static {
472-
$this->value = Str::short($this->value, $length, $appendix);
473-
return $this;
456+
return $this->value(
457+
fn ($value) => Str::short($value, $length, $appendix)
458+
);
474459
}
475460

476461
/**
477462
* Converts the field content to a slug
478-
* @return $this
479463
*/
480464
public function slug(): static
481465
{
482-
$this->value = Str::slug($this->value);
483-
return $this;
466+
return $this->value(fn ($value) => Str::slug($value));
484467
}
485468

486469
/**
487470
* Applies SmartyPants to the field
488-
* @return $this
489471
*/
490472
public function smartypants(): static
491473
{
492-
$this->value = $this->kirby()->smartypants($this->value);
493-
return $this;
474+
return $this->value(fn ($value) => $this->kirby()->smartypants($value));
494475
}
495476

496477
/**
@@ -801,12 +782,10 @@ public function toUsers(string $separator = 'yaml'): Users
801782

802783
/**
803784
* Converts the field content to uppercase
804-
* @return $this
805785
*/
806786
public function upper(): static
807787
{
808-
$this->value = Str::upper($this->value);
809-
return $this;
788+
return $this->value(fn ($value) => Str::upper($value));
810789
}
811790

812791
/**
@@ -820,11 +799,12 @@ public function value(string|Closure|null $value = null): mixed
820799
return $this->value;
821800
}
822801

802+
$clone = clone $this;
803+
823804
if ($value instanceof Closure) {
824-
$value = $value->call($this, $this->value);
805+
$value = $value->call($this, $this->value, $clone);
825806
}
826807

827-
$clone = clone $this;
828808
$clone->value = (string)$value;
829809

830810
return $clone;
@@ -833,12 +813,10 @@ public function value(string|Closure|null $value = null): mixed
833813
/**
834814
* Avoids typographical widows in strings by replacing
835815
* the last space with `&nbsp;`
836-
* @return $this
837816
*/
838817
public function widont(): static
839818
{
840-
$this->value = Str::widont($this->value);
841-
return $this;
819+
return $this->value(fn ($value) => Str::widont($value));
842820
}
843821

844822
/**
@@ -851,12 +829,10 @@ public function words(): int
851829

852830
/**
853831
* Converts the field content to valid XML
854-
* @return $this
855832
*/
856833
public function xml(): static
857834
{
858-
$this->value = Xml::encode($this->value);
859-
return $this;
835+
return $this->value(fn ($value) => Xml::encode($value));
860836
}
861837

862838
/**

0 commit comments

Comments
 (0)