[url_replace] Add support for empty config value
[friendica-addons.git/.git] / url_replace / url_replace.php
1 <?php
2 /**
3  * Name: URL Replace
4  * Description: Replaces occurrences of specified URLs with the address of alternative servers in all displays of postings on a node.
5  * Version: 1.0
6  * Author: Dr. Tobias Quathamer <https://social.anoxinon.de/@toddy>
7  * Maintainer: Dr. Tobias Quathamer <https://social.anoxinon.de/@toddy>
8  */
9
10 use Friendica\Core\Hook;
11 use Friendica\Core\Renderer;
12 use Friendica\DI;
13
14 function url_replace_install()
15 {
16         Hook::register('prepare_body_final', 'addon/url_replace/url_replace.php', 'url_replace_render');
17 }
18
19 /**
20  * Handle sent data from admin settings
21  */
22 function url_replace_addon_admin_post()
23 {
24         DI::config()->set('url_replace', 'nitter_server', rtrim(trim($_POST['nitter_server']), '/'));
25         DI::config()->set('url_replace', 'invidious_server', rtrim(trim($_POST['invidious_server']), '/'));
26         // Convert twelvefeet_sites into an array before setting the new value
27         $twelvefeet_sites = explode(PHP_EOL, $_POST['twelvefeet_sites']);
28         // Normalize URLs by using lower case, removing a trailing slash and whitespace
29         $twelvefeet_sites = array_map(fn($value): string => rtrim(trim(strtolower($value)), '/'), $twelvefeet_sites);
30         // Do not store empty lines or duplicates
31         $twelvefeet_sites = array_filter($twelvefeet_sites, fn($value): bool => !empty($value));
32         $twelvefeet_sites = array_unique($twelvefeet_sites);
33         // Ensure a protocol and default to HTTPS
34         $twelvefeet_sites = array_map(
35                 fn($value): string => substr($value, 0, 4) !== 'http' ? 'https://' . $value : $value,
36                 $twelvefeet_sites
37         );
38         asort($twelvefeet_sites);
39         DI::config()->set('url_replace', 'twelvefeet_sites', $twelvefeet_sites);
40 }
41
42 /**
43  * Hook into admin settings to enable choosing a different server
44  * for twitter, youtube, and news sites.
45  */
46 function url_replace_addon_admin(string &$o)
47 {
48         $nitter_server    = DI::config()->get('url_replace', 'nitter_server');
49         $invidious_server = DI::config()->get('url_replace', 'invidious_server');
50         $twelvefeet_sites = implode(PHP_EOL, DI::config()->get('url_replace', 'twelvefeet_sites') ?? [] ?: []);
51
52         $t = Renderer::getMarkupTemplate('admin.tpl', 'addon/url_replace/');
53         $o = Renderer::replaceMacros($t, [
54                 '$nitter_server' => [
55                         'nitter_server',
56                         DI::l10n()->t('Nitter server'),
57                         $nitter_server,
58                         DI::l10n()->t('Specify the URL with protocol. The default is https://nitter.net.'),
59                         null,
60                         'placeholder="https://nitter.net"',
61                 ],
62                 '$invidious_server' => [
63                         'invidious_server',
64                         DI::l10n()->t('Invidious server'),
65                         $invidious_server,
66                         DI::l10n()->t('Specify the URL with protocol. The default is https://yewtu.be.'),
67                         null,
68                         'placeholder="https://yewtu.be"',
69                 ],
70                 '$twelvefeet_sites' => [
71                         'twelvefeet_sites',
72                         DI::l10n()->t('Sites which are accessed through 12ft.io'),
73                         $twelvefeet_sites,
74                         DI::l10n()->t('Specify the URLs with protocol, one per line.'),
75                         null,
76                         'rows="6"'
77                 ],
78                 '$submit' => DI::l10n()->t('Save settings'),
79         ]);
80 }
81
82 /**
83  * Replace proprietary URLs with their specified counterpart
84  */
85 function url_replace_render(array &$b)
86 {
87         $replaced = false;
88
89         $nitter_server = DI::config()->get('url_replace', 'nitter_server');
90         if (empty($nitter_server)) {
91                 $nitter_server = 'https://nitter.net';
92         }
93
94         $invidious_server = DI::config()->get('url_replace', 'invidious_server');
95         if (empty($invidious_server)) {
96                 $invidious_server = 'https://yewtu.be';
97         }
98
99         // Handle some of twitter and youtube
100         $replacements = [
101                 'https://mobile.twitter.com' => $nitter_server,
102                 'https://twitter.com'        => $nitter_server,
103                 'https://mobile.x.com'       => $nitter_server,
104                 'https://x.com'              => $nitter_server,
105                 'https://www.youtube.com'    => $invidious_server,
106                 'https://youtube.com'        => $invidious_server,
107                 'https://m.youtube.com'      => $invidious_server,
108                 'https://youtu.be'           => $invidious_server,
109         ];
110         foreach ($replacements as $server => $replacement) {
111                 if (strpos($b['html'], $server) !== false) {
112                         $b['html'] = str_replace($server, $replacement, $b['html']);
113                         $replaced  = true;
114                 }
115         }
116
117         $twelvefeet_sites = DI::config()->get('url_replace', 'twelvefeet_sites') ?? [] ?: [];
118         foreach ($twelvefeet_sites as $twelvefeet_site) {
119                 if (strpos($b['html'], $twelvefeet_site) !== false) {
120                         $b['html'] = str_replace($twelvefeet_site, 'https://12ft.io/' . $twelvefeet_site, $b['html']);
121                         $replaced  = true;
122                 }
123         }
124
125
126         if ($replaced) {
127                 $b['html'] .= '<hr><p><small>' . DI::l10n()->t('(URL replace addon enabled for X, YouTube and some news sites.)') . '</small></p>';
128         }
129 }