]> git.mxchange.org Git - friendica.git/blob - src/Module/Settings/Profile/Index.php
The "thread" table isn't used anymore
[friendica.git] / src / Module / Settings / Profile / Index.php
1 <?php
2 /**
3  * @copyright Copyright (C) 2020, Friendica
4  *
5  * @license GNU AGPL version 3 or any later version
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License as
9  * published by the Free Software Foundation, either version 3 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Affero General Public License for more details.
16  *
17  * You should have received a copy of the GNU Affero General Public License
18  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19  *
20  */
21
22 namespace Friendica\Module\Settings\Profile;
23
24 use Friendica\Core\ACL;
25 use Friendica\Core\Hook;
26 use Friendica\Core\Protocol;
27 use Friendica\Core\Renderer;
28 use Friendica\Core\Session;
29 use Friendica\Core\Theme;
30 use Friendica\Core\Worker;
31 use Friendica\Database\DBA;
32 use Friendica\DI;
33 use Friendica\Model\Contact;
34 use Friendica\Model\Profile;
35 use Friendica\Model\ProfileField;
36 use Friendica\Model\User;
37 use Friendica\Module\BaseSettings;
38 use Friendica\Module\Security\Login;
39 use Friendica\Network\HTTPException;
40 use Friendica\Util\DateTimeFormat;
41 use Friendica\Util\Strings;
42 use Friendica\Util\Temporal;
43
44 class Index extends BaseSettings
45 {
46         public static function post(array $parameters = [])
47         {
48                 if (!local_user()) {
49                         return;
50                 }
51
52                 $profile = Profile::getByUID(local_user());
53                 if (!DBA::isResult($profile)) {
54                         return;
55                 }
56
57                 self::checkFormSecurityTokenRedirectOnError('/settings/profile', 'settings_profile');
58
59                 Hook::callAll('profile_post', $_POST);
60
61                 $dob = trim($_POST['dob'] ?? '');
62
63                 if ($dob && !in_array($dob, ['0000-00-00', DBA::NULL_DATE])) {
64                         $y = substr($dob, 0, 4);
65                         if ((!ctype_digit($y)) || ($y < 1900)) {
66                                 $ignore_year = true;
67                         } else {
68                                 $ignore_year = false;
69                         }
70
71                         if (strpos($dob, '0000-') === 0 || strpos($dob, '0001-') === 0) {
72                                 $ignore_year = true;
73                                 $dob = substr($dob, 5);
74                         }
75
76                         if ($ignore_year) {
77                                 $dob = '0000-' . DateTimeFormat::utc('1900-' . $dob, 'm-d');
78                         } else {
79                                 $dob = DateTimeFormat::utc($dob, 'Y-m-d');
80                         }
81                 }
82
83                 $name = Strings::escapeTags(trim($_POST['name'] ?? ''));
84                 if (!strlen($name)) {
85                         notice(DI::l10n()->t('Profile Name is required.'));
86                         return;
87                 }
88
89                 $namechanged = $profile['name'] != $name;
90
91                 $about = Strings::escapeTags(trim($_POST['about']));
92                 $address = Strings::escapeTags(trim($_POST['address']));
93                 $locality = Strings::escapeTags(trim($_POST['locality']));
94                 $region = Strings::escapeTags(trim($_POST['region']));
95                 $postal_code = Strings::escapeTags(trim($_POST['postal_code']));
96                 $country_name = Strings::escapeTags(trim($_POST['country_name']));
97                 $pub_keywords = self::cleanKeywords(Strings::escapeTags(trim($_POST['pub_keywords'])));
98                 $prv_keywords = self::cleanKeywords(Strings::escapeTags(trim($_POST['prv_keywords'])));
99                 $xmpp = Strings::escapeTags(trim($_POST['xmpp']));
100                 $homepage = Strings::escapeTags(trim($_POST['homepage']));
101                 if ((strpos($homepage, 'http') !== 0) && (strlen($homepage))) {
102                         // neither http nor https in URL, add them
103                         $homepage = 'http://' . $homepage;
104                 }
105
106                 $profileFields = DI::profileField()->selectByUserId(local_user());
107
108                 $profileFields = DI::profileField()->updateCollectionFromForm(
109                         local_user(),
110                         $profileFields,
111                         $_REQUEST['profile_field'],
112                         $_REQUEST['profile_field_order']
113                 );
114
115                 DI::profileField()->saveCollection($profileFields);
116
117                 $result = DBA::update(
118                         'profile',
119                         [
120                                 'name'         => $name,
121                                 'about'        => $about,
122                                 'dob'          => $dob,
123                                 'address'      => $address,
124                                 'locality'     => $locality,
125                                 'region'       => $region,
126                                 'postal-code'  => $postal_code,
127                                 'country-name' => $country_name,
128                                 'xmpp'         => $xmpp,
129                                 'homepage'     => $homepage,
130                                 'pub_keywords' => $pub_keywords,
131                                 'prv_keywords' => $prv_keywords,
132                         ],
133                         ['uid' => local_user()]
134                 );
135
136                 if (!$result) {
137                         notice(DI::l10n()->t('Profile couldn\'t be updated.'));
138                         return;
139                 }
140
141                 if ($namechanged) {
142                         DBA::update('user', ['username' => $name], ['uid' => local_user()]);
143                 }
144
145                 Contact::updateSelfFromUserID(local_user());
146
147                 // Update global directory in background
148                 if (Session::get('my_url') && strlen(DI::config()->get('system', 'directory'))) {
149                         Worker::add(PRIORITY_LOW, 'Directory', Session::get('my_url'));
150                 }
151
152                 Worker::add(PRIORITY_LOW, 'ProfileUpdate', local_user());
153         }
154
155         public static function content(array $parameters = [])
156         {
157                 if (!local_user()) {
158                         notice(DI::l10n()->t('You must be logged in to use this module'));
159                         return Login::form();
160                 }
161
162                 parent::content();
163
164                 $o = '';
165
166                 $profile = Profile::getByUID(local_user());
167                 if (!DBA::isResult($profile)) {
168                         throw new HTTPException\NotFoundException();
169                 }
170
171                 $a = DI::app();
172
173                 DI::page()->registerFooterScript('view/asset/es-jquery-sortable/source/js/jquery-sortable-min.js');
174                 DI::page()->registerFooterScript(Theme::getPathForFile('js/module/settings/profile/index.js'));
175
176                 $custom_fields = [];
177
178                 $profileFields = DI::profileField()->selectByUserId(local_user());
179                 foreach ($profileFields as $profileField) {
180                         /** @var ProfileField $profileField */
181                         $defaultPermissions = ACL::getDefaultUserPermissions($profileField->permissionset->toArray());
182
183                         $custom_fields[] = [
184                                 'id' => $profileField->id,
185                                 'legend' => $profileField->label,
186                                 'fields' => [
187                                         'label' => ['profile_field[' . $profileField->id . '][label]', DI::l10n()->t('Label:'), $profileField->label],
188                                         'value' => ['profile_field[' . $profileField->id . '][value]', DI::l10n()->t('Value:'), $profileField->value],
189                                         'acl' => ACL::getFullSelectorHTML(
190                                                 DI::page(),
191                                                 $a->user,
192                                                 false,
193                                                 $defaultPermissions,
194                                                 ['network' => Protocol::DFRN],
195                                                 'profile_field[' . $profileField->id . ']'
196                                         ),
197                                 ],
198                                 'permissions' => DI::l10n()->t('Field Permissions'),
199                                 'permdesc' => DI::l10n()->t("(click to open/close)"),
200                         ];
201                 };
202
203                 $custom_fields[] = [
204                         'id' => 'new',
205                         'legend' => DI::l10n()->t('Add a new profile field'),
206                         'fields' => [
207                                 'label' => ['profile_field[new][label]', DI::l10n()->t('Label:')],
208                                 'value' => ['profile_field[new][value]', DI::l10n()->t('Value:')],
209                                 'acl' => ACL::getFullSelectorHTML(
210                                         DI::page(),
211                                         $a->user,
212                                         false,
213                                         ['allow_cid' => []],
214                                         ['network' => Protocol::DFRN],
215                                         'profile_field[new]'
216                                 ),
217                         ],
218                         'permissions' => DI::l10n()->t('Field Permissions'),
219                         'permdesc' => DI::l10n()->t("(click to open/close)"),
220                 ];
221
222                 DI::page()['htmlhead'] .= Renderer::replaceMacros(Renderer::getMarkupTemplate('settings/profile/index_head.tpl'), [
223                         '$baseurl' => DI::baseUrl()->get(true),
224                 ]);
225
226                 $personal_account = !in_array($a->user['page-flags'], [User::PAGE_FLAGS_COMMUNITY, User::PAGE_FLAGS_PRVGROUP]);
227
228                 $tpl = Renderer::getMarkupTemplate('settings/profile/index.tpl');
229                 $o .= Renderer::replaceMacros($tpl, [
230                         '$personal_account' => $personal_account,
231
232                         '$form_security_token' => self::getFormSecurityToken('settings_profile'),
233                         '$form_security_token_photo' => self::getFormSecurityToken('settings_profile_photo'),
234
235                         '$profile_action' => DI::l10n()->t('Profile Actions'),
236                         '$banner' => DI::l10n()->t('Edit Profile Details'),
237                         '$submit' => DI::l10n()->t('Submit'),
238                         '$profpic' => DI::l10n()->t('Change Profile Photo'),
239                         '$profpiclink' => '/photos/' . $a->user['nickname'],
240                         '$viewprof' => DI::l10n()->t('View Profile'),
241
242                         '$lbl_personal_section' => DI::l10n()->t('Personal'),
243                         '$lbl_picture_section' => DI::l10n()->t('Profile picture'),
244                         '$lbl_location_section' => DI::l10n()->t('Location'),
245                         '$lbl_miscellaneous_section' => DI::l10n()->t('Miscellaneous'),
246                         '$lbl_custom_fields_section' => DI::l10n()->t('Custom Profile Fields'),
247
248                         '$lbl_profile_photo' => DI::l10n()->t('Upload Profile Photo'),
249
250                         '$baseurl' => DI::baseUrl()->get(true),
251                         '$nickname' => $a->user['nickname'],
252                         '$name' => ['name', DI::l10n()->t('Display name:'), $profile['name']],
253                         '$about' => ['about', DI::l10n()->t('Description:'), $profile['about']],
254                         '$dob' => Temporal::getDateofBirthField($profile['dob'], $a->user['timezone']),
255                         '$address' => ['address', DI::l10n()->t('Street Address:'), $profile['address']],
256                         '$locality' => ['locality', DI::l10n()->t('Locality/City:'), $profile['locality']],
257                         '$region' => ['region', DI::l10n()->t('Region/State:'), $profile['region']],
258                         '$postal_code' => ['postal_code', DI::l10n()->t('Postal/Zip Code:'), $profile['postal-code']],
259                         '$country_name' => ['country_name', DI::l10n()->t('Country:'), $profile['country-name']],
260                         '$age' => ((intval($profile['dob'])) ? '(' . DI::l10n()->t('Age: ') . DI::l10n()->tt('%d year old', '%d years old', Temporal::getAgeByTimezone($profile['dob'], $a->user['timezone'])) . ')' : ''),
261                         '$xmpp' => ['xmpp', DI::l10n()->t('XMPP (Jabber) address:'), $profile['xmpp'], DI::l10n()->t('The XMPP address will be propagated to your contacts so that they can follow you.')],
262                         '$homepage' => ['homepage', DI::l10n()->t('Homepage URL:'), $profile['homepage']],
263                         '$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)')],
264                         '$prv_keywords' => ['prv_keywords', DI::l10n()->t('Private Keywords:'), $profile['prv_keywords'], DI::l10n()->t('(Used for searching profiles, never shown to others)')],
265                         '$custom_fields_description' => DI::l10n()->t("<p>Custom fields appear on <a href=\"%s\">your profile page</a>.</p>
266                                 <p>You can use BBCodes in the field values.</p>
267                                 <p>Reorder by dragging the field title.</p>
268                                 <p>Empty the label field to remove a custom field.</p>
269                                 <p>Non-public fields can only be seen by the selected Friendica contacts or the Friendica contacts in the selected groups.</p>",
270                                 'profile/' . $a->user['nickname']
271                         ),
272                         '$custom_fields' => $custom_fields,
273                 ]);
274
275                 $arr = ['profile' => $profile, 'entry' => $o];
276                 Hook::callAll('profile_edit', $arr);
277
278                 return $o;
279         }
280
281         private static function cleanKeywords($keywords)
282         {
283                 $keywords = str_replace(',', ' ', $keywords);
284                 $keywords = explode(' ', $keywords);
285
286                 $cleaned = [];
287                 foreach ($keywords as $keyword) {
288                         $keyword = trim(strtolower($keyword));
289                         $keyword = trim($keyword, '#');
290                         if ($keyword != '') {
291                                 $cleaned[] = $keyword;
292                         }
293                 }
294
295                 $keywords = implode(', ', $cleaned);
296
297                 return $keywords;
298         }
299 }