| | |
| | | { |
| | | $this->roles = array_keys(JVB_USER); |
| | | $this->content = array_map(function($content) { |
| | | return strtolower($content['plural']); |
| | | return strtolower($content['plural']??$content['singular'].'s'); |
| | | },JVB_CONTENT); |
| | | add_action('set_user_role', [$this, 'updateRoles'], 10, 3); |
| | | } |
| | | |
| | | public function updateRoles(int $userID, string $role, array $oldRoles):void |
| | | { |
| | | if (doing_action('set_user_role') > 1) { |
| | | return; |
| | | } |
| | | $temp = jvbNoBase($role); |
| | | if (array_key_exists($temp, JVB_USER)) { |
| | | $user = get_userdata($userID); |
| | | if (!$user) { |
| | | return; |
| | | } |
| | | $this->reset($user); |
| | | $this->setUserAs($user, $temp); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @param WP_User $user |
| | |
| | | /** |
| | | * @param WP_User $user |
| | | * @param string $type |
| | | * @param bool $add |
| | | * |
| | | * @return void |
| | | */ |
| | |
| | | if (empty($capsMap)){ |
| | | $capsMap = [ |
| | | $content, |
| | | str_replace('-', '_',sanitize_title(strtolower(JVB_CONTENT[$content]['plural']))) |
| | | str_replace('-', '_',sanitize_title(strtolower(JVB_CONTENT[$content]['plural']??JVB_TAXONOMY[$content]['plural']))) |
| | | ]; |
| | | return $capsMap[1]; |
| | | } |
| | |
| | | $this->registerRole($slug, $config); |
| | | } |
| | | } |
| | | |
| | | /****************************************************************** |
| | | * OWNABLE and MANAGABLE terms (ie: tattoo shops) |
| | | ******************************************************************/ |
| | | /** |
| | | * Grant ownership of a content taxonomy term |
| | | * Owners have full control over the term and its members |
| | | * |
| | | * @param int $userID User ID |
| | | * @param int $termID Term ID |
| | | * @param string $taxonomy Taxonomy slug (without BASE) |
| | | * @return bool Success |
| | | */ |
| | | public function grantOwnership(int $userID, int $termID, string $taxonomy): bool |
| | | { |
| | | if (!get_userdata($userID) || !term_exists($termID)){ |
| | | return false; |
| | | } |
| | | $taxonomy = jvbNoBase($taxonomy); |
| | | |
| | | // Verify this is an ownable content taxonomy |
| | | if (!Features::forTaxonomy($taxonomy)->has('is_content') || |
| | | !Features::forTaxonomy($taxonomy)->has('is_ownable')) { |
| | | return false; |
| | | } |
| | | |
| | | $user = get_userdata($userID); |
| | | if (!$user) { |
| | | return false; |
| | | } |
| | | |
| | | // Grant both ownership and management |
| | | $user->add_cap(BASE . 'can_own_' . $termID); |
| | | $user->add_cap(BASE . 'can_manage_' . $termID); |
| | | |
| | | do_action(BASE . 'granted_ownership', $userID, $termID, $taxonomy); |
| | | |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * Revoke ownership of a content taxonomy term |
| | | * |
| | | * @param int $userID User ID |
| | | * @param int $termID Term ID |
| | | * @param string $taxonomy Taxonomy slug (without BASE) |
| | | * @return bool Success |
| | | */ |
| | | public function revokeOwnership(int $userID, int $termID, string $taxonomy): bool |
| | | { |
| | | if (!get_userdata($userID) || !term_exists($termID)){ |
| | | return false; |
| | | } |
| | | $taxonomy = jvbNoBase($taxonomy); |
| | | |
| | | $user = get_userdata($userID); |
| | | if (!$user) { |
| | | return false; |
| | | } |
| | | |
| | | $user->remove_cap(BASE . 'can_own_' . $termID); |
| | | |
| | | do_action(BASE . 'revoked_ownership', $userID, $termID, $taxonomy); |
| | | |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * Grant management capabilities for a content taxonomy term |
| | | * Managers can approve members and edit content but don't own the term |
| | | * |
| | | * @param int $userID User ID |
| | | * @param int $termID Term ID |
| | | * @param string $taxonomy Taxonomy slug (without BASE) |
| | | * @return bool Success |
| | | */ |
| | | public function grantManagement(int $userID, int $termID, string $taxonomy): bool |
| | | { |
| | | if (!get_userdata($userID) || !term_exists($termID)){ |
| | | return false; |
| | | } |
| | | $taxonomy = jvbNoBase($taxonomy); |
| | | |
| | | // Verify this is an ownable content taxonomy |
| | | if (!Features::forTaxonomy($taxonomy)->has('is_content') || |
| | | !Features::forTaxonomy($taxonomy)->has('is_ownable')) { |
| | | return false; |
| | | } |
| | | |
| | | $user = get_userdata($userID); |
| | | if (!$user) { |
| | | return false; |
| | | } |
| | | |
| | | $user->add_cap(BASE . 'can_manage_' . $termID); |
| | | |
| | | do_action(BASE . 'granted_management', $userID, $termID, $taxonomy); |
| | | |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * Revoke management capabilities for a content taxonomy term |
| | | * |
| | | * @param int $userID User ID |
| | | * @param int $termID Term ID |
| | | * @param string $taxonomy Taxonomy slug (without BASE) |
| | | * @return bool Success |
| | | */ |
| | | public function revokeManagement(int $userID, int $termID, string $taxonomy): bool |
| | | { |
| | | if (!get_userdata($userID) || !term_exists($termID)){ |
| | | return false; |
| | | } |
| | | $taxonomy = jvbNoBase($taxonomy); |
| | | |
| | | $user = get_userdata($userID); |
| | | if (!$user) { |
| | | return false; |
| | | } |
| | | |
| | | $user->remove_cap(BASE . 'can_manage_' . $termID); |
| | | |
| | | do_action(BASE . 'revoked_management', $userID, $termID, $taxonomy); |
| | | |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * Check if user owns a term |
| | | * |
| | | * @param int $userID User ID |
| | | * @param int $termID Term ID |
| | | * @return bool |
| | | */ |
| | | public function isOwner(int $userID, int $termID): bool |
| | | { |
| | | return user_can($userID, BASE . 'can_own_' . $termID); |
| | | } |
| | | |
| | | /** |
| | | * Check if user can manage a term (owner or manager) |
| | | * |
| | | * @param int $userID User ID |
| | | * @param int $termID Term ID |
| | | * @return bool |
| | | */ |
| | | public function isManager(int $userID, int $termID): bool |
| | | { |
| | | return user_can($userID, BASE . 'can_manage_' . $termID) || |
| | | user_can($userID, BASE . 'can_own_' . $termID); |
| | | } |
| | | |
| | | /** |
| | | * Get all terms a user owns |
| | | * |
| | | * @param int $userID User ID |
| | | * @param string|null $taxonomy Optional: filter by taxonomy |
| | | * @return array Array of term IDs |
| | | */ |
| | | public function getOwnedTerms(int $userID, ?string $taxonomy = null): array |
| | | { |
| | | $user = get_userdata($userID); |
| | | if (!$user) { |
| | | return []; |
| | | } |
| | | |
| | | $owned = []; |
| | | foreach ($user->allcaps as $cap => $value) { |
| | | if ($value && strpos($cap, BASE . 'can_own_') === 0) { |
| | | $termID = (int) str_replace(BASE . 'can_own_', '', $cap); |
| | | if ($termID) { |
| | | $owned[] = $termID; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // Filter by taxonomy if specified |
| | | if ($taxonomy && !empty($owned)) { |
| | | $taxonomy = jvbCheckBase($taxonomy); |
| | | $filtered = []; |
| | | foreach ($owned as $termID) { |
| | | $term = get_term($termID); |
| | | if ($term && !is_wp_error($term) && $term->taxonomy === $taxonomy) { |
| | | $filtered[] = $termID; |
| | | } |
| | | } |
| | | return $filtered; |
| | | } |
| | | |
| | | return $owned; |
| | | } |
| | | |
| | | /** |
| | | * Get all terms a user can manage (owns or manages) |
| | | * |
| | | * @param int $userID User ID |
| | | * @param string|null $taxonomy Optional: filter by taxonomy |
| | | * @return array Array of term IDs |
| | | */ |
| | | public function getManagedTerms(int $userID, ?string $taxonomy = null): array |
| | | { |
| | | $user = get_userdata($userID); |
| | | if (!$user) { |
| | | return []; |
| | | } |
| | | |
| | | $managed = []; |
| | | foreach ($user->allcaps as $cap => $value) { |
| | | if ($value && (strpos($cap, BASE . 'can_manage_') === 0 || |
| | | strpos($cap, BASE . 'can_own_') === 0)) { |
| | | $termID = (int) str_replace([BASE . 'can_manage_', BASE . 'can_own_'], '', $cap); |
| | | if ($termID && !in_array($termID, $managed)) { |
| | | $managed[] = $termID; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // Filter by taxonomy if specified |
| | | if ($taxonomy && !empty($managed)) { |
| | | $taxonomy = jvbCheckBase($taxonomy); |
| | | $filtered = []; |
| | | foreach ($managed as $termID) { |
| | | $term = get_term($termID); |
| | | if ($term && !is_wp_error($term) && $term->taxonomy === $taxonomy) { |
| | | $filtered[] = $termID; |
| | | } |
| | | } |
| | | return $filtered; |
| | | } |
| | | |
| | | return $managed; |
| | | } |
| | | |
| | | /** |
| | | * Get all ownable taxonomies |
| | | * |
| | | * @return array Array of taxonomy slugs |
| | | */ |
| | | public function getOwnableTaxonomies(): array |
| | | { |
| | | static $ownable = null; |
| | | |
| | | if ($ownable === null) { |
| | | $ownable = []; |
| | | foreach (JVB_TAXONOMY as $taxonomy => $config) { |
| | | if (Features::forTaxonomy($taxonomy)->has('is_content') && |
| | | Features::forTaxonomy($taxonomy)->has('is_ownable')) { |
| | | $ownable[] = $taxonomy; |
| | | } |
| | | } |
| | | } |
| | | |
| | | return $ownable; |
| | | } |
| | | |
| | | /** |
| | | * Get all invitable taxonomies |
| | | * |
| | | * @return array Array of taxonomy slugs |
| | | */ |
| | | public function getInvitableTaxonomies(): array |
| | | { |
| | | static $invitable = null; |
| | | |
| | | if ($invitable === null) { |
| | | $invitable = []; |
| | | foreach (JVB_TAXONOMY as $taxonomy => $config) { |
| | | if (Features::forTaxonomy($taxonomy)->has('invitable')) { |
| | | $invitable[] = $taxonomy; |
| | | } |
| | | } |
| | | } |
| | | |
| | | return $invitable; |
| | | } |
| | | } |