Browse Source

Merge branch 'master' into develop

pull/4651/head
Hypolite Petovan 4 years ago
parent
commit
27d94023ee
  1. 128
      CHANGELOG
  2. 26
      INSTALL.txt
  3. 2
      VERSION
  4. 2
      bin/worker.php
  5. 4
      boot.php
  6. 3
      database.sql
  7. 3
      doc/Developers-Intro.md
  8. 26
      doc/FAQ.md
  9. 14
      doc/Install.md
  10. 23
      doc/Settings.md
  11. 37
      doc/de/FAQ.md
  12. 3
      doc/de/Install.md
  13. 23
      doc/de/Settings.md
  14. 1
      doc/htconfig.md
  15. 3
      doc/themes.md
  16. 8
      include/api.php
  17. 6
      include/conversation.php
  18. 10
      include/enotify.php
  19. 24
      include/event.php
  20. 4
      include/items.php
  21. 125
      include/text.php
  22. 2
      index.php
  23. 2
      mod/admin.php
  24. 18
      mod/contacts.php
  25. 37
      mod/delegate.php
  26. 6
      mod/dfrn_notify.php
  27. 152
      mod/directory.php
  28. 55
      mod/dirfind.php
  29. 6
      mod/display.php
  30. 18
      mod/follow.php
  31. 15
      mod/install.php
  32. 3
      mod/ostatus_subscribe.php
  33. 178
      mod/pubsub.php
  34. 5
      mod/settings.php
  35. 4
      mod/unfollow.php
  36. 60
      src/Content/Text/BBCode.php
  37. 64
      src/Core/NotificationsManager.php
  38. 2
      src/Core/Worker.php
  39. 22
      src/Database/DBStructure.php
  40. 73
      src/Model/Contact.php
  41. 87
      src/Model/GContact.php
  42. 23
      src/Model/Item.php
  43. 2
      src/Model/User.php
  44. 4
      src/Protocol/DFRN.php
  45. 55
      src/Protocol/Diaspora.php
  46. 49
      src/Protocol/Feed.php
  47. 122
      src/Protocol/OStatus.php
  48. 11
      src/Protocol/PortableContact.php
  49. 14
      src/Util/Map.php
  50. 7
      src/Util/Network.php
  51. 9
      src/Worker/OnePoll.php
  52. 7
      util/credits.txt
  53. 5036
      util/messages.po
  54. 8492
      view/lang/de/messages.po
  55. 1716
      view/lang/de/strings.php
  56. 9926
      view/lang/en-gb/messages.po
  57. 2063
      view/lang/en-gb/strings.php
  58. 9920
      view/lang/en-us/messages.po
  59. 1993
      view/lang/en-us/strings.php
  60. 14073
      view/lang/it/messages.po
  61. 2551
      view/lang/it/strings.php
  62. 10100
      view/lang/zh-cn/messages.po
  63. 1612
      view/lang/zh-cn/strings.php
  64. 18
      view/templates/delegate.tpl
  65. 8
      view/templates/field_datetime.tpl
  66. 2
      view/templates/htconfig.tpl
  67. 2
      view/templates/settings/connectors.tpl
  68. 2
      view/theme/frio/php/schema.php
  69. 4
      view/theme/frio/templates/settings/connectors.tpl
  70. 41
      view/theme/vier/style.php

128
CHANGELOG

@ -1,3 +1,129 @@
Version 3.6 (2018-03-23)
Friendica Core:
Updates to the translations (DE, EN_GB, EN_US, ES, FR, IT, ZH_CN) [translation teams]
Updates for the Danish and French regions [Alkarex]
Update for the documentation [andyhee, annando, rabuzarus, ratten, rudlof, silke, tobiasd]
Updates to the themes [Andi-K, annando, fabrixxm, hoergen, rebeka-catalina, rabuzarus]
Enhancements to the ARIA support in frio [rabuzarus]
Enhancements to the DB handling and structure [annando]
Enhancements to the API [annando, fabrixxm, MrPetovan, rudlof]
Enhancements to the support of Open Graph with images [hoergen]
Enhancements to the Diaspora federation (participation signal, relay of dislikes, basic forum support for D*, Birthdays) [annando]
Enhancements to the OStatus federation [annando]
Enhancements to the handling of feed contacts [MrPetovan]
Enhancements to the display of threaded discussions (optional) [MrPetovan]
Enhancements to the display of events [hoergen]
Enhancements to the ACL dialog (selection of forums) [rabuzarus]
Enhancements to the handling of new connections [annando]
Enhancements to the vitality check of contacts [annando]
Enhancements to the daemon script [annando]
Enhancements to the federation stats [annando, tobiasd]
Enhancements to the interaction with public posts [annando]
Enhancements to the structure of the admin panel [tobiasd]
Enhancements to the community page [annando]
Enhancements to the delegation of accounts [annando, MrPetovan]
Enhancements to the user import and server relocation functionality [annando]
Enhancements to the menu layout in the admin panel [tobiasd]
Enhancements to the extraction of strings to be translated [fabrixxm, MrPetovan]
Enhancements to the installation wizard [annando, tobias]
Enhancements to the events [annando, hoergen, MrPetovan, rabuzarus]
Enhancements to the handling of email contacts [annando]
Enhancements to the Vagrant configuration of the development VM [tobias]
Enhancements to the probing of pump.io profiles [annando]
Enhancements to the handling of BBCode tags [MrPetovan]
Enhancements to the OEmbed handling [MrPetovan]
Fixed a bug that triggered the display of activities on the cummunity page [annando]
Fixed a bug with personal notes [annando]
Fixed a display issue of long postings when using the showmore option [annando]
Fixed a bug that caused Twidere to crash on reload [annando]
Fixed a bug in the exported data to the-federation.info [annando]
Fixed a bug in URL completion for feed fragments [annando]
Fixed a bug in the notification system about new registrations [annando]
Fixed the display of dislikes [annando]
Fixed the display of orphans childs in threads [MrPetovan]
Fixed some SQL problems [annando]
Fixed the CLI config script [tobiasd]
Fixed the forum selection on the network display [annando]
Fixed a bug during the import of accounts [annando]
Fixed a problem with UTF8 encoding during account export [annando]
Fixed a problem with archiving "self" contacts [annando]
Fixes to file permissions lintian reported [tobiasd]
Fixed a session problem leading to double login problem [MrPetovan]
Fixed a bug that caused code blocks on Diaspora being displayed wrongly [MrPetovan]
Fixed a bug that suggested it was possible to use some bridges without an account on the other side [annando]
Fixed the situation that an OStatus activity was triggered when publishing a image without sending out a posting for it [annando]
Fixed some issues with the display of exported events on GNU social and diaspora [annando]
Fixed the issue that Atom feeds of forums had no postings listed [annando]
Fixed a problem with the expiration of accounts [annando]
Added Atom feed for conversations [annando]
Added the possibility to address forums with !forumname [annando]
Added option to compare version against upstream version [tobiasd]
Added an optional hint that a global community page is global [tobiasd]
Added an option to always display the preview image in shared articles even if larger ones exist [annando]
Added CLI script to silence accounts on the community page [tobiasd]
Added CLI script to block postings to a node from accounts [tobiasd]
Added account block interface to the admin panel [MrPetovan]
Added browser bookmarklet code snippet [hoergen]
Added an additional feature to display a tag cloud on the profile page [rabuzarus]
Added retrieval of Mastodon server statistics [annando]
Added Atom feed that only contains top level postings of a user [annando]
Added tag following via saved search for #hashtag [annando]
Added PHP version information to the admin panel [MrPetovan]
Added the possibility to change relationships between Friendica contacts [annando]
Added the membersince functionality from the addon to the core [rabuzarus]
Added support of nodeinfo 2.0 [annando]
Removed the long deprecated internal templating engine [annando]
Removed the obsolete mysql support, you have to use MySQLI or PDO [annando]
Removed the unused mood module [annando]
Removed connect link from side panel when it should not be there [annando]
Removed very old updating routines [annando]
Dependencies are now (mostly) handled by composer [MrPetovan, zeroadam]
General code refactoring and beautification work [annando, MrPetovan, tobiasd, zeroadam]
ejabberd logs are now handled by syslog [annando]
Moved the poller script to the "scripts" directory and renamed it to worker [annando]
Threaded display of conversations is now always enabled [annando]
Images send to public forums are now always public as well [annando]
The DB cleanup option now includes the conversation table [annando]
Hash tags now always search locally [annando]
Consistent naming of addons (instead of plugins and addons) [zeroadam]
Community page is split between local and global and always visible for local users [annando]
Updated the credits to include new contributors [tobiasd]
Friendica Addons:
Updates to the translations (DE, EN_GB, ES, FR, IT, NL, ZH_CN) [translation teams]
all bridges don't relay postings anymore that are posted to a public forum [annando]
DAV addon marked unsupported [tobiasd]
Current Weather: fixing a problem with the weathermap link [zeroadam]
NSFW added config examples, reworked the description, now ignores the CW from Mastodon [andyhee, annando, rebeka-catalina]
Twitter support 280 chars limit [annando]
OpenWeatherMap fix broken map link [zeroadam]
CommunityHome added settings to admin panel, removed active users feature [annando, fabrixxm]
General code refactoring and beautification work [annando, MrPetovan, tobiasd, zeroadam]
Public Server reworked [annando]
pageheader settings beautifications [tobiasd]
mailstream settings beautifications [tobiasd]
Membersince is now part of the core [rabuzarus]
Forum posts are not transmitted over the connectors anymore [annando]
Friendica Dir:
Fixed a problem with the maintenance cron [MrPetovan]
Fixed a problem with the location widget [MrPetovan]
Work on the UI [MrPetovan]
Closed Issues:
929, 1050, 1056, 1125, 1215, 1251, 1289, 1312, 1429, 1488, 1540,
1610, 1858, 2786, 2845, 3020, 3039, 3337, 3379, 3394, 3396, 3566,
3583, 3661, 3671, 3680, 3801, 3822, 3824, 3828, 3839, 3855, 3857,
3860, 3863, 3867, 3905, 3911, 3916, 3942, 3946, 3999, 4013, 4020,
4023, 4041, 4042, 4061, 4069, 4070, 4071, 4075, 4078, 4082, 4094,
4105, 4115, 4116, 4137, 4141, 4144, 4150, 4155, 4161, 4163, 4173,
4184, 4199, 4200, 4207, 4227, 4228, 4236, 4251, 4272, 4273, 4278,
4279, 4281, 4290, 4294, 4295, 4296, 4304, 4306, 4319, 4348, 4362,
4368, 4369, 4377, 4390, 4395, 4396, 4409, 4412, 4426, 4431, 4445,
4450, 4452, 4458, 4463, 4481, 4482, 4495, 4497, 4498, 4508, 4518,
4520, 4522, 4535, 4543, 4550, 4555, 4556, 4571, 4575, 4610, 4611,
4620
Version 3.5.4 (2017-10-16)
Friendica Core:
Updates to the translations (DE) [translation teams]
@ -90,7 +216,7 @@ Version 3.5.2 (2017-06-06)
Updates to the translations (DE, EN-GB, EN-US, ES, IT, PT-BR, RU) [translation teams]
Updates to the documentation [annando, beardyunixer, rabuzarus, tobiasd]
Updated the nginx example configuration [beardyunixer]
Code revision and refactoring [annando, hypolite, Quix0r, rebeka-catalina]
Code revision and refactoring [annando, MrPetovan, Quix0r, rebeka-catalina]
Background process is now done by the new worker process [annando]
Added support of Composer for dependencies [Hypolite]
Added support of Web app manifests [Rudloff]

26
INSTALL.txt

@ -37,10 +37,12 @@ local .htaccess file
- PHP *command line* access with register_argc_argv set to true in the
php.ini file [or see 'poormancron' in section 8]
- curl, gd (with at least jpeg support), mysql, mbstring, xml and openssl extensions
- curl, gd (with at least jpeg support), mysql, mbstring, xml, zip and openssl extensions
- some form of email server or email gateway such that PHP mail() works
- The POSIX module of PHP needs to be activated (e.g. RHEL, CentOS have disabled it)
- Mysql 5.5.3+ or an equivalant alternative for MySQL (MariaDB, Percona Server etc.)
- ability to schedule jobs with cron (Linux/Mac) or Scheduled Tasks
@ -129,24 +131,16 @@ assistance. Friendica will not work correctly if you cannot perform this step.
You should also be sure that $a->config['php_path'] is set correctly, it should
look like (changing it to the correct PHP location)
$a->config['php_path'] = '/usr/local/php53/bin/php'
Alternative: You may be able to use the 'poormancron' addon to perform this
step if you are using a recent Friendica release. 'poormancron' may result in
perfomance and memory issues and is only suitable for small sites with one or
two users and a handful of contacts. To do this, edit the file
".htconfig.php" and look for a line describing your addons. On a fresh
installation, it will look like
$a->config['system']['addon'] = 'js_upload';
$a->config['php_path'] = '/usr/local/php56/bin/php'
This indicates the "js_upload" addon module is enabled. You may add additional
addons using this same line in the configuration file. Change it to
read
Alternative: If you cannot use a cron job as described above, you can use
the frontend worker and an external cron service to trigger the execution
of the worker script. You can enable the frontend worker after the installation
from the admin panel of your node and call
$a->config['system']['addon'] = 'js_upload,poormancron';
https://example.com/worker
and save your changes.
with the service of your choice.
9. (Recommended) Set up a backup plan

2
VERSION

@ -1 +1 @@
3.6-dev
3.6

2
bin/worker.php

@ -39,7 +39,7 @@ Config::load();
check_db(true);
// Quit when in maintenance
if (Config::get('system', 'maintenance', true)) {
if (Config::get('system', 'maintenance', false, true)) {
return;
}

4
boot.php

@ -38,8 +38,8 @@ use Friendica\Util\DateTimeFormat;
require_once 'include/text.php';
define('FRIENDICA_PLATFORM', 'Friendica');
define('FRIENDICA_CODENAME', 'Asparagus');
define('FRIENDICA_VERSION', '3.6-dev');
define('FRIENDICA_CODENAME', 'The Tazmans Flax-lily');
define('FRIENDICA_VERSION', '3.6');
define('DFRN_PROTOCOL_VERSION', '2.23');
define('DB_UPDATE_VERSION', 1256);
define('NEW_UPDATE_ROUTINE_VERSION', 1170);

3
database.sql

@ -1,5 +1,5 @@
-- ------------------------------------------
-- Friendica 3.6-dev (Asparagus)
-- Friendica 2018-05-dev (Tazmans Flax-lilly)
-- DB_UPDATE_VERSION 1256
-- ------------------------------------------
@ -466,6 +466,7 @@ CREATE TABLE IF NOT EXISTS `item` (
`author-link` varchar(255) NOT NULL DEFAULT '' COMMENT '',
`author-avatar` varchar(255) NOT NULL DEFAULT '' COMMENT '',
`title` varchar(255) NOT NULL DEFAULT '' COMMENT '',
`content-warning` varchar(255) NOT NULL DEFAULT '' COMMENT '',
`body` mediumtext COMMENT '',
`app` varchar(255) NOT NULL DEFAULT '' COMMENT '',
`verb` varchar(100) NOT NULL DEFAULT '' COMMENT '',

3
doc/Developers-Intro.md

@ -16,7 +16,6 @@ Whether you feel like an expert or like a newbie - join us with your ideas!
The discussion of Friendica development takes place in the following Friendica forums:
* The main [forum for Friendica development](https://forum.friendi.ca/profile/developers)
* The [forum for Friendica theme development](https://friendica.eu/profile/ftdevs)
## Help other users
@ -141,7 +140,7 @@ If you want to get involved here:
* Look at the first steps that were made (e.g. the clean theme).
Ask us to find out whom to talk to about their experiences.
* Talk to design people if you know any.
* Let us know about your plans [in the dev forum](https://forum.friendi.ca/profile/developers) or the [theme developer forum](https://friendica.eu/profile/ftdevs).
* Let us know about your plans [in the dev forum](https://forum.friendi.ca/profile/developers)
Do not worry about cross-posting.
### Client software

26
doc/FAQ.md

@ -70,7 +70,8 @@ See Wikipedia for more of them ([video](http://en.wikipedia.org/wiki/HTML5_video
<a name="avatars"></a>
### Is it possible to have different avatars per profile?
Yes. On your Edit/Manage Profiles page, you will find a "change profile photo" link.
Yes.
On your Edit/Manage Profiles page, you will find a "change profile photo" link.
Clicking this will take you to a page where you can upload a photograph and select which profile it will be associated with.
To avoid privacy leakage, we only display the photograph associated with your default profile as the avatar in your posts.
@ -111,15 +112,9 @@ After that, your account is deleted.
<a name="hashtag"></a>
### Can I follow a hashtag?
No. The act of 'following' a hashtags is an interesting technology, but presents a few issues.
1. Posts would have to be copied to all sites on the network that are "listening" to that hashtag. This would increase the storage demands to the detriment of small sites. It would make the use of shared hosting practically impossible.
2. Making spam easy (tag spam is a serious issue on Twitter for instance)
3. It creates a natural bias towards large sites which hold more tagged content - if your network uses tagging instead of other conversation federation mechanisms such as groups/forums.
Instead, we offer other mechanisms for wide-area conversations while retaining a 'level playing ground' for both large and small sites, such as forums and community pages and shared tags.
Yes. Simply add the hash tag to your saved searches.
The posts will appear on your network page.
For technical reasons, your answers to such posts won't appear on the "personal" tab in the network page and the whole thread isn't accessible via the API.
<a name="rss"></a>
### How to create a RSS feed of the stream?
@ -171,10 +166,15 @@ Depending on the features of the client you might encounter some glitches in usa
### Where I can find help?
If you have problems with your Friendica page, you can ask the community at the [Friendica Support Group](https://forum.friendi.ca/profile/helpers).
If you can't use your default profile you can use an account at a public site [list](https://dir.friendica.social/servers) or you can use the Librelist mailing list.
If you want to use the mailing list, please just send a mail to friendica AT librelist DOT com.
If you can't use your default profile you can use an account at a public site [list](https://dir.friendica.social/servers).
In case you do not want to set up another account on Friendica, you can also use one of the following channels to reach out for help:
If you are a theme developer, you will find help at this forum: [Friendica Theme Developers](https://friendica.eu/profile/ftdevs).
* [Friendica Support Forum](https://forum.friendi.ca/~helpers)
* [Mailing List Archive](http://mailman.friendi.ca/mailman/listinfo/support-friendi.ca) you can subscribe to the list by sending an email to ``support-request(at)friendi.ca?subject=subscribe``
* XMPP/Jabber MUC: support(at)forum.friendi.ca
* IRC: #friendica at irc.freenode.net
* Matrix: #friendi.ca or #friendica at matrix.org
Admin
--------

14
doc/Install.md

@ -28,7 +28,8 @@ Requirements
* Apache with mod-rewrite enabled and "Options All" so you can use a local .htaccess file
* PHP 5.6+ (PHP 7 is recommended for performance)
* PHP *command line* access with register_argc_argv set to true in the php.ini file
* Curl, GD, PDO, MySQLi, hash, xml and OpenSSL extensions
* Curl, GD, PDO, MySQLi, hash, xml, zip and OpenSSL extensions
* The POSIX module of PHP needs to be activated (e.g. [RHEL, CentOS](http://www.bigsoft.co.uk/blog/index.php/2014/12/08/posix-php-commands-not-working-under-centos-7) have disabled it)
* some form of email server or email gateway such that PHP mail() works
* Mysql 5.5.3+ or an equivalant alternative for MySQL (MariaDB, Percona Server etc.)
* the ability to schedule jobs with cron (Linux/Mac) or Scheduled Tasks (Windows) (Note: other options are presented in Section 7 of this document.)
@ -38,7 +39,7 @@ Requirements
Installation procedure
---
###Get Friendica
### Get Friendica
Unpack the Friendica files into the root of your web server document area.
If you are able to do so, we recommend using git to clone the source repository rather than to use a packaged tar or zip file.
@ -64,7 +65,7 @@ Clone the addon repository (separately):
If you copy the directory tree to your webserver, make sure that you also copy .htaccess - as "dot" files are often hidden and aren't normally copied.
###Create a database
### Create a database
Create an empty database and note the access details (hostname, username, password, database name).
@ -79,7 +80,7 @@ In this case find the [mysqld] section in your my.cnf file and add the line :
Restart mysql and you should be fine.
###Run the installer
### Run the installer
Point your web browser to the new site and follow the instructions.
Please note any error messages and correct these before continuing.
@ -96,7 +97,7 @@ Registration errors should all be recoverable automatically.
If you get any *critical* failure at this point, it generally indicates the database was not installed correctly.
You might wish to move/rename .htconfig.php to another name and empty (called 'dropping') the database tables, so that you can start fresh.
###Set up the worker
### Set up the worker
Set up a cron job or scheduled task to run the worker once every 5-10 minutes in order to perform background processing.
Example:
@ -118,7 +119,8 @@ If it is not possible to set up a cron job then please activate the "frontend wo
Once you have installed Friendica and created an admin account as part of the process, you can access the admin panel of your installation and do most of the server wide configuration from there
###Set up a backup plan
### Set up a backup plan
Bad things will happen.
Let there be a hardware failure, a corrupted database or whatever you can think of.
So once the installation of your Friendica node is done, you should make yourself a backup plan.

23
doc/Settings.md

@ -57,6 +57,21 @@ The `vier` theme for instance is mobile friendly.
### Registration
#### Register policy
With this drop down selector you can set the nodes registration policy.
You can chose between the following modes:
* **open**: Everybody can register a new account and start using it right away.
* **requires approval**: Everybody can register a new account, but the admin has to approve it before it can be used.
* **closed**: No new registrations are possible.
##### Invitation based registry
Additionally to the setting in the admin panel, you can devide if registrations are only possible using an invitation code or not.
To enable invitation based registration, you have to set the `invitation_only` setting in the [.htconfig.php](/help/htconfig) file.
If you want to use this method, the registration policy has to be set to either *open* or *requires approval*.
#### Check Full Names
You may find a lot of spammers trying to register on your site.
@ -111,6 +126,14 @@ Unauthorised persons will also not be able to request friendship with site membe
Default is false.
Available in version 2.2 or greater.
#### Community pages for Visitors
The community pages show all public postings, separated by their origin being local or the entire network.
With this setting you can select which community pages will be shown to visitors of your Friendica node.
Your local users will always have access to both pages.
**Note**: Several settings, like users hiding their contacts from the public will prevent the postings to show up on the global community page.
#### Allowed Friend Domains
Comma separated list of domains which are allowed to establish friendships with this site.

37
doc/de/FAQ.md

@ -10,7 +10,7 @@ Nutzer
* **[Ist es möglich, bei mehreren Profilen verschiedene Avatare (Nutzerbilder) zu haben?](help/FAQ#avatars)**
* **[Was ist der Unterschied zwischen blockierten|ignorierten|archivierten|versteckten Kontakten?](help/FAQ#contacts)**
* **[Was passiert, wenn ein Account gelöscht ist? Ist dieser richtig gelöscht?](help/FAQ#removed)**
* **[Kann ich einem hashtag folgen?](help/FAQ#hashtag)**
* **[Kann ich einem Hashtag folgen?](help/FAQ#hashtag)**
* **[Wie kann ich einen RSS-Feed meiner Netzwerkseite (Stream) erstellen?](help/FAQ#rss)**
* **[Gibt es Clients für Friendica?](help/FAQ#clients)**
* **[Wo finde ich Hilfe?](help/FAQ#help)**
@ -85,9 +85,9 @@ Zum Konvertieren von Videos in das lizenfreie Videoformat WebM gibt es unter Win
### Ist es möglich, bei mehreren Profilen verschiedene Avatare (Nutzerbilder) zu haben?
Ja.
Auf Deiner ["Profile verwalten/editieren"-Seite](../profiles) wählst Du zunächst das gewünschte Profil aus.
Anschließend siehst Du eine Seite mit allen Infos zu diesem Profil.
Klicke nun oben auf den Link "Profilbild ändern" und lade im nächsten Fenster ein Bild von Deinem PC hoch.
Auf Deiner ["Profile verwalten/editieren"-Seite](../profiles) wählst Du zunächst das gewünschte Profil aus.
Anschließend siehst Du eine Seite mit allen Infos zu diesem Profil.
Klicke nun oben auf den Link "Profilbild ändern" und lade im nächsten Fenster ein Bild von Deinem PC hoch.
Um Deine privaten Daten zu schützen, wird in Beiträgen nur das Bild aus Deinem öffentlichen Profil angezeigt.
<a name="contacts"></a>
@ -122,19 +122,11 @@ Dieses Vorgehen setzt voraus, dass Dein Profil für 24 Stunden weiterhin "teilwe
Wir können also Dein Profil blockieren und es so erscheinen lassen, als wären alle Daten sofort gelöscht, allerdings warten wir 24 Stunden (bzw. bis alle Deine Kontakte informiert wurden), bevor wir die Daten auch physikalisch löschen.
<a name="hashtag"></a>
### Kann ich einem hashtag folgen?
### Kann ich einem Hashtag folgen?
Nein.
Die Möglichkeit, einem hashtag zu folgen, ist eine interessante Technik, führt aber zu einigen Schwierigkeiten.
1.) Alle Beiträge, die diesen tag nutzen, müssten zu allen Seiten im Netzwerk kopiert werden. Das erhöht den Speicherbedarf und beeinträchtigt kleine Seiten. Die Nutzung von geteilten Hosting-Angeboten (Shared Hosting) wäre praktisch unmöglich.
2.) Die Verbreitung von Spam wäre vereinfacht (tag-Spam ist z.B. bei Twitter ein schwerwiegendes Problem)
3.) Der wichtigste Grund der gegen diese Technik spricht ist, dass sie eine natürliche Ausrichtung auf größere Seiten mit mehr getaggten Inhalten zur Folge hat. Dies kann z.B. aufkommen, wenn Dein Netzwerk tags anstelle von anderen Kommunikationsmitteln wie Gruppen oder Foren nutzt.
Stattdessen bieten wir andere Mechanismen, um globale Unterhaltungen zu erreichen, dabei aber eine angemesse Basis für kleine und große Seiten zu bieten.
Hierzu gehören Foren, Gruppen und geteilte tags.
Ja.
Füge die Tags zu Deinen gespeicherten Suchen hinzu, sie werden automatisch auf der Netzwerk-Seite auftauchen.
Bitte beachte, dass Deine Antworten auf solche Posts aus technischen Gründen nicht unter dem "Persönlich"-Reiter auf der Netzwerk-Seite und der gesamte Thread nicht per API zu sehen sind.
<a name="rss"></a>
### Wie kann ich einen RSS-Feed meiner Netzwerkseite (Stream) erstellen?
@ -188,11 +180,16 @@ Hier ist eine Liste von Clients bei denen dies möglich ist, bzw. die speziell f
<a name="help"></a>
### Wo finde ich Hilfe?
Wenn Du Probleme mit Deiner Friendica-Seite hast, dann kannst Du die Community in der [Friendica-Support-Gruppe](https://forum.friendi.ca/profile/helpers) oder im [deutschen Friendica-Support-Forum](http://toktan.org/profile/wiki) fragen oder Dir das [deutsche Wiki](http://wiki.toktan.org/doku.php) anschauen.
Wenn Du Deinen Account nicht nutzen kannst, kannst Du entweder einen [Testaccount](https://tryfriendica.de) bzw. einen Account auf einer öffentlichen Seite ([Liste](https://dir.friendica.social/servers)) nutzen, oder Du wählst die Librelist-mailing-Liste.
Wenn Du die Mailing-Liste nutzen willst, schicke eine Mail an friendica AT librelist PUNKT com.
Wenn Du Probleme mit Deiner Friendica-Seite hast, dann kannst Du die Community in der [Friendica-Support-Gruppe](https://forum.friendi.ca/profile/helpers) oder im [deutschen Friendica-Support-Forum](http://toktan.org/profile/wiki) fragen oder Dir das [deutsche Wiki](http://wiki.toktan.org/doku.php) anschauen.
Wenn Du Deinen Account nicht nutzen kannst, kannst Du entweder einen [Testaccount](https://tryfriendica.de) bzw. einen Account auf einer öffentlichen Seite ([Liste](https://dir.friendica.social/servers)) nutzen.
Wenn du dir keinen weiteren Friendica Account einrichten willst, kannst du auch gerne über einen der folgenden alternativen Kanäle Hilfe suchen:
Wenn Du ein Theme-Entwickler bist, wirst Du in diesem Forum Hilfe finden: [Friendica Theme Developers](https://friendica.eu/profile/ftdevs).
* [Friendica Support Forum](https://forum.friendi.ca/~helpers)
* [Mailing List Archive](http://mailman.friendi.ca/mailman/listinfo/support-friendi.ca) you can subscribe to the list by sending an email to ``support-request(at)friendi.ca?subject=subscribe``
* XMPP/Jabber MUC: support(at)forum.friendi.ca
* IRC: #friendica at irc.freenode.net
* Matrix: #friendi.ca or #friendica at matrix.org.
Admin
--------

3
doc/de/Install.md

@ -24,8 +24,9 @@ Wir planen, diese Einschränkung in einer zukünftigen Version zu beheben.
- Apache mit einer aktiverten mod-rewrite-Funktion und dem Eintrag "Options All", so dass du die lokale .htaccess-Datei nutzen kannst
- PHP 5.6+. Je neuer, desto besser.
- PHP *Kommandozeilen*-Zugang mit register_argc_argv auf "true" gesetzt in der php.ini-Datei
- Curl, GD, PDO, MySQLi, xml und OpenSSL-Erweiterung
- Curl, GD, PDO, MySQLi, xml, zip und OpenSSL-Erweiterung
- etwas in der Art eines Email-Servers oder eines Gateways wie PHP mail()
- Das POSIX Modul muss aktiviert sein ([CentOS, RHEL](http://www.bigsoft.co.uk/blog/index.php/2014/12/08/posix-php-commands-not-working-under-centos-7http://www.bigsoft.co.uk/blog/index.php/2014/12/08/posix-php-commands-not-working-under-centos-7) haben dies z.B. deaktiviert)
- Mysql 5.5.3+
- die Möglichkeit, wiederkehrende Aufgaben mit cron (Linux/Mac) oder "Scheduled Tasks" einzustellen (Windows) [Beachte: andere Optionen sind in Abschnitt 7 dieser Dokumentation zu finden]
- Installation in einer Top-Level-Domain oder Subdomain (ohne eine Verzeichnis/Pfad-Komponente in der URL) wird bevorzugt. Verzeichnispfade sind für diesen Zweck nicht so günstig und wurden auch nicht ausführlich getestet.

23
doc/de/Settings.md

@ -54,6 +54,20 @@ Das `vier` Theme z.B. unterstützt kleine Anzeigen und benötigt kein zusätzlic
### Registrierung
#### Registrierungsmethode
Diese Einstellung regelt die Art der Registrierung.
Dabei kannst du zwischen den folgenden Optionen wählen:
* **Offen**: Jeder kann ein neues Nutzerkonto anlegen und es sofort benutzen.
* **Bedarf der Zustimmung**: Jeder kann ein Nutzerkonto anlegen. Dieses muss allerdings durch den Admin freigeschaltet werden, bevor es verwendet werden kann.
* **Geschlossen**: Es können keine weiteren Nutzerkonten angelegt werden.
##### Einladungen
Zusätzlich zu den oben genannten Möglichkeiten, kann die Registrierung eines neuen Nutzerkontos an eine Einladung durch einen bestehenden Nutzer gekoppelt werden.
Hierzu muss in der [.htconfig.php](/help/htconfig) Datei die Option `invitation_only` aktiviert und als Registrierungsmethode entweder *Offen* oder *Bedarf der Zustimmung* gewählt werden.
#### Namen auf Vollständigkeit überprüfen
Es kann vorkommen, dass viele Spammer versuchen, sich auf deiner Seite zu registrieren.
@ -108,6 +122,15 @@ Unautorisierte Personen haben ebenfalls nicht die Möglichkeit, Freundschaftsanf
Die Standardeinstellung ist deaktiviert.
Verfügbar in Version 2.2 und höher.
#### Für Besucher verfügbare Gemeinschaftsseiten
Die Gemeinschaftsseiten zeigen all öffentlichen Beiträge.
Es gibt zwei Gemeinschaftsseiten, eine lokale auf der die Beiträge der Nutzer des Knotens gesammelt werden und eine globale auf der alle bekannten Beiträge aus dem gesamten Netzwerk erscheinen.
Mit dieser Einstellung kann geregelt werden, welche dieser beiden Seiten Besucher aufrufen können.
Angemeldete Nutzer des Knotens können grundsätzlich beide Seiten verwenden.
**Hinweis**: Einige Einstellungen, wie z.B. das Verbergen von Kontakten auf der Profilseite, können die Sichtbarkeit der Beiträge auf der Gemeinschaftsseiten beeinflussen.
#### Erlaubte Domains für Kontakte
Kommagetrennte Liste von Domains, welche eine Freundschaft mit dieser Seite eingehen dürfen.

1
doc/htconfig.md

@ -49,6 +49,7 @@ Example: To set the automatic database cleanup process add this line to your .ht
* **ignore_cache** (Boolean) - For development only. Disables the item cache.
* **instances_social_key** - Key to the API of https://instances.social which retrieves data about mastodon servers. See https://instances.social/api/token to get an API key.
* **ipv4_resolve** (Boolean) - Resolve IPV4 addresses only. Don't resolve to IPV6. Default value is false.
* **invitation_only** (Boolean) - If set true registration is only possible after a current member of the node has send an invitation. Default is false.
* **like_no_comment** (Boolean) - Don't update the "commented" value of an item when it is liked.
* **local_block** (Boolean) - Used in conjunction with "block_public".
* **local_search** (Boolean) - Blocks search for users who are not logged in to prevent crawlers from blocking your system.

3
doc/themes.md

@ -6,7 +6,6 @@ To change the look of friendica you have to touch the themes.
The current default theme is [Vier](https://github.com/friendica/friendica/tree/master/view/theme/vier) but there are numerous others.
Have a look at [friendica-themes.com](http://friendica-themes.com) for an overview of the existing themes.
In case none of them suits your needs, there are several ways to change a theme.
If you need help theming, there is a forum @[ftdevs@friendica.eu](https://friendica.eu/profile/ftdevs) where you can ask theme specific questions and present your themes.
So, how to work on the UI of friendica.
@ -206,7 +205,7 @@ Basically what you have to do is identify which template you have to change so i
Adopt the CSS of the theme accordingly.
And iterate the process until you have the theme the way you want it.
*Use the source Luke.* and don't hesitate to ask in @[ftdevs](https://friendica.eu/profile/ftdevs) or @[helpers](https://forum.friendi.ca/profile/helpers).
*Use the source Luke.* and don't hesitate to ask in @[developers](https://forum.friendi.ca/profile/developers) or @[helpers](https://forum.friendi.ca/profile/helpers).
## Special Files

8
include/api.php

@ -5931,10 +5931,12 @@ function api_saved_searches_list($type)
$result = [];
while ($term = $terms->fetch()) {
$result[] = [
'name' => $term['term'],
'query' => $term['term'],
'created_at' => api_date(time()),
'id' => intval($term['id']),
'id_str' => $term['id'],
'id' => intval($term['id'])
'name' => $term['term'],
'position' => null,
'query' => $term['term']
];
}

6
include/conversation.php

@ -443,7 +443,7 @@ These Fields are not added below (yet). They are here to for bug search.
return "`item`.`author-id`, `item`.`author-link`, `item`.`author-name`, `item`.`author-avatar`,
`item`.`owner-id`, `item`.`owner-link`, `item`.`owner-name`, `item`.`owner-avatar`,
`item`.`contact-id`, `item`.`uid`, `item`.`id`, `item`.`parent`,
`item`.`uri`, `item`.`thr-parent`, `item`.`parent-uri`,
`item`.`uri`, `item`.`thr-parent`, `item`.`parent-uri`, `item`.`content-warning`,
`item`.`commented`, `item`.`created`, `item`.`edited`, `item`.`received`,
`item`.`verb`, `item`.`object-type`, `item`.`postopts`, `item`.`plink`,
`item`.`guid`, `item`.`wall`, `item`.`private`, `item`.`starred`,
@ -1245,7 +1245,7 @@ function format_like($cnt, array $arr, $type, $id) {
break;
case 'attendmaybe':
$phrase = L10n::t('<span %1$s>%2$d people</span> attend maybe', $spanatts, $cnt);
$explikers = L10n::t('%s anttend maybe.', $likers);
$explikers = L10n::t('%s attend maybe.', $likers);
break;
}
@ -1643,7 +1643,7 @@ function get_responses($conv_responses, $response_verbs, $ob, $item) {
foreach ($response_verbs as $v) {
$ret[$v] = [];
$ret[$v]['count'] = defaults($conv_responses[$v], $item['uri'], '');
$ret[$v]['list'] = defaults($conv_responses[$v], $item['uri'] . '-l', '');
$ret[$v]['list'] = defaults($conv_responses[$v], $item['uri'] . '-l', []);
$ret[$v]['self'] = defaults($conv_responses[$v], $item['uri'] . '-self', '0');
if (count($ret[$v]['list']) > MAX_LIKERS) {
$ret[$v]['list_part'] = array_slice($ret[$v]['list'], 0, MAX_LIKERS);

10
include/enotify.php

@ -16,10 +16,10 @@ use Friendica\Util\Emailer;
* @brief Creates a notification entry and possibly sends a mail
*
* @param array $params Array with the elements:
uid, item, parent, type, otype, verb, event,
link, subject, body, to_name, to_email, source_name,
source_link, activity, preamble, notify_flags,
language, show_in_notification_page
* uid, item, parent, type, otype, verb, event,
* link, subject, body, to_name, to_email, source_name,
* source_link, activity, preamble, notify_flags,
* language, show_in_notification_page
*/
function notification($params)
{
@ -368,7 +368,7 @@ function notification($params)
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]'
);
$body = L10n::t('Full Name: %1$s\nSite Location: %2$s\nLogin Name: %3$s ' . "\x28" . '%4$s' . "\x28",
$body = L10n::t('Full Name: %1$s\nSite Location: %2$s\nLogin Name: %3$s ' . "\x28" . '%4$s' . "\x29",
$params['source_name'],
$siteurl, $params['source_mail'],
$params['source_nick']

24
include/event.php

@ -38,9 +38,9 @@ function format_event_html($ev, $simple = false) {
);
if ($simple) {
$o = "<h3>" . BBCode::convert($ev['summary']) . "</h3>";
$o = "<h3>" . BBCode::convert($ev['summary'], false, $simple) . "</h3>";
$o .= "<div>" . BBCode::convert($ev['desc']) . "</div>";
$o .= "<p>" . BBCode::convert($ev['desc'], false, $simple) . "</p>";
$o .= "<h4>" . L10n::t('Starts:') . "</h4><p>" . $event_start . "</p>";
@ -49,7 +49,7 @@ function format_event_html($ev, $simple = false) {
}
if (strlen($ev['location'])) {
$o .= "<h4>" . L10n::t('Location:') . "</h4><p>" . $ev['location'] . "</p>";
$o .= "<h4>" . L10n::t('Location:') . "</h4><p>" . BBCode::convert($ev['location'], false, $simple) . "</p>";
}
return $o;
@ -57,7 +57,7 @@ function format_event_html($ev, $simple = false) {
$o = '<div class="vevent">' . "\r\n";
$o .= '<div class="summary event-summary">' . BBCode::convert($ev['summary']) . '</div>' . "\r\n";
$o .= '<div class="summary event-summary">' . BBCode::convert($ev['summary'], false, $simple) . '</div>' . "\r\n";
$o .= '<div class="event-start"><span class="event-label">' . L10n::t('Starts:') . '</span>&nbsp;<span class="dtstart" title="'
. DateTimeFormat::utc($ev['start'], (($ev['adjust']) ? DateTimeFormat::ATOM : 'Y-m-d\TH:i:s' ))
@ -71,16 +71,16 @@ function format_event_html($ev, $simple = false) {
. '</span></div>' . "\r\n";
}
$o .= '<div class="description event-description">' . BBCode::convert($ev['desc']) . '</div>' . "\r\n";
$o .= '<div class="description event-description">' . BBCode::convert($ev['desc'], false, $simple) . '</div>' . "\r\n";
if (strlen($ev['location'])) {
$o .= '<div class="event-location"><span class="event-label">' . L10n::t('Location:') . '</span>&nbsp;<span class="location">'
. BBCode::convert($ev['location'])
. BBCode::convert($ev['location'], false, $simple)
. '</span></div>' . "\r\n";
// Include a map of the location if the [map] BBCode is used.
if (strpos($ev['location'], "[map") !== false) {
$map = Map::byLocation($ev['location']);
$map = Map::byLocation($ev['location'], $simple);
if ($map !== $ev['location']) {
$o.= $map;
}
@ -241,14 +241,20 @@ function event_store($arr) {
$a = get_app();
$arr['created'] = (($arr['created']) ? $arr['created'] : DateTimeFormat::utcNow());
$arr['edited'] = (($arr['edited']) ? $arr['edited'] : DateTimeFormat::utcNow());
$arr['created'] = (($arr['created']) ? DateTimeFormat::utc($arr['created']) : DateTimeFormat::utcNow());
$arr['edited'] = (($arr['edited']) ? DateTimeFormat::utc($arr['edited']) : DateTimeFormat::utcNow());
$arr['start'] = (($arr['start']) ? DateTimeFormat::utc($arr['start']) : NULL_DATE);
$arr['finish'] = (($arr['finish']) ? DateTimeFormat::utc($arr['finish']) : NULL_DATE);
$arr['type'] = (($arr['type']) ? $arr['type'] : 'event' );
$arr['cid'] = ((intval($arr['cid'])) ? intval($arr['cid']) : 0);
$arr['uri'] = (x($arr, 'uri') ? $arr['uri'] : item_new_uri($a->get_hostname(), $arr['uid']));
$arr['private'] = ((x($arr, 'private')) ? intval($arr['private']) : 0);
$arr['guid'] = get_guid(32);
if ($arr['finish'] < NULL_DATE) {
$arr['finish'] = NULL_DATE;
}
if ($arr['cid']) {
$c = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1",
intval($arr['cid']),

4
include/items.php

@ -228,7 +228,7 @@ function add_page_info_to_body($body, $texturl = false, $no_photos = false) {
*
* @TODO find proper type-hints
*/
function consume_feed($xml, $importer, &$contact, &$hub, $datedir = 0, $pass = 0) {
function consume_feed($xml, $importer, $contact, &$hub, $datedir = 0, $pass = 0) {
if ($contact['network'] === NETWORK_OSTATUS) {
if ($pass < 2) {
// Test - remove before flight
@ -290,7 +290,7 @@ function subscribe_to_hub($url, $importer, $contact, $hubmode = 'subscribe') {
return;
}
$push_url = Config::get('system','url') . '/pubsub/' . $r[0]['nickname'] . '/' . $contact['id'];
$push_url = System::baseUrl() . '/pubsub/' . $r[0]['nickname'] . '/' . $contact['id'];
// Use a single verify token, even if multiple hubs
$verify_token = ((strlen($contact['hub-verify'])) ? $contact['hub-verify'] : random_string());

125
include/text.php

@ -1062,7 +1062,7 @@ function linkify($s) {
* Load poke verbs
*
* @return array index is present tense verb
value is array containing past tense verb, translation of present, translation of past
* value is array containing past tense verb, translation of present, translation of past
* @hook poke_verbs pokes array
*/
function get_poke_verbs() {
@ -1169,8 +1169,25 @@ function redir_private_images($a, &$item)
}
}
/**
* Sets the "rendered-html" field of the provided item
*
* Body is preserved to avoid side-effects as we modify it just-in-time for spoilers and private image links
*
* @param array $item
* @param bool $update
*
* @todo Remove reference, simply return "rendered-html" and "rendered-hash"
*/
function put_item_in_cache(&$item, $update = false)
{
$body = $item["body"];
// Add the content warning
if (!empty($item['content-warning'])) {
$item["body"] = $item['content-warning'] . '[spoiler]' . $item["body"] . '[/spoiler]';
}
$rendered_hash = defaults($item, 'rendered-hash', '');
if ($rendered_hash == ''
@ -1178,22 +1195,19 @@ function put_item_in_cache(&$item, $update = false)
|| $rendered_hash != hash("md5", $item["body"])
|| Config::get("system", "ignore_cache")
) {
// The function "redir_private_images" changes the body.
// I'm not sure if we should store it permanently, so we save the old value.
$body = $item["body"];
$a = get_app();
redir_private_images($a, $item);
$item["rendered-html"] = prepare_text($item["body"]);
$item["rendered-hash"] = hash("md5", $item["body"]);
$item["body"] = $body;
if ($update && ($item["id"] > 0)) {
dba::update('item', ['rendered-html' => $item["rendered-html"], 'rendered-hash' => $item["rendered-hash"]],
['id' => $item["id"]], false);
}
}
$item["body"] = $body;
}
/**
@ -1281,62 +1295,55 @@ function prepare_body(&$item, $attach = false, $preview = false) {
$as = '';
$vhead = false;
$arr = explode('[/attach],', $item['attach']);
if (count($arr)) {
foreach ($arr as $r) {
$matches = false;
$icon = '';
$cnt = preg_match_all('|\[attach\]href=\"(.*?)\" length=\"(.*?)\" type=\"(.*?)\" title=\"(.*?)\"|',$r ,$matches, PREG_SET_ORDER);
if ($cnt) {
foreach ($matches as $mtch) {
$mime = $mtch[3];
if ((local_user() == $item['uid']) && ($item['contact-id'] != $a->contact['id']) && ($item['network'] == NETWORK_DFRN)) {
$the_url = 'redir/' . $item['contact-id'] . '?f=1&url=' . $mtch[1];
} else {
$the_url = $mtch[1];
}
if (strpos($mime, 'video') !== false) {
if (!$vhead) {
$vhead = true;
$a->page['htmlhead'] .= replace_macros(get_markup_template('videos_head.tpl'), [
'$baseurl' => System::baseUrl(),
]);
$a->page['end'] .= replace_macros(get_markup_template('videos_end.tpl'), [
'$baseurl' => System::baseUrl(),
]);
}
$id = end(explode('/', $the_url));
$as .= replace_macros(get_markup_template('video_top.tpl'), [
'$video' => [
'id' => $id,
'title' => L10n::t('View Video'),
'src' => $the_url,
'mime' => $mime,
],
]);
}
$filetype = strtolower(substr($mime, 0, strpos($mime, '/')));
if ($filetype) {
$filesubtype = strtolower(substr($mime, strpos($mime, '/') + 1));
$filesubtype = str_replace('.', '-', $filesubtype);
} else {
$filetype = 'unkn';
$filesubtype = 'unkn';
}
$title = ((strlen(trim($mtch[4]))) ? escape_tags(trim($mtch[4])) : escape_tags($mtch[1]));
$title .= ' ' . $mtch[2] . ' ' . L10n::t('bytes');
$icon = '<div class="attachtype icon s22 type-' . $filetype . ' subtype-' . $filesubtype . '"></div>';
$as .= '<a href="' . strip_tags($the_url) . '" title="' . $title . '" class="attachlink" target="_blank" >' . $icon . '</a>';
}
$matches = [];
preg_match_all('|\[attach\]href=\"(.*?)\" length=\"(.*?)\" type=\"(.*?)\"(?: title=\"(.*?)\")?|', $item['attach'], $matches, PREG_SET_ORDER);
foreach ($matches as $mtch) {
$mime = $mtch[3];
if ((local_user() == $item['uid']) && ($item['contact-id'] != $a->contact['id']) && ($item['network'] == NETWORK_DFRN)) {
$the_url = 'redir/' . $item['contact-id'] . '?f=1&url=' . $mtch[1];
} else {
$the_url = $mtch[1];
}
if (strpos($mime, 'video') !== false) {
if (!$vhead) {
$vhead = true;
$a->page['htmlhead'] .= replace_macros(get_markup_template('videos_head.tpl'), [
'$baseurl' => System::baseUrl(),
]);
$a->page['end'] .= replace_macros(get_markup_template('videos_end.tpl'), [
'$baseurl' => System::baseUrl(),
]);
}
$id = end(explode('/', $the_url));
$as .= replace_macros(get_markup_template('video_top.tpl'), [
'$video' => [
'id' => $id,
'title' => L10n::t('View Video'),
'src' => $the_url,
'mime' => $mime,
],
]);
}
$filetype = strtolower(substr($mime, 0, strpos($mime, '/')));
if ($filetype) {
$filesubtype = strtolower(substr($mime, strpos($mime, '/') + 1));
$filesubtype = str_replace('.', '-', $filesubtype);
} else {
$filetype = 'unkn';
$filesubtype = 'unkn';
}
$title = escape_tags(trim(!empty($mtch[4]) ? $mtch[4] : $mtch[1]));
$title .= ' ' . $mtch[2] . ' ' . L10n::t('bytes');
$icon = '<div class="attachtype icon s22 type-' . $filetype . ' subtype-' . $filesubtype . '"></div>';
$as .= '<a href="' . strip_tags($the_url) . '" title="' . $title . '" class="attachlink" target="_blank" >' . $icon . '</a>';
}
if ($as != '') {
$s .= '<div class="body-attach">'.$as.'<div class="clear"></div></div>';
}

2
index.php

@ -74,7 +74,7 @@ if (!$install) {
if (Config::get('system', 'force_ssl') && ($a->get_scheme() == "http")
&& (intval(Config::get('system', 'ssl_policy')) == SSL_POLICY_FULL)
&& (substr(System::baseUrl(), 0, 8) == "https://")
) {
&& ($_SERVER['REQUEST_METHOD'] == 'GET')) {
header("HTTP/1.1 302 Moved Temporarily");
header("Location: " . System::baseUrl() . "/" . $a->query_string);
exit();

2
mod/admin.php

@ -1568,7 +1568,7 @@ function admin_page_users(App $a)
if ($a->argc > 2) {
$uid = $a->argv[3];
$user = dba::selectFirst('user', ['username', 'blocked'], ['uid' => $uid]);
if (DBM::is_result($user)) {
if (!DBM::is_result($user)) {
notice('User not found' . EOL);
goaway('admin/users');
return ''; // NOTREACHED

18
mod/contacts.php

@ -45,6 +45,14 @@ function contacts_init(App $a)
}
if (DBM::is_result($contact)) {
if ($contact['self']) {
if (($a->argc == 3) && intval($a->argv[1]) && ($a->argv[2] == "posts")) {
goaway('profile/' . $contact['nick']);
} else {
goaway('profile/' . $contact['nick'] . '?tab=profile');
}
}
$a->data['contact'] = $contact;
if (($a->data['contact']['network'] != "") && ($a->data['contact']['network'] != NETWORK_DFRN)) {
@ -579,9 +587,10 @@ function contacts_content(App $a)
$profile_select = ContactSelector::profileAssign($contact['profile-id'], (($contact['network'] !== NETWORK_DFRN) ? true : false));
}
/// @todo Only show the following link with DFRN when the remote version supports it
$follow = '';
$follow_text = '';
if (in_array($contact['network'], [NETWORK_DIASPORA, NETWORK_OSTATUS])) {
if (in_array($contact['network'], [NETWORK_DIASPORA, NETWORK_OSTATUS, NETWORK_DFRN])) {
if ($contact['rel'] == CONTACT_IS_FOLLOWER) {
$follow = System::baseUrl(true) . "/follow?url=" . urlencode($contact["url"]);
$follow_text = L10n::t("Connect/Follow");
@ -939,6 +948,13 @@ function _contact_detail_for_template($rr)
$sparkle = '';
}
if ($rr['self']) {
$dir_icon = 'images/larrow.gif';
$alt_text = L10n::t('This is you');
$url = $rr['url'];
$sparkle = '';
}
return [
'img_hover' => L10n::t('Visit %s\'s profile [%s]', $rr['name'], $rr['url']),
'edit_hover' => L10n::t('Edit contact'),

37
mod/delegate.php

@ -6,6 +6,7 @@ use Friendica\App;
use Friendica\Core\L10n;
use Friendica\Core\System;
use Friendica\Database\DBM;
use Friendica\Model\User;
require_once 'mod/settings.php';
@ -28,6 +29,21 @@ function delegate_post(App $a)
check_form_security_token_redirectOnErr('/delegate', 'delegate');
$parent_uid = defaults($_POST, 'parent_user', 0);
$parent_password = defaults($_POST, 'parent_password', '');
if ($parent_uid != 0) {
$user = dba::selectFirst('user', ['nickname'], ['uid' => $parent_uid]);
if (!DBM::is_result($user)) {
notice(L10n::t('Parent user not found.') . EOL);
return;
}
$success = User::authenticate($user['nickname'], trim($parent_password));
if (!$success) {
notice(L10n::t('Permission denied.') . EOL);
return;
}
}
dba::update('user', ['parent-uid' => $parent_uid], ['uid' => local_user()]);
}
@ -70,16 +86,6 @@ function delegate_content(App $a)
goaway(System::baseUrl() . '/delegate');
}
// These people can manage this account/page with full privilege
$full_managers = [];
$r = q("SELECT * FROM `user` WHERE `email` = '%s' AND `password` = '%s' ",
dbesc($a->user['email']),
dbesc($a->user['password'])
);
if (DBM::is_result($r)) {
$full_managers = $r;
}
// find everybody that currently has delegated management to this account/page
$delegates = [];
$r = q("SELECT * FROM `user` WHERE `uid` IN (SELECT `uid` FROM `manage` WHERE `mid` = %d)",
@ -90,10 +96,6 @@ function delegate_content(App $a)
}
$uids = [];
foreach ($full_managers as $rr) {
$uids[] = $rr['uid'];
}
foreach ($delegates as $rr) {
$uids[] = $rr['uid'];
}
@ -153,18 +155,21 @@ function delegate_content(App $a)
}
}
if (!is_null($parent_user)) {
$parent_password = ['parent_password', L10n::t('Parent Password:'), '', L10n::t('Please enter the password of the parent account to legitimize your request.')];
}
$o = replace_macros(get_markup_template('delegate.tpl'), [
'$form_security_token' => get_form_security_token('delegate'),
'$parent_header' => L10n::t('Parent User'),
'$parent_user' => $parent_user,
'$parent_password' => $parent_password,
'$parent_desc' => L10n::t('Parent users have total control about this account, including the account settings. Please double check whom you give this access.'),
'$submit' => L10n::t('Save Settings'),
'$header' => L10n::t('Delegate Page Management'),
'$delegates_header' => L10n::t('Delegates'),
'$base' => System::baseUrl(),
'$desc' => L10n::t('Delegates are able to manage all aspects of this account/page except for basic account settings. Please do not delegate your personal account to anybody that you do not trust completely.'),
'$head_managers' => L10n::t('Existing Page Managers'),
'$managers' => $full_managers,
'$head_delegates' => L10n::t('Existing Page Delegates'),
'$delegates' => $delegates,
'$head_potentials' => L10n::t('Potential Delegates'),

6
mod/dfrn_notify.php

@ -18,6 +18,12 @@ require_once 'include/event.php';
function dfrn_notify_post(App $a) {
logger(__function__, LOGGER_TRACE);
if (empty($_POST)) {
require_once 'mod/salmon.php';
salmon_post($a);
}
$dfrn_id = ((x($_POST,'dfrn_id')) ? notags(trim($_POST['dfrn_id'])) : '');
$dfrn_version = ((x($_POST,'dfrn_version')) ? (float) $_POST['dfrn_version'] : 2.0);
$challenge = ((x($_POST,'challenge')) ? notags(trim($_POST['challenge'])) : '');

152
mod/directory.php

@ -12,12 +12,12 @@ use Friendica\Database\DBM;
use Friendica\Model\Contact;
use Friendica\Model\Profile;
function directory_init(App $a) {
function directory_init(App $a)
{
$a->set_pager_itemspage(60);
if(local_user()) {
if (local_user()) {
$a->page['aside'] .= Widget::findPeople();
$a->page['aside'] .= Widget::follow();
} else {
unset($_SESSION['theme']);
@ -25,16 +25,20 @@ function directory_init(App $a) {
}
}
function directory_post(App $a) {
if(x($_POST,'search'))
function directory_post(App $a)
{
if (x($_POST, 'search')) {
$a->data['search'] = $_POST['search'];
}
}
function directory_content(App $a) {
function directory_content(App $a)
{
require_once("mod/proxy.php");
if((Config::get('system','block_public')) && (! local_user()) && (! remote_user()) ||
(Config::get('system','block_local_dir')) && (! local_user()) && (! remote_user())) {
if ((Config::get('system', 'block_public') && !local_user() && !remote_user())
|| (Config::get('system', 'block_local_dir') && !local_user() && !remote_user())
) {
notice(L10n::t('Public access denied.') . EOL);
return;
}
@ -42,18 +46,19 @@ function directory_content(App $a) {
$o = '';
Nav::setSelected('directory');
if(x($a->data,'search'))
if (x($a->data, 'search')) {
$search = notags(trim($a->data['search']));
else
$search = ((x($_GET,'search')) ? notags(trim(rawurldecode($_GET['search']))) : '');
} else {
$search = ((x($_GET, 'search')) ? notags(trim(rawurldecode($_GET['search']))) : '');
}
$gdirpath = '';
$dirurl = Config::get('system','directory');
if(strlen($dirurl)) {
$gdirpath = Profile::zrl($dirurl,true);
$dirurl = Config::get('system', 'directory');
if (strlen($dirurl)) {
$gdirpath = Profile::zrl($dirurl, true);
}
if($search) {
if ($search) {
$search = dbesc($search);
$sql_extra = " AND ((`profile`.`name` LIKE '%$search%') OR
@ -73,35 +78,35 @@ function directory_content(App $a) {
(`profile`.`prv_keywords` LIKE '%$search%'))";
}
$publish = ((Config::get('system','publish_all')) ? '' : " AND `publish` = 1 " );
$publish = ((Config::get('system', 'publish_all')) ? '' : " AND `publish` = 1 " );
$r = q("SELECT COUNT(*) AS `total` FROM `profile`
LEFT JOIN `user` ON `user`.`uid` = `profile`.`uid`
WHERE `is-default` = 1 $publish AND `user`.`blocked` = 0 $sql_extra ");
if (DBM::is_result($r))
$a->set_pager_total($r[0]['total']);
$cnt = dba::selectFirst("SELECT COUNT(*) AS `total` FROM `profile`
LEFT JOIN `user` ON `user`.`uid` = `profile`.`uid`
WHERE `is-default` = 1 $publish AND `user`.`blocked` = 0 $sql_extra "
);
if (DBM::is_result($cnt)) {
$a->set_pager_total($cnt['total']);
}
$order = " ORDER BY `name` ASC ";
$limit = intval($a->pager['start']).",".intval($a->pager['itemspage']);
$limit = intval($a->pager['start'])."," . intval($a->pager['itemspage']);
$r = q("SELECT `profile`.*, `profile`.`uid` AS `profile_uid`, `user`.`nickname`, `user`.`timezone` , `user`.`page-flags`,
$r = dba::p("SELECT `profile`.*, `profile`.`uid` AS `profile_uid`, `user`.`nickname`, `user`.`timezone` , `user`.`page-flags`,
`contact`.`addr`, `contact`.`url` AS profile_url FROM `profile`
LEFT JOIN `user` ON `user`.`uid` = `profile`.`uid`
LEFT JOIN `contact` ON `contact`.`uid` = `user`.`uid`
WHERE `is-default` $publish AND `user`.`blocked` = 0 AND `contact`.`self` $sql_extra $order LIMIT ".$limit);
WHERE `is-default` $publish AND `user`.`blocked` = 0 AND `contact`.`self` $sql_extra $order LIMIT ".$limit
);
if (DBM::is_result($r)) {
if (in_array('small', $a->argv)) {
$photo = 'thumb';
}
else {
} else {
$photo = 'photo';
}
foreach ($r as $rr) {
while ($rr = dba::fetch($r)) {
$itemurl= '';
$itemurl = (($rr['addr'] != "") ? $rr['addr'] : $rr['profile_url']);
@ -111,16 +116,19 @@ function directory_content(App $a) {
$pdesc = (($rr['pdesc']) ? $rr['pdesc'] . '<br />' : '');
$details = '';
if(strlen($rr['locality']))
if (strlen($rr['locality'])) {
$details .= $rr['locality'];
if(strlen($rr['region'])) {
if(strlen($rr['locality']))
}
if (strlen($rr['region'])) {
if (strlen($rr['locality'])) {
$details .= ', ';
}
$details .= $rr['region'];
}
if(strlen($rr['country-name'])) {
if(strlen($details))
if (strlen($rr['country-name'])) {
if (strlen($details)) {
$details .= ', ';
}
$details .= $rr['country-name'];
}
// if(strlen($rr['dob'])) {
@ -132,20 +140,19 @@ function directory_content(App $a) {
$profile = $rr;
if((x($profile,'address') == 1)
|| (x($profile,'locality') == 1)
|| (x($profile,'region') == 1)
|| (x($profile,'postal-code') == 1)
|| (x($profile,'country-name') == 1))
$location = L10n::t('Location:');
$gender = ((x($profile,'gender') == 1) ? L10n::t('Gender:') : False);
$marital = ((x($profile,'marital') == 1) ? L10n::t('Status:') : False);
$homepage = ((x($profile,'homepage') == 1) ? L10n::t('Homepage:') : False);
if ((x($profile, 'address') == 1)
|| (x($profile, 'locality') == 1)
|| (x($profile, 'region') == 1)
|| (x($profile, 'postal-code') == 1)
|| (x($profile, 'country-name') == 1)
) {
$location = L10n::t('Location:');
}
$about = ((x($profile,'about') == 1) ? L10n::t('About:') : False);
$gender = ((x($profile, 'gender') == 1) ? L10n::t('Gender:') : false);
$marital = ((x($profile, 'marital') == 1) ? L10n::t('Status:') : false);
$homepage = ((x($profile, 'homepage') == 1) ? L10n::t('Homepage:') : false);
$about = ((x($profile, 'about') == 1) ? L10n::t('About:') : false);
$location_e = $location;
@ -154,23 +161,23 @@ function directory_content(App $a) {
];
$entry = [
'id' => $rr['id'],
'url' => $profile_link,
'itemurl' => $itemurl,
'thumb' => proxy_url($rr[$photo], false, PROXY_SIZE_THUMB),
'img_hover' => $rr['name'],
'name' => $rr['name'],
'details' => $details,
'id' => $rr['id'],
'url' => $profile_link,
'itemurl' => $itemurl,
'thumb' => proxy_url($rr[$photo], false, PROXY_SIZE_THUMB),
'img_hover' => $rr['name'],
'name' => $rr['name'],
'details' => $details,
'account_type' => Contact::getAccountType($rr),
'profile' => $profile,
'location' => $location_e,
'tags' => $rr['pub_keywords'],
'gender' => $gender,
'pdesc' => $pdesc,
'marital' => $marital,
'homepage' => $homepage,
'about' => $about,
'photo_menu' => $photo_menu,
'profile' => $profile,
'location' => $location_e,
'tags' => $rr['pub_keywords'],
'gender' => $gender,
'pdesc' => $pdesc,
'marital' => $marital,
'homepage' => $homepage,
'about' => $about,
'photo_menu' => $photo_menu,
];
@ -187,20 +194,21 @@ function directory_content(App $a) {
$entries[] = $arr['entry'];
}
dba::close($r);
$tpl = get_markup_template('directory_header.tpl');
$o .= replace_macros($tpl, [
'$search' => $search,
'$search' => $search,
'$globaldir' => L10n::t('Global Directory'),
'$gdirpath' => $gdirpath,
'$desc' => L10n::t('Find on this site'),
'$contacts' => $entries,
'$finding' => L10n::t('Results for:'),
'$findterm' => (strlen($search) ? $search : ""),
'$title' => L10n::t('Site Directory'),
'$submit' => L10n::t('Find'),
'$paginate' => paginate($a),
'$gdirpath' => $gdirpath,
'$desc' => L10n::t('Find on this site'),
'$contacts' => $entries,
'$finding' => L10n::t('Results for:'),
'$findterm' => (strlen($search) ? $search : ""),
'$title' => L10n::t('Site Directory'),
'$submit' => L10n::t('Find'),
'$paginate' => paginate($a),
]);
} else {
info(L10n::t("No entries \x28some entries may be hidden\x29.") . EOL);

55
mod/dirfind.php

@ -15,6 +15,7 @@ use Friendica\Model\Profile;
use Friendica\Network\Probe;
use Friendica\Protocol\PortableContact;
use Friendica\Util\Network;
use Friendica\Database\DBM;
require_once 'mod/contacts.php';
@ -113,32 +114,22 @@ function dirfind_content(App $a, $prefix = "") {
/// @TODO These 2 SELECTs are not checked on validity with DBM::is_result()
$count = q("SELECT count(*) AS `total` FROM `gcontact`
LEFT JOIN `contact` ON `contact`.`nurl` = `gcontact`.`nurl`
AND `contact`.`network` = `gcontact`.`network`
AND `contact`.`uid` = %d AND NOT `contact`.`blocked`
AND NOT `contact`.`pending` AND `contact`.`rel` IN ('%s', '%s')
WHERE (`contact`.`id` > 0 OR (NOT `gcontact`.`hide` AND `gcontact`.`network` IN ('%s', '%s', '%s') AND
((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR (`gcontact`.`updated` >= `gcontact`.`last_failure`)))) AND
(`gcontact`.`url` LIKE '%s' OR `gcontact`.`name` LIKE '%s' OR `gcontact`.`location` LIKE '%s' OR
`gcontact`.`addr` LIKE '%s' OR `gcontact`.`about` LIKE '%s' OR `gcontact`.`keywords` LIKE '%s') $extra_sql",
intval(local_user()), dbesc(CONTACT_IS_SHARING), dbesc(CONTACT_IS_FRIEND),
WHERE NOT `hide` AND `network` IN ('%s', '%s', '%s') AND
((`last_contact` >= `last_failure`) OR (`updated` >= `last_failure`)) AND
(`url` LIKE '%s' OR `name` LIKE '%s' OR `location` LIKE '%s' OR
`addr` LIKE '%s' OR `about` LIKE '%s' OR `keywords` LIKE '%s') $extra_sql",
dbesc(NETWORK_DFRN), dbesc($ostatus), dbesc($diaspora),
dbesc(escape_tags($search2)), dbesc(escape_tags($search2)), dbesc(escape_tags($search2)),
dbesc(escape_tags($search2)), dbesc(escape_tags($search2)), dbesc(escape_tags($search2)));
$results = q("SELECT `contact`.`id` AS `cid`, `gcontact`.`url`, `gcontact`.`name`, `gcontact`.`photo`, `gcontact`.`network`, `gcontact`.`keywords`, `gcontact`.`addr`
$results = q("SELECT `nurl`
FROM `gcontact`
LEFT JOIN `contact` ON `contact`.`nurl` = `gcontact`.`nurl`
AND `contact`.`network` = `gcontact`.`network`
AND `contact`.`uid` = %d AND NOT `contact`.`blocked`
AND NOT `contact`.`pending` AND `contact`.`rel` IN ('%s', '%s')
WHERE (`contact`.`id` > 0 OR (NOT `gcontact`.`hide` AND `gcontact`.`network` IN ('%s', '%s', '%s') AND
((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR (`gcontact`.`updated` >= `gcontact`.`last_failure`)))) AND
(`gcontact`.`url` LIKE '%s' OR `gcontact`.`name` LIKE '%s' OR `gcontact`.`location` LIKE '%s' OR
`gcontact`.`addr` LIKE '%s' OR `gcontact`.`about` LIKE '%s' OR `gcontact`.`keywords` LIKE '%s') $extra_sql
GROUP BY `gcontact`.`nurl`
ORDER BY `gcontact`.`updated` DESC LIMIT %d, %d",
intval(local_user()), dbesc(CONTACT_IS_SHARING), dbesc(CONTACT_IS_FRIEND),
WHERE NOT `hide` AND `network` IN ('%s', '%s', '%s') AND
((`last_contact` >= `last_failure`) OR (`updated` >= `last_failure`)) AND
(`url` LIKE '%s' OR `name` LIKE '%s' OR `location` LIKE '%s' OR
`addr` LIKE '%s' OR `about` LIKE '%s' OR `keywords` LIKE '%s') $extra_sql
GROUP BY `nurl`
ORDER BY `updated` DESC LIMIT %d, %d",
dbesc(NETWORK_DFRN), dbesc($ostatus), dbesc($diaspora),
dbesc(escape_tags($search2)), dbesc(escape_tags($search2)), dbesc(escape_tags($search2)),
dbesc(escape_tags($search2)), dbesc(escape_tags($search2)), dbesc(escape_tags($search2)),
@ -148,14 +139,21 @@ function dirfind_content(App $a, $prefix = "") {
$j->items_page = $perpage;
$j->page = $a->pager['page'];
foreach ($results AS $result) {
if (PortableContact::alternateOStatusUrl($result["url"])) {
if (PortableContact::alternateOStatusUrl($result["nurl"])) {
continue;
}
$result = Contact::getDetailsByURL($result["url"], local_user(), $result);
$urlparts = parse_url($result["nurl"]);
// Ignore results that look strange.
// For historic reasons the gcontact table does contain some garbage.
if (!empty($urlparts['query']) || !empty($urlparts['fragment'])) {
continue;
}
$result = Contact::getDetailsByURL($result["nurl"], local_user());
if ($result["name"] == "") {
$urlparts = parse_url($result["url"]);
$result["name"] = end(explode("/", $urlparts["path"]));
}
@ -204,11 +202,10 @@ function dirfind_content(App $a, $prefix = "") {
if ($jj->cid > 0) {
$connlnk = "";
$conntxt = "";
$contact = q("SELECT * FROM `contact` WHERE `id` = %d",
intval($jj->cid));
if ($contact) {
$photo_menu = Contact::photoMenu($contact[0]);
$details = _contact_detail_for_template($contact[0]);
$contact = dba::selectFirst('contact', [], ['id' => $jj->cid]);
if (DBM::is_result($contact)) {
$photo_menu = Contact::photoMenu($contact);
$details = _contact_detail_for_template($contact);
$alt_text = $details['alt_text'];
} else {
$photo_menu = [];

6
mod/display.php

@ -212,7 +212,11 @@ function display_content(App $a, $update = false, $update_uid = 0) {
if ($update) {
$item_id = $_REQUEST['item_id'];
$item = dba::selectFirst('item', ['uid', 'parent'], ['id' => $item_id]);
$a->profile = ['uid' => intval($item['uid']), 'profile_uid' => intval($item['uid'])];
if ($item['uid'] != 0) {
$a->profile = ['uid' => intval($item['uid']), 'profile_uid' => intval($item['uid'])];
} else {
$a->profile = ['uid' => intval($update_uid), 'profile_uid' => intval($update_uid)];
}
$item_parent = $item['parent'];
} else {
$item_id = (($a->argc > 2) ? $a->argv[2] : 0);

18
mod/follow.php

@ -9,6 +9,7 @@ use Friendica\Core\System;
use Friendica\Model\Contact;
use Friendica\Model\Profile;
use Friendica\Network\Probe;
use Friendica\Database\DBM;
function follow_post(App $a) {
@ -60,19 +61,20 @@ function follow_content(App $a) {
$submit = L10n::t('Submit Request');
// There is a current issue. It seems as if you can't start following a Friendica that is following you
// With Diaspora this works - but Friendica is special, it seems ...
$r = q("SELECT `url` FROM `contact` WHERE `uid` = %d AND ((`rel` != %d) OR (`network` = '%s')) AND
// Don't try to add a pending contact
$r = q("SELECT `pending` FROM `contact` WHERE `uid` = %d AND ((`rel` != %d) OR (`network` = '%s')) AND
(`nurl` = '%s' OR `alias` = '%s' OR `alias` = '%s') AND
`network` != '%s' LIMIT 1",
intval(local_user()), dbesc(CONTACT_IS_FOLLOWER), dbesc(NETWORK_DFRN), dbesc(normalise_link($url)),
dbesc(normalise_link($url)), dbesc($url), dbesc(NETWORK_STATUSNET));
if ($r) {
notice(L10n::t('You already added this contact.').EOL);
$submit = "";
//goaway($_SESSION['return_url']);
// NOTREACHED
if ($r[0]['pending']) {
notice(L10n::t('You already added this contact.').EOL);
$submit = "";
//goaway($_SESSION['return_url']);
// NOTREACHED
}
}
$ret = Probe::uri($url);
@ -102,7 +104,7 @@ function follow_content(App $a) {
$ret["url"] = $ret["addr"];
}
if ($ret['network'] === NETWORK_DFRN) {
if (($ret['network'] === NETWORK_DFRN) && !DBM::is_result($r)) {
$request = $ret["request"];
$tpl = get_markup_template('dfrn_request.tpl');
} else {

15
mod/install.php

@ -397,7 +397,8 @@ function check_funcs(&$checks) {
check_add($ck_funcs, L10n::t('PDO or MySQLi PHP module'), true, true, "");
check_add($ck_funcs, L10n::t('mb_string PHP module'), true, true, "");
check_add($ck_funcs, L10n::t('XML PHP module'), true, true, "");
check_add($ck_funcs, L10n::t('iconv module'), true, true, "");
check_add($ck_funcs, L10n::t('iconv PHP module'), true, true, "");
check_add($ck_funcs, L10n::t('POSIX PHP module'), true, true, "");
if (function_exists('apache_get_modules')) {
if (! in_array('mod_rewrite',apache_get_modules())) {
@ -432,8 +433,12 @@ function check_funcs(&$checks) {
$ck_funcs[4]['help'] = L10n::t('Error: mb_string PHP module required but not installed.');
}
if (! function_exists('iconv_strlen')) {
$ck_funcs[6]['status'] = false;
$ck_funcs[6]['help'] = L10n::t('Error: iconv PHP module required but not installed.');
}
if (! function_exists('posix_kill')) {
$ck_funcs[7]['status'] = false;
$ck_funcs[7]['help'] = L10n::t('Error: iconv PHP module required but not installed.');
$ck_funcs[7]['help'] = L10n::t('Error: POSIX PHP module required but not installed.');
}
$checks = array_merge($checks, $ck_funcs);
@ -442,8 +447,8 @@ function check_funcs(&$checks) {
try {
$xml = new DOMDocument();
} catch (Exception $e) {
$ck_funcs[6]['status'] = false;
$ck_funcs[6]['help'] = L10n::t('Error, XML PHP module required but not installed.');
$ck_funcs[5]['status'] = false;
$ck_funcs[5]['help'] = L10n::t('Error, XML PHP module required but not installed.');
}
}
@ -540,7 +545,7 @@ function load_database_rem($v, $i) {
}