]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - plugins/ExtendedProfile/actions/profiledetailsettings.php
Merge branch '1.0.x' of gitorious.org:statusnet/mainline into 1.0.x
[quix0rs-gnu-social.git] / plugins / ExtendedProfile / actions / profiledetailsettings.php
1 <?php
2 /*
3  * StatusNet - the distributed open-source microblogging tool
4  * Copyright (C) 2011, StatusNet, Inc.
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Affero General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Affero General Public License for more details.
15  *
16  * You should have received a copy of the GNU Affero General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 if (!defined('STATUSNET')) {
21     exit(1);
22 }
23
24 class ProfileDetailSettingsAction extends ProfileSettingsAction
25 {
26
27     function title()
28     {
29         return _m('Extended profile settings');
30     }
31
32     /**
33      * Instructions for use
34      *
35      * @return instructions for use
36      */
37     function getInstructions()
38     {
39         // TRANS: Usage instructions for profile settings.
40         return _('You can update your personal profile info here '.
41                  'so people know more about you.');
42     }
43
44     function showStylesheets() {
45         parent::showStylesheets();
46         $this->cssLink('plugins/ExtendedProfile/css/profiledetail.css');
47         return true;
48     }
49
50     function  showScripts() {
51         parent::showScripts();
52         $this->script('plugins/ExtendedProfile/js/profiledetail.js');
53         return true;
54     }
55
56     function handlePost()
57     {
58         // CSRF protection
59         $token = $this->trimmed('token');
60         if (!$token || $token != common_session_token()) {
61             $this->showForm(
62                 _m(
63                     'There was a problem with your session token. '
64                     .   'Try again, please.'
65                   )
66             );
67             return;
68         }
69
70         if ($this->arg('save')) {
71             $this->saveDetails();
72         } else {
73             // TRANS: Message given submitting a form with an unknown action
74             $this->showForm(_m('Unexpected form submission.'));
75         }
76     }
77
78     function showContent()
79     {
80         $cur = common_current_user();
81         $profile = $cur->getProfile();
82
83         $widget = new ExtendedProfileWidget(
84             $this,
85             $profile,
86             ExtendedProfileWidget::EDITABLE
87         );
88         $widget->show();
89     }
90
91     function saveDetails()
92     {
93         common_debug(var_export($_POST, true));
94
95         $user = common_current_user();
96
97         try {
98             $this->saveStandardProfileDetails($user);
99
100             $profile = $user->getProfile();
101
102             $simpleFieldNames = array('title', 'spouse', 'kids', 'manager');
103             $dateFieldNames   = array('birthday');
104
105             foreach ($simpleFieldNames as $name) {
106                 $value = $this->trimmed('extprofile-' . $name);
107                 if (!empty($value)) {
108                     $this->saveField($user, $name, $value);
109                 }
110             }
111
112             foreach ($dateFieldNames as $name) {
113                 $value = $this->trimmed('extprofile-' . $name);
114                 $dateVal = $this->parseDate($name, $value);
115                 $this->saveField(
116                     $user,
117                     $name,
118                     null,
119                     null,
120                     null,
121                     $dateVal
122                 );
123             }
124
125             $this->savePhoneNumbers($user);
126             $this->saveIms($user);
127             $this->saveWebsites($user);
128             $this->saveExperiences($user);
129             $this->saveEducations($user);
130
131         } catch (Exception $e) {
132             $this->showForm($e->getMessage(), false);
133             return;
134         }
135
136         $this->showForm(_('Details saved.'), true);
137
138     }
139
140     function parseDate($fieldname, $datestr, $required = false)
141     {
142         if (empty($datestr)) {
143             if ($required) {
144                 $msg = sprintf(
145                     _m('You must supply a date for "%s".'),
146                     $fieldname
147                 );
148                 throw new Exception($msg);
149             }
150         } else {
151             $ts = strtotime($datestr);
152             if ($ts === false) {
153                 throw new Exception(
154                     sprintf(
155                         _m('Invalid date entered for "%s": %s'),
156                         $fieldname,
157                         $ts
158                     )
159                 );
160             }
161             return common_sql_date($ts);
162         }
163         return null;
164     }
165
166     function savePhoneNumbers($user) {
167         $phones = $this->findPhoneNumbers();
168         $this->removeAll($user, 'phone');
169         $i = 0;
170         foreach($phones as $phone) {
171             if (!empty($phone['value'])) {
172                 ++$i;
173                 $this->saveField(
174                     $user,
175                     'phone',
176                     $phone['value'],
177                     $phone['rel'],
178                     $i
179                 );
180             }
181         }
182     }
183
184     function findPhoneNumbers() {
185
186         // Form vals look like this:
187         // 'extprofile-phone-1' => '11332',
188         // 'extprofile-phone-1-rel' => 'mobile',
189
190         $phones     = $this->sliceParams('phone', 2);
191         $phoneArray = array();
192
193         foreach ($phones as $phone) {
194             list($number, $rel) = array_values($phone);
195             $phoneArray[] = array(
196                 'value' => $number,
197                 'rel'   => $rel
198             );
199         }
200
201         return $phoneArray;
202     }
203
204     function findIms() {
205
206         //  Form vals look like this:
207         // 'extprofile-im-0' => 'jed',
208         // 'extprofile-im-0-rel' => 'yahoo',
209
210         $ims     = $this->sliceParams('im', 2);
211         $imArray = array();
212
213         foreach ($ims as $im) {
214             list($id, $rel) = array_values($im);
215             $imArray[] = array(
216                 'value' => $id,
217                 'rel'   => $rel
218             );
219         }
220
221         return $imArray;
222     }
223
224     function saveIms($user) {
225         $ims = $this->findIms();
226         $this->removeAll($user, 'im');
227         $i = 0;
228         foreach($ims as $im) {
229             if (!empty($im['value'])) {
230                 ++$i;
231                 $this->saveField(
232                     $user,
233                     'im',
234                     $im['value'],
235                     $im['rel'],
236                     $i
237                 );
238             }
239         }
240     }
241
242     function findWebsites() {
243
244         //  Form vals look like this:
245
246         $sites = $this->sliceParams('website', 2);
247         $wsArray = array();
248
249         foreach ($sites as $site) {
250             list($id, $rel) = array_values($site);
251             $wsArray[] = array(
252                 'value' => $id,
253                 'rel'   => $rel
254             );
255         }
256
257         return $wsArray;
258     }
259
260     function saveWebsites($user) {
261         $sites = $this->findWebsites();
262         $this->removeAll($user, 'website');
263         $i = 0;
264         foreach($sites as $site) {
265             if (!empty($site['value']) && !Validate::uri(
266                 $site['value'],
267                 array('allowed_schemes' => array('http', 'https')))
268             ) {
269                 throw new Exception(sprintf(_m('Invalid URL: %s'), $site['value']));
270             }
271
272             if (!empty($site['value'])) {
273                 ++$i;
274                 $this->saveField(
275                     $user,
276                     'website',
277                     $site['value'],
278                     $site['rel'],
279                     $i
280                 );
281             }
282         }
283     }
284
285     function findExperiences() {
286
287         // Form vals look like this:
288         // 'extprofile-experience-0'         => 'Bozotronix',
289         // 'extprofile-experience-0-current' => 'true'
290         // 'extprofile-experience-0-start'   => '1/5/10',
291         // 'extprofile-experience-0-end'     => '2/3/11',
292
293         $experiences = $this->sliceParams('experience', 4);
294         $expArray = array();
295
296         foreach ($experiences as $exp) {
297             if (sizeof($experiences) == 4) {
298                 list($company, $current, $end, $start) = array_values($exp);
299             } else {
300                 $end = null;
301                 list($company, $current, $start) = array_values($exp);
302             }
303             if (!empty($company)) {
304                 $expArray[] = array(
305                     'company' => $company,
306                     'start'   => $this->parseDate('Start', $start, true),
307                     'end'     => ($current == 'false') ? $this->parseDate('End', $end, true) : null,
308                     'current' => ($current == 'false') ? false : true
309                 );
310             }
311         }
312
313         return $expArray;
314     }
315
316     function saveExperiences($user) {
317         common_debug('save experiences');
318         $experiences = $this->findExperiences();
319
320         $this->removeAll($user, 'company');
321         $this->removeAll($user, 'start');
322         $this->removeAll($user, 'end'); // also stores 'current'
323
324         $i = 0;
325         foreach($experiences as $experience) {
326             if (!empty($experience['company'])) {
327                 ++$i;
328                 $this->saveField(
329                     $user,
330                     'company',
331                     $experience['company'],
332                     null,
333                     $i
334                 );
335
336                 $this->saveField(
337                     $user,
338                     'start',
339                     null,
340                     null,
341                     $i,
342                     $experience['start']
343                 );
344
345                 // Save "current" employer indicator in rel
346                 if ($experience['current']) {
347                     $this->saveField(
348                         $user,
349                         'end',
350                         null,
351                         'current', // rel
352                         $i
353                     );
354                 } else {
355                     $this->saveField(
356                         $user,
357                         'end',
358                         null,
359                         null,
360                         $i,
361                         $experience['end']
362                     );
363                 }
364
365             }
366         }
367     }
368
369     function findEducations() {
370
371         // Form vals look like this:
372         // 'extprofile-education-0-school' => 'Pigdog',
373         // 'extprofile-education-0-degree' => 'BA',
374         // 'extprofile-education-0-description' => 'Blar',
375         // 'extprofile-education-0-start' => '05/22/99',
376         // 'extprofile-education-0-end' => '05/22/05',
377
378         $edus = $this->sliceParams('education', 5);
379         $eduArray = array();
380
381         foreach ($edus as $edu) {
382             list($school, $degree, $description, $end, $start) = array_values($edu);
383             if (!empty($school)) {
384                 $eduArray[] = array(
385                     'school'      => $school,
386                     'degree'      => $degree,
387                     'description' => $description,
388                     'start'       => $this->parseDate('Start', $start, true),
389                     'end'         => $this->parseDate('End', $end, true)
390                 );
391             }
392         }
393
394         return $eduArray;
395     }
396
397
398     function saveEducations($user) {
399          common_debug('save education');
400          $edus = $this->findEducations();
401          common_debug(var_export($edus, true));
402
403          $this->removeAll($user, 'school');
404          $this->removeAll($user, 'degree');
405          $this->removeAll($user, 'degree_descr');
406          $this->removeAll($user, 'school_start');
407          $this->removeAll($user, 'school_end');
408
409          $i = 0;
410          foreach($edus as $edu) {
411              if (!empty($edu['school'])) {
412                  ++$i;
413                  $this->saveField(
414                      $user,
415                      'school',
416                      $edu['school'],
417                      null,
418                      $i
419                  );
420                  $this->saveField(
421                      $user,
422                      'degree',
423                      $edu['degree'],
424                      null,
425                      $i
426                  );
427                  $this->saveField(
428                      $user,
429                      'degree_descr',
430                      $edu['description'],
431                      null,
432                      $i
433                  );
434                  $this->saveField(
435                      $user,
436                      'school_start',
437                      null,
438                      null,
439                      $i,
440                      $edu['start']
441                  );
442
443                  $this->saveField(
444                      $user,
445                      'school_end',
446                      null,
447                      null,
448                      $i,
449                      $edu['end']
450                  );
451             }
452          }
453      }
454
455     function arraySplit($array, $pieces)
456     {
457         if ($pieces < 2) {
458             return array($array);
459         }
460
461         $newCount = ceil(count($array) / $pieces);
462         $a = array_slice($array, 0, $newCount);
463         $b = $this->arraySplit(array_slice($array, $newCount), $pieces - 1);
464
465         return array_merge(array($a), $b);
466     }
467
468     function findMultiParams($type) {
469         $formVals = array();
470         $target   = $type;
471         foreach ($_POST as $key => $val) {
472             if (strrpos('extprofile-' . $key, $target) !== false) {
473                 $formVals[$key] = $val;
474             }
475         }
476         return $formVals;
477     }
478
479     function sliceParams($key, $size) {
480         $slice = array();
481         $params = $this->findMultiParams($key);
482         ksort($params);
483         $slice = $this->arraySplit($params, sizeof($params) / $size);
484         return $slice;
485     }
486
487     /**
488      * Save an extended profile field as a Profile_detail
489      *
490      * @param User   $user    the current user
491      * @param string $name    field name
492      * @param string $value   field value
493      * @param string $rel     field rel (type)
494      * @param int    $index   index (fields can have multiple values)
495      * @param date   $date    related date
496      */
497     function saveField($user, $name, $value, $rel = null, $index = null, $date = null)
498     {
499         $profile = $user->getProfile();
500         $detail  = new Profile_detail();
501
502         $detail->profile_id  = $profile->id;
503         $detail->field_name  = $name;
504         $detail->value_index = $index;
505
506         $result = $detail->find(true);
507
508         if (empty($result)) {
509             $detial->value_index = $index;
510             $detail->rel         = $rel;
511             $detail->field_value = $value;
512             $detail->date        = $date;
513             $detail->created     = common_sql_now();
514             $result = $detail->insert();
515             if (empty($result)) {
516                 common_log_db_error($detail, 'INSERT', __FILE__);
517                 $this->serverError(_m('Could not save profile details.'));
518             }
519         } else {
520             $orig = clone($detail);
521
522             $detail->field_value = $value;
523             $detail->rel         = $rel;
524             $detail->date        = $date;
525
526             $result = $detail->update($orig);
527             if (empty($result)) {
528                 common_log_db_error($detail, 'UPDATE', __FILE__);
529                 $this->serverError(_m('Could not save profile details.'));
530             }
531         }
532
533         $detail->free();
534     }
535
536     function removeAll($user, $name)
537     {
538         $profile = $user->getProfile();
539         $detail  = new Profile_detail();
540         $detail->profile_id  = $profile->id;
541         $detail->field_name  = $name;
542         $detail->delete();
543         $detail->free();
544     }
545
546     /**
547      * Save fields that should be stored in the main profile object
548      *
549      * XXX: There's a lot of dupe code here from ProfileSettingsAction.
550      *      Do not want.
551      *
552      * @param User $user the current user
553      */
554     function saveStandardProfileDetails($user)
555     {
556         $fullname  = $this->trimmed('extprofile-fullname');
557         $location  = $this->trimmed('extprofile-location');
558         $tagstring = $this->trimmed('extprofile-tags');
559         $bio       = $this->trimmed('extprofile-bio');
560
561         if ($tagstring) {
562             $tags = array_map(
563                 'common_canonical_tag',
564                 preg_split('/[\s,]+/', $tagstring)
565             );
566         } else {
567             $tags = array();
568         }
569
570         foreach ($tags as $tag) {
571             if (!common_valid_profile_tag($tag)) {
572                 // TRANS: Validation error in form for profile settings.
573                 // TRANS: %s is an invalid tag.
574                 throw new Exception(sprintf(_m('Invalid tag: "%s".'), $tag));
575             }
576         }
577
578         $profile = $user->getProfile();
579
580         $oldTags = $user->getSelfTags();
581         $newTags = array_diff($tags, $oldTags);
582
583         if ($fullname    != $profile->fullname
584             || $location != $profile->location
585             || !empty($newTags)
586             || $bio      != $profile->bio) {
587
588             $orig = clone($profile);
589
590             $profile->nickname = $user->nickname;
591             $profile->fullname = $fullname;
592             $profile->bio      = $bio;
593             $profile->location = $location;
594
595             $loc = Location::fromName($location);
596
597             if (empty($loc)) {
598                 $profile->lat         = null;
599                 $profile->lon         = null;
600                 $profile->location_id = null;
601                 $profile->location_ns = null;
602             } else {
603                 $profile->lat         = $loc->lat;
604                 $profile->lon         = $loc->lon;
605                 $profile->location_id = $loc->location_id;
606                 $profile->location_ns = $loc->location_ns;
607             }
608
609             $profile->profileurl = common_profile_url($user->nickname);
610
611             $result = $profile->update($orig);
612
613             if ($result === false) {
614                 common_log_db_error($profile, 'UPDATE', __FILE__);
615                 // TRANS: Server error thrown when user profile settings could not be saved.
616                 $this->serverError(_('Could not save profile.'));
617                 return;
618             }
619
620             // Set the user tags
621             $result = $user->setSelfTags($tags);
622
623             if (!$result) {
624                 // TRANS: Server error thrown when user profile settings tags could not be saved.
625                 $this->serverError(_('Could not save tags.'));
626                 return;
627             }
628
629             Event::handle('EndProfileSaveForm', array($this));
630             common_broadcast_profile($profile);
631         }
632     }
633
634 }