Line # Revision Author
1 196 ahitrov package users::UserProfile;
2
3 use base "Contenido::Document";
4 use Digest::MD5;
5 use Contenido::Globals;
6 325 ahitrov use Data::Dumper;
7 196 ahitrov
8 305 ahitrov my %CREDENTIAL_FIELDS = (
9 'users::Email' => 'email',
10 'users::Phone' => 'phone',
11 'users::OA::VK' => 'vkontakte',
12 'users::OA::FaceBook' => 'facebook',
13 'users::OA::Google' => 'google',
14 'users::OA::Mailru' => 'mailru',
15 );
16
17 310 ahitrov my %CREDENTIAL_REVERSE = (
18 'email' => 'users::Email',
19 'phone' => 'users::Phone',
20 'vkontakte' => 'users::OA::VK',
21 'facebook' => 'users::OA::FaceBook',
22 'google' => 'users::OA::Google',
23 'mailru' => 'users::OA::Mailru',
24 );
25
26 196 ahitrov sub extra_properties
27 {
28 return (
29 258 ahitrov { 'attr' => 'status', 'type' => 'status', 'rusname' => 'Статус пользователя',
30 196 ahitrov 'cases' => [
31 [0, 'Блокированный'],
32 [1, 'Активный'],
33 [5, 'Временная активация'],
34 ],
35 },
36 258 ahitrov { 'attr' => 'type', 'type' => 'status', 'rusname' => 'Тип аккаунта',
37 'cases' => [
38 [0, 'Обычный пользователь'],
39 [1, 'Продвинутый пользователь'],
40 [2, 'Модератор'],
41 [10, 'Администратор'],
42 ],
43 },
44 196 ahitrov { 'attr' => 'visibility', 'type' => 'status', 'rusname' => 'Область видимости',
45 'cases' => [
46 [0, 'Данные моего аккаунта видны только мне'],
47 [1, 'Данные моего аккаунта видны всем'],
48 [2, 'Данные моего аккаунта видны друзьям'],
49 [3, 'Данные моего аккаунта видны друзьям и членам клубов'],
50 ],
51 },
52 { 'attr' => 'country', 'type' => 'string', 'rusname' => 'Страна' },
53 { 'attr' => 'passwd', 'type' => 'password', 'rusname' => 'Пароль', 'rem' => '(<font color="red">Не отображается. Указывать при создании и для изменения</font>)' },
54 { 'attr' => 'confirm', 'type' => 'string', 'rusname' => 'Код подтверждения', hidden => 1 },
55 { 'attr' => 'secmail', 'type' => 'string', 'rusname' => 'E-mail (secondary)' },
56 { 'attr' => 'q1', 'type' => 'string', 'rusname' => 'Контрольный вопрос 1' },
57 { 'attr' => 'a1', 'type' => 'string', 'rusname' => 'Контрольный ответ 1' },
58 { 'attr' => 'q2', 'type' => 'string', 'rusname' => 'Контрольный вопрос 2' },
59 { 'attr' => 'a2', 'type' => 'string', 'rusname' => 'Контрольный ответ 2' },
60 { 'attr' => 'account', 'type' => 'string', 'rusname' => 'Сумма на счете' },
61 { 'attr' => 'interests', 'type' => 'text', 'rusname' => 'Жизненные интересы', rows => 10 },
62 { 'attr' => 'origin', 'type' => 'text', 'rusname' => 'Ориджин', rows => 4 },
63 258 ahitrov { 'attr' => 'avatar', 'type' => 'image', 'rusname' => 'Аватар', crop => ['32x32','150x150'], preview => ['200x200'] },
64 196 ahitrov )
65 }
66
67 305 ahitrov
68 sub post_init {
69 my $self = shift;
70 my $opts = shift;
71
72 $self->{passwd_prev} = $self->passwd;
73
74 return if exists $opts->{ids} || exists $opts{names} || exists $opts{light};
75 if ( $self->id && $state->{users}->use_credentials ) {
76 310 ahitrov $self->{credentials_available} = {};
77 305 ahitrov my $creds = $keeper->get_documents(
78 uid => $self->id,
79 table => 'users::SQL::CredentialsTable',
80 return_mode => 'array_ref',
81 );
82 if ( @$creds ) {
83 my %creds;
84 foreach my $cred ( @$creds ) {
85 $cred->{keeper} = undef;
86 my $main_field = $CREDENTIAL_FIELDS{$cred->class} if exists $CREDENTIAL_FIELDS{$cred->class};
87 310 ahitrov $self->{credentials_available}{$main_field} = 1;
88 305 ahitrov if ( $main_field ) {
89 my $multi_field = $main_field.'s';
90 $self->{$multi_field} = [] unless exists $self->{$multi_field};
91 push @{$self->{$multi_field}}, $cred;
92 $self->{$main_field} = $cred if $cred->main;
93 }
94 367 ahitrov if ( ref $self->{credentials_available} eq 'HASH' ) {
95 foreach my $main_field ( keys %{$self->{credentials_available}} ) {
96 my $multi_field = $main_field.'s';
97 unless ( $self->{$main_field} ) {
98 $self->{$main_field} = $self->{$multi_field}->[0];
99 }
100 }
101 }
102 305 ahitrov }
103 }
104 }
105 return;
106 }
107
108
109 238 ahitrov sub name_full
110 {
111 my $self = shift;
112 my $name = $self->name;
113 if ( $name =~ /^(.*?),[\ \t]+(.*)$/ ) {
114 $name = $2.' '.$1;
115 }
116 return $name;
117 }
118
119 sub name_part
120 {
121 my $self = shift;
122 my $name = $self->name;
123 if ( $name =~ /^(.*?),[\ \t]+(.*)$/ ) {
124 $name = $2;
125 }
126 return $name;
127 }
128
129 sub name_family
130 {
131 my $self = shift;
132 my $name = $self->name;
133 if ( $name =~ /^(.*?),[\ \t]+(.*)$/ ) {
134 $name = $1;
135 }
136 return $name;
137 }
138
139 196 ahitrov sub class_name
140 {
141 return 'Профиль пользователя';
142 }
143
144 sub class_description
145 {
146 return 'Профиль пользователя';
147 }
148
149 sub search_fields
150 {
151 return ('email', 'name', 'login');
152 }
153
154 sub class_table
155 {
156 return 'users::SQL::UserProfile';
157 }
158
159 sub contenido_status_style
160 {
161 my $self = shift;
162 if ( $self->status == 2 ) {
163 return 'color:green;';
164 } elsif ( $self->status == 3 ) {
165 return 'color:olive;';
166 } elsif ( $self->status == 4 ) {
167 return 'color:green;';
168 } elsif ( $self->status == 5 ) {
169 return 'color:red;';
170 }
171 }
172
173 305 ahitrov
174 310 ahitrov sub get_credentials {
175 my ($self, $name, %opts) = @_;
176 my $objects;
177 if ( $name ) {
178 return undef unless exists $CREDENTIAL_REVERSE{$name};
179 my $names = $name.'s';
180 if ( exists $self->{credentials_available}{$name} ) {
181 $objects = $self->{$names};
182 }
183 } elsif ( my @keys = keys %{$self->{credentials_available}} ) {
184 $objects = {};
185 foreach my $key ( @keys ) {
186 my $names = $key.'s';
187 311 ahitrov push @{$objects->{$key}}, $self->{$names};
188 310 ahitrov }
189 }
190 return $objects;
191 }
192
193 305 ahitrov sub confirm_credential {
194 my ($self, %opts) = @_;
195 my $object;
196 if ( exists $opts{confirm} && $opts{name} && $opts{class} ) {
197 ($object) = $self->keeper->get_documents(
198 class => $opts{class},
199 uid => $self->id,
200 name => lc($opts{name}),
201 limit => 1,
202 );
203 if ( ref $object && $object->confirm eq $opts{confirm} ) {
204 $object->status(1);
205 $object->store;
206 }
207 } elsif ( $opts{name} && $opts{class} ) {
208 ($object) = $self->keeper->get_documents(
209 class => $opts{class},
210 uid => $self->id,
211 name => lc($opts{name}),
212 limit => 1,
213 );
214 if ( ref $object ) {
215 $object->status(1);
216 $object->store;
217 }
218 }
219 return $object;
220 }
221
222
223 sub create_credential {
224 my ($self, %opts) = @_;
225 my $object;
226 if ( $opts{vkontakte} ) {
227 ($object) = $self->keeper->get_documents(
228 306 ahitrov class => 'users::OA::VK',
229 305 ahitrov ext_id => $opts{vkontakte},
230 limit => 1,
231 );
232 310 ahitrov return undef if ref $object && $object->uid != $self->id;
233 305 ahitrov unless ( ref $object ) {
234 $object = users::OA::VK->new ($keeper);
235 $object->name( $opts{name} );
236 314 ahitrov $object->ext_id( $opts{vkontakte} );
237 305 ahitrov $object->status( 1 );
238 $object->opaque( $opts{opaque} || 0 );
239 $object->uid( $self->id );
240 $object->ava_url( $opts{avatar} );
241 $object->store;
242 }
243 } elsif ( $opts{facebook} ) {
244 ($object) = $self->keeper->get_documents(
245 306 ahitrov class => 'users::OA::FaceBook',
246 305 ahitrov ext_id => $opts{facebook},
247 limit => 1,
248 );
249 310 ahitrov return undef if ref $object && $object->uid != $self->id;
250 305 ahitrov unless ( ref $object ) {
251 $object = users::OA::FaceBook->new ($keeper);
252 $object->name( $opts{name} );
253 314 ahitrov $object->ext_id( $opts{facebook} );
254 305 ahitrov $object->status( 1 );
255 $object->opaque( $opts{opaque} || 0 );
256 $object->uid( $self->id );
257 $object->ava_url( $opts{avatar} );
258 $object->store;
259 }
260 } elsif ( $opts{google} ) {
261 ($object) = $self->keeper->get_documents(
262 306 ahitrov class => 'users::OA::Google',
263 305 ahitrov ext_id => $opts{google},
264 limit => 1,
265 );
266 310 ahitrov return undef if ref $object && $object->uid != $self->id;
267 305 ahitrov unless ( ref $object ) {
268 $object = users::OA::Google->new ($keeper);
269 $object->name( $opts{name} );
270 314 ahitrov $object->ext_id( $opts{google} );
271 305 ahitrov if ( $opts{email} ) {
272 $object->email( $opts{email} );
273 $self->create_credential( email => $opts{email}, status => 1 );
274 }
275 $object->status( 1 );
276 $object->opaque( $opts{opaque} || 0 );
277 $object->uid( $self->id );
278 $object->ava_url( $opts{avatar} );
279 $object->store;
280 }
281 } elsif ( $opts{mailru} ) {
282 ($object) = $self->keeper->get_documents(
283 306 ahitrov class => 'users::OA::Mailru',
284 305 ahitrov ext_id => $opts{mailru},
285 limit => 1,
286 );
287 310 ahitrov return undef if ref $object && $object->uid != $self->id;
288 305 ahitrov unless ( ref $object ) {
289 $object = users::OA::Mailru->new ($keeper);
290 $object->name( $opts{name} );
291 314 ahitrov $object->ext_id( $opts{mailru} );
292 305 ahitrov if ( $opts{email} ) {
293 $object->email( $opts{email} );
294 $self->create_credential( email => $opts{email}, status => 1 );
295 }
296 $object->status( 1 );
297 $object->opaque( $opts{opaque} || 0 );
298 $object->uid( $self->id );
299 $object->ava_url( $opts{avatar} );
300 $object->store;
301 }
302 } elsif ( $opts{email} ) {
303 ($object) = $self->keeper->get_documents(
304 306 ahitrov class => 'users::Email',
305 305 ahitrov name => lc($opts{email}),
306 limit => 1,
307 );
308 310 ahitrov return undef if ref $object && $object->uid != $self->id;
309 305 ahitrov unless ( ref $object ) {
310 $object = users::Email->new ($keeper);
311 $object->name( lc($opts{email}) );
312 $object->name_orig( $opts{email} );
313 $object->main( $opts{main} || 0 );
314 $object->status( $opts{status} || 0 );
315 $object->opaque( $opts{opaque} || 0 );
316 $object->uid( $self->id );
317 $object->confirm( Digest::MD5::md5_hex(int(rand(1000000)), $self->id, $opts{email}) );
318 $object->store;
319 }
320 } elsif ( $opts{phone} ) {
321 ($object) = $self->keeper->get_documents(
322 306 ahitrov class => 'users::Phone',
323 305 ahitrov name => $keeper->{users}->_phone_reduction( $opts{phone} ),
324 limit => 1,
325 );
326 310 ahitrov return undef if ref $object && $object->uid != $self->id;
327 305 ahitrov unless ( ref $object ) {
328 $object = users::Phone->new ($keeper);
329 $object->name( $keeper->{users}->_phone_reduction($opts{phone}) );
330 $object->name_format( $keeper->{users}->_phone_format($opts{phone}) );
331 $object->name_orig( $opts{phone} );
332 $object->main( $opts{main} || 0 );
333 $object->status( $opts{status} || 0 );
334 $object->opaque( $opts{opaque} || 0 );
335 $object->uid( $self->id );
336 $object->confirm( Digest::MD5::md5_hex(int(rand(1000000)), $self->id, $opts{email}) );
337 $object->store;
338 }
339 }
340 return $object;
341 }
342
343
344 339 ahitrov sub table_links
345 {
346 my $self = shift;
347 my @links;
348 if ( $state->{users}->use_credentials ) {
349 @links = (
350 { name => 'E-mail', class => 'users::Email', filter => 'uid', field => 'uid' },
351 { name => 'Phone', class => 'users::Phone', filter => 'uid', field => 'uid' },
352 );
353 }
354 return \@links;
355 }
356
357 196 ahitrov sub pre_store
358 {
359 my $self = shift;
360
361 305 ahitrov my $passwd_prev = $self->{passwd_prev} || '';
362 if ( $self->passwd && $self->passwd ne $passwd_prev ) {
363 196 ahitrov warn "Pass = ".$self->passwd."\n" if $DEBUG;
364 my $pass = Digest::MD5::md5_hex($self->passwd);
365 warn "Pass_hex = $pass\n" if $DEBUG;
366 $self->passwd($pass);
367 305 ahitrov } else {
368 $self->passwd($passwd_prev);
369 196 ahitrov }
370 305 ahitrov $self->login( lc($self->login) );
371 196 ahitrov
372 305 ahitrov if ( $state->{users}->use_credentials ) {
373 foreach my $prop ( $self->structure ) {
374 my $name = $prop->{attr};
375 325 ahitrov if ( ref($self->{$name}) =~ /^users\:\:OA\:\:/ ) {
376 315 ahitrov my $obj = $self->{$name};
377 321 ahitrov $self->{$name} = $obj->ext_id;
378 325 ahitrov } elsif ( ref($self->{$name}) =~ /^users\:\:/ ) {
379 315 ahitrov my $obj = $self->{$name};
380 321 ahitrov $self->{$name} = $obj->name;
381 305 ahitrov }
382 }
383 } else {
384 $self->email( $keeper->{users}->_email_reduction($self->email) );
385 }
386
387 196 ahitrov my $default_section = $project->s_alias->{users} if ref $project->s_alias eq 'HASH' && exists $project->s_alias->{users};
388 if ( $default_section ) {
389 my $sections = $self->{sections};
390 if ( ref $sections eq 'ARRAY' && scalar @$sections ) {
391 my @new_sects = grep { $_ != $default_section } @$sections;
392 push @new_sects, $default_section;
393 $self->sections(@new_sects);
394 } elsif ( $sections && !ref $sections && $sections != $default_section ) {
395 my @new_sects = ($default_section, $sections);
396 $self->sections(@new_sects);
397 } else {
398 $self->sections($default_section);
399 }
400 }
401 return 1;
402 }
403 310 ahitrov
404
405 sub post_delete
406 {
407 my $self = shift;
408
409 if ( $state->{users}->use_credentials ) {
410 my $creds = $keeper->get_documents(
411 table => 'users::SQL::CredentialsTable',
412 uid => $self->id,
413 return_mode => 'array_ref',
414 );
415 map { $_->delete( attachments => 1 ) } @$creds;
416 }
417 1;
418 }
419
420 196 ahitrov 1;