| | |
| | | { |
| | | private array $roles; |
| | | private array $content; |
| | | private array $subTypes = []; |
| | | |
| | | public function __construct() |
| | | { |
| | |
| | | Registrar::getFeatured('is_content', 'term') |
| | | )); |
| | | add_action('set_user_role', [$this, 'updateRoles'], 10, 3); |
| | | |
| | | $this->checkRoleSubTypes(); |
| | | } |
| | | |
| | | public function checkRoleSubTypes():void |
| | | { |
| | | foreach ($this->roles as $role) { |
| | | $registrar = Registrar::getInstance($role); |
| | | if ($registrar->getUserSubtype()){ |
| | | $this->subTypes[jvbCheckBase($registrar->getUserSubtype())] = $registrar->getCreatable(); |
| | | } |
| | | } |
| | | if (!empty($this->subTypes)) { |
| | | add_action('set_object_terms', [$this, 'maybeSwitchPermissions'],10, 6); |
| | | } |
| | | } |
| | | |
| | | public function updateRoles(int $userID, string $role, array $oldRoles):void |
| | | { |
| | | if (doing_action('set_user_role') > 1) { |
| | |
| | | $roles = array_keys($user->roles); |
| | | |
| | | foreach ($roles as $role) { |
| | | $role = jvbNoBase($role); |
| | | $registrar = Registrar::getInstance($role); |
| | | if (!$registrar) { |
| | | return false; |
| | |
| | | if (!in_array($type, $this->roles)) { |
| | | return false; |
| | | } |
| | | $link = get_user_meta($user->ID, BASE.'link', true); |
| | | $link = get_user_meta($user->ID, BASE.'profile_link', true); |
| | | if ($link === '') { |
| | | $type = BASE.$type; |
| | | $name = $user->display_name; |
| | |
| | | 'post_author' => $user->ID, |
| | | ]); |
| | | if ($link) { |
| | | update_user_meta($user->ID, BASE.'link', $link); |
| | | update_post_meta($link, BASE.'link', $user->ID); |
| | | update_user_meta($user->ID, BASE.'profile_link', $link); |
| | | update_post_meta($link, BASE.'profile_link', $user->ID); |
| | | } |
| | | } |
| | | return $link; |
| | |
| | | if ($registrar->hasFeature('has_dashboard') ?? false) { |
| | | $admin_role = get_role('administrator'); |
| | | if ($admin_role) { |
| | | $admin_role->add_cap("manage_{$role_name}s", true); |
| | | $admin_role->add_cap("edit_{$role_name}_settings", true); |
| | | $admin_role->add_cap("manage_{$role_name}s"); |
| | | $admin_role->add_cap("edit_{$role_name}_settings"); |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | return [ |
| | | "edit_{$content}", |
| | | "edit_published_{$content}", |
| | | "read_{$content}", |
| | | "delete_{$content}", |
| | | "delete_published_{$content}", |
| | | "edit_{$plural}", |
| | | "edit_others_{$plural}", |
| | | "publish_{$plural}", |
| | | "read_private_{$plural}", |
| | | "edit_private_{$plural}", |
| | | "delete_private_{$plural}", |
| | | ]; |
| | | } |
| | | protected function getOthersCapabilities(string $content):array |
| | |
| | | return [ |
| | | "edit_others_{$plural}", |
| | | "delete_others_{$plural}", |
| | | "read_private_{$plural}", |
| | | "edit_private_{$plural}", |
| | | "delete_private_{$plural}", |
| | | ]; |
| | | } |
| | | |
| | |
| | | return str_replace(' ', '_', $content.'s'); |
| | | } |
| | | |
| | | public function activate(): void |
| | | public static function activate(): void |
| | | { |
| | | error_log('[RoleManager]::activate'); |
| | | error_log('Registering roles...'); |
| | | $instance = new self; |
| | | foreach (Registrar::getRegistered('user') as $role) { |
| | | $this->registerRole($role); |
| | | $instance->registerRole($role); |
| | | } |
| | | error_log('Roles registered!'); |
| | | error_log('Removing unneeded roles...'); |
| | | remove_role('contributor'); |
| | | remove_role('author'); |
| | | remove_role('editor'); |
| | | error_log('Roles removed!'); |
| | | |
| | | error_log('Adding Admin Capabilities'); |
| | | $instance->addAdminCaps(); |
| | | error_log('Ensuring Existing User\'s Roles...'); |
| | | $instance->ensureRoleCaps(); |
| | | error_log('Roles activated!'); |
| | | } |
| | | protected function addAdminCaps():void |
| | | { |
| | | $users = get_users(['role' => 'administrator']); |
| | | foreach (array_merge(Registrar::getRegistered('post'), Registrar::getFeatured('is_content')) as $slug) { |
| | | $this->grantRoleCapabilities('administrator', $slug); |
| | | $this->grantRoleOthersCapabilities('administrator', $slug); |
| | | |
| | | foreach ($users as $user) { |
| | | $this->grantContent($user, $slug); |
| | | $this->grantOthersContent($user, $slug); |
| | | } |
| | | } |
| | | } |
| | | protected function ensureRoleCaps():void |
| | | { |
| | | $roles = Registrar::getRegistered('user'); |
| | | foreach ($roles as $role) { |
| | | $registrar = Registrar::getInstance($role); |
| | | $creatable = $registrar->getCreatable(); |
| | | $manageable = $registrar->getManageOthers(); |
| | | if (!empty($creatable) || !empty($manageable)) { |
| | | $users = get_users(['role' => jvbCheckBase($role)]); |
| | | foreach ($users as $user) { |
| | | foreach ($creatable as $slug) { |
| | | $this->grantContent($user, $slug); |
| | | } |
| | | foreach ($manageable as $slug) { |
| | | $this->grantOthersContent($user, $slug); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /****************************************************************** |
| | | * OWNABLE and MANAGABLE terms (ie: tattoo shops) |
| | |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | public function maybeSwitchPermissions(int $object_id, array $terms, array $tt_ids, string $taxonomy, bool $append, array $old_tt_ids):void |
| | | { |
| | | //This shouldn't happen, but whatever |
| | | if (empty($this->subTypes)) { |
| | | return; |
| | | } |
| | | |
| | | if (!in_array($taxonomy, array_keys($this->subTypes))) { |
| | | return; |
| | | } |
| | | |
| | | $new = array_diff($tt_ids, $old_tt_ids); |
| | | $old = array_diff($old_tt_ids, $tt_ids); |
| | | |
| | | $userID = (int)get_post_meta($object_id, BASE.'profile_link',true); |
| | | if ($userID === 0) { |
| | | return; |
| | | } |
| | | $user = get_userdata($userID); |
| | | if (!$user) { |
| | | return; |
| | | } |
| | | |
| | | //Revoke old first |
| | | if (!empty($old)) { |
| | | $old = array_filter(array_map(function ($id) use ($taxonomy) { |
| | | $termID = $this->getTermIDFromTTID($id); |
| | | return $this->getRootTermSlug($termID, $taxonomy); |
| | | }, $old)); |
| | | foreach ($old as $slug) { |
| | | if (!array_key_exists($slug, $this->subTypes[$taxonomy])) { |
| | | error_log('[RoleManager]::maybeSwitchPermissions Could not find creatable types for role subtype '.$slug); |
| | | continue; |
| | | } |
| | | foreach ($this->subTypes[$taxonomy][$slug] ?? [] as $s) { |
| | | $this->grantContent($user, $s, false); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (!empty($new)) { |
| | | $new = array_filter(array_map(function ($id) use ($taxonomy){ |
| | | $termID = $this->getTermIDFromTTID($id); |
| | | return $this->getRootTermSlug($termID, $taxonomy); |
| | | }, $new)); |
| | | foreach ($new as $slug) { |
| | | if (!array_key_exists($slug, $this->subTypes[$taxonomy])) { |
| | | error_log('[RoleManager]::maybeSwitchPermissions Could not find creatable types for role subtype '.$slug); |
| | | continue; |
| | | } |
| | | foreach ($this->subTypes[$taxonomy][$slug] ?? [] as $s) { |
| | | $this->grantContent($user, $s); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Helper function to get term_id from term_taxonomy_id |
| | | * @param int $tt_id |
| | | * |
| | | * @return int |
| | | */ |
| | | private function getTermIDFromTTID(int $tt_id):int |
| | | { |
| | | global $wpdb; |
| | | return $wpdb->get_var($wpdb->prepare( |
| | | "SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id = %d", |
| | | $tt_id |
| | | )); |
| | | } |
| | | |
| | | private function getRootTermSlug(int $termID, string $taxonomy): string|false |
| | | { |
| | | $term = get_term($termID, $taxonomy); |
| | | if (!$term || is_wp_error($term)) { |
| | | return false; |
| | | } |
| | | while ($term->parent !== 0) { |
| | | $term = get_term($term->parent, $taxonomy); |
| | | if (!$term || is_wp_error($term)) { |
| | | return false; |
| | | } |
| | | } |
| | | return $term->slug; |
| | | } |
| | | } |