class-otgs-template-service-php-model.php
2.76 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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<?php
class OTGS_Template_Service_Php_Model {
/**
* @var OTGS_Template_Service_Php_Model[]|mixed[]
*/
private $attributes = [];
/**
* @param array $data
*/
public function __construct( $data = [] ) {
foreach ( $data as $key => $value ) {
$this->__set( $key, $value );
}
}
/**
* If a property does not exist, the method will create it as an "empty" instance of `Model`
* so that children properties can be called without throwing errors.
*
* @param string $name
*
* @return mixed|null
* @see OTGS_Template_Service_Php_Model::__toString
*/
public function __get( $name ) {
if ( ! array_key_exists( $name, $this->attributes ) ) {
$this->attributes[ $name ] = new OTGS_Template_Service_Php_Model();
}
return $this->attributes[ $name ];
}
/**
* It ensures that $value is always either an array or a primitive type.
*
* @param string $name
* @param mixed $value
*/
public function __set( $name, $value ) {
if ( is_object( $value ) ) {
$value = get_object_vars( $value );
}
if ( is_array( $value ) ) {
if( $this->isAssoc( $value ) ) {
$value = new OTGS_Template_Service_Php_Model( $value );
} else {
foreach ($value as $id => $element) {
$value[$id] = $this->isAssoc( $element ) ? new OTGS_Template_Service_Php_Model( $element ) : $element;
}
}
}
$this->attributes[ $name ] = $value;
}
/**
* @param mixed $value
*
* @return bool
*/
private function isAssoc( $value ) {
return is_array( $value ) && count( array_filter( array_keys( $value ), 'is_string' ) ) > 0;
}
/**
* @param string $name
*
* @return bool
*/
public function hasValue( $name ) {
return ! $this->isNull( $name ) && ! $this->isEmpty( $name );
}
/**
* @param string $name
*
* @return bool
*/
public function isNull( $name ) {
return $this->__get( $name ) === null;
}
/**
* @param string $name
*
* @return bool
*/
public function isEmpty( $name ) {
return $this->__get( $name ) === ''
|| ( ( $this->__get( $name ) instanceof OTGS_Template_Service_Php_Model )
&& ! $this->__get( $name )->getAttributes()
);
}
/**
* @return mixed[]|OTGS_Template_Service_Php_Model[]
*/
public function getAttributes() {
return $this->attributes;
}
/**
* This logic allows using the model in a template even when referring to properties which do no exist.
*
* Example:
* `<h1><?php echo esc_html( $model->non_existing_property->title ); ?></h1>` Will output an empty string instead of throwing an error
*
* @return string
*/
public function __toString() {
if ( count( $this->attributes ) === 0 ) {
return '';
}
if ( count( $this->attributes ) === 1 ) {
return array_values( $this->attributes )[0];
}
return wp_json_encode( $this->attributes );
}
}