-
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathCommonAbstract.php
More file actions
105 lines (99 loc) · 4.02 KB
/
CommonAbstract.php
File metadata and controls
105 lines (99 loc) · 4.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
<?php
/**
* Common abstract for the common classes package (last modified: 2026.03.17).
*
* This file is a part of the "common classes package", utilised by a number of
* packages and projects, including CIDRAM and phpMussel.
* @link https://github.com/Maikuolan/Common
*
* License: GNU/GPLv2
* @see LICENSE.txt
*
* "COMMON CLASSES PACKAGE" COPYRIGHT 2019 and beyond by Caleb Mazalevskis.
*/
namespace Maikuolan\Common;
abstract class CommonAbstract
{
/**
* @var string Common Classes Package tag/release version.
* @link https://github.com/Maikuolan/Common/tags
*/
public const VERSION = '2.16.0';
/**
* Traverse data path.
*
* @param mixed $Data The data to traverse.
* @param string|array $Path The path to traverse.
* @param bool $AllowNonScalar Whether to allow non-scalar returns.
* @param bool $AllowMethodCalls Whether to allow method calls.
* @return mixed The traversed data, or an empty string on failure.
*/
public function dataTraverse(&$Data, $Path = [], bool $AllowNonScalar = false, bool $AllowMethodCalls = false)
{
if (!\is_array($Path)) {
$Path = \preg_split('~(?<!\\\\)\\.~', $Path) ?: [];
}
$Segment = \array_shift($Path);
if ($Segment === null || \strlen($Segment) === 0) {
return $AllowNonScalar || \is_scalar($Data) ? $Data : '';
}
$Segment = \str_replace('\.', '.', $Segment);
if ($Data instanceof \Maikuolan\Common\LazyArray) {
$Data->trigger();
$Data = $Data->Data;
}
if (\is_array($Data)) {
if (\preg_match('~^(?:keys|flip|pop|shift)\\(\\)$~i', $Segment)) {
$Segment = 'array_' . \substr($Segment, 0, -2);
$Working = $Segment($Data);
return $this->dataTraverse($Working, $Path, $AllowNonScalar, $AllowMethodCalls);
}
return isset($Data[$Segment]) ? $this->dataTraverse($Data[$Segment], $Path, $AllowNonScalar, $AllowMethodCalls) : '';
}
if (\is_object($Data)) {
if (\property_exists($Data, $Segment)) {
return $this->dataTraverse($Data->$Segment, $Path, $AllowNonScalar, $AllowMethodCalls);
}
if ($AllowMethodCalls && \method_exists($Data, $Segment)) {
$Working = $Data->{$Segment}(...$Path);
return $this->dataTraverse($Working, [], $AllowNonScalar);
}
}
if (
(\is_string($Data) && \preg_match('~^(?:str(?:tolower|toupper|len)|trim)\\(\\)$~i', $Segment)) ||
(\is_numeric($Data) && \preg_match('~^(?:floor|ceil)\\(\\)$~i', $Segment))
) {
$Segment = \substr($Segment, 0, -2);
$Working = $Segment($Data);
return $this->dataTraverse($Working, $Path, $AllowNonScalar, $AllowMethodCalls);
}
return $this->dataTraverse($Data, $Path, $AllowNonScalar, $AllowMethodCalls);
}
/**
* Used to redact sensitive properties from an object's dump.
*
* @return array An object's dumped properties.
*/
public function __debugInfo(): array
{
$Properties = \get_object_vars($this);
/** Attributes available as of PHP >= 8. Properties returned as is for older PHP versions. */
if (!\class_exists('\ReflectionProperty') || !\method_exists('\ReflectionProperty', 'getAttributes')) {
return $Properties;
}
foreach ($Properties as $Property => &$Value) {
$Reflection = new \ReflectionProperty($this, $Property);
$Attributes = $Reflection->getAttributes();
foreach ($Attributes as $Attribute) {
$Name = $Attribute->getName();
if ($Name === 'Maikuolan\Common\Context') {
$Arguments = $Attribute->getArguments();
if (!empty($Arguments['Sensitive'])) {
$Value = $Attribute->newInstance();
}
}
}
}
return $Properties;
}
}