DBSiteStore::clear()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 8
nc 2
nop 0
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Represents the site configuration of a wiki.
5
 * Holds a list of sites (ie SiteList), stored in the database.
6
 *
7
 * This program is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 2 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License along
18
 * with this program; if not, write to the Free Software Foundation, Inc.,
19
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
 * http://www.gnu.org/copyleft/gpl.html
21
 *
22
 * @since 1.25
23
 *
24
 * @file
25
 * @ingroup Site
26
 *
27
 * @license GNU GPL v2+
28
 * @author Jeroen De Dauw < [email protected] >
29
 * @author Daniel Kinzler
30
 */
31
class DBSiteStore implements SiteStore {
32
33
	/**
34
	 * @var SiteList|null
35
	 */
36
	protected $sites = null;
37
38
	/**
39
	 * @var LoadBalancer
40
	 */
41
	private $dbLoadBalancer;
42
43
	/**
44
	 * @since 1.27
45
	 *
46
	 * @todo: inject some kind of connection manager that is aware of the target wiki,
47
	 * instead of injecting a LoadBalancer.
48
	 *
49
	 * @param LoadBalancer $dbLoadBalancer
50
	 */
51
	public function __construct( LoadBalancer $dbLoadBalancer ) {
52
		$this->dbLoadBalancer = $dbLoadBalancer;
53
	}
54
55
	/**
56
	 * @see SiteStore::getSites
57
	 *
58
	 * @since 1.25
59
	 *
60
	 * @return SiteList
61
	 */
62
	public function getSites() {
63
		$this->loadSites();
64
65
		return $this->sites;
66
	}
67
68
	/**
69
	 * Fetches the site from the database and loads them into the sites field.
70
	 *
71
	 * @since 1.25
72
	 */
73
	protected function loadSites() {
74
		$this->sites = new SiteList();
75
76
		$dbr = $this->dbLoadBalancer->getConnection( DB_REPLICA );
77
78
		$res = $dbr->select(
79
			'sites',
80
			[
81
				'site_id',
82
				'site_global_key',
83
				'site_type',
84
				'site_group',
85
				'site_source',
86
				'site_language',
87
				'site_protocol',
88
				'site_domain',
89
				'site_data',
90
				'site_forward',
91
				'site_config',
92
			],
93
			'',
94
			__METHOD__,
95
			[ 'ORDER BY' => 'site_global_key' ]
96
		);
97
98
		foreach ( $res as $row ) {
99
			$site = Site::newForType( $row->site_type );
100
			$site->setGlobalId( $row->site_global_key );
101
			$site->setInternalId( (int)$row->site_id );
102
			$site->setForward( (bool)$row->site_forward );
103
			$site->setGroup( $row->site_group );
104
			$site->setLanguageCode( $row->site_language === ''
105
				? null
106
				: $row->site_language
107
			);
108
			$site->setSource( $row->site_source );
109
			$site->setExtraData( unserialize( $row->site_data ) );
110
			$site->setExtraConfig( unserialize( $row->site_config ) );
111
			$this->sites[] = $site;
112
		}
113
114
		// Batch load the local site identifiers.
115
		$ids = $dbr->select(
116
			'site_identifiers',
117
			[
118
				'si_site',
119
				'si_type',
120
				'si_key',
121
			],
122
			[],
123
			__METHOD__
124
		);
125
126
		foreach ( $ids as $id ) {
127
			if ( $this->sites->hasInternalId( $id->si_site ) ) {
128
				$site = $this->sites->getSiteByInternalId( $id->si_site );
129
				$site->addLocalId( $id->si_type, $id->si_key );
130
				$this->sites->setSite( $site );
0 ignored issues
show
Unused Code introduced by
The call to the method SiteList::setSite() seems un-needed as the method has no side-effects.

PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left.

Let’s take a look at an example:

class User
{
    private $email;

    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }
}

If we look at the getEmail() method, we can see that it has no side-effect. Whether you call this method or not, no future calls to other methods are affected by this. As such code as the following is useless:

$user = new User();
$user->getEmail(); // This line could safely be removed as it has no effect.

On the hand, if we look at the setEmail(), this method _has_ side-effects. In the following case, we could not remove the method call:

$user = new User();
$user->setEmail('email@domain'); // This line has a side-effect (it changes an
                                 // instance variable).
Loading history...
131
			}
132
		}
133
	}
134
135
	/**
136
	 * @see SiteStore::getSite
137
	 *
138
	 * @since 1.25
139
	 *
140
	 * @param string $globalId
141
	 *
142
	 * @return Site|null
143
	 */
144
	public function getSite( $globalId ) {
145
		if ( $this->sites === null ) {
146
			$this->sites = $this->getSites();
147
		}
148
149
		return $this->sites->hasSite( $globalId ) ? $this->sites->getSite( $globalId ) : null;
150
	}
151
152
	/**
153
	 * @see SiteStore::saveSite
154
	 *
155
	 * @since 1.25
156
	 *
157
	 * @param Site $site
158
	 *
159
	 * @return bool Success indicator
160
	 */
161
	public function saveSite( Site $site ) {
162
		return $this->saveSites( [ $site ] );
163
	}
164
165
	/**
166
	 * @see SiteStore::saveSites
167
	 *
168
	 * @since 1.25
169
	 *
170
	 * @param Site[] $sites
171
	 *
172
	 * @return bool Success indicator
173
	 */
174
	public function saveSites( array $sites ) {
175
		if ( empty( $sites ) ) {
176
			return true;
177
		}
178
179
		$dbw = $this->dbLoadBalancer->getConnection( DB_MASTER );
180
181
		$dbw->startAtomic( __METHOD__ );
182
183
		$success = true;
184
185
		$internalIds = [];
186
		$localIds = [];
187
188
		foreach ( $sites as $site ) {
189
			if ( $site->getInternalId() !== null ) {
190
				$internalIds[] = $site->getInternalId();
191
			}
192
193
			$fields = [
194
				// Site data
195
				'site_global_key' => $site->getGlobalId(), // TODO: check not null
196
				'site_type' => $site->getType(),
197
				'site_group' => $site->getGroup(),
198
				'site_source' => $site->getSource(),
199
				'site_language' => $site->getLanguageCode() === null ? '' : $site->getLanguageCode(),
200
				'site_protocol' => $site->getProtocol(),
201
				'site_domain' => strrev( $site->getDomain() ) . '.',
202
				'site_data' => serialize( $site->getExtraData() ),
203
204
				// Site config
205
				'site_forward' => $site->shouldForward() ? 1 : 0,
206
				'site_config' => serialize( $site->getExtraConfig() ),
207
			];
208
209
			$rowId = $site->getInternalId();
210
			if ( $rowId !== null ) {
211
				$success = $dbw->update(
212
					'sites', $fields, [ 'site_id' => $rowId ], __METHOD__
213
				) && $success;
214
			} else {
215
				$rowId = $dbw->nextSequenceValue( 'sites_site_id_seq' );
216
				$fields['site_id'] = $rowId;
217
				$success = $dbw->insert( 'sites', $fields, __METHOD__ ) && $success;
218
				$rowId = $dbw->insertId();
219
			}
220
221 View Code Duplication
			foreach ( $site->getLocalIds() as $idType => $ids ) {
222
				foreach ( $ids as $id ) {
223
					$localIds[] = [ $rowId, $idType, $id ];
224
				}
225
			}
226
		}
227
228
		if ( $internalIds !== [] ) {
229
			$dbw->delete(
230
				'site_identifiers',
231
				[ 'si_site' => $internalIds ],
232
				__METHOD__
233
			);
234
		}
235
236
		foreach ( $localIds as $localId ) {
237
			$dbw->insert(
238
				'site_identifiers',
239
				[
240
					'si_site' => $localId[0],
241
					'si_type' => $localId[1],
242
					'si_key' => $localId[2],
243
				],
244
				__METHOD__
245
			);
246
		}
247
248
		$dbw->endAtomic( __METHOD__ );
249
250
		$this->reset();
251
252
		return $success;
253
	}
254
255
	/**
256
	 * Resets the SiteList
257
	 *
258
	 * @since 1.25
259
	 */
260
	public function reset() {
261
		$this->sites = null;
262
	}
263
264
	/**
265
	 * Clears the list of sites stored in the database.
266
	 *
267
	 * @see SiteStore::clear()
268
	 *
269
	 * @return bool Success
270
	 */
271
	public function clear() {
272
		$dbw = $this->dbLoadBalancer->getConnection( DB_MASTER );
273
274
		$dbw->startAtomic( __METHOD__ );
275
		$ok = $dbw->delete( 'sites', '*', __METHOD__ );
276
		$ok = $dbw->delete( 'site_identifiers', '*', __METHOD__ ) && $ok;
277
		$dbw->endAtomic( __METHOD__ );
278
279
		$this->reset();
280
281
		return $ok;
282
	}
283
284
}
285