*/ abstract class AAM_Core_Subject { /** * Subject ID * * Whether it is User ID or Role ID * * @var string|int * * @access private */ private $_id; /** * WordPres Subject * * It can be WP_User or WP_Role, based on what class has been used * * @var WP_Role|WP_User * * @access private */ private $_subject; /** * Covering the scenario of multi-subjects * * For example this is quite typical for the multi-roles * * @var array * * @access private */ private $_siblings = array(); /** * List of Objects to be access controlled for current subject * * All access control objects like Admin Menu, Metaboxes, Posts etc * * @var array * * @access private */ private $_objects = array(); /** * Constructor * * @param string|int $id * * @return void * * @access public */ public function __construct($id = '') { //set subject $this->setId($id); //retrieve and set subject itself $this->setSubject($this->retrieveSubject()); } /** * */ public function initialize() { } /** * Trigger Subject native methods * * @param string $name * @param array $args * * @return mixed * * @access public */ public function __call($name, $args) { $subject = $this->getSubject(); //make sure that method is callable if (method_exists($subject, $name)) { $response = call_user_func_array(array($subject, $name), $args); } else { $response = null; } return $response; } /** * Get Subject's native properties * * @param string $name * * @return mixed * * @access public */ public function __get($name) { $subject = $this->getSubject(); return (!empty($subject->$name) ? $subject->$name : null); } /** * Set Subject's native properties * * @param string $name * * @return mixed * * @access public */ public function __set($name, $value) { $subject = $this->getSubject(); if ($subject) { $subject->$name = $value; } } /** * Set Subject ID * * @param string|int * * @return void * * @access public */ public function setId($id) { $this->_id = $id; } /** * Get Subject ID * * @return string|int * * @access public */ public function getId() { return $this->_id; } /** * Get subject name * * @return string * * @access public */ public function getName() { return ''; } /** * * @return int */ public function getMaxLevel() { return 0; } /** * Get Subject * * @return WP_Role|WP_User * * @access public */ public function getSubject() { return $this->_subject; } /** * Set Subject * * @param WP_Role|WP_User $subject * * @return void * * @access public */ public function setSubject($subject) { $this->_subject = $subject; } /** * * @param type $siblings */ public function setSiblings($siblings) { $this->_siblings = $siblings; } /** * * @return type */ public function hasSiblings() { return count($this->_siblings) ? true : false; } /** * * @return type */ public function getSiblings() { return $this->_siblings; } /** * Get Individual Object * * @param string $type * @param mixed $id * * @return AAM_Core_Object * * @access public */ public function getObject($type, $id = 0, $param = null) { $object = null; //performance optimization $id = (is_scalar($id) ? $id : 'none'); //prevent from any surprises //check if there is an object with specified ID if (!isset($this->_objects[$type][$id])) { $classname = 'AAM_Core_Object_' . ucfirst($type); if (class_exists($classname)) { $object = new $classname($this, $id, $param); } $object = apply_filters('aam-object-filter', $object, $type, $id, $this); if (is_a($object, 'AAM_Core_Object')) { $this->_objects[$type][$id] = $object; } } else { $object = $this->_objects[$type][$id]; } return $object; } /** * Check if subject has capability * * @param string $capability * * @return boolean * * @access public */ public function hasCapability($capability) { $subject = $this->getSubject(); return ($subject ? $subject->has_cap($capability) : false); } /** * Save option * * @param string $param * @param mixed $value * @param string $object * @param mixed $objectId * * @return boolean * * @access public */ public function save($param, $value, $object, $objectId = 0) { return $this->getObject($object, $objectId)->save($param, $value); } /** * Reset object * * @param string $object * * @return boolean * * @access public */ public function resetObject($object) { return $this->deleteOption($object); } /** * Delete option * * @param string $object * @param mixed $id * * @return boolean * * @access public */ public function deleteOption($object, $id = 0) { return AAM_Core_API::deleteOption($this->getOptionName($object, $id)); } /** * Retrieve list of subject's capabilities * * @return array * * @access public */ public function getCapabilities() { return array(); } /** * Retrieve subject based on used class * * @return void * * @access protected */ protected function retrieveSubject() { return null; } /** * */ public function getOptionName($object, $id) { return ''; } /** * Read object from parent subject * * @param string $object * @param mixed $id * * @return mixed * * @access public */ public function inheritFromParent($object, $id = '', $param = null){ $subject = $this->getParent(); if (is_a($subject, 'AAM_Core_Subject')){ $option = $subject->getObject($object, $id, $param)->getOption(); $multi = AAM::api()->getConfig('core.settings.multiSubject', false); if ($multi && $subject->hasSiblings()) { foreach($subject->getSiblings() as $sibling) { $option = $sibling->getObject($object, $id, $param)->mergeOption( $option ); } } } else { $option = null; } return $option; } /** * Retrieve parent subject * * If there is no parent subject, return null * * @return AAM_Core_Subject|null * * @access public */ public function getParent() { return null; } }