1
|
|
|
<?php /** MicroDetailViewWidget */ |
2
|
|
|
namespace Micro\Widget; |
3
|
|
|
|
4
|
|
|
use Micro\Base\Exception; |
5
|
|
|
use Micro\Mvc\Models\IModel; |
6
|
|
|
use Micro\Mvc\Models\IQuery; |
7
|
|
|
use Micro\Mvc\Widget; |
8
|
|
|
use Micro\Web\Html; |
9
|
|
|
|
10
|
|
|
/** |
11
|
|
|
* DetailViewWidget class file. |
12
|
|
|
* |
13
|
|
|
* @author Oleg Lunegov <[email protected]> |
14
|
|
|
* @link https://github.com/lugnsk/micro |
15
|
|
|
* @copyright Copyright © 2013 Oleg Lunegov |
16
|
|
|
* @license /LICENSE |
17
|
|
|
* @package Micro |
18
|
|
|
* @subpackage Widget |
19
|
|
|
* @version 1.0 |
20
|
|
|
* @since 1.0 |
21
|
|
|
*/ |
22
|
|
|
class DetailViewWidget extends Widget |
23
|
|
|
{ |
24
|
|
|
/** @var array $columns Rendered columns */ |
25
|
|
|
public $columns; |
26
|
|
|
/** @var array $attributes attributes for dl */ |
27
|
|
|
public $attributes = []; |
28
|
|
|
/** @var array $attributesElement attributes for dt */ |
29
|
|
|
public $attributesElement = []; |
30
|
|
|
/** @var array $attributesValue attributes for dd */ |
31
|
|
|
public $attributesValue = []; |
32
|
|
|
/** @var array $attributeLabels labels for attributes */ |
33
|
|
|
public $attributeLabels = []; |
34
|
|
|
|
35
|
|
|
/** @var array $keys Data keys */ |
36
|
|
|
protected $keys; |
37
|
|
|
/** @var mixed $data Data source */ |
38
|
|
|
protected $data; |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* Redeclare constructor, generate keys and data |
42
|
|
|
* |
43
|
|
|
* @access public |
44
|
|
|
* |
45
|
|
|
* @param array $args Arguments |
46
|
|
|
* |
47
|
|
|
* @result void |
48
|
|
|
* @throws \Micro\base\Exception |
49
|
|
|
*/ |
50
|
|
|
public function __construct(array $args = []) |
51
|
|
|
{ |
52
|
|
|
parent::__construct($args); |
53
|
|
|
|
54
|
|
|
if (empty($args['data'])) { |
55
|
|
|
throw new Exception('Argument "data" not initialized into DetailViewWidget'); |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
switch (gettype($args['data'])) { |
59
|
|
|
case 'array': |
60
|
|
|
$this->data = (object)$args['data']; |
61
|
|
|
$this->keys = array_keys($args['data']); |
62
|
|
|
break; |
63
|
|
|
|
64
|
|
|
case 'object': |
65
|
|
|
if ($args['data'] instanceof IQuery) { |
66
|
|
View Code Duplication |
if ($args['data']->objectName) { |
|
|
|
|
67
|
|
|
/** @var IModel $cls */ |
68
|
|
|
$cls = $args['data']->objectName; |
|
|
|
|
69
|
|
|
$args['data']->table = $cls::tableName(); |
|
|
|
|
70
|
|
|
} elseif (!$args['data']->table) { |
|
|
|
|
71
|
|
|
throw new Exception('Data query not set table or objectName'); |
72
|
|
|
} |
73
|
|
|
$this->data = $args['data']->run(); |
74
|
|
|
} elseif (is_subclass_of($args['data'], 'Micro\\Mvc\\Models\\Model')) { |
75
|
|
|
$this->data = $args['data']; |
76
|
|
|
} else { |
77
|
|
|
throw new Exception('Argument "model" not supported type into DetailViewWidget'); |
78
|
|
|
} |
79
|
|
|
$this->keys = $this->data->getAttributes(); |
80
|
|
|
break; |
81
|
|
|
|
82
|
|
|
default: |
83
|
|
|
throw new Exception('Argument "model" not supported type into DetailViewWidget'); |
84
|
|
|
} |
85
|
|
|
if (empty($args['columns'])) { |
86
|
|
|
$this->columns = $this->keys; |
87
|
|
|
} |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
/** |
91
|
|
|
* Prepare selected rows |
92
|
|
|
* |
93
|
|
|
* @access public |
94
|
|
|
* |
95
|
|
|
* @return void |
96
|
|
|
* @throws Exception |
97
|
|
|
*/ |
98
|
|
|
public function init() |
99
|
|
|
{ |
100
|
|
|
$result = []; |
101
|
|
|
|
102
|
|
|
// обходим заданные параметры |
103
|
|
|
foreach ($this->columns AS $key => $val) { |
104
|
|
|
$data = []; |
105
|
|
|
|
106
|
|
|
// если параметр число и вал строка - это ключ |
107
|
|
|
if (is_int($key) && is_string($val)) { |
108
|
|
|
$column = $val; |
109
|
|
|
// если параметр строка и вал массив - is good |
110
|
|
|
} elseif (is_string($key) && is_array($val)) { |
111
|
|
|
$column = $key; |
112
|
|
|
} else { |
113
|
|
|
throw new Exception('Unknown `data` format into DetailViewWidget'); |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
$result[] = [ |
117
|
|
|
'title' => !empty($data['title']) ? $data['title'] : ucfirst(method_exists($this->data, |
118
|
|
|
'getLabel') ? $this->data->getLabel($column) : $column), |
119
|
|
|
'type' => !empty($data['type']) ? $data['type'] : 'text', |
120
|
|
|
'value' => !empty($data['value']) ? $data['value'] : $this->data->{$column} |
121
|
|
|
]; |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
$this->columns = $result; |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
/** |
128
|
|
|
* Run drawing |
129
|
|
|
* |
130
|
|
|
* @access public |
131
|
|
|
* |
132
|
|
|
* @return void |
133
|
|
|
*/ |
134
|
|
|
public function run() |
135
|
|
|
{ |
136
|
|
|
$result = Html::openTag('dl', $this->attributes); |
137
|
|
|
|
138
|
|
|
foreach ($this->columns AS $key => $val) { |
139
|
|
|
$result .= Html::openTag('dt', $this->attributesElement); |
140
|
|
|
$result .= $val['title']; |
141
|
|
|
$result .= Html::closeTag('dt'); |
142
|
|
|
$result .= Html::openTag('dd', $this->attributesValue); |
143
|
|
|
|
144
|
|
|
$buffer = ''; |
145
|
|
|
/** @noinspection DegradedSwitchInspection */ |
146
|
|
|
switch ($val['type']) { |
147
|
|
|
case 'raw': |
148
|
|
|
/** @noinspection OnlyWritesOnParameterInspection */ |
149
|
|
|
/** @noinspection PhpUnusedLocalVariableInspection */ |
150
|
|
|
$data = $this->data; // for eval |
|
|
|
|
151
|
|
|
$buffer .= eval('return ' . $val['value']); |
|
|
|
|
152
|
|
|
break; |
153
|
|
|
|
154
|
|
|
default: |
155
|
|
|
if (property_exists($this->data, $val['value'])) { |
156
|
|
|
$buffer .= htmlspecialchars($this->data->{$val['value']}); |
157
|
|
|
} else { |
158
|
|
|
$buffer .= htmlspecialchars($val['value']); |
159
|
|
|
} |
160
|
|
|
} |
161
|
|
|
|
162
|
|
|
$result .= (strlen($buffer) ? $buffer : ' ') . Html::closeTag('dd'); |
163
|
|
|
} |
164
|
|
|
|
165
|
|
|
echo $result, Html::closeTag('dl'); |
166
|
|
|
} |
167
|
|
|
} |
168
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.