]> git.mxchange.org Git - friendica.git/blob - mod/settings.php
Use the top-level author theme if they're a local user in mod/display
[friendica.git] / mod / settings.php
1 <?php
2 /**
3  * @copyright Copyright (C) 2010-2022, the Friendica project
4  *
5  * @license GNU AGPL version 3 or any later version
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License as
9  * published by the Free Software Foundation, either version 3 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Affero General Public License for more details.
16  *
17  * You should have received a copy of the GNU Affero General Public License
18  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19  *
20  */
21
22 use Friendica\App;
23 use Friendica\BaseModule;
24 use Friendica\Content\Feature;
25 use Friendica\Content\Nav;
26 use Friendica\Core\ACL;
27 use Friendica\Core\Hook;
28 use Friendica\Core\Logger;
29 use Friendica\Core\Renderer;
30 use Friendica\Core\Worker;
31 use Friendica\Database\DBA;
32 use Friendica\DI;
33 use Friendica\Model\Group;
34 use Friendica\Model\Item;
35 use Friendica\Model\Notification;
36 use Friendica\Model\Profile;
37 use Friendica\Model\User;
38 use Friendica\Model\Verb;
39 use Friendica\Module\BaseSettings;
40 use Friendica\Module\Security\Login;
41 use Friendica\Protocol\Activity;
42 use Friendica\Protocol\Email;
43 use Friendica\Util\Temporal;
44 use Friendica\Worker\Delivery;
45
46 function settings_init(App $a)
47 {
48         if (!local_user()) {
49                 notice(DI::l10n()->t('Permission denied.'));
50                 return;
51         }
52
53         BaseSettings::createAside();
54 }
55
56 function settings_post(App $a)
57 {
58         if (!$a->isLoggedIn()) {
59                 notice(DI::l10n()->t('Permission denied.'));
60                 return;
61         }
62
63         if (!empty($_SESSION['submanage'])) {
64                 return;
65         }
66
67         if ((DI::args()->getArgc() > 1) && (DI::args()->getArgv()[1] == 'addon')) {
68                 BaseModule::checkFormSecurityTokenRedirectOnError(DI::args()->getQueryString(), 'settings_addon');
69
70                 Hook::callAll('addon_settings_post', $_POST);
71                 DI::baseUrl()->redirect(DI::args()->getQueryString());
72                 return;
73         }
74
75         $user = User::getById($a->getLoggedInUserId());
76
77         if ((DI::args()->getArgc() > 1) && (DI::args()->getArgv()[1] == 'connectors')) {
78                 BaseModule::checkFormSecurityTokenRedirectOnError(DI::args()->getQueryString(), 'settings_connectors');
79
80                 if (!empty($_POST['general-submit'])) {
81                         DI::pConfig()->set(local_user(), 'system', 'accept_only_sharer', intval($_POST['accept_only_sharer']));
82                         DI::pConfig()->set(local_user(), 'system', 'disable_cw', !intval($_POST['enable_cw']));
83                         DI::pConfig()->set(local_user(), 'system', 'no_intelligent_shortening', !intval($_POST['enable_smart_shortening']));
84                         DI::pConfig()->set(local_user(), 'system', 'simple_shortening', intval($_POST['simple_shortening']));
85                         DI::pConfig()->set(local_user(), 'system', 'attach_link_title', intval($_POST['attach_link_title']));
86                         DI::pConfig()->set(local_user(), 'ostatus', 'legacy_contact', $_POST['legacy_contact']);
87                 } elseif (!empty($_POST['mail-submit'])) {
88                         $mail_server       =                 $_POST['mail_server']       ?? '';
89                         $mail_port         =                 $_POST['mail_port']         ?? '';
90                         $mail_ssl          = strtolower(trim($_POST['mail_ssl']          ?? ''));
91                         $mail_user         =                 $_POST['mail_user']         ?? '';
92                         $mail_pass         =            trim($_POST['mail_pass']         ?? '');
93                         $mail_action       =            trim($_POST['mail_action']       ?? '');
94                         $mail_movetofolder =            trim($_POST['mail_movetofolder'] ?? '');
95                         $mail_replyto      =                 $_POST['mail_replyto']      ?? '';
96                         $mail_pubmail      =                 $_POST['mail_pubmail']      ?? '';
97
98                         if (function_exists('imap_open') && !DI::config()->get('system', 'imap_disabled')) {
99                                 if (!DBA::exists('mailacct', ['uid' => local_user()])) {
100                                         DBA::insert('mailacct', ['uid' => local_user()]);
101                                 }
102                                 if (strlen($mail_pass)) {
103                                         $pass = '';
104                                         openssl_public_encrypt($mail_pass, $pass, $user['pubkey']);
105                                         DBA::update('mailacct', ['pass' => bin2hex($pass)], ['uid' => local_user()]);
106                                 }
107
108                                 $r = DBA::update('mailacct', [
109                                         'server'       => $mail_server,
110                                         'port'         => $mail_port,
111                                         'ssltype'      => $mail_ssl,
112                                         'user'         => $mail_user,
113                                         'action'       => $mail_action,
114                                         'movetofolder' => $mail_movetofolder,
115                                         'mailbox'      => 'INBOX',
116                                         'reply_to'     => $mail_replyto,
117                                         'pubmail'      => $mail_pubmail
118                                 ], ['uid' => local_user()]);
119
120                                 Logger::notice('updating mailaccount', ['response' => $r]);
121                                 $mailacct = DBA::selectFirst('mailacct', [], ['uid' => local_user()]);
122                                 if (DBA::isResult($mailacct)) {
123                                         $mb = Email::constructMailboxName($mailacct);
124
125                                         if (strlen($mailacct['server'])) {
126                                                 $dcrpass = '';
127                                                 openssl_private_decrypt(hex2bin($mailacct['pass']), $dcrpass, $user['prvkey']);
128                                                 $mbox = Email::connect($mb, $mail_user, $dcrpass);
129                                                 unset($dcrpass);
130                                                 if (!$mbox) {
131                                                         notice(DI::l10n()->t('Failed to connect with email account using the settings provided.'));
132                                                 }
133                                         }
134                                 }
135                         }
136                 }
137
138                 Hook::callAll('connector_settings_post', $_POST);
139                 DI::baseUrl()->redirect(DI::args()->getQueryString());
140                 return;
141         }
142
143         if ((DI::args()->getArgc() > 1) && (DI::args()->getArgv()[1] === 'features')) {
144                 BaseModule::checkFormSecurityTokenRedirectOnError('/settings/features', 'settings_features');
145                 foreach ($_POST as $k => $v) {
146                         if (strpos($k, 'feature_') === 0) {
147                                 DI::pConfig()->set(local_user(), 'feature', substr($k, 8), ((intval($v)) ? 1 : 0));
148                         }
149                 }
150                 return;
151         }
152 }
153
154 function settings_content(App $a)
155 {
156         $o = '';
157         Nav::setSelected('settings');
158
159         if (!local_user()) {
160                 //notice(DI::l10n()->t('Permission denied.'));
161                 return Login::form();
162         }
163
164         if (!empty($_SESSION['submanage'])) {
165                 notice(DI::l10n()->t('Permission denied.'));
166                 return '';
167         }
168
169         if ((DI::args()->getArgc() > 1) && (DI::args()->getArgv()[1] === 'oauth')) {
170                 if ((DI::args()->getArgc() > 3) && (DI::args()->getArgv()[2] === 'delete')) {
171                         BaseModule::checkFormSecurityTokenRedirectOnError('/settings/oauth', 'settings_oauth', 't');
172
173                         DBA::delete('application-token', ['application-id' => DI::args()->getArgv()[3], 'uid' => local_user()]);
174                         DI::baseUrl()->redirect('settings/oauth/', true);
175                         return '';
176                 }
177
178                 $applications = DBA::selectToArray('application-view', ['id', 'uid', 'name', 'website', 'scopes', 'created_at'], ['uid' => local_user()]);
179
180                 $tpl = Renderer::getMarkupTemplate('settings/oauth.tpl');
181                 $o .= Renderer::replaceMacros($tpl, [
182                         '$form_security_token' => BaseModule::getFormSecurityToken("settings_oauth"),
183                         '$baseurl'             => DI::baseUrl()->get(true),
184                         '$title'               => DI::l10n()->t('Connected Apps'),
185                         '$name'                => DI::l10n()->t('Name'),
186                         '$website'             => DI::l10n()->t('Home Page'),
187                         '$created_at'          => DI::l10n()->t('Created'),
188                         '$delete'              => DI::l10n()->t('Remove authorization'),
189                         '$apps'                => $applications,
190                 ]);
191                 return $o;
192         }
193
194         if ((DI::args()->getArgc() > 1) && (DI::args()->getArgv()[1] === 'addon')) {
195                 $addon_settings_forms = [];
196                 foreach (DI::dba()->selectToArray('hook', ['file', 'function'], ['hook' => 'addon_settings']) as $hook) {
197                         $data = [];
198                         Hook::callSingle(DI::app(), 'addon_settings', [$hook['file'], $hook['function']], $data);
199
200                         if (!empty($data['href'])) {
201                                 $tpl = Renderer::getMarkupTemplate('settings/addon/link.tpl');
202                                 $addon_settings_forms[] = Renderer::replaceMacros($tpl, [
203                                         '$addon' => $data['addon'],
204                                         '$title' => $data['title'],
205                                         '$href'  => $data['href'],
206                                 ]);
207                         } elseif(!empty($data['addon'])) {
208                                 $tpl = Renderer::getMarkupTemplate('settings/addon/panel.tpl');
209                                 $addon_settings_forms[$data['addon']] = Renderer::replaceMacros($tpl, [
210                                         '$addon'  => $data['addon'],
211                                         '$title'  => $data['title'],
212                                         '$open'   => (DI::args()->getArgv()[2] ?? '') === $data['addon'],
213                                         '$html'   => $data['html'] ?? '',
214                                         '$submit' => $data['submit'] ?? DI::l10n()->t('Save Settings'),
215                                 ]);
216                         }
217                 }
218
219                 $tpl = Renderer::getMarkupTemplate('settings/addons.tpl');
220                 $o .= Renderer::replaceMacros($tpl, [
221                         '$form_security_token' => BaseModule::getFormSecurityToken("settings_addon"),
222                         '$title'        => DI::l10n()->t('Addon Settings'),
223                         '$no_addons_settings_configured' => DI::l10n()->t('No Addon settings configured'),
224                         '$addon_settings_forms' => $addon_settings_forms,
225                 ]);
226                 return $o;
227         }
228
229         if ((DI::args()->getArgc() > 1) && (DI::args()->getArgv()[1] === 'features')) {
230
231                 $arr = [];
232                 $features = Feature::get();
233                 foreach ($features as $fname => $fdata) {
234                         $arr[$fname] = [];
235                         $arr[$fname][0] = $fdata[0];
236                         foreach (array_slice($fdata,1) as $f) {
237                                 $arr[$fname][1][] = ['feature_' . $f[0], $f[1], Feature::isEnabled(local_user(), $f[0]), $f[2]];
238                         }
239                 }
240
241                 $tpl = Renderer::getMarkupTemplate('settings/features.tpl');
242                 $o .= Renderer::replaceMacros($tpl, [
243                         '$form_security_token' => BaseModule::getFormSecurityToken("settings_features"),
244                         '$title'               => DI::l10n()->t('Additional Features'),
245                         '$features'            => $arr,
246                         '$submit'              => DI::l10n()->t('Save Settings'),
247                 ]);
248                 return $o;
249         }
250
251         if ((DI::args()->getArgc() > 1) && (DI::args()->getArgv()[1] === 'connectors')) {
252                 $accept_only_sharer        = intval(DI::pConfig()->get(local_user(), 'system', 'accept_only_sharer'));
253                 $enable_cw                 = !intval(DI::pConfig()->get(local_user(), 'system', 'disable_cw'));
254                 $enable_smart_shortening   = !intval(DI::pConfig()->get(local_user(), 'system', 'no_intelligent_shortening'));
255                 $simple_shortening         = intval(DI::pConfig()->get(local_user(), 'system', 'simple_shortening'));
256                 $attach_link_title         = intval(DI::pConfig()->get(local_user(), 'system', 'attach_link_title'));
257                 $legacy_contact            = DI::pConfig()->get(local_user(), 'ostatus', 'legacy_contact');
258
259                 if (!empty($legacy_contact)) {
260                         /// @todo Isn't it supposed to be a $a->internalRedirect() call?
261                         DI::page()['htmlhead'] = '<meta http-equiv="refresh" content="0; URL=' . DI::baseUrl().'/ostatus_subscribe?url=' . urlencode($legacy_contact) . '">';
262                 }
263
264                 $connector_settings_forms = [];
265                 foreach (DI::dba()->selectToArray('hook', ['file', 'function'], ['hook' => 'connector_settings']) as $hook) {
266                         $data = [];
267                         Hook::callSingle(DI::app(), 'connector_settings', [$hook['file'], $hook['function']], $data);
268
269                         $tpl = Renderer::getMarkupTemplate('settings/addon/connector.tpl');
270                         $connector_settings_forms[$data['connector']] = Renderer::replaceMacros($tpl, [
271                                 '$connector' => $data['connector'],
272                                 '$title'     => $data['title'],
273                                 '$image'     => $data['image'] ?? '',
274                                 '$enabled'   => $data['enabled'] ?? true,
275                                 '$open'      => (DI::args()->getArgv()[2] ?? '') === $data['connector'],
276                                 '$html'      => $data['html'] ?? '',
277                                 '$submit'    => $data['submit'] ?? DI::l10n()->t('Save Settings'),
278                         ]);
279                 }
280
281                 if ($a->isSiteAdmin()) {
282                         $diasp_enabled = DI::l10n()->t('Built-in support for %s connectivity is %s', DI::l10n()->t('Diaspora (Socialhome, Hubzilla)'), ((DI::config()->get('system', 'diaspora_enabled')) ? DI::l10n()->t('enabled') : DI::l10n()->t('disabled')));
283                         $ostat_enabled = DI::l10n()->t('Built-in support for %s connectivity is %s', DI::l10n()->t('OStatus (GNU Social)'), ((DI::config()->get('system', 'ostatus_disabled')) ? DI::l10n()->t('disabled') : DI::l10n()->t('enabled')));
284                 } else {
285                         $diasp_enabled = "";
286                         $ostat_enabled = "";
287                 }
288
289                 $mail_disabled = ((function_exists('imap_open') && (!DI::config()->get('system', 'imap_disabled'))) ? 0 : 1);
290                 if (!$mail_disabled) {
291                         $mailacct = DBA::selectFirst('mailacct', [], ['uid' => local_user()]);
292                 } else {
293                         $mailacct = null;
294                 }
295
296                 $mail_server       = $mailacct['server'] ?? '';
297                 $mail_port         = (!empty($mailacct['port']) && is_numeric($mailacct['port'])) ? (int)$mailacct['port'] : '';
298                 $mail_ssl          = $mailacct['ssltype'] ?? '';
299                 $mail_user         = $mailacct['user'] ?? '';
300                 $mail_replyto      = $mailacct['reply_to'] ?? '';
301                 $mail_pubmail      = $mailacct['pubmail'] ?? 0;
302                 $mail_action       = $mailacct['action'] ?? 0;
303                 $mail_movetofolder = $mailacct['movetofolder'] ?? '';
304                 $mail_chk          = $mailacct['last_check'] ?? DBA::NULL_DATETIME;
305
306
307                 $tpl = Renderer::getMarkupTemplate('settings/connectors.tpl');
308
309                 $mail_disabled_message = ($mail_disabled ? DI::l10n()->t('Email access is disabled on this site.') : '');
310
311                 $ssl_options = ['TLS' => 'TLS', 'SSL' => 'SSL'];
312
313                 if (DI::config()->get('system', 'insecure_imap')) {
314                         $ssl_options['notls'] = DI::l10n()->t('None');
315                 }
316
317                 $o .= Renderer::replaceMacros($tpl, [
318                         '$form_security_token' => BaseModule::getFormSecurityToken("settings_connectors"),
319
320                         '$title'        => DI::l10n()->t('Social Networks'),
321
322                         '$diasp_enabled' => $diasp_enabled,
323                         '$ostat_enabled' => $ostat_enabled,
324
325                         '$general_settings' => DI::l10n()->t('General Social Media Settings'),
326                         '$accept_only_sharer' => [
327                                 'accept_only_sharer',
328                                 DI::l10n()->t('Followed content scope'),
329                                 $accept_only_sharer,
330                                 DI::l10n()->t('By default, conversations in which your follows participated but didn\'t start will be shown in your timeline. You can turn this behavior off, or expand it to the conversations in which your follows liked a post.'),
331                                 [
332                                         Item::COMPLETION_NONE    => DI::l10n()->t('Only conversations my follows started'),
333                                         Item::COMPLETION_COMMENT => DI::l10n()->t('Conversations my follows started or commented on (default)'),
334                                         Item::COMPLETION_LIKE    => DI::l10n()->t('Any conversation my follows interacted with, including likes'),
335                                 ]
336                         ],
337                         '$enable_cw' => ['enable_cw', DI::l10n()->t('Enable Content Warning'), $enable_cw, DI::l10n()->t('Users on networks like Mastodon or Pleroma are able to set a content warning field which collapse their post by default. This enables the automatic collapsing instead of setting the content warning as the post title. Doesn\'t affect any other content filtering you eventually set up.')],
338                         '$enable_smart_shortening' => ['enable_smart_shortening', DI::l10n()->t('Enable intelligent shortening'), $enable_smart_shortening, DI::l10n()->t('Normally the system tries to find the best link to add to shortened posts. If disabled, every shortened post will always point to the original friendica post.')],
339                         '$simple_shortening' => ['simple_shortening', DI::l10n()->t('Enable simple text shortening'), $simple_shortening, DI::l10n()->t('Normally the system shortens posts at the next line feed. If this option is enabled then the system will shorten the text at the maximum character limit.')],
340                         '$attach_link_title' => ['attach_link_title', DI::l10n()->t('Attach the link title'), $attach_link_title, DI::l10n()->t('When activated, the title of the attached link will be added as a title on posts to Diaspora. This is mostly helpful with "remote-self" contacts that share feed content.')],
341                         '$legacy_contact' => ['legacy_contact', DI::l10n()->t('Your legacy ActivityPub/GNU Social account'), $legacy_contact, DI::l10n()->t("If you enter your old account name from an ActivityPub based system or your GNU Social/Statusnet account name here (in the format user@domain.tld), your contacts will be added automatically. The field will be emptied when done.")],
342
343                         '$repair_ostatus_url' => DI::baseUrl() . '/repair_ostatus',
344                         '$repair_ostatus_text' => DI::l10n()->t('Repair OStatus subscriptions'),
345
346                         '$connector_settings_forms' => $connector_settings_forms,
347
348                         '$h_mail' => DI::l10n()->t('Email/Mailbox Setup'),
349                         '$mail_desc' => DI::l10n()->t("If you wish to communicate with email contacts using this service \x28optional\x29, please specify how to connect to your mailbox."),
350                         '$mail_lastcheck' => ['mail_lastcheck', DI::l10n()->t('Last successful email check:'), $mail_chk, ''],
351                         '$mail_disabled' => $mail_disabled_message,
352                         '$mail_server'  => ['mail_server',      DI::l10n()->t('IMAP server name:'), $mail_server, ''],
353                         '$mail_port'    => ['mail_port',        DI::l10n()->t('IMAP port:'), $mail_port, ''],
354                         '$mail_ssl'     => ['mail_ssl',         DI::l10n()->t('Security:'), strtoupper($mail_ssl), '', $ssl_options],
355                         '$mail_user'    => ['mail_user',        DI::l10n()->t('Email login name:'), $mail_user, ''],
356                         '$mail_pass'    => ['mail_pass',        DI::l10n()->t('Email password:'), '', ''],
357                         '$mail_replyto' => ['mail_replyto',     DI::l10n()->t('Reply-to address:'), $mail_replyto, 'Optional'],
358                         '$mail_pubmail' => ['mail_pubmail',     DI::l10n()->t('Send public posts to all email contacts:'), $mail_pubmail, ''],
359                         '$mail_action'  => ['mail_action',      DI::l10n()->t('Action after import:'), $mail_action, '', [0 => DI::l10n()->t('None'), 1 => DI::l10n()->t('Delete'), 2 => DI::l10n()->t('Mark as seen'), 3 => DI::l10n()->t('Move to folder')]],
360                         '$mail_movetofolder' => ['mail_movetofolder', DI::l10n()->t('Move to folder:'), $mail_movetofolder, ''],
361                         '$submit' => DI::l10n()->t('Save Settings'),
362                 ]);
363
364                 Hook::callAll('display_settings', $o);
365                 return $o;
366         }
367 }