PluginProbe
User Access Manager / 1.2.11
User Access Manager v1.2.11
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.11, at class/UserAccessManager.php

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