PluginProbe
User Access Manager / 2.0.3
User Access Manager v2.0.3
2.3.20 2.3.19 2.3.18 2.3.17 2.3.16 2.3.15 2.3.14 2.3.13 trunk 0.6 0.6.1 0.6.2 0.7 0.7 Beta 0.7.0.1 0.8 0.8.0.1 0.8.0.2 0.9 0.9.1 0.9.1.1 0.9.1.2 0.9.1.3 0.9.1.4 1.0 All 136 releases
user-access-manager / src / UserAccessManager / SetupHandler / SetupHandler.php

SetupHandler.php in User Access Manager 2.0.3, at src/UserAccessManager/SetupHandler/SetupHandler.php

565 lines 18.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * SetupHandler.php
4 *
5 * The SetupHandler class file.
6 *
7 * PHP versions 5
8 *
9 * @author Alexander Schneider <alexanderschneider85@gmail.com>
10 * @copyright 2008-2017 Alexander Schneider
11 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2
12 * @version SVN: $id$
13 * @link http://wordpress.org/extend/plugins/user-access-manager/
14 */
15 namespace UserAccessManager\SetupHandler;
16
17 use UserAccessManager\Config\Config;
18 use UserAccessManager\Database\Database;
19 use UserAccessManager\FileHandler\FileHandler;
20 use UserAccessManager\ObjectHandler\ObjectHandler;
21 use UserAccessManager\UserAccessManager;
22 use UserAccessManager\Wrapper\Wordpress;
23
24 /**
25 * Class SetupHandler
26 *
27 * @package UserAccessManager\SetupHandler
28 */
29 class SetupHandler
30 {
31 /**
32 * @var Wordpress
33 */
34 private $wordpress;
35
36 /**
37 * @var Database
38 */
39 private $database;
40
41 /**
42 * @var ObjectHandler
43 */
44 private $objectHandler;
45
46 /**
47 * @var FileHandler
48 */
49 private $fileHandler;
50
51 /**
52 * SetupHandler constructor.
53 *
54 * @param Wordpress $wordpress
55 * @param Database $database
56 * @param ObjectHandler $objectHandler
57 * @param FileHandler $fileHandler
58 */
59 public function __construct(
60 Wordpress $wordpress,
61 Database $database,
62 ObjectHandler $objectHandler,
63 FileHandler $fileHandler
64 ) {
65 $this->wordpress = $wordpress;
66 $this->database = $database;
67 $this->objectHandler = $objectHandler;
68 $this->fileHandler = $fileHandler;
69 }
70
71 /**
72 * Returns all blog of the network.
73 *
74 * @return array
75 */
76 public function getBlogIds()
77 {
78 $currentBlogId = $this->database->getCurrentBlogId();
79 $blogIds = [$currentBlogId => $currentBlogId];
80 $sites = $this->wordpress->getSites();
81
82 foreach ($sites as $site) {
83 $blogIds[$site->blog_id] = $site->blog_id;
84 }
85
86 return $blogIds;
87 }
88
89 /**
90 * Installs the user access manager.
91 *
92 * @param bool $networkWide
93 */
94 public function install($networkWide = false)
95 {
96 if ($networkWide === true) {
97 $blogIds = $this->getBlogIds();
98 $currentBlogId = $this->database->getCurrentBlogId();
99
100 foreach ($blogIds as $blogId) {
101 $this->wordpress->switchToBlog($blogId);
102 $this->runInstall();
103 }
104
105 $this->wordpress->switchToBlog($currentBlogId);
106 } else {
107 $this->runInstall();
108 }
109 }
110
111 /**
112 * Creates the needed tables at the database and adds the options
113 */
114 private function runInstall()
115 {
116 $charsetCollate = $this->database->getCharset();
117 $dbAccessGroupTable = $this->database->getUserGroupTable();
118
119 $dbUserGroup = $this->database->getVariable(
120 "SHOW TABLES
121 LIKE '{$dbAccessGroupTable}'"
122 );
123
124 if ($dbUserGroup !== $dbAccessGroupTable) {
125 $this->database->dbDelta(
126 "CREATE TABLE {$dbAccessGroupTable} (
127 ID INT(11) NOT NULL AUTO_INCREMENT,
128 groupname TINYTEXT NOT NULL,
129 groupdesc TEXT NOT NULL,
130 read_access TINYTEXT NOT NULL,
131 write_access TINYTEXT NOT NULL,
132 ip_range MEDIUMTEXT NULL,
133 PRIMARY KEY (ID)
134 ) {$charsetCollate};"
135 );
136 }
137
138 $dbAccessGroupToObjectTable = $this->database->getUserGroupToObjectTable();
139
140 $dbAccessGroupToObject = (string)$this->database->getVariable(
141 "SHOW TABLES
142 LIKE '".$dbAccessGroupToObjectTable."'"
143 );
144
145 if ($dbAccessGroupToObject !== $dbAccessGroupToObjectTable) {
146 $this->database->dbDelta(
147 "CREATE TABLE {$dbAccessGroupToObjectTable} (
148 object_id VARCHAR(64) NOT NULL,
149 general_object_type VARCHAR(64) NOT NULL,
150 object_type VARCHAR(64) NOT NULL,
151 group_id INT(11) NOT NULL,
152 PRIMARY KEY (object_id,object_type,group_id)
153 ) {$charsetCollate};"
154 );
155 }
156
157 $this->wordpress->addOption('uam_db_version', UserAccessManager::DB_VERSION);
158 }
159
160 /**
161 * Checks if a database update is necessary.
162 *
163 * @return bool
164 */
165 public function isDatabaseUpdateNecessary()
166 {
167 $blogIds = $this->getBlogIds();
168
169 if ($this->wordpress->isSuperAdmin() === true) {
170 foreach ($blogIds as $blogId) {
171 $table = $this->database->getBlogPrefix($blogId).'options';
172 $select = "SELECT option_value FROM {$table} WHERE option_name = '%s' LIMIT 1";
173 $select = $this->database->prepare($select, 'uam_db_version');
174 $currentDbVersion = $this->database->getVariable($select);
175
176 if (version_compare($currentDbVersion, UserAccessManager::DB_VERSION, '<') === true) {
177 return true;
178 }
179 }
180 }
181
182 $currentDbVersion = $this->wordpress->getOption('uam_db_version');
183 return version_compare($currentDbVersion, UserAccessManager::DB_VERSION, '<');
184 }
185
186 /**
187 * Creates a database backup.
188 *
189 * @return bool
190 */
191 public function backupDatabase()
192 {
193 $currentDbVersion = $this->wordpress->getOption('uam_db_version');
194
195 if (empty($currentDbVersion) === true
196 || version_compare($currentDbVersion, '1.2', '<') === true
197 ) {
198 return false;
199 }
200
201 $tables = [
202 $this->database->getUserGroupTable(),
203 $this->database->getUserGroupToObjectTable()
204 ];
205
206 $currentDbVersion = str_replace('.', '-', $currentDbVersion);
207 $success = true;
208
209 foreach ($tables as $table) {
210 $createQuery = "CREATE TABLE `{$table}_{$currentDbVersion}` LIKE `{$table}`";
211 $success = $success && ($this->database->query($createQuery) !== false);
212 $insertQuery = "INSERT `{$table}_{$currentDbVersion}` SELECT * FROM `{$table}`";
213 $success = $success && ($this->database->query($insertQuery) !== false);
214 }
215
216 return $success;
217 }
218
219 /**
220 * Returns the version for which a backup was created.
221 *
222 * @return array
223 */
224 public function getBackups()
225 {
226 $versions = [];
227 $tables = (array)$this->database->getColumn(
228 "SHOW TABLES LIKE '{$this->database->getPrefix()}uam_%'"
229 );
230
231 foreach ($tables as $table) {
232 if (preg_match('/.*\_([0-9\-]+)/i', $table, $matches) === 1) {
233 $version = str_replace('-', '.', $matches[1]);
234 $versions[$version] = $version;
235 }
236 }
237
238 return $versions;
239 }
240
241 /**
242 * Returns the backup tables for the given version.
243 *
244 * @param string $version
245 *
246 * @return array
247 */
248 private function getBackupTables($version)
249 {
250 $backupTables = [];
251 $tables = [
252 $this->database->getUserGroupTable(),
253 $this->database->getUserGroupToObjectTable()
254 ];
255
256 $versionForDb = str_replace('.', '-', $version);
257
258 foreach ($tables as $table) {
259 $backupTable = (string)$this->database->getVariable(
260 "SHOW TABLES LIKE '{$table}_{$versionForDb}'"
261 );
262
263 if ($backupTable !== '') {
264 $backupTables[$table] = $backupTable;
265 }
266 }
267
268 return $backupTables;
269 }
270
271 /**
272 * Reverts the database to the given version.
273 *
274 * @param string $version
275 *
276 * @return bool
277 */
278 public function revertDatabase($version)
279 {
280 $success = true;
281 $tables = $this->getBackupTables($version);
282
283 foreach ($tables as $table => $backupTable) {
284 $dropQuery = "DROP TABLE IF EXISTS `{$table}`";
285 $success = $success && ($this->database->query($dropQuery) !== false);
286 $renameQuery = "RENAME TABLE `{$backupTable}` TO `{$table}`";
287 $success = $success && ($this->database->query($renameQuery) !== false);
288 }
289
290 if ($success === true) {
291 $this->wordpress->updateOption('uam_db_version', $version);
292 }
293
294 return $success;
295 }
296
297 /**
298 * Deletes the given database backup.
299 *
300 * @param string $version
301 *
302 * @return bool
303 */
304 public function deleteBackup($version)
305 {
306 $success = true;
307 $tables = $this->getBackupTables($version);
308
309 foreach ($tables as $table => $backupTable) {
310 $dropQuery = "DROP TABLE IF EXISTS `{$backupTable}`";
311 $success = $success && ($this->database->query($dropQuery) !== false);
312 }
313
314 return $success;
315 }
316
317 /**
318 * Updates the user access manager if an old version was installed.
319 *
320 * @return true
321 */
322 public function update()
323 {
324 $currentDbVersion = $this->wordpress->getOption('uam_db_version');
325
326 if (empty($currentDbVersion) === true) {
327 return false;
328 }
329
330 $uamVersion = $this->wordpress->getOption('uam_version', '0');
331
332 if (version_compare($uamVersion, '1.0', '<') === true) {
333 $this->wordpress->deleteOption('allow_comments_locked');
334 }
335
336 $dbAccessGroup = $this->database->getUserGroupTable();
337
338 $dbUserGroup = $this->database->getVariable(
339 "SHOW TABLES LIKE '{$dbAccessGroup}'"
340 );
341
342 if (version_compare($currentDbVersion, UserAccessManager::DB_VERSION, '<') === true) {
343 $prefix = $this->database->getPrefix();
344 $charsetCollate = $this->database->getCharset();
345
346 if (version_compare($currentDbVersion, '1.0', '<=') === true) {
347 if ($dbUserGroup === $dbAccessGroup) {
348 $alterQuery = "ALTER TABLE {$dbAccessGroup}
349 ADD read_access TINYTEXT NOT NULL DEFAULT '',
350 ADD write_access TINYTEXT NOT NULL DEFAULT '',
351 ADD ip_range MEDIUMTEXT NULL DEFAULT ''";
352 $this->database->query($alterQuery);
353
354 $updateQuery = "UPDATE {$dbAccessGroup}
355 SET read_access = 'group', write_access = 'group'";
356 $this->database->query($updateQuery);
357
358 $selectQuery = "SHOW columns FROM {$dbAccessGroup} LIKE 'ip_range'";
359 $dbIpRange = $this->database->getVariable($selectQuery);
360
361 if ($dbIpRange != 'ip_range') {
362 $alterQuery = "ALTER TABLE {$dbAccessGroup}
363 ADD ip_range MEDIUMTEXT NULL DEFAULT ''";
364
365 $this->database->query($alterQuery);
366 }
367 }
368
369 $dbAccessGroupToObject = $prefix.'uam_accessgroup_to_object';
370 $dbAccessGroupToPost = $prefix.'uam_accessgroup_to_post';
371 $dbAccessGroupToUser = $prefix.'uam_accessgroup_to_user';
372 $dbAccessGroupToCategory = $prefix.'uam_accessgroup_to_category';
373 $dbAccessGroupToRole = $prefix.'uam_accessgroup_to_role';
374
375 $alterQuery = "ALTER TABLE '{$dbAccessGroupToObject}'
376 CHANGE 'object_id' 'object_id' VARCHAR(64) {$charsetCollate}";
377 $this->database->query($alterQuery);
378
379 $objectTypes = $this->objectHandler->getObjectTypes();
380 $postTable = $this->database->getPostsTable();
381
382 foreach ($objectTypes as $objectType) {
383 $addition = '';
384
385 if ($this->objectHandler->isPostType($objectType) === true) {
386 $dbIdName = 'post_id';
387 $database = $dbAccessGroupToPost.', '.$postTable;
388 $addition = " WHERE post_id = ID
389 AND post_type = '".$objectType."'";
390 } elseif ($objectType === 'category') {
391 $dbIdName = 'category_id';
392 $database = $dbAccessGroupToCategory;
393 } elseif ($objectType === 'user') {
394 $dbIdName = 'user_id';
395 $database = $dbAccessGroupToUser;
396 } elseif ($objectType === 'role') {
397 $dbIdName = 'role_name';
398 $database = $dbAccessGroupToRole;
399 } else {
400 continue;
401 }
402
403 $fullDatabase = $database.$addition;
404
405 $query = "SELECT {$dbIdName} AS id, group_id AS groupId
406 FROM {$fullDatabase}";
407
408 $dbObjects = (array)$this->database->getResults($query);
409
410 foreach ($dbObjects as $dbObject) {
411 $this->database->insert(
412 $dbAccessGroupToObject,
413 [
414 'group_id' => $dbObject->groupId,
415 'object_id' => $dbObject->id,
416 'object_type' => $objectType,
417 ],
418 [
419 '%d',
420 '%d',
421 '%s',
422 ]
423 );
424 }
425 }
426
427 $dropQuery = "DROP TABLE {$dbAccessGroupToPost},
428 {$dbAccessGroupToUser},
429 {$dbAccessGroupToCategory},
430 {$dbAccessGroupToRole}";
431
432 $this->database->query($dropQuery);
433 }
434
435 $dbAccessGroupToObject = $this->database->getUserGroupToObjectTable();
436
437 if (version_compare($currentDbVersion, '1.2', '<=') === true) {
438 $query = "
439 ALTER TABLE `{$dbAccessGroupToObject}`
440 CHANGE `object_id` `object_id` VARCHAR(64) NOT NULL,
441 CHANGE `object_type` `object_type` VARCHAR(64) NOT NULL";
442
443 $this->database->query($query);
444 }
445
446 if (version_compare($currentDbVersion, '1.3', '<=') === true) {
447 $generalTermType = ObjectHandler::GENERAL_TERM_OBJECT_TYPE;
448 $this->database->update(
449 $dbAccessGroupToObject,
450 ['object_type' => $generalTermType],
451 ['object_type' => 'category']
452 );
453 }
454
455 if (version_compare($currentDbVersion, '1.4', '<=') === true) {
456 $alterQuery = "ALTER TABLE {$dbAccessGroupToObject}
457 ADD general_object_type VARCHAR(64) NOT NULL AFTER object_id";
458
459 $this->database->query($alterQuery);
460
461 // Update post entries
462 $generalPostType = ObjectHandler::GENERAL_POST_OBJECT_TYPE;
463
464 $query = "UPDATE {$dbAccessGroupToObject}
465 SET general_object_type = '{$generalPostType}'
466 WHERE object_type IN ('post', 'page', 'attachment')";
467
468 $this->database->query($query);
469
470 // Update role entries
471 $generalRoleType = ObjectHandler::GENERAL_ROLE_OBJECT_TYPE;
472
473 $query = "UPDATE {$dbAccessGroupToObject}
474 SET general_object_type = '{$generalRoleType}'
475 WHERE object_type = 'role'";
476
477 $this->database->query($query);
478
479 // Update user entries
480 $generalUserType = ObjectHandler::GENERAL_USER_OBJECT_TYPE;
481
482 $query = "UPDATE {$dbAccessGroupToObject}
483 SET general_object_type = '{$generalUserType}'
484 WHERE object_type = 'user'";
485
486 $this->database->query($query);
487
488 // Update term entries
489 $generalTermType = ObjectHandler::GENERAL_TERM_OBJECT_TYPE;
490
491 $query = "UPDATE {$dbAccessGroupToObject}
492 SET general_object_type = '{$generalTermType}'
493 WHERE object_type = 'term'";
494
495 $this->database->query($query);
496
497 $query = "UPDATE {$dbAccessGroupToObject} AS gto
498 LEFT JOIN {$this->database->getTermTaxonomyTable()} AS tt
499 ON gto.object_id = tt.term_id
500 SET gto.object_type = tt.taxonomy
501 WHERE gto.general_object_type = '{$generalTermType}'";
502
503 $this->database->query($query);
504 }
505
506 if (version_compare($currentDbVersion, '1.5.1', '<=') === true) {
507 $query = "SELECT object_id AS objectId, object_type AS objectType, group_id AS groupId
508 FROM {$dbAccessGroupToObject}
509 WHERE general_object_type = ''";
510
511 $dbObjects = (array)$this->database->getResults($query);
512
513 foreach ($dbObjects as $dbObject) {
514 $this->database->update(
515 $dbAccessGroupToObject,
516 ['general_object_type' => $this->objectHandler->getGeneralObjectType($dbObject->objectType)],
517 [
518 'object_id' => $dbObject->objectId,
519 'group_id' => $dbObject->groupId,
520 'object_type' => $dbObject->objectType
521 ]
522 );
523 }
524 }
525
526 $this->wordpress->updateOption('uam_db_version', UserAccessManager::DB_VERSION);
527 }
528
529 return true;
530 }
531
532 /**
533 * Clean up wordpress if the plugin will be uninstalled.
534 */
535 public function uninstall()
536 {
537 $blogIds = $this->getBlogIds();
538
539 foreach ($blogIds as $blogId) {
540 $this->wordpress->switchToBlog($blogId);
541 $userGroupTable = $this->database->getUserGroupTable();
542 $userGroupToObjectTable = $this->database->getUserGroupToObjectTable();
543
544 $dropQuery = "DROP TABLE {$userGroupTable}, {$userGroupToObjectTable}";
545 $this->database->query($dropQuery);
546
547 $this->wordpress->deleteOption(Config::ADMIN_OPTIONS_NAME);
548 $this->wordpress->deleteOption('uam_version');
549 $this->wordpress->deleteOption('uam_db_version');
550 }
551
552 $this->fileHandler->deleteFileProtection();
553 }
554
555 /**
556 * Remove the htaccess file if the plugin is deactivated.
557 *
558 * @return bool
559 */
560 public function deactivate()
561 {
562 return $this->fileHandler->deleteFileProtection();
563 }
564 }
565