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