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 4     4   1620 use warnings; use strict;
  4     4   9  
  4         145  
  4         23  
  4         11  
  4         135  
3              
4 4     4   27 use Mouse;
  4         10  
  4         112  
5 4     4   1635 use Mouse::Util::TypeConstraints;
  4         9  
  4         32  
6              
7             extends 'Elive::DAO::Array';
8              
9 4     4   1724 use Elive::Entity::Participant;
  4         9  
  4         114  
10 4     4   25 use Elive::Entity::Role;
  4         6  
  4         104  
11 4     4   20 use Elive::Util;
  4         8  
  4         4456  
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   96 my $class = shift;
33 58         74 my $spec = shift;
34              
35 58         168 my $type = Elive::Util::_reftype( $spec );
36              
37 58         86 my @participants;
38              
39 58 100       135 if ($type) {
    50          
40 48 50       124 $spec = [$spec]
41             unless $type eq 'ARRAY';
42              
43 48         123 @participants = @$spec;
44             }
45             elsif (defined $spec) {
46 10         37 @participants = split(__PACKAGE__->separator, Elive::Util::string($spec));
47             }
48              
49 58         86 my $cur_role;
50             my @args;
51 58         207 my $element_class = $class->element_class;
52              
53 58         475 foreach (@participants) {
54              
55 106 50       283 foreach (Elive::Util::_reftype($_) eq 'ARRAY' ? @$_ : ($_)) {
56 106 50       218 next unless defined;
57              
58 106 50 66     400 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         144 my $participant = $_;
73 106 50 66     913 $participant = $element_class->new($participant)
      33        
74             unless ref && Scalar::Util::blessed($_) && $_->isa($element_class);
75              
76 106 50       522 $participant->role($cur_role) if $cur_role;
77              
78 106         494 push (@args, $participant);
79             }
80             }
81             }
82              
83 58         238 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;