forked from GNUsocial/gnu-social
644 lines
19 KiB
PHP
644 lines
19 KiB
PHP
<?php
|
|
/*
|
|
* StatusNet - the distributed open-source microblogging tool
|
|
* Copyright (C) 2011, StatusNet, Inc.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
if (!defined('STATUSNET')) {
|
|
exit(1);
|
|
}
|
|
|
|
class ProfileDetailSettingsAction extends ProfileSettingsAction
|
|
{
|
|
function title()
|
|
{
|
|
// TRANS: Title for extended profile settings.
|
|
return _m('Extended profile settings');
|
|
}
|
|
|
|
/**
|
|
* Instructions for use
|
|
*
|
|
* @return instructions for use
|
|
*/
|
|
function getInstructions()
|
|
{
|
|
// TRANS: Usage instructions for profile settings.
|
|
return _m('You can update your personal profile info here '.
|
|
'so people know more about you.');
|
|
}
|
|
|
|
function showStylesheets() {
|
|
parent::showStylesheets();
|
|
$this->cssLink('plugins/ExtendedProfile/css/profiledetail.css');
|
|
return true;
|
|
}
|
|
|
|
function showScripts() {
|
|
parent::showScripts();
|
|
$this->script('plugins/ExtendedProfile/js/profiledetail.js');
|
|
return true;
|
|
}
|
|
|
|
function handlePost()
|
|
{
|
|
// CSRF protection
|
|
$token = $this->trimmed('token');
|
|
if (!$token || $token != common_session_token()) {
|
|
$this->showForm(
|
|
// TRANS: Client error displayed when the session token does not match or is not given.
|
|
_m('There was a problem with your session token. '
|
|
. 'Try again, please.'
|
|
)
|
|
);
|
|
return;
|
|
}
|
|
|
|
if ($this->arg('save')) {
|
|
$this->saveDetails();
|
|
} else {
|
|
// TRANS: Message given submitting a form with an unknown action.
|
|
$this->showForm(_m('Unexpected form submission.'));
|
|
}
|
|
}
|
|
|
|
function showContent()
|
|
{
|
|
$cur = common_current_user();
|
|
$profile = $cur->getProfile();
|
|
|
|
$widget = new ExtendedProfileWidget(
|
|
$this,
|
|
$profile,
|
|
ExtendedProfileWidget::EDITABLE
|
|
);
|
|
$widget->show();
|
|
}
|
|
|
|
function saveDetails()
|
|
{
|
|
common_debug(var_export($_POST, true));
|
|
|
|
$user = common_current_user();
|
|
|
|
try {
|
|
$this->saveStandardProfileDetails($user);
|
|
|
|
$profile = $user->getProfile();
|
|
|
|
$simpleFieldNames = array('title', 'spouse', 'kids', 'manager');
|
|
$dateFieldNames = array('birthday');
|
|
|
|
foreach ($simpleFieldNames as $name) {
|
|
$value = $this->trimmed('extprofile-' . $name);
|
|
if (!empty($value)) {
|
|
$this->saveField($user, $name, $value);
|
|
}
|
|
}
|
|
|
|
foreach ($dateFieldNames as $name) {
|
|
$value = $this->trimmed('extprofile-' . $name);
|
|
$dateVal = $this->parseDate($name, $value);
|
|
$this->saveField(
|
|
$user,
|
|
$name,
|
|
null,
|
|
null,
|
|
null,
|
|
$dateVal
|
|
);
|
|
}
|
|
|
|
$this->savePhoneNumbers($user);
|
|
$this->saveIms($user);
|
|
$this->saveWebsites($user);
|
|
$this->saveExperiences($user);
|
|
$this->saveEducations($user);
|
|
|
|
} catch (Exception $e) {
|
|
$this->showForm($e->getMessage(), false);
|
|
return;
|
|
}
|
|
|
|
// TRANS: Success message after saving extended profile details.
|
|
$this->showForm(_m('Details saved.'), true);
|
|
|
|
}
|
|
|
|
function parseDate($fieldname, $datestr, $required = false)
|
|
{
|
|
if (empty($datestr)) {
|
|
if ($required) {
|
|
$msg = sprintf(
|
|
// TRANS: Exception thrown when no date was entered in a required date field.
|
|
// TRANS: %s is the field name.
|
|
_m('You must supply a date for "%s".'),
|
|
$fieldname
|
|
);
|
|
throw new Exception($msg);
|
|
}
|
|
} else {
|
|
$ts = strtotime($datestr);
|
|
if ($ts === false) {
|
|
throw new Exception(
|
|
sprintf(
|
|
// TRANS: Exception thrown on incorrect data input.
|
|
// TRANS: %1$s is a field name, %2$s is the incorrect input.
|
|
_m('Invalid date entered for "%1$s": %2$s.'),
|
|
$fieldname,
|
|
$ts
|
|
)
|
|
);
|
|
}
|
|
return common_sql_date($ts);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function savePhoneNumbers($user) {
|
|
$phones = $this->findPhoneNumbers();
|
|
$this->removeAll($user, 'phone');
|
|
$i = 0;
|
|
foreach($phones as $phone) {
|
|
if (!empty($phone['value'])) {
|
|
++$i;
|
|
$this->saveField(
|
|
$user,
|
|
'phone',
|
|
$phone['value'],
|
|
$phone['rel'],
|
|
$i
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
function findPhoneNumbers() {
|
|
|
|
// Form vals look like this:
|
|
// 'extprofile-phone-1' => '11332',
|
|
// 'extprofile-phone-1-rel' => 'mobile',
|
|
|
|
$phones = $this->sliceParams('phone', 2);
|
|
$phoneArray = array();
|
|
|
|
foreach ($phones as $phone) {
|
|
list($number, $rel) = array_values($phone);
|
|
$phoneArray[] = array(
|
|
'value' => $number,
|
|
'rel' => $rel
|
|
);
|
|
}
|
|
|
|
return $phoneArray;
|
|
}
|
|
|
|
function findIms() {
|
|
|
|
// Form vals look like this:
|
|
// 'extprofile-im-0' => 'jed',
|
|
// 'extprofile-im-0-rel' => 'yahoo',
|
|
|
|
$ims = $this->sliceParams('im', 2);
|
|
$imArray = array();
|
|
|
|
foreach ($ims as $im) {
|
|
list($id, $rel) = array_values($im);
|
|
$imArray[] = array(
|
|
'value' => $id,
|
|
'rel' => $rel
|
|
);
|
|
}
|
|
|
|
return $imArray;
|
|
}
|
|
|
|
function saveIms($user) {
|
|
$ims = $this->findIms();
|
|
$this->removeAll($user, 'im');
|
|
$i = 0;
|
|
foreach($ims as $im) {
|
|
if (!empty($im['value'])) {
|
|
++$i;
|
|
$this->saveField(
|
|
$user,
|
|
'im',
|
|
$im['value'],
|
|
$im['rel'],
|
|
$i
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
function findWebsites() {
|
|
|
|
// Form vals look like this:
|
|
|
|
$sites = $this->sliceParams('website', 2);
|
|
$wsArray = array();
|
|
|
|
foreach ($sites as $site) {
|
|
list($id, $rel) = array_values($site);
|
|
$wsArray[] = array(
|
|
'value' => $id,
|
|
'rel' => $rel
|
|
);
|
|
}
|
|
|
|
return $wsArray;
|
|
}
|
|
|
|
function saveWebsites($user) {
|
|
$sites = $this->findWebsites();
|
|
$this->removeAll($user, 'website');
|
|
$i = 0;
|
|
foreach($sites as $site) {
|
|
if (!empty($site['value']) && !Validate::uri(
|
|
$site['value'],
|
|
array('allowed_schemes' => array('http', 'https')))
|
|
) {
|
|
// TRANS: Exception thrown when entering an invalid URL.
|
|
// TRANS: %s is the invalid URL.
|
|
throw new Exception(sprintf(_m('Invalid URL: %s.'), $site['value']));
|
|
}
|
|
|
|
if (!empty($site['value'])) {
|
|
++$i;
|
|
$this->saveField(
|
|
$user,
|
|
'website',
|
|
$site['value'],
|
|
$site['rel'],
|
|
$i
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
function findExperiences() {
|
|
|
|
// Form vals look like this:
|
|
// 'extprofile-experience-0' => 'Bozotronix',
|
|
// 'extprofile-experience-0-current' => 'true'
|
|
// 'extprofile-experience-0-start' => '1/5/10',
|
|
// 'extprofile-experience-0-end' => '2/3/11',
|
|
|
|
$experiences = $this->sliceParams('experience', 4);
|
|
$expArray = array();
|
|
|
|
foreach ($experiences as $exp) {
|
|
if (sizeof($experiences) == 4) {
|
|
list($company, $current, $end, $start) = array_values($exp);
|
|
} else {
|
|
$end = null;
|
|
list($company, $current, $start) = array_values($exp);
|
|
}
|
|
if (!empty($company)) {
|
|
$expArray[] = array(
|
|
'company' => $company,
|
|
'start' => $this->parseDate('Start', $start, true),
|
|
'end' => ($current == 'false') ? $this->parseDate('End', $end, true) : null,
|
|
'current' => ($current == 'false') ? false : true
|
|
);
|
|
}
|
|
}
|
|
|
|
return $expArray;
|
|
}
|
|
|
|
function saveExperiences($user) {
|
|
common_debug('save experiences');
|
|
$experiences = $this->findExperiences();
|
|
|
|
$this->removeAll($user, 'company');
|
|
$this->removeAll($user, 'start');
|
|
$this->removeAll($user, 'end'); // also stores 'current'
|
|
|
|
$i = 0;
|
|
foreach($experiences as $experience) {
|
|
if (!empty($experience['company'])) {
|
|
++$i;
|
|
$this->saveField(
|
|
$user,
|
|
'company',
|
|
$experience['company'],
|
|
null,
|
|
$i
|
|
);
|
|
|
|
$this->saveField(
|
|
$user,
|
|
'start',
|
|
null,
|
|
null,
|
|
$i,
|
|
$experience['start']
|
|
);
|
|
|
|
// Save "current" employer indicator in rel
|
|
if ($experience['current']) {
|
|
$this->saveField(
|
|
$user,
|
|
'end',
|
|
null,
|
|
'current', // rel
|
|
$i
|
|
);
|
|
} else {
|
|
$this->saveField(
|
|
$user,
|
|
'end',
|
|
null,
|
|
null,
|
|
$i,
|
|
$experience['end']
|
|
);
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
function findEducations() {
|
|
|
|
// Form vals look like this:
|
|
// 'extprofile-education-0-school' => 'Pigdog',
|
|
// 'extprofile-education-0-degree' => 'BA',
|
|
// 'extprofile-education-0-description' => 'Blar',
|
|
// 'extprofile-education-0-start' => '05/22/99',
|
|
// 'extprofile-education-0-end' => '05/22/05',
|
|
|
|
$edus = $this->sliceParams('education', 5);
|
|
$eduArray = array();
|
|
|
|
foreach ($edus as $edu) {
|
|
list($school, $degree, $description, $end, $start) = array_values($edu);
|
|
if (!empty($school)) {
|
|
$eduArray[] = array(
|
|
'school' => $school,
|
|
'degree' => $degree,
|
|
'description' => $description,
|
|
'start' => $this->parseDate('Start', $start, true),
|
|
'end' => $this->parseDate('End', $end, true)
|
|
);
|
|
}
|
|
}
|
|
|
|
return $eduArray;
|
|
}
|
|
|
|
|
|
function saveEducations($user) {
|
|
common_debug('save education');
|
|
$edus = $this->findEducations();
|
|
common_debug(var_export($edus, true));
|
|
|
|
$this->removeAll($user, 'school');
|
|
$this->removeAll($user, 'degree');
|
|
$this->removeAll($user, 'degree_descr');
|
|
$this->removeAll($user, 'school_start');
|
|
$this->removeAll($user, 'school_end');
|
|
|
|
$i = 0;
|
|
foreach($edus as $edu) {
|
|
if (!empty($edu['school'])) {
|
|
++$i;
|
|
$this->saveField(
|
|
$user,
|
|
'school',
|
|
$edu['school'],
|
|
null,
|
|
$i
|
|
);
|
|
$this->saveField(
|
|
$user,
|
|
'degree',
|
|
$edu['degree'],
|
|
null,
|
|
$i
|
|
);
|
|
$this->saveField(
|
|
$user,
|
|
'degree_descr',
|
|
$edu['description'],
|
|
null,
|
|
$i
|
|
);
|
|
$this->saveField(
|
|
$user,
|
|
'school_start',
|
|
null,
|
|
null,
|
|
$i,
|
|
$edu['start']
|
|
);
|
|
|
|
$this->saveField(
|
|
$user,
|
|
'school_end',
|
|
null,
|
|
null,
|
|
$i,
|
|
$edu['end']
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
function arraySplit($array, $pieces)
|
|
{
|
|
if ($pieces < 2) {
|
|
return array($array);
|
|
}
|
|
|
|
$newCount = ceil(count($array) / $pieces);
|
|
$a = array_slice($array, 0, $newCount);
|
|
$b = $this->arraySplit(array_slice($array, $newCount), $pieces - 1);
|
|
|
|
return array_merge(array($a), $b);
|
|
}
|
|
|
|
function findMultiParams($type) {
|
|
$formVals = array();
|
|
$target = $type;
|
|
foreach ($_POST as $key => $val) {
|
|
if (strrpos('extprofile-' . $key, $target) !== false) {
|
|
$formVals[$key] = $val;
|
|
}
|
|
}
|
|
return $formVals;
|
|
}
|
|
|
|
function sliceParams($key, $size) {
|
|
$slice = array();
|
|
$params = $this->findMultiParams($key);
|
|
ksort($params);
|
|
$slice = $this->arraySplit($params, sizeof($params) / $size);
|
|
return $slice;
|
|
}
|
|
|
|
/**
|
|
* Save an extended profile field as a Profile_detail
|
|
*
|
|
* @param User $user the current user
|
|
* @param string $name field name
|
|
* @param string $value field value
|
|
* @param string $rel field rel (type)
|
|
* @param int $index index (fields can have multiple values)
|
|
* @param date $date related date
|
|
*/
|
|
function saveField($user, $name, $value, $rel = null, $index = null, $date = null)
|
|
{
|
|
$profile = $user->getProfile();
|
|
$detail = new Profile_detail();
|
|
|
|
$detail->profile_id = $profile->id;
|
|
$detail->field_name = $name;
|
|
$detail->value_index = $index;
|
|
|
|
$result = $detail->find(true);
|
|
|
|
if (empty($result)) {
|
|
$detial->value_index = $index;
|
|
$detail->rel = $rel;
|
|
$detail->field_value = $value;
|
|
$detail->date = $date;
|
|
$detail->created = common_sql_now();
|
|
$result = $detail->insert();
|
|
if (empty($result)) {
|
|
common_log_db_error($detail, 'INSERT', __FILE__);
|
|
// TRANS: Server error displayed when a field could not be saved in the database.
|
|
$this->serverError(_m('Could not save profile details.'));
|
|
}
|
|
} else {
|
|
$orig = clone($detail);
|
|
|
|
$detail->field_value = $value;
|
|
$detail->rel = $rel;
|
|
$detail->date = $date;
|
|
|
|
$result = $detail->update($orig);
|
|
if (empty($result)) {
|
|
common_log_db_error($detail, 'UPDATE', __FILE__);
|
|
// TRANS: Server error displayed when a field could not be saved in the database.
|
|
$this->serverError(_m('Could not save profile details.'));
|
|
}
|
|
}
|
|
|
|
$detail->free();
|
|
}
|
|
|
|
function removeAll($user, $name)
|
|
{
|
|
$profile = $user->getProfile();
|
|
$detail = new Profile_detail();
|
|
$detail->profile_id = $profile->id;
|
|
$detail->field_name = $name;
|
|
$detail->delete();
|
|
$detail->free();
|
|
}
|
|
|
|
/**
|
|
* Save fields that should be stored in the main profile object
|
|
*
|
|
* XXX: There's a lot of dupe code here from ProfileSettingsAction.
|
|
* Do not want.
|
|
*
|
|
* @param User $user the current user
|
|
*/
|
|
function saveStandardProfileDetails($user)
|
|
{
|
|
$fullname = $this->trimmed('extprofile-fullname');
|
|
$location = $this->trimmed('extprofile-location');
|
|
$tagstring = $this->trimmed('extprofile-tags');
|
|
$bio = $this->trimmed('extprofile-bio');
|
|
|
|
if ($tagstring) {
|
|
$tags = array_map(
|
|
'common_canonical_tag',
|
|
preg_split('/[\s,]+/', $tagstring)
|
|
);
|
|
} else {
|
|
$tags = array();
|
|
}
|
|
|
|
foreach ($tags as $tag) {
|
|
if (!common_valid_profile_tag($tag)) {
|
|
// TRANS: Validation error in form for profile settings.
|
|
// TRANS: %s is an invalid tag.
|
|
throw new Exception(sprintf(_m('Invalid tag: "%s".'), $tag));
|
|
}
|
|
}
|
|
|
|
$profile = $user->getProfile();
|
|
|
|
$oldTags = $user->getSelfTags();
|
|
$newTags = array_diff($tags, $oldTags);
|
|
|
|
if ($fullname != $profile->fullname
|
|
|| $location != $profile->location
|
|
|| !empty($newTags)
|
|
|| $bio != $profile->bio) {
|
|
|
|
$orig = clone($profile);
|
|
|
|
$profile->nickname = $user->nickname;
|
|
$profile->fullname = $fullname;
|
|
$profile->bio = $bio;
|
|
$profile->location = $location;
|
|
|
|
$loc = Location::fromName($location);
|
|
|
|
if (empty($loc)) {
|
|
$profile->lat = null;
|
|
$profile->lon = null;
|
|
$profile->location_id = null;
|
|
$profile->location_ns = null;
|
|
} else {
|
|
$profile->lat = $loc->lat;
|
|
$profile->lon = $loc->lon;
|
|
$profile->location_id = $loc->location_id;
|
|
$profile->location_ns = $loc->location_ns;
|
|
}
|
|
|
|
$profile->profileurl = common_profile_url($user->nickname);
|
|
|
|
$result = $profile->update($orig);
|
|
|
|
if ($result === false) {
|
|
common_log_db_error($profile, 'UPDATE', __FILE__);
|
|
// TRANS: Server error thrown when user profile settings could not be saved.
|
|
$this->serverError(_m('Could not save profile.'));
|
|
return;
|
|
}
|
|
|
|
// Set the user tags
|
|
$result = $user->setSelfTags($tags);
|
|
|
|
if (!$result) {
|
|
// TRANS: Server error thrown when user profile settings tags could not be saved.
|
|
$this->serverError(_m('Could not save tags.'));
|
|
return;
|
|
}
|
|
|
|
Event::handle('EndProfileSaveForm', array($this));
|
|
common_broadcast_profile($profile);
|
|
}
|
|
}
|
|
|
|
}
|