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