]> git.mxchange.org Git - friendica.git/blob - mod/settings.php
Rename App Methods
[friendica.git] / mod / settings.php
1 <?php
2 /**
3  * @file mod/settings.php
4  */
5
6 use Friendica\App;
7 use Friendica\Content\Feature;
8 use Friendica\Content\Nav;
9 use Friendica\Core\ACL;
10 use Friendica\Core\Addon;
11 use Friendica\Core\Config;
12 use Friendica\Core\L10n;
13 use Friendica\Core\PConfig;
14 use Friendica\Core\System;
15 use Friendica\Core\Theme;
16 use Friendica\Core\Worker;
17 use Friendica\Database\DBA;
18 use Friendica\Model\Contact;
19 use Friendica\Model\GContact;
20 use Friendica\Model\Group;
21 use Friendica\Model\User;
22 use Friendica\Protocol\Email;
23 use Friendica\Util\Network;
24 use Friendica\Util\Temporal;
25 use Friendica\Module\Login;
26
27 function get_theme_config_file($theme)
28 {
29         $a = get_app();
30         $base_theme = defaults($a->theme_info, 'extends');
31
32         if (file_exists("view/theme/$theme/config.php")) {
33                 return "view/theme/$theme/config.php";
34         }
35         if ($base_theme && file_exists("view/theme/$base_theme/config.php")) {
36                 return "view/theme/$base_theme/config.php";
37         }
38         return null;
39 }
40
41 function settings_init(App $a)
42 {
43         if (!local_user()) {
44                 notice(L10n::t('Permission denied.') . EOL);
45                 return;
46         }
47
48         // These lines provide the javascript needed by the acl selector
49
50         $tpl = get_markup_template('settings/head.tpl');
51         $a->page['htmlhead'] .= replace_macros($tpl, [
52                 '$ispublic' => L10n::t('everybody')
53         ]);
54
55         $tabs = [
56                 [
57                         'label' => L10n::t('Account'),
58                         'url'   => 'settings',
59                         'selected'      =>  (($a->argc == 1) && ($a->argv[0] === 'settings')?'active':''),
60                         'accesskey' => 'o',
61                 ],
62         ];
63
64         $tabs[] =       [
65                 'label' => L10n::t('Profiles'),
66                 'url'   => 'profiles',
67                 'selected'      => (($a->argc == 1) && ($a->argv[0] === 'profiles')?'active':''),
68                 'accesskey' => 'p',
69         ];
70
71         if (Feature::get()) {
72                 $tabs[] =       [
73                                         'label' => L10n::t('Additional features'),
74                                         'url'   => 'settings/features',
75                                         'selected'      => (($a->argc > 1) && ($a->argv[1] === 'features') ? 'active' : ''),
76                                         'accesskey' => 't',
77                                 ];
78         }
79
80         $tabs[] =       [
81                 'label' => L10n::t('Display'),
82                 'url'   => 'settings/display',
83                 'selected'      => (($a->argc > 1) && ($a->argv[1] === 'display')?'active':''),
84                 'accesskey' => 'i',
85         ];
86
87         $tabs[] =       [
88                 'label' => L10n::t('Social Networks'),
89                 'url'   => 'settings/connectors',
90                 'selected'      => (($a->argc > 1) && ($a->argv[1] === 'connectors')?'active':''),
91                 'accesskey' => 'w',
92         ];
93
94         $tabs[] =       [
95                 'label' => L10n::t('Addons'),
96                 'url'   => 'settings/addon',
97                 'selected'      => (($a->argc > 1) && ($a->argv[1] === 'addon')?'active':''),
98                 'accesskey' => 'l',
99         ];
100
101         $tabs[] =       [
102                 'label' => L10n::t('Delegations'),
103                 'url'   => 'delegate',
104                 'selected'      => (($a->argc == 1) && ($a->argv[0] === 'delegate')?'active':''),
105                 'accesskey' => 'd',
106         ];
107
108         $tabs[] =       [
109                 'label' => L10n::t('Connected apps'),
110                 'url' => 'settings/oauth',
111                 'selected' => (($a->argc > 1) && ($a->argv[1] === 'oauth')?'active':''),
112                 'accesskey' => 'b',
113         ];
114
115         $tabs[] =       [
116                 'label' => L10n::t('Export personal data'),
117                 'url' => 'uexport',
118                 'selected' => (($a->argc == 1) && ($a->argv[0] === 'uexport')?'active':''),
119                 'accesskey' => 'e',
120         ];
121
122         $tabs[] =       [
123                 'label' => L10n::t('Remove account'),
124                 'url' => 'removeme',
125                 'selected' => (($a->argc == 1) && ($a->argv[0] === 'removeme')?'active':''),
126                 'accesskey' => 'r',
127         ];
128
129
130         $tabtpl = get_markup_template("generic_links_widget.tpl");
131         $a->page['aside'] = replace_macros($tabtpl, [
132                 '$title' => L10n::t('Settings'),
133                 '$class' => 'settings-widget',
134                 '$items' => $tabs,
135         ]);
136
137 }
138
139 function settings_post(App $a)
140 {
141         if (!local_user()) {
142                 return;
143         }
144
145         if (x($_SESSION, 'submanage') && intval($_SESSION['submanage'])) {
146                 return;
147         }
148
149         if (count($a->user) && x($a->user, 'uid') && $a->user['uid'] != local_user()) {
150                 notice(L10n::t('Permission denied.') . EOL);
151                 return;
152         }
153
154         $old_page_flags = $a->user['page-flags'];
155
156         if (($a->argc > 1) && ($a->argv[1] === 'oauth') && x($_POST, 'remove')) {
157                 check_form_security_token_redirectOnErr('/settings/oauth', 'settings_oauth');
158
159                 $key = $_POST['remove'];
160                 DBA::delete('tokens', ['id' => $key, 'uid' => local_user()]);
161                 goaway(System::baseUrl(true)."/settings/oauth/");
162                 return;
163         }
164
165         if (($a->argc > 2) && ($a->argv[1] === 'oauth')  && ($a->argv[2] === 'edit'||($a->argv[2] === 'add')) && x($_POST, 'submit')) {
166                 check_form_security_token_redirectOnErr('/settings/oauth', 'settings_oauth');
167
168                 $name     = defaults($_POST, 'name'    , '');
169                 $key      = defaults($_POST, 'key'     , '');
170                 $secret   = defaults($_POST, 'secret'  , '');
171                 $redirect = defaults($_POST, 'redirect', '');
172                 $icon     = defaults($_POST, 'icon'    , '');
173
174                 if ($name == "" || $key == "" || $secret == "") {
175                         notice(L10n::t("Missing some important data!"));
176                 } else {
177                         if ($_POST['submit'] == L10n::t("Update")) {
178                                 q("UPDATE clients SET
179                                                         client_id='%s',
180                                                         pw='%s',
181                                                         name='%s',
182                                                         redirect_uri='%s',
183                                                         icon='%s',
184                                                         uid=%d
185                                                 WHERE client_id='%s'",
186                                         DBA::escape($key),
187                                         DBA::escape($secret),
188                                         DBA::escape($name),
189                                         DBA::escape($redirect),
190                                         DBA::escape($icon),
191                                         local_user(),
192                                         DBA::escape($key)
193                                 );
194                         } else {
195                                 q("INSERT INTO clients
196                                                         (client_id, pw, name, redirect_uri, icon, uid)
197                                                 VALUES ('%s', '%s', '%s', '%s', '%s',%d)",
198                                         DBA::escape($key),
199                                         DBA::escape($secret),
200                                         DBA::escape($name),
201                                         DBA::escape($redirect),
202                                         DBA::escape($icon),
203                                         local_user()
204                                 );
205                         }
206                 }
207                 goaway(System::baseUrl(true)."/settings/oauth/");
208                 return;
209         }
210
211         if (($a->argc > 1) && ($a->argv[1] == 'addon')) {
212                 check_form_security_token_redirectOnErr('/settings/addon', 'settings_addon');
213
214                 Addon::callHooks('addon_settings_post', $_POST);
215                 return;
216         }
217
218         if (($a->argc > 1) && ($a->argv[1] == 'connectors')) {
219                 check_form_security_token_redirectOnErr('/settings/connectors', 'settings_connectors');
220
221                 if (x($_POST, 'general-submit')) {
222                         PConfig::set(local_user(), 'system', 'disable_cw', intval($_POST['disable_cw']));
223                         PConfig::set(local_user(), 'system', 'no_intelligent_shortening', intval($_POST['no_intelligent_shortening']));
224                         PConfig::set(local_user(), 'system', 'ostatus_autofriend', intval($_POST['snautofollow']));
225                         PConfig::set(local_user(), 'ostatus', 'default_group', $_POST['group-selection']);
226                         PConfig::set(local_user(), 'ostatus', 'legacy_contact', $_POST['legacy_contact']);
227                 } elseif (x($_POST, 'imap-submit')) {
228
229                         $mail_server       = ((x($_POST, 'mail_server')) ? $_POST['mail_server'] : '');
230                         $mail_port         = ((x($_POST, 'mail_port')) ? $_POST['mail_port'] : '');
231                         $mail_ssl          = ((x($_POST, 'mail_ssl')) ? strtolower(trim($_POST['mail_ssl'])) : '');
232                         $mail_user         = ((x($_POST, 'mail_user')) ? $_POST['mail_user'] : '');
233                         $mail_pass         = ((x($_POST, 'mail_pass')) ? trim($_POST['mail_pass']) : '');
234                         $mail_action       = ((x($_POST, 'mail_action')) ? trim($_POST['mail_action']) : '');
235                         $mail_movetofolder = ((x($_POST, 'mail_movetofolder')) ? trim($_POST['mail_movetofolder']) : '');
236                         $mail_replyto      = ((x($_POST, 'mail_replyto')) ? $_POST['mail_replyto'] : '');
237                         $mail_pubmail      = ((x($_POST, 'mail_pubmail')) ? $_POST['mail_pubmail'] : '');
238
239
240                         $mail_disabled = ((function_exists('imap_open') && (!Config::get('system', 'imap_disabled'))) ? 0 : 1);
241                         if (Config::get('system', 'dfrn_only')) {
242                                 $mail_disabled = 1;
243                         }
244
245                         if (!$mail_disabled) {
246                                 $failed = false;
247                                 $r = q("SELECT * FROM `mailacct` WHERE `uid` = %d LIMIT 1",
248                                         intval(local_user())
249                                 );
250                                 if (!DBA::isResult($r)) {
251                                         DBA::insert('mailacct', ['uid' => local_user()]);
252                                 }
253                                 if (strlen($mail_pass)) {
254                                         $pass = '';
255                                         openssl_public_encrypt($mail_pass, $pass, $a->user['pubkey']);
256                                         DBA::update('mailacct', ['pass' => bin2hex($pass)], ['uid' => local_user()]);
257                                 }
258                                 $r = q("UPDATE `mailacct` SET `server` = '%s', `port` = %d, `ssltype` = '%s', `user` = '%s',
259                                         `action` = %d, `movetofolder` = '%s',
260                                         `mailbox` = 'INBOX', `reply_to` = '%s', `pubmail` = %d WHERE `uid` = %d",
261                                         DBA::escape($mail_server),
262                                         intval($mail_port),
263                                         DBA::escape($mail_ssl),
264                                         DBA::escape($mail_user),
265                                         intval($mail_action),
266                                         DBA::escape($mail_movetofolder),
267                                         DBA::escape($mail_replyto),
268                                         intval($mail_pubmail),
269                                         intval(local_user())
270                                 );
271                                 logger("mail: updating mailaccount. Response: ".print_r($r, true));
272                                 $r = q("SELECT * FROM `mailacct` WHERE `uid` = %d LIMIT 1",
273                                         intval(local_user())
274                                 );
275                                 if (DBA::isResult($r)) {
276                                         $eacct = $r[0];
277                                         $mb = Email::constructMailboxName($eacct);
278
279                                         if (strlen($eacct['server'])) {
280                                                 $dcrpass = '';
281                                                 openssl_private_decrypt(hex2bin($eacct['pass']), $dcrpass, $a->user['prvkey']);
282                                                 $mbox = Email::connect($mb, $mail_user, $dcrpass);
283                                                 unset($dcrpass);
284                                                 if (!$mbox) {
285                                                         $failed = true;
286                                                         notice(L10n::t('Failed to connect with email account using the settings provided.') . EOL);
287                                                 }
288                                         }
289                                 }
290                                 if (!$failed) {
291                                         info(L10n::t('Email settings updated.') . EOL);
292                                 }
293                         }
294                 }
295
296                 Addon::callHooks('connector_settings_post', $_POST);
297                 return;
298         }
299
300         if (($a->argc > 1) && ($a->argv[1] === 'features')) {
301                 check_form_security_token_redirectOnErr('/settings/features', 'settings_features');
302                 foreach ($_POST as $k => $v) {
303                         if (strpos($k, 'feature_') === 0) {
304                                 PConfig::set(local_user(), 'feature', substr($k, 8), ((intval($v)) ? 1 : 0));
305                         }
306                 }
307                 info(L10n::t('Features updated') . EOL);
308                 return;
309         }
310
311         if (($a->argc > 1) && ($a->argv[1] === 'display')) {
312                 check_form_security_token_redirectOnErr('/settings/display', 'settings_display');
313
314                 $theme             = x($_POST, 'theme')             ? notags(trim($_POST['theme']))        : $a->user['theme'];
315                 $mobile_theme      = x($_POST, 'mobile_theme')      ? notags(trim($_POST['mobile_theme'])) : '';
316                 $nosmile           = x($_POST, 'nosmile')           ? intval($_POST['nosmile'])            : 0;
317                 $first_day_of_week = x($_POST, 'first_day_of_week') ? intval($_POST['first_day_of_week'])  : 0;
318                 $noinfo            = x($_POST, 'noinfo')            ? intval($_POST['noinfo'])             : 0;
319                 $infinite_scroll   = x($_POST, 'infinite_scroll')   ? intval($_POST['infinite_scroll'])    : 0;
320                 $no_auto_update    = x($_POST, 'no_auto_update')    ? intval($_POST['no_auto_update'])     : 0;
321                 $bandwidth_saver   = x($_POST, 'bandwidth_saver')   ? intval($_POST['bandwidth_saver'])    : 0;
322                 $smart_threading   = x($_POST, 'smart_threading')   ? intval($_POST['smart_threading'])    : 0;
323                 $nowarn_insecure   = x($_POST, 'nowarn_insecure')   ? intval($_POST['nowarn_insecure'])    : 0;
324                 $browser_update    = x($_POST, 'browser_update')    ? intval($_POST['browser_update'])     : 0;
325                 if ($browser_update != -1) {
326                         $browser_update = $browser_update * 1000;
327                         if ($browser_update < 10000) {
328                                 $browser_update = 10000;
329                         }
330                 }
331
332                 $itemspage_network = x($_POST, 'itemspage_network')  ? intval($_POST['itemspage_network'])  : 40;
333                 if ($itemspage_network > 100) {
334                         $itemspage_network = 100;
335                 }
336                 $itemspage_mobile_network = x($_POST, 'itemspage_mobile_network') ? intval($_POST['itemspage_mobile_network']) : 20;
337                 if ($itemspage_mobile_network > 100) {
338                         $itemspage_mobile_network = 100;
339                 }
340
341                 if ($mobile_theme !== '') {
342                         PConfig::set(local_user(), 'system', 'mobile_theme', $mobile_theme);
343                 }
344
345                 PConfig::set(local_user(), 'system', 'nowarn_insecure'         , $nowarn_insecure);
346                 PConfig::set(local_user(), 'system', 'update_interval'         , $browser_update);
347                 PConfig::set(local_user(), 'system', 'itemspage_network'       , $itemspage_network);
348                 PConfig::set(local_user(), 'system', 'itemspage_mobile_network', $itemspage_mobile_network);
349                 PConfig::set(local_user(), 'system', 'no_smilies'              , $nosmile);
350                 PConfig::set(local_user(), 'system', 'first_day_of_week'       , $first_day_of_week);
351                 PConfig::set(local_user(), 'system', 'ignore_info'             , $noinfo);
352                 PConfig::set(local_user(), 'system', 'infinite_scroll'         , $infinite_scroll);
353                 PConfig::set(local_user(), 'system', 'no_auto_update'          , $no_auto_update);
354                 PConfig::set(local_user(), 'system', 'bandwidth_saver'         , $bandwidth_saver);
355                 PConfig::set(local_user(), 'system', 'smart_threading'         , $smart_threading);
356
357                 if ($theme == $a->user['theme']) {
358                         // call theme_post only if theme has not been changed
359                         if (($themeconfigfile = get_theme_config_file($theme)) !== null) {
360                                 require_once $themeconfigfile;
361                                 theme_post($a);
362                         }
363                 }
364                 Theme::install($theme);
365
366                 $r = q("UPDATE `user` SET `theme` = '%s' WHERE `uid` = %d",
367                                 DBA::escape($theme),
368                                 intval(local_user())
369                 );
370
371                 Addon::callHooks('display_settings_post', $_POST);
372                 goaway('settings/display');
373                 return; // NOTREACHED
374         }
375
376         check_form_security_token_redirectOnErr('/settings', 'settings');
377
378         if (x($_POST,'resend_relocate')) {
379                 Worker::add(PRIORITY_HIGH, 'Notifier', 'relocate', local_user());
380                 info(L10n::t("Relocate message has been send to your contacts"));
381                 goaway('settings');
382         }
383
384         Addon::callHooks('settings_post', $_POST);
385
386         if (x($_POST, 'password') || x($_POST, 'confirm')) {
387                 $newpass = $_POST['password'];
388                 $confirm = $_POST['confirm'];
389
390                 $err = false;
391                 if ($newpass != $confirm) {
392                         notice(L10n::t('Passwords do not match. Password unchanged.') . EOL);
393                         $err = true;
394                 }
395
396                 if (!x($newpass) || !x($confirm)) {
397                         notice(L10n::t('Empty passwords are not allowed. Password unchanged.') . EOL);
398                         $err = true;
399                 }
400
401                 if (!Config::get('system', 'disable_password_exposed', false) && User::isPasswordExposed($newpass)) {
402                         notice(L10n::t('The new password has been exposed in a public data dump, please choose another.') . EOL);
403                         $err = true;
404                 }
405
406                 //  check if the old password was supplied correctly before changing it to the new value
407                 if (!User::authenticate(intval(local_user()), $_POST['opassword'])) {
408                         notice(L10n::t('Wrong password.') . EOL);
409                         $err = true;
410                 }
411
412                 if (!$err) {
413                         $result = User::updatePassword(local_user(), $newpass);
414                         if (DBA::isResult($result)) {
415                                 info(L10n::t('Password changed.') . EOL);
416                         } else {
417                                 notice(L10n::t('Password update failed. Please try again.') . EOL);
418                         }
419                 }
420         }
421
422         $username         = ((x($_POST, 'username'))   ? notags(trim($_POST['username']))     : '');
423         $email            = ((x($_POST, 'email'))      ? notags(trim($_POST['email']))        : '');
424         $timezone         = ((x($_POST, 'timezone'))   ? notags(trim($_POST['timezone']))     : '');
425         $language         = ((x($_POST, 'language'))   ? notags(trim($_POST['language']))     : '');
426
427         $defloc           = ((x($_POST, 'defloc'))     ? notags(trim($_POST['defloc']))       : '');
428         $openid           = ((x($_POST, 'openid_url')) ? notags(trim($_POST['openid_url']))   : '');
429         $maxreq           = ((x($_POST, 'maxreq'))     ? intval($_POST['maxreq'])             : 0);
430         $expire           = ((x($_POST, 'expire'))     ? intval($_POST['expire'])             : 0);
431         $def_gid          = ((x($_POST, 'group-selection')) ? intval($_POST['group-selection']) : 0);
432
433
434         $expire_items     = ((x($_POST, 'expire_items')) ? intval($_POST['expire_items'])        : 0);
435         $expire_notes     = ((x($_POST, 'expire_notes')) ? intval($_POST['expire_notes'])        : 0);
436         $expire_starred   = ((x($_POST, 'expire_starred')) ? intval($_POST['expire_starred']) : 0);
437         $expire_photos    = ((x($_POST, 'expire_photos'))? intval($_POST['expire_photos'])       : 0);
438         $expire_network_only    = ((x($_POST, 'expire_network_only'))? intval($_POST['expire_network_only'])     : 0);
439
440         $allow_location   = (((x($_POST, 'allow_location')) && (intval($_POST['allow_location']) == 1)) ? 1: 0);
441         $publish          = (((x($_POST, 'profile_in_directory')) && (intval($_POST['profile_in_directory']) == 1)) ? 1: 0);
442         $net_publish      = (((x($_POST, 'profile_in_netdirectory')) && (intval($_POST['profile_in_netdirectory']) == 1)) ? 1: 0);
443         $old_visibility   = (((x($_POST, 'visibility')) && (intval($_POST['visibility']) == 1)) ? 1 : 0);
444         $account_type     = (((x($_POST, 'account-type')) && (intval($_POST['account-type']))) ? intval($_POST['account-type']) : 0);
445         $page_flags       = (((x($_POST, 'page-flags')) && (intval($_POST['page-flags']))) ? intval($_POST['page-flags']) : 0);
446         $blockwall        = (((x($_POST, 'blockwall')) && (intval($_POST['blockwall']) == 1)) ? 0: 1); // this setting is inverted!
447         $blocktags        = (((x($_POST, 'blocktags')) && (intval($_POST['blocktags']) == 1)) ? 0: 1); // this setting is inverted!
448         $unkmail          = (((x($_POST, 'unkmail')) && (intval($_POST['unkmail']) == 1)) ? 1: 0);
449         $cntunkmail       = ((x($_POST, 'cntunkmail')) ? intval($_POST['cntunkmail']) : 0);
450         $suggestme        = ((x($_POST, 'suggestme')) ? intval($_POST['suggestme'])  : 0);
451         $hide_friends     = (($_POST['hide-friends'] == 1) ? 1: 0);
452         $hidewall         = (($_POST['hidewall'] == 1) ? 1: 0);
453
454         $email_textonly   = (($_POST['email_textonly'] == 1) ? 1 : 0);
455         $detailed_notif   = (($_POST['detailed_notif'] == 1) ? 1 : 0);
456
457         $notify = 0;
458
459         if (x($_POST, 'notify1')) {
460                 $notify += intval($_POST['notify1']);
461         }
462         if (x($_POST, 'notify2')) {
463                 $notify += intval($_POST['notify2']);
464         }
465         if (x($_POST, 'notify3')) {
466                 $notify += intval($_POST['notify3']);
467         }
468         if (x($_POST, 'notify4')) {
469                 $notify += intval($_POST['notify4']);
470         }
471         if (x($_POST, 'notify5')) {
472                 $notify += intval($_POST['notify5']);
473         }
474         if (x($_POST, 'notify6')) {
475                 $notify += intval($_POST['notify6']);
476         }
477         if (x($_POST, 'notify7')) {
478                 $notify += intval($_POST['notify7']);
479         }
480         if (x($_POST, 'notify8')) {
481                 $notify += intval($_POST['notify8']);
482         }
483
484         // Adjust the page flag if the account type doesn't fit to the page flag.
485         if (($account_type == Contact::ACCOUNT_TYPE_PERSON) && !in_array($page_flags, [Contact::PAGE_NORMAL, Contact::PAGE_SOAPBOX, Contact::PAGE_FREELOVE])) {
486                 $page_flags = Contact::PAGE_NORMAL;
487         } elseif (($account_type == Contact::ACCOUNT_TYPE_ORGANISATION) && !in_array($page_flags, [Contact::PAGE_SOAPBOX])) {
488                 $page_flags = Contact::PAGE_SOAPBOX;
489         } elseif (($account_type == Contact::ACCOUNT_TYPE_NEWS) && !in_array($page_flags, [Contact::PAGE_SOAPBOX])) {
490                 $page_flags = Contact::PAGE_SOAPBOX;
491         } elseif (($account_type == Contact::ACCOUNT_TYPE_COMMUNITY) && !in_array($page_flags, [Contact::PAGE_COMMUNITY, Contact::PAGE_PRVGROUP])) {
492                 $page_flags = Contact::PAGE_COMMUNITY;
493         }
494
495         $email_changed = false;
496
497         $err = '';
498
499         if ($username != $a->user['username']) {
500                 if (strlen($username) > 40) {
501                         $err .= L10n::t(' Please use a shorter name.');
502                 }
503                 if (strlen($username) < 3) {
504                         $err .= L10n::t(' Name too short.');
505                 }
506         }
507
508         if ($email != $a->user['email']) {
509                 $email_changed = true;
510                 //  check for the correct password
511                 if (!User::authenticate(intval(local_user()), $_POST['mpassword'])) {
512                         $err .= L10n::t('Wrong Password') . EOL;
513                         $email = $a->user['email'];
514                 }
515                 //  check the email is valid
516                 if (!valid_email($email)) {
517                         $err .= L10n::t('Invalid email.');
518                 }
519                 //  ensure new email is not the admin mail
520                 if (Config::get('config', 'admin_email')) {
521                         $adminlist = explode(",", str_replace(" ", "", strtolower(Config::get('config', 'admin_email'))));
522                         if (in_array(strtolower($email), $adminlist)) {
523                                 $err .= L10n::t('Cannot change to that email.');
524                                 $email = $a->user['email'];
525                         }
526                 }
527         }
528
529         if (strlen($err)) {
530                 notice($err . EOL);
531                 return;
532         }
533
534         if (($timezone != $a->user['timezone']) && strlen($timezone)) {
535                 date_default_timezone_set($timezone);
536         }
537
538         $str_group_allow   = !empty($_POST['group_allow'])   ? perms2str($_POST['group_allow'])   : '';
539         $str_contact_allow = !empty($_POST['contact_allow']) ? perms2str($_POST['contact_allow']) : '';
540         $str_group_deny    = !empty($_POST['group_deny'])    ? perms2str($_POST['group_deny'])    : '';
541         $str_contact_deny  = !empty($_POST['contact_deny'])  ? perms2str($_POST['contact_deny'])  : '';
542
543         $openidserver = $a->user['openidserver'];
544         //$openid = normalise_openid($openid);
545
546         // If openid has changed or if there's an openid but no openidserver, try and discover it.
547         if ($openid != $a->user['openid'] || (strlen($openid) && (!strlen($openidserver)))) {
548                 if (Network::isUrlValid($openid)) {
549                         logger('updating openidserver');
550                         $open_id_obj = new LightOpenID($a->getHostName());
551                         $open_id_obj->identity = $openid;
552                         $openidserver = $open_id_obj->discover($open_id_obj->identity);
553                 } else {
554                         $openidserver = '';
555                 }
556         }
557
558         PConfig::set(local_user(), 'expire', 'items', $expire_items);
559         PConfig::set(local_user(), 'expire', 'notes', $expire_notes);
560         PConfig::set(local_user(), 'expire', 'starred', $expire_starred);
561         PConfig::set(local_user(), 'expire', 'photos', $expire_photos);
562         PConfig::set(local_user(), 'expire', 'network_only', $expire_network_only);
563
564         PConfig::set(local_user(), 'system', 'suggestme', $suggestme);
565
566         PConfig::set(local_user(), 'system', 'email_textonly', $email_textonly);
567         PConfig::set(local_user(), 'system', 'detailed_notif', $detailed_notif);
568
569         if ($page_flags == Contact::PAGE_PRVGROUP) {
570                 $hidewall = 1;
571                 if (!$str_contact_allow && !$str_group_allow && !$str_contact_deny && !$str_group_deny) {
572                         if ($def_gid) {
573                                 info(L10n::t('Private forum has no privacy permissions. Using default privacy group.'). EOL);
574                                 $str_group_allow = '<' . $def_gid . '>';
575                         } else {
576                                 notice(L10n::t('Private forum has no privacy permissions and no default privacy group.') . EOL);
577                         }
578                 }
579         }
580
581
582         $r = q("UPDATE `user` SET `username` = '%s', `email` = '%s',
583                                 `openid` = '%s', `timezone` = '%s',
584                                 `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s',
585                                 `notify-flags` = %d, `page-flags` = %d, `account-type` = %d, `default-location` = '%s',
586                                 `allow_location` = %d, `maxreq` = %d, `expire` = %d, `openidserver` = '%s',
587                                 `def_gid` = %d, `blockwall` = %d, `hidewall` = %d, `blocktags` = %d,
588                                 `unkmail` = %d, `cntunkmail` = %d, `language` = '%s'
589                         WHERE `uid` = %d",
590                         DBA::escape($username),
591                         DBA::escape($email),
592                         DBA::escape($openid),
593                         DBA::escape($timezone),
594                         DBA::escape($str_contact_allow),
595                         DBA::escape($str_group_allow),
596                         DBA::escape($str_contact_deny),
597                         DBA::escape($str_group_deny),
598                         intval($notify),
599                         intval($page_flags),
600                         intval($account_type),
601                         DBA::escape($defloc),
602                         intval($allow_location),
603                         intval($maxreq),
604                         intval($expire),
605                         DBA::escape($openidserver),
606                         intval($def_gid),
607                         intval($blockwall),
608                         intval($hidewall),
609                         intval($blocktags),
610                         intval($unkmail),
611                         intval($cntunkmail),
612                         DBA::escape($language),
613                         intval(local_user())
614         );
615         if (DBA::isResult($r)) {
616                 info(L10n::t('Settings updated.') . EOL);
617         }
618
619         // clear session language
620         unset($_SESSION['language']);
621
622         $r = q("UPDATE `profile`
623                 SET `publish` = %d,
624                 `name` = '%s',
625                 `net-publish` = %d,
626                 `hide-friends` = %d
627                 WHERE `is-default` = 1 AND `uid` = %d",
628                 intval($publish),
629                 DBA::escape($username),
630                 intval($net_publish),
631                 intval($hide_friends),
632                 intval(local_user())
633         );
634
635         Contact::updateSelfFromUserID(local_user());
636
637         if (($old_visibility != $net_publish) || ($page_flags != $old_page_flags)) {
638                 // Update global directory in background
639                 $url = $_SESSION['my_url'];
640                 if ($url && strlen(Config::get('system', 'directory'))) {
641                         Worker::add(PRIORITY_LOW, "Directory", $url);
642                 }
643         }
644
645         Worker::add(PRIORITY_LOW, 'ProfileUpdate', local_user());
646
647         // Update the global contact for the user
648         GContact::updateForUser(local_user());
649
650         goaway('settings');
651         return; // NOTREACHED
652 }
653
654
655 function settings_content(App $a)
656 {
657         $o = '';
658         Nav::setSelected('settings');
659
660         if (!local_user()) {
661                 //notice(L10n::t('Permission denied.') . EOL);
662                 return Login::form();
663         }
664
665         if (x($_SESSION, 'submanage') && intval($_SESSION['submanage'])) {
666                 notice(L10n::t('Permission denied.') . EOL);
667                 return;
668         }
669
670         if (($a->argc > 1) && ($a->argv[1] === 'oauth')) {
671                 if (($a->argc > 2) && ($a->argv[2] === 'add')) {
672                         $tpl = get_markup_template('settings/oauth_edit.tpl');
673                         $o .= replace_macros($tpl, [
674                                 '$form_security_token' => get_form_security_token("settings_oauth"),
675                                 '$title'        => L10n::t('Add application'),
676                                 '$submit'       => L10n::t('Save Settings'),
677                                 '$cancel'       => L10n::t('Cancel'),
678                                 '$name'         => ['name', L10n::t('Name'), '', ''],
679                                 '$key'          => ['key', L10n::t('Consumer Key'), '', ''],
680                                 '$secret'       => ['secret', L10n::t('Consumer Secret'), '', ''],
681                                 '$redirect'     => ['redirect', L10n::t('Redirect'), '', ''],
682                                 '$icon'         => ['icon', L10n::t('Icon url'), '', ''],
683                         ]);
684                         return $o;
685                 }
686
687                 if (($a->argc > 3) && ($a->argv[2] === 'edit')) {
688                         $r = q("SELECT * FROM clients WHERE client_id='%s' AND uid=%d",
689                                         DBA::escape($a->argv[3]),
690                                         local_user());
691
692                         if (!DBA::isResult($r)) {
693                                 notice(L10n::t("You can't edit this application."));
694                                 return;
695                         }
696                         $app = $r[0];
697
698                         $tpl = get_markup_template('settings/oauth_edit.tpl');
699                         $o .= replace_macros($tpl, [
700                                 '$form_security_token' => get_form_security_token("settings_oauth"),
701                                 '$title'        => L10n::t('Add application'),
702                                 '$submit'       => L10n::t('Update'),
703                                 '$cancel'       => L10n::t('Cancel'),
704                                 '$name'         => ['name', L10n::t('Name'), $app['name'] , ''],
705                                 '$key'          => ['key', L10n::t('Consumer Key'), $app['client_id'], ''],
706                                 '$secret'       => ['secret', L10n::t('Consumer Secret'), $app['pw'], ''],
707                                 '$redirect'     => ['redirect', L10n::t('Redirect'), $app['redirect_uri'], ''],
708                                 '$icon'         => ['icon', L10n::t('Icon url'), $app['icon'], ''],
709                         ]);
710                         return $o;
711                 }
712
713                 if (($a->argc > 3) && ($a->argv[2] === 'delete')) {
714                         check_form_security_token_redirectOnErr('/settings/oauth', 'settings_oauth', 't');
715
716                         DBA::delete('clients', ['client_id' => $a->argv[3], 'uid' => local_user()]);
717                         goaway(System::baseUrl(true)."/settings/oauth/");
718                         return;
719                 }
720
721                 /// @TODO validate result with DBA::isResult()
722                 $r = q("SELECT clients.*, tokens.id as oauth_token, (clients.uid=%d) AS my
723                                 FROM clients
724                                 LEFT JOIN tokens ON clients.client_id=tokens.client_id
725                                 WHERE clients.uid IN (%d, 0)",
726                                 local_user(),
727                                 local_user());
728
729
730                 $tpl = get_markup_template('settings/oauth.tpl');
731                 $o .= replace_macros($tpl, [
732                         '$form_security_token' => get_form_security_token("settings_oauth"),
733                         '$baseurl'      => System::baseUrl(true),
734                         '$title'        => L10n::t('Connected Apps'),
735                         '$add'          => L10n::t('Add application'),
736                         '$edit'         => L10n::t('Edit'),
737                         '$delete'               => L10n::t('Delete'),
738                         '$consumerkey' => L10n::t('Client key starts with'),
739                         '$noname'       => L10n::t('No name'),
740                         '$remove'       => L10n::t('Remove authorization'),
741                         '$apps'         => $r,
742                 ]);
743                 return $o;
744         }
745
746         if (($a->argc > 1) && ($a->argv[1] === 'addon')) {
747                 $settings_addons = "";
748
749                 $r = q("SELECT * FROM `hook` WHERE `hook` = 'addon_settings' ");
750                 if (!DBA::isResult($r)) {
751                         $settings_addons = L10n::t('No Addon settings configured');
752                 }
753
754                 Addon::callHooks('addon_settings', $settings_addons);
755
756
757                 $tpl = get_markup_template('settings/addons.tpl');
758                 $o .= replace_macros($tpl, [
759                         '$form_security_token' => get_form_security_token("settings_addon"),
760                         '$title'        => L10n::t('Addon Settings'),
761                         '$settings_addons' => $settings_addons
762                 ]);
763                 return $o;
764         }
765
766         if (($a->argc > 1) && ($a->argv[1] === 'features')) {
767
768                 $arr = [];
769                 $features = Feature::get();
770                 foreach ($features as $fname => $fdata) {
771                         $arr[$fname] = [];
772                         $arr[$fname][0] = $fdata[0];
773                         foreach (array_slice($fdata,1) as $f) {
774                                 $arr[$fname][1][] = ['feature_' .$f[0], $f[1],((intval(Feature::isEnabled(local_user(), $f[0]))) ? "1" : ''), $f[2],[L10n::t('Off'), L10n::t('On')]];
775                         }
776                 }
777
778                 $tpl = get_markup_template('settings/features.tpl');
779                 $o .= replace_macros($tpl, [
780                         '$form_security_token' => get_form_security_token("settings_features"),
781                         '$title'               => L10n::t('Additional Features'),
782                         '$features'            => $arr,
783                         '$submit'              => L10n::t('Save Settings'),
784                 ]);
785                 return $o;
786         }
787
788         if (($a->argc > 1) && ($a->argv[1] === 'connectors')) {
789                 $disable_cw                = intval(PConfig::get(local_user(), 'system', 'disable_cw'));
790                 $no_intelligent_shortening = intval(PConfig::get(local_user(), 'system', 'no_intelligent_shortening'));
791                 $ostatus_autofriend        = intval(PConfig::get(local_user(), 'system', 'ostatus_autofriend'));
792                 $default_group             = PConfig::get(local_user(), 'ostatus', 'default_group');
793                 $legacy_contact            = PConfig::get(local_user(), 'ostatus', 'legacy_contact');
794
795                 if (x($legacy_contact)) {
796                         /// @todo Isn't it supposed to be a goaway() call?
797                         $a->page['htmlhead'] = '<meta http-equiv="refresh" content="0; URL=' . System::baseUrl().'/ostatus_subscribe?url=' . urlencode($legacy_contact) . '">';
798                 }
799
800                 $settings_connectors = '';
801                 Addon::callHooks('connector_settings', $settings_connectors);
802
803                 if (is_site_admin()) {
804                         $diasp_enabled = L10n::t('Built-in support for %s connectivity is %s', L10n::t('Diaspora'), ((Config::get('system', 'diaspora_enabled')) ? L10n::t('enabled') : L10n::t('disabled')));
805                         $ostat_enabled = L10n::t('Built-in support for %s connectivity is %s', L10n::t("GNU Social \x28OStatus\x29"), ((Config::get('system', 'ostatus_disabled')) ? L10n::t('disabled') : L10n::t('enabled')));
806                 } else {
807                         $diasp_enabled = "";
808                         $ostat_enabled = "";
809                 }
810
811                 $mail_disabled = ((function_exists('imap_open') && (!Config::get('system', 'imap_disabled'))) ? 0 : 1);
812                 if (Config::get('system', 'dfrn_only')) {
813                         $mail_disabled = 1;
814                 }
815                 if (!$mail_disabled) {
816                         $r = q("SELECT * FROM `mailacct` WHERE `uid` = %d LIMIT 1",
817                                 local_user()
818                         );
819                 } else {
820                         $r = null;
821                 }
822
823                 $mail_server       = ((DBA::isResult($r)) ? $r[0]['server'] : '');
824                 $mail_port         = ((DBA::isResult($r) && intval($r[0]['port'])) ? intval($r[0]['port']) : '');
825                 $mail_ssl          = ((DBA::isResult($r)) ? $r[0]['ssltype'] : '');
826                 $mail_user         = ((DBA::isResult($r)) ? $r[0]['user'] : '');
827                 $mail_replyto      = ((DBA::isResult($r)) ? $r[0]['reply_to'] : '');
828                 $mail_pubmail      = ((DBA::isResult($r)) ? $r[0]['pubmail'] : 0);
829                 $mail_action       = ((DBA::isResult($r)) ? $r[0]['action'] : 0);
830                 $mail_movetofolder = ((DBA::isResult($r)) ? $r[0]['movetofolder'] : '');
831                 $mail_chk          = ((DBA::isResult($r)) ? $r[0]['last_check'] : NULL_DATE);
832
833
834                 $tpl = get_markup_template('settings/connectors.tpl');
835
836                 $mail_disabled_message = (($mail_disabled) ? L10n::t('Email access is disabled on this site.') : '');
837
838                 $o .= replace_macros($tpl, [
839                         '$form_security_token' => get_form_security_token("settings_connectors"),
840
841                         '$title'        => L10n::t('Social Networks'),
842
843                         '$diasp_enabled' => $diasp_enabled,
844                         '$ostat_enabled' => $ostat_enabled,
845
846                         '$general_settings' => L10n::t('General Social Media Settings'),
847                         '$disable_cw' => ['disable_cw', L10n::t('Disable Content Warning'), $disable_cw, L10n::t('Users on networks like Mastodon or Pleroma are able to set a content warning field which collapse their post by default. This disables the automatic collapsing and sets the content warning as the post title. Doesn\'t affect any other content filtering you eventually set up.')],
848                         '$no_intelligent_shortening' => ['no_intelligent_shortening', L10n::t('Disable intelligent shortening'), $no_intelligent_shortening, L10n::t('Normally the system tries to find the best link to add to shortened posts. If this option is enabled then every shortened post will always point to the original friendica post.')],
849                         '$ostatus_autofriend' => ['snautofollow', L10n::t("Automatically follow any GNU Social \x28OStatus\x29 followers/mentioners"), $ostatus_autofriend, L10n::t('If you receive a message from an unknown OStatus user, this option decides what to do. If it is checked, a new contact will be created for every unknown user.')],
850                         '$default_group' => Group::displayGroupSelection(local_user(), $default_group, L10n::t("Default group for OStatus contacts")),
851                         '$legacy_contact' => ['legacy_contact', L10n::t('Your legacy GNU Social account'), $legacy_contact, L10n::t("If you enter your old GNU Social/Statusnet account name here \x28in the format user@domain.tld\x29, your contacts will be added automatically. The field will be emptied when done.")],
852
853                         '$repair_ostatus_url' => System::baseUrl() . '/repair_ostatus',
854                         '$repair_ostatus_text' => L10n::t('Repair OStatus subscriptions'),
855
856                         '$settings_connectors' => $settings_connectors,
857
858                         '$h_imap' => L10n::t('Email/Mailbox Setup'),
859                         '$imap_desc' => L10n::t("If you wish to communicate with email contacts using this service \x28optional\x29, please specify how to connect to your mailbox."),
860                         '$imap_lastcheck' => ['imap_lastcheck', L10n::t('Last successful email check:'), $mail_chk, ''],
861                         '$mail_disabled' => $mail_disabled_message,
862                         '$mail_server'  => ['mail_server',  L10n::t('IMAP server name:'), $mail_server, ''],
863                         '$mail_port'    => ['mail_port',         L10n::t('IMAP port:'), $mail_port, ''],
864                         '$mail_ssl'             => ['mail_ssl',          L10n::t('Security:'), strtoupper($mail_ssl), '', ['notls'=>L10n::t('None'), 'TLS'=>'TLS', 'SSL'=>'SSL']],
865                         '$mail_user'    => ['mail_user',    L10n::t('Email login name:'), $mail_user, ''],
866                         '$mail_pass'    => ['mail_pass',         L10n::t('Email password:'), '', ''],
867                         '$mail_replyto' => ['mail_replyto', L10n::t('Reply-to address:'), $mail_replyto, 'Optional'],
868                         '$mail_pubmail' => ['mail_pubmail', L10n::t('Send public posts to all email contacts:'), $mail_pubmail, ''],
869                         '$mail_action'  => ['mail_action',       L10n::t('Action after import:'), $mail_action, '', [0=>L10n::t('None'), /*1=>L10n::t('Delete'),*/ 2=>L10n::t('Mark as seen'), 3=>L10n::t('Move to folder')]],
870                         '$mail_movetofolder'    => ['mail_movetofolder',         L10n::t('Move to folder:'), $mail_movetofolder, ''],
871                         '$submit' => L10n::t('Save Settings'),
872                 ]);
873
874                 Addon::callHooks('display_settings', $o);
875                 return $o;
876         }
877
878         /*
879          * DISPLAY SETTINGS
880          */
881         if (($a->argc > 1) && ($a->argv[1] === 'display')) {
882                 $default_theme = Config::get('system', 'theme');
883                 if (!$default_theme) {
884                         $default_theme = 'default';
885                 }
886                 $default_mobile_theme = Config::get('system', 'mobile-theme');
887                 if (!$default_mobile_theme) {
888                         $default_mobile_theme = 'none';
889                 }
890
891                 $allowed_themes_str = Config::get('system', 'allowed_themes');
892                 $allowed_themes_raw = explode(',', $allowed_themes_str);
893                 $allowed_themes = [];
894                 if (count($allowed_themes_raw)) {
895                         foreach ($allowed_themes_raw as $x) {
896                                 if (strlen(trim($x)) && is_dir("view/theme/$x")) {
897                                         $allowed_themes[] = trim($x);
898                                 }
899                         }
900                 }
901
902
903                 $themes = [];
904                 $mobile_themes = ["---" => L10n::t('No special theme for mobile devices')];
905                 if ($allowed_themes) {
906                         foreach ($allowed_themes as $theme) {
907                                 $is_experimental = file_exists('view/theme/' . $theme . '/experimental');
908                                 $is_unsupported  = file_exists('view/theme/' . $theme . '/unsupported');
909                                 $is_mobile       = file_exists('view/theme/' . $theme . '/mobile');
910                                 if (!$is_experimental || ($is_experimental && (Config::get('experimentals', 'exp_themes')==1 || is_null(Config::get('experimentals', 'exp_themes'))))) {
911                                         $theme_name = ucfirst($theme);
912                                         if ($is_unsupported) {
913                                                 $theme_name = L10n::t("%s - \x28Unsupported\x29", $theme_name);
914                                         } elseif ($is_experimental) {
915                                                 $theme_name = L10n::t("%s - \x28Experimental\x29", $theme_name);
916                                         }
917                                         if ($is_mobile) {
918                                                 $mobile_themes[$theme] = $theme_name;
919                                         } else {
920                                                 $themes[$theme] = $theme_name;
921                                         }
922                                 }
923                         }
924                 }
925                 $theme_selected        = defaults($_SESSION, 'theme'       , $default_theme);
926                 $mobile_theme_selected = defaults($_SESSION, 'mobile-theme', $default_mobile_theme);
927
928                 $nowarn_insecure = intval(PConfig::get(local_user(), 'system', 'nowarn_insecure'));
929
930                 $browser_update = intval(PConfig::get(local_user(), 'system', 'update_interval'));
931                 if (intval($browser_update) != -1) {
932                         $browser_update = (($browser_update == 0) ? 40 : $browser_update / 1000); // default if not set: 40 seconds
933                 }
934
935                 $itemspage_network = intval(PConfig::get(local_user(), 'system', 'itemspage_network'));
936                 $itemspage_network = (($itemspage_network > 0 && $itemspage_network < 101) ? $itemspage_network : 40); // default if not set: 40 items
937                 $itemspage_mobile_network = intval(PConfig::get(local_user(), 'system', 'itemspage_mobile_network'));
938                 $itemspage_mobile_network = (($itemspage_mobile_network > 0 && $itemspage_mobile_network < 101) ? $itemspage_mobile_network : 20); // default if not set: 20 items
939
940                 $nosmile = PConfig::get(local_user(), 'system', 'no_smilies', 0);
941                 $first_day_of_week = PConfig::get(local_user(), 'system', 'first_day_of_week', 0);
942                 $weekdays = [0 => L10n::t("Sunday"), 1 => L10n::t("Monday")];
943
944                 $noinfo = PConfig::get(local_user(), 'system', 'ignore_info', 0);
945                 $infinite_scroll = PConfig::get(local_user(), 'system', 'infinite_scroll', 0);
946                 $no_auto_update = PConfig::get(local_user(), 'system', 'no_auto_update', 0);
947                 $bandwidth_saver = PConfig::get(local_user(), 'system', 'bandwidth_saver', 0);
948                 $smart_threading = PConfig::get(local_user(), 'system', 'smart_threading', 0);
949
950                 $theme_config = "";
951                 if (($themeconfigfile = get_theme_config_file($theme_selected)) !== null) {
952                         require_once $themeconfigfile;
953                         $theme_config = theme_content($a);
954                 }
955
956                 $tpl = get_markup_template('settings/display.tpl');
957                 $o = replace_macros($tpl, [
958                         '$ptitle'       => L10n::t('Display Settings'),
959                         '$form_security_token' => get_form_security_token("settings_display"),
960                         '$submit'       => L10n::t('Save Settings'),
961                         '$baseurl' => System::baseUrl(true),
962                         '$uid' => local_user(),
963
964                         '$theme'        => ['theme', L10n::t('Display Theme:'), $theme_selected, '', $themes, true],
965                         '$mobile_theme' => ['mobile_theme', L10n::t('Mobile Theme:'), $mobile_theme_selected, '', $mobile_themes, false],
966                         '$nowarn_insecure' => ['nowarn_insecure',  L10n::t('Suppress warning of insecure networks'), $nowarn_insecure, L10n::t("Should the system suppress the warning that the current group contains members of networks that can't receive non public postings.")],
967                         '$ajaxint'   => ['browser_update',  L10n::t("Update browser every xx seconds"), $browser_update, L10n::t('Minimum of 10 seconds. Enter -1 to disable it.')],
968                         '$itemspage_network'   => ['itemspage_network',  L10n::t("Number of items to display per page:"), $itemspage_network, L10n::t('Maximum of 100 items')],
969                         '$itemspage_mobile_network'   => ['itemspage_mobile_network',  L10n::t("Number of items to display per page when viewed from mobile device:"), $itemspage_mobile_network, L10n::t('Maximum of 100 items')],
970                         '$nosmile'      => ['nosmile', L10n::t("Don't show emoticons"), $nosmile, ''],
971                         '$calendar_title' => L10n::t('Calendar'),
972                         '$first_day_of_week'    => ['first_day_of_week', L10n::t('Beginning of week:'), $first_day_of_week, '', $weekdays, false],
973                         '$noinfo'       => ['noinfo', L10n::t("Don't show notices"), $noinfo, ''],
974                         '$infinite_scroll'      => ['infinite_scroll', L10n::t("Infinite scroll"), $infinite_scroll, ''],
975                         '$no_auto_update'       => ['no_auto_update', L10n::t("Automatic updates only at the top of the network page"), $no_auto_update, L10n::t('When disabled, the network page is updated all the time, which could be confusing while reading.')],
976                         '$bandwidth_saver' => ['bandwidth_saver', L10n::t('Bandwidth Saver Mode'), $bandwidth_saver, L10n::t('When enabled, embedded content is not displayed on automatic updates, they only show on page reload.')],
977                         '$smart_threading' => ['smart_threading', L10n::t('Smart Threading'), $smart_threading, L10n::t('When enabled, suppress extraneous thread indentation while keeping it where it matters. Only works if threading is available and enabled.')],
978
979                         '$d_tset' => L10n::t('General Theme Settings'),
980                         '$d_ctset' => L10n::t('Custom Theme Settings'),
981                         '$d_cset' => L10n::t('Content Settings'),
982                         'stitle' => L10n::t('Theme settings'),
983                         '$theme_config' => $theme_config,
984                 ]);
985
986                 return $o;
987         }
988
989
990         /*
991          * ACCOUNT SETTINGS
992          */
993
994         $profile = DBA::selectFirst('profile', [], ['is-default' => true, 'uid' => local_user()]);
995         if (!DBA::isResult($profile)) {
996                 notice(L10n::t('Unable to find your profile. Please contact your admin.') . EOL);
997                 return;
998         }
999
1000         $username   = $a->user['username'];
1001         $email      = $a->user['email'];
1002         $nickname   = $a->user['nickname'];
1003         $timezone   = $a->user['timezone'];
1004         $language   = $a->user['language'];
1005         $notify     = $a->user['notify-flags'];
1006         $defloc     = $a->user['default-location'];
1007         $openid     = $a->user['openid'];
1008         $maxreq     = $a->user['maxreq'];
1009         $expire     = ((intval($a->user['expire'])) ? $a->user['expire'] : '');
1010         $unkmail    = $a->user['unkmail'];
1011         $cntunkmail = $a->user['cntunkmail'];
1012
1013         $expire_items = PConfig::get(local_user(), 'expire', 'items', true);
1014         $expire_notes = PConfig::get(local_user(), 'expire', 'notes', true);
1015         $expire_starred = PConfig::get(local_user(), 'expire', 'starred', true);
1016         $expire_photos = PConfig::get(local_user(), 'expire', 'photos', false);
1017         $expire_network_only = PConfig::get(local_user(), 'expire', 'network_only', false);
1018         $suggestme = PConfig::get(local_user(), 'system', 'suggestme', false);
1019
1020         // nowarn_insecure
1021
1022         if (!strlen($a->user['timezone'])) {
1023                 $timezone = date_default_timezone_get();
1024         }
1025
1026         // Set the account type to "Community" when the page is a community page but the account type doesn't fit
1027         // This is only happening on the first visit after the update
1028         if (in_array($a->user['page-flags'], [Contact::PAGE_COMMUNITY, Contact::PAGE_PRVGROUP]) &&
1029                 ($a->user['account-type'] != Contact::ACCOUNT_TYPE_COMMUNITY))
1030                 $a->user['account-type'] = Contact::ACCOUNT_TYPE_COMMUNITY;
1031
1032         $pageset_tpl = get_markup_template('settings/pagetypes.tpl');
1033
1034         $pagetype = replace_macros($pageset_tpl, [
1035                 '$account_types'        => L10n::t("Account Types"),
1036                 '$user'                 => L10n::t("Personal Page Subtypes"),
1037                 '$community'            => L10n::t("Community Forum Subtypes"),
1038                 '$account_type'         => $a->user['account-type'],
1039                 '$type_person'          => Contact::ACCOUNT_TYPE_PERSON,
1040                 '$type_organisation'    => Contact::ACCOUNT_TYPE_ORGANISATION,
1041                 '$type_news'            => Contact::ACCOUNT_TYPE_NEWS,
1042                 '$type_community'       => Contact::ACCOUNT_TYPE_COMMUNITY,
1043
1044                 '$account_person'       => ['account-type', L10n::t('Personal Page'), Contact::ACCOUNT_TYPE_PERSON,
1045                                                                         L10n::t('Account for a personal profile.'),
1046                                                                         ($a->user['account-type'] == Contact::ACCOUNT_TYPE_PERSON)],
1047
1048                 '$account_organisation' => ['account-type', L10n::t('Organisation Page'), Contact::ACCOUNT_TYPE_ORGANISATION,
1049                                                                         L10n::t('Account for an organisation that automatically approves contact requests as "Followers".'),
1050                                                                         ($a->user['account-type'] == Contact::ACCOUNT_TYPE_ORGANISATION)],
1051
1052                 '$account_news'         => ['account-type', L10n::t('News Page'), Contact::ACCOUNT_TYPE_NEWS,
1053                                                                         L10n::t('Account for a news reflector that automatically approves contact requests as "Followers".'),
1054                                                                         ($a->user['account-type'] == Contact::ACCOUNT_TYPE_NEWS)],
1055
1056                 '$account_community'    => ['account-type', L10n::t('Community Forum'), Contact::ACCOUNT_TYPE_COMMUNITY,
1057                                                                         L10n::t('Account for community discussions.'),
1058                                                                         ($a->user['account-type'] == Contact::ACCOUNT_TYPE_COMMUNITY)],
1059
1060                 '$page_normal'          => ['page-flags', L10n::t('Normal Account Page'), Contact::PAGE_NORMAL,
1061                                                                         L10n::t('Account for a regular personal profile that requires manual approval of "Friends" and "Followers".'),
1062                                                                         ($a->user['page-flags'] == Contact::PAGE_NORMAL)],
1063
1064                 '$page_soapbox'         => ['page-flags', L10n::t('Soapbox Page'), Contact::PAGE_SOAPBOX,
1065                                                                         L10n::t('Account for a public profile that automatically approves contact requests as "Followers".'),
1066                                                                         ($a->user['page-flags'] == Contact::PAGE_SOAPBOX)],
1067
1068                 '$page_community'       => ['page-flags', L10n::t('Public Forum'), Contact::PAGE_COMMUNITY,
1069                                                                         L10n::t('Automatically approves all contact requests.'),
1070                                                                         ($a->user['page-flags'] == Contact::PAGE_COMMUNITY)],
1071
1072                 '$page_freelove'        => ['page-flags', L10n::t('Automatic Friend Page'), Contact::PAGE_FREELOVE,
1073                                                                         L10n::t('Account for a popular profile that automatically approves contact requests as "Friends".'),
1074                                                                         ($a->user['page-flags'] == Contact::PAGE_FREELOVE)],
1075
1076                 '$page_prvgroup'        => ['page-flags', L10n::t('Private Forum [Experimental]'), Contact::PAGE_PRVGROUP,
1077                                                                         L10n::t('Requires manual approval of contact requests.'),
1078                                                                         ($a->user['page-flags'] == Contact::PAGE_PRVGROUP)],
1079
1080
1081         ]);
1082
1083         $noid = Config::get('system', 'no_openid');
1084
1085         if ($noid) {
1086                 $openid_field = false;
1087         } else {
1088                 $openid_field = ['openid_url', L10n::t('OpenID:'), $openid, L10n::t("\x28Optional\x29 Allow this OpenID to login to this account."), "", "", "url"];
1089         }
1090
1091         $opt_tpl = get_markup_template("field_yesno.tpl");
1092         if (Config::get('system', 'publish_all')) {
1093                 $profile_in_dir = '<input type="hidden" name="profile_in_directory" value="1" />';
1094         } else {
1095                 $profile_in_dir = replace_macros($opt_tpl, [
1096                         '$field' => ['profile_in_directory', L10n::t('Publish your default profile in your local site directory?'), $profile['publish'], L10n::t('Your profile will be published in this node\'s <a href="%s">local directory</a>. Your profile details may be publicly visible depending on the system settings.', System::baseUrl().'/directory'), [L10n::t('No'), L10n::t('Yes')]]
1097                 ]);
1098         }
1099
1100         if (strlen(Config::get('system', 'directory'))) {
1101                 $profile_in_net_dir = replace_macros($opt_tpl, [
1102                         '$field' => ['profile_in_netdirectory', L10n::t('Publish your default profile in the global social directory?'), $profile['net-publish'], L10n::t('Your profile will be published in the global friendica directories (e.g. <a href="%s">%s</a>). Your profile will be visible in public.', Config::get('system', 'directory'), Config::get('system', 'directory')), [L10n::t('No'), L10n::t('Yes')]]
1103                 ]);
1104         } else {
1105                 $profile_in_net_dir = '';
1106         }
1107
1108         $hide_friends = replace_macros($opt_tpl, [
1109                 '$field' => ['hide-friends', L10n::t('Hide your contact/friend list from viewers of your default profile?'), $profile['hide-friends'], L10n::t('Your contact list won\'t be shown in your default profile page. You can decide to show your contact list separately for each additional profile you create'), [L10n::t('No'), L10n::t('Yes')]],
1110         ]);
1111
1112         $hide_wall = replace_macros($opt_tpl, [
1113                 '$field' => ['hidewall', L10n::t('Hide your profile details from anonymous viewers?'), $a->user['hidewall'], L10n::t('Anonymous visitors will only see your profile picture, your display name and the nickname you are using on your profile page. Your public posts and replies will still be accessible by other means.'), [L10n::t('No'), L10n::t('Yes')]],
1114         ]);
1115
1116         $blockwall = replace_macros($opt_tpl, [
1117                 '$field' => ['blockwall', L10n::t('Allow friends to post to your profile page?'), (intval($a->user['blockwall']) ? '0' : '1'), L10n::t('Your contacts may write posts on your profile wall. These posts will be distributed to your contacts'), [L10n::t('No'), L10n::t('Yes')]],
1118         ]);
1119
1120         $blocktags = replace_macros($opt_tpl, [
1121                 '$field' => ['blocktags', L10n::t('Allow friends to tag your posts?'), (intval($a->user['blocktags']) ? '0' : '1'), L10n::t('Your contacts can add additional tags to your posts.'), [L10n::t('No'), L10n::t('Yes')]],
1122         ]);
1123
1124         $suggestme = replace_macros($opt_tpl, [
1125                 '$field' => ['suggestme', L10n::t('Allow us to suggest you as a potential friend to new members?'), $suggestme, L10n::t('If you like, Friendica may suggest new members to add you as a contact.'), [L10n::t('No'), L10n::t('Yes')]],
1126         ]);
1127
1128         $unkmail = replace_macros($opt_tpl, [
1129                 '$field' => ['unkmail', L10n::t('Permit unknown people to send you private mail?'), $unkmail, L10n::t('Friendica network users may send you private messages even if they are not in your contact list.'), [L10n::t('No'), L10n::t('Yes')]],
1130         ]);
1131
1132         if (!$profile['publish'] && !$profile['net-publish']) {
1133                 info(L10n::t('Profile is <strong>not published</strong>.') . EOL);
1134         }
1135
1136         $tpl_addr = get_markup_template('settings/nick_set.tpl');
1137
1138         $prof_addr = replace_macros($tpl_addr,[
1139                 '$desc' => L10n::t("Your Identity Address is <strong>'%s'</strong> or '%s'.", $nickname . '@' . $a->getHostName() . $a->getURLpath(), System::baseUrl() . '/profile/' . $nickname),
1140                 '$basepath' => $a->getHostName()
1141         ]);
1142
1143         $stpl = get_markup_template('settings/settings.tpl');
1144
1145         $expire_arr = [
1146                 'days' => ['expire',  L10n::t("Automatically expire posts after this many days:"), $expire, L10n::t('If empty, posts will not expire. Expired posts will be deleted')],
1147                 'advanced' => L10n::t('Advanced expiration settings'),
1148                 'label' => L10n::t('Advanced Expiration'),
1149                 'items' => ['expire_items',  L10n::t("Expire posts:"), $expire_items, '', [L10n::t('No'), L10n::t('Yes')]],
1150                 'notes' => ['expire_notes',  L10n::t("Expire personal notes:"), $expire_notes, '', [L10n::t('No'), L10n::t('Yes')]],
1151                 'starred' => ['expire_starred',  L10n::t("Expire starred posts:"), $expire_starred, '', [L10n::t('No'), L10n::t('Yes')]],
1152                 'photos' => ['expire_photos',  L10n::t("Expire photos:"), $expire_photos, '', [L10n::t('No'), L10n::t('Yes')]],
1153                 'network_only' => ['expire_network_only',  L10n::t("Only expire posts by others:"), $expire_network_only, '', [L10n::t('No'), L10n::t('Yes')]],
1154         ];
1155
1156         $group_select = Group::displayGroupSelection(local_user(), $a->user['def_gid']);
1157
1158         // Private/public post links for the non-JS ACL form
1159         $private_post = 1;
1160         if (!empty($_REQUEST['public']) && !$_REQUEST['public']) {
1161                 $private_post = 0;
1162         }
1163
1164         $query_str = $a->query_string;
1165         if (strpos($query_str, 'public=1') !== false) {
1166                 $query_str = str_replace(['?public=1', '&public=1'], ['', ''], $query_str);
1167         }
1168
1169         // I think $a->query_string may never have ? in it, but I could be wrong
1170         // It looks like it's from the index.php?q=[etc] rewrite that the web
1171         // server does, which converts any ? to &, e.g. suggest&ignore=61 for suggest?ignore=61
1172         if (strpos($query_str, '?') === false) {
1173                 $public_post_link = '?public=1';
1174         } else {
1175                 $public_post_link = '&public=1';
1176         }
1177
1178         /* Installed langs */
1179         $lang_choices = L10n::getAvailableLanguages();
1180
1181         /// @TODO Fix indending (or so)
1182         $o .= replace_macros($stpl, [
1183                 '$ptitle'       => L10n::t('Account Settings'),
1184
1185                 '$submit'       => L10n::t('Save Settings'),
1186                 '$baseurl' => System::baseUrl(true),
1187                 '$uid' => local_user(),
1188                 '$form_security_token' => get_form_security_token("settings"),
1189                 '$nickname_block' => $prof_addr,
1190
1191                 '$h_pass'       => L10n::t('Password Settings'),
1192                 '$password1'=> ['password', L10n::t('New Password:'), '', ''],
1193                 '$password2'=> ['confirm', L10n::t('Confirm:'), '', L10n::t('Leave password fields blank unless changing')],
1194                 '$password3'=> ['opassword', L10n::t('Current Password:'), '', L10n::t('Your current password to confirm the changes')],
1195                 '$password4'=> ['mpassword', L10n::t('Password:'), '', L10n::t('Your current password to confirm the changes')],
1196                 '$oid_enable' => (!Config::get('system', 'no_openid')),
1197                 '$openid'       => $openid_field,
1198
1199                 '$h_basic'      => L10n::t('Basic Settings'),
1200                 '$username' => ['username',  L10n::t('Full Name:'), $username, ''],
1201                 '$email'        => ['email', L10n::t('Email Address:'), $email, '', '', '', 'email'],
1202                 '$timezone' => ['timezone_select' , L10n::t('Your Timezone:'), Temporal::getTimezoneSelect($timezone), ''],
1203                 '$language' => ['language', L10n::t('Your Language:'), $language, L10n::t('Set the language we use to show you friendica interface and to send you emails'), $lang_choices],
1204                 '$defloc'       => ['defloc', L10n::t('Default Post Location:'), $defloc, ''],
1205                 '$allowloc' => ['allow_location', L10n::t('Use Browser Location:'), ($a->user['allow_location'] == 1), ''],
1206
1207
1208                 '$h_prv'        => L10n::t('Security and Privacy Settings'),
1209
1210                 '$maxreq'       => ['maxreq', L10n::t('Maximum Friend Requests/Day:'), $maxreq , L10n::t("\x28to prevent spam abuse\x29")],
1211                 '$permissions' => L10n::t('Default Post Permissions'),
1212                 '$permdesc' => L10n::t("\x28click to open/close\x29"),
1213                 '$visibility' => $profile['net-publish'],
1214                 '$aclselect' => ACL::getFullSelectorHTML($a->user),
1215                 '$suggestme' => $suggestme,
1216                 '$blockwall'=> $blockwall, // array('blockwall', L10n::t('Allow friends to post to your profile page:'), !$blockwall, ''),
1217                 '$blocktags'=> $blocktags, // array('blocktags', L10n::t('Allow friends to tag your posts:'), !$blocktags, ''),
1218
1219                 // ACL permissions box
1220                 '$group_perms' => L10n::t('Show to Groups'),
1221                 '$contact_perms' => L10n::t('Show to Contacts'),
1222                 '$private' => L10n::t('Default Private Post'),
1223                 '$public' => L10n::t('Default Public Post'),
1224                 '$is_private' => $private_post,
1225                 '$return_path' => $query_str,
1226                 '$public_link' => $public_post_link,
1227                 '$settings_perms' => L10n::t('Default Permissions for New Posts'),
1228
1229                 '$group_select' => $group_select,
1230
1231
1232                 '$expire'       => $expire_arr,
1233
1234                 '$profile_in_dir' => $profile_in_dir,
1235                 '$profile_in_net_dir' => $profile_in_net_dir,
1236                 '$hide_friends' => $hide_friends,
1237                 '$hide_wall' => $hide_wall,
1238                 '$unkmail' => $unkmail,
1239                 '$cntunkmail'   => ['cntunkmail', L10n::t('Maximum private messages per day from unknown people:'), $cntunkmail , L10n::t("\x28to prevent spam abuse\x29")],
1240
1241
1242                 '$h_not'        => L10n::t('Notification Settings'),
1243                 '$lbl_not'      => L10n::t('Send a notification email when:'),
1244                 '$notify1'      => ['notify1', L10n::t('You receive an introduction'), ($notify & NOTIFY_INTRO), NOTIFY_INTRO, ''],
1245                 '$notify2'      => ['notify2', L10n::t('Your introductions are confirmed'), ($notify & NOTIFY_CONFIRM), NOTIFY_CONFIRM, ''],
1246                 '$notify3'      => ['notify3', L10n::t('Someone writes on your profile wall'), ($notify & NOTIFY_WALL), NOTIFY_WALL, ''],
1247                 '$notify4'      => ['notify4', L10n::t('Someone writes a followup comment'), ($notify & NOTIFY_COMMENT), NOTIFY_COMMENT, ''],
1248                 '$notify5'      => ['notify5', L10n::t('You receive a private message'), ($notify & NOTIFY_MAIL), NOTIFY_MAIL, ''],
1249                 '$notify6'  => ['notify6', L10n::t('You receive a friend suggestion'), ($notify & NOTIFY_SUGGEST), NOTIFY_SUGGEST, ''],
1250                 '$notify7'  => ['notify7', L10n::t('You are tagged in a post'), ($notify & NOTIFY_TAGSELF), NOTIFY_TAGSELF, ''],
1251                 '$notify8'  => ['notify8', L10n::t('You are poked/prodded/etc. in a post'), ($notify & NOTIFY_POKE), NOTIFY_POKE, ''],
1252
1253                 '$desktop_notifications' => ['desktop_notifications', L10n::t('Activate desktop notifications') , false, L10n::t('Show desktop popup on new notifications')],
1254
1255                 '$email_textonly' => ['email_textonly', L10n::t('Text-only notification emails'),
1256                                                                         PConfig::get(local_user(), 'system', 'email_textonly'),
1257                                                                         L10n::t('Send text only notification emails, without the html part')],
1258
1259                 '$detailed_notif' => ['detailed_notif', L10n::t('Show detailled notifications'),
1260                                                                         PConfig::get(local_user(), 'system', 'detailed_notif'),
1261                                                                         L10n::t('Per default, notifications are condensed to a single notification per item. When enabled every notification is displayed.')],
1262
1263                 '$h_advn' => L10n::t('Advanced Account/Page Type Settings'),
1264                 '$h_descadvn' => L10n::t('Change the behaviour of this account for special situations'),
1265                 '$pagetype' => $pagetype,
1266
1267                 '$relocate' => L10n::t('Relocate'),
1268                 '$relocate_text' => L10n::t("If you have moved this profile from another server, and some of your contacts don't receive your updates, try pushing this button."),
1269                 '$relocate_button' => L10n::t("Resend relocate message to contacts"),
1270
1271         ]);
1272
1273         Addon::callHooks('settings_form', $o);
1274
1275         $o .= '</form>' . "\r\n";
1276
1277         return $o;
1278
1279 }