1
|
|
|
<?php |
|
|
|
|
2
|
|
|
/** |
3
|
|
|
* Joomla! component. |
4
|
|
|
* |
5
|
|
|
* @copyright Copyright (C) 2017 Roberto Segura López, Inc. All rights reserved. |
6
|
|
|
* @license GNU/GPL 2, http://www.gnu.org/licenses/gpl-2.0.htm |
7
|
|
|
*/ |
8
|
|
|
|
9
|
|
|
namespace Phproberto\Joomla\Component; |
10
|
|
|
|
11
|
|
|
use Joomla\Registry\Registry; |
12
|
|
|
use Phproberto\Joomla\Traits; |
13
|
|
|
|
14
|
1 |
|
defined('JPATH_PLATFORM') || die; |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* Table finder. |
18
|
|
|
* |
19
|
|
|
* @since __DEPLOY_VERSION__ |
20
|
|
|
*/ |
21
|
|
|
class Component |
22
|
|
|
{ |
23
|
|
|
use Traits\HasExtension, Traits\HasParams; |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* Component option. Example: com_content |
27
|
|
|
* |
28
|
|
|
* @var string |
29
|
|
|
*/ |
30
|
|
|
protected $option; |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* Component prefix for classes, etc. |
34
|
|
|
* |
35
|
|
|
* @var string |
36
|
|
|
*/ |
37
|
|
|
protected $prefix; |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* Cached instances. |
41
|
|
|
* |
42
|
|
|
* @var array |
43
|
|
|
*/ |
44
|
|
|
protected static $instances = array(); |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* Constructor |
48
|
|
|
* |
49
|
|
|
* @param string $option Component option |
50
|
|
|
* |
51
|
|
|
* @throws \InvalidArgumentException |
52
|
|
|
*/ |
53
|
6 |
|
public function __construct($option) |
54
|
|
|
{ |
55
|
6 |
|
$option = trim(strtolower($option)); |
56
|
|
|
|
57
|
6 |
|
if (empty($option)) |
58
|
|
|
{ |
59
|
1 |
|
throw new \InvalidArgumentException(__CLASS__ . ': Empty component option.'); |
60
|
|
|
} |
61
|
|
|
|
62
|
5 |
|
$this->option = $option; |
63
|
5 |
|
} |
64
|
|
|
|
65
|
|
|
/** |
66
|
|
|
* Clear a singleton instance. |
67
|
|
|
* |
68
|
|
|
* @param string $option Component option |
69
|
|
|
* |
70
|
|
|
* @return void |
71
|
|
|
*/ |
72
|
3 |
|
public static function clearInstance($option) |
73
|
|
|
{ |
74
|
3 |
|
unset(static::$instances[get_called_class()][$option]); |
75
|
3 |
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* Get the active component. |
79
|
|
|
* |
80
|
|
|
* @return $this |
81
|
|
|
* |
82
|
|
|
* @throws \InvalidArgumentException |
83
|
|
|
*/ |
84
|
1 |
|
public static function getActive() |
85
|
|
|
{ |
86
|
1 |
|
return static::getInstance(static::getActiveOption()); |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
/** |
90
|
|
|
* Get the active component option. Isolated for testing purposes. |
91
|
|
|
* |
92
|
|
|
* @return string |
93
|
|
|
* |
94
|
|
|
* @codeCoverageIgnore |
95
|
|
|
*/ |
96
|
|
|
protected static function getActiveOption() |
97
|
|
|
{ |
98
|
|
|
return \JApplicationHelper::getComponentName(); |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
/** |
102
|
|
|
* Ensure that we retrieve a non-statically-cached instance. |
103
|
|
|
* |
104
|
|
|
* @param string $option Component option |
105
|
|
|
* |
106
|
|
|
* @return $this |
107
|
|
|
*/ |
108
|
2 |
|
public static function getFreshInstance($option) |
109
|
|
|
{ |
110
|
2 |
|
static::clearInstance($option); |
111
|
|
|
|
112
|
2 |
|
return static::getInstance($option); |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
/** |
116
|
|
|
* Get a singleton instance. |
117
|
|
|
* |
118
|
|
|
* @param string $option Component option |
119
|
|
|
* |
120
|
|
|
* @return $this |
121
|
|
|
*/ |
122
|
10 |
|
public static function getInstance($option) |
123
|
|
|
{ |
124
|
10 |
|
$option = trim(strtolower($option)); |
125
|
|
|
|
126
|
10 |
|
$class = get_called_class(); |
127
|
|
|
|
128
|
10 |
|
if (empty(static::$instances[$class][$option])) |
129
|
|
|
{ |
130
|
5 |
|
static::$instances[$class][$option] = new static($option); |
131
|
|
|
} |
132
|
|
|
|
133
|
10 |
|
return static::$instances[$class][$option]; |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
/** |
137
|
|
|
* Get the component prefix. |
138
|
|
|
* |
139
|
|
|
* @return string |
140
|
|
|
*/ |
141
|
7 |
|
public function getPrefix() |
142
|
|
|
{ |
143
|
7 |
|
if (null === $this->prefix) |
144
|
|
|
{ |
145
|
5 |
|
$parts = array_map( |
146
|
5 |
|
function ($part) |
147
|
|
|
{ |
148
|
5 |
|
return ucfirst(strtolower($part)); |
149
|
5 |
|
}, |
150
|
5 |
|
explode('_', substr($this->option, 4)) |
151
|
|
|
); |
152
|
|
|
|
153
|
5 |
|
$this->prefix = implode('_', $parts); |
154
|
|
|
} |
155
|
|
|
|
156
|
7 |
|
return $this->prefix; |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
/** |
160
|
|
|
* Get a component table. |
161
|
|
|
* |
162
|
|
|
* @param string $name Name of the table to load. Example: Article |
163
|
|
|
* @param array $config Optional array of configuration for the table |
164
|
|
|
* @param boolean $backend Search in backend folder? |
165
|
|
|
* |
166
|
|
|
* @return \JTable |
167
|
|
|
* |
168
|
|
|
* @throws \InvalidArgumentException If table not found |
169
|
|
|
*/ |
170
|
2 |
|
public function getTable($name, array $config = array(), $backend = true) |
171
|
|
|
{ |
172
|
2 |
|
$prefix = $this->getPrefix() . 'Table'; |
173
|
|
|
|
174
|
2 |
|
$baseFolder = $backend ? JPATH_ADMINISTRATOR : JPATH_SITE; |
175
|
|
|
|
176
|
2 |
|
\JTable::addIncludePath($baseFolder . '/components/' . $this->option . '/tables'); |
177
|
|
|
|
178
|
2 |
|
$table = \JTable::getInstance($name, $prefix, $config); |
179
|
|
|
|
180
|
2 |
|
if (!$table instanceof \JTable) |
|
|
|
|
181
|
|
|
{ |
182
|
1 |
|
throw new \InvalidArgumentException( |
183
|
1 |
|
sprintf('Cannot find the table %s in component %s.', $prefix . $name, $this->option) |
184
|
|
|
); |
185
|
|
|
} |
186
|
|
|
|
187
|
1 |
|
return $table; |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
/** |
191
|
|
|
* Load extension from DB. |
192
|
|
|
* |
193
|
|
|
* @return \stdClass |
194
|
|
|
*/ |
195
|
3 |
View Code Duplication |
protected function loadExtension() |
|
|
|
|
196
|
|
|
{ |
197
|
3 |
|
$db = \JFactory::getDbo(); |
198
|
3 |
|
$query = $db->getQuery(true) |
199
|
3 |
|
->select('*') |
200
|
3 |
|
->from('#__extensions') |
201
|
3 |
|
->where('type = ' . $db->quote('component')) |
202
|
3 |
|
->where('element = ' . $db->q($this->option)); |
203
|
|
|
|
204
|
3 |
|
$db->setQuery($query); |
205
|
|
|
|
206
|
3 |
|
return $db->loadObject() ?: new \stdClass; |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
/** |
210
|
|
|
* Load parameters from database. |
211
|
|
|
* |
212
|
|
|
* @return Registry |
213
|
|
|
*/ |
214
|
2 |
|
protected function loadParams() |
215
|
|
|
{ |
216
|
2 |
|
return new Registry($this->getExtensionProperty('params', array())); |
217
|
|
|
} |
218
|
|
|
|
219
|
|
|
/** |
220
|
|
|
* Save parameters to database. |
221
|
|
|
* |
222
|
|
|
* @return Registry |
223
|
|
|
*/ |
224
|
1 |
|
public function saveParams() |
225
|
|
|
{ |
226
|
1 |
|
$db = \JFactory::getDbo(); |
227
|
|
|
|
228
|
1 |
|
$query = $db->getQuery(true) |
229
|
1 |
|
->update('#__extensions') |
230
|
1 |
|
->set('params = ' . $db->q($this->getParams()->toString())) |
231
|
1 |
|
->where('type = ' . $db->quote('component')) |
232
|
1 |
|
->where('element = ' . $db->q($this->option)); |
233
|
|
|
|
234
|
1 |
|
$db->setQuery($query); |
235
|
|
|
|
236
|
1 |
|
return $db->execute() ? true : false; |
237
|
|
|
} |
238
|
|
|
} |
239
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.