]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - plugins/ExtendedProfile/actions/profiledetailsettings.php
Merge commit 'refs/merge-requests/157' of git://gitorious.org/statusnet/mainline...
[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     function title()
27     {
28         // TRANS: Title for extended profile settings.
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 _m('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                 // TRANS: Client error displayed when the session token does not match or is not given.
63                 _m('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         // TRANS: Success message after saving extended profile details.
137         $this->showForm(_m('Details saved.'), true);
138
139     }
140
141     function parseDate($fieldname, $datestr, $required = false)
142     {
143         if (empty($datestr)) {
144             if ($required) {
145                 $msg = sprintf(
146                     // TRANS: Exception thrown when no date was entered in a required date field.
147                     // TRANS: %s is the field name.
148                     _m('You must supply a date for "%s".'),
149                     $fieldname
150                 );
151                 throw new Exception($msg);
152             }
153         } else {
154             $ts = strtotime($datestr);
155             if ($ts === false) {
156                 throw new Exception(
157                     sprintf(
158                         // TRANS: Exception thrown on incorrect data input.
159                         // TRANS: %1$s is a field name, %2$s is the incorrect input.
160                         _m('Invalid date entered for "%1$s": %2$s.'),
161                         $fieldname,
162                         $ts
163                     )
164                 );
165             }
166             return common_sql_date($ts);
167         }
168         return null;
169     }
170
171     function savePhoneNumbers($user) {
172         $phones = $this->findPhoneNumbers();
173         $this->removeAll($user, 'phone');
174         $i = 0;
175         foreach($phones as $phone) {
176             if (!empty($phone['value'])) {
177                 ++$i;
178                 $this->saveField(
179                     $user,
180                     'phone',
181                     $phone['value'],
182                     $phone['rel'],
183                     $i
184                 );
185             }
186         }
187     }
188
189     function findPhoneNumbers() {
190
191         // Form vals look like this:
192         // 'extprofile-phone-1' => '11332',
193         // 'extprofile-phone-1-rel' => 'mobile',
194
195         $phones     = $this->sliceParams('phone', 2);
196         $phoneArray = array();
197
198         foreach ($phones as $phone) {
199             list($number, $rel) = array_values($phone);
200             $phoneArray[] = array(
201                 'value' => $number,
202                 'rel'   => $rel
203             );
204         }
205
206         return $phoneArray;
207     }
208
209     function findIms() {
210
211         //  Form vals look like this:
212         // 'extprofile-im-0' => 'jed',
213         // 'extprofile-im-0-rel' => 'yahoo',
214
215         $ims     = $this->sliceParams('im', 2);
216         $imArray = array();
217
218         foreach ($ims as $im) {
219             list($id, $rel) = array_values($im);
220             $imArray[] = array(
221                 'value' => $id,
222                 'rel'   => $rel
223             );
224         }
225
226         return $imArray;
227     }
228
229     function saveIms($user) {
230         $ims = $this->findIms();
231         $this->removeAll($user, 'im');
232         $i = 0;
233         foreach($ims as $im) {
234             if (!empty($im['value'])) {
235                 ++$i;
236                 $this->saveField(
237                     $user,
238                     'im',
239                     $im['value'],
240                     $im['rel'],
241                     $i
242                 );
243             }
244         }
245     }
246
247     function findWebsites() {
248
249         //  Form vals look like this:
250
251         $sites = $this->sliceParams('website', 2);
252         $wsArray = array();
253
254         foreach ($sites as $site) {
255             list($id, $rel) = array_values($site);
256             $wsArray[] = array(
257                 'value' => $id,
258                 'rel'   => $rel
259             );
260         }
261
262         return $wsArray;
263     }
264
265     function saveWebsites($user) {
266         $sites = $this->findWebsites();
267         $this->removeAll($user, 'website');
268         $i = 0;
269         foreach($sites as $site) {
270             if (!empty($site['value']) && !Validate::uri(
271                 $site['value'],
272                 array('allowed_schemes' => array('http', 'https')))
273             ) {
274                 // TRANS: Exception thrown when entering an invalid URL.
275                 // TRANS: %s is the invalid URL.
276                 throw new Exception(sprintf(_m('Invalid URL: %s.'), $site['value']));
277             }
278
279             if (!empty($site['value'])) {
280                 ++$i;
281                 $this->saveField(
282                     $user,
283                     'website',
284                     $site['value'],
285                     $site['rel'],
286                     $i
287                 );
288             }
289         }
290     }
291
292     function findExperiences() {
293
294         // Form vals look like this:
295         // 'extprofile-experience-0'         => 'Bozotronix',
296         // 'extprofile-experience-0-current' => 'true'
297         // 'extprofile-experience-0-start'   => '1/5/10',
298         // 'extprofile-experience-0-end'     => '2/3/11',
299
300         $experiences = $this->sliceParams('experience', 4);
301         $expArray = array();
302
303         foreach ($experiences as $exp) {
304             if (sizeof($experiences) == 4) {
305                 list($company, $current, $end, $start) = array_values($exp);
306             } else {
307                 $end = null;
308                 list($company, $current, $start) = array_values($exp);
309             }
310             if (!empty($company)) {
311                 $expArray[] = array(
312                     'company' => $company,
313                     'start'   => $this->parseDate('Start', $start, true),
314                     'end'     => ($current == 'false') ? $this->parseDate('End', $end, true) : null,
315                     'current' => ($current == 'false') ? false : true
316                 );
317             }
318         }
319
320         return $expArray;
321     }
322
323     function saveExperiences($user) {
324         common_debug('save experiences');
325         $experiences = $this->findExperiences();
326
327         $this->removeAll($user, 'company');
328         $this->removeAll($user, 'start');
329         $this->removeAll($user, 'end'); // also stores 'current'
330
331         $i = 0;
332         foreach($experiences as $experience) {
333             if (!empty($experience['company'])) {
334                 ++$i;
335                 $this->saveField(
336                     $user,
337                     'company',
338                     $experience['company'],
339                     null,
340                     $i
341                 );
342
343                 $this->saveField(
344                     $user,
345                     'start',
346                     null,
347                     null,
348                     $i,
349                     $experience['start']
350                 );
351
352                 // Save "current" employer indicator in rel
353                 if ($experience['current']) {
354                     $this->saveField(
355                         $user,
356                         'end',
357                         null,
358                         'current', // rel
359                         $i
360                     );
361                 } else {
362                     $this->saveField(
363                         $user,
364                         'end',
365                         null,
366                         null,
367                         $i,
368                         $experience['end']
369                     );
370                 }
371
372             }
373         }
374     }
375
376     function findEducations() {
377
378         // Form vals look like this:
379         // 'extprofile-education-0-school' => 'Pigdog',
380         // 'extprofile-education-0-degree' => 'BA',
381         // 'extprofile-education-0-description' => 'Blar',
382         // 'extprofile-education-0-start' => '05/22/99',
383         // 'extprofile-education-0-end' => '05/22/05',
384
385         $edus = $this->sliceParams('education', 5);
386         $eduArray = array();
387
388         foreach ($edus as $edu) {
389             list($school, $degree, $description, $end, $start) = array_values($edu);
390             if (!empty($school)) {
391                 $eduArray[] = array(
392                     'school'      => $school,
393                     'degree'      => $degree,
394                     'description' => $description,
395                     'start'       => $this->parseDate('Start', $start, true),
396                     'end'         => $this->parseDate('End', $end, true)
397                 );
398             }
399         }
400
401         return $eduArray;
402     }
403
404
405     function saveEducations($user) {
406          common_debug('save education');
407          $edus = $this->findEducations();
408          common_debug(var_export($edus, true));
409
410          $this->removeAll($user, 'school');
411          $this->removeAll($user, 'degree');
412          $this->removeAll($user, 'degree_descr');
413          $this->removeAll($user, 'school_start');
414          $this->removeAll($user, 'school_end');
415
416          $i = 0;
417          foreach($edus as $edu) {
418              if (!empty($edu['school'])) {
419                  ++$i;
420                  $this->saveField(
421                      $user,
422                      'school',
423                      $edu['school'],
424                      null,
425                      $i
426                  );
427                  $this->saveField(
428                      $user,
429                      'degree',
430                      $edu['degree'],
431                      null,
432                      $i
433                  );
434                  $this->saveField(
435                      $user,
436                      'degree_descr',
437                      $edu['description'],
438                      null,
439                      $i
440                  );
441                  $this->saveField(
442                      $user,
443                      'school_start',
444                      null,
445                      null,
446                      $i,
447                      $edu['start']
448                  );
449
450                  $this->saveField(
451                      $user,
452                      'school_end',
453                      null,
454                      null,
455                      $i,
456                      $edu['end']
457                  );
458             }
459          }
460      }
461
462     function arraySplit($array, $pieces)
463     {
464         if ($pieces < 2) {
465             return array($array);
466         }
467
468         $newCount = ceil(count($array) / $pieces);
469         $a = array_slice($array, 0, $newCount);
470         $b = $this->arraySplit(array_slice($array, $newCount), $pieces - 1);
471
472         return array_merge(array($a), $b);
473     }
474
475     function findMultiParams($type) {
476         $formVals = array();
477         $target   = $type;
478         foreach ($_POST as $key => $val) {
479             if (strrpos('extprofile-' . $key, $target) !== false) {
480                 $formVals[$key] = $val;
481             }
482         }
483         return $formVals;
484     }
485
486     function sliceParams($key, $size) {
487         $slice = array();
488         $params = $this->findMultiParams($key);
489         ksort($params);
490         $slice = $this->arraySplit($params, sizeof($params) / $size);
491         return $slice;
492     }
493
494     /**
495      * Save an extended profile field as a Profile_detail
496      *
497      * @param User   $user    the current user
498      * @param string $name    field name
499      * @param string $value   field value
500      * @param string $rel     field rel (type)
501      * @param int    $index   index (fields can have multiple values)
502      * @param date   $date    related date
503      */
504     function saveField($user, $name, $value, $rel = null, $index = null, $date = null)
505     {
506         $profile = $user->getProfile();
507         $detail  = new Profile_detail();
508
509         $detail->profile_id  = $profile->id;
510         $detail->field_name  = $name;
511         $detail->value_index = $index;
512
513         $result = $detail->find(true);
514
515         if (empty($result)) {
516             $detial->value_index = $index;
517             $detail->rel         = $rel;
518             $detail->field_value = $value;
519             $detail->date        = $date;
520             $detail->created     = common_sql_now();
521             $result = $detail->insert();
522             if (empty($result)) {
523                 common_log_db_error($detail, 'INSERT', __FILE__);
524                 // TRANS: Server error displayed when a field could not be saved in the database.
525                 $this->serverError(_m('Could not save profile details.'));
526             }
527         } else {
528             $orig = clone($detail);
529
530             $detail->field_value = $value;
531             $detail->rel         = $rel;
532             $detail->date        = $date;
533
534             $result = $detail->update($orig);
535             if (empty($result)) {
536                 common_log_db_error($detail, 'UPDATE', __FILE__);
537                 // TRANS: Server error displayed when a field could not be saved in the database.
538                 $this->serverError(_m('Could not save profile details.'));
539             }
540         }
541
542         $detail->free();
543     }
544
545     function removeAll($user, $name)
546     {
547         $profile = $user->getProfile();
548         $detail  = new Profile_detail();
549         $detail->profile_id  = $profile->id;
550         $detail->field_name  = $name;
551         $detail->delete();
552         $detail->free();
553     }
554
555     /**
556      * Save fields that should be stored in the main profile object
557      *
558      * XXX: There's a lot of dupe code here from ProfileSettingsAction.
559      *      Do not want.
560      *
561      * @param User $user the current user
562      */
563     function saveStandardProfileDetails($user)
564     {
565         $fullname  = $this->trimmed('extprofile-fullname');
566         $location  = $this->trimmed('extprofile-location');
567         $tagstring = $this->trimmed('extprofile-tags');
568         $bio       = $this->trimmed('extprofile-bio');
569
570         if ($tagstring) {
571             $tags = array_map(
572                 'common_canonical_tag',
573                 preg_split('/[\s,]+/', $tagstring)
574             );
575         } else {
576             $tags = array();
577         }
578
579         foreach ($tags as $tag) {
580             if (!common_valid_profile_tag($tag)) {
581                 // TRANS: Validation error in form for profile settings.
582                 // TRANS: %s is an invalid tag.
583                 throw new Exception(sprintf(_m('Invalid tag: "%s".'), $tag));
584             }
585         }
586
587         $profile = $user->getProfile();
588
589         $oldTags = $user->getSelfTags();
590         $newTags = array_diff($tags, $oldTags);
591
592         if ($fullname    != $profile->fullname
593             || $location != $profile->location
594             || !empty($newTags)
595             || $bio      != $profile->bio) {
596
597             $orig = clone($profile);
598
599             $profile->nickname = $user->nickname;
600             $profile->fullname = $fullname;
601             $profile->bio      = $bio;
602             $profile->location = $location;
603
604             $loc = Location::fromName($location);
605
606             if (empty($loc)) {
607                 $profile->lat         = null;
608                 $profile->lon         = null;
609                 $profile->location_id = null;
610                 $profile->location_ns = null;
611             } else {
612                 $profile->lat         = $loc->lat;
613                 $profile->lon         = $loc->lon;
614                 $profile->location_id = $loc->location_id;
615                 $profile->location_ns = $loc->location_ns;
616             }
617
618             $profile->profileurl = common_profile_url($user->nickname);
619
620             $result = $profile->update($orig);
621
622             if ($result === false) {
623                 common_log_db_error($profile, 'UPDATE', __FILE__);
624                 // TRANS: Server error thrown when user profile settings could not be saved.
625                 $this->serverError(_m('Could not save profile.'));
626                 return;
627             }
628
629             // Set the user tags
630             $result = $user->setSelfTags($tags);
631
632             if (!$result) {
633                 // TRANS: Server error thrown when user profile settings tags could not be saved.
634                 $this->serverError(_m('Could not save tags.'));
635                 return;
636             }
637
638             Event::handle('EndProfileSaveForm', array($this));
639             common_broadcast_profile($profile);
640         }
641     }
642
643 }