| | |
| | | use Exception; |
| | | use JVBase\managers\queue\executors\InvitationExecutor; |
| | | use JVBase\managers\queue\TypeConfig; |
| | | use JVBase\utility\Features; |
| | | use JVBase\registrar\Registrar; |
| | | use JVBase\base\Site; |
| | | use WP_Error; |
| | | |
| | | if (!defined('ABSPATH')) { |
| | |
| | | protected array $inviteConfig; |
| | | protected CustomTable $table; |
| | | protected int $expiryDays = 14; |
| | | protected Cache $cache; |
| | | public function __construct() |
| | | { |
| | | $this->defineTable(); |
| | | if (!isset($this->table)) { |
| | | return; |
| | | } |
| | | $this->setInviteConfig(); |
| | | $this->table = CustomTable::for('invitations'); |
| | | $this->cache = Cache::for('invitations'); |
| | | add_action('init', [$this, 'registerInvitationExecutors'], 5); |
| | | |
| | | add_action('user_register', [$this, 'checkInvitation']); |
| | |
| | | add_filter(BASE . 'handle_bulk_operation', [$this, 'processOperation'], 10, 3); |
| | | } |
| | | |
| | | public function defineTable():void |
| | | { |
| | | $terms = Registrar::getFeatured('invitable', 'term'); |
| | | $membership = Site::membership(); |
| | | $roles = ($membership) ? Site::membership()->has('can_invite') :[]; |
| | | if (empty($terms) && empty($roles)) { |
| | | return; |
| | | } |
| | | |
| | | $table = CustomTable::for('invitations'); |
| | | $columns = [ |
| | | 'id' => 'bigint(20) unsigned NOT NULL AUTO_INCREMENT', |
| | | 'name' => 'varchar(255) NOT NULL', |
| | | 'email' => 'varchar(255) NOT NULL', |
| | | 'invitation_token' => 'varchar(255) NOT NULL', |
| | | 'invited_role' => 'varchar(50) NOT NULL', //Role being invited to |
| | | 'status' => "ENUM('pending','accepted','rejected','expired','revoked') DEFAULT 'pending'", |
| | | 'inviters' => 'JSON NOT NULL', // Array of {user_id, invited_at} |
| | | 'new_user_id' => $table->getUserIDType().' DEFAULT NULL', |
| | | 'expires_at' => 'datetime NOT NULL', |
| | | 'accepted_at' => 'datetime DEFAULT NULL', |
| | | 'created_at' => 'datetime NOT NULL DEFAULT CURRENT_TIMESTAMP', |
| | | 'updated_at' => 'datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP' |
| | | ]; |
| | | |
| | | foreach ($terms as $tax) { |
| | | $columns["to_{$tax}"] = $table->getTermIDType().' DEFAULT NULL'; |
| | | } |
| | | $table->setColumns($columns); |
| | | |
| | | |
| | | $table->setKeys([ |
| | | ['key' => 'PRIMARY', 'value' => '(`id`)'], |
| | | ['key' => 'UNIQUE', 'value' => '`unique_email_role` (`email`, `invited_role`)'], |
| | | '`token_lookup` (`invitation_token`)', |
| | | '`status_expiry` (`status`, `expires_at`)', |
| | | '`role_status` (`invited_role`, `status`)', |
| | | '`email_status` (`email`, `status`)' |
| | | ]); |
| | | $constraints = []; |
| | | $base = BASE; |
| | | global $wpdb; |
| | | foreach ($terms as $tax) { |
| | | $constraints[] = "CONSTRAINT `{$base}invitations_{$tax}_fk` FOREIGN KEY (`to_{$tax}`) REFERENCES `{$wpdb->terms}` (`term_id`) |
| | | ON DELETE SET NULL"; |
| | | } |
| | | $constraints[] = "CONSTRAINT `{$base}invitations_user_fk` FOREIGN KEY (`new_user_id`) REFERENCES `{$table->getUserTable()}` (`ID`) |
| | | ON DELETE SET NULL"; |
| | | |
| | | $table->setConstraints($constraints); |
| | | |
| | | $table->defineTable(); |
| | | $this->table = $table; |
| | | } |
| | | |
| | | protected function setInviteConfig():void |
| | | { |
| | | $this->inviteConfig = get_option(BASE.'invitation_config', [ |
| | |
| | | */ |
| | | protected function buildInviteTypes(): array |
| | | { |
| | | $types = []; |
| | | $invitable = $this->cache->remember( |
| | | 'invitableTypes', |
| | | function () { |
| | | $types = []; |
| | | |
| | | // Global invitations from JVB_MEMBERSHIP |
| | | if (!empty(JVB_MEMBERSHIP['can_invite'])) { |
| | | foreach (JVB_MEMBERSHIP['can_invite'] as $role => $canInvite) { |
| | | $types[$role] = [ |
| | | 'can_invite' => $canInvite, |
| | | 'to_terms' => [] |
| | | ]; |
| | | } |
| | | } |
| | | // Global invitations from JVB_MEMBERSHIP |
| | | if (!empty(JVB_MEMBERSHIP['can_invite'])) { |
| | | foreach (JVB_MEMBERSHIP['can_invite'] as $role => $canInvite) { |
| | | $types[$role] = [ |
| | | 'can_invite' => $canInvite, |
| | | 'to_terms' => [] |
| | | ]; |
| | | } |
| | | } |
| | | |
| | | // Term invitations from invitable content taxonomies |
| | | foreach (JVB_TAXONOMY as $taxonomy => $config) { |
| | | if (Features::forTaxonomy($taxonomy)->has('invitable') && |
| | | Features::forTaxonomy($taxonomy)->has('is_content') && |
| | | Features::forTaxonomy($taxonomy)->has('is_ownable')) { |
| | | // Term invitations from invitable content taxonomies |
| | | $invitable = Registrar::getFeatured('invitable', 'term'); |
| | | $content = Registrar::getFeatured('is_content', 'term'); |
| | | $ownable = Registrar::getFeatured('is_ownable', 'term'); |
| | | $taxonomies = array_intersect($invitable, $content, $ownable); |
| | | if (!empty($taxonomies)) { |
| | | $users = Registrar::getRegistered('user'); |
| | | } |
| | | foreach ($taxonomies as $taxonomy) { |
| | | $registrar = Registrar::getInstance($taxonomy); |
| | | |
| | | $forContent = $config['for_content'] ?? []; |
| | | foreach ($forContent as $content) { |
| | | // Find which user roles can create this content |
| | | foreach (JVB_USER as $role => $userConfig) { |
| | | $creatable = Features::forUser($role)->getCreatableContent(); |
| | | if (in_array($content, $creatable)) { |
| | | if (!isset($types[$role])) { |
| | | $types[$role] = [ |
| | | 'can_invite' => [], |
| | | 'to_terms' => [] |
| | | ]; |
| | | } |
| | | if (!in_array($taxonomy, $types[$role]['to_terms'])) { |
| | | $types[$role]['to_terms'][] = $taxonomy; |
| | | foreach ($registrar->registrar->for as $content) { |
| | | // Find which user roles can create this content |
| | | foreach ($users as $user) { |
| | | $userRegistrar = Registrar::getInstance($user); |
| | | |
| | | $creatable = $userRegistrar->getCreatable(); |
| | | if (in_array($content, $creatable)) { |
| | | if (!isset($types[$role])) { |
| | | $types[$role] = [ |
| | | 'can_invite' => [], |
| | | 'to_terms' => [] |
| | | ]; |
| | | } |
| | | if (!in_array($taxonomy, $types[$role]['to_terms'])) { |
| | | $types[$role]['to_terms'][] = $taxonomy; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | return $types; |
| | | return $types; |
| | | } |
| | | ); |
| | | return $invitable; |
| | | |
| | | } |
| | | |
| | | /****************************************************************** |
| | |
| | | |
| | | $term = get_term($termID, BASE . $taxonomy); |
| | | if ($term && !is_wp_error($term)) { |
| | | $config = JVB_TAXONOMY[$taxonomy] ?? []; |
| | | $singular = $config['singular'] ?? $taxonomy; |
| | | $registrar = Registrar::getInstance($taxonomy); |
| | | |
| | | $singular = $registrar ? $registrar->getSingular() : $taxonomy; |
| | | |
| | | $termContent[] = sprintf( |
| | | "<p>%s has also invited you to join %s. You'll be automatically added to this %s when you register.</p>", |