* @copyright 2008-2017 Alexander Schneider * @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 * @version SVN: $id$ * @link http://wordpress.org/extend/plugins/user-access-manager/ */ namespace UserAccessManager\Object; use UserAccessManager\ObjectMembership\MissingObjectMembershipHandlerException; use UserAccessManager\ObjectMembership\ObjectMembershipHandler; use UserAccessManager\ObjectMembership\ObjectMembershipHandlerFactory; use UserAccessManager\Wrapper\Php; use UserAccessManager\Wrapper\Wordpress; /** * Class ObjectHandler * * @package UserAccessManager\ObjectHandler */ class ObjectHandler { const GENERAL_ROLE_OBJECT_TYPE = '_role_'; const GENERAL_USER_OBJECT_TYPE = '_user_'; const GENERAL_POST_OBJECT_TYPE = '_post_'; const GENERAL_TERM_OBJECT_TYPE = '_term_'; const ATTACHMENT_OBJECT_TYPE = 'attachment'; const POST_OBJECT_TYPE = 'post'; const PAGE_OBJECT_TYPE = 'page'; const POST_FORMAT_TYPE = 'post_format'; /** * @var Php */ private $php; /** * @var Wordpress */ private $wordpress; /** * @var ObjectMembershipHandlerFactory */ private $membershipHandlerFactory; /** * @var null|array */ private $postTypes = null; /** * @var null|array */ private $taxonomies = null; /** * @var \WP_User */ private $users = null; /** * @var \WP_Post[] */ private $posts = null; /** * @var \WP_Term[] */ private $terms = null; /** * @var null|array */ private $objectMembershipHandlers = null; /** * @var null|array */ private $objectTypes = null; /** * @var null|array */ private $allObjectTypesMap = null; /** * @var null|array */ private $allObjectTypes = null; /** * @var array */ private $validObjectTypes = []; /** * ObjectHandler constructor. * * @param Php $php * @param Wordpress $wordpress * @param ObjectMembershipHandlerFactory $membershipHandlerFactory */ public function __construct( Php $php, Wordpress $wordpress, ObjectMembershipHandlerFactory $membershipHandlerFactory ) { $this->php = $php; $this->wordpress = $wordpress; $this->membershipHandlerFactory = $membershipHandlerFactory; } /** * Returns all post types. * * @return array */ public function getPostTypes() { if ($this->postTypes === null) { $this->postTypes = $this->wordpress->getPostTypes(['public' => true]); } return $this->postTypes; } /** * Returns the taxonomies. * * @return array */ public function getTaxonomies() { if ($this->taxonomies === null) { $this->taxonomies = $this->wordpress->getTaxonomies(['public' => true]); } return $this->taxonomies; } /** * Returns a user. * * @param int|string $id The user id. * * @return \WP_User|false */ public function getUser($id) { if (isset($this->users[$id]) === false) { $this->users[$id] = $this->wordpress->getUserData($id); } return $this->users[$id]; } /** * Returns a post. * * @param int $id The post id. * * @return \WP_Post|false */ public function getPost($id) { if (isset($this->posts[$id]) === false) { $post = $this->wordpress->getPost($id); $this->posts[$id] = ($post instanceof \WP_Post) ? $post : false; } return $this->posts[$id]; } /** * Returns a term. * * @param int $id The term id. * @param string $taxonomy The taxonomy. * * @return false|\WP_Term */ public function getTerm($id, $taxonomy = '') { $fullId = $id.'|'.$taxonomy; if (isset($this->terms[$fullId]) === false) { $term = $this->wordpress->getTerm($id, $taxonomy); $this->terms[$fullId] = ($term instanceof \WP_Term) ? $term : false; } return $this->terms[$fullId]; } /** * Used for adding custom post types using the registered_post_type hook * @see http://wordpress.org/support/topic/modifying-post-type-using-the-registered_post_type-hook * * @param string $postType The string for the new post_type * @param \WP_Post_Type $arguments The array of arguments used to create the post_type */ public function registeredPostType($postType, \WP_Post_Type $arguments) { if ((bool)$arguments->public === true) { $this->postTypes = $this->getPostTypes(); $this->postTypes[$postType] = $postType; $this->objectTypes = null; $this->allObjectTypes = null; $this->allObjectTypesMap = null; $this->validObjectTypes = []; } } /** * Adds an custom taxonomy. * * @param string $taxonomy * @param string $objectType * @param array $arguments */ public function registeredTaxonomy($taxonomy, $objectType, array $arguments) { if ((bool)$arguments['public'] === true) { $this->taxonomies = $this->getTaxonomies(); $this->taxonomies[$taxonomy] = $taxonomy; $this->objectTypes = null; $this->allObjectTypes = null; $this->allObjectTypesMap = null; $this->validObjectTypes = []; } } /** * Checks if type is postable. * * @param string $type * * @return bool */ public function isPostType($type) { $postableTypes = $this->getPostTypes(); return isset($postableTypes[$type]); } /** * Checks if the taxonomy is a valid one. * * @param string $taxonomy * * @return bool */ public function isTaxonomy($taxonomy) { $taxonomies = $this->getTaxonomies(); return in_array($taxonomy, $taxonomies); } /** * Returns the predefined object types. * * @return array */ public function getObjectTypes() { if ($this->objectTypes === null) { $this->objectTypes = array_merge( $this->getPostTypes(), $this->getTaxonomies() ); } return $this->objectTypes; } /** * Returns the object types map. * * @return array */ private function getAllObjectsTypesMap() { if ($this->allObjectTypesMap === null) { $this->allObjectTypesMap = []; $objectHandlers = $this->getObjectMembershipHandlers(); foreach ($objectHandlers as $objectHandler) { $handledObjects = $objectHandler->getHandledObjects(); if ($handledObjects === []) { continue; } $handledObjectsMap = array_combine( $handledObjects, $this->php->arrayFill(0, count($handledObjects), $objectHandler->getGeneralObjectType()) ); $this->allObjectTypesMap = array_merge($this->allObjectTypesMap, $handledObjectsMap); } } return $this->allObjectTypesMap; } /** * Returns all objects types. * * @return array */ public function getAllObjectTypes() { if ($this->allObjectTypes === null) { $objectTypes = array_keys($this->getAllObjectsTypesMap()); $this->allObjectTypes = array_combine($objectTypes, $objectTypes); } return $this->allObjectTypes; } /** * Returns the general object type. * * @param string $objectType * * @return string */ public function getGeneralObjectType($objectType) { $objectsTypeMap = $this->getAllObjectsTypesMap(); return (isset($objectsTypeMap[$objectType]) === true) ? $objectsTypeMap[$objectType] : null; } /** * Checks if the object type is a valid one. * * @param string $objectType The object type to check. * * @return bool */ public function isValidObjectType($objectType) { if (isset($this->validObjectTypes[$objectType]) === false) { $objectTypesMap = $this->getAllObjectTypes(); $this->validObjectTypes[$objectType] = isset($objectTypesMap[$objectType]); } return $this->validObjectTypes[$objectType]; } /** * Returns the object membership handlers. * * @return ObjectMembershipHandler[] */ private function getObjectMembershipHandlers() { if ($this->objectMembershipHandlers === null) { $factory = $this->membershipHandlerFactory; $roleMembershipHandler = $factory->createRoleMembershipHandler(); $userMembershipHandler = $factory->createUserMembershipHandler($this); $termMembershipHandler = $factory->createTermMembershipHandler($this); $postMembershipHandler = $factory->createPostMembershipHandler($this); $this->objectMembershipHandlers = [ $roleMembershipHandler->getGeneralObjectType() => $roleMembershipHandler, $userMembershipHandler->getGeneralObjectType() => $userMembershipHandler, $termMembershipHandler->getGeneralObjectType() => $termMembershipHandler, $postMembershipHandler->getGeneralObjectType() => $postMembershipHandler ]; $this->objectMembershipHandlers = $this->wordpress->applyFilters( 'uam_register_object_membership_handler', $this->objectMembershipHandlers ); } return $this->objectMembershipHandlers; } /** * Returns the membership handler for the given object type. * * @param string $objectType * * @return ObjectMembershipHandler * * @throws MissingObjectMembershipHandlerException */ public function getObjectMembershipHandler($objectType) { $objectMembershipHandlers = $this->getObjectMembershipHandlers(); $generalObjectType = $this->getGeneralObjectType($objectType); if (isset($objectMembershipHandlers[$generalObjectType]) === false) { throw new MissingObjectMembershipHandlerException("Missing membership handler for '{$objectType}'."); } return $objectMembershipHandlers[$generalObjectType]; } }