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 379 ahitrov return undef unless $self->id;
196 305 ahitrov my $object;
197 if ( exists $opts{confirm} && $opts{name} && $opts{class} ) {
198 ($object) = $self->keeper->get_documents(
199 class => $opts{class},
200 uid => $self->id,
201 name => lc($opts{name}),
202 limit => 1,
203 );
204 if ( ref $object && $object->confirm eq $opts{confirm} ) {
205 $object->status(1);
206 $object->store;
207 }
208 } elsif ( $opts{name} && $opts{class} ) {
209 ($object) = $self->keeper->get_documents(
210 class => $opts{class},
211 uid => $self->id,
212 name => lc($opts{name}),
213 limit => 1,
214 );
215 if ( ref $object ) {
216 $object->status(1);
217 $object->store;
218 }
219 }
220 379 ahitrov if ( ref $object && ($object->class eq 'users::Phone' || $object->class eq 'users::Email') && $object->main && $self->status == 5 ) {
221 $self->status(1);
222 $self->store;
223 }
224 305 ahitrov return $object;
225 }
226
227
228 sub create_credential {
229 my ($self, %opts) = @_;
230 my $object;
231 if ( $opts{vkontakte} ) {
232 ($object) = $self->keeper->get_documents(
233 306 ahitrov class => 'users::OA::VK',
234 305 ahitrov ext_id => $opts{vkontakte},
235 limit => 1,
236 );
237 310 ahitrov return undef if ref $object && $object->uid != $self->id;
238 305 ahitrov unless ( ref $object ) {
239 $object = users::OA::VK->new ($keeper);
240 $object->name( $opts{name} );
241 314 ahitrov $object->ext_id( $opts{vkontakte} );
242 305 ahitrov $object->status( 1 );
243 $object->opaque( $opts{opaque} || 0 );
244 $object->uid( $self->id );
245 $object->ava_url( $opts{avatar} );
246 $object->store;
247 }
248 } elsif ( $opts{facebook} ) {
249 ($object) = $self->keeper->get_documents(
250 306 ahitrov class => 'users::OA::FaceBook',
251 305 ahitrov ext_id => $opts{facebook},
252 limit => 1,
253 );
254 310 ahitrov return undef if ref $object && $object->uid != $self->id;
255 305 ahitrov unless ( ref $object ) {
256 $object = users::OA::FaceBook->new ($keeper);
257 $object->name( $opts{name} );
258 314 ahitrov $object->ext_id( $opts{facebook} );
259 305 ahitrov $object->status( 1 );
260 $object->opaque( $opts{opaque} || 0 );
261 $object->uid( $self->id );
262 $object->ava_url( $opts{avatar} );
263 $object->store;
264 }
265 } elsif ( $opts{google} ) {
266 ($object) = $self->keeper->get_documents(
267 306 ahitrov class => 'users::OA::Google',
268 305 ahitrov ext_id => $opts{google},
269 limit => 1,
270 );
271 310 ahitrov return undef if ref $object && $object->uid != $self->id;
272 305 ahitrov unless ( ref $object ) {
273 $object = users::OA::Google->new ($keeper);
274 $object->name( $opts{name} );
275 314 ahitrov $object->ext_id( $opts{google} );
276 305 ahitrov if ( $opts{email} ) {
277 $object->email( $opts{email} );
278 $self->create_credential( email => $opts{email}, status => 1 );
279 }
280 $object->status( 1 );
281 $object->opaque( $opts{opaque} || 0 );
282 $object->uid( $self->id );
283 $object->ava_url( $opts{avatar} );
284 $object->store;
285 }
286 } elsif ( $opts{mailru} ) {
287 ($object) = $self->keeper->get_documents(
288 306 ahitrov class => 'users::OA::Mailru',
289 305 ahitrov ext_id => $opts{mailru},
290 limit => 1,
291 );
292 310 ahitrov return undef if ref $object && $object->uid != $self->id;
293 305 ahitrov unless ( ref $object ) {
294 $object = users::OA::Mailru->new ($keeper);
295 $object->name( $opts{name} );
296 314 ahitrov $object->ext_id( $opts{mailru} );
297 305 ahitrov if ( $opts{email} ) {
298 $object->email( $opts{email} );
299 $self->create_credential( email => $opts{email}, status => 1 );
300 }
301 $object->status( 1 );
302 $object->opaque( $opts{opaque} || 0 );
303 $object->uid( $self->id );
304 $object->ava_url( $opts{avatar} );
305 $object->store;
306 }
307 } elsif ( $opts{email} ) {
308 ($object) = $self->keeper->get_documents(
309 306 ahitrov class => 'users::Email',
310 305 ahitrov name => lc($opts{email}),
311 limit => 1,
312 );
313 310 ahitrov return undef if ref $object && $object->uid != $self->id;
314 305 ahitrov unless ( ref $object ) {
315 $object = users::Email->new ($keeper);
316 $object->name( lc($opts{email}) );
317 $object->name_orig( $opts{email} );
318 $object->main( $opts{main} || 0 );
319 $object->status( $opts{status} || 0 );
320 $object->opaque( $opts{opaque} || 0 );
321 $object->uid( $self->id );
322 $object->confirm( Digest::MD5::md5_hex(int(rand(1000000)), $self->id, $opts{email}) );
323 $object->store;
324 373 ahitrov } else {
325 if ( exists $opts{status} && $object->status != $opts{status} ) {
326 $object->status( $opts{status} );
327 $object->store;
328 }
329 305 ahitrov }
330 373 ahitrov if ( $opts{main} ) {
331 my $sql = $keeper->SQL->prepare('update profile_credentials set main = 0 where class = ? and uid = ? and id != ?');
332 $sql->execute( $object->class, $self->id, $object->id );
333 $sql->finish;
334 }
335 305 ahitrov } elsif ( $opts{phone} ) {
336 ($object) = $self->keeper->get_documents(
337 306 ahitrov class => 'users::Phone',
338 305 ahitrov name => $keeper->{users}->_phone_reduction( $opts{phone} ),
339 limit => 1,
340 );
341 310 ahitrov return undef if ref $object && $object->uid != $self->id;
342 305 ahitrov unless ( ref $object ) {
343 $object = users::Phone->new ($keeper);
344 $object->name( $keeper->{users}->_phone_reduction($opts{phone}) );
345 $object->name_format( $keeper->{users}->_phone_format($opts{phone}) );
346 $object->name_orig( $opts{phone} );
347 $object->main( $opts{main} || 0 );
348 $object->status( $opts{status} || 0 );
349 $object->opaque( $opts{opaque} || 0 );
350 $object->uid( $self->id );
351 $object->confirm( Digest::MD5::md5_hex(int(rand(1000000)), $self->id, $opts{email}) );
352 $object->store;
353 373 ahitrov } else {
354 if ( exists $opts{status} && $object->status != $opts{status} ) {
355 $object->status( $opts{status} );
356 $object->store;
357 }
358 305 ahitrov }
359 373 ahitrov if ( $opts{main} ) {
360 my $sql = $keeper->SQL->prepare('update profile_credentials set main = 0 where class = ? and uid = ? and id != ?');
361 $sql->execute( $object->class, $self->id, $object->id );
362 $sql->finish;
363 }
364 305 ahitrov }
365 return $object;
366 }
367
368
369 339 ahitrov sub table_links
370 {
371 my $self = shift;
372 my @links;
373 if ( $state->{users}->use_credentials ) {
374 @links = (
375 { name => 'E-mail', class => 'users::Email', filter => 'uid', field => 'uid' },
376 { name => 'Phone', class => 'users::Phone', filter => 'uid', field => 'uid' },
377 );
378 }
379 return \@links;
380 }
381
382 196 ahitrov sub pre_store
383 {
384 my $self = shift;
385
386 305 ahitrov my $passwd_prev = $self->{passwd_prev} || '';
387 if ( $self->passwd && $self->passwd ne $passwd_prev ) {
388 196 ahitrov warn "Pass = ".$self->passwd."\n" if $DEBUG;
389 my $pass = Digest::MD5::md5_hex($self->passwd);
390 warn "Pass_hex = $pass\n" if $DEBUG;
391 $self->passwd($pass);
392 305 ahitrov } else {
393 $self->passwd($passwd_prev);
394 196 ahitrov }
395 305 ahitrov $self->login( lc($self->login) );
396 196 ahitrov
397 305 ahitrov if ( $state->{users}->use_credentials ) {
398 foreach my $prop ( $self->structure ) {
399 my $name = $prop->{attr};
400 325 ahitrov if ( ref($self->{$name}) =~ /^users\:\:OA\:\:/ ) {
401 315 ahitrov my $obj = $self->{$name};
402 321 ahitrov $self->{$name} = $obj->ext_id;
403 325 ahitrov } elsif ( ref($self->{$name}) =~ /^users\:\:/ ) {
404 315 ahitrov my $obj = $self->{$name};
405 321 ahitrov $self->{$name} = $obj->name;
406 305 ahitrov }
407 }
408 } else {
409 $self->email( $keeper->{users}->_email_reduction($self->email) );
410 }
411
412 196 ahitrov my $default_section = $project->s_alias->{users} if ref $project->s_alias eq 'HASH' && exists $project->s_alias->{users};
413 if ( $default_section ) {
414 my $sections = $self->{sections};
415 if ( ref $sections eq 'ARRAY' && scalar @$sections ) {
416 my @new_sects = grep { $_ != $default_section } @$sections;
417 push @new_sects, $default_section;
418 $self->sections(@new_sects);
419 } elsif ( $sections && !ref $sections && $sections != $default_section ) {
420 my @new_sects = ($default_section, $sections);
421 $self->sections(@new_sects);
422 } else {
423 $self->sections($default_section);
424 }
425 }
426 return 1;
427 }
428 310 ahitrov
429
430 379 ahitrov sub post_store
431 {
432 my $self = shift;
433
434 if ( $state->{users}->use_credentials && $self->email ) {
435 $self->create_credential( email => $self->email, main => 1, $self->status == 1 ? (status => 1) : () );
436 }
437
438 1;
439 }
440
441
442 310 ahitrov sub post_delete
443 {
444 my $self = shift;
445
446 if ( $state->{users}->use_credentials ) {
447 my $creds = $keeper->get_documents(
448 table => 'users::SQL::CredentialsTable',
449 uid => $self->id,
450 return_mode => 'array_ref',
451 );
452 map { $_->delete( attachments => 1 ) } @$creds;
453 }
454 1;
455 }
456
457 196 ahitrov 1;