Completed
Push — master ( 658f80...3de8bf )
by Steve
20:06 queued 10:55
created

ElggSite::__get()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 6
ccs 4
cts 4
cp 1
crap 2
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * A Site entity.
4
 *
5
 * \ElggSite represents a single site entity.
6
 *
7
 * An \ElggSite object is an \ElggEntity child class with the subtype
8
 * of "site."  It is created upon installation and holds information about a site:
9
 *  - name
10
 *  - description
11
 *  - url
12
 *
13
 * Every \ElggEntity belongs to a site.
14
 *
15
 * @note Internal: \ElggSite represents a single row from the sites_entity
16
 * table, as well as the corresponding \ElggEntity row from the entities table.
17
 *
18
 * @warning Multiple site support isn't fully developed.
19
 *
20
 * @package    Elgg.Core
21
 * @subpackage DataMode.Site
22
 * @link       http://learn.elgg.org/en/stable/design/database.html
23
 *
24
 * @property      string $name        The name or title of the website
25
 * @property      string $description A motto, mission statement, or description of the website
26
 * @property-read string $url         The root web address for the site, including trailing slash
27
 */
28
class ElggSite extends \ElggEntity {
29
30
	/**
31
	 * Initialize the attributes array.
32
	 * This is vital to distinguish between metadata and base attributes.
33
	 *
34
	 * @return void
35
	 */
36 4
	protected function initializeAttributes() {
37 4
		parent::initializeAttributes();
38
39 4
		$this->attributes['type'] = "site";
40 4
		$this->attributes += self::getExternalAttributes();
41 4
	}
42
43
	/**
44
	 * Get default values for attributes stored in a separate table
45
	 *
46
	 * @return array
47
	 * @access private
48
	 *
49
	 * @see \Elgg\Database\EntityTable::getEntities
50
	 */
51 4
	final public static function getExternalAttributes() {
52
		return [
53 4
			'name' => null,
54
			'description' => null,
55
			'url' => null,
56
		];
57
	}
58
59
	/**
60
	 * Create a new \ElggSite.
61
	 *
62
	 * Plugin developers should only use the constructor to create a new entity.
63
	 * To retrieve entities, use get_entity() and the elgg_get_entities* functions.
64
	 *
65
	 * @param \stdClass $row Database row result. Default is null to create a new site.
66
	 *
67
	 * @throws IOException If cannot load remaining data from db
68
	 * @throws InvalidParameterException If not passed a db result
69
	 */
70 4 View Code Duplication
	public function __construct(\stdClass $row = null) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
71 4
		$this->initializeAttributes();
72
73 4
		if ($row) {
74
			// Load the rest
75
			if (!$this->load($row)) {
76
				$msg = "Failed to load new " . get_class() . " for GUID:" . $row->guid;
77
				throw new \IOException($msg);
78
			}
79
		}
80 4
	}
81
82
	/**
83
	 * {@inheritdoc}
84
	 */
85
	public function save() {
86
		$db = $this->getDatabase();
87
		$rows = $db->getDataRow("
88
			SELECT guid FROM {$db->prefix}sites_entity
89
		");
90
		if ($rows) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $rows of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
91
			if ($rows[0]->guid == $this->attributes['guid']) {
92
				// can save active site
93
				return parent::save();
0 ignored issues
show
Bug Compatibility introduced by
The expression parent::save(); of type boolean|integer adds the type integer to the return on line 93 which is incompatible with the return type declared by the abstract method ElggData::save of type boolean.
Loading history...
94
			}
95
96
			_elgg_services()->logger->error('More than 1 site entity cannot be created.');
97
			return false;
98
		}
99
100
		return parent::save(); // TODO: Change the autogenerated stub
0 ignored issues
show
Bug Compatibility introduced by
The expression parent::save(); of type boolean|integer adds the type integer to the return on line 100 which is incompatible with the return type declared by the abstract method ElggData::save of type boolean.
Loading history...
101
	}
102
103
	/**
104
	 * Loads the full \ElggSite when given a guid.
105
	 *
106
	 * @param mixed $guid GUID of \ElggSite entity or database row object
107
	 *
108
	 * @return bool
109
	 * @throws InvalidClassException
110
	 */
111 View Code Duplication
	protected function load($guid) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
112
		// TODO(steve) we only have 1 site, simplify this...
113
		$attr_loader = new \Elgg\AttributeLoader(get_class(), 'site', $this->attributes);
114
		$attr_loader->requires_access_control = !($this instanceof \ElggPlugin);
115
		$attr_loader->secondary_loader = 'get_site_entity_as_row';
116
117
		$attrs = $attr_loader->getRequiredAttributes($guid);
118
		if (!$attrs) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $attrs of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
119
			return false;
120
		}
121
122
		$this->attributes = $attrs;
123
		$this->loadAdditionalSelectValues($attr_loader->getAdditionalSelectValues());
124
		_elgg_services()->entityCache->set($this);
125
126
		return true;
127
	}
128
129
	/**
130
	 * {@inheritdoc}
131
	 */
132
	protected function create() {
133
		$guid = parent::create();
134
		$db = $this->getDatabase();
135
136
		$query = "
137
			INSERT INTO {$db->prefix}sites_entity
138
			(guid, name, description, url) VALUES (:guid, :name, :desc, :url)
139
		";
140
		$params = [
141
			':guid' => $guid,
142
			':name' => (string) $this->attributes['name'],
143
			':desc' => (string) $this->attributes['description'],
144
			':url' => '',
145
		];
146
147
		$result = $db->insertData($query, $params);
148
		if ($result === false) {
149
			return false;
150
		}
151
152
		return $guid;
153
	}
154
155
	/**
156
	 * {@inheritdoc}
157
	 */
158
	protected function update() {
159
		if (!parent::update()) {
160
			return false;
161
		}
162
163
		$guid = (int) $this->guid;
164
		$db = $this->getDatabase();
165
166
		$query = "
167
			UPDATE {$db->prefix}sites_entity
168
			SET name = :name, description = :desc, url = :url WHERE guid = :guid
169
		";
170
		$params = [
171
			':guid' => $guid,
172
			':name' => (string) $this->attributes['name'],
173
			':desc' => (string) $this->attributes['description'],
174
			':url' => '',
175
		];
176
177
		return $db->updateData($query, false, $params) !== false;
178
	}
179
180
	/**
181
	 * Delete the site.
182
	 *
183
	 * @note You cannot delete the current site.
184
	 *
185
	 * @return bool
186
	 * @throws SecurityException
187
	 */
188
	public function delete() {
189
		global $CONFIG;
190
		if ($CONFIG->site->getGUID() == $this->guid) {
191
			throw new \SecurityException('You cannot delete the current site');
192
		}
193
194
		return parent::delete();
195
	}
196
197
	/**
198
	 * Disable the site
199
	 *
200
	 * @note You cannot disable the current site.
201
	 *
202
	 * @param string $reason    Optional reason for disabling
203
	 * @param bool   $recursive Recursively disable all contained entities?
204
	 *
205
	 * @return bool
206
	 * @throws SecurityException
207
	 */
208
	public function disable($reason = "", $recursive = true) {
209
		if ($this->guid == 1) {
210
			throw new \SecurityException('You cannot disable the current site');
211
		}
212
213
		return parent::disable($reason, $recursive);
214
	}
215
216
	/**
217
	 * {@inheritdoc}
218
	 */
219 2
	public function __set($name, $value) {
220 2
		if ($name === 'url') {
221 1
			_elgg_services()->logger->warn("ElggSite::url cannot be set");
222 1
			return;
223
		}
224 1
		parent::__set($name, $value);
225 1
	}
226
227
	/**
228
	 * {@inheritdoc}
229
	 */
230 3
	public function __get($name) {
231 3
		if ($name === 'url') {
232 2
			return $this->getURL();
233
		}
234 2
		return parent::__get($name);
235
	}
236
237
	/**
238
	 * Returns the URL for this site
239
	 *
240
	 * @return string The URL
241
	 */
242 2
	public function getURL() {
243 2
		return _elgg_services()->config->getSiteUrl();
244
	}
245
246
	/**
247
	 * {@inheritdoc}
248
	 */
249
	public function getDisplayName() {
250
		return $this->name;
251
	}
252
253
	/**
254
	 * {@inheritdoc}
255
	 */
256
	public function setDisplayName($displayName) {
257
		$this->name = $displayName;
258
	}
259
260
	/**
261
	 * {@inheritdoc}
262
	 */
263 View Code Duplication
	protected function prepareObject($object) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
264
		$object = parent::prepareObject($object);
265
		$object->name = $this->getDisplayName();
266
		$object->description = $this->description;
267
		unset($object->read_access);
268
		return $object;
269
	}
270
271
	/**
272
	 * Get the domain for this site
273
	 *
274
	 * @return string
275
	 * @since 1.9
276
	 */
277 1
	public function getDomain() {
278 1
		$breakdown = parse_url($this->url);
279 1
		return $breakdown['host'];
280
	}
281
282
	/**
283
	 * Get the email address for the site
284
	 *
285
	 * This can be set in the basic site settings or fallback to noreply@domain
286
	 *
287
	 * @return string
288
	 * @since 3.0.0
289
	 */
290 2
	public function getEmailAddress() {
291 2
		$email = $this->email;
292 2
		if (empty($email)) {
293 1
			$email = "noreply@{$this->getDomain()}";
294
		}
295
296 2
		return $email;
297
	}
298
}
299