]> git.mxchange.org Git - friendica.git/blob - src/Module/Admin/Federation.php
User lowercase for platform data
[friendica.git] / src / Module / Admin / Federation.php
1 <?php
2
3 namespace Friendica\Module\Admin;
4
5 use Friendica\Core\Config;
6 use Friendica\Core\L10n;
7 use Friendica\Core\Renderer;
8 use Friendica\Database\DBA;
9 use Friendica\Module\BaseAdminModule;
10
11 class Federation extends BaseAdminModule
12 {
13         public static function content(array $parameters = [])
14         {
15                 parent::content($parameters);
16
17                 // get counts on active federation systems this node is knowing
18                 // We list the more common systems by name. The rest is counted as "other"
19                 $systems = [
20                         'friendica'   => ['name' => 'Friendica', 'color' => '#ffc018'], // orange from the logo
21                         'diaspora'    => ['name' => 'Diaspora', 'color' => '#a1a1a1'], // logo is black and white, makes a gray
22                         'funkwhale'   => ['name' => 'Funkwhale', 'color' => '#4082B4'], // From the homepage
23                         'gnusocial'   => ['name' => 'GNU Social/Statusnet', 'color' => '#a22430'], // dark red from the logo
24                         'hubzilla'    => ['name' => 'Hubzilla/Red Matrix', 'color' => '#43488a'], // blue from the logo
25                         'mastodon'    => ['name' => 'Mastodon', 'color' => '#1a9df9'], // blue from the Mastodon logo
26                         'misskey'     => ['name' => 'Misskey', 'color' => '#ccfefd'], // Font color of the homepage
27                         'peertube'    => ['name' => 'Peertube', 'color' => '#ffad5c'], // One of the logo colors
28                         'pixelfed'    => ['name' => 'Pixelfed', 'color' => '#11da47'], // One of the logo colors
29                         'pleroma'     => ['name' => 'Pleroma', 'color' => '#E46F0F'], // Orange from the text that is used on Pleroma instances
30                         'plume'       => ['name' => 'Plume', 'color' => '#7765e3'], // From the homepage
31                         'socialhome'  => ['name' => 'SocialHome', 'color' => '#52056b'], // lilac from the Django Image used at the Socialhome homepage
32                         'wordpress'   => ['name' => 'WordPress', 'color' => '#016087'], // Background color of the homepage
33                         'writefreely' => ['name' => 'WriteFreely', 'color' => '#292929'], // Font color of the homepage
34                         'other'       => ['name' => L10n::t('Other'), 'color' => '#F1007E'], // ActivityPub main color
35                 ];
36
37                 $platforms = array_keys($systems);
38
39                 $counts = [];
40                 foreach ($platforms as $platform) {
41                         $counts[$platform] = [];
42                 }
43
44                 $total = 0;
45                 $users = 0;
46
47                 $gservers = DBA::p("SELECT COUNT(*) AS `total`, SUM(`registered-users`) AS `users`, `platform`,
48                         ANY_VALUE(`network`) AS `network`, MAX(`version`) AS `version`
49                         FROM `gserver` WHERE `last_contact` >= `last_failure` GROUP BY `platform`");
50                 while ($gserver = DBA::fetch($gservers)) {
51                         $total += $gserver['total'];
52                         $users += $gserver['users'];
53
54                         $versionCounts = [];
55                         $versions = DBA::p("SELECT COUNT(*) AS `total`, `version` FROM `gserver`
56                                 WHERE `last_contact` >= `last_failure` AND `platform` = ?
57                                 GROUP BY `version` ORDER BY `version`", $gserver['platform']);
58                         while ($version = DBA::fetch($versions)) {
59                                 $version['version'] = str_replace(["\n", "\r", "\t"], " ", $version['version']);
60
61                                 if (in_array($gserver['platform'], ['Red Matrix', 'redmatrix', 'red'])) {
62                                         $version['version'] = 'Red ' . $version['version'];
63                                 }
64
65                                 $versionCounts[] = $version;
66                         }
67                         DBA::close($versions);
68
69                         $platform = $gserver['platform'] = strtolower($gserver['platform']);
70
71                         if ($platform == 'friendika') {
72                                 $platform = 'friendica';
73                         } elseif (in_array($platform, ['red matrix', 'redmatrix', 'red'])) {
74                                 $platform = 'hubzilla';
75                         } elseif(stristr($platform, 'pleroma')) {
76                                 $platform = 'pleroma';
77                         } elseif(stristr($platform, 'statusnet')) {
78                                 $platform = 'gnusocial';
79                         } elseif(stristr($platform, 'wordpress')) {
80                                 $platform = 'wordpress';
81                         } elseif (!in_array($platform, $platforms)) {
82                                 $platform = 'other';
83                         }
84
85                         if ($platform != $gserver['platform']) {
86                                 if ($platform == 'other') {
87                                         $versionCounts = $counts[$platform][1] ?? [];
88                                         $versionCounts[] = ['version' => $gserver['platform'] ?: L10n::t('unknown'), 'total' => $gserver['total']];
89                                         $gserver['version'] = '';
90                                 } else {
91                                         $versionCounts = array_merge($versionCounts, $counts[$platform][1] ?? []);
92                                 }
93
94                                 $gserver['platform'] = $platform;
95                                 $gserver['total'] += $counts[$platform][0]['total'] ?? 0;
96                                 $gserver['users'] += $counts[$platform][0]['users'] ?? 0;
97                         }
98
99                         if ($platform == 'friendica') {
100                                 $versionCounts = self::reformaFriendicaVersions($versionCounts);
101                         } elseif ($platform == 'pleroma') {
102                                 $versionCounts = self::reformaPleromaVersions($versionCounts);
103                         } elseif ($platform == 'diaspora') {
104                                 $versionCounts = self::reformaDiasporaVersions($versionCounts);
105                         }
106
107                         $versionCounts = self::sortVersion($versionCounts);
108
109                         $gserver['platform'] = $systems[$platform]['name'];
110
111                         $counts[$platform] = [$gserver, $versionCounts, str_replace([' ', '%'], '', $platform), $systems[$platform]['color']];
112                 }
113                 DBA::close($gserver);
114
115                 // some helpful text
116                 $intro = L10n::t('This page offers you some numbers to the known part of the federated social network your Friendica node is part of. These numbers are not complete but only reflect the part of the network your node is aware of.');
117                 $hint = L10n::t('The <em>Auto Discovered Contact Directory</em> feature is not enabled, it will improve the data displayed here.');
118
119                 // load the template, replace the macros and return the page content
120                 $t = Renderer::getMarkupTemplate('admin/federation.tpl');
121                 return Renderer::replaceMacros($t, [
122                         '$title' => L10n::t('Administration'),
123                         '$page' => L10n::t('Federation Statistics'),
124                         '$intro' => $intro,
125                         '$hint' => $hint,
126                         '$autoactive' => Config::get('system', 'poco_completion'),
127                         '$counts' => $counts,
128                         '$version' => FRIENDICA_VERSION,
129                         '$legendtext' => L10n::t('Currently this node is aware of %d nodes with %d registered users from the following platforms:', $total, $users),
130                 ]);
131         }
132
133         /**
134          * early friendica versions have the format x.x.xxxx where xxxx is the
135          * DB version stamp; those should be operated out and versions be combined
136          *
137          * @param array $versionCounts list of version numbers
138          * @return array with cleaned version numbers
139          */
140         private static function reformaFriendicaVersions(array $versionCounts)
141         {
142                 $newV = [];
143                 $newVv = [];
144                 foreach ($versionCounts as $vv) {
145                         $newVC = $vv['total'];
146                         $newVV = $vv['version'];
147                         $lastDot = strrpos($newVV, '.');
148                         $len = strlen($newVV) - 1;
149                         if (($lastDot == $len - 4) && (!strrpos($newVV, '-rc') == $len - 3)) {
150                                 $newVV = substr($newVV, 0, $lastDot);
151                         }
152                         if (isset($newV[$newVV])) {
153                                 $newV[$newVV] += $newVC;
154                         } else {
155                                 $newV[$newVV] = $newVC;
156                         }
157                 }
158                 foreach ($newV as $key => $value) {
159                         array_push($newVv, ['total' => $value, 'version' => $key]);
160                 }
161                 $versionCounts = $newVv;
162
163                 return $versionCounts;
164         }
165
166         /**
167          * in the DB the Diaspora versions have the format x.x.x.x-xx the last
168          * part (-xx) should be removed to clean up the versions from the "head
169          * commit" information and combined into a single entry for x.x.x.x
170          *
171          * @param array $versionCounts list of version numbers
172          * @return array with cleaned version numbers
173          */
174         private static function reformaDiasporaVersions(array $versionCounts)
175         {
176                 $newV = [];
177                 $newVv = [];
178                 foreach ($versionCounts as $vv) {
179                         $newVC = $vv['total'];
180                         $newVV = $vv['version'];
181                         $posDash = strpos($newVV, '-');
182                         if ($posDash) {
183                                 $newVV = substr($newVV, 0, $posDash);
184                         }
185                         if (isset($newV[$newVV])) {
186                                 $newV[$newVV] += $newVC;
187                         } else {
188                                 $newV[$newVV] = $newVC;
189                         }
190                 }
191                 foreach ($newV as $key => $value) {
192                         array_push($newVv, ['total' => $value, 'version' => $key]);
193                 }
194                 $versionCounts = $newVv;
195
196                 return $versionCounts;
197         }
198
199         /**
200          * Clean up Pleroma version numbers
201          *
202          * @param array $versionCounts list of version numbers
203          * @return array with cleaned version numbers
204          */
205         private static function reformaPleromaVersions(array $versionCounts)
206         {
207                 $compacted = [];
208                 foreach ($versionCounts as $key => $value) {
209                         $version = $versionCounts[$key]['version'];
210                         $parts = explode(' ', trim($version));
211                         do {
212                                 $part = array_pop($parts);
213                         } while (!empty($parts) && ((strlen($part) >= 40) || (strlen($part) <= 3)));
214                         // only take the x.x.x part of the version, not the "release" after the dash
215                         if (!empty($part) && strpos($part, '-')) {
216                                 $part = explode('-', $part)[0];
217                         }
218                         if (!empty($part)) {
219                                 if (empty($compacted[$part])) {
220                                         $compacted[$part] = $versionCounts[$key]['total'];
221                                 } else {
222                                         $compacted[$part] += $versionCounts[$key]['total'];
223                                 }
224                         }
225                 }
226
227                 $versionCounts = [];
228                 foreach ($compacted as $version => $pl_total) {
229                         $versionCounts[] = ['version' => $version, 'total' => $pl_total];
230                 }
231
232                 return $versionCounts;
233         }
234
235         /**
236          * Reformat, sort and compact version numbers
237          *
238          * @param array $versionCounts list of version numbers
239          * @return array with reformatted version numbers
240          */
241         private static function sortVersion(array $versionCounts)
242         {
243                 //
244                 // clean up version numbers
245                 //
246                 // some platforms do not provide version information, add a unkown there
247                 // to the version string for the displayed list.
248                 foreach ($versionCounts as $key => $value) {
249                         if ($versionCounts[$key]['version'] == '') {
250                                 $versionCounts[$key] = ['total' => $versionCounts[$key]['total'], 'version' => L10n::t('unknown')];
251                         }
252                 }
253
254                 // Assure that the versions are sorted correctly
255                 $v2 = [];
256                 $versions = [];
257                 foreach ($versionCounts as $vv) {
258                         $version = trim(strip_tags($vv["version"]));
259                         $v2[$version] = $vv;
260                         $versions[] = $version;
261                 }
262
263                 usort($versions, 'version_compare');
264
265                 $versionCounts = [];
266                 foreach ($versions as $version) {
267                         $versionCounts[] = $v2[$version];
268                 }
269
270                 return $versionCounts;
271         }
272 }