Merge pull request #13339 from MrPetovan/task/13332-deprecate-profile-name

Deprecate profile.name in favor of user.username
This commit is contained in:
Michael Vogel 2023-08-20 20:18:47 +02:00 committed by GitHub
commit fe48fcf9de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 585 additions and 713 deletions

View File

@ -1,6 +1,6 @@
-- ------------------------------------------ -- ------------------------------------------
-- Friendica 2023.09-dev (Giant Rhubarb) -- Friendica 2023.09-dev (Giant Rhubarb)
-- DB_UPDATE_VERSION 1524 -- DB_UPDATE_VERSION 1525
-- ------------------------------------------ -- ------------------------------------------
@ -1586,7 +1586,7 @@ CREATE TABLE IF NOT EXISTS `profile` (
`profile-name` varchar(255) COMMENT 'Deprecated', `profile-name` varchar(255) COMMENT 'Deprecated',
`is-default` boolean COMMENT 'Deprecated', `is-default` boolean COMMENT 'Deprecated',
`hide-friends` boolean NOT NULL DEFAULT '0' COMMENT 'Hide friend list from viewers of this profile', `hide-friends` boolean NOT NULL DEFAULT '0' COMMENT 'Hide friend list from viewers of this profile',
`name` varchar(255) NOT NULL DEFAULT '' COMMENT '', `name` varchar(255) NOT NULL DEFAULT '' COMMENT 'Unused in favor of user.username',
`pdesc` varchar(255) COMMENT 'Deprecated', `pdesc` varchar(255) COMMENT 'Deprecated',
`dob` varchar(32) NOT NULL DEFAULT '0000-00-00' COMMENT 'Day of birth', `dob` varchar(32) NOT NULL DEFAULT '0000-00-00' COMMENT 'Day of birth',
`address` varchar(255) NOT NULL DEFAULT '' COMMENT '', `address` varchar(255) NOT NULL DEFAULT '' COMMENT '',

View File

@ -13,7 +13,7 @@ Fields
| profile-name | Deprecated | varchar(255) | YES | | NULL | | | profile-name | Deprecated | varchar(255) | YES | | NULL | |
| is-default | Deprecated | boolean | YES | | NULL | | | is-default | Deprecated | boolean | YES | | NULL | |
| hide-friends | Hide friend list from viewers of this profile | boolean | NO | | 0 | | | hide-friends | Hide friend list from viewers of this profile | boolean | NO | | 0 | |
| name | | varchar(255) | NO | | | | | name | Unused in favor of user.username | varchar(255) | NO | | | |
| pdesc | Deprecated | varchar(255) | YES | | NULL | | | pdesc | Deprecated | varchar(255) | YES | | NULL | |
| dob | Day of birth | varchar(32) | NO | | 0000-00-00 | | | dob | Day of birth | varchar(32) | NO | | 0000-00-00 | |
| address | | varchar(255) | NO | | | | | address | | varchar(255) | NO | | | |

View File

@ -788,10 +788,10 @@ class Contact
/** /**
* Updates the self-contact for the provided user id * Updates the self-contact for the provided user id
* *
* @param int $uid * @param int $uid
* @param bool $update_avatar Force the avatar update * @param bool $update_avatar Force the avatar update
* @return bool "true" if updated * @return bool "true" if updated
* @throws HTTPException\InternalServerErrorException * @throws \Exception
*/ */
public static function updateSelfFromUserID(int $uid, bool $update_avatar = false): bool public static function updateSelfFromUserID(int $uid, bool $update_avatar = false): bool
{ {

View File

@ -37,6 +37,7 @@ use Friendica\DI;
use Friendica\Network\HTTPClient\Client\HttpClientAccept; use Friendica\Network\HTTPClient\Client\HttpClientAccept;
use Friendica\Network\HTTPClient\Client\HttpClientOptions; use Friendica\Network\HTTPClient\Client\HttpClientOptions;
use Friendica\Network\HTTPException; use Friendica\Network\HTTPException;
use Friendica\Network\HTTPException\InternalServerErrorException;
use Friendica\Protocol\Activity; use Friendica\Protocol\Activity;
use Friendica\Protocol\Diaspora; use Friendica\Protocol\Diaspora;
use Friendica\Security\PermissionSet\Entity\PermissionSet; use Friendica\Security\PermissionSet\Entity\PermissionSet;
@ -93,10 +94,11 @@ class Profile
/** /**
* Update a profile entry and distribute the changes if needed * Update a profile entry and distribute the changes if needed
* *
* @param array $fields Profile fields to update * @param array $fields Profile fields to update
* @param integer $uid User id * @param integer $uid User id
* *
* @return boolean Whether update was successful * @return boolean Whether update was successful
* @throws \Exception
*/ */
public static function update(array $fields, int $uid): bool public static function update(array $fields, int $uid): bool
{ {
@ -116,10 +118,6 @@ class Profile
return false; return false;
} }
if ($old_owner['name'] != $owner['name']) {
User::update(['username' => $owner['name']], $uid);
}
$profile_fields = ['postal-code', 'dob', 'prv_keywords', 'homepage']; $profile_fields = ['postal-code', 'dob', 'prv_keywords', 'homepage'];
foreach ($profile_fields as $field) { foreach ($profile_fields as $field) {
if ($old_owner[$field] != $owner[$field]) { if ($old_owner[$field] != $owner[$field]) {

View File

@ -37,6 +37,7 @@ use Friendica\Database\DBA;
use Friendica\DI; use Friendica\DI;
use Friendica\Module; use Friendica\Module;
use Friendica\Network\HTTPClient\Client\HttpClientAccept; use Friendica\Network\HTTPClient\Client\HttpClientAccept;
use Friendica\Network\HTTPException\InternalServerErrorException;
use Friendica\Security\TwoFactor\Model\AppSpecificPassword; use Friendica\Security\TwoFactor\Model\AppSpecificPassword;
use Friendica\Network\HTTPException; use Friendica\Network\HTTPException;
use Friendica\Object\Image; use Friendica\Object\Image;
@ -1328,33 +1329,18 @@ class User
/** /**
* Update a user entry and distribute the changes if needed * Update a user entry and distribute the changes if needed
* *
* @param array $fields * @param array $fields
* @param integer $uid * @param integer $uid
* @return boolean * @return boolean
* @throws Exception
*/ */
public static function update(array $fields, int $uid): bool public static function update(array $fields, int $uid): bool
{ {
$old_owner = self::getOwnerDataById($uid);
if (empty($old_owner)) {
return false;
}
if (!DBA::update('user', $fields, ['uid' => $uid])) { if (!DBA::update('user', $fields, ['uid' => $uid])) {
return false; return false;
} }
$update = Contact::updateSelfFromUserID($uid); if (Contact::updateSelfFromUserID($uid)) {
$owner = self::getOwnerDataById($uid);
if (empty($owner)) {
return false;
}
if ($old_owner['name'] != $owner['name']) {
Profile::update(['name' => $owner['name']], $uid);
}
if ($update) {
Profile::publishUpdate($uid); Profile::publishUpdate($uid);
} }

View File

@ -573,7 +573,7 @@ class Account extends BaseSettings
'$delete_openid' => ['delete_openid', DI::l10n()->t('Delete OpenID URL'), false, ''], '$delete_openid' => ['delete_openid', DI::l10n()->t('Delete OpenID URL'), false, ''],
'$h_basic' => DI::l10n()->t('Basic Settings'), '$h_basic' => DI::l10n()->t('Basic Settings'),
'$username' => ['username', DI::l10n()->t('Full Name:'), $username, '', false, 'autocomplete="off"'], '$username' => ['username', DI::l10n()->t('Display name:'), $username, '', false, 'autocomplete="off"'],
'$email' => ['email', DI::l10n()->t('Email Address:'), $email, '', '', 'autocomplete="off"', 'email'], '$email' => ['email', DI::l10n()->t('Email Address:'), $email, '', '', 'autocomplete="off"', 'email'],
'$timezone' => ['timezone_select', DI::l10n()->t('Your Timezone:'), Temporal::getTimezoneSelect($timezone), ''], '$timezone' => ['timezone_select', DI::l10n()->t('Your Timezone:'), Temporal::getTimezoneSelect($timezone), ''],
'$language' => ['language', DI::l10n()->t('Your Language:'), $language, DI::l10n()->t('Set the language we use to show you friendica interface and to send you emails'), $lang_choices], '$language' => ['language', DI::l10n()->t('Your Language:'), $language, DI::l10n()->t('Set the language we use to show you friendica interface and to send you emails'), $lang_choices],

View File

@ -21,43 +21,75 @@
namespace Friendica\Module\Settings\Profile; namespace Friendica\Module\Settings\Profile;
use Friendica\App;
use Friendica\Core\ACL; use Friendica\Core\ACL;
use Friendica\Core\Hook; use Friendica\Core\Hook;
use Friendica\Core\L10n;
use Friendica\Core\Protocol; use Friendica\Core\Protocol;
use Friendica\Core\Renderer; use Friendica\Core\Renderer;
use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Core\Theme; use Friendica\Core\Theme;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\Contact; use Friendica\Model\Contact;
use Friendica\Model\Profile; use Friendica\Model\Profile;
use Friendica\Profile\ProfileField\Collection\ProfileFields; use Friendica\Module\Response;
use Friendica\Profile\ProfileField\Entity\ProfileField; use Friendica\Navigation\SystemMessages;
use Friendica\Profile\ProfileField;
use Friendica\Model\User; use Friendica\Model\User;
use Friendica\Module\BaseSettings; use Friendica\Module\BaseSettings;
use Friendica\Module\Security\Login; use Friendica\Module\Security\Login;
use Friendica\Network\HTTPException; use Friendica\Network\HTTPException;
use Friendica\Security\PermissionSet;
use Friendica\Util\ACLFormatter;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Util\Profiler;
use Friendica\Util\Temporal; use Friendica\Util\Temporal;
use Friendica\Core\Worker; use Friendica\Core\Worker;
use Psr\Log\LoggerInterface;
class Index extends BaseSettings class Index extends BaseSettings
{ {
/** @var ProfileField\Repository\ProfileField */
private $profileFieldRepo;
/** @var ProfileField\Factory\ProfileField */
private $profileFieldFactory;
/** @var SystemMessages */
private $systemMessages;
/** @var PermissionSet\Repository\PermissionSet */
private $permissionSetRepo;
/** @var PermissionSet\Factory\PermissionSet */
private $permissionSetFactory;
/** @var ACLFormatter */
private $aclFormatter;
public function __construct(ACLFormatter $aclFormatter, PermissionSet\Factory\PermissionSet $permissionSetFactory, PermissionSet\Repository\PermissionSet $permissionSetRepo, SystemMessages $systemMessages, ProfileField\Factory\ProfileField $profileFieldFactory, ProfileField\Repository\ProfileField $profileFieldRepo, IHandleUserSessions $session, App\Page $page, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
{
parent::__construct($session, $page, $l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->profileFieldRepo = $profileFieldRepo;
$this->profileFieldFactory = $profileFieldFactory;
$this->systemMessages = $systemMessages;
$this->permissionSetRepo = $permissionSetRepo;
$this->permissionSetFactory = $permissionSetFactory;
$this->aclFormatter = $aclFormatter;
}
protected function post(array $request = []) protected function post(array $request = [])
{ {
if (!DI::userSession()->getLocalUserId()) { if (!$this->session->getLocalUserId()) {
return; return;
} }
$profile = Profile::getByUID(DI::userSession()->getLocalUserId()); $profile = Profile::getByUID($this->session->getLocalUserId());
if (!DBA::isResult($profile)) { if (!$profile) {
return; return;
} }
self::checkFormSecurityTokenRedirectOnError('/settings/profile', 'settings_profile'); self::checkFormSecurityTokenRedirectOnError('/settings/profile', 'settings_profile');
Hook::callAll('profile_post', $_POST); Hook::callAll('profile_post', $request);
$dob = trim($_POST['dob'] ?? ''); $dob = trim($request['dob'] ?? '');
if ($dob && !in_array($dob, ['0000-00-00', DBA::NULL_DATE])) { if ($dob && !in_array($dob, ['0000-00-00', DBA::NULL_DATE])) {
$y = substr($dob, 0, 4); $y = substr($dob, 0, 4);
@ -79,39 +111,40 @@ class Index extends BaseSettings
} }
} }
$name = trim($_POST['name'] ?? ''); $username = trim($request['username'] ?? '');
if (!strlen($name)) { if (!$username) {
DI::sysmsg()->addNotice(DI::l10n()->t('Profile Name is required.')); $this->systemMessages->addNotice($this->t('Display Name is required.'));
return; return;
} }
$about = trim($_POST['about']); $about = trim($request['about']);
$address = trim($_POST['address']); $address = trim($request['address']);
$locality = trim($_POST['locality']); $locality = trim($request['locality']);
$region = trim($_POST['region']); $region = trim($request['region']);
$postal_code = trim($_POST['postal_code']); $postal_code = trim($request['postal_code']);
$country_name = trim($_POST['country_name']); $country_name = trim($request['country_name']);
$pub_keywords = self::cleanKeywords(trim($_POST['pub_keywords'])); $pub_keywords = self::cleanKeywords(trim($request['pub_keywords']));
$prv_keywords = self::cleanKeywords(trim($_POST['prv_keywords'])); $prv_keywords = self::cleanKeywords(trim($request['prv_keywords']));
$xmpp = trim($_POST['xmpp']); $xmpp = trim($request['xmpp']);
$matrix = trim($_POST['matrix']); $matrix = trim($request['matrix']);
$homepage = trim($_POST['homepage']); $homepage = trim($request['homepage']);
if ((strpos($homepage, 'http') !== 0) && (strlen($homepage))) { if ((strpos($homepage, 'http') !== 0) && (strlen($homepage))) {
// neither http nor https in URL, add them // neither http nor https in URL, add them
$homepage = 'http://' . $homepage; $homepage = 'http://' . $homepage;
} }
$profileFieldsNew = self::getProfileFieldsFromInput( $profileFieldsNew = $this->getProfileFieldsFromInput(
DI::userSession()->getLocalUserId(), $this->session->getLocalUserId(),
$_REQUEST['profile_field'], $request['profile_field'],
$_REQUEST['profile_field_order'] $request['profile_field_order']
); );
DI::profileField()->saveCollectionForUser(DI::userSession()->getLocalUserId(), $profileFieldsNew); $this->profileFieldRepo->saveCollectionForUser($this->session->getLocalUserId(), $profileFieldsNew);
User::update(['username' => $username], $this->session->getLocalUserId());
$result = Profile::update( $result = Profile::update(
[ [
'name' => $name,
'about' => $about, 'about' => $about,
'dob' => $dob, 'dob' => $dob,
'address' => $address, 'address' => $address,
@ -125,23 +158,23 @@ class Index extends BaseSettings
'pub_keywords' => $pub_keywords, 'pub_keywords' => $pub_keywords,
'prv_keywords' => $prv_keywords, 'prv_keywords' => $prv_keywords,
], ],
DI::userSession()->getLocalUserId() $this->session->getLocalUserId()
); );
Worker::add(Worker::PRIORITY_MEDIUM, 'CheckRelMeProfileLink', DI::userSession()->getLocalUserId()); Worker::add(Worker::PRIORITY_MEDIUM, 'CheckRelMeProfileLink', $this->session->getLocalUserId());
if (!$result) { if (!$result) {
DI::sysmsg()->addNotice(DI::l10n()->t('Profile couldn\'t be updated.')); $this->systemMessages->addNotice($this->t("Profile couldn't be updated."));
return; return;
} }
DI::baseUrl()->redirect('settings/profile'); $this->baseUrl->redirect('settings/profile');
} }
protected function content(array $request = []): string protected function content(array $request = []): string
{ {
if (!DI::userSession()->getLocalUserId()) { if (!$this->session->getLocalUserId()) {
DI::sysmsg()->addNotice(DI::l10n()->t('You must be logged in to use this module')); $this->systemMessages->addNotice($this->t('You must be logged in to use this module'));
return Login::form(); return Login::form();
} }
@ -149,147 +182,145 @@ class Index extends BaseSettings
$o = ''; $o = '';
$profile = User::getOwnerDataById(DI::userSession()->getLocalUserId()); $owner = User::getOwnerDataById($this->session->getLocalUserId());
if (!DBA::isResult($profile)) { if (!$owner) {
throw new HTTPException\NotFoundException(); throw new HTTPException\NotFoundException();
} }
$a = DI::app(); $this->page->registerFooterScript('view/asset/es-jquery-sortable/source/js/jquery-sortable-min.js');
$this->page->registerFooterScript(Theme::getPathForFile('js/module/settings/profile/index.js'));
DI::page()->registerFooterScript('view/asset/es-jquery-sortable/source/js/jquery-sortable-min.js');
DI::page()->registerFooterScript(Theme::getPathForFile('js/module/settings/profile/index.js'));
$custom_fields = []; $custom_fields = [];
$profileFields = DI::profileField()->selectByUserId(DI::userSession()->getLocalUserId()); $profileFields = $this->profileFieldRepo->selectByUserId($this->session->getLocalUserId());
foreach ($profileFields as $profileField) { foreach ($profileFields as $profileField) {
/** @var ProfileField $profileField */
$defaultPermissions = $profileField->permissionSet->withAllowedContacts( $defaultPermissions = $profileField->permissionSet->withAllowedContacts(
Contact::pruneUnavailable($profileField->permissionSet->allow_cid) Contact::pruneUnavailable($profileField->permissionSet->allow_cid)
); );
$custom_fields[] = [ $custom_fields[] = [
'id' => $profileField->id, 'id' => $profileField->id,
'legend' => $profileField->label, 'legend' => $profileField->label,
'fields' => [ 'fields' => [
'label' => ['profile_field[' . $profileField->id . '][label]', DI::l10n()->t('Label:'), $profileField->label], 'label' => ['profile_field[' . $profileField->id . '][label]', $this->t('Label:'), $profileField->label],
'value' => ['profile_field[' . $profileField->id . '][value]', DI::l10n()->t('Value:'), $profileField->value], 'value' => ['profile_field[' . $profileField->id . '][value]', $this->t('Value:'), $profileField->value],
'acl' => ACL::getFullSelectorHTML( 'acl' => ACL::getFullSelectorHTML(
DI::page(), $this->page,
$a->getLoggedInUserId(), $this->session->getLocalUserId(),
false, false,
$defaultPermissions->toArray(), $defaultPermissions->toArray(),
['network' => Protocol::DFRN], ['network' => Protocol::DFRN],
'profile_field[' . $profileField->id . ']' 'profile_field[' . $profileField->id . ']'
), ),
], ],
'permissions' => DI::l10n()->t('Field Permissions'),
'permdesc' => DI::l10n()->t("(click to open/close)"), 'permissions' => $this->t('Field Permissions'),
'permdesc' => $this->t("(click to open/close)"),
]; ];
}; }
$custom_fields[] = [ $custom_fields[] = [
'id' => 'new', 'id' => 'new',
'legend' => DI::l10n()->t('Add a new profile field'), 'legend' => $this->t('Add a new profile field'),
'fields' => [ 'fields' => [
'label' => ['profile_field[new][label]', DI::l10n()->t('Label:')], 'label' => ['profile_field[new][label]', $this->t('Label:')],
'value' => ['profile_field[new][value]', DI::l10n()->t('Value:')], 'value' => ['profile_field[new][value]', $this->t('Value:')],
'acl' => ACL::getFullSelectorHTML( 'acl' => ACL::getFullSelectorHTML(
DI::page(), $this->page,
$a->getLoggedInUserId(), $this->session->getLocalUserId(),
false, false,
['allow_cid' => []], ['allow_cid' => []],
['network' => Protocol::DFRN], ['network' => Protocol::DFRN],
'profile_field[new]' 'profile_field[new]'
), ),
], ],
'permissions' => DI::l10n()->t('Field Permissions'),
'permdesc' => DI::l10n()->t("(click to open/close)"), 'permissions' => $this->t('Field Permissions'),
'permdesc' => $this->t("(click to open/close)"),
]; ];
DI::page()['htmlhead'] .= Renderer::replaceMacros(Renderer::getMarkupTemplate('settings/profile/index_head.tpl'), [ $this->page['htmlhead'] .= Renderer::replaceMacros(Renderer::getMarkupTemplate('settings/profile/index_head.tpl'));
]);
$personal_account = ($profile['account-type'] != User::ACCOUNT_TYPE_COMMUNITY); $personal_account = ($owner['account-type'] != User::ACCOUNT_TYPE_COMMUNITY);
if ($profile['homepage_verified']) { if ($owner['homepage_verified']) {
$homepage_help_text = DI::l10n()->t('The homepage is verified. A rel="me" link back to your Friendica profile page was found on the homepage.'); $homepage_help_text = $this->t('The homepage is verified. A rel="me" link back to your Friendica profile page was found on the homepage.');
} else { } else {
$homepage_help_text = DI::l10n()->t('To verify your homepage, add a rel="me" link to it, pointing to your profile URL (%s).', $profile['url']); $homepage_help_text = $this->t('To verify your homepage, add a rel="me" link to it, pointing to your profile URL (%s).', $owner['url']);
} }
$tpl = Renderer::getMarkupTemplate('settings/profile/index.tpl'); $tpl = Renderer::getMarkupTemplate('settings/profile/index.tpl');
$o .= Renderer::replaceMacros($tpl, [ $o .= Renderer::replaceMacros($tpl, [
'$personal_account' => $personal_account, '$l10n' => [
'profile_action' => $this->t('Profile Actions'),
'$form_security_token' => self::getFormSecurityToken('settings_profile'), 'banner' => $this->t('Edit Profile Details'),
'$form_security_token_photo' => self::getFormSecurityToken('settings_profile_photo'), 'submit' => $this->t('Submit'),
'profpic' => $this->t('Change Profile Photo'),
'$profile_action' => DI::l10n()->t('Profile Actions'), 'viewprof' => $this->t('View Profile'),
'$banner' => DI::l10n()->t('Edit Profile Details'), 'personal_section' => $this->t('Personal'),
'$submit' => DI::l10n()->t('Submit'), 'picture_section' => $this->t('Profile picture'),
'$profpic' => DI::l10n()->t('Change Profile Photo'), 'location_section' => $this->t('Location'),
'$profpiclink' => '/profile/' . $profile['nickname'] . '/photos', 'miscellaneous_section' => $this->t('Miscellaneous'),
'$viewprof' => DI::l10n()->t('View Profile'), 'custom_fields_section' => $this->t('Custom Profile Fields'),
'profile_photo' => $this->t('Upload Profile Photo'),
'$lbl_personal_section' => DI::l10n()->t('Personal'), 'custom_fields_description' => $this->t('<p>Custom fields appear on <a href="%s">your profile page</a>.</p>
'$lbl_picture_section' => DI::l10n()->t('Profile picture'),
'$lbl_location_section' => DI::l10n()->t('Location'),
'$lbl_miscellaneous_section' => DI::l10n()->t('Miscellaneous'),
'$lbl_custom_fields_section' => DI::l10n()->t('Custom Profile Fields'),
'$lbl_profile_photo' => DI::l10n()->t('Upload Profile Photo'),
'$baseurl' => DI::baseUrl(),
'$nickname' => $profile['nickname'],
'$name' => ['name', DI::l10n()->t('Display name:'), $profile['name']],
'$about' => ['about', DI::l10n()->t('Description:'), $profile['about']],
'$dob' => Temporal::getDateofBirthField($profile['dob'], $profile['timezone']),
'$address' => ['address', DI::l10n()->t('Street Address:'), $profile['address']],
'$locality' => ['locality', DI::l10n()->t('Locality/City:'), $profile['locality']],
'$region' => ['region', DI::l10n()->t('Region/State:'), $profile['region']],
'$postal_code' => ['postal_code', DI::l10n()->t('Postal/Zip Code:'), $profile['postal-code']],
'$country_name' => ['country_name', DI::l10n()->t('Country:'), $profile['country-name']],
'$age' => ((intval($profile['dob'])) ? '(' . DI::l10n()->t('Age: ') . DI::l10n()->tt('%d year old', '%d years old', Temporal::getAgeByTimezone($profile['dob'], $profile['timezone'])) . ')' : ''),
'$xmpp' => ['xmpp', DI::l10n()->t('XMPP (Jabber) address:'), $profile['xmpp'], DI::l10n()->t('The XMPP address will be published so that people can follow you there.')],
'$matrix' => ['matrix', DI::l10n()->t('Matrix (Element) address:'), $profile['matrix'], DI::l10n()->t('The Matrix address will be published so that people can follow you there.')],
'$homepage' => ['homepage', DI::l10n()->t('Homepage URL:'), $profile['homepage'], $homepage_help_text],
'$pub_keywords' => ['pub_keywords', DI::l10n()->t('Public Keywords:'), $profile['pub_keywords'], DI::l10n()->t('(Used for suggesting potential friends, can be seen by others)')],
'$prv_keywords' => ['prv_keywords', DI::l10n()->t('Private Keywords:'), $profile['prv_keywords'], DI::l10n()->t('(Used for searching profiles, never shown to others)')],
'$custom_fields_description' => DI::l10n()->t("<p>Custom fields appear on <a href=\"%s\">your profile page</a>.</p>
<p>You can use BBCodes in the field values.</p> <p>You can use BBCodes in the field values.</p>
<p>Reorder by dragging the field title.</p> <p>Reorder by dragging the field title.</p>
<p>Empty the label field to remove a custom field.</p> <p>Empty the label field to remove a custom field.</p>
<p>Non-public fields can only be seen by the selected Friendica contacts or the Friendica contacts in the selected circles.</p>", <p>Non-public fields can only be seen by the selected Friendica contacts or the Friendica contacts in the selected circles.</p>',
'profile/' . $profile['nickname'] . '/profile' 'profile/' . $owner['nickname'] . '/profile'
), ),
],
'$personal_account' => $personal_account,
'$form_security_token' => self::getFormSecurityToken('settings_profile'),
'$form_security_token_photo' => self::getFormSecurityToken('settings_profile_photo'),
'$profpiclink' => '/profile/' . $owner['nickname'] . '/photos',
'$nickname' => $owner['nickname'],
'$username' => ['username', $this->t('Display name:'), $owner['name']],
'$about' => ['about', $this->t('Description:'), $owner['about']],
'$dob' => Temporal::getDateofBirthField($owner['dob'], $owner['timezone']),
'$address' => ['address', $this->t('Street Address:'), $owner['address']],
'$locality' => ['locality', $this->t('Locality/City:'), $owner['locality']],
'$region' => ['region', $this->t('Region/State:'), $owner['region']],
'$postal_code' => ['postal_code', $this->t('Postal/Zip Code:'), $owner['postal-code']],
'$country_name' => ['country_name', $this->t('Country:'), $owner['country-name']],
'$age' => ((intval($owner['dob'])) ? '(' . $this->t('Age: ') . $this->tt('%d year old', '%d years old', Temporal::getAgeByTimezone($owner['dob'], $owner['timezone'])) . ')' : ''),
'$xmpp' => ['xmpp', $this->t('XMPP (Jabber) address:'), $owner['xmpp'], $this->t('The XMPP address will be published so that people can follow you there.')],
'$matrix' => ['matrix', $this->t('Matrix (Element) address:'), $owner['matrix'], $this->t('The Matrix address will be published so that people can follow you there.')],
'$homepage' => ['homepage', $this->t('Homepage URL:'), $owner['homepage'], $homepage_help_text],
'$pub_keywords' => ['pub_keywords', $this->t('Public Keywords:'), $owner['pub_keywords'], $this->t('(Used for suggesting potential friends, can be seen by others)')],
'$prv_keywords' => ['prv_keywords', $this->t('Private Keywords:'), $owner['prv_keywords'], $this->t('(Used for searching profiles, never shown to others)')],
'$custom_fields' => $custom_fields, '$custom_fields' => $custom_fields,
]); ]);
$arr = ['profile' => $profile, 'entry' => $o]; $arr = ['profile' => $owner, 'entry' => $o];
Hook::callAll('profile_edit', $arr); Hook::callAll('profile_edit', $arr);
return $o; return $o;
} }
private static function getProfileFieldsFromInput(int $uid, array $profileFieldInputs, array $profileFieldOrder): ProfileFields private function getProfileFieldsFromInput(int $uid, array $profileFieldInputs, array $profileFieldOrder): ProfileField\Collection\ProfileFields
{ {
$profileFields = new ProfileFields(); $profileFields = new ProfileField\Collection\ProfileFields();
// Returns an associative array of id => order values // Returns an associative array of id => order values
$profileFieldOrder = array_flip($profileFieldOrder); $profileFieldOrder = array_flip($profileFieldOrder);
// Creation of the new field // Creation of the new field
if (!empty($profileFieldInputs['new']['label'])) { if (!empty($profileFieldInputs['new']['label'])) {
$permissionSet = DI::permissionSet()->selectOrCreate(DI::permissionSetFactory()->createFromString( $permissionSet = $this->permissionSetRepo->selectOrCreate($this->permissionSetFactory->createFromString(
$uid, $uid,
DI::aclFormatter()->toString($profileFieldInputs['new']['contact_allow'] ?? ''), $this->aclFormatter->toString($profileFieldInputs['new']['contact_allow'] ?? ''),
DI::aclFormatter()->toString($profileFieldInputs['new']['circle_allow'] ?? ''), $this->aclFormatter->toString($profileFieldInputs['new']['circle_allow'] ?? ''),
DI::aclFormatter()->toString($profileFieldInputs['new']['contact_deny'] ?? ''), $this->aclFormatter->toString($profileFieldInputs['new']['contact_deny'] ?? ''),
DI::aclFormatter()->toString($profileFieldInputs['new']['circle_deny'] ?? '') $this->aclFormatter->toString($profileFieldInputs['new']['circle_deny'] ?? '')
)); ));
$profileFields->append(DI::profileFieldFactory()->createFromValues( $profileFields->append($this->profileFieldFactory->createFromValues(
$uid, $uid,
$profileFieldOrder['new'], $profileFieldOrder['new'],
$profileFieldInputs['new']['label'], $profileFieldInputs['new']['label'],
@ -302,15 +333,15 @@ class Index extends BaseSettings
unset($profileFieldOrder['new']); unset($profileFieldOrder['new']);
foreach ($profileFieldInputs as $id => $profileFieldInput) { foreach ($profileFieldInputs as $id => $profileFieldInput) {
$permissionSet = DI::permissionSet()->selectOrCreate(DI::permissionSetFactory()->createFromString( $permissionSet = $this->permissionSetRepo->selectOrCreate($this->permissionSetFactory->createFromString(
$uid, $uid,
DI::aclFormatter()->toString($profileFieldInput['contact_allow'] ?? ''), $this->aclFormatter->toString($profileFieldInput['contact_allow'] ?? ''),
DI::aclFormatter()->toString($profileFieldInput['circle_allow'] ?? ''), $this->aclFormatter->toString($profileFieldInput['circle_allow'] ?? ''),
DI::aclFormatter()->toString($profileFieldInput['contact_deny'] ?? ''), $this->aclFormatter->toString($profileFieldInput['contact_deny'] ?? ''),
DI::aclFormatter()->toString($profileFieldInput['circle_deny'] ?? '') $this->aclFormatter->toString($profileFieldInput['circle_deny'] ?? '')
)); ));
$profileFields->append(DI::profileFieldFactory()->createFromValues( $profileFields->append($this->profileFieldFactory->createFromValues(
$uid, $uid,
$profileFieldOrder[$id], $profileFieldOrder[$id],
$profileFieldInput['label'], $profileFieldInput['label'],
@ -322,22 +353,20 @@ class Index extends BaseSettings
return $profileFields; return $profileFields;
} }
private static function cleanKeywords($keywords) private static function cleanKeywords($keywords): string
{ {
$keywords = str_replace(',', ' ', $keywords); $keywords = str_replace(',', ' ', $keywords);
$keywords = explode(' ', $keywords); $keywords = explode(' ', $keywords);
$cleaned = []; $cleaned = [];
foreach ($keywords as $keyword) { foreach ($keywords as $keyword) {
$keyword = trim(strtolower($keyword)); $keyword = trim($keyword);
$keyword = trim($keyword, '#'); $keyword = trim($keyword, '#');
if ($keyword != '') { if ($keyword != '') {
$cleaned[] = $keyword; $cleaned[] = $keyword;
} }
} }
$keywords = implode(', ', $cleaned); return implode(', ', $cleaned);
return $keywords;
} }
} }

View File

@ -211,7 +211,7 @@ class PermissionSet extends BaseRepository
} }
/** /**
* Selects or creates a PermissionSet based on it's fields * Selects or creates a PermissionSet based on its fields
* *
* @param Entity\PermissionSet $permissionSet * @param Entity\PermissionSet $permissionSet
* *

View File

@ -56,7 +56,7 @@ use Friendica\Database\DBA;
// This file is required several times during the test in DbaDefinition which justifies this condition // This file is required several times during the test in DbaDefinition which justifies this condition
if (!defined('DB_UPDATE_VERSION')) { if (!defined('DB_UPDATE_VERSION')) {
define('DB_UPDATE_VERSION', 1524); define('DB_UPDATE_VERSION', 1525);
} }
return [ return [
@ -1583,7 +1583,7 @@ return [
"profile-name" => ["type" => "varchar(255)", "comment" => "Deprecated"], "profile-name" => ["type" => "varchar(255)", "comment" => "Deprecated"],
"is-default" => ["type" => "boolean", "comment" => "Deprecated"], "is-default" => ["type" => "boolean", "comment" => "Deprecated"],
"hide-friends" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "Hide friend list from viewers of this profile"], "hide-friends" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "Hide friend list from viewers of this profile"],
"name" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""], "name" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => "Unused in favor of user.username"],
"pdesc" => ["type" => "varchar(255)", "comment" => "Deprecated"], "pdesc" => ["type" => "varchar(255)", "comment" => "Deprecated"],
"dob" => ["type" => "varchar(32)", "not null" => "1", "default" => "0000-00-00", "comment" => "Day of birth"], "dob" => ["type" => "varchar(32)", "not null" => "1", "default" => "0000-00-00", "comment" => "Day of birth"],
"address" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""], "address" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],

View File

@ -1349,3 +1349,30 @@ function update_1524(): int
return Update::SUCCESS; return Update::SUCCESS;
} }
function update_1525(): int
{
// Use expected value for user.username
if (!DBA::e('UPDATE `user` u
JOIN `profile` p
ON p.`uid` = u.`uid`
SET u.`username` = p.`name`')) {
return Update::FAILED;
}
// Blank out deprecated field profile.name to avoid future confusion
if (!DBA::e('UPDATE `profile` p
SET p.`name` = ""')) {
return Update::FAILED;
}
// Update users' self-contact name if needed
if (!DBA::e('UPDATE `contact` c
JOIN `user` u
ON u.`uid` = c.`uid` AND c.`self` = 1
SET c.`name` = u.`username`')) {
return Update::FAILED;
}
return Update::SUCCESS;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,121 +1,131 @@
<h1>{{$banner}}</h1> <script>
$(document).ready(function () {
//$('.toggle-section-content + .toggle-section-content').hide();
$('.js-section-toggler').click(function () {
$('.toggle-section-content').hide();
$(this).parents('.toggle-section').find('.toggle-section-content').toggle();
});
});
</script>
{{$default nofilter}} <h1>{{$l10n.banner}}</h1>
<div id="profile-edit-links"> <div id="profile-edit-links">
<ul> <ul>
<li><a href="settings/profile/photo" id="profile-photo_upload-link" title="{{$profpic}}">{{$profpic}}</a></li> <li><a class="btn" href="profile/{{$nickname}}/profile" id="profile-edit-view-link">{{$l10n.viewprof}}</a></li>
<li><a href="profile/{{$nickname}}/profile" id="profile-edit-view-link" title="{{$viewprof}}">{{$viewprof}}</a></li>
</ul> </ul>
</div> </div>
<div id="profile-edit-links-end"></div> <div id="profile-edit-links-end"></div>
<div id="profile-edit-wrapper"> <div id="profile-edit-wrapper">
<form id="profile-edit-form" name="form1" action="settings/profiles" method="post"> <form enctype="multipart/form-data" action="settings/profile/photo" method="post">
<input type="hidden" name="form_security_token" value="{{$form_security_token_photo}}">
<!-- Profile picture -->
<div class="toggle-section js-toggle-section">
<h2><a class="section-caption js-section-toggler" href="javascript:;">{{$l10n.picture_section}} &raquo;</a></h2>
<div class="js-section toggle-section-content hidden">
<div id="profile-photo-upload-wrapper">
<label id="profile-photo-upload-label" for="profile-photo-upload">{{$l10n.profile_photo}}:</label>
<input name="userfile" type="file" id="profile-photo-upload" size="48"/>
</div>
<div class="profile-edit-submit-wrapper">
<button type="submit" name="submit" class="profile-edit-submit-button">{{$l10n.submit}}</button>
</div>
<div class="profile-edit-submit-end"></div>
</div>
</div>
</form>
<form id="profile-edit-form" name="form1" action="" method="post">
<input type="hidden" name="form_security_token" value="{{$form_security_token}}"> <input type="hidden" name="form_security_token" value="{{$form_security_token}}">
<div id="profile-edit-name-wrapper"> <!-- Basic information -->
<label id="profile-edit-name-label" for="profile-edit-name">{{$name.1}} </label> <div class="toggle-section js-toggle-section">
<input type="text" size="32" name="name" id="profile-edit-name" value="{{$name.2}}"/> <h2><a class="section-caption js-section-toggler" href="javascript:;">{{$l10n.personal_section}} &raquo;</a></h2>
</div> <div class="js-section toggle-section-content hidden">
<div id="profile-edit-name-end"></div>
<div id="profile-edit-about-wrapper">
<label id="profile-edit-about-label" for="profile-edit-about">{{$about.1}} </label>
<input type="text" size="32" name="about" id="profile-edit-about" value="{{$about.1}}"/>
</div>
<div id="profile-edit-about-end"></div>
<div id="profile-edit-dob-wrapper">
{{$dob nofilter}}
</div>
<div id="profile-edit-dob-end"></div>
{{$hide_friends nofilter}}
<div class="profile-edit-submit-wrapper">
<input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}"/>
</div>
<div class="profile-edit-submit-end"></div>
<div id="profile-edit-address-wrapper">
<label id="profile-edit-address-label" for="profile-edit-address">{{$address.1}} </label>
<input type="text" size="32" name="address" id="profile-edit-address" value="{{$address.2}}"/>
</div>
<div id="profile-edit-address-end"></div>
<div id="profile-edit-locality-wrapper">
<label id="profile-edit-locality-label" for="profile-edit-locality">{{$locality.1}} </label>
<input type="text" size="32" name="locality" id="profile-edit-locality" value="{{$locality.2}}"/>
</div>
<div id="profile-edit-locality-end"></div>
<div id="profile-edit-postal-code-wrapper">
<label id="profile-edit-postal-code-label" for="profile-edit-postal-code">{{$postal_code.1}} </label>
<input type="text" size="32" name="postal_code" id="profile-edit-postal-code" value="{{$postal_code.2}}"/>
</div>
<div id="profile-edit-postal-code-end"></div>
<div id="profile-edit-country-name-wrapper">
<label id="profile-edit-country-name-label" for="profile-edit-country-name">{{$country_name.1}} </label>
<select name="country_name" id="profile-edit-country-name" onChange="Fill_States('{{$region.2}}');">
<option selected="selected">{{$country_name.2}}</option>
<option>temp</option>
</select>
</div>
<div id="profile-edit-country-name-end"></div>
<div id="profile-edit-region-wrapper">
<label id="profile-edit-region-label" for="profile-edit-region">{{$region.1}} </label>
<select name="region" id="profile-edit-region" onChange="Update_Globals();">
<option selected="selected">{{$region.2}}</option>
<option>temp</option>
</select>
</div>
<div id="profile-edit-region-end"></div>
<div class="profile-edit-submit-wrapper">
<input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}"/>
</div>
<div class="profile-edit-submit-end"></div>
<div id="profile-edit-homepage-wrapper">
<label id="profile-edit-homepage-label" for="profile-edit-homepage">{{$homepage.1}} </label>
<input type="url" size="32" name="homepage" id="profile-edit-homepage" value="{{$homepage.2}}"/>
</div>
<div id="profile-edit-homepage-desc">{{$homepage.3}}</div>
<div id="profile-edit-homepage-end"></div>
<div id="profile-edit-xmpp-wrapper">
<label id="profile-edit-xmpp-label" for="profile-edit-xmpp">{{$xmpp.1}} </label>
<input type="text" size="32" name="xmpp" id="profile-edit-xmpp" title="{{$lbl_ex2}}" value="{{$xmpp.2}}"/>
</div>
<div id="profile-edit-xmpp-desc">{{$xmpp.3}}</div>
<div id="profile-edit-xmpp-end"></div>
<div id="profile-edit-matrix-wrapper">
<label id="profile-edit-matrix-label" for="profile-edit-matrix">{{$matrix.1}} </label>
<input type="text" size="32" name="matrix" id="profile-edit-matrix" title="{{$lbl_ex2}}" value="{{$matrix.2}}"/>
</div>
<div id="profile-edit-matrix-desc">{{$matrix.3}}</div>
<div id="profile-edit-matrix-end"></div>
<div id="profile-edit-pubkeywords-wrapper">
<label id="profile-edit-pubkeywords-label" for="profile-edit-pubkeywords">{{$pub_keywords.1}} </label>
<input type="text" size="32" name="pub_keywords" id="profile-edit-pubkeywords" title="{{$lbl_ex2}}" value="{{$pub_keywords.2}}"/>
</div>
<div id="profile-edit-pubkeywords-desc">{{$pub_keywords.3}}</div>
<div id="profile-edit-pubkeywords-end"></div>
<div id="profile-edit-prvkeywords-wrapper">
<label id="profile-edit-prvkeywords-label" for="profile-edit-prvkeywords">{{$prv_keywords.1}} </label>
<input type="text" size="32" name="prv_keywords" id="profile-edit-prvkeywords" title="{{$lbl_ex2}}" value="{{$prv_keywords.2}}"/>
</div>
<div id="profile-edit-prvkeywords-desc">{{$prv_keywords.3}}</div>
<div id="profile-edit-prvkeywords-end"></div>
<div class="profile-edit-submit-wrapper">
<input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}"/>
</div>
<div class="profile-edit-submit-end"></div>
<h2>{{$lbl_custom_fields_section}}</h2> {{include file="field_input.tpl" field=$username}}
{{$custom_fields_description nofilter}}
<div id="profile-custom-fields">
{{foreach $custom_fields as $custom_field}}
{{include file="settings/profile/field/edit.tpl" profile_field=$custom_field}}
{{/foreach}}
</div>
<div class="profile-edit-submit-wrapper"> {{include file="field_textarea.tpl" field=$about}}
<input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}"/>
{{include file="field_input.tpl" field=$xmpp}}
{{include file="field_input.tpl" field=$matrix}}
{{include file="field_input.tpl" field=$homepage}}
<div id="profile-edit-dob-wrapper">
{{$dob nofilter}}
</div>
<div id="profile-edit-dob-end"></div>
{{$hide_friends nofilter}}
{{include file="field_input.tpl" field=$pub_keywords}}
{{include file="field_input.tpl" field=$prv_keywords}}
<div class="profile-edit-submit-wrapper">
<button type="submit" name="submit" class="profile-edit-submit-button">{{$l10n.submit}}</button>
</div>
<div class="profile-edit-submit-end"></div>
</div>
</div>
<!-- About you -->
<div class="toggle-section js-toggle-section">
<h2><a class="section-caption js-section-toggler" href="javascript:;">{{$l10n.location_section}} &raquo;</a></h2>
<div class="js-section toggle-section-content hidden">
{{include file="field_input.tpl" field=$address}}
{{include file="field_input.tpl" field=$locality}}
{{include file="field_input.tpl" field=$postal_code}}
<div id="profile-edit-country-name-wrapper">
<label id="profile-edit-country-name-label" for="profile-edit-country-name">{{$country_name.1}} </label>
<select name="country_name" id="profile-edit-country-name" onChange="Fill_States('{{$region.2}}');">
<option selected="selected">{{$country_name.2}}</option>
</select>
</div>
<div id="profile-edit-country-name-end"></div>
<div id="profile-edit-region-wrapper">
<label id="profile-edit-region-label" for="profile-edit-region">{{$region.1}} </label>
<select name="region" id="profile-edit-region" onChange="Update_Globals();">
<option selected="selected">{{$region.2}}</option>
</select>
</div>
<div id="profile-edit-region-end"></div>
<div class="profile-edit-submit-wrapper">
<button type="submit" name="submit" class="profile-edit-submit-button">{{$l10n.submit}}</button>
</div>
<div class="profile-edit-submit-end"></div>
</div>
</div>
<!-- Interests -->
<div class="toggle-section js-toggle-section">
<h2><a class="section-caption js-section-toggler" href="javascript:;">{{$l10n.custom_fields_section}} &raquo;</a></h2>
<div class="js-section toggle-section-content hidden">
{{$custom_fields_description nofilter}}
<div id="profile-custom-fields">
{{foreach $custom_fields as $custom_field}}
{{include file="settings/profile/field/edit.tpl" profile_field=$custom_field}}
{{/foreach}}
</div>
<div class="profile-edit-submit-wrapper">
<button type="submit" name="submit" class="profile-edit-submit-button">{{$l10n.submit}}</button>
</div>
<div class="profile-edit-submit-end"></div>
</div>
</div> </div>
<div class="profile-edit-submit-end"></div>
</form> </form>
</div> </div>
<script type="text/javascript"> <script type="text/javascript">

View File

@ -1,18 +1,18 @@
<div class="generic-page-wrapper"> <div class="generic-page-wrapper">
<h1>{{$banner}}</h1> <h2>{{$l10n.banner}}</h2>
{{* The actions dropdown which can performed to the current profile *}} {{* The actions dropdown which can performed to the current profile *}}
<div id="profile-edit-links"> <div id="profile-edit-links">
<ul class="nav nav-pills preferences"> <ul class="nav nav-pills preferences">
<li class="dropdown pull-right"> <li class="dropdown pull-right">
<button type="button" class="btn btn-link dropdown-toggle" id="profile-edit-links-dropdown" data-toggle="dropdown" aria-expanded="false"> <button type="button" class="btn btn-link dropdown-toggle" id="profile-edit-links-dropdown" data-toggle="dropdown" aria-expanded="false">
<i class="fa fa-angle-down" aria-hidden="true"></i>&nbsp;{{$profile_action}} <i class="fa fa-angle-down" aria-hidden="true"></i>&nbsp;{{$l10n.profile_action}}
</button> </button>
<ul class="dropdown-menu pull-right" role="menu" aria-labelledby="profile-edit-links-dropdown"> <ul class="dropdown-menu pull-right" role="menu" aria-labelledby="profile-edit-links-dropdown">
<li role="presentation"><a role="menuitem" href="{{$profpiclink}}" id="profile-photo_upload-link" title="{{$profpic}}"><i class="fa fa-user" aria-hidden="true"></i>&nbsp;{{$profpic}}</a></li> <li role="presentation"><a role="menuitem" href="{{$profpiclink}}" id="profile-photo_upload-link"><i class="fa fa-user" aria-hidden="true"></i>&nbsp;{{$l10n.profpic}}</a></li>
<li role="presentation"><button role="menuitem" type="button" class="btn-link" id="profile-photo_upload-link-new" title="{{$lbl_profile_photo}}" onclick="openClose('profile-photo-upload-section');"><i class="fa fa-user" aria-hidden="true"></i>&nbsp;{{$lbl_profile_photo}}</button></li> <li role="presentation"><button role="menuitem" type="button" class="btn-link" id="profile-photo_upload-link-new" onclick="openClose('profile-photo-upload-section');"><i class="fa fa-user" aria-hidden="true"></i>&nbsp;{{$l10n.profile_photo}}</button></li>
<li role="presentation" class="divider"></li> <li role="presentation" class="divider"></li>
<li role="presentation"><a role="menuitem" href="profile/{{$nickname}}/profile" id="profile-edit-view-link" title="{{$viewprof}}">{{$viewprof}}</a></li> <li role="presentation"><a role="menuitem" href="profile/{{$nickname}}/profile" id="profile-edit-view-link">{{$l10n.viewprof}}</a></li>
</ul> </ul>
</li> </li>
</ul> </ul>
@ -26,12 +26,12 @@
<div id="profile-photo-upload-section" class="panel"> <div id="profile-photo-upload-section" class="panel">
<a id="profile-photo-upload-close" class="close pull-right" onclick="openClose('profile-photo-upload-section');"><i class="fa fa-times" aria-hidden="true"></i></a> <a id="profile-photo-upload-close" class="close pull-right" onclick="openClose('profile-photo-upload-section');"><i class="fa fa-times" aria-hidden="true"></i></a>
<div id="profile-photo-upload-wrapper"> <div id="profile-photo-upload-wrapper">
<label id="profile-photo-upload-label" for="profile-photo-upload">{{$lbl_profile_photo}}:</label> <label id="profile-photo-upload-label" for="profile-photo-upload">{{$l10n.profile_photo}}:</label>
<input name="userfile" type="file" id="profile-photo-upload" size="48" /> <input name="userfile" type="file" id="profile-photo-upload" size="48" />
</div> </div>
<div class="profile-edit-submit-wrapper pull-right"> <div class="profile-edit-submit-wrapper pull-right">
<button type="submit" name="submit" class="profile-edit-submit-button btn btn-primary" value="{{$submit}}">{{$submit}}</button> <button type="submit" name="submit" class="profile-edit-submit-button btn btn-primary">{{$l10n.submit}}</button>
</div> </div>
<div class="clear"></div> <div class="clear"></div>
</div> </div>
@ -53,14 +53,14 @@
<div class="section-subtitle-wrapper panel-heading" role="tab" id="personal"> <div class="section-subtitle-wrapper panel-heading" role="tab" id="personal">
<h2> <h2>
<button class="btn-link accordion-toggle" data-toggle="collapse" data-parent="#profile-edit-wrapper" href="#personal-collapse" aria-expanded="true" aria-controls="personal-collapse"> <button class="btn-link accordion-toggle" data-toggle="collapse" data-parent="#profile-edit-wrapper" href="#personal-collapse" aria-expanded="true" aria-controls="personal-collapse">
{{$lbl_personal_section}} {{$l10n.personal_section}}
</button> </button>
</h2> </h2>
</div> </div>
{{* for the $detailed_profile we use bootstraps collapsable panel-groups to have expandable groups *}} {{* for the $detailed_profile we use bootstraps collapsable panel-groups to have expandable groups *}}
<div id="personal-collapse" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="personal"> <div id="personal-collapse" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="personal">
<div class="panel-body"> <div class="panel-body">
{{include file="field_input.tpl" field=$name}} {{include file="field_input.tpl" field=$username}}
{{include file="field_textarea.tpl" field=$about}} {{include file="field_textarea.tpl" field=$about}}
@ -69,7 +69,7 @@
{{$hide_friends nofilter}} {{$hide_friends nofilter}}
</div> </div>
<div class="panel-footer"> <div class="panel-footer">
<button type="submit" name="submit" class="btn btn-primary" value="{{$submit}}">{{$submit}}</button> <button type="submit" name="submit" class="btn btn-primary">{{$l10n.submit}}</button>
</div> </div>
</div> </div>
</div> </div>
@ -79,7 +79,7 @@
<div class="section-subtitle-wrapper panel-heading" role="tab" id="location"> <div class="section-subtitle-wrapper panel-heading" role="tab" id="location">
<h2> <h2>
<button class="btn-link accordion-toggle collapsed" data-toggle="collapse" data-parent="#profile-edit-wrapper" href="#location-collapse" aria-expanded="false" aria-controls="location-collapse"> <button class="btn-link accordion-toggle collapsed" data-toggle="collapse" data-parent="#profile-edit-wrapper" href="#location-collapse" aria-expanded="false" aria-controls="location-collapse">
{{$lbl_location_section}} {{$l10n.location_section}}
</button> </button>
</h2> </h2>
</div> </div>
@ -109,7 +109,7 @@
</div> </div>
</div> </div>
<div class="panel-footer"> <div class="panel-footer">
<button type="submit" name="submit" class="btn btn-primary" value="{{$submit}}">{{$submit}}</button> <button type="submit" name="submit" class="btn btn-primary">{{$l10n.submit}}</button>
</div> </div>
</div> </div>
</div> </div>
@ -119,7 +119,7 @@
<div class="section-subtitle-wrapper panel-heading" role="tab" id="miscellaneous"> <div class="section-subtitle-wrapper panel-heading" role="tab" id="miscellaneous">
<h2> <h2>
<button class="btn-link accordion-toggle collapsed" data-toggle="collapse" data-parent="#profile-edit-wrapper" href="#miscellaneous-collapse" aria-expanded="false" aria-controls="miscellaneous-collapse"> <button class="btn-link accordion-toggle collapsed" data-toggle="collapse" data-parent="#profile-edit-wrapper" href="#miscellaneous-collapse" aria-expanded="false" aria-controls="miscellaneous-collapse">
{{$lbl_miscellaneous_section}} {{$l10n.miscellaneous_section}}
</button> </button>
</h2> </h2>
</div> </div>
@ -136,7 +136,7 @@
{{include file="field_input.tpl" field=$prv_keywords}} {{include file="field_input.tpl" field=$prv_keywords}}
</div> </div>
<div class="panel-footer"> <div class="panel-footer">
<button type="submit" name="submit" class="btn btn-primary" value="{{$submit}}">{{$submit}}</button> <button type="submit" name="submit" class="btn btn-primary">{{$l10n.submit}}</button>
</div> </div>
</div> </div>
</div> </div>
@ -146,7 +146,7 @@
<div class="section-subtitle-wrapper panel-heading" role="tab" id="custom-fields"> <div class="section-subtitle-wrapper panel-heading" role="tab" id="custom-fields">
<h2> <h2>
<button class="btn-link accordion-toggle collapsed" data-toggle="collapse" data-parent="#profile-edit-wrapper" href="#custom-fields-collapse" aria-expanded="false" aria-controls="custom-fields-collapse"> <button class="btn-link accordion-toggle collapsed" data-toggle="collapse" data-parent="#profile-edit-wrapper" href="#custom-fields-collapse" aria-expanded="false" aria-controls="custom-fields-collapse">
{{$lbl_custom_fields_section}} {{$l10n.custom_fields_section}}
</button> </button>
</h2> </h2>
</div> </div>
@ -160,7 +160,7 @@
</div> </div>
</div> </div>
<div class="panel-footer"> <div class="panel-footer">
<button type="submit" name="submit" class="btn btn-primary" value="{{$submit}}">{{$submit}}</button> <button type="submit" name="submit" class="btn btn-primary">{{$l10n.submit}}</button>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,179 +0,0 @@
<script>
$(document).ready(function () {
//$('.toggle-section-content + .toggle-section-content').hide();
$('.js-section-toggler').click(function () {
$('.toggle-section-content').hide();
$(this).parents('.toggle-section').find('.toggle-section-content').toggle();
});
});
</script>
<h1>{{$banner}}</h1>
<div id="profile-edit-links">
<ul>
<li><a class="btn" href="profile/{{$nickname}}/profile" id="profile-edit-view-link" title="{{$viewprof}}">{{$viewprof}}</a></li>
</ul>
</div>
<div id="profile-edit-links-end"></div>
<div id="profile-edit-wrapper">
<form enctype="multipart/form-data" action="settings/profile/photo" method="post">
<input type="hidden" name="form_security_token" value="{{$form_security_token_photo}}">
<!-- Profile picture -->
<div class="toggle-section js-toggle-section">
<h2><a class="section-caption js-section-toggler" href="javascript:;">{{$lbl_picture_section}} &raquo;</a></h2>
<div class="js-section toggle-section-content hidden">
<div id="profile-photo-upload-wrapper">
<label id="profile-photo-upload-label" for="profile-photo-upload">{{$lbl_profile_photo}}:</label>
<input name="userfile" type="file" id="profile-photo-upload" size="48"/>
</div>
<div class="profile-edit-submit-wrapper">
<input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}"/>
</div>
<div class="profile-edit-submit-end"></div>
</div>
</div>
</form>
<form id="profile-edit-form" name="form1" action="" method="post">
<input type="hidden" name="form_security_token" value="{{$form_security_token}}">
<!-- Basic information -->
<div class="toggle-section js-toggle-section">
<h2><a class="section-caption js-section-toggler" href="javascript:;">{{$lbl_personal_section}} &raquo;</a></h2>
<div class="js-section toggle-section-content hidden">
<div id="profile-edit-name-wrapper">
<label id="profile-edit-name-label" for="profile-edit-name">{{$name.1}} </label>
<input type="text" size="32" name="name" id="profile-edit-name" value="{{$name.2}}"/>
</div>
<div id="profile-edit-name-end"></div>
<div id="profile-edit-about-wrapper">
<label id="profile-edit-about-label" for="profile-edit-about">{{$about.1}} </label>
<input type="text" size="32" name="about" id="profile-edit-about" value="{{$about.2}}"/>
</div>
<div id="profile-edit-about-end"></div>
<div id="profile-edit-xmpp-wrapper">
<label id="profile-edit-xmpp-label" for="profile-edit-xmpp">{{$xmpp.1}} </label>
<input type="text" size="32" name="xmpp" id="profile-edit-xmpp" value="{{$xmpp.2}}"/>
</div>
<div id="profile-edit-xmpp-desc">{{$xmpp.3}}</div>
<div id="profile-edit-xmpp-end"></div>
<div id="profile-edit-matrix-wrapper">
<label id="profile-edit-matrix-label" for="profile-edit-matrix">{{$matrix.1}} </label>
<input type="text" size="32" name="matrix" id="profile-edit-matrix" value="{{$matrix.2}}"/>
</div>
<div id="profile-edit-matrix-desc">{{$matrix.3}}</div>
<div id="profile-edit-matrix-end"></div>
<div id="profile-edit-homepage-wrapper">
<label id="profile-edit-homepage-label" for="profile-edit-homepage">{{$homepage.1}} </label>
<input type="text" size="32" name="homepage" id="profile-edit-homepage" value="{{$homepage.2}}"/>
</div>
<div id="profile-edit-homepage-desc">{{$homepage.3}}</div>
<div id="profile-edit-homepage-end"></div>
<div id="profile-edit-dob-wrapper">
{{$dob nofilter}}
</div>
<div id="profile-edit-dob-end"></div>
{{$hide_friends nofilter}}
<div id="profile-edit-pubkeywords-wrapper">
<label id="profile-edit-pubkeywords-label" for="profile-edit-pubkeywords">{{$pub_keywords.1}} </label>
<input type="text" size="32" name="pub_keywords" id="profile-edit-pubkeywords" title="{{$lbl_ex2}}" value="{{$pub_keywords.2}}"/>
</div>
<div id="profile-edit-pubkeywords-desc">{{$pub_keywords.3}}</div>
<div id="profile-edit-pubkeywords-end"></div>
<div id="profile-edit-prvkeywords-wrapper">
<label id="profile-edit-prvkeywords-label" for="profile-edit-prvkeywords">{{$prv_keywords.1}} </label>
<input type="text" size="32" name="prv_keywords" id="profile-edit-prvkeywords" title="{{$lbl_ex2}}" value="{{$prv_keywords.2}}"/>
</div>
<div id="profile-edit-prvkeywords-desc">{{$prv_keywords.3}}</div>
<div id="profile-edit-prvkeywords-end"></div>
<div class="profile-edit-submit-wrapper">
<input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}"/>
</div>
<div class="profile-edit-submit-end"></div>
</div>
</div>
<!-- About you -->
<div class="toggle-section js-toggle-section">
<h2><a class="section-caption js-section-toggler" href="javascript:;">{{$lbl_location_section}} &raquo;</a></h2>
<div class="js-section toggle-section-content hidden">
<div id="profile-edit-address-wrapper">
<label id="profile-edit-address-label" for="profile-edit-address">{{$address.1}} </label>
<input type="text" size="32" name="address" id="profile-edit-address" value="{{$address.2}}"/>
</div>
<div id="profile-edit-address-end"></div>
<div id="profile-edit-locality-wrapper">
<label id="profile-edit-locality-label" for="profile-edit-locality">{{$locality.1}} </label>
<input type="text" size="32" name="locality" id="profile-edit-locality" value="{{$locality.2}}"/>
</div>
<div id="profile-edit-locality-end"></div>
<div id="profile-edit-postal-code-wrapper">
<label id="profile-edit-postal-code-label" for="profile-edit-postal-code">{{$postal_code.1}} </label>
<input type="text" size="32" name="postal_code" id="profile-edit-postal-code" value="{{$postal_code.2}}"/>
</div>
<div id="profile-edit-postal-code-end"></div>
<div id="profile-edit-country-name-wrapper">
<label id="profile-edit-country-name-label" for="profile-edit-country-name">{{$country_name.1}} </label>
<select name="country_name" id="profile-edit-country-name" onChange="Fill_States('{{$region.2}}');">
<option selected="selected">{{$country_name.2}}</option>
</select>
</div>
<div id="profile-edit-country-name-end"></div>
<div id="profile-edit-region-wrapper">
<label id="profile-edit-region-label" for="profile-edit-region">{{$region.1}} </label>
<select name="region" id="profile-edit-region" onChange="Update_Globals();">
<option selected="selected">{{$region.2}}</option>
</select>
</div>
<div id="profile-edit-region-end"></div>
<div class="profile-edit-submit-wrapper">
<input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}"/>
</div>
<div class="profile-edit-submit-end"></div>
</div>
</div>
<!-- Interests -->
<div class="toggle-section js-toggle-section">
<h2><a class="section-caption js-section-toggler" href="javascript:;">{{$lbl_custom_fields_section}} &raquo;</a></h2>
<div class="js-section toggle-section-content hidden">
{{$custom_fields_description nofilter}}
<div id="profile-custom-fields">
{{foreach $custom_fields as $custom_field}}
{{include file="settings/profile/field/edit.tpl" profile_field=$custom_field}}
{{/foreach}}
</div>
<div class="profile-edit-submit-wrapper">
<input type="submit" name="submit" class="profile-edit-submit-button" value="{{$submit}}"/>
</div>
<div class="profile-edit-submit-end"></div>
</div>
</div>
</form>
</div>
<script type="text/javascript">
Fill_Country('{{$country_name.2}}');
Fill_States('{{$region.2}}');
</script>