3 * StatusNet - the distributed open-source microblogging tool
4 * Copyright (C) 2011, StatusNet, Inc.
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.
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.
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/>.
20 if (!defined('GNUSOCIAL')) { exit(1); }
22 class ProfileDetailSettingsAction extends ProfileSettingsAction
26 // TRANS: Title for extended profile settings.
27 return _m('Extended profile settings');
30 function showStylesheets() {
31 parent::showStylesheets();
32 $this->cssLink('plugins/ExtendedProfile/css/profiledetail.css');
36 function showScripts() {
37 parent::showScripts();
38 $this->script('plugins/ExtendedProfile/js/profiledetail.js');
42 protected function doPost()
44 if ($this->arg('save')) {
45 return $this->saveDetails();
48 // TRANS: Message given submitting a form with an unknown action.
49 throw new ClientException(_m('Unexpected form submission.'));
52 function showContent()
54 $widget = new ExtendedProfileWidget(
57 ExtendedProfileWidget::EDITABLE
62 function saveDetails()
64 common_debug(var_export($_POST, true));
66 $this->saveStandardProfileDetails();
68 $simpleFieldNames = array('title', 'spouse', 'kids', 'manager');
69 $dateFieldNames = array('birthday');
71 foreach ($simpleFieldNames as $name) {
72 $value = $this->trimmed('extprofile-' . $name);
74 $this->saveField($name, $value);
78 foreach ($dateFieldNames as $name) {
79 $value = $this->trimmed('extprofile-' . $name);
80 $dateVal = $this->parseDate($name, $value);
90 $this->savePhoneNumbers();
92 $this->saveWebsites();
93 $this->saveExperiences();
94 $this->saveEducations();
96 // TRANS: Success message after saving extended profile details.
97 return _m('Details saved.');
101 function parseDate($fieldname, $datestr, $required = false)
103 if (empty($datestr)) {
106 // TRANS: Exception thrown when no date was entered in a required date field.
107 // TRANS: %s is the field name.
108 _m('You must supply a date for "%s".'),
111 throw new Exception($msg);
114 $ts = strtotime($datestr);
118 // TRANS: Exception thrown on incorrect data input.
119 // TRANS: %1$s is a field name, %2$s is the incorrect input.
120 _m('Invalid date entered for "%1$s": %2$s.'),
126 return common_sql_date($ts);
131 function savePhoneNumbers() {
132 $phones = $this->findPhoneNumbers();
133 $this->removeAll('phone');
135 foreach($phones as $phone) {
136 if (!empty($phone['value'])) {
148 function findPhoneNumbers() {
150 // Form vals look like this:
151 // 'extprofile-phone-1' => '11332',
152 // 'extprofile-phone-1-rel' => 'mobile',
154 $phones = $this->sliceParams('phone', 2);
155 $phoneArray = array();
157 foreach ($phones as $phone) {
158 list($number, $rel) = array_values($phone);
159 $phoneArray[] = array(
170 // Form vals look like this:
171 // 'extprofile-im-0' => 'jed',
172 // 'extprofile-im-0-rel' => 'yahoo',
174 $ims = $this->sliceParams('im', 2);
177 foreach ($ims as $im) {
178 list($id, $rel) = array_values($im);
189 $ims = $this->findIms();
190 $this->removeAll('im');
192 foreach($ims as $im) {
193 if (!empty($im['value'])) {
205 function findWebsites() {
207 // Form vals look like this:
209 $sites = $this->sliceParams('website', 2);
212 foreach ($sites as $site) {
213 list($id, $rel) = array_values($site);
223 function saveWebsites() {
224 $sites = $this->findWebsites();
225 $this->removeAll('website');
227 foreach($sites as $site) {
228 if (!empty($site['value']) && !common_valid_http_url($site['value'])) {
229 // TRANS: Exception thrown when entering an invalid URL.
230 // TRANS: %s is the invalid URL.
231 throw new Exception(sprintf(_m('Invalid URL: %s.'), $site['value']));
234 if (!empty($site['value'])) {
246 function findExperiences() {
248 // Form vals look like this:
249 // 'extprofile-experience-0' => 'Bozotronix',
250 // 'extprofile-experience-0-current' => 'true'
251 // 'extprofile-experience-0-start' => '1/5/10',
252 // 'extprofile-experience-0-end' => '2/3/11',
254 $experiences = $this->sliceParams('experience', 4);
257 foreach ($experiences as $exp) {
258 if (sizeof($experiences) == 4) {
259 list($company, $current, $end, $start) = array_values($exp);
262 list($company, $current, $start) = array_values($exp);
264 if (!empty($company)) {
266 'company' => $company,
267 'start' => $this->parseDate('Start', $start, true),
268 'end' => ($current == 'false') ? $this->parseDate('End', $end, true) : null,
269 'current' => ($current == 'false') ? false : true
277 function saveExperiences() {
278 common_debug('save experiences');
279 $experiences = $this->findExperiences();
281 $this->removeAll('company');
282 $this->removeAll('start');
283 $this->removeAll('end'); // also stores 'current'
286 foreach($experiences as $experience) {
287 if (!empty($experience['company'])) {
291 $experience['company'],
304 // Save "current" employer indicator in rel
305 if ($experience['current']) {
326 function findEducations() {
328 // Form vals look like this:
329 // 'extprofile-education-0-school' => 'Pigdog',
330 // 'extprofile-education-0-degree' => 'BA',
331 // 'extprofile-education-0-description' => 'Blar',
332 // 'extprofile-education-0-start' => '05/22/99',
333 // 'extprofile-education-0-end' => '05/22/05',
335 $edus = $this->sliceParams('education', 5);
338 foreach ($edus as $edu) {
339 list($school, $degree, $description, $end, $start) = array_values($edu);
340 if (!empty($school)) {
344 'description' => $description,
345 'start' => $this->parseDate('Start', $start, true),
346 'end' => $this->parseDate('End', $end, true)
355 function saveEducations() {
356 common_debug('save education');
357 $edus = $this->findEducations();
358 common_debug(var_export($edus, true));
360 $this->removeAll('school');
361 $this->removeAll('degree');
362 $this->removeAll('degree_descr');
363 $this->removeAll('school_start');
364 $this->removeAll('school_end');
367 foreach($edus as $edu) {
368 if (!empty($edu['school'])) {
407 function arraySplit($array, $pieces)
410 return array($array);
413 $newCount = ceil(count($array) / $pieces);
414 $a = array_slice($array, 0, $newCount);
415 $b = $this->arraySplit(array_slice($array, $newCount), $pieces - 1);
417 return array_merge(array($a), $b);
420 function findMultiParams($type) {
423 foreach ($_POST as $key => $val) {
424 if (strrpos('extprofile-' . $key, $target) !== false) {
425 $formVals[$key] = $val;
431 function sliceParams($key, $size) {
433 $params = $this->findMultiParams($key);
435 $slice = $this->arraySplit($params, sizeof($params) / $size);
440 * Save an extended profile field as a Profile_detail
442 * @param string $name field name
443 * @param string $value field value
444 * @param string $rel field rel (type)
445 * @param int $index index (fields can have multiple values)
446 * @param date $date related date
448 function saveField($name, $value, $rel = null, $index = null, $date = null)
450 $detail = new Profile_detail();
452 $detail->profile_id = $this->scoped->getID();
453 $detail->field_name = $name;
454 $detail->value_index = $index;
456 $result = $detail->find(true);
458 if (!$result instanceof Profile_detail) {
459 $detail->value_index = $index;
461 $detail->field_value = $value;
462 $detail->date = $date;
463 $detail->created = common_sql_now();
464 $result = $detail->insert();
465 if ($result === false) {
466 common_log_db_error($detail, 'INSERT', __FILE__);
467 // TRANS: Server error displayed when a field could not be saved in the database.
468 throw new ServerException(_m('Could not save profile details.'));
471 $orig = clone($detail);
473 $detail->field_value = $value;
475 $detail->date = $date;
477 $result = $detail->update($orig);
478 if ($result === false) {
479 common_log_db_error($detail, 'UPDATE', __FILE__);
480 // TRANS: Server error displayed when a field could not be saved in the database.
481 throw new ServerException(_m('Could not save profile details.'));
488 function removeAll($name)
490 $detail = new Profile_detail();
491 $detail->profile_id = $this->scoped->getID();
492 $detail->field_name = $name;
498 * Save fields that should be stored in the main profile object
500 * XXX: There's a lot of dupe code here from ProfileSettingsAction.
503 function saveStandardProfileDetails()
505 $fullname = $this->trimmed('extprofile-fullname');
506 $location = $this->trimmed('extprofile-location');
507 $tagstring = $this->trimmed('extprofile-tags');
508 $bio = $this->trimmed('extprofile-bio');
512 'common_canonical_tag',
513 preg_split('/[\s,]+/', $tagstring)
519 foreach ($tags as $tag) {
520 if (!common_valid_profile_tag($tag)) {
521 // TRANS: Validation error in form for profile settings.
522 // TRANS: %s is an invalid tag.
523 throw new Exception(sprintf(_m('Invalid tag: "%s".'), $tag));
527 $oldTags = Profile_tag::getSelfTagsArray($this->scoped);
528 $newTags = array_diff($tags, $oldTags);
530 if ($fullname != $this->scoped->getFullname()
531 || $location != $this->scoped->location
533 || $bio != $this->scoped->getDescription()) {
535 $orig = clone($this->scoped);
537 // Skipping nickname change here until we add logic for when the site allows it or not
538 // old Profilesettings will still let us do that.
540 $this->scoped->fullname = $fullname;
541 $this->scoped->bio = $bio;
542 $this->scoped->location = $location;
544 $loc = Location::fromName($location);
547 $this->scoped->lat = null;
548 $this->scoped->lon = null;
549 $this->scoped->location_id = null;
550 $this->scoped->location_ns = null;
552 $this->scoped->lat = $loc->lat;
553 $this->scoped->lon = $loc->lon;
554 $this->scoped->location_id = $loc->location_id;
555 $this->scoped->location_ns = $loc->location_ns;
558 $result = $this->scoped->update($orig);
560 if ($result === false) {
561 common_log_db_error($this->scoped, 'UPDATE', __FILE__);
562 // TRANS: Server error thrown when user profile settings could not be saved.
563 throw new ServerException(_m('Could not save profile.'));
567 $result = Profile_tag::setSelfTags($this->scoped, $tags);
569 Event::handle('EndProfileSaveForm', array($this));