2019-10-27 10:08:14 -04:00
< ? php
2020-02-09 15:45:36 +01:00
/**
2021-03-29 08:40:20 +02:00
* @ copyright Copyright ( C ) 2010 - 2021 , the Friendica project
2020-02-09 15:45:36 +01:00
*
* @ license GNU AGPL version 3 or any later version
*
* 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 < https :// www . gnu . org / licenses />.
*
*/
2019-10-27 10:08:14 -04:00
namespace Friendica\Module\Settings\Profile ;
2020-01-13 22:22:50 -05:00
use Friendica\Core\ACL ;
2019-10-27 10:08:14 -04:00
use Friendica\Core\Hook ;
2020-01-13 22:22:50 -05:00
use Friendica\Core\Protocol ;
2019-10-27 10:08:14 -04:00
use Friendica\Core\Renderer ;
2020-01-18 10:43:28 -05:00
use Friendica\Core\Theme ;
2019-10-27 10:08:14 -04:00
use Friendica\Database\DBA ;
use Friendica\DI ;
2021-10-05 23:30:10 +02:00
use Friendica\Model\Contact ;
2020-01-13 22:22:50 -05:00
use Friendica\Model\Profile ;
2021-10-10 20:39:35 +02:00
use Friendica\Profile\ProfileField\Collection\ProfileFields ;
2021-10-08 19:17:27 +02:00
use Friendica\Profile\ProfileField\Entity\ProfileField ;
2019-10-27 10:08:14 -04:00
use Friendica\Model\User ;
2020-01-22 23:14:14 -05:00
use Friendica\Module\BaseSettings ;
2019-10-27 10:08:14 -04:00
use Friendica\Module\Security\Login ;
use Friendica\Network\HTTPException ;
use Friendica\Util\DateTimeFormat ;
use Friendica\Util\Strings ;
use Friendica\Util\Temporal ;
2020-01-22 23:14:14 -05:00
class Index extends BaseSettings
2019-10-27 10:08:14 -04:00
{
public static function post ( array $parameters = [])
{
if ( ! local_user ()) {
return ;
}
2020-01-13 22:22:50 -05:00
$profile = Profile :: getByUID ( local_user ());
2019-10-27 10:08:14 -04:00
if ( ! DBA :: isResult ( $profile )) {
return ;
}
self :: checkFormSecurityTokenRedirectOnError ( '/settings/profile' , 'settings_profile' );
Hook :: callAll ( 'profile_post' , $_POST );
2020-02-09 02:17:48 -05:00
$dob = trim ( $_POST [ 'dob' ] ? ? '' );
2019-10-27 10:08:14 -04:00
2020-02-09 02:17:48 -05:00
if ( $dob && ! in_array ( $dob , [ '0000-00-00' , DBA :: NULL_DATE ])) {
$y = substr ( $dob , 0 , 4 );
if (( ! ctype_digit ( $y )) || ( $y < 1900 )) {
$ignore_year = true ;
} else {
$ignore_year = false ;
}
2019-10-27 10:08:14 -04:00
if ( strpos ( $dob , '0000-' ) === 0 || strpos ( $dob , '0001-' ) === 0 ) {
$ignore_year = true ;
$dob = substr ( $dob , 5 );
}
if ( $ignore_year ) {
$dob = '0000-' . DateTimeFormat :: utc ( '1900-' . $dob , 'm-d' );
} else {
$dob = DateTimeFormat :: utc ( $dob , 'Y-m-d' );
}
}
$name = Strings :: escapeTags ( trim ( $_POST [ 'name' ] ? ? '' ));
if ( ! strlen ( $name )) {
notice ( DI :: l10n () -> t ( 'Profile Name is required.' ));
return ;
}
2020-02-09 02:36:19 -05:00
$about = Strings :: escapeTags ( trim ( $_POST [ 'about' ]));
2019-10-27 10:08:14 -04:00
$address = Strings :: escapeTags ( trim ( $_POST [ 'address' ]));
$locality = Strings :: escapeTags ( trim ( $_POST [ 'locality' ]));
$region = Strings :: escapeTags ( trim ( $_POST [ 'region' ]));
$postal_code = Strings :: escapeTags ( trim ( $_POST [ 'postal_code' ]));
$country_name = Strings :: escapeTags ( trim ( $_POST [ 'country_name' ]));
$pub_keywords = self :: cleanKeywords ( Strings :: escapeTags ( trim ( $_POST [ 'pub_keywords' ])));
$prv_keywords = self :: cleanKeywords ( Strings :: escapeTags ( trim ( $_POST [ 'prv_keywords' ])));
$xmpp = Strings :: escapeTags ( trim ( $_POST [ 'xmpp' ]));
2021-08-09 01:39:09 +00:00
$matrix = Strings :: escapeTags ( trim ( $_POST [ 'matrix' ]));
2019-10-27 10:08:14 -04:00
$homepage = Strings :: escapeTags ( trim ( $_POST [ 'homepage' ]));
if (( strpos ( $homepage , 'http' ) !== 0 ) && ( strlen ( $homepage ))) {
// neither http nor https in URL, add them
$homepage = 'http://' . $homepage ;
}
2021-10-10 20:39:35 +02:00
$profileFieldsNew = self :: getProfileFieldsFromInput (
2020-01-13 22:22:50 -05:00
local_user (),
$_REQUEST [ 'profile_field' ],
$_REQUEST [ 'profile_field_order' ]
);
2019-10-27 10:08:14 -04:00
2021-10-10 20:54:29 +02:00
DI :: profileField () -> saveCollectionForUser ( local_user (), $profileFieldsNew );
2019-10-27 10:08:14 -04:00
2021-06-15 11:12:44 +00:00
$result = Profile :: update (
2019-10-27 10:08:14 -04:00
[
'name' => $name ,
2020-02-09 02:36:19 -05:00
'about' => $about ,
2019-10-27 10:08:14 -04:00
'dob' => $dob ,
'address' => $address ,
'locality' => $locality ,
'region' => $region ,
'postal-code' => $postal_code ,
'country-name' => $country_name ,
'xmpp' => $xmpp ,
2021-08-09 01:39:09 +00:00
'matrix' => $matrix ,
2019-10-27 10:08:14 -04:00
'homepage' => $homepage ,
'pub_keywords' => $pub_keywords ,
'prv_keywords' => $prv_keywords ,
],
2021-06-15 11:12:44 +00:00
local_user ()
2019-10-27 10:08:14 -04:00
);
2020-01-13 22:22:50 -05:00
2020-07-23 06:11:21 +00:00
if ( ! $result ) {
2019-10-27 10:08:14 -04:00
notice ( DI :: l10n () -> t ( 'Profile couldn\'t be updated.' ));
return ;
}
2021-10-21 19:11:28 -04:00
DI :: baseUrl () -> redirect ( 'settings/profile' );
2019-10-27 10:08:14 -04:00
}
public static function content ( array $parameters = [])
{
if ( ! local_user ()) {
notice ( DI :: l10n () -> t ( 'You must be logged in to use this module' ));
return Login :: form ();
}
parent :: content ();
$o = '' ;
2021-08-09 15:38:22 +00:00
$profile = User :: getOwnerDataById ( local_user ());
2019-10-27 10:08:14 -04:00
if ( ! DBA :: isResult ( $profile )) {
throw new HTTPException\NotFoundException ();
}
$a = DI :: app ();
2020-01-18 10:43:28 -05:00
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' ));
2020-01-13 22:22:50 -05:00
$custom_fields = [];
2021-10-10 20:54:29 +02:00
$profileFields = DI :: profileField () -> selectByUserId ( local_user ());
2020-01-13 22:22:50 -05:00
foreach ( $profileFields as $profileField ) {
/** @var ProfileField $profileField */
2021-10-07 20:48:39 +02:00
$defaultPermissions = $profileField -> permissionSet -> withAllowedContacts (
Contact :: pruneUnavailable ( $profileField -> permissionSet -> allow_cid )
2021-10-05 23:30:10 +02:00
);
2020-01-13 22:22:50 -05:00
$custom_fields [] = [
'id' => $profileField -> id ,
'legend' => $profileField -> label ,
'fields' => [
2020-01-18 14:12:43 -05:00
'label' => [ 'profile_field[' . $profileField -> id . '][label]' , DI :: l10n () -> t ( 'Label:' ), $profileField -> label ],
'value' => [ 'profile_field[' . $profileField -> id . '][value]' , DI :: l10n () -> t ( 'Value:' ), $profileField -> value ],
2020-01-13 22:22:50 -05:00
'acl' => ACL :: getFullSelectorHTML (
DI :: page (),
2021-08-09 20:33:46 +00:00
$a -> getLoggedInUserId (),
2020-01-13 22:22:50 -05:00
false ,
2021-10-05 23:30:10 +02:00
$defaultPermissions -> toArray (),
2020-01-13 22:22:50 -05:00
[ 'network' => Protocol :: DFRN ],
'profile_field[' . $profileField -> id . ']'
),
],
'permissions' => DI :: l10n () -> t ( 'Field Permissions' ),
'permdesc' => DI :: l10n () -> t ( " (click to open/close) " ),
];
};
$custom_fields [] = [
'id' => 'new' ,
'legend' => DI :: l10n () -> t ( 'Add a new profile field' ),
'fields' => [
'label' => [ 'profile_field[new][label]' , DI :: l10n () -> t ( 'Label:' )],
2020-01-18 14:12:43 -05:00
'value' => [ 'profile_field[new][value]' , DI :: l10n () -> t ( 'Value:' )],
2020-01-13 22:22:50 -05:00
'acl' => ACL :: getFullSelectorHTML (
DI :: page (),
2021-08-09 20:33:46 +00:00
$a -> getLoggedInUserId (),
2020-01-13 22:22:50 -05:00
false ,
[ 'allow_cid' => []],
[ 'network' => Protocol :: DFRN ],
'profile_field[new]'
),
],
'permissions' => DI :: l10n () -> t ( 'Field Permissions' ),
'permdesc' => DI :: l10n () -> t ( " (click to open/close) " ),
];
2019-10-27 10:08:14 -04:00
DI :: page ()[ 'htmlhead' ] .= Renderer :: replaceMacros ( Renderer :: getMarkupTemplate ( 'settings/profile/index_head.tpl' ), [
'$baseurl' => DI :: baseUrl () -> get ( true ),
]);
2021-08-08 10:14:56 +00:00
$personal_account = ! in_array ( $profile [ 'page-flags' ], [ User :: PAGE_FLAGS_COMMUNITY , User :: PAGE_FLAGS_PRVGROUP ]);
2019-10-27 10:08:14 -04:00
$tpl = Renderer :: getMarkupTemplate ( 'settings/profile/index.tpl' );
$o .= Renderer :: replaceMacros ( $tpl , [
'$personal_account' => $personal_account ,
'$form_security_token' => self :: getFormSecurityToken ( 'settings_profile' ),
'$form_security_token_photo' => self :: getFormSecurityToken ( 'settings_profile_photo' ),
'$profile_action' => DI :: l10n () -> t ( 'Profile Actions' ),
'$banner' => DI :: l10n () -> t ( 'Edit Profile Details' ),
'$submit' => DI :: l10n () -> t ( 'Submit' ),
'$profpic' => DI :: l10n () -> t ( 'Change Profile Photo' ),
2021-08-08 10:14:56 +00:00
'$profpiclink' => '/photos/' . $profile [ 'nickname' ],
2020-02-17 23:42:35 +01:00
'$viewprof' => DI :: l10n () -> t ( 'View Profile' ),
2019-10-27 10:08:14 -04:00
2020-01-13 22:22:50 -05:00
'$lbl_personal_section' => DI :: l10n () -> t ( 'Personal' ),
2019-10-27 10:08:14 -04:00
'$lbl_picture_section' => DI :: l10n () -> t ( 'Profile picture' ),
'$lbl_location_section' => DI :: l10n () -> t ( 'Location' ),
'$lbl_miscellaneous_section' => DI :: l10n () -> t ( 'Miscellaneous' ),
2020-01-13 22:22:50 -05:00
'$lbl_custom_fields_section' => DI :: l10n () -> t ( 'Custom Profile Fields' ),
2019-10-27 10:08:14 -04:00
'$lbl_profile_photo' => DI :: l10n () -> t ( 'Upload Profile Photo' ),
'$baseurl' => DI :: baseUrl () -> get ( true ),
2021-08-08 10:14:56 +00:00
'$nickname' => $profile [ 'nickname' ],
2019-10-27 10:08:14 -04:00
'$name' => [ 'name' , DI :: l10n () -> t ( 'Display name:' ), $profile [ 'name' ]],
2020-02-09 02:36:19 -05:00
'$about' => [ 'about' , DI :: l10n () -> t ( 'Description:' ), $profile [ 'about' ]],
2021-08-08 10:14:56 +00:00
'$dob' => Temporal :: getDateofBirthField ( $profile [ 'dob' ], $profile [ 'timezone' ]),
2019-10-27 10:08:14 -04:00
'$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' ]],
2021-08-08 10:14:56 +00:00
'$age' => (( intval ( $profile [ 'dob' ])) ? '(' . DI :: l10n () -> t ( 'Age: ' ) . DI :: l10n () -> tt ( '%d year old' , '%d years old' , Temporal :: getAgeByTimezone ( $profile [ 'dob' ], $profile [ 'timezone' ])) . ')' : '' ),
2021-08-16 06:15:18 +00:00
'$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.' )],
2021-08-09 01:39:09 +00:00
'$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.' )],
2019-10-27 10:08:14 -04:00
'$homepage' => [ 'homepage' , DI :: l10n () -> t ( 'Homepage URL:' ), $profile [ 'homepage' ]],
'$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)' )],
2020-01-18 14:12:43 -05:00
'$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 > Reorder by dragging the field title .</ 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 groups .</ p > " ,
2021-08-08 10:14:56 +00:00
'profile/' . $profile [ 'nickname' ]
2020-01-18 14:12:43 -05:00
),
2020-01-13 22:22:50 -05:00
'$custom_fields' => $custom_fields ,
2019-10-27 10:08:14 -04:00
]);
$arr = [ 'profile' => $profile , 'entry' => $o ];
Hook :: callAll ( 'profile_edit' , $arr );
return $o ;
}
2021-10-10 20:39:35 +02:00
private static function getProfileFieldsFromInput ( int $uid , array $profileFieldInputs , array $profileFieldOrder ) : ProfileFields
{
$profileFields = new ProfileFields ();
// Returns an associative array of id => order values
$profileFieldOrder = array_flip ( $profileFieldOrder );
// Creation of the new field
if ( ! empty ( $profileFieldInputs [ 'new' ][ 'label' ])) {
$permissionSet = DI :: permissionSet () -> selectOrCreate ( DI :: permissionSetFactory () -> createFromString (
$uid ,
2021-10-17 15:32:50 +02:00
DI :: aclFormatter () -> toString ( $profileFieldInputs [ 'new' ][ 'contact_allow' ] ? ? '' ),
DI :: aclFormatter () -> toString ( $profileFieldInputs [ 'new' ][ 'group_allow' ] ? ? '' ),
DI :: aclFormatter () -> toString ( $profileFieldInputs [ 'new' ][ 'contact_deny' ] ? ? '' ),
DI :: aclFormatter () -> toString ( $profileFieldInputs [ 'new' ][ 'group_deny' ] ? ? '' )
2021-10-10 20:39:35 +02:00
));
2021-10-17 15:32:50 +02:00
$profileFields -> append ( DI :: profileFieldFactory () -> createFromValues (
2021-10-10 20:39:35 +02:00
$uid ,
$profileFieldOrder [ 'new' ],
$profileFieldInputs [ 'new' ][ 'label' ],
$profileFieldInputs [ 'new' ][ 'value' ],
$permissionSet
));
}
2021-10-17 23:10:10 +02:00
unset ( $profileFieldInputs [ 'new' ]);
unset ( $profileFieldOrder [ 'new' ]);
2021-10-10 20:39:35 +02:00
foreach ( $profileFieldInputs as $id => $profileFieldInput ) {
$permissionSet = DI :: permissionSet () -> selectOrCreate ( DI :: permissionSetFactory () -> createFromString (
$uid ,
2021-10-17 15:32:50 +02:00
DI :: aclFormatter () -> toString ( $profileFieldInput [ 'contact_allow' ] ? ? '' ),
DI :: aclFormatter () -> toString ( $profileFieldInput [ 'group_allow' ] ? ? '' ),
DI :: aclFormatter () -> toString ( $profileFieldInput [ 'contact_deny' ] ? ? '' ),
DI :: aclFormatter () -> toString ( $profileFieldInput [ 'group_deny' ] ? ? '' )
2021-10-10 20:39:35 +02:00
));
2021-10-17 15:32:50 +02:00
$profileFields -> append ( DI :: profileFieldFactory () -> createFromValues (
2021-10-10 20:39:35 +02:00
$uid ,
$profileFieldOrder [ $id ],
$profileFieldInput [ 'label' ],
$profileFieldInput [ 'value' ],
$permissionSet
));
}
return $profileFields ;
}
2019-10-27 10:08:14 -04:00
private static function cleanKeywords ( $keywords )
{
$keywords = str_replace ( ',' , ' ' , $keywords );
$keywords = explode ( ' ' , $keywords );
$cleaned = [];
foreach ( $keywords as $keyword ) {
$keyword = trim ( strtolower ( $keyword ));
$keyword = trim ( $keyword , '#' );
if ( $keyword != '' ) {
$cleaned [] = $keyword ;
}
}
$keywords = implode ( ', ' , $cleaned );
return $keywords ;
}
}