table = $db->prefix . 'us_invites'; } /** * Persist an invite. Returns the new row id, or 0 when the insert failed — * callers must not hand out a registration link for an unstored token. */ public function insert( Invite $invite ): int { $result = $this->db->insert( $this->table, [ 'email' => $invite->email, 'token' => $invite->token, 'role' => $invite->role, 'kind' => $invite->kind, 'offering_id' => $invite->offeringId, 'status' => $invite->status, 'invited_by' => $invite->invitedBy, 'accepted_user_id' => $invite->acceptedUserId, 'created_at' => current_time( 'mysql' ), 'accepted_at' => $invite->acceptedAt, 'expires_at' => $invite->expiresAt, ], [ '%s', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%s', '%s', '%s' ] ); return false === $result ? 0 : $this->db->insert_id; } public function findByToken( string $token ): ?Invite { $row = $this->db->get_row( $this->db->prepare( 'SELECT * FROM %i WHERE token = %s', $this->table, $token ) ); return $row ? Invite::fromRow( $row ) : null; } public function findById( int $id ): ?Invite { $row = $this->db->get_row( $this->db->prepare( 'SELECT * FROM %i WHERE id = %d', $this->table, $id ) ); return $row ? Invite::fromRow( $row ) : null; } /** * The most recent pending invite for an email, if any. */ public function findPendingByEmail( string $email ): ?Invite { $row = $this->db->get_row( $this->db->prepare( 'SELECT * FROM %i WHERE email = %s AND status = %s ORDER BY id DESC LIMIT 1', $this->table, $email, Invite::STATUS_PENDING ) ); return $row ? Invite::fromRow( $row ) : null; } /** * All invites awaiting acceptance, newest first. * * @return list */ public function findPending(): array { $rows = $this->db->get_results( $this->db->prepare( 'SELECT * FROM %i WHERE status = %s ORDER BY created_at DESC', $this->table, Invite::STATUS_PENDING ) ); return array_map( Invite::fromRow( ... ), $rows ?? [] ); } public function markAccepted( int $id, int $userId ): bool { return false !== $this->db->update( $this->table, [ 'status' => Invite::STATUS_ACCEPTED, 'accepted_user_id' => $userId, 'accepted_at' => current_time( 'mysql' ), ], [ 'id' => $id ], [ '%s', '%d', '%s' ], [ '%d' ] ); } public function revoke( int $id ): bool { return false !== $this->db->update( $this->table, [ 'status' => Invite::STATUS_REVOKED ], [ 'id' => $id ], [ '%s' ], [ '%d' ] ); } }