PluginProbe
User Access Manager / 1.2.14
User Access Manager v1.2.14
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 / class / UserAccessManager.php

UserAccessManager.php in User Access Manager 1.2.14, at class/UserAccessManager.php

2,581 lines 76.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * UserAccessManager.php
4 *
5 * The UserAccessManager class file.
6 *
7 * PHP versions 5
8 *
9 * @category UserAccessManager
10 * @package UserAccessManager
11 * @author Alexander Schneider <alexanderschneider85@googlemail.com>
12 * @copyright 2008-2016 Alexander Schneider
13 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2
14 * @version SVN: $Id$
15 * @link http://wordpress.org/extend/plugins/user-access-manager/
16 */
17
18 /**
19 * The user user access manager class.
20 *
21 * @category UserAccessManager
22 * @package UserAccessManager
23 * @author Alexander Schneider <alexanderschneider85@gmail.com>
24 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2
25 * @link http://wordpress.org/extend/plugins/user-access-manager/
26 */
27 class UserAccessManager
28 {
29 const USER_OBJECT_TYPE = 'user';
30 const POST_OBJECT_TYPE = 'post';
31 const PAGE_OBJECT_TYPE = 'page';
32 const TERM_OBJECT_TYPE = 'term';
33 const ROLE_OBJECT_TYPE = 'role';
34 const ATTACHMENT_OBJECT_TYPE = 'attachment';
35
36 protected $_oConfig = null;
37 protected $_blAtAdminPanel = false;
38 protected $_sUamVersion = '1.2.14';
39 protected $_sUamDbVersion = '1.4';
40 protected $_oAccessHandler = null;
41 protected $_aPostUrls = array();
42 protected $_aMimeTypes = null;
43 protected $_aCache = array();
44 protected $_aUsers = array();
45 protected $_aPosts = array();
46 protected $_aTerms = array();
47 protected $_aWpOptions = array();
48 protected $_aTermPostMap = null;
49 protected $_aTermTreeMap = null;
50 protected $_aPostTreeMap = null;
51 protected $_aPostTypes = null;
52 protected $_aTaxonomies = null;
53
54 /**
55 * Constructor.
56 */
57 public function __construct()
58 {
59 do_action('uam_init', $this);
60 }
61
62 /**
63 * Flushes the cache.
64 */
65 public function flushCache()
66 {
67 $this->_aCache = array();
68 }
69
70 /**
71 * Returns the database.
72 *
73 * @return wpdb
74 */
75 public function getDatabase()
76 {
77 global $wpdb;
78 return $wpdb;
79 }
80
81 /**
82 * Returns all post types.
83 *
84 * @return array
85 */
86 public function getPostTypes()
87 {
88 if ($this->_aPostTypes === null) {
89 $this->_aPostTypes = get_post_types(array('publicly_queryable' => true));
90 }
91
92 return $this->_aPostTypes;
93 }
94
95 /**
96 * Wrapper for is_post_type_hierarchical
97 *
98 * @param string $sType
99 *
100 * @return bool
101 */
102 public function isPostTypeHierarchical($sType)
103 {
104 return is_post_type_hierarchical($sType);
105 }
106
107 /**
108 * Returns the taxonomies.
109 *
110 * @return array
111 */
112 public function getTaxonomies()
113 {
114 if ($this->_aTaxonomies === null) {
115 $this->_aTaxonomies = get_taxonomies();
116 }
117
118 return $this->_aTaxonomies;
119 }
120
121 /**
122 * Adds the variable to the cache.
123 *
124 * @param string $sKey The cache key
125 * @param mixed $mValue The value.
126 */
127 public function addToCache($sKey, $mValue)
128 {
129 $this->_aCache[$sKey] = $mValue;
130 }
131
132 /**
133 * Returns a value from the cache by the given key.
134 *
135 * @param string $sKey
136 *
137 * @return mixed
138 */
139 public function getFromCache($sKey)
140 {
141 if (isset($this->_aCache[$sKey])) {
142 return $this->_aCache[$sKey];
143 }
144
145 return null;
146 }
147
148 /**
149 * Returns a user.
150 *
151 * @param string $sId The user id.
152 *
153 * @return mixed
154 */
155 public function getUser($sId)
156 {
157 if (!isset($this->_aUsers[$sId])) {
158 $this->_aUsers[$sId] = get_userdata($sId);
159 }
160
161 return $this->_aUsers[$sId];
162 }
163
164 /**
165 * Returns a post.
166 *
167 * @param string $sId The post id.
168 *
169 * @return mixed
170 */
171 public function getPost($sId)
172 {
173 if (!isset($this->_aPosts[$sId])) {
174 $this->_aPosts[$sId] = get_post($sId);
175 }
176
177 return $this->_aPosts[$sId];
178 }
179
180 /**
181 * Returns a term.
182 *
183 * @param string $sId The term id.
184 * @param string $sTaxonomy The taxonomy.
185 *
186 * @return mixed
187 */
188 public function getTerm($sId, $sTaxonomy = '')
189 {
190 if (!isset($this->_aTerms[$sId])) {
191 $iPriority = has_filter('get_term', array($this, 'showTerm'));
192 $blRemoveSuccess = remove_filter('get_term', array($this, 'showTerm'), $iPriority);
193
194 $this->_aTerms[$sId] = get_term($sId, $sTaxonomy);
195
196 if ($blRemoveSuccess === true) {
197 add_filter('get_term', array($this, 'showTerm'), $iPriority, 2);
198 }
199 }
200
201 return $this->_aTerms[$sId];
202 }
203
204 /**
205 * Returns all blog of the network.
206 *
207 * @return array()
208 */
209 protected function _getBlogIds()
210 {
211 $oDatabase = $this->getDatabase();
212 $aBlogIds = array();
213
214 if (is_multisite()) {
215 $aBlogIds = $oDatabase->get_col(
216 "SELECT blog_id
217 FROM ".$oDatabase->blogs
218 );
219 }
220
221 return $aBlogIds;
222 }
223
224 /**
225 * Installs the user access manager.
226 */
227 public function install()
228 {
229 $oDatabase = $this->getDatabase();
230 $aBlogIds = $this->_getBlogIds();
231
232 if (isset($_GET['networkwide'])
233 && ((int)$_GET['networkwide'] === 1)
234 ) {
235 $iCurrentBlogId = $oDatabase->blogid;
236
237 foreach ($aBlogIds as $iBlogId) {
238 switch_to_blog($iBlogId);
239 $this->_installUam();
240 }
241
242 switch_to_blog($iCurrentBlogId);
243
244 return null;
245 }
246
247 $this->_installUam();
248 }
249
250 /**
251 * Creates the needed tables at the database and adds the options
252 */
253 protected function _installUam()
254 {
255 $oDatabase = $this->getDatabase();
256 include_once ABSPATH.'wp-admin/includes/upgrade.php';
257
258 $sCharsetCollate = $this->_getCharset();
259
260 $sDbAccessGroupTable = $oDatabase->prefix.'uam_accessgroups';
261
262 $sDbUserGroup = $oDatabase->get_var(
263 "SHOW TABLES
264 LIKE '".$sDbAccessGroupTable."'"
265 );
266
267 if ($sDbUserGroup != $sDbAccessGroupTable) {
268 dbDelta(
269 "CREATE TABLE ".$sDbAccessGroupTable." (
270 ID int(11) NOT NULL auto_increment,
271 groupname tinytext NOT NULL,
272 groupdesc text NOT NULL,
273 read_access tinytext NOT NULL,
274 write_access tinytext NOT NULL,
275 ip_range mediumtext NULL,
276 PRIMARY KEY (ID)
277 ) $sCharsetCollate;"
278 );
279 }
280
281 $sDbAccessGroupToObjectTable = $oDatabase->prefix.'uam_accessgroup_to_object';
282
283 $sDbAccessGroupToObject = $oDatabase->get_var(
284 "SHOW TABLES
285 LIKE '".$sDbAccessGroupToObjectTable."'"
286 );
287
288 if ($sDbAccessGroupToObject != $sDbAccessGroupToObjectTable) {
289 dbDelta(
290 "CREATE TABLE " . $sDbAccessGroupToObjectTable . " (
291 object_id VARCHAR(64) NOT NULL,
292 object_type varchar(64) NOT NULL,
293 group_id int(11) NOT NULL,
294 PRIMARY KEY (object_id,object_type,group_id)
295 ) $sCharsetCollate;"
296 );
297 }
298
299 add_option("uam_db_version", $this->_sUamDbVersion);
300 }
301
302 /**
303 * Checks if a database update is necessary.
304 *
305 * @return boolean
306 */
307 public function isDatabaseUpdateNecessary()
308 {
309 $oDatabase = $this->getDatabase();
310 $aBlogIds = $this->_getBlogIds();
311
312 if ($aBlogIds !== array()
313 && is_super_admin()
314 ) {
315 foreach ($aBlogIds as $iBlogId) {
316 $sTable = $oDatabase->get_blog_prefix($iBlogId).'options';
317 $sSelect = "SELECT option_value FROM {$sTable} WHERE option_name = %s LIMIT 1";
318 $sSelect = $oDatabase->prepare($sSelect, 'uam_db_version');
319 $sCurrentDbVersion = $oDatabase->get_var($sSelect);
320
321 if (version_compare($sCurrentDbVersion, $this->_sUamDbVersion, '<')) {
322 return true;
323 }
324 }
325 }
326
327 $sCurrentDbVersion = get_option('uam_db_version');
328 return version_compare($sCurrentDbVersion, $this->_sUamDbVersion, '<');
329 }
330
331 /**
332 * Updates the user access manager if an old version was installed.
333 *
334 * @param boolean $blNetworkWide If true update network wide
335 */
336 public function update($blNetworkWide)
337 {
338 $oDatabase = $this->getDatabase();
339 $aBlogIds = $this->_getBlogIds();
340
341 if ($blNetworkWide
342 && $aBlogIds !== array()
343 ) {
344 $iCurrentBlogId = $oDatabase->blogid;
345
346 foreach ($aBlogIds as $iBlogId) {
347 switch_to_blog($iBlogId);
348 $this->_installUam();
349 $this->_updateUam();
350 }
351
352 switch_to_blog($iCurrentBlogId);
353 } else {
354 $this->_updateUam();
355 }
356 }
357
358 /**
359 * Updates the user access manager if an old version was installed.
360 */
361 protected function _updateUam()
362 {
363 $oDatabase = $this->getDatabase();
364 $sCurrentDbVersion = get_option('uam_db_version');
365
366 if (empty($sCurrentDbVersion)) {
367 $this->install();
368 }
369
370 if (!get_option('uam_version') || version_compare(get_option('uam_version'), "1.0", '<')) {
371 delete_option('allow_comments_locked');
372 }
373
374 $sDbAccessGroup = $oDatabase->prefix.'uam_accessgroups';
375
376 $sDbUserGroup = $oDatabase->get_var(
377 "SHOW TABLES
378 LIKE '".$sDbAccessGroup."'"
379 );
380
381 if (version_compare($sCurrentDbVersion, $this->_sUamDbVersion, '<')) {
382 $sCharsetCollate = $this->_getCharset();
383
384 if (version_compare($sCurrentDbVersion, "1.0", '<=')) {
385 if ($sDbUserGroup == $sDbAccessGroup) {
386 $oDatabase->query(
387 "ALTER TABLE ".$sDbAccessGroup."
388 ADD read_access TINYTEXT NOT NULL DEFAULT '',
389 ADD write_access TINYTEXT NOT NULL DEFAULT '',
390 ADD ip_range MEDIUMTEXT NULL DEFAULT ''"
391 );
392
393 $oDatabase->query(
394 "UPDATE ".$sDbAccessGroup."
395 SET read_access = 'group',
396 write_access = 'group'"
397 );
398
399 $sDbIpRange = $oDatabase->get_var(
400 "SHOW columns
401 FROM ".$sDbAccessGroup."
402 LIKE 'ip_range'"
403 );
404
405 if ($sDbIpRange != 'ip_range') {
406 $oDatabase->query(
407 "ALTER TABLE ".$sDbAccessGroup."
408 ADD ip_range MEDIUMTEXT NULL DEFAULT ''"
409 );
410 }
411 }
412
413 $sDbAccessGroupToObject = $oDatabase->prefix.'uam_accessgroup_to_object';
414 $sDbAccessGroupToPost = $oDatabase->prefix.'uam_accessgroup_to_post';
415 $sDbAccessGroupToUser = $oDatabase->prefix.'uam_accessgroup_to_user';
416 $sDbAccessGroupToCategory = $oDatabase->prefix.'uam_accessgroup_to_category';
417 $sDbAccessGroupToRole = $oDatabase->prefix.'uam_accessgroup_to_role';
418
419 $oDatabase->query(
420 "ALTER TABLE '{$sDbAccessGroupToObject}'
421 CHANGE 'object_id' 'object_id' VARCHAR(64)
422 ".$sCharsetCollate
423 );
424
425 $aObjectTypes = $this->getAccessHandler()->getObjectTypes();
426
427 foreach ($aObjectTypes as $sObjectType) {
428 $sAddition = '';
429
430 if ($this->getAccessHandler()->isPostableType($sObjectType)) {
431 $sDbIdName = 'post_id';
432 $sDatabase = $sDbAccessGroupToPost.', '.$oDatabase->posts;
433 $sAddition = " WHERE post_id = ID
434 AND post_type = '".$sObjectType."'";
435 } elseif ($sObjectType == 'category') {
436 $sDbIdName = 'category_id';
437 $sDatabase = $sDbAccessGroupToCategory;
438 } elseif ($sObjectType == 'user') {
439 $sDbIdName = 'user_id';
440 $sDatabase = $sDbAccessGroupToUser;
441 } elseif ($sObjectType == 'role') {
442 $sDbIdName = 'role_name';
443 $sDatabase = $sDbAccessGroupToRole;
444 } else {
445 continue;
446 }
447
448 $sFullDatabase = $sDatabase.$sAddition;
449
450 $sSql = "SELECT {$sDbIdName} as id, group_id as groupId
451 FROM {$sFullDatabase}";
452
453 $aDbObjects = $oDatabase->get_results($sSql);
454
455 foreach ($aDbObjects as $oDbObject) {
456 $oDatabase->insert(
457 $sDbAccessGroupToObject,
458 array(
459 'group_id' => $oDbObject->groupId,
460 'object_id' => $oDbObject->id,
461 'object_type' => $sObjectType,
462 ),
463 array(
464 '%d',
465 '%d',
466 '%s',
467 )
468 );
469 }
470 }
471
472 $oDatabase->query(
473 "DROP TABLE {$sDbAccessGroupToPost},
474 {$sDbAccessGroupToUser},
475 {$sDbAccessGroupToCategory},
476 {$sDbAccessGroupToRole}"
477 );
478 }
479
480 if (version_compare($sCurrentDbVersion, "1.2", '<=')) {
481 $sDbAccessGroupToObject = $oDatabase->prefix.'uam_accessgroup_to_object';
482
483 $sSql = "
484 ALTER TABLE `{$sDbAccessGroupToObject}`
485 CHANGE `object_id` `object_id` VARCHAR(64) NOT NULL,
486 CHANGE `object_type` `object_type` VARCHAR(64) NOT NULL";
487
488 $oDatabase->query($sSql);
489 }
490
491 if (version_compare($sCurrentDbVersion, "1.3", '<=')) {
492 $sDbAccessGroupToObject = $oDatabase->prefix.'uam_accessgroup_to_object';
493 $sTermType = UserAccessManager::TERM_OBJECT_TYPE;
494 $oDatabase->update(
495 $sDbAccessGroupToObject,
496 array(
497 'object_type' => $sTermType,
498 ),
499 array(
500 'object_type' => 'category',
501 )
502 );
503 }
504
505 update_option('uam_db_version', $this->_sUamDbVersion);
506 }
507 }
508
509 /**
510 * Clean up wordpress if the plugin will be uninstalled.
511 */
512 public function uninstall()
513 {
514 $oDatabase = $this->getDatabase();
515
516 $oDatabase->query(
517 "DROP TABLE ".DB_ACCESSGROUP.",
518 ".DB_ACCESSGROUP_TO_OBJECT
519 );
520
521 delete_option(UamConfig::ADMIN_OPTIONS_NAME);
522 delete_option('uam_version');
523 delete_option('uam_db_version');
524 $this->deleteFileProtectionFiles();
525 }
526
527 /**
528 * Returns the database charset.
529 *
530 * @return string
531 */
532 protected function _getCharset()
533 {
534 $oDatabase = $this->getDatabase();
535 $sCharsetCollate = '';
536
537 $sMySlqVersion = $oDatabase->get_var("SELECT VERSION() as mysql_version");
538
539 if (version_compare($sMySlqVersion, '4.1.0', '>=')) {
540 if (!empty($oDatabase->charset)) {
541 $sCharsetCollate = "DEFAULT CHARACTER SET $oDatabase->charset";
542 }
543
544 if (!empty($oDatabase->collate)) {
545 $sCharsetCollate.= " COLLATE $oDatabase->collate";
546 }
547 }
548
549 return $sCharsetCollate;
550 }
551
552 /**
553 * Remove the htaccess file if the plugin is deactivated.
554 */
555 public function deactivate()
556 {
557 $this->deleteFileProtectionFiles();
558 }
559
560 /**
561 * Returns the current user.
562 *
563 * @return WP_User
564 */
565 public function getCurrentUser()
566 {
567 if (!function_exists('get_userdata')) {
568 include_once ABSPATH.'wp-includes/pluggable.php';
569 }
570
571 //Force user information
572 return wp_get_current_user();
573 }
574
575 /**
576 * Returns the full supported mine types.
577 *
578 * @return array
579 */
580 protected function _getMimeTypes()
581 {
582 if ($this->_aMimeTypes === null) {
583 $aMimeTypes = get_allowed_mime_types();
584 $aFullMimeTypes = array();
585
586 foreach ($aMimeTypes as $sExtensions => $sMineType) {
587 $aExtension = explode('|', $sExtensions);
588
589 foreach ($aExtension as $sExtension) {
590 $aFullMimeTypes[$sExtension] = $sMineType;
591 }
592 }
593
594 $this->_aMimeTypes = $aFullMimeTypes;
595 }
596
597 return $this->_aMimeTypes;
598 }
599
600 /**
601 * @param string $sFileTypes The file types which should be cleaned up.
602 *
603 * @return string
604 */
605 protected function _cleanUpFileTypesForHtaccess($sFileTypes)
606 {
607 $aValidFileTypes = array();
608 $aFileTypes = explode(',', $sFileTypes);
609 $aMimeTypes = $this->_getMimeTypes();
610
611 foreach ($aFileTypes as $sFileType) {
612 $sCleanFileType = trim($sFileType);
613
614 if (isset($aMimeTypes[$sCleanFileType])) {
615 $aValidFileTypes[$sCleanFileType] = $sCleanFileType;
616 }
617 }
618
619 return implode('|', $aValidFileTypes);
620 }
621
622 /**
623 * Returns true if web server is nginx.
624 *
625 * @return bool
626 */
627 public function isNginx()
628 {
629 global $is_nginx;
630 return $is_nginx;
631 }
632
633 /**
634 * Creates a htaccess file.
635 *
636 * @param string $sDir The destination directory.
637 * @param string $sObjectType The object type.
638 */
639 public function createFileProtection($sDir = null, $sObjectType = null)
640 {
641 $blNginx = $this->isNginx();
642
643 if ($sDir === null) {
644 $aWordpressUploadDir = wp_upload_dir();
645
646 if (empty($aWordpressUploadDir['error'])) {
647 $sDir = $aWordpressUploadDir['basedir'] . "/";
648 }
649 }
650
651 $sFileName = ($blNginx === true) ? "uam.conf" : ".htaccess";
652
653 if ($sDir !== null) {
654 $sFile = "";
655 $sAreaName = "WP-Files";
656 $oConfig = $this->getConfig();
657
658 if (!$this->isPermalinksActive()) {
659 $sFileTypes = null;
660
661 if ($oConfig->getLockedFileTypes() == 'selected') {
662 $sFileTypes = $this->_cleanUpFileTypesForHtaccess($oConfig->getLockedFileTypes());
663 $sFileTypes = "\.(".$sFileTypes.")";
664 } elseif ($blNginx === false && $oConfig->getLockedFileTypes() == 'not_selected') {
665 $sFileTypes = $this->_cleanUpFileTypesForHtaccess($oConfig->getLockedFileTypes());
666 $sFileTypes = "^\.(".$sFileTypes.")";
667 }
668
669 if ($blNginx === true) {
670 $sFile = "location " . str_replace(ABSPATH, '/', $sDir) . " {\n";
671
672 if ($sFileTypes !== null) {
673 $sFile .= "location ~ $sFileTypes {\n";
674 }
675
676 $sFile .= "auth_basic \"" . $sAreaName . "\";" . "\n";
677 $sFile .= "auth_basic_user_file ". $sDir . ".htpasswd;" . "\n";
678 $sFile .= "}\n";
679
680 if ($sFileTypes !== null) {
681 $sFile .= "}\n";
682 }
683 } else {
684 // make .htaccess and .htpasswd
685 $sFile .= "AuthType Basic" . "\n";
686 $sFile .= "AuthName \"" . $sAreaName . "\"" . "\n";
687 $sFile .= "AuthUserFile " . $sDir . ".htpasswd" . "\n";
688 $sFile .= "require valid-user" . "\n";
689
690 if ($sFileTypes !== null) {
691 $sFile = "<FilesMatch '" . $sFileTypes . "'>\n" . $sFile . "</FilesMatch>\n";
692 }
693 }
694
695 $this->createHtpasswd(true);
696 } else {
697 if ($sObjectType === null) {
698 $sObjectType = UserAccessManager::ATTACHMENT_OBJECT_TYPE;
699 }
700
701 if ($blNginx === true) {
702 $sFile = "location " . str_replace(ABSPATH, '/', $sDir) . " {" . "\n";
703 $sFile .= "rewrite ^(.*)$ /index.php?uamfiletype=" . $sObjectType . "&uamgetfile=$1 last;" . "\n";
704 $sFile .= "}" . "\n";
705 } else {
706 $aHomeRoot = parse_url(home_url());
707 $sHomeRoot = (isset($aHomeRoot['path'])) ? trailingslashit($aHomeRoot['path']) : '/';
708
709 $sFile = "<IfModule mod_rewrite.c>\n";
710 $sFile .= "RewriteEngine On\n";
711 $sFile .= "RewriteBase " . $sHomeRoot . "\n";
712 $sFile .= "RewriteRule ^index\.php$ - [L]\n";
713 $sFile .= "RewriteRule (.*) ";
714 $sFile .= $sHomeRoot . "index.php?uamfiletype=" . $sObjectType . "&uamgetfile=$1 [L]\n";
715 $sFile .= "</IfModule>\n";
716 }
717 }
718
719 // save files
720 $sFileWithPath = ($blNginx === true) ? ABSPATH.$sFileName : $sDir.$sFileName;
721
722 $oFileHandler = fopen($sFileWithPath, "w");
723 fwrite($oFileHandler, $sFile);
724 fclose($oFileHandler);
725 }
726 }
727
728 /**
729 * Creates a htpasswd file.
730 *
731 * @param boolean $blCreateNew Force to create new file.
732 * @param string $sDir The destination directory.
733 */
734 public function createHtpasswd($blCreateNew = false, $sDir = null)
735 {
736 $oCurrentUser = $this->getCurrentUser();
737 if (!function_exists('get_userdata')) {
738 include_once ABSPATH.'wp-includes/pluggable.php';
739 }
740
741 $oConfig = $this->getConfig();
742
743 // get url
744 if ($sDir === null) {
745 $aWordpressUploadDir = wp_upload_dir();
746
747 if (empty($aWordpressUploadDir['error'])) {
748 $sDir = $aWordpressUploadDir['basedir'] . "/";
749 }
750 }
751
752 if ($sDir !== null) {
753 $oUserData = $this->getUser($oCurrentUser->ID);
754
755 if (!file_exists($sDir.".htpasswd") || $blCreateNew) {
756 if ($oConfig->getFilePassType() === 'random') {
757 $sPassword = md5($this->getRandomPassword());
758 } else {
759 $sPassword = $oUserData->user_pass;
760 }
761
762 $sUser = $oUserData->user_login;
763
764 // make .htpasswd
765 $sHtpasswdTxt = "$sUser:" . $sPassword . "\n";
766
767 // save file
768 $oFileHandler = fopen($sDir.".htpasswd", "w");
769 fwrite($oFileHandler, $sHtpasswdTxt);
770 fclose($oFileHandler);
771 }
772 }
773 }
774
775 /**
776 * Deletes the htaccess files.
777 *
778 * @param string $sDir The destination directory.
779 */
780 public function deleteFileProtectionFiles($sDir = null)
781 {
782 if ($sDir === null) {
783 $aWordpressUploadDir = wp_upload_dir();
784
785 if (empty($aWordpressUploadDir['error'])) {
786 $sDir = $aWordpressUploadDir['basedir'] . "/";
787 }
788 }
789
790 if ($sDir !== null) {
791 $blNginx = $this->isNginx();
792 $sFileName = ($blNginx === true) ? ABSPATH."uam.conf" : $sDir.".htaccess";
793
794 if (file_exists($sFileName)) {
795 unlink($sFileName);
796 }
797
798 if (file_exists($sDir.".htpasswd")) {
799 unlink($sDir.".htpasswd");
800 }
801 }
802 }
803
804 /**
805 * Generates and returns a random password.
806 *
807 * @return string
808 */
809 public function getRandomPassword()
810 {
811 //create password
812 $aArray = array();
813 $iLength = 16;
814
815 // numbers
816 for ($i = 48; $i < 58; $i++) {
817 $aArray[] = chr($i);
818 }
819
820 // small
821 for ($i = 97; $i < 122; $i++) {
822 $aArray[] = chr($i);
823 }
824
825 // capitals
826 for ($i = 65; $i < 90; $i++) {
827 $aArray[] = chr($i);
828 }
829
830 mt_srand((double)microtime() * 1000000);
831 $sPassword = '';
832
833 for ($i = 1; $i <= $iLength; $i++) {
834 $iRandomNumber = mt_rand(0, count($aArray) - 1);
835 $sPassword .= $aArray[$iRandomNumber];
836 }
837
838 return $sPassword;
839 }
840
841 /**
842 * Returns the current config.
843 *
844 * @return UamConfig
845 */
846 public function getConfig()
847 {
848 if ($this->_oConfig === null) {
849 $this->_oConfig = new UamConfig();
850 }
851
852 return $this->_oConfig;
853 }
854
855 /**
856 * Returns the content of the excluded php file.
857 *
858 * @param string $sFileName The file name
859 * @param integer $iObjectId The _iId if needed.
860 * @param string $sObjectType The object type if needed.
861 *
862 * @return string
863 */
864 public function getIncludeContents($sFileName, $iObjectId = null, $sObjectType = null)
865 {
866 if (is_file($sFileName)) {
867 ob_start();
868 include $sFileName;
869 $sContents = ob_get_contents();
870 ob_end_clean();
871
872 return $sContents;
873 }
874
875 return '';
876 }
877
878 /**
879 * Returns the access handler object.
880 *
881 * @return UamAccessHandler
882 */
883 public function &getAccessHandler()
884 {
885 if ($this->_oAccessHandler == null) {
886 $this->_oAccessHandler = new UamAccessHandler($this);
887 }
888
889 return $this->_oAccessHandler;
890 }
891
892 /**
893 * Returns the current version of the user access manager.
894 *
895 * @return string
896 */
897 public function getVersion()
898 {
899 return $this->_sUamVersion;
900 }
901
902 /**
903 * Returns true if a user is at the admin panel.
904 *
905 * @return boolean
906 */
907 public function atAdminPanel()
908 {
909 return $this->_blAtAdminPanel;
910 }
911
912 /**
913 * Sets the atAdminPanel var to true.
914 */
915 public function setAtAdminPanel()
916 {
917 $this->_blAtAdminPanel = true;
918 }
919
920
921 /*
922 * Helper functions.
923 */
924
925 /**
926 * Checks if a string starts with the given needle.
927 *
928 * @param string $sHaystack The haystack.
929 * @param string $sNeedle The needle.
930 *
931 * @return boolean
932 */
933 public function startsWith($sHaystack, $sNeedle)
934 {
935 return $sNeedle === '' || strpos($sHaystack, $sNeedle) === 0;
936 }
937
938 /**
939 * Checks if a string ends with the given needle.
940 *
941 * @param string $sHaystack
942 * @param string $sNeedle
943 *
944 * @return bool
945 */
946 public function endsWith($sHaystack, $sNeedle)
947 {
948 return $sNeedle === '' || substr($sHaystack, -strlen($sNeedle)) === $sNeedle;
949 }
950
951 /*
952 * Functions for the admin panel content.
953 */
954
955 /**
956 * The function for the wp_print_styles action.
957 */
958 public function addStyles()
959 {
960 wp_enqueue_style(
961 'UserAccessManagerAdmin',
962 UAM_URLPATH . "css/uamAdmin.css",
963 array() ,
964 '1.0',
965 'screen'
966 );
967
968 wp_enqueue_style(
969 'UserAccessManagerLoginForm',
970 UAM_URLPATH . "css/uamLoginForm.css",
971 array() ,
972 '1.0',
973 'screen'
974 );
975 }
976
977 /**
978 * The function for the wp_print_scripts action.
979 */
980 public function addScripts()
981 {
982 wp_enqueue_script(
983 'UserAccessManagerFunctions',
984 UAM_URLPATH . 'js/functions.js',
985 array('jquery')
986 );
987 }
988
989 /**
990 * Prints the admin page.
991 */
992 public function printAdminPage()
993 {
994 if (isset($_GET['page'])) {
995 $sAdminPage = $_GET['page'];
996
997 if ($sAdminPage == 'uam_settings') {
998 include UAM_REALPATH.'tpl/adminSettings.php';
999 } elseif ($sAdminPage == 'uam_usergroup') {
1000 include UAM_REALPATH.'tpl/adminGroup.php';
1001 } elseif ($sAdminPage == 'uam_setup') {
1002 include UAM_REALPATH.'tpl/adminSetup.php';
1003 } elseif ($sAdminPage == 'uam_about') {
1004 include UAM_REALPATH.'tpl/about.php';
1005 }
1006 }
1007 }
1008
1009 /**
1010 * Shows the error if the user has no rights to edit the content.
1011 */
1012 public function noRightsToEditContent()
1013 {
1014 $blNoRights = false;
1015
1016 if (isset($_GET['post']) && is_numeric($_GET['post'])) {
1017 $oPost = $this->getPost($_GET['post']);
1018 $blNoRights = !$this->getAccessHandler()->checkObjectAccess($oPost->post_type, $oPost->ID);
1019 }
1020
1021 if (isset($_GET['attachment_id']) && is_numeric($_GET['attachment_id']) && !$blNoRights) {
1022 $oPost = $this->getPost($_GET['attachment_id']);
1023 $blNoRights = !$this->getAccessHandler()->checkObjectAccess($oPost->post_type, $oPost->ID);
1024 }
1025
1026 if (isset($_GET['tag_ID']) && is_numeric($_GET['tag_ID']) && !$blNoRights) {
1027 $blNoRights = !$this->getAccessHandler()->checkObjectAccess(self::TERM_OBJECT_TYPE, $_GET['tag_ID']);
1028 }
1029
1030 if ($blNoRights) {
1031 wp_die(TXT_UAM_NO_RIGHTS);
1032 }
1033 }
1034
1035 /**
1036 * The function for the wp_dashboard_setup action.
1037 * Removes widgets to which a user should not have access.
1038 */
1039 public function setupAdminDashboard()
1040 {
1041 global $wp_meta_boxes;
1042
1043 if (!$this->getAccessHandler()->checkUserAccess('manage_user_groups')) {
1044 unset($wp_meta_boxes['dashboard']['normal']['core']['dashboard_recent_comments']);
1045 }
1046 }
1047
1048 /**
1049 * The function for the update_option_permalink_structure action.
1050 */
1051 public function updatePermalink()
1052 {
1053 $this->createFileProtection();
1054 }
1055
1056
1057 /*
1058 * Meta functions
1059 */
1060
1061 /**
1062 * Saves the object data to the database.
1063 *
1064 * @param string $sObjectType The object type.
1065 * @param integer $iObjectId The _iId of the object.
1066 * @param UamUserGroup[] $aUserGroups The new usergroups for the object.
1067 */
1068 protected function _saveObjectData($sObjectType, $iObjectId, $aUserGroups = null)
1069 {
1070 $oUamAccessHandler = $this->getAccessHandler();
1071 $oConfig = $this->getConfig();
1072 $aFormData = array();
1073
1074 if (isset($_POST['uam_update_groups'])) {
1075 $aFormData = $_POST;
1076 } elseif (isset($_GET['uam_update_groups'])) {
1077 $aFormData = $_GET;
1078 }
1079
1080 if (isset($aFormData['uam_update_groups'])
1081 && ($oUamAccessHandler->checkUserAccess('manage_user_groups')
1082 || $oConfig->authorsCanAddPostsToGroups() === true)
1083 ) {
1084 if ($aUserGroups === null) {
1085 $aUserGroups = (isset($aFormData['uam_usergroups']) && is_array($aFormData['uam_usergroups']))
1086 ? $aFormData['uam_usergroups'] : array();
1087 }
1088
1089 $aAddUserGroups = array_flip($aUserGroups);
1090 $aRemoveUserGroups = $oUamAccessHandler->getUserGroupsForObject($sObjectType, $iObjectId);
1091 $aUamUserGroups = $oUamAccessHandler->getUserGroups();
1092 $blRemoveOldAssignments = true;
1093
1094 if (isset($aFormData['uam_bulk_type'])) {
1095 $sBulkType = $aFormData['uam_bulk_type'];
1096
1097 if ($sBulkType === 'add') {
1098 $blRemoveOldAssignments = false;
1099 } elseif ($sBulkType === 'remove') {
1100 $aRemoveUserGroups = $aAddUserGroups;
1101 $aAddUserGroups = array();
1102 }
1103 }
1104
1105 foreach ($aUamUserGroups as $sGroupId => $oUamUserGroup) {
1106 if (isset($aRemoveUserGroups[$sGroupId])) {
1107 $oUamUserGroup->removeObject($sObjectType, $iObjectId);
1108 }
1109
1110 if (isset($aAddUserGroups[$sGroupId])) {
1111 $oUamUserGroup->addObject($sObjectType, $iObjectId);
1112 }
1113
1114 $oUamUserGroup->save($blRemoveOldAssignments);
1115 }
1116 }
1117 }
1118
1119 /**
1120 * Removes the object data.
1121 *
1122 * @param string $sObjectType The object type.
1123 * @param int $iId The object id.
1124 */
1125 protected function _removeObjectData($sObjectType, $iId)
1126 {
1127 $oDatabase = $this->getDatabase();
1128
1129 $oDatabase->delete(
1130 DB_ACCESSGROUP_TO_OBJECT,
1131 array(
1132 'object_id' => $iId ,
1133 'object_type' => $sObjectType,
1134 ),
1135 array(
1136 '%d',
1137 '%s',
1138 )
1139 );
1140 }
1141
1142
1143 /*
1144 * Functions for the post actions.
1145 */
1146
1147 /**
1148 * The function for the manage_posts_columns and
1149 * the manage_pages_columns filter.
1150 *
1151 * @param array $aDefaults The table headers.
1152 *
1153 * @return array
1154 */
1155 public function addPostColumnsHeader($aDefaults)
1156 {
1157 $aDefaults['uam_access'] = __('Access', 'user-access-manager');
1158 return $aDefaults;
1159 }
1160
1161 /**
1162 * The function for the manage_users_custom_column action.
1163 *
1164 * @param string $sColumnName The column name.
1165 * @param integer $iId The id.
1166 */
1167 public function addPostColumn($sColumnName, $iId)
1168 {
1169 if ($sColumnName == 'uam_access') {
1170 $oPost = $this->getPost($iId);
1171 echo $this->getIncludeContents(UAM_REALPATH.'tpl/objectColumn.php', $oPost->ID, $oPost->post_type);
1172 }
1173 }
1174
1175 /**
1176 * The function for the uma_post_access metabox.
1177 *
1178 * @param object $oPost The post.
1179 */
1180 public function editPostContent($oPost)
1181 {
1182 $iObjectId = $oPost->ID;
1183 include UAM_REALPATH.'tpl/postEditForm.php';
1184 }
1185
1186 public function addBulkAction($sColumnName)
1187 {
1188 if ($sColumnName == 'uam_access') {
1189 include UAM_REALPATH.'tpl/bulkEditForm.php';
1190 }
1191 }
1192
1193 /**
1194 * The function for the save_post action.
1195 *
1196 * @param mixed $mPostParam The post _iId or a array of a post.
1197 */
1198 public function savePostData($mPostParam)
1199 {
1200 if (is_array($mPostParam)) {
1201 $oPost = $this->getPost($mPostParam['ID']);
1202 } else {
1203 $oPost = $this->getPost($mPostParam);
1204 }
1205
1206 $iPostId = $oPost->ID;
1207 $sPostType = $oPost->post_type;
1208
1209 if ($sPostType == 'revision') {
1210 $iPostId = $oPost->post_parent;
1211 $oParentPost = $this->getPost($iPostId);
1212 $sPostType = $oParentPost->post_type;
1213 }
1214
1215 $this->_saveObjectData($sPostType, $iPostId);
1216 }
1217
1218 /**
1219 * The function for the attachment_fields_to_save filter.
1220 * We have to use this because the attachment actions work
1221 * not in the way we need.
1222 *
1223 * @param object $oAttachment The attachment id.
1224 *
1225 * @return object
1226 */
1227 public function saveAttachmentData($oAttachment)
1228 {
1229 $this->savePostData($oAttachment['ID']);
1230
1231 return $oAttachment;
1232 }
1233
1234 /**
1235 * The function for the delete_post action.
1236 *
1237 * @param integer $iPostId The post id.
1238 */
1239 public function removePostData($iPostId)
1240 {
1241 $oDatabase = $this->getDatabase();
1242 $oPost = $this->getPost($iPostId);
1243
1244 $oDatabase->delete(
1245 DB_ACCESSGROUP_TO_OBJECT,
1246 array(
1247 'object_id' => $iPostId,
1248 'object_type' => $oPost->post_type,
1249 ),
1250 array(
1251 '%d',
1252 '%s',
1253 )
1254 );
1255 }
1256
1257 /**
1258 * The function for the media_meta action.
1259 *
1260 * @param string $sMeta The meta.
1261 * @param object $oPost The post.
1262 *
1263 * @return string
1264 */
1265 public function showMediaFile($sMeta = '', $oPost = null)
1266 {
1267 $sContent = $sMeta;
1268 $sContent .= '</td></tr><tr>';
1269 $sContent .= '<th class="label">';
1270 $sContent .= '<label>'.TXT_UAM_SET_UP_USERGROUPS.'</label>';
1271 $sContent .= '</th>';
1272 $sContent .= '<td class="field">';
1273 $sContent .= $this->getIncludeContents(UAM_REALPATH.'tpl/postEditForm.php', $oPost->ID);
1274
1275 return $sContent;
1276 }
1277
1278
1279 /*
1280 * Functions for the user actions.
1281 */
1282
1283 /**
1284 * The function for the manage_users_columns filter.
1285 *
1286 * @param array $aDefaults The table headers.
1287 *
1288 * @return array
1289 */
1290 public function addUserColumnsHeader($aDefaults)
1291 {
1292 $aDefaults['uam_access'] = __('uam user groups');
1293 return $aDefaults;
1294 }
1295
1296 /**
1297 * The function for the manage_users_custom_column action.
1298 *
1299 * @param string $sReturn The normal return value.
1300 * @param string $sColumnName The column name.
1301 * @param integer $iId The id.
1302 *
1303 * @return string|null
1304 */
1305 public function addUserColumn($sReturn, $sColumnName, $iId)
1306 {
1307 if ($sColumnName == 'uam_access') {
1308 return $this->getIncludeContents(UAM_REALPATH.'tpl/userColumn.php', $iId, self::USER_OBJECT_TYPE);
1309 }
1310
1311 return $sReturn;
1312 }
1313
1314 /**
1315 * The function for the edit_user_profile action.
1316 */
1317 public function showUserProfile()
1318 {
1319 echo $this->getIncludeContents(UAM_REALPATH.'tpl/userProfileEditForm.php');
1320 }
1321
1322 /**
1323 * The function for the profile_update action.
1324 *
1325 * @param integer $iUserId The user id.
1326 */
1327 public function saveUserData($iUserId)
1328 {
1329 $this->_saveObjectData(self::USER_OBJECT_TYPE, $iUserId);
1330 }
1331
1332 /**
1333 * The function for the delete_user action.
1334 *
1335 * @param integer $iUserId The user id.
1336 */
1337 public function removeUserData($iUserId)
1338 {
1339 $this->_removeObjectData(self::USER_OBJECT_TYPE, $iUserId);
1340 }
1341
1342
1343 /*
1344 * Functions for the term actions.
1345 */
1346
1347 /**
1348 * The function for the manage_categories_columns filter.
1349 *
1350 * @param array $aDefaults The table headers.
1351 *
1352 * @return array
1353 */
1354 public function addTermColumnsHeader($aDefaults)
1355 {
1356 $aDefaults['uam_access'] = __('Access', 'user-access-manager');
1357 return $aDefaults;
1358 }
1359
1360 /**
1361 * The function for the manage_categories_custom_column action.
1362 *
1363 * @param string $sEmpty An empty string from wordpress? What the hell?!?
1364 * @param string $sColumnName The column name.
1365 * @param integer $iId The id.
1366 *
1367 * @return string|null
1368 */
1369 public function addTermColumn($sEmpty, $sColumnName, $iId)
1370 {
1371 if ($sColumnName == 'uam_access') {
1372 return $this->getIncludeContents(UAM_REALPATH.'tpl/objectColumn.php', $iId, self::TERM_OBJECT_TYPE);
1373 }
1374
1375 return null;
1376 }
1377
1378 /**
1379 * The function for the edit_{term}_form action.
1380 *
1381 * @param object $oTerm The term.
1382 */
1383 public function showTermEditForm($oTerm)
1384 {
1385 include UAM_REALPATH.'tpl/termEditForm.php';
1386 }
1387
1388 /**
1389 * The function for the edit_{term} action.
1390 *
1391 * @param integer $iTermId The term id.
1392 */
1393 public function saveTermData($iTermId)
1394 {
1395 $this->_saveObjectData(self::TERM_OBJECT_TYPE, $iTermId);
1396 }
1397
1398 /**
1399 * The function for the delete_{term} action.
1400 *
1401 * @param integer $iTermId The id of the term.
1402 */
1403 public function removeTermData($iTermId)
1404 {
1405 $this->_removeObjectData(self::TERM_OBJECT_TYPE, $iTermId);
1406 }
1407
1408
1409 /*
1410 * Functions for the pluggable object actions.
1411 */
1412
1413 /**
1414 * The function for the pluggable save action.
1415 *
1416 * @param string $sObjectType The name of the pluggable object.
1417 * @param integer $iObjectId The pluggable object id.
1418 * @param array $aUserGroups The user groups for the object.
1419 */
1420 public function savePlObjectData($sObjectType, $iObjectId, $aUserGroups = null)
1421 {
1422 $this->_saveObjectData($sObjectType, $iObjectId, $aUserGroups);
1423 }
1424
1425 /**
1426 * The function for the pluggable remove action.
1427 *
1428 * @param string $sObjectName The name of the pluggable object.
1429 * @param integer $iObjectId The pluggable object id.
1430 */
1431 public function removePlObjectData($sObjectName, $iObjectId)
1432 {
1433 $this->_removeObjectData($sObjectName, $iObjectId);
1434 }
1435
1436 /**
1437 * Returns the group selection form for pluggable objects.
1438 *
1439 * @param string $sObjectType The object type.
1440 * @param integer $iObjectId The _iId of the object.
1441 * @param string $aGroupsFormName The name of the form which contains the groups.
1442 *
1443 * @return string;
1444 */
1445 public function showPlGroupSelectionForm($sObjectType, $iObjectId, $aGroupsFormName = null)
1446 {
1447 $sFileName = UAM_REALPATH.'tpl/groupSelectionForm.php';
1448 $aUamUserGroups = $this->getAccessHandler()->getUserGroups();
1449 $aUserGroupsForObject = $this->getAccessHandler()->getUserGroupsForObject($sObjectType, $iObjectId);
1450
1451 if (is_file($sFileName)) {
1452 ob_start();
1453 include $sFileName;
1454 $sContents = ob_get_contents();
1455 ob_end_clean();
1456
1457 return $sContents;
1458 }
1459
1460 return '';
1461 }
1462
1463 /**
1464 * Returns the column for a pluggable object.
1465 *
1466 * @param string $sObjectType The object type.
1467 * @param integer $iObjectId The object id.
1468 *
1469 * @return string
1470 */
1471 public function getPlColumn($sObjectType, $iObjectId)
1472 {
1473 return $this->getIncludeContents(UAM_REALPATH.'tpl/objectColumn.php', $iObjectId, $sObjectType);
1474 }
1475
1476
1477 /*
1478 * Functions for the blog content.
1479 */
1480
1481 /**
1482 * Manipulates the wordpress query object to filter content.
1483 *
1484 * @param object $oWpQuery The wordpress query object.
1485 */
1486 public function parseQuery($oWpQuery)
1487 {
1488 $oUamAccessHandler = $this->getAccessHandler();
1489 $aExcludedPosts = $oUamAccessHandler->getExcludedPosts();
1490 $aAllExcludedPosts = $aExcludedPosts['all'];
1491
1492 if (count($aAllExcludedPosts) > 0) {
1493 $oWpQuery->query_vars['post__not_in'] = array_merge(
1494 $oWpQuery->query_vars['post__not_in'],
1495 $aAllExcludedPosts
1496 );
1497 }
1498 }
1499
1500 /**
1501 * Modifies the content of the post by the given settings.
1502 *
1503 * @param object $oPost The current post.
1504 *
1505 * @return object|null
1506 */
1507 protected function _processPost($oPost)
1508 {
1509 $oConfig = $this->getConfig();
1510 $oUamAccessHandler = $this->getAccessHandler();
1511
1512 $sPostType = $oPost->post_type;
1513
1514 if ($this->getAccessHandler()->isPostableType($sPostType)
1515 && $sPostType != UserAccessManager::POST_OBJECT_TYPE
1516 && $sPostType != UserAccessManager::PAGE_OBJECT_TYPE
1517 ) {
1518 $sPostType = UserAccessManager::POST_OBJECT_TYPE;
1519 } elseif ($sPostType != UserAccessManager::POST_OBJECT_TYPE
1520 && $sPostType != UserAccessManager::PAGE_OBJECT_TYPE
1521 ) {
1522 return $oPost;
1523 }
1524
1525 if ($oConfig->hideObjectType($sPostType) === true || $this->atAdminPanel()) {
1526 if ($oUamAccessHandler->checkObjectAccess($oPost->post_type, $oPost->ID)) {
1527 $oPost->post_title .= $this->adminOutput($oPost->post_type, $oPost->ID);
1528 return $oPost;
1529 }
1530 } else {
1531 if (!$oUamAccessHandler->checkObjectAccess($oPost->post_type, $oPost->ID)) {
1532 $oPost->isLocked = true;
1533
1534 $sUamPostContent = $oConfig->getObjectTypeContent($sPostType);
1535 $sUamPostContent = str_replace('[LOGIN_FORM]', $this->getLoginBarHtml(), $sUamPostContent);
1536
1537 if ($oConfig->hideObjectTypeTitle($sPostType) === true) {
1538 $oPost->post_title = $oConfig->getObjectTypeTitle($sPostType);
1539 }
1540
1541 if ($oConfig->hideObjectTypeComments($sPostType) === false) {
1542 $oPost->comment_status = 'close';
1543 }
1544
1545 if ($sPostType === 'post'
1546 && $oConfig->showPostContentBeforeMore() === true
1547 && preg_match('/<!--more(.*?)?-->/', $oPost->post_content, $aMatches)
1548 ) {
1549 $oPost->post_content = explode($aMatches[0], $oPost->post_content, 2);
1550 $sUamPostContent = $oPost->post_content[0] . " " . $sUamPostContent;
1551 }
1552
1553 $oPost->post_content = stripslashes($sUamPostContent);
1554 }
1555
1556 $oPost->post_title .= $this->adminOutput($oPost->post_type, $oPost->ID);
1557
1558 return $oPost;
1559 }
1560
1561 return null;
1562 }
1563
1564 /**
1565 * The function for the the_posts filter.
1566 *
1567 * @param array $aPosts The posts.
1568 *
1569 * @return array
1570 */
1571 public function showPosts($aPosts = array())
1572 {
1573 $aShowPosts = array();
1574 $oConfig = $this->getConfig();
1575
1576 if (!is_feed() || ($oConfig->protectFeed() === true && is_feed())) {
1577 foreach ($aPosts as $iPostId) {
1578 if ($iPostId !== null) {
1579 $oPost = $this->_processPost($iPostId);
1580
1581 if ($oPost !== null) {
1582 $aShowPosts[] = $oPost;
1583 }
1584 }
1585 }
1586
1587 $aPosts = $aShowPosts;
1588 }
1589
1590 return $aPosts;
1591 }
1592
1593 /**
1594 * The function for the posts_where_paged filter.
1595 *
1596 * @param string $sSql The where sql statement.
1597 *
1598 * @return string
1599 */
1600 public function showPostSql($sSql)
1601 {
1602 $oUamAccessHandler = $this->getAccessHandler();
1603 $oDatabase = $this->getDatabase();
1604 $aExcludedPosts = $oUamAccessHandler->getExcludedPosts();
1605 $aAllExcludedPosts = $aExcludedPosts['all'];
1606
1607 if (count($aAllExcludedPosts) > 0) {
1608 $sExcludedPostsStr = implode(',', $aAllExcludedPosts);
1609 $sSql .= " AND $oDatabase->posts.ID NOT IN($sExcludedPostsStr) ";
1610 }
1611
1612 return $sSql;
1613 }
1614
1615 /**
1616 * Function for the wp_count_posts filter.
1617 *
1618 * @param stdClass $oCounts
1619 * @param string $sType
1620 *
1621 * @return stdClass
1622 */
1623 public function showPostCount($oCounts, $sType)
1624 {
1625 $aExcludedPosts = $this->getAccessHandler()->getExcludedPosts();
1626
1627 if (isset($aExcludedPosts[$sType])) {
1628 $oCounts->publish -= count($aExcludedPosts[$sType]);
1629 }
1630
1631 return $oCounts;
1632 }
1633
1634 /**
1635 * Sets the excluded terms as argument.
1636 *
1637 * @param array $aArguments
1638 *
1639 * @return array
1640 */
1641 public function getTermArguments($aArguments)
1642 {
1643 $aExclude = (isset($aArguments['exclude'])) ? wp_parse_id_list($aArguments['exclude']) : array();
1644 $aExcludedTerms = $this->getAccessHandler()->getExcludedTerms();
1645
1646 if ($this->getConfig()->lockRecursive() === true) {
1647 $aTermTreeMap = $this->getTermTreeMap();
1648
1649 foreach ($aExcludedTerms as $sTermId) {
1650 if (isset($aTermTreeMap[$sTermId])) {
1651 $aExcludedTerms = array_merge($aExcludedTerms, array_keys($aTermTreeMap[$sTermId]));
1652 }
1653 }
1654 }
1655
1656 $aArguments['exclude'] = array_merge($aExclude, $aExcludedTerms);
1657
1658 return $aArguments;
1659 }
1660
1661 /**
1662 * The function for the wp_get_nav_menu_items filter.
1663 *
1664 * @param array $aItems The menu item.
1665 *
1666 * @return array
1667 */
1668 public function showCustomMenu($aItems)
1669 {
1670 $aShowItems = array();
1671 $aTaxonomies = $this->getTaxonomies();
1672
1673 foreach ($aItems as $oItem) {
1674 if ($oItem->object == UserAccessManager::POST_OBJECT_TYPE
1675 || $oItem->object == UserAccessManager::PAGE_OBJECT_TYPE
1676 ) {
1677 $oObject = $this->getPost($oItem->object_id);
1678
1679 if ($oObject !== null) {
1680 $oPost = $this->_processPost($oObject);
1681
1682 if ($oPost !== null) {
1683 if (isset($oPost->isLocked)) {
1684 $oItem->title = $oPost->post_title;
1685 }
1686
1687 $oItem->title .= $this->adminOutput($oItem->object, $oItem->object_id);
1688 $aShowItems[] = $oItem;
1689 }
1690 }
1691 } elseif (isset($aTaxonomies[$oItem->object])) {
1692 $oObject = $this->getTerm($oItem->object_id);
1693 $oCategory = $this->_processTerm($oObject);
1694
1695 if ($oCategory !== null && !$oCategory->isEmpty) {
1696 $oItem->title .= $this->adminOutput($oItem->object, $oItem->object_id);
1697 $aShowItems[] = $oItem;
1698 }
1699 } else {
1700 $aShowItems[] = $oItem;
1701 }
1702 }
1703
1704 return $aShowItems;
1705 }
1706
1707 /**
1708 * The function for the comments_array filter.
1709 *
1710 * @param array $aComments The comments.
1711 *
1712 * @return array
1713 */
1714 public function showComment($aComments = array())
1715 {
1716 $aShowComments = array();
1717 $oConfig = $this->getConfig();
1718 $oUamAccessHandler = $this->getAccessHandler();
1719
1720 foreach ($aComments as $oComment) {
1721 $oPost = $this->getPost($oComment->comment_post_ID);
1722 $sPostType = $oPost->post_type;
1723
1724 if ($oConfig->hideObjectTypeComments($sPostType) === true
1725 || $oConfig->hideObjectType($sPostType) === true
1726 || $this->atAdminPanel()
1727 ) {
1728 if ($oUamAccessHandler->checkObjectAccess($oPost->post_type, $oPost->ID)) {
1729 $aShowComments[] = $oComment;
1730 }
1731 } else {
1732 if (!$oUamAccessHandler->checkObjectAccess($oPost->post_type, $oPost->ID)) {
1733 $oComment->comment_content = $oConfig->getObjectTypeCommentContent($sPostType);
1734 }
1735
1736 $aShowComments[] = $oComment;
1737 }
1738 }
1739
1740 $aComments = $aShowComments;
1741
1742 return $aComments;
1743 }
1744
1745 /**
1746 * The function for the get_pages filter.
1747 *
1748 * @param array $aPages The pages.
1749 *
1750 * @return array
1751 */
1752 public function showPages($aPages = array())
1753 {
1754 $aShowPages = array();
1755 $oConfig = $this->getConfig();
1756 $oUamAccessHandler = $this->getAccessHandler();
1757
1758 foreach ($aPages as $oPage) {
1759 if ($oConfig->hidePage() === true
1760 || $this->atAdminPanel()
1761 ) {
1762 if ($oUamAccessHandler->checkObjectAccess($oPage->post_type, $oPage->ID)) {
1763 $oPage->post_title .= $this->adminOutput(
1764 $oPage->post_type,
1765 $oPage->ID
1766 );
1767 $aShowPages[] = $oPage;
1768 }
1769 } else {
1770 if (!$oUamAccessHandler->checkObjectAccess($oPage->post_type, $oPage->ID)) {
1771 if ($oConfig->hidePageTitle() === true) {
1772 $oPage->post_title = $oConfig->getPageTitle();
1773 }
1774
1775 $oPage->post_content = $oConfig->getPageContent();
1776 }
1777
1778 $oPage->post_title .= $this->adminOutput($oPage->post_type, $oPage->ID);
1779 $aShowPages[] = $oPage;
1780 }
1781 }
1782
1783 $aPages = $aShowPages;
1784
1785 return $aPages;
1786 }
1787
1788 /**
1789 * Resolves all sub elements
1790 *
1791 * @param array $aTree
1792 * @param string $iId
1793 *
1794 * @return array
1795 */
1796 protected function _processTreeMapSiblings(&$aTree, $iId)
1797 {
1798 foreach ($aTree[$iId] as $iChildId => $sType) {
1799 if (isset($aTree[$iChildId])) {
1800 $aSiblings = $this->_processTreeMapSiblings($aTree, $iChildId);
1801 $aTree[$iId] = $aTree[$iId] + $aSiblings;
1802 }
1803 }
1804
1805 return $aTree[$iId];
1806 }
1807
1808 /**
1809 * Returns the tree map for the query.
1810 *
1811 * @param string $sSelect
1812 *
1813 * @return array
1814 */
1815 protected function _getTreeMap($sSelect)
1816 {
1817 $aTree = array();
1818 $oDatabase = $this->getDatabase();
1819 $aResults = $oDatabase->get_results($sSelect);
1820
1821 foreach ($aResults as $oResult) {
1822 if (!isset($aTree[$oResult->parentId])) {
1823 $aTree[$oResult->parentId] = array();
1824 }
1825
1826 $aTree[$oResult->parentId][$oResult->id] = $oResult->type;
1827 }
1828
1829 //Add siblings
1830 foreach ($aTree as $iParentId => $aChildren) {
1831 $this->_processTreeMapSiblings($aTree, $iParentId);
1832 }
1833
1834 return $aTree;
1835 }
1836
1837 /**
1838 * Returns the post tree map.
1839 *
1840 * @return array
1841 */
1842 public function getPostTreeMap()
1843 {
1844 if ($this->_aPostTreeMap === null) {
1845 $oDatabase = $this->getDatabase();
1846
1847 $sSelect = "
1848 SELECT ID AS id, post_parent AS parentId, post_type AS type
1849 FROM {$oDatabase->posts}
1850 WHERE post_parent != 0";
1851
1852 $this->_aPostTreeMap = $this->_getTreeMap($sSelect);
1853 }
1854
1855 return $this->_aPostTreeMap;
1856 }
1857
1858 /**
1859 * Returns the term post map.
1860 *
1861 * @return array
1862 */
1863 public function getTermPostMap()
1864 {
1865 if ($this->_aTermPostMap === null) {
1866 $this->_aTermPostMap = array();
1867 $oDatabase = $this->getDatabase();
1868
1869 $sSelect = "
1870 SELECT tr.object_id, tr.term_taxonomy_id, p.post_type
1871 FROM {$oDatabase->term_relationships} AS tr LEFT JOIN {$oDatabase->posts} as p
1872 ON (tr.object_id = p.ID)";
1873
1874 $aResults = $oDatabase->get_results($sSelect);
1875
1876 foreach ($aResults as $oResult) {
1877 if (!isset($this->_aTermPostMap[$oResult->term_taxonomy_id])) {
1878 $this->_aTermPostMap[$oResult->term_taxonomy_id] = array();
1879 }
1880
1881 $this->_aTermPostMap[$oResult->term_taxonomy_id][$oResult->object_id] = $oResult->post_type;
1882 }
1883 }
1884
1885 return $this->_aTermPostMap;
1886 }
1887
1888 /**
1889 * Returns the term tree map.
1890 *
1891 * @return array
1892 */
1893 public function getTermTreeMap()
1894 {
1895 if ($this->_aTermTreeMap === null) {
1896 $oDatabase = $this->getDatabase();
1897 $sSelect = "
1898 SELECT term_id AS id, parent AS parentId, taxonomy as type
1899 FROM {$oDatabase->term_taxonomy}
1900 WHERE parent != 0";
1901
1902 $this->_aTermTreeMap = $this->_getTreeMap($sSelect);
1903 }
1904
1905 return $this->_aTermTreeMap;
1906 }
1907
1908 /**
1909 * Returns the post count for the term.
1910 *
1911 * @param int $iTermId
1912 *
1913 * @return int
1914 */
1915 protected function _getVisibleElementsCount($iTermId)
1916 {
1917 $iCount = 0;
1918 $aTermPostMap = $this->getTermPostMap();
1919
1920 if (isset($aTermPostMap[$iTermId])) {
1921 foreach ($aTermPostMap[$iTermId] as $iPostId => $sPostType) {
1922 if ($this->getConfig()->hideObjectType($sPostType) === false
1923 || $this->getAccessHandler()->checkObjectAccess($sPostType, $iPostId)
1924 ) {
1925 $iCount++;
1926 }
1927 }
1928 }
1929
1930 return $iCount;
1931 }
1932
1933 /**
1934 * Modifies the content of the term by the given settings.
1935 *
1936 * @param object $oTerm The current term.
1937 *
1938 * @return object|null
1939 */
1940 protected function _processTerm($oTerm)
1941 {
1942 if (is_object($oTerm) === false) {
1943 return $oTerm;
1944 }
1945
1946 $oTerm->name .= $this->adminOutput(self::TERM_OBJECT_TYPE, $oTerm->term_id, $oTerm->name);
1947 $oConfig = $this->getConfig();
1948 $oUamAccessHandler = $this->getAccessHandler();
1949
1950 $oTerm->isEmpty = false;
1951
1952 if ($oUamAccessHandler->checkObjectAccess(self::TERM_OBJECT_TYPE, $oTerm->term_id)) {
1953 if ($oConfig->hidePost() === true || $oConfig->hidePage() === true) {
1954 $iTermRequest = $oTerm->term_id;
1955 $oTerm->count = $this->_getVisibleElementsCount($iTermRequest);
1956 $iFullCount = $oTerm->count;
1957
1958 if ($iFullCount <= 0) {
1959 $aTermTreeMap = $this->getTermTreeMap();
1960
1961 if (isset($aTermTreeMap[$iTermRequest])) {
1962 foreach ($aTermTreeMap[$iTermRequest] as $iTermId => $sType) {
1963 if ($oTerm->taxonomy === $sType) {
1964 $iFullCount += $this->_getVisibleElementsCount($iTermId);
1965
1966 if ($iFullCount > 0) {
1967 break;
1968 }
1969 }
1970 }
1971 }
1972 }
1973
1974 //For categories
1975 if ($iFullCount <= 0
1976 && $this->atAdminPanel() === false
1977 && $oConfig->hideEmptyCategories() === true
1978 && ($oTerm->taxonomy == 'term' || $oTerm->taxonomy == 'category')
1979 ) {
1980 $oTerm->isEmpty = true;
1981 }
1982
1983 if ($oConfig->lockRecursive() === false) {
1984 $oCurrentTerm = $oTerm;
1985
1986 while ($oCurrentTerm->parent != 0) {
1987 $oCurrentTerm = $this->getTerm($oCurrentTerm->parent);
1988
1989 if ($oUamAccessHandler->checkObjectAccess(UserAccessManager::TERM_OBJECT_TYPE, $oCurrentTerm->term_id)) {
1990 $oTerm->parent = $oCurrentTerm->term_id;
1991 break;
1992 }
1993 }
1994 }
1995 }
1996
1997 return $oTerm;
1998 }
1999
2000 return null;
2001 }
2002
2003 /**
2004 * The function for the get_ancestors filter.
2005 *
2006 * @param array $aAncestors
2007 * @param int $sObjectId
2008 * @param string $sObjectType
2009 * @param string $sResourceType
2010 *
2011 * @return array
2012 */
2013 public function showAncestors($aAncestors, $sObjectId, $sObjectType, $sResourceType)
2014 {
2015 if ($sResourceType === 'taxonomy') {
2016 $oUamAccessHandler = $this->getAccessHandler();
2017
2018 foreach ($aAncestors as $sKey => $aAncestorId) {
2019 if (!$oUamAccessHandler->checkObjectAccess(self::TERM_OBJECT_TYPE, $aAncestorId)) {
2020 unset($aAncestors[$sKey]);
2021 }
2022 }
2023 }
2024
2025 return $aAncestors;
2026 }
2027
2028 /**
2029 * The function for the get_term filter.
2030 *
2031 * @param object $oTerm
2032 *
2033 * @return null|object
2034 */
2035 public function showTerm($oTerm)
2036 {
2037 return $this->_processTerm($oTerm);
2038 }
2039
2040 /**
2041 * The function for the get_terms filter.
2042 *
2043 * @param array $aTerms The terms.
2044 * @param array $aTaxonomies The taxonomies.
2045 * @param array $aArgs The given arguments.
2046 * @param WP_Term_Query $oTermQuery The term query.
2047 *
2048 * @return array
2049 */
2050 public function showTerms($aTerms = array(), $aTaxonomies = array(), $aArgs = array(), $oTermQuery = null)
2051 {
2052 $aShowTerms = array();
2053
2054 foreach ($aTerms as $mTerm) {
2055 if (!is_object($mTerm) && is_numeric($mTerm)) {
2056 if ((int)$mTerm === 0) {
2057 continue;
2058 }
2059
2060 $mTerm = $this->getTerm($mTerm);
2061 }
2062
2063 $mTerm = $this->_processTerm($mTerm);
2064
2065 if ($mTerm !== null && (!isset($mTerm->isEmpty) || !$mTerm->isEmpty)) {
2066 $aShowTerms[$mTerm->term_id] = $mTerm;
2067 }
2068 }
2069
2070 foreach ($aTerms as $sKey => $mTerm) {
2071 if ($mTerm === null || is_object($mTerm) && !isset($aShowTerms[$mTerm->term_id])) {
2072 unset($aTerms[$sKey]);
2073 }
2074 }
2075
2076 return $aTerms;
2077 }
2078
2079 /**
2080 * The function for the get_previous_post_where and
2081 * the get_next_post_where filter.
2082 *
2083 * @param string $sSql The current sql string.
2084 *
2085 * @return string
2086 */
2087 public function showNextPreviousPost($sSql)
2088 {
2089 $oUamAccessHandler = $this->getAccessHandler();
2090 $aExcludedPosts = $oUamAccessHandler->getExcludedPosts();
2091 $aAllExcludedPosts = $aExcludedPosts['all'];
2092
2093 if (count($aAllExcludedPosts) > 0) {
2094 $sExcludedPosts = implode(',', $aAllExcludedPosts);
2095 $sSql.= " AND p.ID NOT IN({$sExcludedPosts}) ";
2096 }
2097
2098 return $sSql;
2099 }
2100
2101 /**
2102 * Returns the admin hint.
2103 *
2104 * @param string $sObjectType The object type.
2105 * @param integer $iObjectId The object id we want to check.
2106 * @param string $sText The text on which we want to append the hint.
2107 *
2108 * @return string
2109 */
2110 public function adminOutput($sObjectType, $iObjectId, $sText = null)
2111 {
2112 $sOutput = '';
2113
2114 if (!$this->atAdminPanel()) {
2115 $oConfig = $this->getConfig();
2116
2117 if ($oConfig->blogAdminHint() === true) {
2118 $sHintText = $oConfig->getBlogAdminHintText();
2119
2120 if ($sText !== null && $this->endsWith($sText, $sHintText)) {
2121 return $sOutput;
2122 }
2123
2124 $oCurrentUser = $this->getCurrentUser();
2125 $oUserData = $this->getUser($oCurrentUser->ID);
2126
2127 if (!isset($oUserData->user_level)) {
2128 return $sOutput;
2129 }
2130
2131 $oUamAccessHandler = $this->getAccessHandler();
2132
2133 if ($oUamAccessHandler->userIsAdmin($oCurrentUser->ID)
2134 && count($oUamAccessHandler->getUserGroupsForObject($sObjectType, $iObjectId)) > 0
2135 ) {
2136 $sOutput .= $sHintText;
2137 }
2138 }
2139 }
2140
2141 return $sOutput;
2142 }
2143
2144 /**
2145 * The function for the edit_post_link filter.
2146 *
2147 * @param string $sLink The edit link.
2148 * @param integer $iPostId The _iId of the post.
2149 *
2150 * @return string
2151 */
2152 public function showGroupMembership($sLink, $iPostId)
2153 {
2154 $oUamAccessHandler = $this->getAccessHandler();
2155 $aGroups = $oUamAccessHandler->getUserGroupsForObject(self::POST_OBJECT_TYPE, $iPostId);
2156
2157 if (count($aGroups) > 0) {
2158 $sLink .= ' | '.TXT_UAM_ASSIGNED_GROUPS.': ';
2159
2160 foreach ($aGroups as $oGroup) {
2161 $sLink .= htmlentities($oGroup->getGroupName()).', ';
2162 }
2163
2164 $sLink = rtrim($sLink, ', ');
2165 }
2166
2167 return $sLink;
2168 }
2169
2170 /**
2171 * Returns the login bar.
2172 *
2173 * @return string
2174 */
2175 public function getLoginBarHtml()
2176 {
2177 if (!is_user_logged_in()) {
2178 return $this->getIncludeContents(UAM_REALPATH.'tpl/loginBar.php');
2179 }
2180
2181 return '';
2182 }
2183
2184
2185 /*
2186 * Functions for the redirection and files.
2187 */
2188
2189 /**
2190 * Returns true if permalinks are active otherwise false.
2191 *
2192 * @return boolean
2193 */
2194 public function isPermalinksActive()
2195 {
2196 $sPermalinkStructure = $this->getConfig()->getWpOption('permalink_structure');
2197 return !empty($sPermalinkStructure);
2198 }
2199
2200 /**
2201 * Redirects to a page or to content.
2202 *
2203 * @param string $sHeaders The headers which are given from wordpress.
2204 * @param object $oPageParams The params of the current page.
2205 *
2206 * @return string
2207 */
2208 public function redirect($sHeaders, $oPageParams)
2209 {
2210 $oConfig = $this->getConfig();
2211
2212 if (isset($_GET['uamgetfile']) && isset($_GET['uamfiletype'])) {
2213 $sFileUrl = $_GET['uamgetfile'];
2214 $sFileType = $_GET['uamfiletype'];
2215 $this->getFile($sFileType, $sFileUrl);
2216 } elseif (!$this->atAdminPanel() && $oConfig->getRedirect() !== 'false') {
2217 $oObject = null;
2218
2219 if (isset($oPageParams->query_vars['p'])) {
2220 $oObject = $this->getPost($oPageParams->query_vars['p']);
2221 $oObjectType = $oObject->post_type;
2222 $iObjectId = $oObject->ID;
2223 } elseif (isset($oPageParams->query_vars['page_id'])) {
2224 $oObject = $this->getPost($oPageParams->query_vars['page_id']);
2225 $oObjectType = $oObject->post_type;
2226 $iObjectId = $oObject->ID;
2227 } elseif (isset($oPageParams->query_vars['cat_id'])) {
2228 $oObject = $this->getTerm($oPageParams->query_vars['cat_id']);
2229 $oObjectType = self::TERM_OBJECT_TYPE;
2230 $iObjectId = $oObject->term_id;
2231 } elseif (isset($oPageParams->query_vars['name'])) {
2232 $oDatabase = $this->getDatabase();
2233 $sPostableTypes = "'" . implode("','", $this->getAccessHandler()->getPostableTypes()) . "'";
2234
2235 $sQuery = $oDatabase->prepare(
2236 "SELECT ID
2237 FROM {$oDatabase->posts}
2238 WHERE post_name = %s
2239 AND post_type IN ({$sPostableTypes})",
2240 $oPageParams->query_vars['name']
2241 );
2242
2243 $sObjectId = $oDatabase->get_var($sQuery);
2244
2245 if ($sObjectId) {
2246 $oObject = get_post($sObjectId);
2247 }
2248
2249 if ($oObject !== null) {
2250 $oObjectType = $oObject->post_type;
2251 $iObjectId = $oObject->ID;
2252 }
2253 } elseif (isset($oPageParams->query_vars['pagename'])) {
2254 $oObject = get_page_by_path($oPageParams->query_vars['pagename']);
2255
2256 if ($oObject !== null) {
2257 $oObjectType = $oObject->post_type;
2258 $iObjectId = $oObject->ID;
2259 }
2260 }
2261
2262 if ($oObject !== null
2263 && isset($oObjectType)
2264 && isset($iObjectId)
2265 && !$this->getAccessHandler()->checkObjectAccess($oObjectType, $iObjectId)
2266 ) {
2267 $this->redirectUser($oObject);
2268 }
2269 }
2270
2271 return $sHeaders;
2272 }
2273
2274 /**
2275 * Returns the current url.
2276 *
2277 * @return string
2278 */
2279 public function getCurrentUrl()
2280 {
2281 if (!isset($_SERVER['REQUEST_URI'])) {
2282 $sServerRequestUri = $_SERVER['PHP_SELF'];
2283 } else {
2284 $sServerRequestUri = $_SERVER['REQUEST_URI'];
2285 }
2286
2287 $sSecure = empty($_SERVER["HTTPS"]) ? '' : ($_SERVER["HTTPS"] == "on") ? "s" : "";
2288 $aProtocols = explode("/", strtolower($_SERVER["SERVER_PROTOCOL"]));
2289 $sProtocol = $aProtocols[0].$sSecure;
2290 $sPort = ($_SERVER["SERVER_PORT"] == "80") ? "" : (":".$_SERVER["SERVER_PORT"]);
2291
2292 return $sProtocol."://".$_SERVER['SERVER_NAME'].$sPort.$sServerRequestUri;
2293 }
2294
2295 /**
2296 * Redirects the user to his destination.
2297 *
2298 * @param object $oObject The current object we want to access.
2299 */
2300 public function redirectUser($oObject = null)
2301 {
2302 global $wp_query;
2303
2304 $blPostToShow = false;
2305 $aPosts = $wp_query->get_posts();
2306
2307 if ($oObject === null && isset($aPosts)) {
2308 foreach ($aPosts as $oPost) {
2309 if ($this->getAccessHandler()->checkObjectAccess($oPost->post_type, $oPost->ID)) {
2310 $blPostToShow = true;
2311 break;
2312 }
2313 }
2314 }
2315
2316 if ($blPostToShow === false) {
2317 $oConfig = $this->getConfig();
2318 $sPermalink = null;
2319
2320 if ($oConfig->getRedirect() === 'custom_page') {
2321 $sRedirectCustomPage = $oConfig->getRedirectCustomPage();
2322 $oPost = $this->getPost($sRedirectCustomPage);
2323 $sUrl = $oPost->guid;
2324 $sPermalink = get_page_link($oPost);
2325 } elseif ($oConfig->getRedirect() === 'custom_url') {
2326 $sUrl = $oConfig->getRedirectCustomUrl();
2327 } else {
2328 $sUrl = home_url('/');
2329 }
2330
2331 if ($sUrl != $this->getCurrentUrl() && $sPermalink != $this->getCurrentUrl()) {
2332 wp_redirect($sUrl);
2333 exit;
2334 }
2335 }
2336 }
2337
2338 /**
2339 * Delivers the content of the requested file.
2340 *
2341 * @param string $sObjectType The type of the requested file.
2342 * @param string $sObjectUrl The file url.
2343 *
2344 * @return null
2345 */
2346 public function getFile($sObjectType, $sObjectUrl)
2347 {
2348 $oObject = $this->_getFileSettingsByType($sObjectType, $sObjectUrl);
2349
2350 if ($oObject === null) {
2351 return null;
2352 }
2353
2354 $sFile = null;
2355
2356 if ($this->getAccessHandler()->checkObjectAccess($oObject->type, $oObject->id)) {
2357 $sFile = $oObject->file;
2358 } elseif ($oObject->isImage) {
2359 $sFile = UAM_REALPATH.'gfx/noAccessPic.png';
2360 } else {
2361 wp_die(TXT_UAM_NO_RIGHTS);
2362 }
2363
2364 //Deliver content
2365 if (file_exists($sFile)) {
2366 $sFileName = basename($sFile);
2367
2368 /*
2369 * This only for compatibility
2370 * mime_content_type has been deprecated as the PECL extension file info
2371 * provides the same functionality (and more) in a much cleaner way.
2372 */
2373 $sFileExt = strtolower(array_pop(explode('.', $sFileName)));
2374 $aMimeTypes = $this->_getMimeTypes();
2375
2376 if (function_exists('finfo_open')) {
2377 $sFileInfo = finfo_open(FILEINFO_MIME);
2378 $sFileMimeType = finfo_file($sFileInfo, $sFile);
2379 finfo_close($sFileInfo);
2380 } elseif (function_exists('mime_content_type')) {
2381 $sFileMimeType = mime_content_type($sFile);
2382 } elseif (isset($aMimeTypes[$sFileExt])) {
2383 $sFileMimeType = $aMimeTypes[$sFileExt];
2384 } else {
2385 $sFileMimeType = 'application/octet-stream';
2386 }
2387
2388 header('Content-Description: File Transfer');
2389 header('Content-Type: '.$sFileMimeType);
2390
2391 if (!$oObject->isImage) {
2392 $sBaseName = str_replace(' ', '_', basename($sFile));
2393 header('Content-Disposition: attachment; filename="'.$sBaseName.'"');
2394 }
2395
2396 header('Content-Transfer-Encoding: binary');
2397 header('Content-Length: '.filesize($sFile));
2398
2399 $oConfig = $this->getConfig();
2400
2401 if ($oConfig->getDownloadType() === 'fopen'
2402 && !$oObject->isImage
2403 ) {
2404 $oHandler = fopen($sFile, 'r');
2405
2406 //TODO find better solution (prevent '\n' / '0A')
2407 ob_clean();
2408 flush();
2409
2410 while (!feof($oHandler)) {
2411 if (!ini_get('safe_mode')) {
2412 set_time_limit(30);
2413 }
2414
2415 echo fread($oHandler, 1024);
2416 }
2417
2418 exit;
2419 } else {
2420 ob_clean();
2421 flush();
2422 readfile($sFile);
2423 exit;
2424 }
2425 } else {
2426 wp_die(TXT_UAM_FILE_NOT_FOUND_ERROR);
2427 return null;
2428 }
2429 }
2430
2431 /**
2432 * Returns the file object by the given type and url.
2433 *
2434 * @param string $sObjectType The type of the requested file.
2435 * @param string $sObjectUrl The file url.
2436 *
2437 * @return object|null
2438 */
2439 protected function _getFileSettingsByType($sObjectType, $sObjectUrl)
2440 {
2441 $oObject = null;
2442
2443 if ($sObjectType == UserAccessManager::ATTACHMENT_OBJECT_TYPE) {
2444 $aUploadDir = wp_upload_dir();
2445 $sUploadDir = str_replace(ABSPATH, '/', $aUploadDir['basedir']);
2446 $sRegex = '/.*'.str_replace('/', '\/', $sUploadDir).'\//i';
2447 $sCleanObjectUrl = preg_replace($sRegex, '', $sObjectUrl);
2448 $sUploadUrl = str_replace('/files', $sUploadDir, $aUploadDir['baseurl']);
2449 $sObjectUrl = $sUploadUrl.'/'.ltrim($sCleanObjectUrl, '/');
2450 $oPost = $this->getPost($this->getPostIdByUrl($sObjectUrl));
2451
2452 if ($oPost !== null
2453 && $oPost->post_type == UserAccessManager::ATTACHMENT_OBJECT_TYPE
2454 ) {
2455 $oObject = new stdClass();
2456 $oObject->id = $oPost->ID;
2457 $oObject->isImage = wp_attachment_is_image($oPost->ID);
2458 $oObject->type = $sObjectType;
2459 $sMultiPath = str_replace('/files', $sUploadDir, $aUploadDir['baseurl']);
2460 $oObject->file = $aUploadDir['basedir'].str_replace($sMultiPath, '', $sObjectUrl );
2461 }
2462 } else {
2463 $aPlObject = $this->getAccessHandler()->getPlObject($sObjectType);
2464
2465 if (isset($aPlObject) && isset($aPlObject['getFileObject'])) {
2466 $oObject = $aPlObject['reference']->{$aPlObject['getFileObject']}($sObjectUrl);
2467 }
2468 }
2469
2470 return $oObject;
2471 }
2472
2473 /**
2474 * Returns the url for a locked file.
2475 *
2476 * @param string $sUrl The base url.
2477 * @param integer $iId The _iId of the file.
2478 *
2479 * @return string
2480 */
2481 public function getFileUrl($sUrl, $iId)
2482 {
2483 $oConfig = $this->getConfig();
2484
2485 if (!$this->isPermalinksActive() && $oConfig->lockFile() === true) {
2486 $oPost = &$this->getPost($iId);
2487 $aType = explode("/", $oPost->post_mime_type);
2488 $sType = $aType[1];
2489 $aFileTypes = explode(',', $oConfig->getLockedFileTypes());
2490
2491 if ($oConfig->getLockedFileTypes() === 'all' || in_array($sType, $aFileTypes)) {
2492 $sUrl = home_url('/').'?uamfiletype=attachment&uamgetfile='.$sUrl;
2493 }
2494 }
2495
2496 return $sUrl;
2497 }
2498
2499 /**
2500 * Returns the post by the given url.
2501 *
2502 * @param string $sUrl The url of the post(attachment).
2503 *
2504 * @return object The post.
2505 */
2506 public function getPostIdByUrl($sUrl)
2507 {
2508 if (isset($this->_aPostUrls[$sUrl])) {
2509 return $this->_aPostUrls[$sUrl];
2510 }
2511
2512 $this->_aPostUrls[$sUrl] = null;
2513
2514 //Filter edit string
2515 $sNewUrl = preg_split("/-e[0-9]{1,}/", $sUrl);
2516
2517 if (count($sNewUrl) == 2) {
2518 $sNewUrl = $sNewUrl[0].$sNewUrl[1];
2519 } else {
2520 $sNewUrl = $sNewUrl[0];
2521 }
2522
2523 //Filter size
2524 $sNewUrl = preg_split("/-[0-9]{1,}x[0-9]{1,}/", $sNewUrl);
2525
2526 if (count($sNewUrl) == 2) {
2527 $sNewUrl = $sNewUrl[0].$sNewUrl[1];
2528 } else {
2529 $sNewUrl = $sNewUrl[0];
2530 }
2531
2532 $oDatabase = $this->getDatabase();
2533
2534 $sSql = $oDatabase->prepare(
2535 "SELECT ID
2536 FROM ".$oDatabase->prefix."posts
2537 WHERE guid = '%s'
2538 LIMIT 1",
2539 $sNewUrl
2540 );
2541
2542 $oDbPost = $oDatabase->get_row($sSql);
2543
2544 if ($oDbPost) {
2545 $this->_aPostUrls[$sUrl] = $oDbPost->ID;
2546 }
2547
2548 return $this->_aPostUrls[$sUrl];
2549 }
2550
2551 /**
2552 * Caches the urls for the post for a later lookup.
2553 *
2554 * @param string $sUrl The url of the post.
2555 * @param object $oPost The post object.
2556 *
2557 * @return string
2558 */
2559 public function cachePostLinks($sUrl, $oPost)
2560 {
2561 $this->_aPostUrls[$sUrl] = $oPost->ID;
2562 return $sUrl;
2563 }
2564
2565 /**
2566 * Filter for Yoast SEO Plugin
2567 *
2568 * Hides the url from the site map if the user has no access
2569 *
2570 * @param string $sUrl The url to check
2571 * @param string $sType The object type
2572 * @param object $oObject The object
2573 *
2574 * @return false|string
2575 */
2576 function wpSeoUrl($sUrl, $sType, $oObject)
2577 {
2578 return ($this->getAccessHandler()->checkObjectAccess($sType, $oObject->ID)) ? $sUrl : false;
2579 }
2580 }
2581