]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - plugins/ExtendedProfile/profiledetailsettingsaction.php
Extended profile - make experience save and display
[quix0rs-gnu-social.git] / plugins / ExtendedProfile / profiledetailsettingsaction.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->show_form(
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');
103
104             foreach ($simpleFieldNames as $name) {
105                 $value = $this->trimmed('extprofile-' . $name);
106                 if (!empty($value)) {
107                     $this->saveField($user, $name, $value);
108                 }
109             }
110
111             $this->savePhoneNumbers($user);
112             $this->saveExperiences($user);
113
114         } catch (Exception $e) {
115             $this->showForm($e->getMessage(), false);
116             return;
117         }
118
119         $this->showForm(_('Details saved.'), true);
120
121     }
122
123     function savePhoneNumbers($user) {
124         $phones = $this->findPhoneNumbers();
125         $this->removeAll($user, 'phone');
126         $i = 0;
127         foreach($phones as $phone) {
128             if (!empty($phone['value'])) {
129                 ++$i;
130                 $this->saveField(
131                     $user,
132                     'phone',
133                     $phone['value'],
134                     $phone['rel'],
135                     $i
136                 );
137             }
138         }
139     }
140
141     function findPhoneNumbers() {
142         $phones      = array();
143         $phoneParams = $this->findMultiParams('phone');
144         ksort($phoneParams); // this sorts them into pairs
145         $phones = $this->arraySplit($phoneParams, sizeof($phoneParams) / 2);
146         $phoneTuples = array();
147
148         foreach ($phones as $phone) {
149             list($number, $rel) = array_values($phone);
150             $phoneTuples[] = array(
151                 'value' => $number,
152                 'rel'   => $rel
153             );
154         }
155
156         return $phoneTuples;
157     }
158
159     function findExperiences() {
160
161         // Form vals look like this:
162         // 'extprofile-experience-0'         => 'Bozotronix',
163         // 'extprofile-experience-0-current' => 'true'
164         // 'extprofile-experience-0-start'   => '1/5/10',
165         // 'extprofile-experience-0-end'     => '2/3/11',
166
167         $experiences = array();
168         $expParams = $this->findMultiParams('experience');
169         ksort($expParams);
170         $experiences = $this->arraySplit($expParams, sizeof($expParams) / 4);
171         $expArray = array();
172
173         foreach ($experiences as $exp) {
174
175             common_debug('Experience: ' . var_export($exp, true));
176
177             list($company, $current, $end, $start) = array_values($exp);
178
179             $startTs = strtotime($start);
180
181             if ($startTs === false) {
182                 throw new Exception(
183                     sprintf(_m("Invalid start date: %s"), $start)
184                 );
185             }
186
187             $endTs = strtotime($end);
188
189             if ($current === 'false' && $endTs === false) {
190                 throw new Exception(
191                     sprintf(_m("Invalid end date: %s"), $start)
192                 );
193             }
194
195             $expArray[] = array(
196                 'company' => $company,
197                 'start'   => common_sql_date($startTs),
198                 'end'     => common_sql_date($endTs),
199                 'current' => $current,
200             );
201         }
202
203         return $expArray;
204     }
205
206     function saveExperiences($user) {
207         common_debug('save experiences');
208         $experiences = $this->findExperiences();
209
210         $this->removeAll($user, 'company');
211         $this->removeAll($user, 'start');
212         $this->removeAll($user, 'end'); // also stores 'current'
213
214         $i = 0;
215         foreach($experiences as $experience) {
216             if (!empty($experience['company'])) {
217                 ++$i;
218                 $this->saveField(
219                     $user,
220                     'company',
221                     $experience['company'],
222                     null,
223                     $i
224                 );
225
226                 $this->saveField(
227                     $user,
228                     'start',
229                     null,
230                     null,
231                     $i,
232                     $experience['start']
233                 );
234
235                 // Save "current" employer indicator in rel
236                 if ($experience['current']) {
237                     $this->saveField(
238                         $user,
239                         'end',
240                         null,
241                         'current', // rel
242                         $i
243                     );
244                 } else {
245                     $this->saveField(
246                         $user,
247                         'end',
248                         null,
249                         null,
250                         $i,
251                         $experience['end']
252                     );
253                 }
254
255             }
256         }
257     }
258
259     function arraySplit($array, $pieces)
260     {
261         if ($pieces < 2) {
262             return array($array);
263         }
264
265         $newCount = ceil(count($array) / $pieces);
266         $a = array_slice($array, 0, $newCount);
267         $b = $this->arraySplit(array_slice($array, $newCount), $pieces - 1);
268
269         return array_merge(array($a), $b);
270     }
271
272     function findMultiParams($type) {
273         $formVals = array();
274         $target   = $type;
275         foreach ($_POST as $key => $val) {
276             if (strrpos('extprofile-' . $key, $target) !== false) {
277                 $formVals[$key] = $val;
278             }
279         }
280         return $formVals;
281     }
282
283     /**
284      * Save an extended profile field as a Profile_detail
285      *
286      * @param User   $user    the current user
287      * @param string $name    field name
288      * @param string $value   field value
289      * @param string $rel     field rel (type)
290      * @param int    $index   index (fields can have multiple values)
291      * @param date   $date    related date
292      */
293     function saveField($user, $name, $value, $rel = null, $index = null, $date = null)
294     {
295         $profile = $user->getProfile();
296         $detail  = new Profile_detail();
297
298         $detail->profile_id  = $profile->id;
299         $detail->field_name  = $name;
300         $detail->value_index = $index;
301
302         $result = $detail->find(true);
303
304         if (empty($result)) {
305             $detial->value_index = $index;
306             $detail->rel         = $rel;
307             $detail->field_value = $value;
308             $detail->date        = $date;
309             $detail->created     = common_sql_now();
310             $result = $detail->insert();
311             if (empty($result)) {
312                 common_log_db_error($detail, 'INSERT', __FILE__);
313                 $this->serverError(_m('Could not save profile details.'));
314             }
315         } else {
316             $orig = clone($detail);
317
318             $detail->field_value = $value;
319             $detail->rel         = $rel;
320             $detail->date        = $date;
321
322             $result = $detail->update($orig);
323             if (empty($result)) {
324                 common_log_db_error($detail, 'UPDATE', __FILE__);
325                 $this->serverError(_m('Could not save profile details.'));
326             }
327         }
328
329         $detail->free();
330     }
331
332     function removeAll($user, $name)
333     {
334         $profile = $user->getProfile();
335         $detail  = new Profile_detail();
336         $detail->profile_id  = $profile->id;
337         $detail->field_name  = $name;
338         $detail->delete();
339         $detail->free();
340     }
341
342     /**
343      * Save fields that should be stored in the main profile object
344      *
345      * XXX: There's a lot of dupe code here from ProfileSettingsAction.
346      *      Do not want.
347      *
348      * @param User $user the current user
349      */
350     function saveStandardProfileDetails($user)
351     {
352         $fullname  = $this->trimmed('extprofile-fullname');
353         $location  = $this->trimmed('extprofile-location');
354         $tagstring = $this->trimmed('extprofile-tags');
355         $bio       = $this->trimmed('extprofile-bio');
356
357         if ($tagstring) {
358             $tags = array_map(
359                 'common_canonical_tag',
360                 preg_split('/[\s,]+/', $tagstring)
361             );
362         } else {
363             $tags = array();
364         }
365
366         foreach ($tags as $tag) {
367             if (!common_valid_profile_tag($tag)) {
368                 // TRANS: Validation error in form for profile settings.
369                 // TRANS: %s is an invalid tag.
370                 throw new Exception(sprintf(_m('Invalid tag: "%s".'), $tag));
371             }
372         }
373
374         $profile = $user->getProfile();
375
376         $oldTags = $user->getSelfTags();
377         $newTags = array_diff($tags, $oldTags);
378
379         if ($fullname    != $profile->fullname
380             || $location != $profile->location
381             || !empty($newTags)
382             || $bio      != $profile->bio) {
383
384             $orig = clone($profile);
385
386             $profile->nickname = $user->nickname;
387             $profile->fullname = $fullname;
388             $profile->bio      = $bio;
389             $profile->location = $location;
390
391             $loc = Location::fromName($location);
392
393             if (empty($loc)) {
394                 $profile->lat         = null;
395                 $profile->lon         = null;
396                 $profile->location_id = null;
397                 $profile->location_ns = null;
398             } else {
399                 $profile->lat         = $loc->lat;
400                 $profile->lon         = $loc->lon;
401                 $profile->location_id = $loc->location_id;
402                 $profile->location_ns = $loc->location_ns;
403             }
404
405             $profile->profileurl = common_profile_url($user->nickname);
406
407             $result = $profile->update($orig);
408
409             if ($result === false) {
410                 common_log_db_error($profile, 'UPDATE', __FILE__);
411                 // TRANS: Server error thrown when user profile settings could not be saved.
412                 $this->serverError(_('Could not save profile.'));
413                 return;
414             }
415
416             // Set the user tags
417             $result = $user->setSelfTags($tags);
418
419             if (!$result) {
420                 // TRANS: Server error thrown when user profile settings tags could not be saved.
421                 $this->serverError(_('Could not save tags.'));
422                 return;
423             }
424
425             Event::handle('EndProfileSaveForm', array($this));
426             common_broadcast_profile($profile);
427         }
428     }
429
430 }