PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backup, Restore, Migration & Clone / 3.8.2
WP STAGING – WordPress Backup, Restore, Migration & Clone v3.8.2
4.9.1 4.9.0 4.8.1 trunk 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.10.0 3.2.0 3.3.1 3.3.2 3.3.3 3.4.1 3.4.3 3.5.0 3.6.0 3.7.1 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.8.6 3.8.7 3.9.0 3.9.1 3.9.2 3.9.3 3.9.4 4.0.0 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.0 4.7.0 4.7.1 4.7.2 4.7.3 4.8.0
wp-staging / Framework / Traits / HydrateTrait.php
wp-staging / Framework / Traits Last commit date
ArrayableTrait.php 2 years ago BenchmarkTrait.php 2 years ago BooleanTransientTrait.php 5 years ago DatabaseSearchReplaceTrait.php 2 years ago DbRowsGeneratorTrait.php 3 years ago DeveloperTimerTrait.php 4 years ago EndOfLinePlaceholderTrait.php 2 years ago EventLoggerTrait.php 1 year ago FileScanToCacheTrait.php 2 years ago HydrateTrait.php 2 years ago MaintenanceTrait.php 5 years ago MemoryExhaustTrait.php 2 years ago MySQLRowsGeneratorTrait.php 2 years ago NoticesTrait.php 2 years ago PropertyConstructor.php 5 years ago ResourceTrait.php 2 years ago ValueGetterTrait.php 1 year ago
HydrateTrait.php
147 lines
1 <?php
2
3 // TODO PHP7.x; declare(strict_types=1);
4 // TODO PHP7.x type-hints & return types
5
6 namespace WPStaging\Framework\Traits;
7
8 use DateTime;
9 use Exception;
10 use ReflectionClass;
11 use ReflectionException;
12 use ReflectionMethod;
13 use TypeError;
14 use WPStaging\Core\WPStaging;
15 use WPStaging\Framework\Adapter\DateTimeAdapter;
16
17 use function WPStaging\functions\debug_log;
18
19 trait HydrateTrait
20 {
21 /** @var string[] */
22 protected $excludeHydrate = [];
23
24 /**
25 * @param array $data
26 * @return $this
27 * @noinspection PhpDocMissingThrowsInspection
28 */
29 public function hydrate(array $data = [])
30 {
31 foreach ($data as $key => $value) {
32 // Let the child class decide which properties to exclude including the excludeHydrate property itself.
33 $propertiesToExclude = array_merge($this->excludeHydrate, ['excludeHydrate']);
34 if (in_array($key, $propertiesToExclude, true)) {
35 continue;
36 }
37
38 /** @noinspection PhpUnhandledExceptionInspection */
39 try {
40 $this->hydrateByMethod('set' . ucfirst($key), $value);
41 } catch (TypeError $e) {
42 $this->debugLog($e->getMessage());
43 } catch (Exception $e) {
44 $this->debugLog($e->getMessage());
45 }
46 }
47
48 return $this;
49 }
50
51 /**
52 * Use to hydrate public properties
53 * @param array $data
54 * @return $this
55 * @noinspection PhpDocMissingThrowsInspection
56 */
57 public function hydrateProperties(array $data = [])
58 {
59 foreach ($data as $key => $value) {
60 if (!property_exists($this, $key)) {
61 $this->debugLog("Trying to hydrate DTO with property that does not exist. {$key}");
62 continue;
63 }
64
65 $this->{$key} = $value;
66 }
67
68 return $this;
69 }
70
71 protected function debugLog($message)
72 {
73 if (WPStaging::areLogsSilenced()) {
74 return;
75 }
76
77 debug_log($message);
78 }
79
80 /**
81 * @param string $method
82 * @param mixed $value
83 *
84 * @throws ReflectionException
85 */
86 private function hydrateByMethod($method, $value)
87 {
88 if (!method_exists($this, $method)) {
89 if (!is_string($value)) {
90 $value = wp_json_encode($value, JSON_UNESCAPED_SLASHES);
91 }
92
93 throw new Exception(sprintf("Trying to hydrate DTO with value that does not exist. %s::%s(%s)", get_class($this), $method, $value));
94 }
95
96 /** @noinspection CallableParameterUseCaseInTypeContextInspection */
97 $method = new ReflectionMethod($this, $method);
98
99 $params = $method->getParameters();
100
101 if (!isset($params[0]) || count($params) > 1) {
102 throw new Exception(sprintf(
103 'Class %s setter method %s does not have a first parameter or has more than one parameter',
104 static::class,
105 $method
106 ));
107 }
108
109 $param = $params[0];
110
111 if (defined('PHP_VERSION_ID') && PHP_VERSION_ID >= 80000) {
112 $class = $param->getType() && !$param->getType()->isBuiltin() ? new ReflectionClass($param->getType()->getName()) : null;
113 } else {
114 $class = $param->getClass();
115 }
116
117 if (!$value || !$class) {
118 $method->invoke($this, $value);
119 return;
120 }
121
122 /** @noinspection PhpUnhandledExceptionInspection */
123 $method->invoke($this, $this->getClassAsValue($class, $value));
124 }
125
126 /**
127 * @param ReflectionClass $class
128 * @param mixed $value
129 * @return object
130 * @throws Exception
131 */
132 private function getClassAsValue(ReflectionClass $class, $value)
133 {
134 $className = $class->getName();
135 if (!$value instanceof DateTime && $className === 'DateTime') {
136 return (new DateTimeAdapter())->getDateTime($value);
137 }
138
139 $obj = new $className();
140 if (is_array($value) && method_exists($obj, 'hydrate')) {
141 $obj->hydrate($value);
142 }
143
144 return $obj;
145 }
146 }
147