File Coverage

blib/lib/Elive/Entity/Participants.pm
Criterion Covered Total %
statement 40 81 49.3
branch 9 36 25.0
condition 5 18 27.7
subroutine 8 11 72.7
pod 2 2 100.0
total 64 148 43.2


line stmt bran cond sub pod time code
1             package Elive::Entity::Participants;
2 5     5   934 use warnings; use strict;
  5     5   7  
  5         145  
  5         19  
  5         5  
  5         114  
3              
4 5     5   20 use Mouse;
  5         5  
  5         83  
5 5     5   1309 use Mouse::Util::TypeConstraints;
  5         10  
  5         26  
6              
7             extends 'Elive::DAO::Array';
8              
9 5     5   1120 use Elive::Entity::Participant;
  5         10  
  5         122  
10 5     5   23 use Elive::Entity::Role;
  5         6  
  5         85  
11 5     5   70 use Elive::Util;
  5         6  
  5         4171  
12              
13             __PACKAGE__->element_class('Elive::Entity::Participant');
14             __PACKAGE__->mk_classdata('separator' => ';');
15              
16             =head1 NAME
17              
18             Elive::Entity::Participants - A list of participants
19              
20             =head1 DESCRIPTION
21              
22             This class implements the C property of C
23             and C
24              
25             =cut
26              
27             =head1 METHODS
28              
29             =cut
30              
31             sub _build_array {
32 58     58   59 my $class = shift;
33 58         66 my $spec = shift;
34              
35 58         134 my $type = Elive::Util::_reftype( $spec );
36              
37 58         71 my @participants;
38              
39 58 100       112 if ($type) {
    50          
40 48 50       93 $spec = [$spec]
41             unless $type eq 'ARRAY';
42              
43 48         90 @participants = @$spec;
44             }
45             elsif (defined $spec) {
46 10         28 @participants = split(__PACKAGE__->separator, Elive::Util::string($spec));
47             }
48              
49 58         64 my $cur_role;
50             my @args;
51 58         132 my $element_class = $class->element_class;
52              
53 58         318 foreach (@participants) {
54              
55 106 50       225 foreach (Elive::Util::_reftype($_) eq 'ARRAY' ? @$_ : ($_)) {
56 106 50       175 next unless defined;
57              
58 106 50 66     347 if (!ref && m{^-(\w+)$}) {
59 0         0 my $opt = $1;
60              
61 0 0       0 if ($opt =~ m{^(participant|other)(s?)$}) {
    0          
62 0         0 $cur_role = ${Elive::Entity::Role::PARTICIPANT};
63             }
64             elsif ($opt =~ m{^moderator(s?)$}) {
65 0         0 $cur_role = ${Elive::Entity::Role::MODERATOR};
66             }
67             else {
68 0         0 die "unknown option '$_' in participant list (expected: '-participant', '-moderator' or '-other'";
69             }
70             }
71             else {
72 106         112 my $participant = $_;
73 106 50 66     696 $participant = $element_class->new($participant)
      33        
74             unless ref && Scalar::Util::blessed($_) && $_->isa($element_class);
75              
76 106 50       369 $participant->role($cur_role) if $cur_role;
77              
78 106         338 push (@args, $participant);
79             }
80             }
81             }
82              
83 58         168 return \@args;
84             }
85              
86             =head2 add
87              
88             $participants->add('alice=2', 'bob');
89              
90             Add additional participants
91              
92             =cut
93              
94             sub add {
95 0     0 1   my ($self, @elems) = @_;
96              
97 0           my $participants = $self->_build_array( \@elems );
98              
99 0           return $self->SUPER::add( @$participants );
100             }
101              
102             our $class = __PACKAGE__;
103             coerce $class => from 'ArrayRef|Str'
104             => via {$class->new($_);};
105              
106             sub _group_by_type {
107 0     0     my $self = shift;
108              
109 0 0         my @raw_participants = @{ $self || [] };
  0            
110              
111 0           my %users;
112             my %groups;
113 0           my %guests;
114              
115 0           foreach my $participant (@raw_participants) {
116              
117 0 0 0       $participant = Elive::Entity::Participant->new($participant)
118             unless Scalar::Util::blessed $participant
119             && $participant->isa('Elive::Entity::Participant');
120              
121 0           my $id;
122 0   0       my $roleId = Elive::Entity::Role->stringify( $participant->role )
123             || ${Elive::Entity::Role::PARTICIPANT};
124              
125 0 0 0       if (!defined $participant->type || $participant->type == ${Elive::Entity::Participant::TYPE_USER}) {
    0          
    0          
126 0           $id = Elive::Entity::User->stringify( $participant->user );
127 0           $users{ $id } = $roleId;
128             }
129             elsif ($participant->type == ${Elive::Entity::Participant::TYPE_GROUP}) {
130 0           $id = Elive::Entity::Group->stringify( $participant->group );
131 0           $groups{ $id } = $roleId;
132             }
133             elsif ($participant->type == ${Elive::Entity::Participant::TYPE_GUEST}) {
134 0           $id = Elive::Entity::InvitedGuest->stringify( $participant->guest );
135 0           $guests{ $id } = $roleId;
136             }
137             else {
138 0           carp("unknown type: $participant->{type} in participant list: ".$self->id);
139             }
140             }
141              
142 0           return (\%users, \%groups, \%guests);
143             }
144              
145             =head2 tidied
146              
147             my $untidy = 'trev;bob=3;bob=2'
148             my $participants = Elive::Entity::Participants->new($untidy);
149             # outputs: alice=2;bob=3;trev=3
150             print $participants->tidied;
151              
152             Produces a tidied list of participants. These are sorted with duplicates
153             removed (highest role is retained).
154              
155             The C option can be used to ensure that the meeting facilitator
156             is included and has a moderator role.
157            
158             =cut
159              
160             sub tidied {
161 0     0 1   my $self = shift;
162              
163 0           my ($_users, $_groups, $_guests) = $self->_group_by_type;
164              
165             # weed out duplicates as we go
166 0           my %roles = (%$_users, %$_groups, %$_guests);
167              
168 0 0         if (wantarray) {
169              
170             # elm3.x compat
171              
172 0           my %guests;
173             my %moderators;
174 0           my %participants;
175              
176 0           foreach (sort keys %roles) {
177              
178 0           my $role = $roles{$_};
179              
180 0 0         if (exists $_guests->{$_} ) {
    0          
181 0           $guests{$_} = $role;
182             }
183             elsif ($role <= 2) {
184 0           $moderators{$_} = $role;
185             }
186             else {
187 0           $participants{$_} = $role;
188             }
189             }
190              
191 0           return ([ sort keys %guests],
192             [ sort keys %moderators],
193             [ sort keys %participants])
194             }
195             else {
196             # elm2.x compat
197 0           return $self->stringify([ map { $_.'='.$roles{$_} } sort keys %roles ]);
  0            
198             }
199             }
200              
201             =head1 SEE ALSO
202              
203             L
204             L
205              
206             =cut
207              
208             1;