PluginProbe
User Access Manager / 2.0.10
User Access Manager v2.0.10
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.10, at src/UserAccessManager/SetupHandler/SetupHandler.php

569 lines 18.6 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 ($currentDbVersion !== null
177 && version_compare($currentDbVersion, UserAccessManager::DB_VERSION, '<') === true
178 ) {
179 return true;
180 }
181 }
182 }
183
184 $currentDbVersion = $this->wordpress->getOption('uam_db_version');
185 return version_compare($currentDbVersion, UserAccessManager::DB_VERSION, '<');
186 }
187
188 /**
189 * Creates a database backup.
190 *
191 * @return bool
192 */
193 public function backupDatabase()
194 {
195 $currentDbVersion = $this->wordpress->getOption('uam_db_version');
196
197 if (empty($currentDbVersion) === true
198 || version_compare($currentDbVersion, '1.2', '<') === true
199 ) {
200 return false;
201 }
202
203 $tables = [
204 $this->database->getUserGroupTable(),
205 $this->database->getUserGroupToObjectTable()
206 ];
207
208 $currentDbVersion = str_replace('.', '-', $currentDbVersion);
209 $success = true;
210
211 foreach ($tables as $table) {
212 $createQuery = "CREATE TABLE `{$table}_{$currentDbVersion}` LIKE `{$table}`";
213 $success = $success && ($this->database->query($createQuery) !== false);
214 $insertQuery = "INSERT `{$table}_{$currentDbVersion}` SELECT * FROM `{$table}`";
215 $success = $success && ($this->database->query($insertQuery) !== false);
216 }
217
218 return $success;
219 }
220
221 /**
222 * Returns the version for which a backup was created.
223 *
224 * @return array
225 */
226 public function getBackups()
227 {
228 $versions = [];
229 $tables = (array)$this->database->getColumn(
230 "SHOW TABLES LIKE '{$this->database->getPrefix()}uam_%'"
231 );
232
233 foreach ($tables as $table) {
234 if (preg_match('/.*\_([0-9\-]+)/i', $table, $matches) === 1) {
235 $version = str_replace('-', '.', $matches[1]);
236 $versions[$version] = $version;
237 }
238 }
239
240 return $versions;
241 }
242
243 /**
244 * Returns the backup tables for the given version.
245 *
246 * @param string $version
247 *
248 * @return array
249 */
250 private function getBackupTables($version)
251 {
252 $backupTables = [];
253 $tables = [
254 $this->database->getUserGroupTable(),
255 $this->database->getUserGroupToObjectTable()
256 ];
257
258 $versionForDb = str_replace('.', '-', $version);
259
260 foreach ($tables as $table) {
261 $backupTable = (string)$this->database->getVariable(
262 "SHOW TABLES LIKE '{$table}_{$versionForDb}'"
263 );
264
265 if ($backupTable !== '') {
266 $backupTables[$table] = $backupTable;
267 }
268 }
269
270 return $backupTables;
271 }
272
273 /**
274 * Reverts the database to the given version.
275 *
276 * @param string $version
277 *
278 * @return bool
279 */
280 public function revertDatabase($version)
281 {
282 $success = true;
283 $tables = $this->getBackupTables($version);
284
285 foreach ($tables as $table => $backupTable) {
286 $dropQuery = "DROP TABLE IF EXISTS `{$table}`";
287 $success = $success && ($this->database->query($dropQuery) !== false);
288 $renameQuery = "RENAME TABLE `{$backupTable}` TO `{$table}`";
289 $success = $success && ($this->database->query($renameQuery) !== false);
290 }
291
292 if ($success === true) {
293 $this->wordpress->updateOption('uam_db_version', $version);
294 }
295
296 return $success;
297 }
298
299 /**
300 * Deletes the given database backup.
301 *
302 * @param string $version
303 *
304 * @return bool
305 */
306 public function deleteBackup($version)
307 {
308 $success = true;
309 $tables = $this->getBackupTables($version);
310
311 foreach ($tables as $table => $backupTable) {
312 $dropQuery = "DROP TABLE IF EXISTS `{$backupTable}`";
313 $success = $success && ($this->database->query($dropQuery) !== false);
314 }
315
316 return $success;
317 }
318
319 /**
320 * Updates the user access manager if an old version was installed.
321 *
322 * @return true
323 */
324 public function update()
325 {
326 $currentDbVersion = $this->wordpress->getOption('uam_db_version');
327
328 if (empty($currentDbVersion) === true) {
329 return false;
330 }
331
332 $uamVersion = $this->wordpress->getOption('uam_version', '0');
333
334 if (version_compare($uamVersion, '1.0', '<') === true) {
335 $this->wordpress->deleteOption('allow_comments_locked');
336 }
337
338 $dbAccessGroup = $this->database->getUserGroupTable();
339
340 $dbUserGroup = $this->database->getVariable(
341 "SHOW TABLES LIKE '{$dbAccessGroup}'"
342 );
343
344 if (version_compare($currentDbVersion, UserAccessManager::DB_VERSION, '<') === true) {
345 $prefix = $this->database->getPrefix();
346 $charsetCollate = $this->database->getCharset();
347
348 if (version_compare($currentDbVersion, '1.0', '<=') === true) {
349 if ($dbUserGroup === $dbAccessGroup) {
350 $alterQuery = "ALTER TABLE {$dbAccessGroup}
351 ADD read_access TINYTEXT NOT NULL DEFAULT '',
352 ADD write_access TINYTEXT NOT NULL DEFAULT '',
353 ADD ip_range MEDIUMTEXT NULL DEFAULT ''";
354 $this->database->query($alterQuery);
355
356 $updateQuery = "UPDATE {$dbAccessGroup}
357 SET read_access = 'group', write_access = 'group'";
358 $this->database->query($updateQuery);
359
360 $selectQuery = "SHOW columns FROM {$dbAccessGroup} LIKE 'ip_range'";
361 $dbIpRange = $this->database->getVariable($selectQuery);
362
363 if ($dbIpRange != 'ip_range') {
364 $alterQuery = "ALTER TABLE {$dbAccessGroup}
365 ADD ip_range MEDIUMTEXT NULL DEFAULT ''";
366
367 $this->database->query($alterQuery);
368 }
369 }
370
371 $dbAccessGroupToObject = $prefix.'uam_accessgroup_to_object';
372 $dbAccessGroupToPost = $prefix.'uam_accessgroup_to_post';
373 $dbAccessGroupToUser = $prefix.'uam_accessgroup_to_user';
374 $dbAccessGroupToCategory = $prefix.'uam_accessgroup_to_category';
375 $dbAccessGroupToRole = $prefix.'uam_accessgroup_to_role';
376
377 $alterQuery = "ALTER TABLE '{$dbAccessGroupToObject}'
378 CHANGE 'object_id' 'object_id' VARCHAR(64) {$charsetCollate}";
379 $this->database->query($alterQuery);
380
381 $objectTypes = $this->objectHandler->getObjectTypes();
382 $postTable = $this->database->getPostsTable();
383
384 foreach ($objectTypes as $objectType) {
385 $addition = '';
386
387 if ($this->objectHandler->isPostType($objectType) === true) {
388 $dbIdName = 'post_id';
389 $database = $dbAccessGroupToPost.', '.$postTable;
390 $addition = " WHERE post_id = ID
391 AND post_type = '".$objectType."'";
392 } elseif ($objectType === 'category') {
393 $dbIdName = 'category_id';
394 $database = $dbAccessGroupToCategory;
395 } elseif ($objectType === 'user') {
396 $dbIdName = 'user_id';
397 $database = $dbAccessGroupToUser;
398 } elseif ($objectType === 'role') {
399 $dbIdName = 'role_name';
400 $database = $dbAccessGroupToRole;
401 } else {
402 continue;
403 }
404
405 $fullDatabase = $database.$addition;
406
407 $query = "SELECT {$dbIdName} AS id, group_id AS groupId
408 FROM {$fullDatabase}";
409
410 $dbObjects = (array)$this->database->getResults($query);
411
412 foreach ($dbObjects as $dbObject) {
413 $this->database->insert(
414 $dbAccessGroupToObject,
415 [
416 'group_id' => $dbObject->groupId,
417 'object_id' => $dbObject->id,
418 'object_type' => $objectType,
419 ],
420 [
421 '%d',
422 '%d',
423 '%s',
424 ]
425 );
426 }
427 }
428
429 $dropQuery = "DROP TABLE {$dbAccessGroupToPost},
430 {$dbAccessGroupToUser},
431 {$dbAccessGroupToCategory},
432 {$dbAccessGroupToRole}";
433
434 $this->database->query($dropQuery);
435 }
436
437 $dbAccessGroupToObject = $this->database->getUserGroupToObjectTable();
438
439 if (version_compare($currentDbVersion, '1.2', '<=') === true) {
440 $query = "
441 ALTER TABLE `{$dbAccessGroupToObject}`
442 CHANGE `object_id` `object_id` VARCHAR(64) NOT NULL,
443 CHANGE `object_type` `object_type` VARCHAR(64) NOT NULL";
444
445 $this->database->query($query);
446 }
447
448 if (version_compare($currentDbVersion, '1.3', '<=') === true) {
449 $generalTermType = ObjectHandler::GENERAL_TERM_OBJECT_TYPE;
450 $this->database->update(
451 $dbAccessGroupToObject,
452 ['object_type' => $generalTermType],
453 ['object_type' => 'category']
454 );
455 }
456
457 if (version_compare($currentDbVersion, '1.4', '<=') === true) {
458 $alterQuery = "ALTER TABLE {$dbAccessGroupToObject}
459 ADD general_object_type VARCHAR(64) NOT NULL AFTER object_id";
460
461 $this->database->query($alterQuery);
462
463 // Update post entries
464 $generalPostType = ObjectHandler::GENERAL_POST_OBJECT_TYPE;
465
466 $query = "UPDATE {$dbAccessGroupToObject}
467 SET general_object_type = '{$generalPostType}'
468 WHERE object_type IN ('post', 'page', 'attachment')";
469
470 $this->database->query($query);
471
472 // Update role entries
473 $generalRoleType = ObjectHandler::GENERAL_ROLE_OBJECT_TYPE;
474
475 $query = "UPDATE {$dbAccessGroupToObject}
476 SET general_object_type = '{$generalRoleType}'
477 WHERE object_type = 'role'";
478
479 $this->database->query($query);
480
481 // Update user entries
482 $generalUserType = ObjectHandler::GENERAL_USER_OBJECT_TYPE;
483
484 $query = "UPDATE {$dbAccessGroupToObject}
485 SET general_object_type = '{$generalUserType}'
486 WHERE object_type = 'user'";
487
488 $this->database->query($query);
489
490 // Update term entries
491 $generalTermType = ObjectHandler::GENERAL_TERM_OBJECT_TYPE;
492
493 $query = "UPDATE {$dbAccessGroupToObject}
494 SET general_object_type = '{$generalTermType}'
495 WHERE object_type = 'term'";
496
497 $this->database->query($query);
498
499 $query = "UPDATE {$dbAccessGroupToObject} AS gto
500 LEFT JOIN {$this->database->getTermTaxonomyTable()} AS tt
501 ON gto.object_id = tt.term_id
502 SET gto.object_type = tt.taxonomy
503 WHERE gto.general_object_type = '{$generalTermType}'";
504
505 $this->database->query($query);
506 }
507
508 if (version_compare($currentDbVersion, '1.5.1', '<=') === true) {
509 $query = "SELECT object_id AS objectId, object_type AS objectType, group_id AS groupId
510 FROM {$dbAccessGroupToObject}
511 WHERE general_object_type = ''";
512
513 $dbObjects = (array)$this->database->getResults($query);
514
515 foreach ($dbObjects as $dbObject) {
516 $this->database->update(
517 $dbAccessGroupToObject,
518 ['general_object_type' => $this->objectHandler->getGeneralObjectType($dbObject->objectType)],
519 [
520 'object_id' => $dbObject->objectId,
521 'group_id' => $dbObject->groupId,
522 'object_type' => $dbObject->objectType
523 ]
524 );
525 }
526 }
527
528 $this->wordpress->updateOption('uam_db_version', UserAccessManager::DB_VERSION);
529 }
530
531 return true;
532 }
533
534 /**
535 * Clean up wordpress if the plugin will be uninstalled.
536 */
537 public function uninstall()
538 {
539 $currentBlogId = $this->database->getCurrentBlogId();
540 $blogIds = $this->getBlogIds();
541
542 foreach ($blogIds as $blogId) {
543 $this->wordpress->switchToBlog($blogId);
544 $userGroupTable = $this->database->getUserGroupTable();
545 $userGroupToObjectTable = $this->database->getUserGroupToObjectTable();
546
547 $dropQuery = "DROP TABLE IF EXISTS {$userGroupTable}, {$userGroupToObjectTable}";
548 $this->database->query($dropQuery);
549
550 $this->wordpress->deleteOption(Config::ADMIN_OPTIONS_NAME);
551 $this->wordpress->deleteOption('uam_version');
552 $this->wordpress->deleteOption('uam_db_version');
553 }
554
555 $this->wordpress->switchToBlog($currentBlogId);
556 $this->fileHandler->deleteFileProtection();
557 }
558
559 /**
560 * Remove the htaccess file if the plugin is deactivated.
561 *
562 * @return bool
563 */
564 public function deactivate()
565 {
566 return $this->fileHandler->deleteFileProtection();
567 }
568 }
569