Skip to content

Commit 94b4a59

Browse files
committed
Update YAML handler.
1 parent d966a32 commit 94b4a59

1 file changed

Lines changed: 76 additions & 59 deletions

File tree

YAML.php

Lines changed: 76 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22
/**
3-
* YAML handler (last modified: 2022.02.21).
3+
* YAML handler (last modified: 2023.03.24).
44
*
55
* This file is a part of the "common classes package", utilised by a number of
66
* packages and projects, including CIDRAM and phpMussel.
@@ -132,7 +132,7 @@ class YAML
132132
* be needed by some implementations to ensure compatibility).
133133
* @link https://github.com/Maikuolan/Common/tags
134134
*/
135-
public const VERSION = '2.9.0';
135+
public const VERSION = '2.9.6';
136136

137137
/**
138138
* Can optionally begin processing data as soon as the object is
@@ -380,7 +380,7 @@ public function process(string $In, array &$Arr, int $Depth = 0, bool $Refs = fa
380380
$Success = true;
381381

382382
/** Needed for processing any remaining data. */
383-
if ($SendTo && !empty($Key)) {
383+
if ($SendTo) {
384384
if (!$this->MultiLine && !$this->MultiLineFolded) {
385385
if (!isset($Arr[$Key]) || !is_array($Arr[$Key])) {
386386
$Arr[$Key] = [];
@@ -448,22 +448,32 @@ public function reconstruct(array $Arr, bool $UseCaptured = false, bool $DoWithA
448448
*
449449
* @param mixed $Data The data to traverse.
450450
* @param string|array $Path The path to traverse.
451+
* @param bool $AllowNonScalar Whether to allow non-scalar returns.
451452
* @return mixed The traversed data, or an empty string on failure.
452453
*/
453-
public function dataTraverse(&$Data, $Path = [])
454+
public function dataTraverse(&$Data, $Path = [], bool $AllowNonScalar = false)
454455
{
455456
if (!is_array($Path)) {
456457
$Path = preg_split('~(?<!\\\)\.~', $Path) ?: [];
457458
}
458459
$Segment = array_shift($Path);
459460
if ($Segment === null || strlen($Segment) === 0) {
460-
return is_scalar($Data) ? $Data : '';
461+
return $AllowNonScalar || is_scalar($Data) ? $Data : '';
461462
}
462463
$Segment = str_replace('\.', '.', $Segment);
463-
if (is_array($Data)) {
464-
return isset($Data[$Segment]) ? $this->dataTraverse($Data[$Segment], $Path) : '';
464+
if (is_array($Data) && isset($Data[$Segment])) {
465+
return $this->dataTraverse($Data[$Segment], $Path, $AllowNonScalar);
465466
}
466-
return $this->dataTraverse($Data, $Path);
467+
if (is_object($Data) && property_exists($Data, $Segment)) {
468+
return $this->dataTraverse($Data->$Segment, $Path, $AllowNonScalar);
469+
}
470+
if (is_string($Data)) {
471+
if (preg_match('~^(?:trim|str(?:tolower|toupper|len))\(\)~i', $Segment)) {
472+
$Segment = substr($Segment, 0, -2);
473+
$Data = $Segment($Data);
474+
}
475+
}
476+
return $this->dataTraverse($Data, $Path, $AllowNonScalar);
467477
}
468478

469479
/**
@@ -766,66 +776,67 @@ private function processInner(array $Arr, string &$Out, int $Depth = 0): void
766776
if ($Depth === $this->FlowRebuildDepth) {
767777
$Out .= "\n";
768778
}
769-
} else {
770-
foreach ($Arr as $Key => $Value) {
771-
if ($Key === '---' && $Value === null) {
772-
$Out .= "---\n";
773-
continue;
774-
}
775-
if ($Key === '...' && $Value === null) {
776-
$Out .= "...\n";
777-
continue;
778-
}
779-
$ThisDepth = str_repeat($this->Indent, $Depth);
780-
if ($NullSet && !$Sequential) {
781-
$Out .= $ThisDepth . '?';
782-
$Value = $Key;
783-
} else {
784-
$Out .= $ThisDepth . ($Sequential ? '-' : ($this->QuoteKeys ? $this->scalarToString($Key) : $Key) . ':');
785-
}
786-
if (is_array($Value)) {
787-
if ($Depth < $this->FlowRebuildDepth - 1) {
788-
$Out .= "\n";
789-
}
790-
$this->processInner($Value, $Out, $Depth + 1);
791-
continue;
779+
return;
780+
}
781+
foreach ($Arr as $Key => $Value) {
782+
if ($Key === '---' && $Value === null) {
783+
$Out .= "---\n";
784+
continue;
785+
}
786+
if ($Key === '...' && $Value === null) {
787+
$Out .= "...\n";
788+
continue;
789+
}
790+
$ThisDepth = str_repeat($this->Indent, $Depth);
791+
if ($NullSet && !$Sequential) {
792+
$Out .= $ThisDepth . '?';
793+
$Value = $Key;
794+
} else {
795+
$Out .= $ThisDepth . ($Sequential ? '-' : ($this->QuoteKeys ? $this->scalarToString($Key) : $Key) . ':');
796+
}
797+
if (is_array($Value)) {
798+
if ($Depth < $this->FlowRebuildDepth - 1) {
799+
$Out .= "\n";
792800
}
793-
$Out .= ' ';
794-
if (is_string($Value)) {
795-
if (strpos($Value, "\n") !== false) {
796-
if (preg_match('~\n{2,}$~m', $Value)) {
797-
$ToAdd = "|+\n" . $ThisDepth . $this->Indent;
798-
} else {
799-
$ToAdd = "|\n" . $ThisDepth . $this->Indent;
800-
}
801-
$ToAdd .= preg_replace('~\n(?=[^\n])~m', "\n" . $ThisDepth . $this->Indent, $Value);
802-
} elseif ($this->FoldedAt > 0 && strpos($Value, ' ') !== false && strlen($Value) >= $this->FoldedAt) {
803-
$ToAdd = ">\n" . $ThisDepth . $this->Indent . wordwrap(
804-
$Value,
805-
$this->FoldedAt,
806-
"\n" . $ThisDepth . $this->Indent
807-
);
801+
$this->processInner($Value, $Out, $Depth + 1);
802+
continue;
803+
}
804+
$Out .= ' ';
805+
if (is_string($Value)) {
806+
$HasHash = strpos($Value, '#') !== false;
807+
if (!$HasHash && strpos($Value, "\n") !== false) {
808+
if (preg_match('~\n{2,}$~m', $Value)) {
809+
$ToAdd = "|+\n" . $ThisDepth . $this->Indent;
808810
} else {
809-
$ToAdd = $this->Quotes . $this->escape($Value) . $this->Quotes;
811+
$ToAdd = "|\n" . $ThisDepth . $this->Indent;
810812
}
813+
$ToAdd .= preg_replace('~\n(?=[^\n])~m', "\n" . $ThisDepth . $this->Indent, $Value);
814+
} elseif (!$HasHash && $this->FoldedAt > 0 && strpos($Value, ' ') !== false && strlen($Value) >= $this->FoldedAt) {
815+
$ToAdd = ">\n" . $ThisDepth . $this->Indent . wordwrap(
816+
$Value,
817+
$this->FoldedAt,
818+
"\n" . $ThisDepth . $this->Indent
819+
);
811820
} else {
812-
$ToAdd = $this->scalarToString($Value);
821+
$ToAdd = $this->Quotes . $this->escape($Value) . $this->Quotes;
813822
}
814-
if ($this->DoWithAnchors) {
815-
foreach ($this->Anchors as $Name => $Data) {
816-
if ($Data === $ToAdd) {
817-
if (empty($this->AnchorsDone[$Name])) {
818-
$ToAdd = '&' . $Name . ' ' . $ToAdd;
819-
$this->AnchorsDone[$Name] = true;
820-
} else {
821-
$ToAdd = '*' . $Name;
822-
}
823-
break;
823+
} else {
824+
$ToAdd = $this->scalarToString($Value);
825+
}
826+
if ($this->DoWithAnchors) {
827+
foreach ($this->Anchors as $Name => $Data) {
828+
if ($Data === $ToAdd) {
829+
if (empty($this->AnchorsDone[$Name])) {
830+
$ToAdd = '&' . $Name . ' ' . $ToAdd;
831+
$this->AnchorsDone[$Name] = true;
832+
} else {
833+
$ToAdd = '*' . $Name;
824834
}
835+
break;
825836
}
826837
}
827-
$Out .= $ToAdd . "\n";
828838
}
839+
$Out .= $ToAdd . "\n";
829840
}
830841
}
831842

@@ -1426,6 +1437,12 @@ private function scalarToString($In): string
14261437
if (is_string($In)) {
14271438
return $this->Quotes . $this->escape($In) . $this->Quotes;
14281439
}
1440+
if (is_object($In)) {
1441+
if (method_exists($In, '__toString')) {
1442+
return $this->Quotes . $this->escape((string)$In) . $this->Quotes;
1443+
}
1444+
throw new \Error('Non-stringable object detected while attempting to reconstruct YAML data');
1445+
}
14291446
return $In;
14301447
}
14311448
}

0 commit comments

Comments
 (0)