Merge remote-tracking branch 'upstream/develop' into develop

This commit is contained in:
Andy H 2017-11-30 14:01:18 +07:00
commit a21f6135fc
265 changed files with 25303 additions and 22258 deletions

View File

@ -102,17 +102,17 @@ tables, so that you can start fresh.
****************************************************************************
****************************************************************************
8. Set up a cron job or scheduled task to run the poller once every 5-10
8. Set up a cron job or scheduled task to run the worker once every 5-10
minutes to pick up the recent "public" postings of your friends. Example:
cd /base/directory; /path/to/php include/poller.php
cd /base/directory; /path/to/php scripts/worker.php
Change "/base/directory", and "/path/to/php" as appropriate for your situation.
If you are using a Linux server, run "crontab -e" and add a line like the
one shown, substituting for your unique paths and settings:
*/10 * * * * cd /home/myname/mywebsite; /usr/bin/php include/poller.php
*/10 * * * * cd /home/myname/mywebsite; /usr/bin/php scripts/worker.php
You can generally find the location of PHP by executing "which php". If you
have troubles with this section please contact your hosting provider for
@ -285,14 +285,14 @@ cron by using something like
*/10 * * * * cd /var/www/friendica/friendica/ && sudo -u www-data /usr/bin/php
-d suhosin.executor.func.blacklist=none -d suhosin.executor.eval.blacklist=none
-f include/poller.php
-f scripts/worker.php
This worked well for simple test cases, but the friendica-cron still failed with
a fatal error:
suhosin[22962]: ALERT - function within blacklist called: proc_open() (attacker
'REMOTE_ADDR not set', file '/var/www/friendica/friendica/boot.php', line 1341)
After a while I noticed, that include/poller.php calls further php script via
After a while I noticed, that scripts/worker.php calls further php script via
proc_open. These scripts themselves also use proc_open and fail, because they
are NOT called with -d suhosin.executor.func.blacklist=none.

View File

@ -27,6 +27,7 @@ use Friendica\Core\Config;
use Friendica\Core\PConfig;
use Friendica\Core\Worker;
use Friendica\Database\DBM;
use Friendica\Object\Contact;
use Friendica\Util\Lock;
require_once 'include/network.php';
@ -39,7 +40,6 @@ require_once 'include/features.php';
require_once 'include/identity.php';
require_once 'update.php';
require_once 'include/dbstructure.php';
require_once 'include/poller.php';
define('FRIENDICA_PLATFORM', 'Friendica');
define('FRIENDICA_CODENAME', 'Asparagus');
@ -619,7 +619,7 @@ function is_ajax()
/**
* @brief Function to check if request was an AJAX (xmlhttprequest) request.
*
* @param boolean $via_worker boolean Is the check run via the poller?
* @param boolean $via_worker boolean Is the check run via the worker?
*/
function check_db($via_worker)
{
@ -630,7 +630,7 @@ function check_db($via_worker)
}
if ($build != DB_UPDATE_VERSION) {
// When we cannot execute the database update via the worker, we will do it directly
if (!Worker::add(PRIORITY_CRITICAL, 'dbupdate') && $via_worker) {
if (!Worker::add(PRIORITY_CRITICAL, 'DBUpdate') && $via_worker) {
update_db(get_app());
}
}
@ -984,10 +984,10 @@ function public_contact()
if (!$public_contact_id && x($_SESSION, 'authenticated')) {
if (x($_SESSION, 'my_address')) {
// Local user
$public_contact_id = intval(get_contact($_SESSION['my_address'], 0));
$public_contact_id = intval(Contact::getIdForURL($_SESSION['my_address'], 0));
} elseif (x($_SESSION, 'visitor_home')) {
// Remote user
$public_contact_id = intval(get_contact($_SESSION['visitor_home'], 0));
$public_contact_id = intval(Contact::getIdForURL($_SESSION['visitor_home'], 0));
}
} elseif (!x($_SESSION, 'authenticated')) {
$public_contact_id = false;
@ -1065,18 +1065,6 @@ function get_max_import_size()
return ((x($a->config, 'max_import_size')) ? $a->config['max_import_size'] : 0 );
}
/**
* @brief compatibilty wrapper for Worker::add function
*
* @param (integer|array) priority or parameter array, strings are deprecated and are ignored
*
* @return boolean "false" if proc_run couldn't be executed
*/
function proc_run()
{
$proc_args = func_get_args();
call_user_func_array('Friendica\Core\Worker::add', $proc_args);
}
function current_theme()
{
@ -1527,15 +1515,6 @@ function get_spoolpath()
return "";
}
/// @deprecated
function set_template_engine(App $a, $engine = 'internal')
{
/// @note This function is no longer necessary, but keep it as a wrapper to the class method
/// to avoid breaking themes again unnecessarily
/// @TODO maybe output a warning here so the theme developer can see it? PHP won't show such warnings like Java does.
$a->set_template_engine($engine);
}
if (!function_exists('exif_imagetype')) {
function exif_imagetype($file)

View File

@ -18,7 +18,8 @@
"league/html-to-markdown": "~4.4.1",
"defuse/php-encryption": "1.*",
"pear/Text_LanguageDetect": "1.*",
"pear-pear.php.net/Text_Highlighter": "*"
"pear-pear.php.net/Text_Highlighter": "*",
"paragonie/random_compat": "^2.0"
},
"repositories": [
{

50
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "a6a3dae4b15752d8f377b1fc1e5a2b47",
"content-hash": "a5c0c297b0e8185f2bcd3aad20ec5acc",
"packages": [
{
"name": "defuse/php-encryption",
@ -211,6 +211,54 @@
],
"time": "2017-08-29T18:23:54+00:00"
},
{
"name": "paragonie/random_compat",
"version": "v2.0.11",
"source": {
"type": "git",
"url": "https://github.com/paragonie/random_compat.git",
"reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/5da4d3c796c275c55f057af5a643ae297d96b4d8",
"reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8",
"shasum": ""
},
"require": {
"php": ">=5.2.0"
},
"require-dev": {
"phpunit/phpunit": "4.*|5.*"
},
"suggest": {
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
},
"type": "library",
"autoload": {
"files": [
"lib/random.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Paragon Initiative Enterprises",
"email": "security@paragonie.com",
"homepage": "https://paragonie.com"
}
],
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
"keywords": [
"csprng",
"pseudorandom",
"random"
],
"time": "2017-09-27T21:40:39+00:00"
},
{
"name": "pear-pear.php.net/Archive_Tar",
"version": "1.4.3",

View File

@ -126,7 +126,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) and 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) or the [theme developer forum](https://friendica.eu/profile/ftdevs).
Do not worry about cross-posting.
###Client software

View File

@ -157,7 +157,7 @@ Friendica is using a [Twitter/GNU Social compatible API](help/api), which means
Here is a list of known working clients:
* Android
* [Friendiqa](https://github.com/lubuwest/friendiqa) (you can find the APK file in the listed files in the repository)
* [Friendiqa](https://github.com/lubuwest/friendiqa) (available in Google Playstore or from a binary repository you can add to [F-Droid](https://freunde.ma-nic.de/display/3e98eba8185a13c5bdbf3d1539646854))
* AndStatus
* Twidere
* Mustard and Mustard-Mod

View File

@ -94,19 +94,19 @@ 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 poller
###Set up the worker
Set up a cron job or scheduled task to run the poller once every 5-10 minutes in order to perform background processing.
Set up a cron job or scheduled task to run the worker once every 5-10 minutes in order to perform background processing.
Example:
cd /base/directory; /path/to/php include/poller.php
cd /base/directory; /path/to/php scripts/worker.php
Change "/base/directory", and "/path/to/php" as appropriate for your situation.
If you are using a Linux server, run "crontab -e" and add a line like the
one shown, substituting for your unique paths and settings:
*/10 * * * * cd /home/myname/mywebsite; /usr/bin/php include/poller.php
*/10 * * * * cd /home/myname/mywebsite; /usr/bin/php scripts/worker.php
You can generally find the location of PHP by executing "which php".
If you run into trouble with this section please contact your hosting provider for assistance.

View File

@ -19,7 +19,7 @@ Salmon notifications arrive via mod/salmon.php.
Push (pubsubhubbub) feeds arrive via mod/pubsub.php
DFRN-poll feed imports arrive via include/poller.php as a scheduled task, this implements the local side of the DFRN-poll protocol.
DFRN-poll feed imports arrive via src/Worker/OnePoll.php as a scheduled task, this implements the local side of the DFRN-poll protocol.
### Scenario #1. Bob posts a public status message
@ -28,7 +28,7 @@ There are two paths it can take - as a bbcode path to DFRN clients, and converte
When a PuSH hub is operational, dfrn-poll clients prefer to receive their information through the PuSH channel.
They will fall back on a daily poll in case the hub has delivery issues (this is quite common when using the default Google reference hub).
If there is no specified hub or hubs, DFRN clients will poll at a configurable (per-contact) rate at up to 5-minute intervals.
Feeds retrieved via dfrn-poll are bbcode and may also contain private conversations which the poller has permissions to see.
Feeds retrieved via dfrn-poll are bbcode and may also contain private conversations which the worker has permissions to see.
### Scenario #2. Jack replies to Bob's public message. Jack is on the Friendica/DFRN network.

View File

@ -69,30 +69,28 @@ If you can successfully access your Friendica instance through https, there are
This is the simplest way to enforce site-wide secure access.
Every time a user tries to access any Friendica page by any mean (manual address bar entry or link), the web server issues a Permanent Redirect response with the secure protocol prepended to the requested URL.
With Apache, simply add the following lines to the [code].htaccess[/code] file in the root folder of your Friendica instance (thanks to [url=https://github.com/AlfredSK]AlfredSK[/url]):
With Apache, enable the modules rewrite and ssl (with a shared hosting provider, this should be enabled already):
[code]
#Force SSL connections
sudo a2enmod rewrite ssl
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://your.friendica.domain/$1 [R=301,L]
[/code]
Add the following lines to the .htaccess file in the root folder of your Friendica instance (thanks to [url=https://github.com/AlfredSK]AlfredSK[/url]):
With nginx, configure your [code]server[/code] directive this way (thanks to [url=https://bjornjohansen.no/redirect-to-https-with-nginx/]Bjørn Johansen[/url]):
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://your.friendica.domain/$1 [R=301,L]
[code]
server {
listen 80;
listen [::]:80;
server_name your.friendica.domain;
return 301 https://$server_name$request_uri;
}
[/code]
With nginx, configure your server directive this way ([documentation](https://www.nginx.com/blog/creating-nginx-rewrite-rules/)):
server {
listen 80;
server_name your.friendica.domain;
return 301 https://$server_name$request_uri;
}
### SSL Settings
In the Admin Settings, there are three SSL-related settings:
- **SSL link policy**: this affects how Friendica generates internal links. If your SSL installation was successful, we recommend "Force all links to SSL" just in case your web server configuration can't be altered like described above.
- **Force SSL**: This forces all external links to HTTPS, which may solve Mixed-Content issues, but not all websites support HTTPS yet. Use at your own risk.
- **Verify SSL**: Enabling this will prevent Friendica to interact with self-signed SSL sites. We recommend you leave it on as a self-signed SSL certificate can be a vectorfor a man-in-the-middle attack.
1. **SSL link policy**: this affects how Friendica generates internal links. If your SSL installation was successful, we recommend "Force all links to SSL" just in case your web server configuration can't be altered like described above.
2. **Force SSL**: This forces all external links to HTTPS, which may solve Mixed-Content issues, but not all websites support HTTPS yet. Use at your own risk.
3. **Verify SSL**: Enabling this will prevent Friendica to interact with self-signed SSL sites. We recommend you leave it on as a self-signed SSL certificate can be a vectorfor a man-in-the-middle attack.

View File

@ -171,7 +171,7 @@ Das bedeutet, dass du jeden Twitter/GNU Social Client verwenden kannst in dem du
Hier ist eine Liste von Clients bei denen dies möglich ist, bzw. die speziell für Friendica entwickelt werden:
* Android
* [Friendiqa](https://github.com/lubuwest/friendiqa) (ydie APK Datei findest du in den gelisteten Dateien im Repository)
* [Friendiqa](https://github.com/lubuwest/friendiqa) (Gibt es im Google Playstore oder als [binary Repository](https://freunde.ma-nic.de/display/3e98eba8185a13c5bdbf3d1539646854) für F-Droid)
* AndStatus
* Twidere
* Mustard and Mustard-Mod

View File

@ -11,7 +11,7 @@ Friendica - Dokumentation und Ressourcen
* [Beiträge kommentieren, einordnen und löschen](help/Text_comment)
* [Profile](help/Profiles)
* [Referenz der Accesskeys](help/Accesskeys)
* [Veranstaltungen](help/events) (EN)
* [Veranstaltungen](help/events)
* Du und andere Nutzer
* [Konnektoren (Connectors)](help/Connectors)
* [Freunde finden](help/Making-Friends)

View File

@ -84,13 +84,13 @@ Wenn du irgendwelche **kritischen** Fehler zu diesen Zeitpunkt erhalten solltest
7. Erstelle einen Cron job oder einen regelmäßigen Task, um den Poller alle 5-10 Minuten im Hintergrund ablaufen zu lassen. Beispiel:
`cd /base/directory; /path/to/php include/poller.php`
`cd /base/directory; /path/to/php scripts/worker.php`
Ändere "/base/directory" und "/path/to/php" auf deine Systemvorgaben.
Wenn du einen Linux-Server nutzt, benutze den Befehl "crontab -e" und ergänze eine Zeile wie die Folgende; angepasst an dein System
`*/10 * * * * cd /home/myname/mywebsite; /usr/bin/php include/poller.php`
`*/10 * * * * cd /home/myname/mywebsite; /usr/bin/php scripts/worker.php`
Du kannst den PHP-Pfad finden, indem du den Befehl „which php“ ausführst.
Wenn du Schwierigkeiten mit diesem Schritt hast, kannst du deinen Hosting-Anbieter kontaktieren.

View File

@ -21,7 +21,7 @@ Salmon-Benachrichtigungen kommen via mod/salmon.php an.
PuSh-Feeds (pubsubhubbub) kommen via mod/pubsub.php an.
DFRN-poll Feed-Imports kommen via include/poller.php als geplanter Task an, das implementiert die lokale Bearbeitung (local side) des DFRN-Protokolls.
DFRN-poll Feed-Imports kommen via src/Worker/OnePoll.php als geplanter Task an, das implementiert die lokale Bearbeitung (local side) des DFRN-Protokolls.
### Szenario #1. Bob schreibt eine öffentliche Statusnachricht

60
doc/de/events.md Normal file
View File

@ -0,0 +1,60 @@
# Veranstaltungen
* [Zur Startseite der Hilfe](help)
Veranstaltungen sind spezielle Postings.
Die Veranstaltungen, die Du und deine Kontakte teilen, können unter [/events](/events) auf deiner Instanz aufgefunden werden.
Um da hinzukommen gehe über den Tab "Veranstalltungen", abhänig von dem Theme, das du benutzt, ist der eventuell ein zusätzlicher link im Navigationsmenü der Seite vorhanden.
## Veranstaltungsübersicht
Die Übersichtsseite zeigt den Kalender des aktuellen Monats an, plus einige Tage am Beginn und am Ende.
Angezeit werden alle Veranstalltungen des aktuellen Monats, die von dir angelegt wurden oder die von deinen Kontakten geteilt wurden.
Dies beinhaltet auch Geburstagserinnerungen, welche mit dir geteilt wurden.
Es gibt Buttons mit denen die Ansicht zwischen Monatlich/Wöchentlich und Täglich wechseln kann.
Um eine neue Veranstaltung anzulegen, kannst du dem Link "Veranstaltung erstellen" folgen oder einen Doppel-Klick in das Kalenderfeld, in dem die Veranstalltung stehen soll, machen.
Mit einem Klick auf eine bereits existierende Veranstalltung, öffnet sich ein Pop-up Fenster, welches dir die Veranstaltung anzeigt.
## Erstelle eine neue Veranstaltung
Folge einer der oben beschriebenen Methoden, dann erreichst du das Formular um die Veranstaltungsdaten einzutragen. Felder mit *** müsen ausgefüllt werden.
* **Veranstaltungsbeginn**: trage den Anfang der Veranstaltung ein.
* **Veranstaltungsende**: trage das Ende der Veranstaltung ein.
Wenn du in eines dieser Felder klickst, wird sich ein Popup Fesnster öffnen, wo du Tag und Uhrzeit eintragen kannst.
Wenn du einen Doppel-Klick auf die Box im Kalender machst, werden diese Felder automatisch ausgefüllt.
Das Veranstaltungsende muss nach dem Veranstaltungsanfang liegen.
Aber du musst es nicht angeben. Wenn eine Veranstaltung ein offenes Ende hat oder das Veranstaltungsende nicht wichtig ist, klicke in die Box zwei Felder darunter.
* **An Zeitzone des Betrachters anpassen**: Wenn du die Box anklickst, wird die Anfangs und Endzeit der Veranstaltung automatisch an die lokale Zeitzone, wie in den Zeitzonen-Einstellung angepasst.
Dies vermeidet verfrühte Geburstagsglückwünsche, oder die Beführchtung, das du den Geburstag deines Freundes auf der anderen Seite der Welt vergisst und ähnliche Ereignisse.
* **Titel**: Titel der Veranstaltung
* **Beschreibung**: eine längere Beschreibung der Veranstaltung
* **Ort**: Ort, wo die Veranstaltung stattfinden wird
Diese 3 Felder beschreiben deine Veranstaltung.
Im Beschreibungs- und Orts-Feld kannst du BBCode zum formatieren des Textes verwenden.
* **Veranstaltung teilen**: wenn diese Box aktiviert wird, kannst du in der ACL auswählen mit wem du diese Veranstaltung teilen willst. Dies funktioniert wie die Kontrolle jedes anderen Postings.
Wenn du Veranstaltungen teilst, werden diese auf deine Pinnwand gepostet mit den Zugriffsberechtigungen, die du ausgewählt hast. Bevor du das machst, kannst du dir die Veranstaltung als Vorschau in einem Popup-Fenster anzeigen lassen.
### Interaktionen mit Veranstaltungen
Wenn du eine Veranstaltung veröffendlichst, kannst du auswählen, wer sie bekommen wird, wie bei einem normalen Posting.
Die Empfänger sehen deine Veranstaltung in einem Posting in ihrem Network-Stream.
Zusätzlich wird die Veranstaltung zu ihrem Kalender hinzugefügt und somit in ihrer Veranstaltungsübersicht angezeigt.
Empfänger von einem Veranstaltungs-Posting, können dies kommentieren oder dis-/liken, wie bei einem normalen Posting.
Zusätzlich können sie sagen ob sie teilnehmen, oder vielleicht teilnehmen an der Veranstaltung mit einem einzigen Klick.
### Kalender exportieren
Wenn du deine öffentlichen Kalender Einträge exportieren möchtest, kannst du dies in den Einstellungen aktivieren (Einstellungen -> Zusätzliche Features -> Allgemeine Features -> Öffentlichen Kalender exportieren).
Im Anschluss sind auf der Veranstaltungs-Übersichtsseite zwei Links zu den exportierten Einträgen (im ical oder csv Format) verfügbar.

View File

@ -62,14 +62,8 @@ Additionally it will be added to their calendar and thus be shown in their event
Recipients of the event-posting can comment or dis-/like the event, as with a regular posting.
Furthermore they can announce that they will attend, not attend or may-be attend the event with a single click.
### Addons
### Calendar Export
#### OpenStreetMap
If you want to export your public events to ical or csv, you can activate an additional feature in your user settings (Additional features -> General Features -> Export Public Calendar).
Afterwards a link will be shown in the events page of your profile to access the calendar.
If this addon is activated on your friendica node, the content of the location field will be matched with the identification service of OSM when you submit the event.
Should OSM find anything matching, a map for the location will be embedded automatically at the end of the events view.
#### Calendar Export
If this addon is activated the public events you have created will be published in ical or csv file.
The URL of the published file is ``example.com/cal/nickname/export/format`` (where format is either ical of csv).

View File

@ -23,6 +23,7 @@ Example: To set the directory value please add this line to your .htconfig.php:
## system ##
* **allowed_link_protocols** (Array) - Allowed protocols in links URLs, add at your own risk. http is always allowed.
* **always_show_preview** (Boolean) - Only show small preview picures. Default value is false.
* **birthday_input_format** - Default value is "ymd".
* **block_local_dir** (Boolean) - Blocks the access to the directory of the local users.
* **auth_cookie_lifetime** (Integer) - Number of days that should pass without any activity before a user who chose "Remember me" when logging in is considered logged out. Defaults to 7.
@ -50,8 +51,8 @@ Example: To set the directory value please add this line to your .htconfig.php:
* **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.
* **local_tags** (Boolean) - If activated, all hashtags will point to the local server.
* **max_connections** - The maximum number of database connections which can be in use before the poller process is deferred to it's next interval. When the system can't detect the maximum numbers of connection then this value can be used.
* **max_connections_level** - The maximum level of connections that are allowed to let the poller start. It is a percentage value. Default value is 75.
* **max_connections** - The maximum number of database connections which can be in use before the worker process is deferred to it's next interval. When the system can't detect the maximum numbers of connection then this value can be used.
* **max_connections_level** - The maximum level of connections that are allowed to let the worker start. It is a percentage value. Default value is 75.
* **max_contact_queue** - Default value is 500.
* **max_batch_queue** - Default value is 1000.
* **max_processes_backend** - Maximum number of concurrent database processes for background tasks. Default value is 5.

View File

@ -172,7 +172,7 @@ The content of this file should be something like
$a-> theme_info = array(
'extends' => 'duepuntozero'.
);
set_template_engine($a, 'smarty3');
$a->set_template_engine('smarty3');
/* and more stuff e.g. the JavaScript function for the header */
}
@ -253,7 +253,7 @@ So in the case of quattro it is
function quattro_init(App $a) {
$a->theme_info = array();
set_template_engine($a, 'smarty3');
$a->set_template_engine('smarty3');
}
Here we have set the basic theme information, in this case they are empty.

View File

@ -1,900 +0,0 @@
<?php
use Friendica\App;
use Friendica\Core\PConfig;
use Friendica\Core\System;
use Friendica\Core\Worker;
use Friendica\Database\DBM;
use Friendica\Network\Probe;
use Friendica\Protocol\Diaspora;
use Friendica\Protocol\DFRN;
// Included here for completeness, but this is a very dangerous operation.
// It is the caller's responsibility to confirm the requestor's intent and
// authorisation to do this.
function user_remove($uid) {
if (!$uid) {
return;
}
logger('Removing user: ' . $uid);
$r = dba::select('user', array(), array('uid' => $uid), array("limit" => 1));
call_hooks('remove_user',$r);
// save username (actually the nickname as it is guaranteed
// unique), so it cannot be re-registered in the future.
dba::insert('userd', array('username' => $r['nickname']));
// The user and related data will be deleted in "cron_expire_and_remove_users" (cronjobs.php)
q("UPDATE `user` SET `account_removed` = 1, `account_expires_on` = UTC_TIMESTAMP() WHERE `uid` = %d", intval($uid));
Worker::add(PRIORITY_HIGH, "notifier", "removeme", $uid);
// Send an update to the directory
Worker::add(PRIORITY_LOW, "directory", $r['url']);
if($uid == local_user()) {
unset($_SESSION['authenticated']);
unset($_SESSION['uid']);
goaway(System::baseUrl());
}
}
function contact_remove($id) {
// We want just to make sure that we don't delete our "self" contact
$r = q("SELECT `uid` FROM `contact` WHERE `id` = %d AND NOT `self` LIMIT 1",
intval($id)
);
if (!DBM::is_result($r) || !intval($r[0]['uid'])) {
return;
}
$archive = PConfig::get($r[0]['uid'], 'system','archive_removed_contacts');
if ($archive) {
q("update contact set `archive` = 1, `network` = 'none', `writable` = 0 where id = %d",
intval($id)
);
return;
}
dba::delete('contact', array('id' => $id));
// Delete the rest in the background
Worker::add(PRIORITY_LOW, 'remove_contact', $id);
}
// sends an unfriend message. Does not remove the contact
function terminate_friendship($user,$self,$contact) {
/// @TODO Get rid of this, include/datetime.php should care about it by itself
$a = get_app();
require_once 'include/datetime.php';
if ($contact['network'] === NETWORK_OSTATUS) {
require_once 'include/ostatus.php';
// create an unfollow slap
$item = array();
$item['verb'] = NAMESPACE_OSTATUS."/unfollow";
$item['follow'] = $contact["url"];
$slap = ostatus::salmon($item, $user);
if ((x($contact,'notify')) && (strlen($contact['notify']))) {
require_once 'include/salmon.php';
slapper($user,$contact['notify'],$slap);
}
} elseif ($contact['network'] === NETWORK_DIASPORA) {
Diaspora::send_unshare($user,$contact);
} elseif ($contact['network'] === NETWORK_DFRN) {
DFRN::deliver($user,$contact,'placeholder', 1);
}
}
// Contact has refused to recognise us as a friend. We will start a countdown.
// If they still don't recognise us in 32 days, the relationship is over,
// and we won't waste any more time trying to communicate with them.
// This provides for the possibility that their database is temporarily messed
// up or some other transient event and that there's a possibility we could recover from it.
function mark_for_death($contact) {
if($contact['archive'])
return;
if ($contact['term-date'] <= NULL_DATE) {
q("UPDATE `contact` SET `term-date` = '%s' WHERE `id` = %d",
dbesc(datetime_convert()),
intval($contact['id'])
);
if ($contact['url'] != '') {
q("UPDATE `contact` SET `term-date` = '%s'
WHERE `nurl` = '%s' AND `term-date` <= '1000-00-00'",
dbesc(datetime_convert()),
dbesc(normalise_link($contact['url']))
);
}
} else {
/// @todo
/// We really should send a notification to the owner after 2-3 weeks
/// so they won't be surprised when the contact vanishes and can take
/// remedial action if this was a serious mistake or glitch
/// @todo
/// Check for contact vitality via probing
$expiry = $contact['term-date'] . ' + 32 days ';
if(datetime_convert() > datetime_convert('UTC','UTC',$expiry)) {
// relationship is really truly dead.
// archive them rather than delete
// though if the owner tries to unarchive them we'll start the whole process over again
q("UPDATE `contact` SET `archive` = 1 WHERE `id` = %d",
intval($contact['id'])
);
if ($contact['url'] != '') {
q("UPDATE `contact` SET `archive` = 1 WHERE `nurl` = '%s'",
dbesc(normalise_link($contact['url']))
);
}
}
}
}
function unmark_for_death($contact) {
$r = q("SELECT `term-date` FROM `contact` WHERE `id` = %d AND (`term-date` > '%s' OR `archive`)",
intval($contact['id']),
dbesc('1000-00-00 00:00:00')
);
// We don't need to update, we never marked this contact as dead
if (!DBM::is_result($r)) {
return;
}
// It's a miracle. Our dead contact has inexplicably come back to life.
$fields = array('term-date' => NULL_DATE, 'archive' => false);
dba::update('contact', $fields, array('id' => $contact['id']));
if ($contact['url'] != '') {
dba::update('contact', $fields, array('nurl' => normalise_link($contact['url'])));
}
}
/**
* @brief Get contact data for a given profile link
*
* The function looks at several places (contact table and gcontact table) for the contact
* It caches its result for the same script execution to prevent duplicate calls
*
* @param string $url The profile link
* @param int $uid User id
* @param array $default If not data was found take this data as default value
*
* @return array Contact data
*/
function get_contact_details_by_url($url, $uid = -1, $default = array()) {
static $cache = array();
if ($url == '') {
return $default;
}
if ($uid == -1) {
$uid = local_user();
}
if (isset($cache[$url][$uid])) {
return $cache[$url][$uid];
}
$ssl_url = str_replace('http://', 'https://', $url);
// Fetch contact data from the contact table for the given user
$s = dba::p("SELECT `id`, `id` AS `cid`, 0 AS `gid`, 0 AS `zid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
`keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, `self`
FROM `contact` WHERE `nurl` = ? AND `uid` = ?",
normalise_link($url), $uid);
$r = dba::inArray($s);
// Fetch contact data from the contact table for the given user, checking with the alias
if (!DBM::is_result($r)) {
$s = dba::p("SELECT `id`, `id` AS `cid`, 0 AS `gid`, 0 AS `zid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
`keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, `self`
FROM `contact` WHERE `alias` IN (?, ?, ?) AND `uid` = ?",
normalise_link($url), $url, $ssl_url, $uid);
$r = dba::inArray($s);
}
// Fetch the data from the contact table with "uid=0" (which is filled automatically)
if (!DBM::is_result($r)) {
$s = dba::p("SELECT `id`, 0 AS `cid`, `id` AS `zid`, 0 AS `gid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
`keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, 0 AS `self`
FROM `contact` WHERE `nurl` = ? AND `uid` = 0",
normalise_link($url));
$r = dba::inArray($s);
}
// Fetch the data from the contact table with "uid=0" (which is filled automatically) - checked with the alias
if (!DBM::is_result($r)) {
$s = dba::p("SELECT `id`, 0 AS `cid`, `id` AS `zid`, 0 AS `gid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
`keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, 0 AS `self`
FROM `contact` WHERE `alias` IN (?, ?, ?) AND `uid` = 0",
normalise_link($url), $url, $ssl_url);
$r = dba::inArray($s);
}
// Fetch the data from the gcontact table
if (!DBM::is_result($r)) {
$s = dba::p("SELECT 0 AS `id`, 0 AS `cid`, `id` AS `gid`, 0 AS `zid`, 0 AS `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, '' AS `xmpp`,
`keywords`, `gender`, `photo`, `photo` AS `thumb`, `photo` AS `micro`, `community` AS `forum`, 0 AS `prv`, `community`, `contact-type`, `birthday`, 0 AS `self`
FROM `gcontact` WHERE `nurl` = ?",
normalise_link($url));
$r = dba::inArray($s);
}
if (DBM::is_result($r)) {
// If there is more than one entry we filter out the connector networks
if (count($r) > 1) {
foreach ($r AS $id => $result) {
if ($result["network"] == NETWORK_STATUSNET) {
unset($r[$id]);
}
}
}
$profile = array_shift($r);
// "bd" always contains the upcoming birthday of a contact.
// "birthday" might contain the birthday including the year of birth.
if ($profile["birthday"] > '0001-01-01') {
$bd_timestamp = strtotime($profile["birthday"]);
$month = date("m", $bd_timestamp);
$day = date("d", $bd_timestamp);
$current_timestamp = time();
$current_year = date("Y", $current_timestamp);
$current_month = date("m", $current_timestamp);
$current_day = date("d", $current_timestamp);
$profile["bd"] = $current_year."-".$month."-".$day;
$current = $current_year."-".$current_month."-".$current_day;
if ($profile["bd"] < $current) {
$profile["bd"] = (++$current_year)."-".$month."-".$day;
}
} else {
$profile["bd"] = '0001-01-01';
}
} else {
$profile = $default;
}
if (($profile["photo"] == "") && isset($default["photo"])) {
$profile["photo"] = $default["photo"];
}
if (($profile["name"] == "") && isset($default["name"])) {
$profile["name"] = $default["name"];
}
if (($profile["network"] == "") && isset($default["network"])) {
$profile["network"] = $default["network"];
}
if (($profile["thumb"] == "") && isset($profile["photo"])) {
$profile["thumb"] = $profile["photo"];
}
if (($profile["micro"] == "") && isset($profile["thumb"])) {
$profile["micro"] = $profile["thumb"];
}
if ((($profile["addr"] == "") || ($profile["name"] == "")) && ($profile["gid"] != 0) &&
in_array($profile["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS))) {
Worker::add(PRIORITY_LOW, "update_gcontact", $profile["gid"]);
}
// Show contact details of Diaspora contacts only if connected
if (($profile["cid"] == 0) && ($profile["network"] == NETWORK_DIASPORA)) {
$profile["location"] = "";
$profile["about"] = "";
$profile["gender"] = "";
$profile["birthday"] = '0001-01-01';
}
$cache[$url][$uid] = $profile;
return $profile;
}
/**
* @brief Get contact data for a given address
*
* The function looks at several places (contact table and gcontact table) for the contact
*
* @param string $addr The profile link
* @param int $uid User id
*
* @return array Contact data
*/
function get_contact_details_by_addr($addr, $uid = -1) {
static $cache = array();
if ($addr == '') {
return array();
}
if ($uid == -1) {
$uid = local_user();
}
// Fetch contact data from the contact table for the given user
$r = q("SELECT `id`, `id` AS `cid`, 0 AS `gid`, 0 AS `zid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
`keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, `self`
FROM `contact` WHERE `addr` = '%s' AND `uid` = %d",
dbesc($addr), intval($uid));
// Fetch the data from the contact table with "uid=0" (which is filled automatically)
if (!DBM::is_result($r))
$r = q("SELECT `id`, 0 AS `cid`, `id` AS `zid`, 0 AS `gid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
`keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, 0 AS `self`
FROM `contact` WHERE `addr` = '%s' AND `uid` = 0",
dbesc($addr));
// Fetch the data from the gcontact table
if (!DBM::is_result($r))
$r = q("SELECT 0 AS `id`, 0 AS `cid`, `id` AS `gid`, 0 AS `zid`, 0 AS `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, '' AS `xmpp`,
`keywords`, `gender`, `photo`, `photo` AS `thumb`, `photo` AS `micro`, `community` AS `forum`, 0 AS `prv`, `community`, `contact-type`, `birthday`, 0 AS `self`
FROM `gcontact` WHERE `addr` = '%s'",
dbesc($addr));
if (!DBM::is_result($r)) {
$data = Probe::uri($addr);
$profile = get_contact_details_by_url($data['url'], $uid);
} else {
$profile = $r[0];
}
return $profile;
}
if (! function_exists('contact_photo_menu')) {
function contact_photo_menu($contact, $uid = 0)
{
$a = get_app();
$contact_url = '';
$pm_url = '';
$status_link = '';
$photos_link = '';
$posts_link = '';
$contact_drop_link = '';
$poke_link = '';
if ($uid == 0) {
$uid = local_user();
}
if ($contact['uid'] != $uid) {
if ($uid == 0) {
$profile_link = zrl($contact['url']);
$menu = Array('profile' => array(t('View Profile'), $profile_link, true));
return $menu;
}
$r = q("SELECT * FROM `contact` WHERE `nurl` = '%s' AND `network` = '%s' AND `uid` = %d",
dbesc($contact['nurl']), dbesc($contact['network']), intval($uid));
if ($r) {
return contact_photo_menu($r[0], $uid);
} else {
$profile_link = zrl($contact['url']);
$connlnk = 'follow/?url='.$contact['url'];
$menu = array(
'profile' => array(t('View Profile'), $profile_link, true),
'follow' => array(t('Connect/Follow'), $connlnk, true)
);
return $menu;
}
}
$sparkle = false;
if ($contact['network'] === NETWORK_DFRN) {
$sparkle = true;
$profile_link = System::baseUrl() . '/redir/' . $contact['id'];
} else {
$profile_link = $contact['url'];
}
if ($profile_link === 'mailbox') {
$profile_link = '';
}
if ($sparkle) {
$status_link = $profile_link . '?url=status';
$photos_link = $profile_link . '?url=photos';
$profile_link = $profile_link . '?url=profile';
}
if (in_array($contact['network'], array(NETWORK_DFRN, NETWORK_DIASPORA))) {
$pm_url = System::baseUrl() . '/message/new/' . $contact['id'];
}
if ($contact['network'] == NETWORK_DFRN) {
$poke_link = System::baseUrl() . '/poke/?f=&c=' . $contact['id'];
}
$contact_url = System::baseUrl() . '/contacts/' . $contact['id'];
$posts_link = System::baseUrl() . '/contacts/' . $contact['id'] . '/posts';
$contact_drop_link = System::baseUrl() . '/contacts/' . $contact['id'] . '/drop?confirm=1';
/**
* menu array:
* "name" => [ "Label", "link", (bool)Should the link opened in a new tab? ]
*/
$menu = array(
'status' => array(t("View Status"), $status_link, true),
'profile' => array(t("View Profile"), $profile_link, true),
'photos' => array(t("View Photos"), $photos_link, true),
'network' => array(t("Network Posts"), $posts_link, false),
'edit' => array(t("View Contact"), $contact_url, false),
'drop' => array(t("Drop Contact"), $contact_drop_link, false),
'pm' => array(t("Send PM"), $pm_url, false),
'poke' => array(t("Poke"), $poke_link, false),
);
$args = array('contact' => $contact, 'menu' => &$menu);
call_hooks('contact_photo_menu', $args);
$menucondensed = array();
foreach ($menu AS $menuname => $menuitem) {
if ($menuitem[1] != '') {
$menucondensed[$menuname] = $menuitem;
}
}
return $menucondensed;
}}
function random_profile() {
$r = q("SELECT `url` FROM `gcontact` WHERE `network` = '%s'
AND `last_contact` >= `last_failure`
AND `updated` > UTC_TIMESTAMP - INTERVAL 1 MONTH
ORDER BY rand() LIMIT 1",
dbesc(NETWORK_DFRN));
if (DBM::is_result($r))
return dirname($r[0]['url']);
return '';
}
function contacts_not_grouped($uid,$start = 0,$count = 0) {
if(! $count) {
$r = q("select count(*) as total from contact where uid = %d and self = 0 and id not in (select distinct(`contact-id`) from group_member where uid = %d) ",
intval($uid),
intval($uid)
);
return $r;
}
$r = q("select * from contact where uid = %d and self = 0 and id not in (select distinct(`contact-id`) from group_member where uid = %d) and blocked = 0 and pending = 0 limit %d, %d",
intval($uid),
intval($uid),
intval($start),
intval($count)
);
return $r;
}
/**
* @brief Fetch the contact id for a given url and user
*
* First lookup in the contact table to find a record matching either `url`, `nurl`,
* `addr` or `alias`.
*
* If there's no record and we aren't looking for a public contact, we quit.
* If there's one, we check that it isn't time to update the picture else we
* directly return the found contact id.
*
* Second, we probe the provided $url wether it's http://server.tld/profile or
* nick@server.tld. We quit if we can't get any info back.
*
* Third, we create the contact record if it doesn't exist
*
* Fourth, we update the existing record with the new data (avatar, alias, nick)
* if there's any updates
*
* @param string $url Contact URL
* @param integer $uid The user id for the contact (0 = public contact)
* @param boolean $no_update Don't update the contact
*
* @return integer Contact ID
*/
function get_contact($url, $uid = 0, $no_update = false) {
logger("Get contact data for url ".$url." and user ".$uid." - ".System::callstack(), LOGGER_DEBUG);
$data = array();
$contact_id = 0;
if ($url == '') {
return 0;
}
// We first try the nurl (http://server.tld/nick), most common case
$contact = dba::select('contact', array('id', 'avatar-date'), array('nurl' => normalise_link($url), 'uid' => $uid), array('limit' => 1));
// Then the addr (nick@server.tld)
if (!DBM::is_result($contact)) {
$contact = dba::select('contact', array('id', 'avatar-date'), array('addr' => $url, 'uid' => $uid), array('limit' => 1));
}
// Then the alias (which could be anything)
if (!DBM::is_result($contact)) {
// The link could be provided as http although we stored it as https
$ssl_url = str_replace('http://', 'https://', $url);
$r = dba::p("SELECT `id`, `avatar-date` FROM `contact` WHERE `alias` IN (?, ?, ?) AND `uid` = ? LIMIT 1",
$url, normalise_link($url), $ssl_url, $uid);
$contact = dba::fetch($r);
dba::close($r);
}
if (DBM::is_result($contact)) {
$contact_id = $contact["id"];
// Update the contact every 7 days
$update_contact = ($contact['avatar-date'] < datetime_convert('','','now -7 days'));
// We force the update if the avatar is empty
if ($contact['avatar'] == '') {
$update_contact = true;
}
if (!$update_contact || $no_update) {
return $contact_id;
}
} elseif ($uid != 0) {
// Non-existing user-specific contact, exiting
return 0;
}
$data = Probe::uri($url, "", $uid);
// Last try in gcontact for unsupported networks
if (!in_array($data["network"], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA, NETWORK_PUMPIO, NETWORK_MAIL))) {
if ($uid != 0) {
return 0;
}
// Get data from the gcontact table
$gcontacts = dba::select('gcontact', array('name', 'nick', 'url', 'photo', 'addr', 'alias', 'network'),
array('nurl' => normalise_link($url)), array('limit' => 1));
if (!DBM::is_result($gcontacts)) {
return 0;
}
$data = array_merge($data, $gcontacts);
}
if (!$contact_id && ($data["alias"] != '') && ($data["alias"] != $url)) {
$contact_id = get_contact($data["alias"], $uid, true);
}
$url = $data["url"];
if (!$contact_id) {
dba::insert('contact', array('uid' => $uid, 'created' => datetime_convert(), 'url' => $data["url"],
'nurl' => normalise_link($data["url"]), 'addr' => $data["addr"],
'alias' => $data["alias"], 'notify' => $data["notify"], 'poll' => $data["poll"],
'name' => $data["name"], 'nick' => $data["nick"], 'photo' => $data["photo"],
'keywords' => $data["keywords"], 'location' => $data["location"], 'about' => $data["about"],
'network' => $data["network"], 'pubkey' => $data["pubkey"],
'rel' => CONTACT_IS_SHARING, 'priority' => $data["priority"],
'batch' => $data["batch"], 'request' => $data["request"],
'confirm' => $data["confirm"], 'poco' => $data["poco"],
'name-date' => datetime_convert(), 'uri-date' => datetime_convert(),
'avatar-date' => datetime_convert(), 'writable' => 1, 'blocked' => 0,
'readonly' => 0, 'pending' => 0));
$contacts = q("SELECT `id` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d ORDER BY `id` LIMIT 2",
dbesc(normalise_link($data["url"])),
intval($uid));
if (!DBM::is_result($contacts)) {
return 0;
}
$contact_id = $contacts[0]["id"];
// Update the newly created contact from data in the gcontact table
$gcontact = dba::select('gcontact', array('location', 'about', 'keywords', 'gender'),
array('nurl' => normalise_link($data["url"])), array('limit' => 1));
if (DBM::is_result($gcontact)) {
// Only use the information when the probing hadn't fetched these values
if ($data['keywords'] != '') {
unset($gcontact['keywords']);
}
if ($data['location'] != '') {
unset($gcontact['location']);
}
if ($data['about'] != '') {
unset($gcontact['about']);
}
dba::update('contact', $gcontact, array('id' => $contact_id));
}
if (count($contacts) > 1 && $uid == 0 && $contact_id != 0 && $data["url"] != "") {
dba::delete('contact', array("`nurl` = ? AND `uid` = 0 AND `id` != ? AND NOT `self`",
normalise_link($data["url"]), $contact_id));
}
}
require_once "Photo.php";
update_contact_avatar($data["photo"], $uid, $contact_id);
$contact = dba::select('contact', array('url', 'nurl', 'addr', 'alias', 'name', 'nick', 'keywords', 'location', 'about', 'avatar-date'),
array('id' => $contact_id), array('limit' => 1));
// This condition should always be true
if (!DBM::is_result($contact)) {
return $contact_id;
}
$updated = array('addr' => $data['addr'],
'alias' => $data['alias'],
'url' => $data['url'],
'nurl' => normalise_link($data['url']),
'name' => $data['name'],
'nick' => $data['nick']);
if ($data['keywords'] != '') {
$updated['keywords'] = $data['keywords'];
}
if ($data['location'] != '') {
$updated['location'] = $data['location'];
}
if ($data['about'] != '') {
$updated['about'] = $data['about'];
}
if (($data["addr"] != $contact["addr"]) || ($data["alias"] != $contact["alias"])) {
$updated['uri-date'] = datetime_convert();
}
if (($data["name"] != $contact["name"]) || ($data["nick"] != $contact["nick"])) {
$updated['name-date'] = datetime_convert();
}
$updated['avatar-date'] = datetime_convert();
dba::update('contact', $updated, array('id' => $contact_id), $contact);
return $contact_id;
}
/**
* @brief Checks if the contact is blocked
*
* @param int $cid contact id
*
* @return boolean Is the contact blocked?
*/
function blockedContact($cid) {
if ($cid == 0) {
return false;
}
$blocked = dba::select('contact', array('blocked'), array('id' => $cid), array('limit' => 1));
if (!DBM::is_result($blocked)) {
return false;
}
return (bool)$blocked['blocked'];
}
/**
* @brief Checks if the contact is hidden
*
* @param int $cid contact id
*
* @return boolean Is the contact hidden?
*/
function hiddenContact($cid) {
if ($cid == 0) {
return false;
}
$hidden = dba::select('contact', array('hidden'), array('id' => $cid), array('limit' => 1));
if (!DBM::is_result($hidden)) {
return false;
}
return (bool)$hidden['hidden'];
}
/**
* @brief Returns posts from a given gcontact
*
* @param App $a argv application class
* @param int $gcontact_id Global contact
*
* @return string posts in HTML
*/
function posts_from_gcontact(App $a, $gcontact_id) {
require_once 'include/conversation.php';
// There are no posts with "uid = 0" with connector networks
// This speeds up the query a lot
$r = q("SELECT `network` FROM `gcontact` WHERE `id` = %d", dbesc($gcontact_id));
if (in_array($r[0]["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, "")))
$sql = "(`item`.`uid` = 0 OR (`item`.`uid` = %d AND `item`.`private`))";
else
$sql = "`item`.`uid` = %d";
$r = q("SELECT `item`.`uri`, `item`.*, `item`.`id` AS `item_id`,
`author-name` AS `name`, `owner-avatar` AS `photo`,
`owner-link` AS `url`, `owner-avatar` AS `thumb`
FROM `item`
WHERE `gcontact-id` = %d AND $sql AND
NOT `deleted` AND NOT `moderated` AND `visible`
ORDER BY `item`.`created` DESC LIMIT %d, %d",
intval($gcontact_id),
intval(local_user()),
intval($a->pager['start']),
intval($a->pager['itemspage'])
);
$o = conversation($a, $r, 'community', false);
$o .= alt_pager($a, count($r));
return $o;
}
/**
* @brief Returns posts from a given contact url
*
* @param App $a argv application class
* @param string $contact_url Contact URL
*
* @return string posts in HTML
*/
function posts_from_contact_url(App $a, $contact_url) {
require_once 'include/conversation.php';
// There are no posts with "uid = 0" with connector networks
// This speeds up the query a lot
$r = q("SELECT `network`, `id` AS `author-id`, `contact-type` FROM `contact`
WHERE `contact`.`nurl` = '%s' AND `contact`.`uid` = 0",
dbesc(normalise_link($contact_url)));
if (!DBM::is_result($r)) {
return '';
}
if (in_array($r[0]["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, ""))) {
$sql = "(`item`.`uid` = 0 OR (`item`.`uid` = %d AND NOT `item`.`global`))";
} else {
$sql = "`item`.`uid` = %d";
}
$author_id = intval($r[0]["author-id"]);
$contact = ($r[0]["contact-type"] == ACCOUNT_TYPE_COMMUNITY ? 'owner-id' : 'author-id');
$r = q(item_query()." AND `item`.`".$contact."` = %d AND ".$sql.
" ORDER BY `item`.`created` DESC LIMIT %d, %d",
intval($author_id),
intval(local_user()),
intval($a->pager['start']),
intval($a->pager['itemspage'])
);
$o = conversation($a, $r, 'community', false);
$o .= alt_pager($a, count($r));
return $o;
}
/**
* @brief Returns a formatted location string from the given profile array
*
* @param array $profile Profile array (Generated from the "profile" table)
*
* @return string Location string
*/
function formatted_location($profile) {
$location = '';
if($profile['locality'])
$location .= $profile['locality'];
if($profile['region'] && ($profile['locality'] != $profile['region'])) {
if($location)
$location .= ', ';
$location .= $profile['region'];
}
if($profile['country-name']) {
if($location)
$location .= ', ';
$location .= $profile['country-name'];
}
return $location;
}
/**
* @brief Returns the account type name
*
* The function can be called with either the user or the contact array
*
* @param array $contact contact or user array
*/
function account_type($contact) {
// There are several fields that indicate that the contact or user is a forum
// "page-flags" is a field in the user table,
// "forum" and "prv" are used in the contact table. They stand for PAGE_COMMUNITY and PAGE_PRVGROUP.
// "community" is used in the gcontact table and is true if the contact is PAGE_COMMUNITY or PAGE_PRVGROUP.
if((isset($contact['page-flags']) && (intval($contact['page-flags']) == PAGE_COMMUNITY))
|| (isset($contact['page-flags']) && (intval($contact['page-flags']) == PAGE_PRVGROUP))
|| (isset($contact['forum']) && intval($contact['forum']))
|| (isset($contact['prv']) && intval($contact['prv']))
|| (isset($contact['community']) && intval($contact['community'])))
$type = ACCOUNT_TYPE_COMMUNITY;
else
$type = ACCOUNT_TYPE_PERSON;
// The "contact-type" (contact table) and "account-type" (user table) are more general then the chaos from above.
if (isset($contact["contact-type"]))
$type = $contact["contact-type"];
if (isset($contact["account-type"]))
$type = $contact["account-type"];
switch($type) {
case ACCOUNT_TYPE_ORGANISATION:
$account_type = t("Organisation");
break;
case ACCOUNT_TYPE_NEWS:
$account_type = t('News');
break;
case ACCOUNT_TYPE_COMMUNITY:
$account_type = t("Forum");
break;
default:
$account_type = "";
break;
}
return $account_type;
}

View File

@ -1,64 +0,0 @@
<?php
/**
* @file include/DirSearch.php
* @brief This file includes the DirSearch class with directory related functions
*/
use Friendica\Core\Config;
/**
* @brief This class handels directory related functions
*/
class DirSearch {
/**
* @brief Search global contact table by nick or name
*
* @param string $search Name or nick
* @param string $mode Search mode (e.g. "community")
* @return array with search results
*/
public static function global_search_by_name($search, $mode = '') {
if($search) {
// check supported networks
if (Config::get('system','diaspora_enabled'))
$diaspora = NETWORK_DIASPORA;
else
$diaspora = NETWORK_DFRN;
if (!Config::get('system','ostatus_disabled'))
$ostatus = NETWORK_OSTATUS;
else
$ostatus = NETWORK_DFRN;
// check if we search only communities or every contact
if($mode === "community")
$extra_sql = " AND `community`";
else
$extra_sql = "";
$search .= "%";
$results = q("SELECT `contact`.`id` AS `cid`, `gcontact`.`url`, `gcontact`.`name`, `gcontact`.`nick`, `gcontact`.`photo`,
`gcontact`.`network`, `gcontact`.`keywords`, `gcontact`.`addr`, `gcontact`.`community`
FROM `gcontact`
LEFT JOIN `contact` ON `contact`.`nurl` = `gcontact`.`nurl`
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`.`addr` LIKE '%s' OR `gcontact`.`name` LIKE '%s' OR `gcontact`.`nick` LIKE '%s') $extra_sql
GROUP BY `gcontact`.`nurl`
ORDER BY `gcontact`.`nurl` DESC
LIMIT 1000",
intval(local_user()), dbesc(CONTACT_IS_SHARING), dbesc(CONTACT_IS_FRIEND),
dbesc(NETWORK_DFRN), dbesc($ostatus), dbesc($diaspora),
dbesc(escape_tags($search)), dbesc(escape_tags($search)), dbesc(escape_tags($search)));
return $results;
}
}
}

View File

@ -1,85 +0,0 @@
<?php
use Friendica\Core\PConfig;
require_once('include/email.php');
class Emailer {
/**
* Send a multipart/alternative message with Text and HTML versions
*
* @param fromName name of the sender
* @param fromEmail email fo the sender
* @param replyTo replyTo address to direct responses
* @param toEmail destination email address
* @param messageSubject subject of the message
* @param htmlVersion html version of the message
* @param textVersion text only version of the message
* @param additionalMailHeader additions to the smtp mail header
* @param optional uid user id of the destination user
*/
public static function send($params) {
call_hooks('emailer_send_prepare', $params);
$email_textonly = False;
if (x($params,"uid")) {
$email_textonly = PConfig::get($params['uid'], "system", "email_textonly");
}
$fromName = email_header_encode(html_entity_decode($params['fromName'],ENT_QUOTES,'UTF-8'),'UTF-8');
$messageSubject = email_header_encode(html_entity_decode($params['messageSubject'],ENT_QUOTES,'UTF-8'),'UTF-8');
// generate a mime boundary
$mimeBoundary =rand(0,9)."-"
.rand(100000000,999999999)."-"
.rand(100000000,999999999)."=:"
.rand(10000,99999);
// generate a multipart/alternative message header
$messageHeader =
$params['additionalMailHeader'] .
"From: $fromName <{$params['fromEmail']}>\n" .
"Reply-To: $fromName <{$params['replyTo']}>\n" .
"MIME-Version: 1.0\n" .
"Content-Type: multipart/alternative; boundary=\"{$mimeBoundary}\"";
// assemble the final multipart message body with the text and html types included
$textBody = chunk_split(base64_encode($params['textVersion']));
$htmlBody = chunk_split(base64_encode($params['htmlVersion']));
$multipartMessageBody =
"--" . $mimeBoundary . "\n" . // plain text section
"Content-Type: text/plain; charset=UTF-8\n" .
"Content-Transfer-Encoding: base64\n\n" .
$textBody . "\n";
if (!$email_textonly && !is_null($params['htmlVersion'])){
$multipartMessageBody .=
"--" . $mimeBoundary . "\n" . // text/html section
"Content-Type: text/html; charset=UTF-8\n" .
"Content-Transfer-Encoding: base64\n\n" .
$htmlBody . "\n";
}
$multipartMessageBody .=
"--" . $mimeBoundary . "--\n"; // message ending
// send the message
$hookdata = array(
'to' => $params['toEmail'],
'subject' => $messageSubject,
'body' => $multipartMessageBody,
'headers' => $messageHeader
);
//echo "<pre>"; var_dump($hookdata); killme();
call_hooks("emailer_send", $hookdata);
$res = mail(
$hookdata['to'], // send to address
$hookdata['subject'], // subject
$hookdata['body'], // message body
$hookdata['headers'] // message headers
);
logger("header " . 'To: ' . $params['toEmail'] . "\n" . $messageHeader, LOGGER_DEBUG);
logger("return value " . (($res)?"true":"false"), LOGGER_DEBUG);
return $res;
}
}

View File

@ -1,105 +0,0 @@
<?php
/**
* Throwable exceptions to return HTTP status code
*
* This list of Exception has be extracted from
* here http://racksburg.com/choosing-an-http-status-code/
*/
class HTTPException extends Exception {
var $httpcode = 200;
var $httpdesc = "";
public function __construct($message="", $code = 0, Exception $previous = null) {
if ($this->httpdesc=="") {
$this->httpdesc = preg_replace("|([a-z])([A-Z])|",'$1 $2', str_replace("Exception","",get_class($this)));
}
parent::__construct($message, $code, $previous);
}
}
// 4xx
class TooManyRequestsException extends HTTPException {
var $httpcode = 429;
}
class UnauthorizedException extends HTTPException {
var $httpcode = 401;
}
class ForbiddenException extends HTTPException {
var $httpcode = 403;
}
class NotFoundException extends HTTPException {
var $httpcode = 404;
}
class GoneException extends HTTPException {
var $httpcode = 410;
}
class MethodNotAllowedException extends HTTPException {
var $httpcode = 405;
}
class NonAcceptableException extends HTTPException {
var $httpcode = 406;
}
class LenghtRequiredException extends HTTPException {
var $httpcode = 411;
}
class PreconditionFailedException extends HTTPException {
var $httpcode = 412;
}
class UnsupportedMediaTypeException extends HTTPException {
var $httpcode = 415;
}
class ExpetationFailesException extends HTTPException {
var $httpcode = 417;
}
class ConflictException extends HTTPException {
var $httpcode = 409;
}
class UnprocessableEntityException extends HTTPException {
var $httpcode = 422;
}
class ImATeapotException extends HTTPException {
var $httpcode = 418;
var $httpdesc = "I'm A Teapot";
}
class BadRequestException extends HTTPException {
var $httpcode = 400;
}
// 5xx
class ServiceUnavaiableException extends HTTPException {
var $httpcode = 503;
}
class BadGatewayException extends HTTPException {
var $httpcode = 502;
}
class GatewayTimeoutException extends HTTPException {
var $httpcode = 504;
}
class NotImplementedException extends HTTPException {
var $httpcode = 501;
}
class InternalServerErrorException extends HTTPException {
var $httpcode = 500;
}

View File

@ -7,10 +7,11 @@
use Friendica\App;
use Friendica\Core\Config;
use Friendica\Database\DBM;
use Friendica\Model\GlobalContact;
use Friendica\Object\Contact;
require_once "include/contact_selectors.php";
require_once "include/contact_widgets.php";
require_once "include/DirSearch.php";
require_once "include/features.php";
require_once "mod/proxy.php";
@ -59,10 +60,9 @@ function group_select($selname,$selclass,$preselected = false,$size = 4) {
return $o;
}
/// @TODO after an optional parameter, no mandadory parameter can follow
/// @TODO find proper type-hints
function contact_selector($selname, $selclass, $preselected = false, $options) {
function contact_selector($selname, $selclass, $options, $preselected = false)
{
$a = get_app();
$mutual = false;
@ -692,7 +692,7 @@ function acl_lookup(App $a, $out_type = 'json') {
);
if (DBM::is_result($r)) {
foreach ($r as $row) {
$contact = get_contact_details_by_url($row['author-link']);
$contact = Contact::getDetailsByURL($row['author-link']);
if (count($contact) > 0) {
$unknown_contacts[] = array(
@ -779,7 +779,7 @@ function navbar_complete(App $a) {
}
if ($localsearch) {
$x = DirSearch::global_search_by_name($search, $mode);
$x = GlobalContact::searchByName($search, $mode);
return $x;
}

View File

@ -12,10 +12,20 @@ use Friendica\Core\Config;
use Friendica\Core\NotificationsManager;
use Friendica\Core\Worker;
use Friendica\Database\DBM;
use Friendica\Model\User;
use Friendica\Network\HTTPException;
use Friendica\Network\HTTPException\BadRequestException;
use Friendica\Network\HTTPException\ForbiddenException;
use Friendica\Network\HTTPException\InternalServerErrorException;
use Friendica\Network\HTTPException\MethodNotAllowedException;
use Friendica\Network\HTTPException\NotFoundException;
use Friendica\Network\HTTPException\NotImplementedException;
use Friendica\Network\HTTPException\UnauthorizedException;
use Friendica\Network\HTTPException\TooManyRequestsException;
use Friendica\Object\Contact;
use Friendica\Protocol\Diaspora;
use Friendica\Util\XML;
require_once 'include/HTTPExceptions.php';
require_once 'include/bbcode.php';
require_once 'include/datetime.php';
require_once 'include/conversation.php';
@ -181,7 +191,6 @@ function api_login(App $a)
$user = $_SERVER['PHP_AUTH_USER'];
$password = $_SERVER['PHP_AUTH_PW'];
$encrypted = hash('whirlpool', trim($password));
// allow "user@server" login (but ignore 'server' part)
$at = strstr($user, "@", true);
@ -209,16 +218,9 @@ function api_login(App $a)
if (($addon_auth['authenticated']) && (count($addon_auth['user_record']))) {
$record = $addon_auth['user_record'];
} else {
// process normal login request
$r = q(
"SELECT * FROM `user` WHERE (`email` = '%s' OR `nickname` = '%s')
AND `password` = '%s' AND NOT `blocked` AND NOT `account_expired` AND NOT `account_removed` AND `verified` LIMIT 1",
dbesc(trim($user)),
dbesc(trim($user)),
dbesc($encrypted)
);
if (DBM::is_result($r)) {
$record = $r[0];
$user_id = User::authenticate(trim($user), trim($password));
if ($user_id) {
$record = dba::select('user', [], ['uid' => $user_id], ['limit' => 1]);
}
}
@ -649,7 +651,7 @@ function api_get_user(App $a, $contact_id = null, $type = "json")
'notifications' => false,
'statusnet_profile_url' => $r[0]["url"],
'uid' => 0,
'cid' => get_contact($r[0]["url"], api_user(), true),
'cid' => Contact::getIdForURL($r[0]["url"], api_user(), true),
'self' => 0,
'network' => $r[0]["network"],
);
@ -737,7 +739,7 @@ function api_get_user(App $a, $contact_id = null, $type = "json")
$network_name = network_to_name($uinfo[0]['network'], $uinfo[0]['url']);
$pcontact_id = get_contact($uinfo[0]['url'], 0, true);
$pcontact_id = Contact::getIdForURL($uinfo[0]['url'], 0, true);
$ret = array(
'id' => intval($pcontact_id),
@ -901,7 +903,7 @@ function api_create_xml($data, $root_element)
$data3 = array($root_element => $data2);
$ret = XML::from_array($data3, $xml, false, $namespaces);
$ret = XML::fromArray($data3, $xml, false, $namespaces);
return $ret;
}
@ -3434,11 +3436,7 @@ function api_fr_photoalbum_delete($type)
}
// now let's delete all photos from the album
$result = q(
"DELETE FROM `photo` WHERE `uid` = %d AND `album` = '%s'",
intval(api_user()),
dbesc($album)
);
$result = dba::delete('photo', array('uid' => api_user(), 'album' => $album));
// return success of deletion or error message
if ($result) {
@ -3721,11 +3719,7 @@ function api_fr_photo_delete($type)
throw new BadRequestException("photo not available");
}
// now we can perform on the deletion of the photo
$result = q(
"DELETE FROM `photo` WHERE `uid` = %d AND `resource-id` = '%s'",
intval(api_user()),
dbesc($photo_id)
);
$result = dba::delete('photo', array('uid' => api_user(), 'resource-id' => $photo_id));
// return success of deletion or error message
if ($result) {
@ -3870,10 +3864,10 @@ function api_account_update_profile_image($type)
//$user = api_get_user(get_app());
$url = System::baseUrl() . '/profile/' . get_app()->user['nickname'];
if ($url && strlen(Config::get('system', 'directory'))) {
Worker::add(PRIORITY_LOW, "directory", $url);
Worker::add(PRIORITY_LOW, "Directory", $url);
}
Worker::add(PRIORITY_LOW, 'profile_update', api_user());
Worker::add(PRIORITY_LOW, 'ProfileUpdate', api_user());
// output for client
if ($data) {
@ -4298,7 +4292,7 @@ function api_share_as_retweet(&$item)
{
$body = trim($item["body"]);
if (Diaspora::is_reshare($body, false)===false) {
if (Diaspora::isReshare($body, false)===false) {
return false;
}
@ -4306,7 +4300,7 @@ function api_share_as_retweet(&$item)
$attributes = preg_replace("/\[share(.*?)\]\s?(.*?)\s?\[\/share\]\s?/ism", "$1", $body);
/*
* Skip if there is no shared message in there
* we already checked this in diaspora::is_reshare()
* we already checked this in diaspora::isReshare()
* but better one more than one less...
*/
if ($body == $attributes) {

View File

@ -4,22 +4,31 @@ use Friendica\App;
use Friendica\Core\System;
use Friendica\Core\Config;
use Friendica\Database\DBM;
use Friendica\Model\User;
require_once('include/security.php');
require_once('include/datetime.php');
require_once 'include/security.php';
require_once 'include/datetime.php';
// When the "Friendica" cookie is set, take the value to authenticate and renew the cookie.
if (isset($_COOKIE["Friendica"])) {
$data = json_decode($_COOKIE["Friendica"]);
if (isset($data->uid)) {
$r = q("SELECT `user`.*, `user`.`pubkey` as `upubkey`, `user`.`prvkey` as `uprvkey`
FROM `user` WHERE `uid` = %d AND NOT `blocked` AND NOT `account_expired` AND NOT `account_removed` AND `verified` LIMIT 1",
intval($data->uid)
$user = dba::select('user',
[],
[
'uid' => $data->uid,
'blocked' => false,
'account_expired' => false,
'account_removed' => false,
'verified' => true,
],
['limit' => 1]
);
if ($r) {
if ($data->hash != cookie_hash($r[0])) {
logger("Hash for user ".$data->uid." doesn't fit.");
if (DBM::is_result($user)) {
if ($data->hash != cookie_hash($user)) {
logger("Hash for user " . $data->uid . " doesn't fit.");
nuke_session();
goaway(System::baseUrl());
}
@ -28,14 +37,15 @@ if (isset($_COOKIE["Friendica"])) {
// Expires after 7 days by default,
// can be set via system.auth_cookie_lifetime
$authcookiedays = Config::get('system', 'auth_cookie_lifetime', 7);
new_cookie($authcookiedays*24*60*60, $r[0]);
new_cookie($authcookiedays * 24 * 60 * 60, $user);
// Do the authentification if not done by now
if (!isset($_SESSION) || !isset($_SESSION['authenticated'])) {
authenticate_success($r[0]);
authenticate_success($user);
if (Config::get('system','paranoia'))
if (Config::get('system', 'paranoia')) {
$_SESSION['addr'] = $data->ip;
}
}
}
}
@ -44,18 +54,16 @@ if (isset($_COOKIE["Friendica"])) {
// login/logout
if (isset($_SESSION) && x($_SESSION,'authenticated') && (!x($_POST,'auth-params') || ($_POST['auth-params'] !== 'login'))) {
if ((x($_POST,'auth-params') && ($_POST['auth-params'] === 'logout')) || ($a->module === 'logout')) {
if (isset($_SESSION) && x($_SESSION, 'authenticated') && (!x($_POST, 'auth-params') || ($_POST['auth-params'] !== 'login'))) {
if ((x($_POST, 'auth-params') && ($_POST['auth-params'] === 'logout')) || ($a->module === 'logout')) {
// process logout request
call_hooks("logging_out");
nuke_session();
info(t('Logged out.').EOL);
info(t('Logged out.') . EOL);
goaway(System::baseUrl());
}
if (x($_SESSION,'visitor_id') && !x($_SESSION,'uid')) {
if (x($_SESSION, 'visitor_id') && !x($_SESSION, 'uid')) {
$r = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1",
intval($_SESSION['visitor_id'])
);
@ -64,25 +72,29 @@ if (isset($_SESSION) && x($_SESSION,'authenticated') && (!x($_POST,'auth-params'
}
}
if (x($_SESSION,'uid')) {
if (x($_SESSION, 'uid')) {
// already logged in user returning
$check = Config::get('system','paranoia');
$check = Config::get('system', 'paranoia');
// extra paranoia - if the IP changed, log them out
if ($check && ($_SESSION['addr'] != $_SERVER['REMOTE_ADDR'])) {
logger('Session address changed. Paranoid setting in effect, blocking session. '.
$_SESSION['addr'].' != '.$_SERVER['REMOTE_ADDR']);
logger('Session address changed. Paranoid setting in effect, blocking session. ' .
$_SESSION['addr'] . ' != ' . $_SERVER['REMOTE_ADDR']);
nuke_session();
goaway(System::baseUrl());
}
$r = q("SELECT `user`.*, `user`.`pubkey` as `upubkey`, `user`.`prvkey` as `uprvkey`
FROM `user` WHERE `uid` = %d AND NOT `blocked` AND NOT `account_expired` AND NOT `account_removed` AND `verified` LIMIT 1",
intval($_SESSION['uid'])
$user = dba::select('user',
[],
[
'uid' => $_SESSION['uid'],
'blocked' => false,
'account_expired' => false,
'account_removed' => false,
'verified' => true,
],
['limit' => 1]
);
if (!DBM::is_result($r)) {
if (!DBM::is_result($user)) {
nuke_session();
goaway(System::baseUrl());
}
@ -91,61 +103,57 @@ if (isset($_SESSION) && x($_SESSION,'authenticated') && (!x($_POST,'auth-params'
// stays logged in for a long time, e.g. with "Remember Me"
$login_refresh = false;
if (!x($_SESSION['last_login_date'])) {
$_SESSION['last_login_date'] = datetime_convert('UTC','UTC');
$_SESSION['last_login_date'] = datetime_convert('UTC', 'UTC');
}
if (strcmp(datetime_convert('UTC','UTC','now - 12 hours'), $_SESSION['last_login_date']) > 0) {
$_SESSION['last_login_date'] = datetime_convert('UTC','UTC');
if (strcmp(datetime_convert('UTC', 'UTC', 'now - 12 hours'), $_SESSION['last_login_date']) > 0) {
$_SESSION['last_login_date'] = datetime_convert('UTC', 'UTC');
$login_refresh = true;
}
authenticate_success($r[0], false, false, $login_refresh);
authenticate_success($user, false, false, $login_refresh);
}
} else {
session_unset();
if (
!(x($_POST, 'password') && strlen($_POST['password']))
&& (
x($_POST, 'openid_url') && strlen($_POST['openid_url'])
|| x($_POST, 'username') && strlen($_POST['username'])
)
) {
$noid = Config::get('system', 'no_openid');
if (x($_POST,'password') && strlen($_POST['password']))
$encrypted = hash('whirlpool',trim($_POST['password']));
else {
if ((x($_POST,'openid_url')) && strlen($_POST['openid_url']) ||
(x($_POST,'username')) && strlen($_POST['username'])) {
$openid_url = trim(strlen($_POST['openid_url']) ? $_POST['openid_url'] : $_POST['username']);
$noid = Config::get('system','no_openid');
// validate_url alters the calling parameter
$openid_url = trim((strlen($_POST['openid_url'])?$_POST['openid_url']:$_POST['username']));
$temp_string = $openid_url;
// validate_url alters the calling parameter
// if it's an email address or doesn't resolve to a URL, fail.
$temp_string = $openid_url;
// if it's an email address or doesn't resolve to a URL, fail.
if ($noid || strpos($temp_string,'@') || !validate_url($temp_string)) {
$a = get_app();
notice(t('Login failed.').EOL);
goaway(System::baseUrl());
// NOTREACHED
}
// Otherwise it's probably an openid.
try {
require_once('library/openid.php');
$openid = new LightOpenID;
$openid->identity = $openid_url;
$_SESSION['openid'] = $openid_url;
$_SESSION['remember'] = $_POST['remember'];
$openid->returnUrl = System::baseUrl(true).'/openid';
goaway($openid->authUrl());
} catch (Exception $e) {
notice(t('We encountered a problem while logging in with the OpenID you provided. Please check the correct spelling of the ID.').'<br /><br >'.t('The error message was:').' '.$e->getMessage());
}
if ($noid || strpos($temp_string, '@') || !validate_url($temp_string)) {
$a = get_app();
notice(t('Login failed.') . EOL);
goaway(System::baseUrl());
// NOTREACHED
}
// Otherwise it's probably an openid.
try {
require_once('library/openid.php');
$openid = new LightOpenID;
$openid->identity = $openid_url;
$_SESSION['openid'] = $openid_url;
$_SESSION['remember'] = $_POST['remember'];
$openid->returnUrl = System::baseUrl(true) . '/openid';
goaway($openid->authUrl());
} catch (Exception $e) {
notice(t('We encountered a problem while logging in with the OpenID you provided. Please check the correct spelling of the ID.') . '<br /><br >' . t('The error message was:') . ' ' . $e->getMessage());
}
// NOTREACHED
}
if (x($_POST,'auth-params') && $_POST['auth-params'] === 'login') {
if (x($_POST, 'auth-params') && $_POST['auth-params'] === 'login') {
$record = null;
$addon_auth = array(
@ -162,39 +170,30 @@ if (isset($_SESSION) && x($_SESSION,'authenticated') && (!x($_POST,'auth-params'
* and later plugins should not interfere with an earlier one that succeeded.
*
*/
call_hooks('authenticate', $addon_auth);
if ($addon_auth['authenticated'] && count($addon_auth['user_record']))
if ($addon_auth['authenticated'] && count($addon_auth['user_record'])) {
$record = $addon_auth['user_record'];
else {
// process normal login request
$r = q("SELECT `user`.*, `user`.`pubkey` as `upubkey`, `user`.`prvkey` as `uprvkey`
FROM `user` WHERE (`email` = '%s' OR `nickname` = '%s')
AND `password` = '%s' AND NOT `blocked` AND NOT `account_expired` AND NOT `account_removed` AND `verified` LIMIT 1",
dbesc(trim($_POST['username'])),
dbesc(trim($_POST['username'])),
dbesc($encrypted)
);
if (DBM::is_result($r))
$record = $r[0];
} else {
$user_id = User::authenticate(trim($_POST['username']), trim($_POST['password']));
if ($user_id) {
$record = dba::select('user', [], ['uid' => $user_id], ['limit' => 1]);
}
}
if (!$record || !count($record)) {
logger('authenticate: failed login attempt: '.notags(trim($_POST['username'])).' from IP '.$_SERVER['REMOTE_ADDR']);
notice(t('Login failed.').EOL);
logger('authenticate: failed login attempt: ' . notags(trim($_POST['username'])) . ' from IP ' . $_SERVER['REMOTE_ADDR']);
notice(t('Login failed.') . EOL);
goaway(System::baseUrl());
}
if (! $_POST['remember']) {
if (!$_POST['remember']) {
new_cookie(0); // 0 means delete on browser exit
}
// if we haven't failed up this point, log them in.
$_SESSION['remember'] = $_POST['remember'];
$_SESSION['last_login_date'] = datetime_convert('UTC','UTC');
$_SESSION['last_login_date'] = datetime_convert('UTC', 'UTC');
authenticate_success($record, true, true);
}
}
@ -202,8 +201,8 @@ if (isset($_SESSION) && x($_SESSION,'authenticated') && (!x($_POST,'auth-params'
/**
* @brief Kills the "Friendica" cookie and all session data
*/
function nuke_session() {
function nuke_session()
{
new_cookie(-3600); // make sure cookie is deleted on browser close, as a security measure
session_unset();
session_destroy();

View File

@ -1,314 +0,0 @@
#!/usr/bin/php
<?php
/*
* ejabberd extauth script for the integration with friendica
*
* Originally written for joomla by Dalibor Karlovic <dado@krizevci.info>
* modified for Friendica by Michael Vogel <icarus@dabo.de>
* published under GPL
*
* Latest version of the original script for joomla is available at:
* http://87.230.15.86/~dado/ejabberd/joomla-login
*
* Installation:
*
* - Change it's owner to whichever user is running the server, ie. ejabberd
* $ chown ejabberd:ejabberd /path/to/friendica/include/auth_ejabberd.php
*
* - Change the access mode so it is readable only to the user ejabberd and has exec
* $ chmod 700 /path/to/friendica/include/auth_ejabberd.php
*
* - Edit your ejabberd.cfg file, comment out your auth_method and add:
* {auth_method, external}.
* {extauth_program, "/path/to/friendica/include/auth_ejabberd.php"}.
*
* - Restart your ejabberd service, you should be able to login with your friendica auth info
*
* Other hints:
* - if your users have a space or a @ in their nickname, they'll run into trouble
* registering with any client so they should be instructed to replace these chars
* " " (space) is replaced with "%20"
* "@" is replaced with "(a)"
*
*/
use Friendica\App;
use Friendica\Core\Config;
use Friendica\Database\DBM;
if (sizeof($_SERVER["argv"]) == 0)
die();
$directory = dirname($_SERVER["argv"][0]);
if (substr($directory, 0, 1) != "/")
$directory = $_SERVER["PWD"]."/".$directory;
$directory = realpath($directory."/..");
chdir($directory);
require_once("boot.php");
global $a;
if (empty($a)) {
$a = new App(dirname(__DIR__));
}
@include(".htconfig.php");
require_once("include/dba.php");
dba::connect($db_host, $db_user, $db_pass, $db_data);
unset($db_host, $db_user, $db_pass, $db_data);
$oAuth = new exAuth();
class exAuth {
private $bDebug;
/**
* @brief Create the class and do the authentification studd
*
* @param boolean $bDebug Debug mode
*/
public function __construct() {
// setter
$this->bDebug = (int)Config::get('jabber', 'debug');
openlog('auth_ejabberd', LOG_PID, LOG_USER);
$this->writeLog(LOG_NOTICE, "start");
// We are connected to the SQL server.
while (!feof(STDIN)) {
// Quit if the database connection went down
if (!dba::connected()) {
$this->writeLog(LOG_ERR, "the database connection went down");
return;
}
$iHeader = fgets(STDIN, 3);
$aLength = unpack("n", $iHeader);
$iLength = $aLength["1"];
// No data? Then quit
if ($iLength == 0) {
$this->writeLog(LOG_ERR, "we got no data, quitting");
return;
}
// Fetching the data
$sData = fgets(STDIN, $iLength + 1);
$this->writeLog(LOG_DEBUG, "received data: ". $sData);
$aCommand = explode(":", $sData);
if (is_array($aCommand)) {
switch ($aCommand[0]) {
case "isuser":
// Check the existance of a given username
$this->isuser($aCommand);
break;
case "auth":
// Check if the givven password is correct
$this->auth($aCommand);
break;
case "setpass":
// We don't accept the setting of passwords here
$this->writeLog(LOG_NOTICE, "setpass command disabled");
fwrite(STDOUT, pack("nn", 2, 0));
break;
default:
// We don't know the given command
$this->writeLog(LOG_NOTICE, "unknown command ". $aCommand[0]);
fwrite(STDOUT, pack("nn", 2, 0));
break;
}
} else {
$this->writeLog(LOG_NOTICE, "invalid command string ".$sData);
fwrite(STDOUT, pack("nn", 2, 0));
}
}
}
/**
* @brief Check if the given username exists
*
* @param array $aCommand The command array
*/
private function isuser($aCommand) {
$a = get_app();
// Check if there is a username
if (!isset($aCommand[1])) {
$this->writeLog(LOG_NOTICE, "invalid isuser command, no username given");
fwrite(STDOUT, pack("nn", 2, 0));
return;
}
// Now we check if the given user is valid
$sUser = str_replace(array("%20", "(a)"), array(" ", "@"), $aCommand[1]);
// Does the hostname match? So we try directly
if ($a->get_hostname() == $aCommand[2]) {
$this->writeLog(LOG_INFO, "internal user check for ". $sUser."@".$aCommand[2]);
$sQuery = "SELECT `uid` FROM `user` WHERE `nickname`='".dbesc($sUser)."'";
$this->writeLog(LOG_DEBUG, "using query ". $sQuery);
$r = q($sQuery);
$found = DBM::is_result($r);
} else {
$found = false;
}
// If the hostnames doesn't match or there is some failure, we try to check remotely
if (!$found) {
$found = $this->check_user($aCommand[2], $aCommand[1], true);
}
if ($found) {
// The user is okay
$this->writeLog(LOG_NOTICE, "valid user: ". $sUser);
fwrite(STDOUT, pack("nn", 2, 1));
} else {
// The user isn't okay
$this->writeLog(LOG_WARNING, "invalid user: ". $sUser);
fwrite(STDOUT, pack("nn", 2, 0));
}
}
/**
* @brief Check remote user existance via HTTP(S)
*
* @param string $host The hostname
* @param string $user Username
* @param boolean $ssl Should the check be done via SSL?
*
* @return boolean Was the user found?
*/
private function check_user($host, $user, $ssl) {
$this->writeLog(LOG_INFO, "external user check for ".$user."@".$host);
$url = ($ssl ? "https":"http")."://".$host."/noscrape/".$user;
$data = z_fetch_url($url);
if (!is_array($data))
return(false);
if ($data["return_code"] != "200")
return(false);
$json = @json_decode($data["body"]);
if (!is_object($json))
return(false);
return($json->nick == $user);
}
/**
* @brief Authenticate the givven user and password
*
* @param array $aCommand The command array
*/
private function auth($aCommand) {
$a = get_app();
// check user authentication
if (sizeof($aCommand) != 4) {
$this->writeLog(LOG_NOTICE, "invalid auth command, data missing");
fwrite(STDOUT, pack("nn", 2, 0));
return;
}
// We now check if the password match
$sUser = str_replace(array("%20", "(a)"), array(" ", "@"), $aCommand[1]);
// Does the hostname match? So we try directly
if ($a->get_hostname() == $aCommand[2]) {
$this->writeLog(LOG_INFO, "internal auth for ".$sUser."@".$aCommand[2]);
$sQuery = "SELECT `uid`, `password` FROM `user` WHERE `nickname`='".dbesc($sUser)."'";
$this->writeLog(LOG_DEBUG, "using query ". $sQuery);
if ($oResult = q($sQuery)) {
$uid = $oResult[0]["uid"];
$Error = ($oResult[0]["password"] != hash('whirlpool',$aCommand[3]));
} else {
$this->writeLog(LOG_WARNING, "invalid query: ". $sQuery);
$Error = true;
$uid = -1;
}
if ($Error) {
$oConfig = q("SELECT `v` FROM `pconfig` WHERE `uid` = %d AND `cat` = 'xmpp' AND `k`='password' LIMIT 1;", intval($uid));
$this->writeLog(LOG_INFO, "check against alternate password for ".$sUser."@".$aCommand[2]);
$Error = ($aCommand[3] != $oConfig[0]["v"]);
}
} else {
$Error = true;
}
// If the hostnames doesn't match or there is some failure, we try to check remotely
if ($Error) {
$Error = !$this->check_credentials($aCommand[2], $aCommand[1], $aCommand[3], true);
}
if ($Error) {
$this->writeLog(LOG_WARNING, "authentification failed for user ".$sUser."@". $aCommand[2]);
fwrite(STDOUT, pack("nn", 2, 0));
} else {
$this->writeLog(LOG_NOTICE, "authentificated user ".$sUser."@".$aCommand[2]);
fwrite(STDOUT, pack("nn", 2, 1));
}
}
/**
* @brief Check remote credentials via HTTP(S)
*
* @param string $host The hostname
* @param string $user Username
* @param string $password Password
* @param boolean $ssl Should the check be done via SSL?
*
* @return boolean Are the credentials okay?
*/
private function check_credentials($host, $user, $password, $ssl) {
$url = ($ssl ? "https":"http")."://".$host."/api/account/verify_credentials.json";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, $user.':'.$password);
$header = curl_exec($ch);
$curl_info = @curl_getinfo($ch);
$http_code = $curl_info["http_code"];
curl_close($ch);
$this->writeLog(LOG_INFO, "external auth for ".$user."@".$host." returned ".$http_code);
return ($http_code == 200);
}
/**
* @brief write data to the syslog
*
* @param integer $loglevel The syslog loglevel
* @param string $sMessage The syslog message
*/
private function writeLog($loglevel, $sMessage) {
if (!$this->bDebug && ($loglevel >= LOG_DEBUG)) {
return;
}
syslog($loglevel, $sMessage);
}
/**
* @brief destroy the class, close the syslog connection.
*/
public function __destruct() {
$this->writeLog(LOG_NOTICE, "stop");
closelog();
}
}

View File

@ -3,6 +3,7 @@
use Friendica\App;
use Friendica\Core\System;
use Friendica\Network\Probe;
use Friendica\Object\Contact;
use League\HTMLToMarkdown\HtmlConverter;
@ -23,7 +24,7 @@ function diaspora_mention2bb($match) {
return;
}
$data = get_contact_details_by_addr($match[2]);
$data = Contact::getDetailsByAddr($match[2]);
$name = $match[1];
@ -96,7 +97,7 @@ function diaspora2bb($s) {
*/
function diaspora_mentions($match) {
$contact = get_contact_details_by_url($match[3]);
$contact = Contact::getDetailsByURL($match[3]);
if (!x($contact, 'addr')) {
$contact = Probe::uri($match[3]);

View File

@ -1,17 +1,17 @@
<?php
use Friendica\App;
use Friendica\Content\Smilies;
use Friendica\Core\Cache;
use Friendica\Core\System;
use Friendica\Core\Config;
use Friendica\Object\Contact;
require_once 'include/oembed.php';
require_once 'include/event.php';
require_once 'include/map.php';
require_once 'mod/proxy.php';
require_once 'include/Contact.php';
require_once 'include/plaintext.php';
require_once 'include/Smilies.php';
function bb_PictureCacheExt($matches) {
if (strpos($matches[3], "data:image/") === 0) {
@ -52,7 +52,10 @@ function bb_attachment($Text, $simplehtml = false, $tryoembed = true) {
$data["title"] = str_replace(array("http://", "https://"), "", $data["title"]);
}
if (((strpos($data["text"], "[img=") !== false) || (strpos($data["text"], "[img]") !== false)) && ($data["image"] != "")) {
if (((strpos($data["text"], "[img=") !== false)
|| (strpos($data["text"], "[img]") !== false)
|| Config::get('system', 'always_show_preview'))
&& ($data["image"] != "")) {
$data["preview"] = $data["image"];
$data["image"] = "";
}
@ -492,9 +495,9 @@ function bb_ShareAttributes($share, $simplehtml) {
// We only call this so that a previously unknown contact can be added.
// This is important for the function "get_contact_details_by_url".
// This function then can fetch an entry from the contact table.
get_contact($profile, 0);
Contact::getIdForURL($profile, 0);
$data = get_contact_details_by_url($profile);
$data = Contact::getDetailsByURL($profile);
if (isset($data["name"]) && ($data["name"] != "") && isset($data["addr"]) && ($data["addr"] != ""))
$userid_compact = $data["name"]." (".$data["addr"].")";

View File

@ -1,46 +0,0 @@
<?php
/**
* @file include/checkversion.php
*
* @brief save Friendica upstream version to the DB
**/
use Friendica\Core\Config;
/**
* @brief check the git repository VERSION file and save the version to the DB
*
* Checking the upstream version is optional (opt-in) and can be done to either
* the master or the develop branch in the repository.
*/
function checkversion_run () {
global $a;
logger('checkversion: start');
$checkurl = Config::get('system', 'check_new_version_url', 'none');
switch ($checkurl) {
case 'master':
$checked_url = 'https://raw.githubusercontent.com/friendica/friendica/master/VERSION';
break;
case 'develop':
$checked_url = 'https://raw.githubusercontent.com/friendica/friendica/develop/VERSION';
break;
default:
// don't check
return;
}
logger("Checking VERSION from: ".$checked_url, LOGGER_DEBUG);
// fetch the VERSION file
$gitversion = dbesc(trim(fetch_url($checked_url)));
logger("Upstream VERSION is: ".$gitversion, LOGGER_DEBUG);
Config::set('system', 'git_friendica_version', $gitversion);
logger('checkversion: end');
return;
}

View File

@ -1,29 +0,0 @@
<?php /** @file */
use Friendica\App;
use Friendica\Core\Config;
require_once('boot.php');
// Everything we need to boot standalone 'background' processes
function cli_startup() {
global $a;
if (empty($a)) {
$a = new App(dirname(__DIR__));
}
@include(".htconfig.php");
require_once("dba.php");
dba::connect($db_host, $db_user, $db_pass, $db_data);
unset($db_host, $db_user, $db_pass, $db_data);
require_once('include/session.php');
Config::load();
$a->set_baseurl(Config::get('system','url'));
load_hooks();
}

View File

@ -1,10 +1,10 @@
<?php
use Friendica\App;
use Friendica\Core\System;
use Friendica\Core\Config;
use Friendica\Core\PConfig;
use Friendica\Database\DBM;
use Friendica\Model\GlobalContact;
require_once 'include/contact_selectors.php';
@ -21,8 +21,6 @@ function follow_widget($value = "") {
}
function findpeople_widget() {
require_once 'include/Contact.php';
$a = get_app();
$global_dir = Config::get('system', 'directory');
@ -248,31 +246,28 @@ function common_friends_visitor_widget($profile_uid) {
return;
}
require_once 'include/socgraph.php';
if ($cid) {
$t = count_common_friends($profile_uid, $cid);
$t = GlobalContact::countCommonFriends($profile_uid, $cid);
} else {
$t = count_common_friends_zcid($profile_uid, $zcid);
$t = GlobalContact::countCommonFriendsZcid($profile_uid, $zcid);
}
if (! $t) {
return;
}
if ($cid) {
$r = common_friends($profile_uid, $cid, 0, 5, true);
$r = GlobalContact::commonFriends($profile_uid, $cid, 0, 5, true);
} else {
$r = common_friends_zcid($profile_uid, $zcid, 0, 5, true);
$r = GlobalContact::commonFriendsZcid($profile_uid, $zcid, 0, 5, true);
}
return replace_macros(get_markup_template('remote_friends_common.tpl'), array(
'$desc' => sprintf( tt("%d contact in common", "%d contacts in common", $t), $t),
'$desc' => sprintf(tt("%d contact in common", "%d contacts in common", $t), $t),
'$base' => System::baseUrl(),
'$uid' => $profile_uid,
'$cid' => (($cid) ? $cid : '0'),
'$linkmore' => (($t > 5) ? 'true' : ''),
'$more' => t('show more'),
'$items' => $r
));
};
'$items' => $r)
);
}

View File

@ -1,10 +1,15 @@
<?php
/**
* @file include/conversation.php
*/
use Friendica\App;
use Friendica\Core\Config;
use Friendica\Core\PConfig;
use Friendica\Core\System;
use Friendica\Database\DBM;
use Friendica\Object\Contact;
use Friendica\Object\Conversation;
use Friendica\Object\Item;
require_once "include/bbcode.php";
require_once "include/acl_selectors.php";
@ -508,7 +513,6 @@ if (!function_exists('conversation')) {
function conversation(App $a, $items, $mode, $update, $preview = false) {
require_once 'include/bbcode.php';
require_once 'include/Contact.php';
require_once 'mod/proxy.php';
$ssl_state = ((local_user()) ? true : false);
@ -729,7 +733,7 @@ function conversation(App $a, $items, $mode, $update, $preview = false) {
}
if (!x($item, 'author-thumb') || ($item['author-thumb'] == "")) {
$author_contact = get_contact_details_by_url($item['author-link'], $profile_owner);
$author_contact = Contact::getDetailsByURL($item['author-link'], $profile_owner);
if ($author_contact["thumb"]) {
$item['author-thumb'] = $author_contact["thumb"];
} else {
@ -738,7 +742,7 @@ function conversation(App $a, $items, $mode, $update, $preview = false) {
}
if (!isset($item['owner-thumb']) || ($item['owner-thumb'] == "")) {
$owner_contact = get_contact_details_by_url($item['owner-link'], $profile_owner);
$owner_contact = Contact::getDetailsByURL($item['owner-link'], $profile_owner);
if ($owner_contact["thumb"]) {
$item['owner-thumb'] = $owner_contact["thumb"];
} else {
@ -776,25 +780,14 @@ function conversation(App $a, $items, $mode, $update, $preview = false) {
list($categories, $folders) = get_cats_and_terms($item);
if ($a->theme['template_engine'] === 'internal') {
$profile_name_e = template_escape($profile_name);
$item['title_e'] = template_escape($item['title']);
$body_e = template_escape($body);
$tags_e = template_escape($tags);
$hashtags_e = template_escape($hashtags);
$mentions_e = template_escape($mentions);
$location_e = template_escape($location);
$owner_name_e = template_escape($owner_name);
} else {
$profile_name_e = $profile_name;
$item['title_e'] = $item['title'];
$body_e = $body;
$tags_e = $tags;
$hashtags_e = $hashtags;
$mentions_e = $mentions;
$location_e = $location;
$owner_name_e = $owner_name;
}
$profile_name_e = $profile_name;
$item['title_e'] = $item['title'];
$body_e = $body;
$tags_e = $tags;
$hashtags_e = $hashtags;
$mentions_e = $mentions;
$location_e = $location;
$owner_name_e = $owner_name;
if ($item['item_network'] == "") {
$item['item_network'] = $item['network'];
@ -860,9 +853,6 @@ function conversation(App $a, $items, $mode, $update, $preview = false) {
// Normal View
$page_template = get_markup_template("threaded_conversation.tpl");
require_once 'object/Conversation.php';
require_once 'object/Item.php';
$conv = new Conversation($mode, $preview);
/*
@ -904,11 +894,11 @@ function conversation(App $a, $items, $mode, $update, $preview = false) {
if ($item['id'] == $item['parent']) {
$item_object = new Item($item);
$conv->add_thread($item_object);
$conv->addThread($item_object);
}
}
$threads = $conv->get_template_data($conv_responses);
$threads = $conv->getTemplateData($conv_responses);
if (!$threads) {
logger('[ERROR] conversation : Failed to get template data.', LOGGER_DEBUG);
@ -1360,13 +1350,22 @@ function status_editor(App $a, $x, $notes_cid = 0, $popup = false) {
return $o;
}
function get_item_children($arr, $parent) {
$children = array();
$a = get_app();
foreach ($arr as $item) {
/**
* Plucks the children of the given parent from a given item list.
*
* @brief Plucks all the children in the given item list of the given parent
*
* @param array $item_list
* @param array $parent
* @param bool $recursive
* @return type
*/
function get_item_children(array &$item_list, array $parent, $recursive = true)
{
$children = [];
foreach ($item_list as $i => $item) {
if ($item['id'] != $item['parent']) {
if (Config::get('system', 'thread_allow') && $a->theme_thread_allow) {
if ($recursive) {
// Fallback to parent-uri if thr-parent is not set
$thr_parent = $item['thr-parent'];
if ($thr_parent == '') {
@ -1374,65 +1373,141 @@ function get_item_children($arr, $parent) {
}
if ($thr_parent == $parent['uri']) {
$item['children'] = get_item_children($arr, $item);
$item['children'] = get_item_children($item_list, $item);
$children[] = $item;
unset($item_list[$i]);
}
} elseif ($item['parent'] == $parent['id']) {
$children[] = $item;
unset($item_list[$i]);
}
}
}
return $children;
}
/// @TODO Add type-hint
function sort_item_children($items) {
/**
* @brief Recursively sorts a tree-like item array
*
* @param array $items
* @return array
*/
function sort_item_children(array $items)
{
$result = $items;
usort($result, 'sort_thr_created_rev');
foreach ($result as $k => $i) {
if (count($result[$k]['children'])) {
if (isset($result[$k]['children'])) {
$result[$k]['children'] = sort_item_children($result[$k]['children']);
}
}
return $result;
}
/// @TODO Add type-hint
function add_children_to_list($children, &$arr) {
foreach ($children as $y) {
$arr[] = $y;
if (count($y['children'])) {
add_children_to_list($y['children'], $arr);
/**
* @brief Recursively add all children items at the top level of a list
*
* @param array $children List of items to append
* @param array $item_list
*/
function add_children_to_list(array $children, array &$item_list)
{
foreach ($children as $child) {
$item_list[] = $child;
if (isset($child['children'])) {
add_children_to_list($child['children'], $item_list);
}
}
}
/// @TODO Add type-hint
function conv_sort($arr, $order) {
if ((!(is_array($arr) && count($arr)))) {
return array();
/**
* This recursive function takes the item tree structure created by conv_sort() and
* flatten the extraneous depth levels when people reply sequentially, removing the
* stairs effect in threaded conversations limiting the available content width.
*
* The basic principle is the following: if a post item has only one reply and is
* the last reply of its parent, then the reply is moved to the parent.
*
* This process is rendered somewhat more complicated because items can be either
* replies or likes, and these don't factor at all in the reply count/last reply.
*
* @brief Selectively flattens a tree-like item structure to prevent threading stairs
*
* @param array $parent A tree-like array of items
* @return array
*/
function smart_flatten_conversation(array $parent)
{
if (! isset($parent['children']) || count($parent['children']) == 0) {
return $parent;
}
$parents = array();
$children = array();
$newarr = array();
// We use a for loop to ensure we process the newly-moved items
for ($i = 0; $i < count($parent['children']); $i++) {
$child = $parent['children'][$i];
/*
* This is a preparation for having two different items with the same uri in one thread
* This will otherwise lead to an endless loop.
*/
foreach ($arr as $x) {
if (!isset($newarr[$x['uri']])) {
$newarr[$x['uri']] = $x;
if (isset($child['children']) && count($child['children'])) {
// This helps counting only the regular posts
$count_post_closure = function($var) {
return $var['verb'] === ACTIVITY_POST;
};
$child_post_count = count(array_filter($child['children'], $count_post_closure));
$remaining_post_count = count(array_filter(array_slice($parent['children'], $i), $count_post_closure));
// If there's only one child's children post and this is the last child post
if ($child_post_count == 1 && $remaining_post_count == 1) {
// Searches the post item in the children
$j = 0;
while($child['children'][$j]['verb'] !== ACTIVITY_POST && $j < count($child['children'])) {
$j ++;
}
$moved_item = $child['children'][$j];
unset($parent['children'][$i]['children'][$j]);
$parent['children'][] = $moved_item;
} else {
$parent['children'][$i] = smart_flatten_conversation($child);
}
}
}
$arr = $newarr;
return $parent;
}
foreach ($arr as $x) {
if ($x['id'] == $x['parent']) {
$parents[] = $x;
/**
* Expands a flat list of items into corresponding tree-like conversation structures,
* sort the top-level posts either on "created" or "commented", and finally
* append all the items at the top level (???)
*
* @brief Expands a flat item list into a conversation array for display
*
* @param array $item_list A list of items belonging to one or more conversations
* @param string $order Either on "created" or "commented"
* @return array
*/
function conv_sort(array $item_list, $order)
{
$parents = [];
if (!(is_array($item_list) && count($item_list))) {
return $parents;
}
$item_array = [];
// Dedupes the item list on the uri to prevent infinite loops
foreach ($item_list as $item) {
$item_array[$item['uri']] = $item;
}
// Extract the top level items
foreach ($item_array as $item) {
if ($item['id'] == $item['parent']) {
$parents[] = $item;
}
}
@ -1442,73 +1517,73 @@ function conv_sort($arr, $order) {
usort($parents, 'sort_thr_commented');
}
if (count($parents)) {
foreach ($parents as $i => $_x) {
$parents[$i]['children'] = get_item_children($arr, $_x);
/*
* Plucks children from the item_array, second pass collects eventual orphan
* items and add them as children of their top-level post.
*/
foreach ($parents as $i => $parent) {
$parents[$i]['children'] =
array_merge(get_item_children($item_array, $parent, true),
get_item_children($item_array, $parent, false));
}
foreach ($parents as $i => $parent) {
$parents[$i]['children'] = sort_item_children($parents[$i]['children']);
}
if (PConfig::get(local_user(), 'system', 'smart_threading', 0)) {
foreach ($parents as $i => $parent) {
$parents[$i] = smart_flatten_conversation($parent);
}
}
/// @TODO Old-lost code?
/*foreach ($arr as $x) {
if ($x['id'] != $x['parent']) {
$p = find_thread_parent_index($parents,$x);
if ($p !== false)
$parents[$p]['children'][] = $x;
}
}*/
if (count($parents)) {
foreach ($parents as $k => $v) {
if (count($parents[$k]['children'])) {
$parents[$k]['children'] = sort_item_children($parents[$k]['children']);
/// @TODO Old-lost code?
/*$y = $parents[$k]['children'];
usort($y,'sort_thr_created_rev');
$parents[$k]['children'] = $y;*/
}
/// @TODO: Stop recusrsively adding all children back to the top level (!!!)
/// However, this apparently ensures responses (likes, attendance) display (?!)
foreach ($parents as $parent) {
if (count($parent['children'])) {
add_children_to_list($parent['children'], $parents);
}
}
$ret = array();
if (count($parents)) {
foreach ($parents as $x) {
$ret[] = $x;
if (count($x['children'])) {
add_children_to_list($x['children'], $ret);
/// @TODO Old-lost code?
/*foreach ($x['children'] as $y)
$ret[] = $y;*/
}
}
}
return $ret;
return $parents;
}
/// @TODO Add type-hint
function sort_thr_created($a, $b) {
/**
* @brief usort() callback to sort item arrays by the created key
*
* @param array $a
* @param array $b
* @return int
*/
function sort_thr_created(array $a, array $b)
{
return strcmp($b['created'], $a['created']);
}
/// @TODO Add type-hint
function sort_thr_created_rev($a, $b) {
/**
* @brief usort() callback to reverse sort item arrays by the created key
*
* @param array $a
* @param array $b
* @return int
*/
function sort_thr_created_rev(array $a, array $b)
{
return strcmp($a['created'], $b['created']);
}
/// @TODO Add type-hint
function sort_thr_commented($a, $b) {
/**
* @brief usort() callback to sort item arrays by the commented key
*
* @param array $a
* @param array $b
* @return type
*/
function sort_thr_commented(array $a, array $b)
{
return strcmp($b['commented'], $a['commented']);
}
/// @TODO Add type-hint
function find_thread_parent_index($arr, $x) {
foreach ($arr as $k => $v) {
if ($v['id'] == $x['parent']) {
return $k;
}
}
return false;
}
/// @TODO Add type-hint
function render_location_dummy($item) {
if ($item['location'] != "") {
@ -1531,7 +1606,7 @@ function get_responses($conv_responses, $response_verbs, $ob, $item) {
if (count($ret[$v]['list']) > MAX_LIKERS) {
$ret[$v]['list_part'] = array_slice($ret[$v]['list'], 0, MAX_LIKERS);
array_push($ret[$v]['list_part'], '<a href="#" data-toggle="modal" data-target="#' . $v . 'Modal-'
. (($ob) ? $ob->get_id() : $item['id']) . '"><b>' . t('View all') . '</b></a>');
. (($ob) ? $ob->getId() : $item['id']) . '"><b>' . t('View all') . '</b></a>');
} else {
$ret[$v]['list_part'] = '';
}

View File

@ -1,19 +0,0 @@
<?php
/**
* @file include/create_shadowentry.php
* @brief This script creates posts with UID = 0 for a given public post.
*
* This script is started from mod/item.php to save some time when doing a post.
*/
require_once("include/threads.php");
function create_shadowentry_run($argv, $argc) {
if ($argc != 2) {
return;
}
$message_id = intval($argv[1]);
add_shadow_entry($message_id);
}

View File

@ -1,258 +0,0 @@
<?php
use Friendica\Core\Config;
use Friendica\Core\Worker;
use Friendica\Database\DBM;
function cron_run(&$argv, &$argc){
global $a;
require_once 'include/datetime.php';
// Poll contacts with specific parameters
if ($argc > 1) {
cron_poll_contacts($argc, $argv);
return;
}
$last = Config::get('system', 'last_cron');
$poll_interval = intval(Config::get('system', 'cron_interval'));
if (! $poll_interval) {
$poll_interval = 10;
}
if ($last) {
$next = $last + ($poll_interval * 60);
if ($next > time()) {
logger('cron intervall not reached');
return;
}
}
logger('cron: start');
// run queue delivery process in the background
Worker::add(PRIORITY_NEGLIGIBLE, "queue");
// run the process to discover global contacts in the background
Worker::add(PRIORITY_LOW, "discover_poco");
// run the process to update locally stored global contacts in the background
Worker::add(PRIORITY_LOW, "discover_poco", "checkcontact");
// Expire and remove user entries
Worker::add(PRIORITY_MEDIUM, "cronjobs", "expire_and_remove_users");
// Call possible post update functions
Worker::add(PRIORITY_LOW, "cronjobs", "post_update");
// update nodeinfo data
Worker::add(PRIORITY_LOW, "cronjobs", "nodeinfo");
// Clear cache entries
Worker::add(PRIORITY_LOW, "cronjobs", "clear_cache");
// Repair missing Diaspora values in contacts
Worker::add(PRIORITY_LOW, "cronjobs", "repair_diaspora");
// Repair entries in the database
Worker::add(PRIORITY_LOW, "cronjobs", "repair_database");
// once daily run birthday_updates and then expire in background
$d1 = Config::get('system', 'last_expire_day');
$d2 = intval(datetime_convert('UTC', 'UTC', 'now', 'd'));
if ($d2 != intval($d1)) {
Worker::add(PRIORITY_LOW, "cronjobs", "update_contact_birthdays");
Worker::add(PRIORITY_LOW, "discover_poco", "update_server");
Worker::add(PRIORITY_LOW, "discover_poco", "suggestions");
Config::set('system', 'last_expire_day', $d2);
Worker::add(PRIORITY_LOW, 'expire');
Worker::add(PRIORITY_MEDIUM, 'dbclean');
Worker::add(PRIORITY_LOW, "cronjobs", "update_photo_albums");
// Delete all done workerqueue entries
dba::delete('workerqueue', array('`done` AND `executed` < UTC_TIMESTAMP() - INTERVAL 12 HOUR'));
// check upstream version?
Worker::add(PRIORITY_LOW, 'checkversion');
}
// Poll contacts
cron_poll_contacts($argc, $argv);
logger('cron: end');
Config::set('system', 'last_cron', time());
return;
}
/**
* @brief Poll contacts for unreceived messages
*
* @param Integer $argc Number of command line arguments
* @param Array $argv Array of command line arguments
*/
function cron_poll_contacts($argc, $argv) {
$manual_id = 0;
$generation = 0;
$force = false;
$restart = false;
if (($argc > 1) && ($argv[1] == 'force')) {
$force = true;
}
if (($argc > 1) && ($argv[1] == 'restart')) {
$restart = true;
$generation = intval($argv[2]);
if (!$generation) {
killme();
}
}
if (($argc > 1) && intval($argv[1])) {
$manual_id = intval($argv[1]);
$force = true;
}
$min_poll_interval = Config::get('system', 'min_poll_interval', 1);
$sql_extra = (($manual_id) ? " AND `id` = $manual_id " : "");
reload_plugins();
$d = datetime_convert();
// Only poll from those with suitable relationships,
// and which have a polling address and ignore Diaspora since
// we are unable to match those posts with a Diaspora GUID and prevent duplicates.
$abandon_days = intval(Config::get('system', 'account_abandon_days'));
if ($abandon_days < 1) {
$abandon_days = 0;
}
$abandon_sql = (($abandon_days)
? sprintf(" AND `user`.`login_date` > UTC_TIMESTAMP() - INTERVAL %d DAY ", intval($abandon_days))
: ''
);
$contacts = q("SELECT `contact`.`id` FROM `user`
STRAIGHT_JOIN `contact`
ON `contact`.`uid` = `user`.`uid` AND `contact`.`rel` IN (%d, %d) AND `contact`.`poll` != ''
AND `contact`.`network` IN ('%s', '%s', '%s', '%s', '%s', '%s') $sql_extra
AND NOT `contact`.`self` AND NOT `contact`.`blocked` AND NOT `contact`.`readonly`
AND NOT `contact`.`archive`
WHERE NOT `user`.`account_expired` AND NOT `user`.`account_removed` $abandon_sql ORDER BY RAND()",
intval(CONTACT_IS_SHARING),
intval(CONTACT_IS_FRIEND),
dbesc(NETWORK_DFRN),
dbesc(NETWORK_ZOT),
dbesc(NETWORK_OSTATUS),
dbesc(NETWORK_FEED),
dbesc(NETWORK_MAIL),
dbesc(NETWORK_MAIL2)
);
if (!DBM::is_result($contacts)) {
return;
}
foreach ($contacts as $c) {
$res = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1",
intval($c['id'])
);
if (!DBM::is_result($res)) {
continue;
}
foreach ($res as $contact) {
$xml = false;
if ($manual_id) {
$contact['last-update'] = NULL_DATE;
}
if (in_array($contact['network'], array(NETWORK_DFRN, NETWORK_ZOT, NETWORK_OSTATUS))) {
$contact['priority'] = 2;
}
if ($contact['subhub'] && in_array($contact['network'], array(NETWORK_DFRN, NETWORK_ZOT, NETWORK_OSTATUS))) {
/*
* We should be getting everything via a hub. But just to be sure, let's check once a day.
* (You can make this more or less frequent if desired by setting 'pushpoll_frequency' appropriately)
* This also lets us update our subscription to the hub, and add or replace hubs in case it
* changed. We will only update hubs once a day, regardless of 'pushpoll_frequency'.
*/
$poll_interval = Config::get('system', 'pushpoll_frequency');
$contact['priority'] = (($poll_interval !== false) ? intval($poll_interval) : 3);
}
if (($contact['priority'] >= 0) && !$force) {
$update = false;
$t = $contact['last-update'];
/*
* Based on $contact['priority'], should we poll this site now? Or later?
*/
switch ($contact['priority']) {
case 5:
if (datetime_convert('UTC', 'UTC', 'now') > datetime_convert('UTC', 'UTC', $t . " + 1 month")) {
$update = true;
}
break;
case 4:
if (datetime_convert('UTC', 'UTC', 'now') > datetime_convert('UTC', 'UTC', $t . " + 1 week")) {
$update = true;
}
break;
case 3:
if (datetime_convert('UTC', 'UTC', 'now') > datetime_convert('UTC', 'UTC', $t . " + 1 day")) {
$update = true;
}
break;
case 2:
if (datetime_convert('UTC', 'UTC', 'now') > datetime_convert('UTC', 'UTC', $t . " + 12 hour")) {
$update = true;
}
break;
case 1:
if (datetime_convert('UTC', 'UTC', 'now') > datetime_convert('UTC', 'UTC', $t . " + 1 hour")) {
$update = true;
}
break;
case 0:
default:
if (datetime_convert('UTC', 'UTC', 'now') > datetime_convert('UTC', 'UTC', $t . " + ".$min_poll_interval." minute")) {
$update = true;
}
break;
}
if (!$update) {
continue;
}
}
logger("Polling " . $contact["network"] . " " . $contact["id"] . " " . $contact["nick"] . " " . $contact["name"]);
if (($contact['network'] == NETWORK_FEED) && ($contact['priority'] <= 3)) {
$priority = PRIORITY_MEDIUM;
} else {
$priority = PRIORITY_LOW;
}
Worker::add(array('priority' => $priority, 'dont_fork' => true), 'onepoll', (int)$contact['id']);
}
}
}

View File

@ -1,54 +0,0 @@
<?php
use Friendica\Core\Config;
use Friendica\Core\Worker;
function cronhooks_run(&$argv, &$argc) {
global $a;
require_once 'include/datetime.php';
if (($argc == 2) && is_array($a->hooks) && array_key_exists("cron", $a->hooks)) {
foreach ($a->hooks["cron"] as $hook) {
if ($hook[1] == $argv[1]) {
logger("Calling cron hook '" . $hook[1] . "'", LOGGER_DEBUG);
call_single_hook($a, $name, $hook, $data);
}
}
return;
}
$last = Config::get('system', 'last_cronhook');
$poll_interval = intval(Config::get('system', 'cronhook_interval'));
if (! $poll_interval) {
$poll_interval = 9;
}
if ($last) {
$next = $last + ($poll_interval * 60);
if ($next > time()) {
logger('cronhook intervall not reached');
return;
}
}
$a->set_baseurl(Config::get('system', 'url'));
logger('cronhooks: start');
$d = datetime_convert();
if (is_array($a->hooks) && array_key_exists("cron", $a->hooks)) {
foreach ($a->hooks["cron"] as $hook) {
logger("Calling cronhooks for '" . $hook[1] . "'", LOGGER_DEBUG);
Worker::add(PRIORITY_MEDIUM, "cronhooks", $hook[1]);
}
}
logger('cronhooks: end');
Config::set('system', 'last_cronhook', time());
return;
}

View File

@ -1,278 +0,0 @@
<?php
use Friendica\App;
use Friendica\Core\Cache;
use Friendica\Core\Config;
use Friendica\Database\DBM;
use Friendica\Network\Probe;
function cronjobs_run(&$argv, &$argc){
global $a;
require_once 'include/datetime.php';
require_once 'include/post_update.php';
require_once 'mod/nodeinfo.php';
require_once 'include/photos.php';
require_once 'include/user.php';
require_once 'include/socgraph.php';
// No parameter set? So return
if ($argc <= 1) {
return;
}
logger("Starting cronjob ".$argv[1], LOGGER_DEBUG);
// Call possible post update functions
// see include/post_update.php for more details
if ($argv[1] == 'post_update') {
post_update();
return;
}
// update nodeinfo data
if ($argv[1] == 'nodeinfo') {
nodeinfo_cron();
return;
}
// Expire and remove user entries
if ($argv[1] == 'expire_and_remove_users') {
cron_expire_and_remove_users();
return;
}
if ($argv[1] == 'update_contact_birthdays') {
update_contact_birthdays();
return;
}
if ($argv[1] == 'update_photo_albums') {
cron_update_photo_albums();
return;
}
// Clear cache entries
if ($argv[1] == 'clear_cache') {
cron_clear_cache($a);
return;
}
// Repair missing Diaspora values in contacts
if ($argv[1] == 'repair_diaspora') {
cron_repair_diaspora($a);
return;
}
// Repair entries in the database
if ($argv[1] == 'repair_database') {
cron_repair_database();
return;
}
logger("Xronjob ".$argv[1]." is unknown.", LOGGER_DEBUG);
return;
}
/**
* @brief Update the cached values for the number of photo albums per user
*/
function cron_update_photo_albums() {
$r = q("SELECT `uid` FROM `user` WHERE NOT `account_expired` AND NOT `account_removed`");
if (!DBM::is_result($r)) {
return;
}
foreach ($r AS $user) {
photo_albums($user['uid'], true);
}
}
/**
* @brief Expire and remove user entries
*/
function cron_expire_and_remove_users() {
// expire any expired accounts
q("UPDATE user SET `account_expired` = 1 where `account_expired` = 0
AND `account_expires_on` > '%s'
AND `account_expires_on` < UTC_TIMESTAMP()", dbesc(NULL_DATE));
// delete user records for recently removed accounts
$r = q("SELECT * FROM `user` WHERE `account_removed` AND `account_expires_on` < UTC_TIMESTAMP() - INTERVAL 3 DAY");
if (DBM::is_result($r)) {
foreach ($r as $user) {
dba::delete('user', array('uid' => $user['uid']));
}
}
}
/**
* @brief Clear cache entries
*
* @param App $a
*/
function cron_clear_cache(App $a) {
$last = Config::get('system','cache_last_cleared');
if ($last) {
$next = $last + (3600); // Once per hour
$clear_cache = ($next <= time());
} else {
$clear_cache = true;
}
if (!$clear_cache) {
return;
}
// clear old cache
Cache::clear();
// clear old item cache files
clear_cache();
// clear cache for photos
clear_cache($a->get_basepath(), $a->get_basepath()."/photo");
// clear smarty cache
clear_cache($a->get_basepath()."/view/smarty3/compiled", $a->get_basepath()."/view/smarty3/compiled");
// clear cache for image proxy
if (!Config::get("system", "proxy_disabled")) {
clear_cache($a->get_basepath(), $a->get_basepath()."/proxy");
$cachetime = Config::get('system','proxy_cache_time');
if (!$cachetime) {
$cachetime = PROXY_DEFAULT_TIME;
}
q('DELETE FROM `photo` WHERE `uid` = 0 AND `resource-id` LIKE "pic:%%" AND `created` < NOW() - INTERVAL %d SECOND', $cachetime);
}
// Delete the cached OEmbed entries that are older than one year
q("DELETE FROM `oembed` WHERE `created` < NOW() - INTERVAL 3 MONTH");
// Delete the cached "parse_url" entries that are older than one year
q("DELETE FROM `parsed_url` WHERE `created` < NOW() - INTERVAL 3 MONTH");
// Maximum table size in megabyte
$max_tablesize = intval(Config::get('system','optimize_max_tablesize')) * 1000000;
if ($max_tablesize == 0) {
$max_tablesize = 100 * 1000000; // Default are 100 MB
}
if ($max_tablesize > 0) {
// Minimum fragmentation level in percent
$fragmentation_level = intval(Config::get('system','optimize_fragmentation')) / 100;
if ($fragmentation_level == 0) {
$fragmentation_level = 0.3; // Default value is 30%
}
// Optimize some tables that need to be optimized
$r = q("SHOW TABLE STATUS");
foreach ($r as $table) {
// Don't optimize tables that are too large
if ($table["Data_length"] > $max_tablesize) {
continue;
}
// Don't optimize empty tables
if ($table["Data_length"] == 0) {
continue;
}
// Calculate fragmentation
$fragmentation = $table["Data_free"] / ($table["Data_length"] + $table["Index_length"]);
logger("Table ".$table["Name"]." - Fragmentation level: ".round($fragmentation * 100, 2), LOGGER_DEBUG);
// Don't optimize tables that needn't to be optimized
if ($fragmentation < $fragmentation_level) {
continue;
}
// So optimize it
logger("Optimize Table ".$table["Name"], LOGGER_DEBUG);
q("OPTIMIZE TABLE `%s`", dbesc($table["Name"]));
}
}
Config::set('system','cache_last_cleared', time());
}
/**
* @brief Repair missing values in Diaspora contacts
*
* @param App $a
*/
function cron_repair_diaspora(App $a) {
$starttime = time();
$r = q("SELECT `id`, `url` FROM `contact`
WHERE `network` = '%s' AND (`batch` = '' OR `notify` = '' OR `poll` = '' OR pubkey = '')
ORDER BY RAND() LIMIT 50", dbesc(NETWORK_DIASPORA));
if (!DBM::is_result($r)) {
return;
}
foreach ($r AS $contact) {
// Quit the loop after 3 minutes
if (time() > ($starttime + 180)) {
return;
}
if (!poco_reachable($contact["url"])) {
continue;
}
$data = Probe::uri($contact["url"]);
if ($data["network"] != NETWORK_DIASPORA) {
continue;
}
logger("Repair contact ".$contact["id"]." ".$contact["url"], LOGGER_DEBUG);
q("UPDATE `contact` SET `batch` = '%s', `notify` = '%s', `poll` = '%s', pubkey = '%s' WHERE `id` = %d",
dbesc($data["batch"]), dbesc($data["notify"]), dbesc($data["poll"]), dbesc($data["pubkey"]),
intval($contact["id"]));
}
}
/**
* @brief Do some repairs in database entries
*
*/
function cron_repair_database() {
// Sometimes there seem to be issues where the "self" contact vanishes.
// We haven't found the origin of the problem by now.
$r = q("SELECT `uid` FROM `user` WHERE NOT EXISTS (SELECT `uid` FROM `contact` WHERE `contact`.`uid` = `user`.`uid` AND `contact`.`self`)");
if (DBM::is_result($r)) {
foreach ($r AS $user) {
logger('Create missing self contact for user '.$user['uid']);
user_create_self_contact($user['uid']);
}
}
// Set the parent if it wasn't set. (Shouldn't happen - but does sometimes)
// This call is very "cheap" so we can do it at any time without a problem
q("UPDATE `item` INNER JOIN `item` AS `parent` ON `parent`.`uri` = `item`.`parent-uri` AND `parent`.`uid` = `item`.`uid` SET `item`.`parent` = `parent`.`id` WHERE `item`.`parent` = 0");
// There was an issue where the nick vanishes from the contact table
q("UPDATE `contact` INNER JOIN `user` ON `contact`.`uid` = `user`.`uid` SET `nick` = `nickname` WHERE `self` AND `nick`=''");
// Update the global contacts for local users
$r = q("SELECT `uid` FROM `user` WHERE `verified` AND NOT `blocked` AND NOT `account_removed` AND NOT `account_expired`");
if (DBM::is_result($r)) {
foreach ($r AS $user) {
update_gcontact_for_user($user["uid"]);
}
}
/// @todo
/// - remove thread entries without item
/// - remove sign entries without item
/// - remove children when parent got lost
/// - set contact-id in item when not present
}

View File

@ -93,18 +93,6 @@ class dba {
}
}
if (!self::$connected && function_exists('mysql_connect')) {
self::$driver = 'mysql';
self::$db = mysql_connect($serveraddr, $user, $pass);
if (self::$db && mysql_select_db($db, self::$db)) {
self::$connected = true;
if (isset($a->config["system"]["db_charset"])) {
mysql_set_charset($a->config["system"]["db_charset"], self::$db);
}
}
}
// No suitable SQL driver was found.
if (!self::$connected) {
self::$db = null;
@ -134,9 +122,6 @@ class dba {
case 'mysqli':
self::$_server_info = self::$db->server_info;
break;
case 'mysql':
self::$_server_info = mysql_get_server_info(self::$db);
break;
}
}
return self::$_server_info;
@ -216,8 +201,6 @@ class dba {
return substr(@self::$db->quote($str, PDO::PARAM_STR), 1, -1);
case 'mysqli':
return @self::$db->real_escape_string($str);
case 'mysql':
return @mysql_real_escape_string($str,self::$db);
}
}
@ -235,9 +218,6 @@ class dba {
case 'mysqli':
$connected = self::$db->ping();
break;
case 'mysql':
$connected = mysql_ping(self::$db);
break;
}
return $connected;
}
@ -485,22 +465,6 @@ class dba {
self::$affected_rows = $retval->affected_rows;
}
break;
case 'mysql':
// For the old "mysql" functions we cannot use prepared statements
$retval = mysql_query(self::replace_parameters($sql, $args), self::$db);
if (mysql_errno(self::$db)) {
self::$error = mysql_error(self::$db);
self::$errorno = mysql_errno(self::$db);
} else {
self::$affected_rows = mysql_affected_rows($retval);
// Due to missing mysql_* support this here wasn't tested at all
// See here: http://php.net/manual/en/function.mysql-num-rows.php
if (self::$affected_rows <= 0) {
self::$affected_rows = mysql_num_rows($retval);
}
}
break;
}
// We are having an own error logging in the function "e"
@ -668,8 +632,6 @@ class dba {
return $stmt->columnCount();
case 'mysqli':
return $stmt->field_count;
case 'mysql':
return mysql_affected_rows($stmt);
}
return 0;
}
@ -688,8 +650,6 @@ class dba {
return $stmt->rowCount();
case 'mysqli':
return $stmt->num_rows;
case 'mysql':
return mysql_num_rows($stmt);
}
return 0;
}
@ -740,8 +700,6 @@ class dba {
$columns[$fields[$param]->name] = $col;
}
return $columns;
case 'mysql':
return mysql_fetch_array($stmt, MYSQL_ASSOC);
}
}
@ -755,6 +713,12 @@ class dba {
* @return boolean was the insert successfull?
*/
public static function insert($table, $param, $on_duplicate_update = false) {
if (empty($table) || empty($param)) {
logger('Table and fields have to be set');
return false;
}
$sql = "INSERT INTO `".self::escape($table)."` (`".implode("`, `", array_keys($param))."`) VALUES (".
substr(str_repeat("?, ", count($param)), 0, -2).")";
@ -781,9 +745,6 @@ class dba {
case 'mysqli':
$id = self::$db->insert_id;
break;
case 'mysql':
$id = mysql_insert_id(self::$db);
break;
}
return $id;
}
@ -897,6 +858,12 @@ class dba {
* @return boolean|array was the delete successfull? When $in_process is set: deletion data
*/
public static function delete($table, $param, $in_process = false, &$callstack = array()) {
if (empty($table) || empty($param)) {
logger('Table and condition have to be set');
return false;
}
$commands = array();
// Create a key for the loop prevention
@ -1059,18 +1026,20 @@ class dba {
* @return boolean was the update successfull?
*/
public static function update($table, $fields, $condition, $old_fields = array()) {
if (empty($table) || empty($fields) || empty($condition)) {
logger('Table, fields and condition have to be set');
return false;
}
$table = self::escape($table);
if (count($condition) > 0) {
$array_element = each($condition);
$array_key = $array_element['key'];
if (is_int($array_key)) {
$condition_string = " WHERE ".array_shift($condition);
} else {
$condition_string = " WHERE `".implode("` = ? AND `", array_keys($condition))."` = ?";
}
$array_element = each($condition);
$array_key = $array_element['key'];
if (is_int($array_key)) {
$condition_string = " WHERE ".array_shift($condition);
} else {
$condition_string = "";
$condition_string = " WHERE `".implode("` = ? AND `", array_keys($condition))."` = ?";
}
if (is_bool($old_fields)) {
@ -1250,10 +1219,8 @@ class dba {
case 'pdo':
return $stmt->closeCursor();
case 'mysqli':
return $stmt->free_result();
$stmt->free_result();
return $stmt->close();
case 'mysql':
return mysql_free_result($stmt);
}
}
}

View File

@ -1,303 +0,0 @@
<?php
/**
* @file include/dbclean.php
* @brief The script is called from time to time to clean the database entries and remove orphaned data.
*/
use Friendica\Core\Config;
use Friendica\Core\Worker;
function dbclean_run(&$argv, &$argc) {
if (!Config::get('system', 'dbclean', false)) {
return;
}
if ($argc == 2) {
$stage = intval($argv[1]);
} else {
$stage = 0;
}
// Get the expire days for step 8 and 9
$days = Config::get('system', 'dbclean-expire-days', 0);
if ($stage == 0) {
for ($i = 1; $i <= 9; $i++) {
// Execute the background script for a step when it isn't finished.
// Execute step 8 and 9 only when $days is defined.
if (!Config::get('system', 'finished-dbclean-'.$i, false) && (($i < 8) || ($days > 0))) {
Worker::add(PRIORITY_LOW, 'dbclean', $i);
}
}
} else {
remove_orphans($stage);
}
}
/**
* @brief Remove orphaned database entries
* @param integer $stage What should be deleted?
*
* Values for $stage:
* ------------------
* 1: Old global item entries from item table without user copy.
* 2: Items without parents.
* 3: Orphaned data from thread table.
* 4: Orphaned data from notify table.
* 5: Orphaned data from notify-threads table.
* 6: Orphaned data from sign table.
* 7: Orphaned data from term table.
* 8: Expired threads.
* 9: Old global item entries from expired threads
*/
function remove_orphans($stage = 0) {
global $db;
$count = 0;
// We split the deletion in many small tasks
$limit = 1000;
// Get the expire days for step 8 and 9
$days = Config::get('system', 'dbclean-expire-days', 0);
if ($stage == 1) {
$last_id = Config::get('system', 'dbclean-last-id-1', 0);
logger("Deleting old global item entries from item table without user copy. Last ID: ".$last_id);
$r = dba::p("SELECT `id` FROM `item` WHERE `uid` = 0 AND
NOT EXISTS (SELECT `guid` FROM `item` AS `i` WHERE `item`.`guid` = `i`.`guid` AND `i`.`uid` != 0) AND
`received` < UTC_TIMESTAMP() - INTERVAL 90 DAY AND `id` >= ?
ORDER BY `id` LIMIT ".intval($limit), $last_id);
$count = dba::num_rows($r);
if ($count > 0) {
logger("found global item orphans: ".$count);
while ($orphan = dba::fetch($r)) {
$last_id = $orphan["id"];
dba::delete('item', array('id' => $orphan["id"]));
}
} else {
logger("No global item orphans found");
}
dba::close($r);
logger("Done deleting ".$count." old global item entries from item table without user copy. Last ID: ".$last_id);
Config::set('system', 'dbclean-last-id-1', $last_id);
} elseif ($stage == 2) {
$last_id = Config::get('system', 'dbclean-last-id-2', 0);
logger("Deleting items without parents. Last ID: ".$last_id);
$r = dba::p("SELECT `id` FROM `item`
WHERE NOT EXISTS (SELECT `id` FROM `item` AS `i` WHERE `item`.`parent` = `i`.`id`)
AND `id` >= ? ORDER BY `id` LIMIT ".intval($limit), $last_id);
$count = dba::num_rows($r);
if ($count > 0) {
logger("found item orphans without parents: ".$count);
while ($orphan = dba::fetch($r)) {
$last_id = $orphan["id"];
dba::delete('item', array('id' => $orphan["id"]));
}
} else {
logger("No item orphans without parents found");
}
dba::close($r);
logger("Done deleting ".$count." items without parents. Last ID: ".$last_id);
Config::set('system', 'dbclean-last-id-2', $last_id);
if ($count < $limit) {
Config::set('system', 'finished-dbclean-2', true);
}
} elseif ($stage == 3) {
$last_id = Config::get('system', 'dbclean-last-id-3', 0);
logger("Deleting orphaned data from thread table. Last ID: ".$last_id);
$r = dba::p("SELECT `iid` FROM `thread`
WHERE NOT EXISTS (SELECT `id` FROM `item` WHERE `item`.`parent` = `thread`.`iid`) AND `iid` >= ?
ORDER BY `iid` LIMIT ".intval($limit), $last_id);
$count = dba::num_rows($r);
if ($count > 0) {
logger("found thread orphans: ".$count);
while ($orphan = dba::fetch($r)) {
$last_id = $orphan["iid"];
dba::delete('thread', array('iid' => $orphan["iid"]));
}
} else {
logger("No thread orphans found");
}
dba::close($r);
logger("Done deleting ".$count." orphaned data from thread table. Last ID: ".$last_id);
Config::set('system', 'dbclean-last-id-3', $last_id);
if ($count < $limit) {
Config::set('system', 'finished-dbclean-3', true);
}
} elseif ($stage == 4) {
$last_id = Config::get('system', 'dbclean-last-id-4', 0);
logger("Deleting orphaned data from notify table. Last ID: ".$last_id);
$r = dba::p("SELECT `iid`, `id` FROM `notify`
WHERE NOT EXISTS (SELECT `id` FROM `item` WHERE `item`.`id` = `notify`.`iid`) AND `id` >= ?
ORDER BY `id` LIMIT ".intval($limit), $last_id);
$count = dba::num_rows($r);
if ($count > 0) {
logger("found notify orphans: ".$count);
while ($orphan = dba::fetch($r)) {
$last_id = $orphan["id"];
dba::delete('notify', array('iid' => $orphan["iid"]));
}
} else {
logger("No notify orphans found");
}
dba::close($r);
logger("Done deleting ".$count." orphaned data from notify table. Last ID: ".$last_id);
Config::set('system', 'dbclean-last-id-4', $last_id);
if ($count < $limit) {
Config::set('system', 'finished-dbclean-4', true);
}
} elseif ($stage == 5) {
$last_id = Config::get('system', 'dbclean-last-id-5', 0);
logger("Deleting orphaned data from notify-threads table. Last ID: ".$last_id);
$r = dba::p("SELECT `id` FROM `notify-threads`
WHERE NOT EXISTS (SELECT `id` FROM `item` WHERE `item`.`parent` = `notify-threads`.`master-parent-item`) AND `id` >= ?
ORDER BY `id` LIMIT ".intval($limit), $last_id);
$count = dba::num_rows($r);
if ($count > 0) {
logger("found notify-threads orphans: ".$count);
while ($orphan = dba::fetch($r)) {
$last_id = $orphan["id"];
dba::delete('notify-threads', array('id' => $orphan["id"]));
}
} else {
logger("No notify-threads orphans found");
}
dba::close($r);
logger("Done deleting ".$count." orphaned data from notify-threads table. Last ID: ".$last_id);
Config::set('system', 'dbclean-last-id-5', $last_id);
if ($count < $limit) {
Config::set('system', 'finished-dbclean-5', true);
}
} elseif ($stage == 6) {
$last_id = Config::get('system', 'dbclean-last-id-6', 0);
logger("Deleting orphaned data from sign table. Last ID: ".$last_id);
$r = dba::p("SELECT `iid`, `id` FROM `sign`
WHERE NOT EXISTS (SELECT `id` FROM `item` WHERE `item`.`id` = `sign`.`iid`) AND `id` >= ?
ORDER BY `id` LIMIT ".intval($limit), $last_id);
$count = dba::num_rows($r);
if ($count > 0) {
logger("found sign orphans: ".$count);
while ($orphan = dba::fetch($r)) {
$last_id = $orphan["id"];
dba::delete('sign', array('iid' => $orphan["iid"]));
}
} else {
logger("No sign orphans found");
}
dba::close($r);
logger("Done deleting ".$count." orphaned data from sign table. Last ID: ".$last_id);
Config::set('system', 'dbclean-last-id-6', $last_id);
if ($count < $limit) {
Config::set('system', 'finished-dbclean-6', true);
}
} elseif ($stage == 7) {
$last_id = Config::get('system', 'dbclean-last-id-7', 0);
logger("Deleting orphaned data from term table. Last ID: ".$last_id);
$r = dba::p("SELECT `oid`, `tid` FROM `term`
WHERE NOT EXISTS (SELECT `id` FROM `item` WHERE `item`.`id` = `term`.`oid`) AND `tid` >= ?
ORDER BY `tid` LIMIT ".intval($limit), $last_id);
$count = dba::num_rows($r);
if ($count > 0) {
logger("found term orphans: ".$count);
while ($orphan = dba::fetch($r)) {
$last_id = $orphan["tid"];
dba::delete('term', array('oid' => $orphan["oid"]));
}
} else {
logger("No term orphans found");
}
dba::close($r);
logger("Done deleting ".$count." orphaned data from term table. Last ID: ".$last_id);
Config::set('system', 'dbclean-last-id-7', $last_id);
if ($count < $limit) {
Config::set('system', 'finished-dbclean-7', true);
}
} elseif ($stage == 8) {
if ($days <= 0) {
return;
}
$last_id = Config::get('system', 'dbclean-last-id-8', 0);
logger("Deleting expired threads. Last ID: ".$last_id);
$r = dba::p("SELECT `thread`.`iid` FROM `thread`
INNER JOIN `contact` ON `thread`.`contact-id` = `contact`.`id` AND NOT `notify_new_posts`
WHERE `thread`.`received` < UTC_TIMESTAMP() - INTERVAL ? DAY
AND NOT `thread`.`mention` AND NOT `thread`.`starred`
AND NOT `thread`.`wall` AND NOT `thread`.`origin`
AND `thread`.`uid` != 0 AND `thread`.`iid` >= ?
AND NOT `thread`.`iid` IN (SELECT `parent` FROM `item`
WHERE (`item`.`starred` OR (`item`.`resource-id` != '')
OR (`item`.`file` != '') OR (`item`.`event-id` != '')
OR (`item`.`attach` != '') OR `item`.`wall` OR `item`.`origin`)
AND `item`.`parent` = `thread`.`iid`)
ORDER BY `thread`.`iid` LIMIT 1000", $days, $last_id);
$count = dba::num_rows($r);
if ($count > 0) {
logger("found expired threads: ".$count);
while ($thread = dba::fetch($r)) {
$last_id = $thread["iid"];
dba::delete('thread', array('iid' => $thread["iid"]));
}
} else {
logger("No expired threads found");
}
dba::close($r);
logger("Done deleting ".$count." expired threads. Last ID: ".$last_id);
Config::set('system', 'dbclean-last-id-8', $last_id);
} elseif ($stage == 9) {
if ($days <= 0) {
return;
}
$last_id = Config::get('system', 'dbclean-last-id-9', 0);
$till_id = Config::get('system', 'dbclean-last-id-8', 0);
logger("Deleting old global item entries from expired threads from ID ".$last_id." to ID ".$till_id);
$r = dba::p("SELECT `id` FROM `item` WHERE `uid` = 0 AND
NOT EXISTS (SELECT `guid` FROM `item` AS `i` WHERE `item`.`guid` = `i`.`guid` AND `i`.`uid` != 0) AND
`received` < UTC_TIMESTAMP() - INTERVAL 90 DAY AND `id` >= ? AND `id` <= ?
ORDER BY `id` LIMIT ".intval($limit), $last_id, $till_id);
$count = dba::num_rows($r);
if ($count > 0) {
logger("found global item entries from expired threads: ".$count);
while ($orphan = dba::fetch($r)) {
$last_id = $orphan["id"];
dba::delete('item', array('id' => $orphan["id"]));
}
} else {
logger("No global item entries from expired threads");
}
dba::close($r);
logger("Done deleting ".$count." old global item entries from expired threads. Last ID: ".$last_id);
Config::set('system', 'dbclean-last-id-9', $last_id);
}
// Call it again if not all entries were purged
if (($stage != 0) && ($count > 0)) {
Worker::add(PRIORITY_MEDIUM, 'dbclean');
}
}

View File

@ -1757,73 +1757,3 @@ function db_definition() {
return($database);
}
/*
* run from command line
*/
function dbstructure_run(&$argv, &$argc) {
global $a;
if (empty($a)) {
$a = new App(dirname(__DIR__));
}
@include ".htconfig.php";
require_once "include/dba.php";
dba::connect($db_host, $db_user, $db_pass, $db_data);
unset($db_host, $db_user, $db_pass, $db_data);
if ($argc == 2) {
switch ($argv[1]) {
case "dryrun":
update_structure(true, false);
return;
case "update":
update_structure(true, true);
$build = Config::get('system','build');
if (!x($build)) {
Config::set('system', 'build', DB_UPDATE_VERSION);
$build = DB_UPDATE_VERSION;
}
$stored = intval($build);
$current = intval(DB_UPDATE_VERSION);
// run any left update_nnnn functions in update.php
for ($x = $stored; $x < $current; $x ++) {
$r = run_update_function($x);
if (!$r) {
break;
}
}
Config::set('system','build',DB_UPDATE_VERSION);
return;
case "dumpsql":
print_structure(db_definition());
return;
case "toinnodb":
convert_to_innodb();
return;
}
}
// print help
echo $argv[0]." <command>\n";
echo "\n";
echo "Commands:\n";
echo "dryrun show database update schema queries without running them\n";
echo "update update database schema\n";
echo "dumpsql dump database schema\n";
echo "toinnodb convert all tables from MyISAM to InnoDB\n";
return;
}
if (array_search(__FILE__,get_included_files())===0) {
dbstructure_run($_SERVER["argv"],$_SERVER["argc"]);
killme();
}

View File

@ -1,13 +0,0 @@
<?php
use Friendica\Core\Config;
function dbupdate_run(&$argv, &$argc) {
global $a;
// We are deleting the latest dbupdate entry.
// This is done to avoid endless loops because the update was interupted.
Config::delete('database', 'dbupdate_'.DB_UPDATE_VERSION);
update_db($a);
}

View File

@ -1,45 +0,0 @@
<?php
use Friendica\Core\Config;
use Friendica\Core\Worker;
use Friendica\Database\DBM;
function directory_run(&$argv, &$argc){
$dir = Config::get('system', 'directory');
if (!strlen($dir)) {
return;
}
if ($argc < 2) {
directory_update_all();
return;
}
$dir .= "/submit";
$arr = array('url' => $argv[1]);
call_hooks('globaldir_update', $arr);
logger('Updating directory: ' . $arr['url'], LOGGER_DEBUG);
if (strlen($arr['url'])) {
fetch_url($dir . '?url=' . bin2hex($arr['url']));
}
return;
}
function directory_update_all() {
$r = q("SELECT `url` FROM `contact`
INNER JOIN `profile` ON `profile`.`uid` = `contact`.`uid`
INNER JOIN `user` ON `user`.`uid` = `contact`.`uid`
WHERE `contact`.`self` AND `profile`.`net-publish` AND `profile`.`is-default` AND
NOT `user`.`account_expired` AND `user`.`verified`");
if (DBM::is_result($r)) {
foreach ($r AS $user) {
Worker::add(PRIORITY_LOW, 'directory', $user['url']);
}
}
}

View File

@ -1,293 +0,0 @@
<?php
use Friendica\Core\Cache;
use Friendica\Core\Config;
use Friendica\Core\Worker;
use Friendica\Database\DBM;
use Friendica\Network\Probe;
require_once 'include/socgraph.php';
require_once 'include/datetime.php';
function discover_poco_run(&$argv, &$argc) {
/*
This function can be called in these ways:
- dirsearch <search pattern>: Searches for "search pattern" in the directory. "search pattern" is url encoded.
- checkcontact: Updates gcontact entries
- suggestions: Discover other servers for their contacts.
- server <poco url>: Searches for the poco server list. "poco url" is base64 encoded.
- update_server: Frequently check the first 250 servers for vitality.
- update_server_directory: Discover the given server id for their contacts
- poco_load: Load POCO data from a given POCO address
- check_profile: Update remote profile data
*/
if (($argc > 2) && ($argv[1] == "dirsearch")) {
$search = urldecode($argv[2]);
$mode = 1;
} elseif (($argc == 2) && ($argv[1] == "checkcontact")) {
$mode = 2;
} elseif (($argc == 2) && ($argv[1] == "suggestions")) {
$mode = 3;
} elseif (($argc == 3) && ($argv[1] == "server")) {
$mode = 4;
} elseif (($argc == 2) && ($argv[1] == "update_server")) {
$mode = 5;
} elseif (($argc == 3) && ($argv[1] == "update_server_directory")) {
$mode = 6;
} elseif (($argc > 5) && ($argv[1] == "poco_load")) {
$mode = 7;
} elseif (($argc == 3) && ($argv[1] == "check_profile")) {
$mode = 8;
} elseif ($argc == 1) {
$search = "";
$mode = 0;
} else {
die("Unknown or missing parameter ".$argv[1]."\n");
}
logger('start '.$search);
if ($mode == 8) {
if ($argv[2] != "") {
poco_last_updated($argv[2], true);
}
} elseif ($mode == 7) {
if ($argc == 6) {
$url = $argv[5];
} else {
$url = '';
}
poco_load_worker(intval($argv[2]), intval($argv[3]), intval($argv[4]), $url);
} elseif ($mode == 6) {
poco_discover_single_server(intval($argv[2]));
} elseif ($mode == 5) {
update_server();
} elseif ($mode == 4) {
$server_url = $argv[2];
if ($server_url == "") {
return;
}
$server_url = filter_var($server_url, FILTER_SANITIZE_URL);
if (substr(normalise_link($server_url), 0, 7) != "http://") {
return;
}
$result = "Checking server ".$server_url." - ";
$ret = poco_check_server($server_url);
if ($ret) {
$result .= "success";
} else {
$result .= "failed";
}
logger($result, LOGGER_DEBUG);
} elseif ($mode == 3) {
update_suggestions();
} elseif (($mode == 2) && Config::get('system','poco_completion')) {
discover_users();
} elseif (($mode == 1) && ($search != "") && Config::get('system','poco_local_search')) {
discover_directory($search);
gs_search_user($search);
} elseif (($mode == 0) && ($search == "") && (Config::get('system','poco_discovery') > 0)) {
// Query Friendica and Hubzilla servers for their users
poco_discover();
// Query GNU Social servers for their users ("statistics" addon has to be enabled on the GS server)
if (!Config::get('system','ostatus_disabled'))
gs_discover();
}
logger('end '.$search);
return;
}
/**
* @brief Updates the first 250 servers
*
*/
function update_server() {
$r = q("SELECT `url`, `created`, `last_failure`, `last_contact` FROM `gserver` ORDER BY rand()");
if (!DBM::is_result($r)) {
return;
}
$updated = 0;
foreach ($r AS $server) {
if (!poco_do_update($server["created"], "", $server["last_failure"], $server["last_contact"])) {
continue;
}
logger('Update server status for server '.$server["url"], LOGGER_DEBUG);
Worker::add(PRIORITY_LOW, "discover_poco", "server", $server["url"]);
if (++$updated > 250) {
return;
}
}
}
function discover_users() {
logger("Discover users", LOGGER_DEBUG);
$starttime = time();
$users = q("SELECT `url`, `created`, `updated`, `last_failure`, `last_contact`, `server_url`, `network` FROM `gcontact`
WHERE `last_contact` < UTC_TIMESTAMP - INTERVAL 1 MONTH AND
`last_failure` < UTC_TIMESTAMP - INTERVAL 1 MONTH AND
`network` IN ('%s', '%s', '%s', '%s', '') ORDER BY rand()",
dbesc(NETWORK_DFRN), dbesc(NETWORK_DIASPORA),
dbesc(NETWORK_OSTATUS), dbesc(NETWORK_FEED));
if (!$users) {
return;
}
$checked = 0;
foreach ($users AS $user) {
$urlparts = parse_url($user["url"]);
if (!isset($urlparts["scheme"])) {
q("UPDATE `gcontact` SET `network` = '%s' WHERE `nurl` = '%s'",
dbesc(NETWORK_PHANTOM), dbesc(normalise_link($user["url"])));
continue;
}
if (in_array($urlparts["host"], array("www.facebook.com", "facebook.com", "twitter.com",
"identi.ca", "alpha.app.net"))) {
$networks = array("www.facebook.com" => NETWORK_FACEBOOK,
"facebook.com" => NETWORK_FACEBOOK,
"twitter.com" => NETWORK_TWITTER,
"identi.ca" => NETWORK_PUMPIO,
"alpha.app.net" => NETWORK_APPNET);
q("UPDATE `gcontact` SET `network` = '%s' WHERE `nurl` = '%s'",
dbesc($networks[$urlparts["host"]]), dbesc(normalise_link($user["url"])));
continue;
}
$server_url = poco_detect_server($user["url"]);
$force_update = false;
if ($user["server_url"] != "") {
$force_update = (normalise_link($user["server_url"]) != normalise_link($server_url));
$server_url = $user["server_url"];
}
if ((($server_url == "") && ($user["network"] == NETWORK_FEED)) || $force_update || poco_check_server($server_url, $user["network"])) {
logger('Check profile '.$user["url"]);
Worker::add(PRIORITY_LOW, "discover_poco", "check_profile", $user["url"]);
if (++$checked > 100) {
return;
}
} else {
q("UPDATE `gcontact` SET `last_failure` = '%s' WHERE `nurl` = '%s'",
dbesc(datetime_convert()), dbesc(normalise_link($user["url"])));
}
// Quit the loop after 3 minutes
if (time() > ($starttime + 180)) {
return;
}
}
}
function discover_directory($search) {
$data = Cache::get("dirsearch:".$search);
if (!is_null($data)) {
// Only search for the same item every 24 hours
if (time() < $data + (60 * 60 * 24)) {
logger("Already searched for ".$search." in the last 24 hours", LOGGER_DEBUG);
return;
}
}
$x = fetch_url(get_server()."/lsearch?p=1&n=500&search=".urlencode($search));
$j = json_decode($x);
if (count($j->results)) {
foreach ($j->results as $jj) {
// Check if the contact already exists
$exists = q("SELECT `id`, `last_contact`, `last_failure`, `updated` FROM `gcontact` WHERE `nurl` = '%s'", normalise_link($jj->url));
if (DBM::is_result($exists)) {
logger("Profile ".$jj->url." already exists (".$search.")", LOGGER_DEBUG);
if (($exists[0]["last_contact"] < $exists[0]["last_failure"]) &&
($exists[0]["updated"] < $exists[0]["last_failure"])) {
continue;
}
// Update the contact
poco_last_updated($jj->url);
continue;
}
$server_url = poco_detect_server($jj->url);
if ($server_url != '') {
if (!poco_check_server($server_url)) {
logger("Friendica server ".$server_url." doesn't answer.", LOGGER_DEBUG);
continue;
}
logger("Friendica server ".$server_url." seems to be okay.", LOGGER_DEBUG);
}
$data = Probe::uri($jj->url);
if ($data["network"] == NETWORK_DFRN) {
logger("Profile ".$jj->url." is reachable (".$search.")", LOGGER_DEBUG);
logger("Add profile ".$jj->url." to local directory (".$search.")", LOGGER_DEBUG);
if ($jj->tags != "") {
$data["keywords"] = $jj->tags;
}
$data["server_url"] = $data["baseurl"];
update_gcontact($data);
} else {
logger("Profile ".$jj->url." is not responding or no Friendica contact - but network ".$data["network"], LOGGER_DEBUG);
}
}
}
Cache::set("dirsearch:".$search, time(), CACHE_DAY);
}
/**
* @brief Search for GNU Social user with gstools.org
*
* @param str $search User name
*/
function gs_search_user($search) {
// Currently disabled, since the service isn't available anymore.
// It is not removed since I hope that there will be a successor.
return false;
$a = get_app();
$url = "http://gstools.org/api/users_search/".urlencode($search);
$result = z_fetch_url($url);
if (!$result["success"]) {
return false;
}
$contacts = json_decode($result["body"]);
if ($contacts->status == 'ERROR') {
return false;
}
/// @TODO AS is considered as a notation for constants (as they usually being written all upper-case)
/// @TODO find all those and convert to all lower-case which is a keyword then
foreach ($contacts->data AS $user) {
$contact = Probe::uri($user->site_address."/".$user->name);
if ($contact["network"] != NETWORK_PHANTOM) {
$contact["about"] = $user->description;
update_gcontact($contact);
}
}
}

View File

@ -1,14 +1,16 @@
<?php
/**
* @file include/enotify.php
*/
use Friendica\App;
use Friendica\Core\Config;
use Friendica\Core\System;
use Friendica\Database\DBM;
use Friendica\Util\Emailer;
require_once('include/Emailer.php');
require_once('include/email.php');
require_once('include/bbcode.php');
require_once('include/html2bbcode.php');
require_once 'include/email.php';
require_once 'include/bbcode.php';
require_once 'include/html2bbcode.php';
/**
* @brief Creates a notification entry and possibly sends a mail
@ -637,7 +639,8 @@ function notification($params) {
// use the Emailer class to send the message
return Emailer::send(array(
return Emailer::send(
array(
'uid' => $params['uid'],
'fromName' => $sender_name,
'fromEmail' => $sender_email,
@ -646,11 +649,11 @@ function notification($params) {
'messageSubject' => $datarray['subject'],
'htmlVersion' => $email_html_body,
'textVersion' => $email_text_body,
'additionalMailHeader' => $datarray['headers'],
));
'additionalMailHeader' => $datarray['headers'])
);
}
return False;
return false;
}
/**

View File

@ -12,6 +12,7 @@ use Friendica\Database\DBM;
require_once 'include/bbcode.php';
require_once 'include/map.php';
require_once 'include/datetime.php';
require_once "include/conversation.php";
function format_event_html($ev, $simple = false) {
if (! ((is_array($ev)) && count($ev))) {
@ -216,7 +217,7 @@ function event_delete($event_id) {
return;
}
q("DELETE FROM `event` WHERE `id` = %d", intval($event_id));
dba::delete('event', array('id' => $event_id));
logger("Deleted event ".$event_id, LOGGER_DEBUG);
}

View File

@ -1,76 +0,0 @@
<?php
use Friendica\Core\Config;
use Friendica\Core\Worker;
use Friendica\Database\DBM;
function expire_run(&$argv, &$argc){
global $a;
require_once('include/datetime.php');
require_once('include/items.php');
require_once('include/Contact.php');
load_hooks();
if (($argc == 2) && ($argv[1] == 'delete')) {
logger('Delete expired items', LOGGER_DEBUG);
// physically remove anything that has been deleted for more than two months
$r = dba::p("SELECT `id` FROM `item` WHERE `deleted` AND `changed` < UTC_TIMESTAMP() - INTERVAL 60 DAY");
while ($row = dba::fetch($r)) {
dba::delete('item', array('id' => $row['id']));
}
dba::close($r);
logger('Delete expired items - done', LOGGER_DEBUG);
// make this optional as it could have a performance impact on large sites
if (intval(Config::get('system', 'optimize_items'))) {
q("OPTIMIZE TABLE `item`");
}
return;
} elseif (($argc == 2) && (intval($argv[1]) > 0)) {
$user = dba::select('user', array('uid', 'username', 'expire'), array('uid' => $argv[1]), array('limit' => 1));
if (DBM::is_result($user)) {
logger('Expire items for user '.$user['uid'].' ('.$user['username'].') - interval: '.$user['expire'], LOGGER_DEBUG);
item_expire($user['uid'], $user['expire']);
logger('Expire items for user '.$user['uid'].' ('.$user['username'].') - done ', LOGGER_DEBUG);
}
return;
} elseif (($argc == 3) && ($argv[1] == 'hook') && is_array($a->hooks) && array_key_exists("expire", $a->hooks)) {
foreach ($a->hooks["expire"] as $hook) {
if ($hook[1] == $argv[2]) {
logger("Calling expire hook '" . $hook[1] . "'", LOGGER_DEBUG);
call_single_hook($a, $name, $hook, $data);
}
}
return;
}
logger('expire: start');
Worker::add(array('priority' => $a->queue['priority'], 'created' => $a->queue['created'], 'dont_fork' => true),
'expire', 'delete');
$r = dba::p("SELECT `uid`, `username` FROM `user` WHERE `expire` != 0");
while ($row = dba::fetch($r)) {
logger('Calling expiry for user '.$row['uid'].' ('.$row['username'].')', LOGGER_DEBUG);
Worker::add(array('priority' => $a->queue['priority'], 'created' => $a->queue['created'], 'dont_fork' => true),
'expire', (int)$row['uid']);
}
dba::close($r);
logger('expire: calling hooks');
if (is_array($a->hooks) && array_key_exists('expire', $a->hooks)) {
foreach ($a->hooks['expire'] as $hook) {
logger("Calling expire hook for '" . $hook[1] . "'", LOGGER_DEBUG);
Worker::add(array('priority' => $a->queue['priority'], 'created' => $a->queue['created'], 'dont_fork' => true),
'expire', 'hook', $hook[1]);
}
}
logger('expire: end');
return;
}

View File

@ -14,16 +14,16 @@ use Friendica\Core\PConfig;
* @return boolean
*/
function feature_enabled($uid, $feature) {
$x = Config::get('feature_lock', $feature);
$x = Config::get('feature_lock', $feature, false);
if (is_null($x)) {
$x = PConfig::get($uid, 'feature', $feature);
if (is_null($x)) {
$x = Config::get('feature', $feature);
if (is_null($x)) {
$x = get_feature_default($feature);
}
}
if ($x === false) {
$x = PConfig::get($uid, 'feature', $feature, false);
}
if ($x === false) {
$x = Config::get('feature', $feature, false);
}
if ($x === false) {
$x = get_feature_default($feature);
}
$arr = array('uid' => $uid, 'feature' => $feature, 'enabled' => $x);
@ -67,53 +67,54 @@ function get_features($filtered = true) {
'general' => array(
t('General Features'),
//array('expire', t('Content Expiration'), t('Remove old posts/comments after a period of time')),
array('multi_profiles', t('Multiple Profiles'), t('Ability to create multiple profiles'), false, Config::get('feature_lock','multi_profiles')),
array('photo_location', t('Photo Location'), t('Photo metadata is normally stripped. This extracts the location (if present) prior to stripping metadata and links it to a map.'), false, Config::get('feature_lock','photo_location')),
array('export_calendar', t('Export Public Calendar'), t('Ability for visitors to download the public calendar'), false, Config::get('feature_lock','export_calendar')),
array('multi_profiles', t('Multiple Profiles'), t('Ability to create multiple profiles'), false, Config::get('feature_lock','multi_profiles', false)),
array('photo_location', t('Photo Location'), t('Photo metadata is normally stripped. This extracts the location (if present) prior to stripping metadata and links it to a map.'), false, Config::get('feature_lock','photo_location', false)),
array('export_calendar', t('Export Public Calendar'), t('Ability for visitors to download the public calendar'), false, Config::get('feature_lock','export_calendar', false)),
),
// Post composition
'composition' => array(
t('Post Composition Features'),
array('preview', t('Post Preview'), t('Allow previewing posts and comments before publishing them'), false, Config::get('feature_lock','preview')),
array('aclautomention', t('Auto-mention Forums'), t('Add/remove mention when a forum page is selected/deselected in ACL window.'), false, Config::get('feature_lock','aclautomention')),
array('preview', t('Post Preview'), t('Allow previewing posts and comments before publishing them'), false, Config::get('feature_lock','preview', false)),
array('aclautomention', t('Auto-mention Forums'), t('Add/remove mention when a forum page is selected/deselected in ACL window.'), false, Config::get('feature_lock','aclautomention', false)),
),
// Network sidebar widgets
'widgets' => array(
t('Network Sidebar Widgets'),
array('archives', t('Search by Date'), t('Ability to select posts by date ranges'), false, Config::get('feature_lock','archives')),
array('forumlist_widget', t('List Forums'), t('Enable widget to display the forums your are connected with'), true, Config::get('feature_lock','forumlist_widget')),
array('groups', t('Group Filter'), t('Enable widget to display Network posts only from selected group'), false, Config::get('feature_lock','groups')),
array('networks', t('Network Filter'), t('Enable widget to display Network posts only from selected network'), false, Config::get('feature_lock','networks')),
array('savedsearch', t('Saved Searches'), t('Save search terms for re-use'), false, Config::get('feature_lock','savedsearch')),
array('archives', t('Search by Date'), t('Ability to select posts by date ranges'), false, Config::get('feature_lock','archives', false)),
array('forumlist_widget', t('List Forums'), t('Enable widget to display the forums your are connected with'), true, Config::get('feature_lock','forumlist_widget', false)),
array('groups', t('Group Filter'), t('Enable widget to display Network posts only from selected group'), false, Config::get('feature_lock','groups', false)),
array('networks', t('Network Filter'), t('Enable widget to display Network posts only from selected network'), false, Config::get('feature_lock','networks', false)),
array('savedsearch', t('Saved Searches'), t('Save search terms for re-use'), false, Config::get('feature_lock','savedsearch', false)),
),
// Network tabs
'net_tabs' => array(
t('Network Tabs'),
array('personal_tab', t('Network Personal Tab'), t('Enable tab to display only Network posts that you\'ve interacted on'), false, Config::get('feature_lock','personal_tab')),
array('new_tab', t('Network New Tab'), t('Enable tab to display only new Network posts (from the last 12 hours)'), false, Config::get('feature_lock','new_tab')),
array('link_tab', t('Network Shared Links Tab'), t('Enable tab to display only Network posts with links in them'), false, Config::get('feature_lock','link_tab')),
array('personal_tab', t('Network Personal Tab'), t('Enable tab to display only Network posts that you\'ve interacted on'), false, Config::get('feature_lock','personal_tab', false)),
array('new_tab', t('Network New Tab'), t('Enable tab to display only new Network posts (from the last 12 hours)'), false, Config::get('feature_lock','new_tab', false)),
array('link_tab', t('Network Shared Links Tab'), t('Enable tab to display only Network posts with links in them'), false, Config::get('feature_lock','link_tab', false)),
),
// Item tools
'tools' => array(
t('Post/Comment Tools'),
array('multi_delete', t('Multiple Deletion'), t('Select and delete multiple posts/comments at once'), false, Config::get('feature_lock','multi_delete')),
array('edit_posts', t('Edit Sent Posts'), t('Edit and correct posts and comments after sending'), false, Config::get('feature_lock','edit_posts')),
array('commtag', t('Tagging'), t('Ability to tag existing posts'), false, Config::get('feature_lock','commtag')),
array('categories', t('Post Categories'), t('Add categories to your posts'), false, Config::get('feature_lock','categories')),
array('filing', t('Saved Folders'), t('Ability to file posts under folders'), false, Config::get('feature_lock','filing')),
array('dislike', t('Dislike Posts'), t('Ability to dislike posts/comments'), false, Config::get('feature_lock','dislike')),
array('star_posts', t('Star Posts'), t('Ability to mark special posts with a star indicator'), false, Config::get('feature_lock','star_posts')),
array('ignore_posts', t('Mute Post Notifications'), t('Ability to mute notifications for a thread'), false, Config::get('feature_lock','ignore_posts')),
array('multi_delete', t('Multiple Deletion'), t('Select and delete multiple posts/comments at once'), false, Config::get('feature_lock','multi_delete', false)),
array('edit_posts', t('Edit Sent Posts'), t('Edit and correct posts and comments after sending'), false, Config::get('feature_lock','edit_posts', false)),
array('commtag', t('Tagging'), t('Ability to tag existing posts'), false, Config::get('feature_lock','commtag', false)),
array('categories', t('Post Categories'), t('Add categories to your posts'), false, Config::get('feature_lock','categories', false)),
array('filing', t('Saved Folders'), t('Ability to file posts under folders'), false, Config::get('feature_lock','filing', false)),
array('dislike', t('Dislike Posts'), t('Ability to dislike posts/comments'), false, Config::get('feature_lock','dislike', false)),
array('star_posts', t('Star Posts'), t('Ability to mark special posts with a star indicator'), false, Config::get('feature_lock','star_posts', false)),
array('ignore_posts', t('Mute Post Notifications'), t('Ability to mute notifications for a thread'), false, Config::get('feature_lock','ignore_posts', false)),
),
// Advanced Profile Settings
'advanced_profile' => array(
t('Advanced Profile Settings'),
array('forumlist_profile', t('List Forums'), t('Show visitors public community forums at the Advanced Profile Page'), false, Config::get('feature_lock','forumlist_profile')),
array('forumlist_profile', t('List Forums'), t('Show visitors public community forums at the Advanced Profile Page'), false, Config::get('feature_lock','forumlist_profile', false)),
array('tagadelic', t('Tag Cloud'), t('Provide a personal tag cloud on your profile page'), false, Config::get('feature_lock', 'tagadelic', false)),
),
);
@ -127,8 +128,7 @@ function get_features($filtered = true) {
if (is_array($arr[$k][$y])) {
if ($arr[$k][$y][4] === false) {
$has_items = true;
}
else {
} else {
unset($arr[$k][$y]);
}
}

View File

@ -344,7 +344,7 @@ function feed_import($xml,$importer,&$contact, &$hub, $simulate = false) {
$item["title"] = '';
}
if ($contact["fetch_further_information"]) {
if (!empty($contact["fetch_further_information"]) && ($contact["fetch_further_information"] < 3)) {
$preview = "";
// Handle enclosures and treat them as preview picture
@ -384,6 +384,9 @@ function feed_import($xml,$importer,&$contact, &$hub, $simulate = false) {
if (!strstr($item["body"], '[url') && ($item['plink'] != '')) {
$item["body"] .= "[hr][url]".$item['plink']."[/url]";
}
if ($contact["fetch_further_information"] == 3) {
$item["tag"] = add_page_keywords($item["plink"], false, $preview, true, $contact["ffi_keyword_blacklist"]);
}
}
if (!$simulate) {

View File

@ -1,5 +1,7 @@
<?php
/**
* @file include/follow.php
*/
use Friendica\App;
use Friendica\Core\Config;
use Friendica\Core\System;
@ -7,11 +9,11 @@ use Friendica\Core\Worker;
use Friendica\Database\DBM;
use Friendica\Network\Probe;
use Friendica\Protocol\Diaspora;
use Friendica\Protocol\OStatus;
use Friendica\Protocol\PortableContact;
require_once 'include/socgraph.php';
require_once 'include/group.php';
require_once 'include/salmon.php';
require_once 'include/ostatus.php';
require_once 'include/Photo.php';
function update_contact($id) {
@ -57,7 +59,7 @@ function update_contact($id) {
);
// Update the corresponding gcontact entry
poco_last_updated($ret["url"]);
PortableContact::lastUpdated($ret["url"]);
return true;
}
@ -252,7 +254,7 @@ function new_contact($uid, $url, $interactive = false, $network = '') {
// pull feed and consume it, which should subscribe to the hub.
Worker::add(PRIORITY_HIGH, "onepoll", $contact_id, "force");
Worker::add(PRIORITY_HIGH, "OnePoll", $contact_id, "force");
$r = q("SELECT `contact`.*, `user`.* FROM `contact` INNER JOIN `user` ON `contact`.`uid` = `user`.`uid`
WHERE `user`.`uid` = %d AND `contact`.`self` LIMIT 1",
@ -265,12 +267,12 @@ function new_contact($uid, $url, $interactive = false, $network = '') {
$item = array();
$item['verb'] = ACTIVITY_FOLLOW;
$item['follow'] = $contact["url"];
$slap = ostatus::salmon($item, $r[0]);
$slap = OStatus::salmon($item, $r[0]);
slapper($r[0], $contact['notify'], $slap);
}
if ($contact['network'] == NETWORK_DIASPORA) {
$ret = Diaspora::send_share($a->user,$contact);
$ret = Diaspora::sendShare($a->user, $contact);
logger('share returns: '.$ret);
}
}

View File

@ -1,6 +1,7 @@
<?php
require_once "object/TemplateEngine.php";
use Friendica\Render\ITemplateEngine;
require_once("library/Smarty/libs/Smarty.class.php");
require_once "include/plugin.php";
@ -54,13 +55,13 @@ class FriendicaSmartyEngine implements ITemplateEngine {
}
// ITemplateEngine interface
public function replace_macros($s, $r) {
public function replaceMacros($s, $r) {
$template = '';
if (gettype($s) === 'string') {
$template = $s;
$s = new FriendicaSmarty();
}
$r['$APP'] = get_app();
// "middleware": inject variables into templates
@ -80,7 +81,7 @@ class FriendicaSmartyEngine implements ITemplateEngine {
return $s->parsed($template);
}
public function get_template_file($file, $root=''){
public function getTemplateFile($file, $root=''){
$a = get_app();
$template_file = get_template_file($a, SMARTY3_TEMPLATE_FOLDER.'/'.$file, $root);
$template = new FriendicaSmarty();

View File

@ -1,57 +0,0 @@
<?php
use Friendica\Core\Cache;
use Friendica\Core\Config;
use Friendica\Database\DBM;
use Friendica\Network\Probe;
require_once 'include/socgraph.php';
require_once 'include/datetime.php';
function gprobe_run(&$argv, &$argc){
if ($argc != 2) {
return;
}
$url = $argv[1];
$r = q("SELECT `id`, `url`, `network` FROM `gcontact` WHERE `nurl` = '%s' ORDER BY `id` LIMIT 1",
dbesc(normalise_link($url))
);
logger("gprobe start for ".normalise_link($url), LOGGER_DEBUG);
if (!DBM::is_result($r)) {
// Is it a DDoS attempt?
$urlparts = parse_url($url);
$result = Cache::get("gprobe:".$urlparts["host"]);
if (!is_null($result)) {
if (in_array($result["network"], array(NETWORK_FEED, NETWORK_PHANTOM))) {
logger("DDoS attempt detected for ".$urlparts["host"]." by ".$_SERVER["REMOTE_ADDR"].". server data: ".print_r($_SERVER, true), LOGGER_DEBUG);
return;
}
}
$arr = Probe::uri($url);
if (is_null($result)) {
Cache::set("gprobe:".$urlparts["host"], $arr);
}
if (!in_array($arr["network"], array(NETWORK_FEED, NETWORK_PHANTOM))) {
update_gcontact($arr);
}
$r = q("SELECT `id`, `url`, `network` FROM `gcontact` WHERE `nurl` = '%s' ORDER BY `id` LIMIT 1",
dbesc(normalise_link($url))
);
}
if (DBM::is_result($r)) {
// Check for accessibility and do a poco discovery
if (poco_last_updated($r[0]['url'], true) && ($r[0]["network"] == NETWORK_DFRN))
poco_load(0,0,$r[0]['id'], str_replace('/profile/','/poco/',$r[0]['url']));
}
logger("gprobe end for ".normalise_link($url), LOGGER_DEBUG);
return;
}

View File

@ -79,10 +79,7 @@ function group_rmv($uid,$name) {
}
// remove all members
$r = q("DELETE FROM `group_member` WHERE `uid` = %d AND `gid` = %d ",
intval($uid),
intval($group_id)
);
dba::delete('group_member', array('uid' => $uid, 'pid' => $group_id));
// remove group
$r = q("UPDATE `group` SET `deleted` = 1 WHERE `uid` = %d AND `name` = '%s'",
@ -109,20 +106,19 @@ function group_byname($uid,$name) {
return false;
}
function group_rmv_member($uid,$name,$member) {
$gid = group_byname($uid,$name);
if (! $gid)
function group_rmv_member($uid, $name, $member) {
$gid = group_byname($uid, $name);
if (!$gid) {
return false;
if (! ( $uid && $gid && $member))
}
if (!($uid && $gid && $member)) {
return false;
$r = q("DELETE FROM `group_member` WHERE `uid` = %d AND `gid` = %d AND `contact-id` = %d",
intval($uid),
intval($gid),
intval($member)
);
}
$r = dba::delete('group_member', array('uid' => $uid, 'gid' => $gid, 'contact-id' => $member));
return $r;
}

View File

@ -4,14 +4,15 @@
*/
use Friendica\App;
use Friendica\Content\ForumManager;
use Friendica\Core\Cache;
use Friendica\Core\Config;
use Friendica\Core\PConfig;
use Friendica\Core\System;
use Friendica\Core\Worker;
use Friendica\Database\DBM;
use Friendica\Object\Contact;
require_once 'include/ForumManager.php';
require_once 'include/bbcode.php';
require_once 'mod/proxy.php';
@ -168,7 +169,7 @@ function get_profiledata_by_nick($nickname, $uid = 0, $profile = 0)
"SELECT `contact`.`id` AS `contact_id`, `contact`.`photo` AS `contact_photo`,
`contact`.`thumb` AS `contact_thumb`, `contact`.`micro` AS `contact_micro`,
`profile`.`uid` AS `profile_uid`, `profile`.*,
`contact`.`avatar-date` AS picdate, `contact`.`addr`, `user`.*
`contact`.`avatar-date` AS picdate, `contact`.`addr`, `contact`.`url`, `user`.*
FROM `profile`
INNER JOIN `contact` on `contact`.`uid` = `profile`.`uid` AND `contact`.`self`
INNER JOIN `user` ON `profile`.`uid` = `user`.`uid`
@ -182,7 +183,7 @@ function get_profiledata_by_nick($nickname, $uid = 0, $profile = 0)
"SELECT `contact`.`id` AS `contact_id`, `contact`.`photo` as `contact_photo`,
`contact`.`thumb` AS `contact_thumb`, `contact`.`micro` AS `contact_micro`,
`profile`.`uid` AS `profile_uid`, `profile`.*,
`contact`.`avatar-date` AS picdate, `contact`.`addr`, `user`.*
`contact`.`avatar-date` AS picdate, `contact`.`addr`, `contact`.`url`, `user`.*
FROM `profile`
INNER JOIN `contact` ON `contact`.`uid` = `profile`.`uid` AND `contact`.`self`
INNER JOIN `user` ON `profile`.`uid` = `user`.`uid`
@ -345,7 +346,7 @@ function profile_sidebar($profile, $block = 0)
}
// Fetch the account type
$account_type = account_type($profile);
$account_type = Contact::getAccountType($profile);
if ((x($profile, 'address') == 1)
|| (x($profile, 'location') == 1)
@ -442,10 +443,6 @@ function profile_sidebar($profile, $block = 0)
$p["photo"] = proxy_url($p["photo"], false, PROXY_SIZE_SMALL);
}
if ($a->theme['template_engine'] === 'internal') {
$location = template_escape($location);
}
$tpl = get_markup_template('profile_vcard.tpl');
$o .= replace_macros(
$tpl,
@ -794,7 +791,7 @@ function advanced_profile(App $a)
//show subcribed forum if it is enabled in the usersettings
if (feature_enabled($uid, 'forumlist_profile')) {
$profile['forumlist'] = array( t('Forums:'), ForumManager::profile_advanced($uid));
$profile['forumlist'] = array( t('Forums:'), ForumManager::profileAdvanced($uid));
}
if ($a->profile['uid'] == local_user()) {
@ -939,7 +936,7 @@ function zrl_init(App $a)
return;
}
Worker::add(PRIORITY_LOW, 'gprobe', $tmp_str);
Worker::add(PRIORITY_LOW, 'GProbe', $tmp_str);
$arr = array('zrl' => $tmp_str, 'url' => $a->cmd);
call_hooks('zrl_init', $arr);
}

View File

@ -5,14 +5,17 @@
*/
use Friendica\App;
use Friendica\Core\System;
use Friendica\ParseUrl;
use Friendica\Util\Lock;
use Friendica\Core\Config;
use Friendica\Core\PConfig;
use Friendica\Core\Worker;
use Friendica\Core\System;
use Friendica\Database\DBM;
use Friendica\Model\GlobalContact;
use Friendica\Object\Contact;
use Friendica\Protocol\DFRN;
use Friendica\Protocol\OStatus;
use Friendica\Util\Lock;
require_once 'include/bbcode.php';
require_once 'include/oembed.php';
@ -24,11 +27,8 @@ require_once 'include/files.php';
require_once 'include/text.php';
require_once 'include/email.php';
require_once 'include/threads.php';
require_once 'include/socgraph.php';
require_once 'include/plaintext.php';
require_once 'include/ostatus.php';
require_once 'include/feed.php';
require_once 'include/Contact.php';
require_once 'mod/share.php';
require_once 'include/enotify.php';
require_once 'include/group.php';
@ -207,7 +207,8 @@ function add_page_info_data($data) {
$preview = str_replace(array("[", "]"), array("&#91;", "&#93;"), htmlentities($data["images"][0]["src"], ENT_QUOTES, 'UTF-8', false));
// if the preview picture is larger than 500 pixels then show it in a larger mode
// But only, if the picture isn't higher than large (To prevent huge posts)
if (($data["images"][0]["width"] >= 500) && ($data["images"][0]["width"] >= $data["images"][0]["height"])) {
if (!Config::get('system', 'always_show_preview') && ($data["images"][0]["width"] >= 500)
&& ($data["images"][0]["width"] >= $data["images"][0]["height"])) {
$text .= " image='".$preview."'";
} else {
$text .= " preview='".$preview."'";
@ -426,7 +427,7 @@ function uri_to_guid($uri, $host = "") {
* @return array Item array with removed conversation data
*/
function store_conversation($arr) {
if (in_array($arr['network'], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS))) {
if (in_array($arr['network'], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS)) && !empty($arr['uri'])) {
$conversation = array('item-uri' => $arr['uri'], 'received' => DBM::date());
if (isset($arr['parent-uri']) && ($arr['parent-uri'] != $arr['uri'])) {
@ -542,9 +543,9 @@ function item_store($arr, $force_parent = false, $notify = false, $dontcache = f
/// @todo Check if this is really still needed
if ($arr['network'] == NETWORK_OSTATUS) {
if (isset($arr['plink'])) {
$arr['plink'] = ostatus::convert_href($arr['plink']);
$arr['plink'] = OStatus::convertHref($arr['plink']);
} elseif (isset($arr['uri'])) {
$arr['plink'] = ostatus::convert_href($arr['uri']);
$arr['plink'] = OStatus::convertHref($arr['uri']);
}
}
@ -718,12 +719,12 @@ function item_store($arr, $force_parent = false, $notify = false, $dontcache = f
* This is done only for comments (See below explanation at "gcontact-id")
*/
if ($arr['parent-uri'] != $arr['uri']) {
$arr["contact-id"] = get_contact($arr['author-link'], $uid);
$arr["contact-id"] = Contact::getIdForURL($arr['author-link'], $uid);
}
// If not present then maybe the owner was found
if ($arr["contact-id"] == 0) {
$arr["contact-id"] = get_contact($arr['owner-link'], $uid);
$arr["contact-id"] = Contact::getIdForURL($arr['owner-link'], $uid);
}
// Still missing? Then use the "self" contact of the current user
@ -745,28 +746,28 @@ function item_store($arr, $force_parent = false, $notify = false, $dontcache = f
* On comments the author is the better choice.
*/
if ($arr['parent-uri'] === $arr['uri']) {
$arr["gcontact-id"] = get_gcontact_id(array("url" => $arr['owner-link'], "network" => $arr['network'],
$arr["gcontact-id"] = GlobalContact::getId(array("url" => $arr['owner-link'], "network" => $arr['network'],
"photo" => $arr['owner-avatar'], "name" => $arr['owner-name']));
} else {
$arr["gcontact-id"] = get_gcontact_id(array("url" => $arr['author-link'], "network" => $arr['network'],
$arr["gcontact-id"] = GlobalContact::getId(array("url" => $arr['author-link'], "network" => $arr['network'],
"photo" => $arr['author-avatar'], "name" => $arr['author-name']));
}
}
if ($arr["author-id"] == 0) {
$arr["author-id"] = get_contact($arr["author-link"], 0);
$arr["author-id"] = Contact::getIdForURL($arr["author-link"], 0);
}
if (blockedContact($arr["author-id"])) {
if (Contact::isBlocked($arr["author-id"])) {
logger('Contact '.$arr["author-id"].' is blocked, item '.$arr["uri"].' will not be stored');
return 0;
}
if ($arr["owner-id"] == 0) {
$arr["owner-id"] = get_contact($arr["owner-link"], 0);
$arr["owner-id"] = Contact::getIdForURL($arr["owner-link"], 0);
}
if (blockedContact($arr["owner-id"])) {
if (Contact::isBlocked($arr["owner-id"])) {
logger('Contact '.$arr["owner-id"].' is blocked, item '.$arr["uri"].' will not be stored');
return 0;
}
@ -1138,7 +1139,7 @@ function item_store($arr, $force_parent = false, $notify = false, $dontcache = f
check_item_notification($current_post, $uid);
if ($notify) {
Worker::add(array('priority' => PRIORITY_HIGH, 'dont_fork' => true), "notifier", $notify_type, $current_post);
Worker::add(array('priority' => PRIORITY_HIGH, 'dont_fork' => true), "Notifier", $notify_type, $current_post);
}
return $current_post;
@ -1421,7 +1422,7 @@ function tag_deliver($uid, $item_id) {
);
update_thread($item_id);
Worker::add(array('priority' => PRIORITY_HIGH, 'dont_fork' => true), 'notifier', 'tgroup', $item_id);
Worker::add(array('priority' => PRIORITY_HIGH, 'dont_fork' => true), 'Notifier', 'tgroup', $item_id);
}
@ -1532,7 +1533,7 @@ function consume_feed($xml, $importer, &$contact, &$hub, $datedir = 0, $pass = 0
//$tempfile = tempnam(get_temppath(), "ostatus2");
//file_put_contents($tempfile, $xml);
logger("Consume OStatus messages ", LOGGER_DEBUG);
ostatus::import($xml, $importer, $contact, $hub);
OStatus::import($xml, $importer, $contact, $hub);
}
return;
}
@ -1750,7 +1751,7 @@ function lose_follower($importer, $contact, array $datarray = array(), $item = "
if (($contact['rel'] == CONTACT_IS_FRIEND) || ($contact['rel'] == CONTACT_IS_SHARING)) {
dba::update('contact', array('rel' => CONTACT_IS_SHARING), array('id' => $contact['id']));
} else {
contact_remove($contact['id']);
Contact::remove($contact['id']);
}
}
@ -1759,7 +1760,7 @@ function lose_sharer($importer, $contact, array $datarray = array(), $item = "")
if (($contact['rel'] == CONTACT_IS_FRIEND) || ($contact['rel'] == CONTACT_IS_FOLLOWER)) {
dba::update('contact', array('rel' => CONTACT_IS_FOLLOWER), array('id' => $contact['id']));
} else {
contact_remove($contact['id']);
Contact::remove($contact['id']);
}
}
@ -2055,7 +2056,7 @@ function item_expire($uid, $days, $network = "", $force = false) {
drop_item($item['id'], false);
}
Worker::add(array('priority' => PRIORITY_LOW, 'dont_fork' => true), "notifier", "expire", $uid);
Worker::add(array('priority' => PRIORITY_LOW, 'dont_fork' => true), "Notifier", "expire", $uid);
}
/// @TODO type-hint is array
@ -2077,7 +2078,7 @@ function drop_items($items) {
// multiple threads may have been deleted, send an expire notification
if ($uid) {
Worker::add(array('priority' => PRIORITY_LOW, 'dont_fork' => true), "notifier", "expire", $uid);
Worker::add(array('priority' => PRIORITY_LOW, 'dont_fork' => true), "Notifier", "expire", $uid);
}
}
@ -2122,7 +2123,7 @@ function drop_item($id, $interactive = true) {
}
if ((local_user() == $item['uid']) || ($contact_id) || (! $interactive)) {
if ((local_user() == $item['uid']) || $contact_id || !$interactive) {
// Check if we should do HTML-based delete confirmation
if ($_REQUEST['confirm']) {
@ -2189,30 +2190,18 @@ function drop_item($id, $interactive = true) {
* generate a resource-id and therefore aren't intimately linked to the item.
*/
if (strlen($item['resource-id'])) {
q("DELETE FROM `photo` WHERE `resource-id` = '%s' AND `uid` = %d ",
dbesc($item['resource-id']),
intval($item['uid'])
);
// ignore the result
dba::delete('photo', array('resource-id' => $item['resource-id'], 'uid' => $item['uid']));
}
// If item is a link to an event, nuke the event record.
if (intval($item['event-id'])) {
q("DELETE FROM `event` WHERE `id` = %d AND `uid` = %d",
intval($item['event-id']),
intval($item['uid'])
);
// ignore the result
dba::delete('event', array('id' => $item['event-id'], 'uid' => $item['uid']));
}
// If item has attachments, drop them
foreach (explode(", ", $item['attach']) as $attach) {
preg_match("|attach/(\d+)|", $attach, $matches);
q("DELETE FROM `attach` WHERE `id` = %d AND `uid` = %d",
intval($matches[1]),
local_user()
);
// ignore the result
dba::delete('attach', array('id' => $matches[1], 'uid' => $item['uid']));
}
// The new code splits the queries since the mysql optimizer really has bad problems with subqueries
@ -2269,7 +2258,7 @@ function drop_item($id, $interactive = true) {
$drop_id = intval($item['id']);
$priority = ($interactive ? PRIORITY_HIGH : PRIORITY_LOW);
Worker::add(array('priority' => $priority, 'dont_fork' => true), "notifier", "drop", $drop_id);
Worker::add(array('priority' => $priority, 'dont_fork' => true), "Notifier", "drop", $drop_id);
if (! $interactive) {
return $owner;

View File

@ -4,6 +4,7 @@ use Friendica\App;
use Friendica\Core\System;
use Friendica\Core\Worker;
use Friendica\Database\DBM;
use Friendica\Object\Contact;
use Friendica\Protocol\Diaspora;
/**
@ -115,7 +116,7 @@ function do_like($item_id, $verb) {
$item_contact_id = $owner_self_contact['id'];
$item_contact = $owner_self_contact;
} else {
$item_contact_id = get_contact($author_contact['url'], $item['uid']);
$item_contact_id = Contact::getIdForURL($author_contact['url'], $item['uid']);
$contacts = q("SELECT * FROM `contact` WHERE `id` = %d",
intval($item_contact_id)
@ -162,12 +163,10 @@ function do_like($item_id, $verb) {
// Clean up the Diaspora signatures for this like
// Go ahead and do it even if Diaspora support is disabled. We still want to clean up
// if it had been enabled in the past
q("DELETE FROM `sign` WHERE `iid` = %d",
intval($like_item['id'])
);
dba::delete('sign', array('iid' => $like_item['id']));
$like_item_id = $like_item['id'];
Worker::add(PRIORITY_HIGH, "notifier", "like", $like_item_id);
Worker::add(PRIORITY_HIGH, "Notifier", "like", $like_item_id);
if (!$event_verb_flag || $like_item['verb'] == $activity) {
return true;
@ -248,13 +247,13 @@ EOT;
}
// Save the author information for the like in case we need to relay to Diaspora
Diaspora::store_like_signature($item_contact, $new_item_id);
Diaspora::storeLikeSignature($item_contact, $new_item_id);
$new_item['id'] = $new_item_id;
call_hooks('post_local_end', $new_item);
Worker::add(PRIORITY_HIGH, "notifier", "like", $new_item_id);
Worker::add(PRIORITY_HIGH, "Notifier", "like", $new_item_id);
return true;
}

View File

@ -145,7 +145,7 @@ function send_message($recipient=0, $body='', $subject='', $replyto=''){
}
if ($post_id) {
Worker::add(PRIORITY_HIGH, "notifier", "mail", $post_id);
Worker::add(PRIORITY_HIGH, "Notifier", "mail", $post_id);
return intval($post_id);
} else {
return -3;

View File

@ -414,7 +414,7 @@ function xml_status($st, $message = '')
$xmldata = array("result" => $result);
echo XML::from_array($xmldata, $xml);
echo XML::fromArray($xmldata, $xml);
killme();
}

View File

@ -1,617 +0,0 @@
<?php
use Friendica\App;
use Friendica\Core\Config;
use Friendica\Core\Worker;
use Friendica\Database\DBM;
use Friendica\Network\Probe;
use Friendica\Protocol\Diaspora;
require_once 'include/queue_fn.php';
require_once 'include/html2plain.php';
require_once 'include/ostatus.php';
require_once 'include/salmon.php';
/*
* This file was at one time responsible for doing all deliveries, but this caused
* big problems when the process was killed or stalled during the delivery process.
* It now invokes separate queues that are delivering via delivery.php and pubsubpublish.php.
*/
/*
* The notifier is typically called with:
*
* Worker::add(PRIORITY_HIGH, "notifier", COMMAND, ITEM_ID);
*
* where COMMAND is one of the following:
*
* activity (in diaspora.php, dfrn_confirm.php, profiles.php)
* comment-import (in diaspora.php, items.php)
* comment-new (in item.php)
* drop (in diaspora.php, items.php, photos.php)
* edit_post (in item.php)
* event (in events.php)
* expire (in items.php)
* like (in like.php, poke.php)
* mail (in message.php)
* suggest (in fsuggest.php)
* tag (in photos.php, poke.php, tagger.php)
* tgroup (in items.php)
* wall-new (in photos.php, item.php)
* removeme (in Contact.php)
* relocate (in uimport.php)
*
* and ITEM_ID is the id of the item in the database that needs to be sent to others.
*/
function notifier_run(&$argv, &$argc){
global $a;
require_once 'include/datetime.php';
require_once 'include/items.php';
require_once 'include/bbcode.php';
require_once 'include/email.php';
if ($argc < 3) {
return;
}
logger('notifier: invoked: ' . print_r($argv,true), LOGGER_DEBUG);
$cmd = $argv[1];
switch($cmd) {
case 'mail':
default:
$item_id = intval($argv[2]);
if (! $item_id) {
return;
}
break;
}
$expire = false;
$mail = false;
$fsuggest = false;
$relocate = false;
$top_level = false;
$recipients = array();
$url_recipients = array();
$normal_mode = true;
if ($cmd === 'mail') {
$normal_mode = false;
$mail = true;
$message = q("SELECT * FROM `mail` WHERE `id` = %d LIMIT 1",
intval($item_id)
);
if (! count($message)) {
return;
}
$uid = $message[0]['uid'];
$recipients[] = $message[0]['contact-id'];
$item = $message[0];
} elseif ($cmd === 'expire') {
$normal_mode = false;
$expire = true;
$items = q("SELECT * FROM `item` WHERE `uid` = %d AND `wall` = 1
AND `deleted` = 1 AND `changed` > UTC_TIMESTAMP() - INTERVAL 10 MINUTE",
intval($item_id)
);
$uid = $item_id;
$item_id = 0;
if (! count($items)) {
return;
}
} elseif ($cmd === 'suggest') {
$normal_mode = false;
$fsuggest = true;
$suggest = q("SELECT * FROM `fsuggest` WHERE `id` = %d LIMIT 1",
intval($item_id)
);
if (! count($suggest)) {
return;
}
$uid = $suggest[0]['uid'];
$recipients[] = $suggest[0]['cid'];
$item = $suggest[0];
} elseif ($cmd === 'removeme') {
$r = q("SELECT `contact`.*, `user`.`pubkey` AS `upubkey`, `user`.`prvkey` AS `uprvkey`,
`user`.`timezone`, `user`.`nickname`, `user`.`sprvkey`, `user`.`spubkey`,
`user`.`page-flags`, `user`.`prvnets`, `user`.`account-type`, `user`.`guid`
FROM `contact` INNER JOIN `user` ON `user`.`uid` = `contact`.`uid`
WHERE `contact`.`uid` = %d AND `contact`.`self` LIMIT 1",
intval($item_id));
if (!$r)
return;
$user = $r[0];
$r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` LIMIT 1", intval($item_id));
if (!$r)
return;
$self = $r[0];
$r = q("SELECT * FROM `contact` WHERE NOT `self` AND `uid` = %d", intval($item_id));
if (!$r) {
return;
}
require_once 'include/Contact.php';
foreach ($r as $contact) {
terminate_friendship($user, $self, $contact);
}
return;
} elseif ($cmd === 'relocate') {
$normal_mode = false;
$relocate = true;
$uid = $item_id;
$recipients_relocate = q("SELECT * FROM `contact` WHERE `uid` = %d AND NOT `self` AND `network` IN ('%s', '%s')",
intval($uid), NETWORK_DFRN, NETWORK_DIASPORA);
} else {
// find ancestors
$r = q("SELECT * FROM `item` WHERE `id` = %d AND visible = 1 AND moderated = 0 LIMIT 1",
intval($item_id)
);
if ((! DBM::is_result($r)) || (! intval($r[0]['parent']))) {
return;
}
$target_item = $r[0];
$parent_id = intval($r[0]['parent']);
$uid = $r[0]['uid'];
$updated = $r[0]['edited'];
$items = q("SELECT `item`.*, `sign`.`signed_text`,`sign`.`signature`,`sign`.`signer`
FROM `item` LEFT JOIN `sign` ON `sign`.`iid` = `item`.`id` WHERE `parent` = %d AND visible = 1 AND moderated = 0 ORDER BY `id` ASC",
intval($parent_id)
);
if (! count($items)) {
return;
}
// avoid race condition with deleting entries
if ($items[0]['deleted']) {
foreach ($items as $item) {
$item['deleted'] = 1;
}
}
if ((count($items) == 1) && ($items[0]['id'] === $target_item['id']) && ($items[0]['uri'] === $items[0]['parent-uri'])) {
logger('notifier: top level post');
$top_level = true;
}
}
$r = q("SELECT `contact`.*, `user`.`pubkey` AS `upubkey`, `user`.`prvkey` AS `uprvkey`,
`user`.`timezone`, `user`.`nickname`, `user`.`sprvkey`, `user`.`spubkey`,
`user`.`page-flags`, `user`.`prvnets`, `user`.`account-type`
FROM `contact` INNER JOIN `user` ON `user`.`uid` = `contact`.`uid`
WHERE `contact`.`uid` = %d AND `contact`.`self` = 1 LIMIT 1",
intval($uid)
);
if (! DBM::is_result($r)) {
return;
}
$owner = $r[0];
$walltowall = ((($top_level) && ($owner['id'] != $items[0]['contact-id'])) ? true : false);
// Should the post be transmitted to Diaspora?
$diaspora_delivery = true;
// If this is a public conversation, notify the feed hub
$public_message = true;
// Do a PuSH
$push_notify = false;
// Deliver directly to a forum, don't PuSH
$direct_forum_delivery = false;
// fill this in with a single salmon slap if applicable
$slap = '';
if (! ($mail || $fsuggest || $relocate)) {
$slap = ostatus::salmon($target_item,$owner);
require_once 'include/group.php';
$parent = $items[0];
$thr_parent = q("SELECT `network`, `author-link`, `owner-link` FROM `item` WHERE `uri` = '%s' AND `uid` = %d",
dbesc($target_item["thr-parent"]), intval($target_item["uid"]));
logger('GUID: '.$target_item["guid"].': Parent is '.$parent['network'].'. Thread parent is '.$thr_parent[0]['network'], LOGGER_DEBUG);
// This is IMPORTANT!!!!
// We will only send a "notify owner to relay" or followup message if the referenced post
// originated on our system by virtue of having our hostname somewhere
// in the URI, AND it was a comment (not top_level) AND the parent originated elsewhere.
// if $parent['wall'] == 1 we will already have the parent message in our array
// and we will relay the whole lot.
// expire sends an entire group of expire messages and cannot be forwarded.
// However the conversation owner will be a part of the conversation and will
// be notified during this run.
// Other DFRN conversation members will be alerted during polled updates.
// Diaspora members currently are not notified of expirations, and other networks have
// either limited or no ability to process deletions. We should at least fix Diaspora
// by stringing togther an array of retractions and sending them onward.
$localhost = str_replace('www.','',$a->get_hostname());
if (strpos($localhost,':')) {
$localhost = substr($localhost,0,strpos($localhost,':'));
}
/**
*
* Be VERY CAREFUL if you make any changes to the following several lines. Seemingly innocuous changes
* have been known to cause runaway conditions which affected several servers, along with
* permissions issues.
*
*/
$relay_to_owner = false;
if (!$top_level && ($parent['wall'] == 0) && !$expire && (stristr($target_item['uri'],$localhost))) {
$relay_to_owner = true;
}
if (($cmd === 'uplink') && (intval($parent['forum_mode']) == 1) && !$top_level) {
$relay_to_owner = true;
}
// until the 'origin' flag has been in use for several months
// we will just use it as a fallback test
// later we will be able to use it as the primary test of whether or not to relay.
if (! $target_item['origin']) {
$relay_to_owner = false;
}
if ($parent['origin']) {
$relay_to_owner = false;
}
// Special treatment for forum posts
if (($target_item['author-link'] != $target_item['owner-link']) &&
($owner['id'] != $target_item['contact-id']) &&
($target_item['uri'] === $target_item['parent-uri'])) {
$fields = array('forum', 'prv');
$condition = array('id' => $target_item['contact-id']);
$contact = dba::select('contact', $fields, $condition, array('limit' => 1));
if (!DBM::is_result($contact)) {
// Should never happen
return false;
}
// Is the post from a forum?
if ($contact['forum'] || $contact['prv']) {
$relay_to_owner = true;
$direct_forum_delivery = true;
}
}
if ($relay_to_owner) {
logger('notifier: followup '.$target_item["guid"], LOGGER_DEBUG);
// local followup to remote post
$followup = true;
$public_message = false; // not public
$conversant_str = dbesc($parent['contact-id']);
$recipients = array($parent['contact-id']);
$recipients_followup = array($parent['contact-id']);
//if (!$target_item['private'] && $target_item['wall'] &&
if (!$target_item['private'] &&
(strlen($target_item['allow_cid'].$target_item['allow_gid'].
$target_item['deny_cid'].$target_item['deny_gid']) == 0))
$push_notify = true;
if (($thr_parent && ($thr_parent[0]['network'] == NETWORK_OSTATUS)) || ($parent['network'] == NETWORK_OSTATUS)) {
$push_notify = true;
if ($parent["network"] == NETWORK_OSTATUS) {
// Distribute the message to the DFRN contacts as if this wasn't a followup since OStatus can't relay comments
// Currently it is work at progress
$r = q("SELECT `id` FROM `contact` WHERE `uid` = %d AND `network` = '%s' AND NOT `blocked` AND NOT `pending` AND NOT `archive`",
intval($uid),
dbesc(NETWORK_DFRN)
);
if (DBM::is_result($r)) {
foreach ($r as $rr) {
$recipients_followup[] = $rr['id'];
}
}
}
}
if ($direct_forum_delivery) {
$push_notify = false;
}
logger("Notify ".$target_item["guid"]." via PuSH: ".($push_notify?"Yes":"No"), LOGGER_DEBUG);
} else {
$followup = false;
logger('Distributing directly '.$target_item["guid"], LOGGER_DEBUG);
// don't send deletions onward for other people's stuff
if ($target_item['deleted'] && (! intval($target_item['wall']))) {
logger('notifier: ignoring delete notification for non-wall item');
return;
}
if ((strlen($parent['allow_cid']))
|| (strlen($parent['allow_gid']))
|| (strlen($parent['deny_cid']))
|| (strlen($parent['deny_gid']))) {
$public_message = false; // private recipients, not public
}
$allow_people = expand_acl($parent['allow_cid']);
$allow_groups = expand_groups(expand_acl($parent['allow_gid']),true);
$deny_people = expand_acl($parent['deny_cid']);
$deny_groups = expand_groups(expand_acl($parent['deny_gid']));
// if our parent is a public forum (forum_mode == 1), uplink to the origional author causing
// a delivery fork. private groups (forum_mode == 2) do not uplink
if ((intval($parent['forum_mode']) == 1) && (! $top_level) && ($cmd !== 'uplink')) {
Worker::add($a->queue['priority'], 'notifier', 'uplink', $item_id);
}
$conversants = array();
foreach ($items as $item) {
$recipients[] = $item['contact-id'];
$conversants[] = $item['contact-id'];
// pull out additional tagged people to notify (if public message)
if ($public_message && strlen($item['inform'])) {
$people = explode(',',$item['inform']);
foreach ($people as $person) {
if (substr($person,0,4) === 'cid:') {
$recipients[] = intval(substr($person,4));
$conversants[] = intval(substr($person,4));
} else {
$url_recipients[] = substr($person,4);
}
}
}
}
if (count($url_recipients))
logger('notifier: '.$target_item["guid"].' url_recipients ' . print_r($url_recipients,true));
$conversants = array_unique($conversants);
$recipients = array_unique(array_merge($recipients,$allow_people,$allow_groups));
$deny = array_unique(array_merge($deny_people,$deny_groups));
$recipients = array_diff($recipients,$deny);
$conversant_str = dbesc(implode(', ',$conversants));
}
// If the thread parent is OStatus then do some magic to distribute the messages.
// We have not only to look at the parent, since it could be a Friendica thread.
if (($thr_parent && ($thr_parent[0]['network'] == NETWORK_OSTATUS)) || ($parent['network'] == NETWORK_OSTATUS)) {
$diaspora_delivery = false;
logger('Some parent is OStatus for '.$target_item["guid"]." - Author: ".$thr_parent[0]['author-link']." - Owner: ".$thr_parent[0]['owner-link'], LOGGER_DEBUG);
// Send a salmon to the parent author
$r = q("SELECT `url`, `notify` FROM `contact` WHERE `nurl`='%s' AND `uid` IN (0, %d) AND `notify` != ''",
dbesc(normalise_link($thr_parent[0]['author-link'])),
intval($uid));
if (DBM::is_result($r)) {
$probed_contact = $r[0];
} else {
$probed_contact = Probe::uri($thr_parent[0]['author-link']);
}
if ($probed_contact["notify"] != "") {
logger('Notify parent author '.$probed_contact["url"].': '.$probed_contact["notify"]);
$url_recipients[$probed_contact["notify"]] = $probed_contact["notify"];
}
// Send a salmon to the parent owner
$r = q("SELECT `url`, `notify` FROM `contact` WHERE `nurl`='%s' AND `uid` IN (0, %d) AND `notify` != ''",
dbesc(normalise_link($thr_parent[0]['owner-link'])),
intval($uid));
if (DBM::is_result($r)) {
$probed_contact = $r[0];
} else {
$probed_contact = Probe::uri($thr_parent[0]['owner-link']);
}
if ($probed_contact["notify"] != "") {
logger('Notify parent owner '.$probed_contact["url"].': '.$probed_contact["notify"]);
$url_recipients[$probed_contact["notify"]] = $probed_contact["notify"];
}
// Send a salmon notification to every person we mentioned in the post
$arr = explode(',',$target_item['tag']);
foreach ($arr as $x) {
//logger('Checking tag '.$x, LOGGER_DEBUG);
$matches = null;
if (preg_match('/@\[url=([^\]]*)\]/',$x,$matches)) {
$probed_contact = Probe::uri($matches[1]);
if ($probed_contact["notify"] != "") {
logger('Notify mentioned user '.$probed_contact["url"].': '.$probed_contact["notify"]);
$url_recipients[$probed_contact["notify"]] = $probed_contact["notify"];
}
}
}
// It only makes sense to distribute answers to OStatus messages to Friendica and OStatus - but not Diaspora
$sql_extra = " AND `network` IN ('".NETWORK_OSTATUS."', '".NETWORK_DFRN."')";
} else {
$sql_extra = " AND `network` IN ('".NETWORK_OSTATUS."', '".NETWORK_DFRN."', '".NETWORK_DIASPORA."', '".NETWORK_MAIL."', '".NETWORK_MAIL2."')";
}
} else {
$public_message = false;
}
// If this is a public message and pubmail is set on the parent, include all your email contacts
$mail_disabled = ((function_exists('imap_open') && (!Config::get('system','imap_disabled'))) ? 0 : 1);
if (! $mail_disabled) {
if ((! strlen($target_item['allow_cid'])) && (! strlen($target_item['allow_gid']))
&& (! strlen($target_item['deny_cid'])) && (! strlen($target_item['deny_gid']))
&& (intval($target_item['pubmail']))) {
$r = q("SELECT `id` FROM `contact` WHERE `uid` = %d AND `network` = '%s'",
intval($uid),
dbesc(NETWORK_MAIL)
);
if (DBM::is_result($r)) {
foreach ($r as $rr) {
$recipients[] = $rr['id'];
}
}
}
}
if ($followup) {
$recip_str = implode(', ', $recipients_followup);
} else {
$recip_str = implode(', ', $recipients);
}
if ($relocate) {
$r = $recipients_relocate;
} else {
$r = q("SELECT `id`, `url`, `network`, `self` FROM `contact`
WHERE `id` IN (%s) AND NOT `blocked` AND NOT `pending` AND NOT `archive`".$sql_extra,
dbesc($recip_str)
);
}
// delivery loop
if (DBM::is_result($r)) {
foreach ($r as $contact) {
if ($contact['self']) {
continue;
}
logger("Deliver ".$target_item["guid"]." to ".$contact['url']." via network ".$contact['network'], LOGGER_DEBUG);
Worker::add(array('priority' => $a->queue['priority'], 'created' => $a->queue['created'], 'dont_fork' => true),
'delivery', $cmd, $item_id, (int)$contact['id']);
}
}
// send salmon slaps to mentioned remote tags (@foo@example.com) in OStatus posts
// They are especially used for notifications to OStatus users that don't follow us.
if ($slap && count($url_recipients) && ($public_message || $push_notify) && $normal_mode) {
if (!Config::get('system','dfrn_only')) {
foreach ($url_recipients as $url) {
if ($url) {
logger('notifier: urldelivery: ' . $url);
$deliver_status = slapper($owner,$url,$slap);
/// @TODO Redeliver/queue these items on failure, though there is no contact record
}
}
}
}
if ($public_message) {
$r0 = array();
$r1 = array();
if ($diaspora_delivery) {
if (!$followup) {
$r0 = Diaspora::relay_list();
}
$r1 = q("SELECT `batch`, ANY_VALUE(`id`) AS `id`, ANY_VALUE(`name`) AS `name`, ANY_VALUE(`network`) AS `network`
FROM `contact` WHERE `network` = '%s' AND `batch` != ''
AND `uid` = %d AND `rel` != %d AND NOT `blocked` AND NOT `pending` AND NOT `archive` GROUP BY `batch`",
dbesc(NETWORK_DIASPORA),
intval($owner['uid']),
intval(CONTACT_IS_SHARING)
);
}
$r2 = q("SELECT `id`, `name`,`network` FROM `contact`
WHERE `network` in ('%s', '%s') AND `uid` = %d AND NOT `blocked` AND NOT `pending` AND NOT `archive` AND `rel` != %d",
dbesc(NETWORK_DFRN),
dbesc(NETWORK_MAIL2),
intval($owner['uid']),
intval(CONTACT_IS_SHARING)
);
$r = array_merge($r2,$r1,$r0);
if (DBM::is_result($r)) {
logger('pubdeliver '.$target_item["guid"].': '.print_r($r,true), LOGGER_DEBUG);
foreach ($r as $rr) {
// except for Diaspora batch jobs
// Don't deliver to folks who have already been delivered to
if (($rr['network'] !== NETWORK_DIASPORA) && (in_array($rr['id'],$conversants))) {
logger('notifier: already delivered id=' . $rr['id']);
continue;
}
if ((! $mail) && (! $fsuggest) && (! $followup)) {
logger('notifier: delivery agent: '.$rr['name'].' '.$rr['id'].' '.$rr['network'].' '.$target_item["guid"]);
Worker::add(array('priority' => $a->queue['priority'], 'created' => $a->queue['created'], 'dont_fork' => true),
'delivery', $cmd, $item_id, (int)$rr['id']);
}
}
}
$push_notify = true;
}
// Notify PuSH subscribers (Used for OStatus distribution of regular posts)
if ($push_notify) {
// Set push flag for PuSH subscribers to this topic,
// they will be notified in queue.php
q("UPDATE `push_subscriber` SET `push` = 1 ".
"WHERE `nickname` = '%s' AND `push` = 0", dbesc($owner['nickname']));
logger('Activating internal PuSH for item '.$item_id, LOGGER_DEBUG);
// Handling the pubsubhubbub requests
Worker::add(array('priority' => PRIORITY_HIGH, 'created' => $a->queue['created'], 'dont_fork' => true),
'pubsubpublish');
}
logger('notifier: calling hooks', LOGGER_DEBUG);
if ($normal_mode) {
call_hooks('notifier_normal',$target_item);
}
call_hooks('notifier_end',$target_item);
return;
}

View File

@ -113,7 +113,7 @@ class FKOAuthDataStore extends OAuthDataStore {
}
q("DELETE FROM tokens WHERE id='%s'", $token->key);
dba::delete('tokens', array('id' => $token->key));
if (!is_null($ret) && $uverifier!==false){
@ -182,93 +182,3 @@ class FKOAuth1 extends OAuthServer {
}
}
/*
class FKOAuth2 extends OAuth2 {
private function db_secret($client_secret){
return hash('whirlpool',$client_secret);
}
public function addClient($client_id, $client_secret, $redirect_uri) {
$client_secret = $this->db_secret($client_secret);
$r = q("INSERT INTO clients (client_id, pw, redirect_uri) VALUES ('%s', '%s', '%s')",
dbesc($client_id),
dbesc($client_secret),
dbesc($redirect_uri)
);
return $r;
}
protected function checkClientCredentials($client_id, $client_secret = NULL) {
$client_secret = $this->db_secret($client_secret);
$r = q("SELECT pw FROM clients WHERE client_id = '%s'",
dbesc($client_id));
if ($client_secret === NULL)
return $result !== FALSE;
return $result["client_secret"] == $client_secret;
}
protected function getRedirectUri($client_id) {
$r = q("SELECT redirect_uri FROM clients WHERE client_id = '%s'",
dbesc($client_id));
if ($r === FALSE)
return FALSE;
return isset($r[0]["redirect_uri"]) && $r[0]["redirect_uri"] ? $r[0]["redirect_uri"] : NULL;
}
protected function getAccessToken($oauth_token) {
$r = q("SELECT client_id, expires, scope FROM tokens WHERE id = '%s'",
dbesc($oauth_token));
if (DBM::is_result($r))
return $r[0];
return null;
}
protected function setAccessToken($oauth_token, $client_id, $expires, $scope = NULL) {
$r = q("INSERT INTO tokens (id, client_id, expires, scope) VALUES ('%s', '%s', %d, '%s')",
dbesc($oauth_token),
dbesc($client_id),
intval($expires),
dbesc($scope));
return $r;
}
protected function getSupportedGrantTypes() {
return array(
OAUTH2_GRANT_TYPE_AUTH_CODE,
);
}
protected function getAuthCode($code) {
$r = q("SELECT id, client_id, redirect_uri, expires, scope FROM auth_codes WHERE id = '%s'",
dbesc($code));
if (DBM::is_result($r))
return $r[0];
return null;
}
protected function setAuthCode($code, $client_id, $redirect_uri, $expires, $scope = NULL) {
$r = q("INSERT INTO auth_codes
(id, client_id, redirect_uri, expires, scope) VALUES
('%s', '%s', '%s', %d, '%s')",
dbesc($code),
dbesc($client_id),
dbesc($redirect_uri),
intval($expires),
dbesc($scope));
return $r;
}
}
*/

View File

@ -28,17 +28,17 @@ function oembed_replacecb($matches){
* @return bool|object Returns object with embed content or false if no embedable
* content exists
*/
function oembed_fetch_url($embedurl, $no_rich_type = false){
function oembed_fetch_url($embedurl, $no_rich_type = false) {
$embedurl = trim($embedurl, "'");
$embedurl = trim($embedurl, '"');
$a = get_app();
$r = q("SELECT * FROM `oembed` WHERE `url` = '%s'",
dbesc(normalise_link($embedurl)));
$condition = array('url' => normalise_link($embedurl));
$r = dba::select('oembed', array('content'), $condition, array('limit' => 1));
if (DBM::is_result($r)) {
$txt = $r[0]["content"];
$txt = $r["content"];
} else {
$txt = Cache::get($a->videowidth . $embedurl);
}

View File

@ -1,625 +0,0 @@
<?php
use Friendica\Core\Config;
use Friendica\Core\PConfig;
use Friendica\Database\DBM;
require_once 'include/follow.php';
function RemoveReply($subject) {
while (in_array(strtolower(substr($subject, 0, 3)), array("re:", "aw:"))) {
$subject = trim(substr($subject, 4));
}
return $subject;
}
function onepoll_run(&$argv, &$argc) {
global $a;
require_once 'include/datetime.php';
require_once 'include/items.php';
require_once 'include/Contact.php';
require_once 'include/email.php';
require_once 'include/socgraph.php';
require_once 'include/queue_fn.php';
logger('onepoll: start');
$manual_id = 0;
$generation = 0;
$hub_update = false;
$force = false;
$restart = false;
if (($argc > 1) && (intval($argv[1]))) {
$contact_id = intval($argv[1]);
}
if (($argc > 2) && ($argv[2] == "force")) {
$force = true;
}
if (!$contact_id) {
logger('onepoll: no contact');
return;
}
$d = datetime_convert();
// Only poll from those with suitable relationships,
// and which have a polling address and ignore Diaspora since
// we are unable to match those posts with a Diaspora GUID and prevent duplicates.
$contacts = q("SELECT `contact`.* FROM `contact`
WHERE (`rel` = %d OR `rel` = %d) AND `poll` != ''
AND NOT `network` IN ('%s', '%s')
AND `contact`.`id` = %d
AND `self` = 0 AND `contact`.`blocked` = 0 AND `contact`.`readonly` = 0
AND `contact`.`archive` = 0 LIMIT 1",
intval(CONTACT_IS_SHARING),
intval(CONTACT_IS_FRIEND),
dbesc(NETWORK_FACEBOOK),
dbesc(NETWORK_PUMPIO),
intval($contact_id)
);
if (!count($contacts)) {
logger('Contact not found or cannot be used.');
return;
}
$contact = $contacts[0];
$importer_uid = $contact['uid'];
// load current friends if possible.
if (($contact['poco'] != "") && ($contact['success_update'] > $contact['failure_update'])) {
$r = q("SELECT count(*) AS total FROM glink
WHERE `cid` = %d AND updated > UTC_TIMESTAMP() - INTERVAL 1 DAY",
intval($contact['id'])
);
if (DBM::is_result($r)) {
if (!$r[0]['total']) {
poco_load($contact['id'], $importer_uid, 0, $contact['poco']);
}
}
}
/// @TODO Check why we don't poll the Diaspora feed at the moment (some guid problem in the items?)
/// @TODO Check whether this is possible with Redmatrix
if ($contact["network"] == NETWORK_DIASPORA) {
if (poco_do_update($contact["created"], $contact["last-item"], $contact["failure_update"], $contact["success_update"])) {
$last_updated = poco_last_updated($contact["url"]);
$updated = datetime_convert();
if ($last_updated) {
$fields = array('last-item' => $last_updated, 'last-update' => $updated, 'success_update' => $updated);
dba::update('contact', $fields, array('id' => $contact['id']));
} else {
dba::update('contact', array('last-update' => $updated, 'failure_update' => $updated), array('id' => $contact['id']));
}
}
return;
}
$xml = false;
$t = $contact['last-update'];
if ($contact['subhub']) {
$poll_interval = Config::get('system', 'pushpoll_frequency');
$contact['priority'] = (($poll_interval !== false) ? intval($poll_interval) : 3);
$hub_update = false;
if (datetime_convert('UTC', 'UTC', 'now') > datetime_convert('UTC', 'UTC', $t . " + 1 day")) {
$hub_update = true;
}
} else {
$hub_update = false;
}
$last_update = (($contact['last-update'] <= NULL_DATE)
? datetime_convert('UTC', 'UTC', 'now - 7 days', ATOM_TIME)
: datetime_convert('UTC', 'UTC', $contact['last-update'], ATOM_TIME)
);
// Update the contact entry
if (($contact['network'] === NETWORK_OSTATUS) || ($contact['network'] === NETWORK_DIASPORA) || ($contact['network'] === NETWORK_DFRN)) {
if (!poco_reachable($contact['url'])) {
logger("Skipping probably dead contact ".$contact['url']);
return;
}
if (!update_contact($contact["id"])) {
mark_for_death($contact);
logger('Contact is marked dead');
return;
} else {
unmark_for_death($contact);
}
}
if ($importer_uid == 0) {
logger('Ignore public contacts');
return;
}
$r = q("SELECT `contact`.*, `user`.`page-flags` FROM `contact` INNER JOIN `user` on `contact`.`uid` = `user`.`uid` WHERE `user`.`uid` = %d AND `contact`.`self` = 1 LIMIT 1",
intval($importer_uid)
);
if (!DBM::is_result($r)) {
logger('No self contact for user '.$importer_uid);
return;
}
$importer = $r[0];
logger("onepoll: poll: ({$contact['id']}) IMPORTER: {$importer['name']}, CONTACT: {$contact['name']}");
if ($contact['network'] === NETWORK_DFRN) {
$idtosend = $orig_id = (($contact['dfrn-id']) ? $contact['dfrn-id'] : $contact['issued-id']);
if (intval($contact['duplex']) && $contact['dfrn-id']) {
$idtosend = '0:' . $orig_id;
}
if (intval($contact['duplex']) && $contact['issued-id']) {
$idtosend = '1:' . $orig_id;
}
// they have permission to write to us. We already filtered this in the contact query.
$perm = 'rw';
// But this may be our first communication, so set the writable flag if it isn't set already.
if (!intval($contact['writable'])) {
$fields = array('writable' => true);
dba::update('contact', $fields, array('id' => $contact['id']));
}
$url = $contact['poll'] . '?dfrn_id=' . $idtosend
. '&dfrn_version=' . DFRN_PROTOCOL_VERSION
. '&type=data&last_update=' . $last_update
. '&perm=' . $perm ;
$ret = z_fetch_url($url);
if ($ret['errno'] == CURLE_OPERATION_TIMEDOUT) {
return;
}
$handshake_xml = $ret['body'];
$html_code = $a->get_curl_code();
logger('onepoll: handshake with url ' . $url . ' returns xml: ' . $handshake_xml, LOGGER_DATA);
if (!strlen($handshake_xml) || ($html_code >= 400) || !$html_code) {
logger("poller: $url appears to be dead - marking for death ");
// dead connection - might be a transient event, or this might
// mean the software was uninstalled or the domain expired.
// Will keep trying for one month.
mark_for_death($contact);
// set the last-update so we don't keep polling
$fields = array('last-update' => datetime_convert(), 'failure_update' => datetime_convert());
dba::update('contact', $fields, array('id' => $contact['id']));
return;
}
if (! strstr($handshake_xml, '<')) {
logger('poller: response from ' . $url . ' did not contain XML.');
mark_for_death($contact);
$fields = array('last-update' => datetime_convert(), 'failure_update' => datetime_convert());
dba::update('contact', $fields, array('id' => $contact['id']));
return;
}
$res = parse_xml_string($handshake_xml);
if (intval($res->status) == 1) {
logger("poller: $url replied status 1 - marking for death ");
// we may not be friends anymore. Will keep trying for one month.
// set the last-update so we don't keep polling
$fields = array('last-update' => datetime_convert(), 'failure_update' => datetime_convert());
dba::update('contact', $fields, array('id' => $contact['id']));
mark_for_death($contact);
} elseif ($contact['term-date'] > NULL_DATE) {
logger("poller: $url back from the dead - removing mark for death");
unmark_for_death($contact);
}
if ((intval($res->status) != 0) || !strlen($res->challenge) || !strlen($res->dfrn_id)) {
return;
}
if (((float)$res->dfrn_version > 2.21) && ($contact['poco'] == '')) {
$fields = array('poco' => str_replace('/profile/', '/poco/', $contact['url']));
dba::update('contact', $fields, array('id' => $contact['id']));
}
$postvars = array();
$sent_dfrn_id = hex2bin((string) $res->dfrn_id);
$challenge = hex2bin((string) $res->challenge);
$final_dfrn_id = '';
if ($contact['duplex'] && strlen($contact['prvkey'])) {
openssl_private_decrypt($sent_dfrn_id, $final_dfrn_id, $contact['prvkey']);
openssl_private_decrypt($challenge, $postvars['challenge'], $contact['prvkey']);
} else {
openssl_public_decrypt($sent_dfrn_id, $final_dfrn_id, $contact['pubkey']);
openssl_public_decrypt($challenge, $postvars['challenge'], $contact['pubkey']);
}
$final_dfrn_id = substr($final_dfrn_id, 0, strpos($final_dfrn_id, '.'));
if (strpos($final_dfrn_id, ':') == 1) {
$final_dfrn_id = substr($final_dfrn_id, 2);
}
if ($final_dfrn_id != $orig_id) {
logger('poller: ID did not decode: ' . $contact['id'] . ' orig: ' . $orig_id . ' final: ' . $final_dfrn_id);
// did not decode properly - cannot trust this site
return;
}
$postvars['dfrn_id'] = $idtosend;
$postvars['dfrn_version'] = DFRN_PROTOCOL_VERSION;
$postvars['perm'] = 'rw';
$xml = post_url($contact['poll'], $postvars);
} elseif (($contact['network'] === NETWORK_OSTATUS)
|| ($contact['network'] === NETWORK_DIASPORA)
|| ($contact['network'] === NETWORK_FEED)) {
// Upgrading DB fields from an older Friendica version
// Will only do this once per notify-enabled OStatus contact
// or if relationship changes
$stat_writeable = ((($contact['notify']) && ($contact['rel'] == CONTACT_IS_FOLLOWER || $contact['rel'] == CONTACT_IS_FRIEND)) ? 1 : 0);
// Contacts from OStatus are always writable
if ($contact['network'] === NETWORK_OSTATUS) {
$stat_writeable = 1;
}
if ($stat_writeable != $contact['writable']) {
$fields = array('writable' => $stat_writeable);
dba::update('contact', $fields, array('id' => $contact['id']));
}
// Are we allowed to import from this person?
if ($contact['rel'] == CONTACT_IS_FOLLOWER || $contact['blocked'] || $contact['readonly']) {
return;
}
$cookiejar = tempnam(get_temppath(), 'cookiejar-onepoll-');
$ret = z_fetch_url($contact['poll'], false, $redirects, array('cookiejar' => $cookiejar));
if ($ret['errno'] == CURLE_OPERATION_TIMEDOUT) {
return;
}
$xml = $ret['body'];
unlink($cookiejar);
} elseif ($contact['network'] === NETWORK_MAIL || $contact['network'] === NETWORK_MAIL2) {
logger("Mail: Fetching for ".$contact['addr'], LOGGER_DEBUG);
$mail_disabled = ((function_exists('imap_open') && (! Config::get('system', 'imap_disabled'))) ? 0 : 1);
if ($mail_disabled) {
return;
}
logger("Mail: Enabled", LOGGER_DEBUG);
$mbox = null;
$x = dba::select('user', array('prvkey'), array('uid' => $importer_uid), array('limit' => 1));
$condition = array("`server` != '' AND `uid` = ?", $importer_uid);
$mailconf = dba::select('mailacct', array(), $condition, array('limit' => 1));
if (DBM::is_result($x) && DBM::is_result($mailconf)) {
$mailbox = construct_mailbox_name($mailconf);
$password = '';
openssl_private_decrypt(hex2bin($mailconf['pass']), $password, $x['prvkey']);
$mbox = email_connect($mailbox, $mailconf['user'], $password);
unset($password);
logger("Mail: Connect to " . $mailconf['user']);
if ($mbox) {
$fields = array('last_check' => datetime_convert());
dba::update('mailacct', $fields, array('id' => $mailconf['id']));
logger("Mail: Connected to " . $mailconf['user']);
} else {
logger("Mail: Connection error ".$mailconf['user']." ".print_r(imap_errors(), true));
}
}
if ($mbox) {
$msgs = email_poll($mbox, $contact['addr']);
if (count($msgs)) {
logger("Mail: Parsing ".count($msgs)." mails from ".$contact['addr']." for ".$mailconf['user'], LOGGER_DEBUG);
$metas = email_msg_meta($mbox,implode(',', $msgs));
if (count($metas) != count($msgs)) {
logger("onepoll: for " . $mailconf['user'] . " there are ". count($msgs) . " messages but received " . count($metas) . " metas", LOGGER_DEBUG);
} else {
$msgs = array_combine($msgs, $metas);
foreach ($msgs as $msg_uid => $meta) {
logger("Mail: Parsing mail ".$msg_uid, LOGGER_DATA);
$datarray = array();
$datarray['verb'] = ACTIVITY_POST;
$datarray['object-type'] = ACTIVITY_OBJ_NOTE;
// $meta = email_msg_meta($mbox, $msg_uid);
// $headers = email_msg_headers($mbox, $msg_uid);
$datarray['uri'] = msgid2iri(trim($meta->message_id, '<>'));
// Have we seen it before?
$fields = array('deleted', 'id');
$condition = array('uid' => $importer_uid, 'uri' => $datarray['uri']);
$r = dba::select('item', $fields, $condition, array('limit' => 1));
if (DBM::is_result($r)) {
logger("Mail: Seen before ".$msg_uid." for ".$mailconf['user']." UID: ".$importer_uid." URI: ".$datarray['uri'],LOGGER_DEBUG);
// Only delete when mails aren't automatically moved or deleted
if (($mailconf['action'] != 1) && ($mailconf['action'] != 3))
if ($meta->deleted && ! $r['deleted']) {
$fields = array('deleted' => true, 'changed' => datetime_convert());
dba::update('item', $fields, array('id' => $r['id']));
}
switch ($mailconf['action']) {
case 0:
logger("Mail: Seen before ".$msg_uid." for ".$mailconf['user'].". Doing nothing.", LOGGER_DEBUG);
break;
case 1:
logger("Mail: Deleting ".$msg_uid." for ".$mailconf['user']);
imap_delete($mbox, $msg_uid, FT_UID);
break;
case 2:
logger("Mail: Mark as seen ".$msg_uid." for ".$mailconf['user']);
imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID);
break;
case 3:
logger("Mail: Moving ".$msg_uid." to ".$mailconf['movetofolder']." for ".$mailconf['user']);
imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID);
if ($mailconf['movetofolder'] != "") {
imap_mail_move($mbox, $msg_uid, $mailconf['movetofolder'], FT_UID);
}
break;
}
continue;
}
// look for a 'references' or an 'in-reply-to' header and try to match with a parent item we have locally.
$raw_refs = ((property_exists($meta, 'references')) ? str_replace("\t", '', $meta->references) : '');
if (! trim($raw_refs)) {
$raw_refs = ((property_exists($meta, 'in_reply_to')) ? str_replace("\t", '', $meta->in_reply_to) : '');
}
$raw_refs = trim($raw_refs); // Don't allow a blank reference in $refs_arr
if ($raw_refs) {
$refs_arr = explode(' ', $raw_refs);
if (count($refs_arr)) {
for ($x = 0; $x < count($refs_arr); $x ++) {
$refs_arr[$x] = "'" . msgid2iri(str_replace(array('<', '>', ' '),array('', '', ''),dbesc($refs_arr[$x]))) . "'";
}
}
$qstr = implode(',', $refs_arr);
$r = q("SELECT `parent-uri` FROM `item` USE INDEX (`uid_uri`) WHERE `uri` IN ($qstr) AND `uid` = %d LIMIT 1",
intval($importer_uid)
);
if (DBM::is_result($r)) {
$datarray['parent-uri'] = $r[0]['parent-uri']; // Set the parent as the top-level item
}
}
// Decoding the header
$subject = imap_mime_header_decode($meta->subject);
$datarray['title'] = "";
foreach ($subject as $subpart) {
if ($subpart->charset != "default") {
$datarray['title'] .= iconv($subpart->charset, 'UTF-8//IGNORE', $subpart->text);
} else {
$datarray['title'] .= $subpart->text;
}
}
$datarray['title'] = notags(trim($datarray['title']));
//$datarray['title'] = notags(trim($meta->subject));
$datarray['created'] = datetime_convert('UTC', 'UTC', $meta->date);
// Is it a reply?
$reply = ((substr(strtolower($datarray['title']), 0, 3) == "re:") ||
(substr(strtolower($datarray['title']), 0, 3) == "re-") ||
($raw_refs != ""));
// Remove Reply-signs in the subject
$datarray['title'] = RemoveReply($datarray['title']);
// If it seems to be a reply but a header couldn't be found take the last message with matching subject
if (empty($datarray['parent-uri']) && $reply) {
$r = q("SELECT `parent-uri` FROM `item` WHERE `title` = \"%s\" AND `uid` = %d AND `network` = '%s' ORDER BY `created` DESC LIMIT 1",
dbesc(protect_sprintf($datarray['title'])),
intval($importer_uid),
dbesc(NETWORK_MAIL));
if (DBM::is_result($r)) {
$datarray['parent-uri'] = $r[0]['parent-uri'];
}
}
if (empty($datarray['parent-uri'])) {
$datarray['parent-uri'] = $datarray['uri'];
}
$r = email_get_msg($mbox, $msg_uid, $reply);
if (!$r) {
logger("Mail: can't fetch msg ".$msg_uid." for ".$mailconf['user']);
continue;
}
$datarray['body'] = escape_tags($r['body']);
$datarray['body'] = limit_body_size($datarray['body']);
logger("Mail: Importing ".$msg_uid." for ".$mailconf['user']);
/// @TODO Adding a gravatar for the original author would be cool
$from = imap_mime_header_decode($meta->from);
$fromdecoded = "";
foreach ($from as $frompart) {
if ($frompart->charset != "default") {
$fromdecoded .= iconv($frompart->charset, 'UTF-8//IGNORE', $frompart->text);
} else {
$fromdecoded .= $frompart->text;
}
}
$fromarr = imap_rfc822_parse_adrlist($fromdecoded, $a->get_hostname());
$frommail = $fromarr[0]->mailbox."@".$fromarr[0]->host;
if (isset($fromarr[0]->personal)) {
$fromname = $fromarr[0]->personal;
} else {
$fromname = $frommail;
}
$datarray['author-name'] = $fromname;
$datarray['author-link'] = "mailto:".$frommail;
$datarray['author-avatar'] = $contact['photo'];
$datarray['owner-name'] = $contact['name'];
$datarray['owner-link'] = "mailto:".$contact['addr'];
$datarray['owner-avatar'] = $contact['photo'];
$datarray['uid'] = $importer_uid;
$datarray['contact-id'] = $contact['id'];
if ($datarray['parent-uri'] === $datarray['uri']) {
$datarray['private'] = 1;
}
if (($contact['network'] === NETWORK_MAIL) && (!PConfig::get($importer_uid, 'system', 'allow_public_email_replies'))) {
$datarray['private'] = 1;
$datarray['allow_cid'] = '<' . $contact['id'] . '>';
}
$stored_item = item_store($datarray);
$condition = array('parent-uri' => $datarray['parent-uri'], 'uid' => $importer_uid);
dba::update('item', array('last-child' => false), $condition);
dba::update('item', array('last-child' => true), array('id' => $stored_item));
switch ($mailconf['action']) {
case 0:
logger("Mail: Seen before ".$msg_uid." for ".$mailconf['user'].". Doing nothing.", LOGGER_DEBUG);
break;
case 1:
logger("Mail: Deleting ".$msg_uid." for ".$mailconf['user']);
imap_delete($mbox, $msg_uid, FT_UID);
break;
case 2:
logger("Mail: Mark as seen ".$msg_uid." for ".$mailconf['user']);
imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID);
break;
case 3:
logger("Mail: Moving ".$msg_uid." to ".$mailconf['movetofolder']." for ".$mailconf['user']);
imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID);
if ($mailconf['movetofolder'] != "") {
imap_mail_move($mbox, $msg_uid, $mailconf['movetofolder'], FT_UID);
}
break;
}
}
}
} else {
logger("Mail: no mails for ".$mailconf['user']);
}
logger("Mail: closing connection for ".$mailconf['user']);
imap_close($mbox);
}
}
if ($xml) {
logger('poller: received xml : ' . $xml, LOGGER_DATA);
if (!strstr($xml, '<')) {
logger('poller: post_handshake: response from ' . $url . ' did not contain XML.');
$fields = array('last-update' => datetime_convert(), 'failure_update' => datetime_convert());
dba::update('contact', $fields, array('id' => $contact['id']));
return;
}
logger("Consume feed of contact ".$contact['id']);
consume_feed($xml, $importer, $contact, $hub, 1, 1);
// do it twice. Ensures that children of parents which may be later in the stream aren't tossed
consume_feed($xml, $importer, $contact, $hub, 1, 2);
$hubmode = 'subscribe';
if ($contact['network'] === NETWORK_DFRN || $contact['blocked'] || $contact['readonly']) {
$hubmode = 'unsubscribe';
}
if (($contact['network'] === NETWORK_OSTATUS || $contact['network'] == NETWORK_FEED) && (! $contact['hub-verify'])) {
$hub_update = true;
}
if ($force) {
$hub_update = true;
}
logger("Contact ".$contact['id']." returned hub: ".$hub." Network: ".$contact['network']." Relation: ".$contact['rel']." Update: ".$hub_update);
if (strlen($hub) && $hub_update && (($contact['rel'] != CONTACT_IS_FOLLOWER) || $contact['network'] == NETWORK_FEED)) {
logger('poller: hub ' . $hubmode . ' : ' . $hub . ' contact name : ' . $contact['name'] . ' local user : ' . $importer['name']);
$hubs = explode(',', $hub);
if (count($hubs)) {
foreach ($hubs as $h) {
$h = trim($h);
if (!strlen($h)) {
continue;
}
subscribe_to_hub($h, $importer, $contact, $hubmode);
}
}
}
$updated = datetime_convert();
dba::update('contact', array('last-update' => $updated, 'success_update' => $updated), array('id' => $contact['id']));
dba::update('gcontact', array('last_contact' => $updated), array('nurl' => $contact['nurl']));
} elseif (in_array($contact["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, NETWORK_FEED))) {
$updated = datetime_convert();
dba::update('contact', array('last-update' => $updated, 'failure_update' => $updated), array('id' => $contact['id']));
dba::update('gcontact', array('last_failure' => $updated), array('nurl' => $contact['nurl']));
} else {
dba::update('contact', array('last-update' => $updated), array('id' => $contact['id']));
}
return;
}

View File

@ -16,19 +16,16 @@ use Friendica\Database\DBM;
* @param string $plugin name of the addon
* @return boolean
*/
if (! function_exists('uninstall_plugin')){
function uninstall_plugin($plugin){
function uninstall_plugin($plugin) {
logger("Addons: uninstalling " . $plugin);
q("DELETE FROM `addon` WHERE `name` = '%s' ",
dbesc($plugin)
);
dba::delete('addon', array('name' => $plugin));
@include_once('addon/' . $plugin . '/' . $plugin . '.php');
if (function_exists($plugin . '_uninstall')) {
$func = $plugin . '_uninstall';
$func();
}
}}
}
/**
* @brief installs an addon.
@ -36,12 +33,12 @@ function uninstall_plugin($plugin){
* @param string $plugin name of the addon
* @return bool
*/
if (! function_exists('install_plugin')){
function install_plugin($plugin) {
// silently fail if plugin was removed
if (! file_exists('addon/' . $plugin . '/' . $plugin . '.php'))
if (!file_exists('addon/' . $plugin . '/' . $plugin . '.php')) {
return false;
}
logger("Addons: installing " . $plugin);
$t = @filemtime('addon/' . $plugin . '/' . $plugin . '.php');
@include_once('addon/' . $plugin . '/' . $plugin . '.php');
@ -62,26 +59,24 @@ function install_plugin($plugin) {
dba::update('addon', array('hidden' => true), array('name' => $plugin));
}
return true;
}
else {
} else {
logger("Addons: FAILED installing " . $plugin);
return false;
}
}}
}
// reload all updated plugins
if (! function_exists('reload_plugins')) {
function reload_plugins() {
$plugins = Config::get('system','addon');
$plugins = Config::get('system', 'addon');
if (strlen($plugins)) {
$r = q("SELECT * FROM `addon` WHERE `installed` = 1");
if (DBM::is_result($r))
if (DBM::is_result($r)) {
$installed = $r;
else
} else {
$installed = array();
}
$parr = explode(',',$plugins);
@ -115,7 +110,7 @@ function reload_plugins() {
}
}
}}
}
/**
* @brief check if addon is enabled
@ -137,21 +132,17 @@ function plugin_enabled($plugin) {
* @param int $priority A priority (defaults to 0)
* @return mixed|bool
*/
if (! function_exists('register_hook')) {
function register_hook($hook,$file,$function,$priority=0) {
$r = q("SELECT * FROM `hook` WHERE `hook` = '%s' AND `file` = '%s' AND `function` = '%s' LIMIT 1",
dbesc($hook),
dbesc($file),
dbesc($function)
);
if (DBM::is_result($r))
function register_hook($hook, $file, $function, $priority=0) {
$condition = array('hook' => $hook, 'file' => $file, 'function' => $function);
$exists = dba::exists('hook', $condition);
if ($exists) {
return true;
}
$r = dba::insert('hook', array('hook' => $hook, 'file' => $file, 'function' => $function, 'priority' => $priority));
return $r;
}}
}
/**
* @brief unregisters a hook.
@ -161,16 +152,11 @@ function register_hook($hook,$file,$function,$priority=0) {
* @param string $function the name of the function that the hook called
* @return array
*/
if (! function_exists('unregister_hook')) {
function unregister_hook($hook,$file,$function) {
$r = q("DELETE FROM `hook` WHERE `hook` = '%s' AND `file` = '%s' AND `function` = '%s'",
dbesc($hook),
dbesc($file),
dbesc($function)
);
function unregister_hook($hook, $file, $function) {
$condition = array('hook' => $hook, 'file' => $file, 'function' => $function);
$r = dba::delete('hook', $condition);
return $r;
}}
}
function load_hooks() {
@ -224,17 +210,13 @@ function call_single_hook($a, $name, $hook, &$data = null) {
$func($a, $data);
} else {
// remove orphan hooks
q("DELETE FROM `hook` WHERE `hook` = '%s' AND `file` = '%s' AND `function` = '%s'",
dbesc($name),
dbesc($hook[0]),
dbesc($hook[1])
);
$condition = array('hook' => $name, 'file' => $hook[0], 'function' => $hook[1]);
dba::delete('hook', $condition);
}
}
//check if an app_menu hook exist for plugin $name.
//Return true if the plugin is an app
if (! function_exists('plugin_is_app')) {
function plugin_is_app($name) {
$a = get_app();
@ -246,7 +228,7 @@ function plugin_is_app($name) {
}
return false;
}}
}
/**
* @brief Parse plugin comment in search of plugin infos.
@ -264,8 +246,7 @@ function plugin_is_app($name) {
* @return array with the plugin information
*/
if (! function_exists('get_plugin_info')){
function get_plugin_info($plugin){
function get_plugin_info($plugin) {
$a = get_app();
@ -285,14 +266,14 @@ function get_plugin_info($plugin){
$r = preg_match("|/\*.*\*/|msU", $f, $m);
if ($r){
if ($r) {
$ll = explode("\n", $m[0]);
foreach ( $ll as $l ) {
$l = trim($l,"\t\n\r */");
if ($l!=""){
if ($l != "") {
list($k,$v) = array_map("trim", explode(":",$l,2));
$k= strtolower($k);
if ($k=="author"){
if ($k == "author") {
$r=preg_match("|([^<]+)<([^>]+)>|", $v, $m);
if ($r) {
$info['author'][] = array('name'=>$m[1], 'link'=>$m[2]);
@ -300,7 +281,7 @@ function get_plugin_info($plugin){
$info['author'][] = array('name'=>$v);
}
} else {
if (array_key_exists($k,$info)){
if (array_key_exists($k,$info)) {
$info[$k]=$v;
}
}
@ -310,7 +291,7 @@ function get_plugin_info($plugin){
}
return $info;
}}
}
/**
@ -329,8 +310,7 @@ function get_plugin_info($plugin){
* @return array
*/
if (! function_exists('get_theme_info')){
function get_theme_info($theme){
function get_theme_info($theme) {
$info=Array(
'name' => $theme,
'description' => "",
@ -356,14 +336,14 @@ function get_theme_info($theme){
$r = preg_match("|/\*.*\*/|msU", $f, $m);
if ($r){
if ($r) {
$ll = explode("\n", $m[0]);
foreach ( $ll as $l ) {
$l = trim($l,"\t\n\r */");
if ($l!=""){
if ($l != "") {
list($k,$v) = array_map("trim", explode(":",$l,2));
$k= strtolower($k);
if ($k=="author"){
if ($k == "author") {
$r=preg_match("|([^<]+)<([^>]+)>|", $v, $m);
if ($r) {
@ -371,8 +351,7 @@ function get_theme_info($theme){
} else {
$info['author'][] = array('name'=>$v);
}
}
elseif ($k=="maintainer"){
} elseif ($k == "maintainer") {
$r=preg_match("|([^<]+)<([^>]+)>|", $v, $m);
if ($r) {
$info['maintainer'][] = array('name'=>$m[1], 'link'=>$m[2]);
@ -380,7 +359,7 @@ function get_theme_info($theme){
$info['maintainer'][] = array('name'=>$v);
}
} else {
if (array_key_exists($k,$info)){
if (array_key_exists($k,$info)) {
$info[$k]=$v;
}
}
@ -390,7 +369,7 @@ function get_theme_info($theme){
}
return $info;
}}
}
/**
* @brief Returns the theme's screenshot.
@ -411,8 +390,7 @@ function get_theme_screenshot($theme) {
}
// install and uninstall theme
if (! function_exists('uninstall_theme')){
function uninstall_theme($theme){
function uninstall_theme($theme) {
logger("Addons: uninstalling theme " . $theme);
include_once("view/theme/$theme/theme.php");
@ -420,9 +398,8 @@ function uninstall_theme($theme){
$func = "{$theme}_uninstall";
$func();
}
}}
}
if (! function_exists('install_theme')){
function install_theme($theme) {
// silently fail if theme was removed
@ -443,7 +420,7 @@ function install_theme($theme) {
return false;
}
}}
}
/**
* @brief Get the full path to relevant theme files by filename

View File

@ -1,58 +0,0 @@
<?php
use Friendica\App;
use Friendica\Core\Worker;
use Friendica\Core\Config;
if (!file_exists("boot.php") && (sizeof($_SERVER["argv"]) != 0)) {
$directory = dirname($_SERVER["argv"][0]);
if (substr($directory, 0, 1) != "/") {
$directory = $_SERVER["PWD"]."/".$directory;
}
$directory = realpath($directory."/..");
chdir($directory);
}
require_once("boot.php");
function poller_run($argv, $argc) {
global $a;
if (empty($a)) {
$a = new App(dirname(__DIR__));
}
require_once ".htconfig.php";
require_once "include/dba.php";
dba::connect($db_host, $db_user, $db_pass, $db_data);
unset($db_host, $db_user, $db_pass, $db_data);
Config::load();
// Check the database structure and possibly fixes it
check_db(true);
// Quit when in maintenance
if (Config::get('system', 'maintenance', true)) {
return;
}
$a->set_baseurl(Config::get('system', 'url'));
load_hooks();
$run_cron = (($argc <= 1) || ($argv[1] != "no_cron"));
Worker::processQueue($run_cron);
return;
}
if (array_search(__file__, get_included_files()) === 0) {
poller_run($_SERVER["argv"], $_SERVER["argc"]);
Worker::unclaimProcess();
get_app()->end_process();
killme();
}

View File

@ -5,6 +5,8 @@
use Friendica\Core\Config;
use Friendica\Database\DBM;
use Friendica\Model\GlobalContact;
use Friendica\Object\Contact;
/**
* @brief Calls the post update functions
@ -72,7 +74,7 @@ function post_update_1192() {
// Set the "gcontact-id" in the item table and add a new gcontact entry if needed
foreach ($item_arr AS $item) {
$gcontact_id = get_gcontact_id(array("url" => $item['author-link'], "network" => $item['network'],
$gcontact_id = GlobalContact::getId(array("url" => $item['author-link'], "network" => $item['network'],
"photo" => $item['author-avatar'], "name" => $item['author-name']));
q("UPDATE `item` SET `gcontact-id` = %d WHERE `uid` = %d AND `author-link` = '%s' AND `gcontact-id` = 0",
intval($gcontact_id), intval($item["uid"]), dbesc($item["author-link"]));
@ -208,8 +210,8 @@ function post_update_1198() {
// Set the "gcontact-id" in the item table and add a new gcontact entry if needed
foreach ($item_arr AS $item) {
$author_id = get_contact($item["author-link"], 0);
$owner_id = get_contact($item["owner-link"], 0);
$author_id = Contact::getIdForURL($item["author-link"], 0);
$owner_id = Contact::getIdForURL($item["owner-link"], 0);
if ($author_id == 0)
$author_id = -1;

View File

@ -1,12 +0,0 @@
<?php
use Friendica\Protocol\Diaspora;
function profile_update_run(&$argv, &$argc) {
if ($argc != 2) {
return;
}
$uid = intval($argv[1]);
Diaspora::send_profile($uid);
}

View File

@ -1,91 +0,0 @@
<?php
use Friendica\App;
use Friendica\Core\System;
use Friendica\Core\Config;
use Friendica\Core\Worker;
use Friendica\Database\DBM;
require_once('include/items.php');
require_once('include/ostatus.php');
function pubsubpublish_run(&$argv, &$argc){
global $a;
if ($argc > 1) {
$pubsubpublish_id = intval($argv[1]);
} else {
// We'll push to each subscriber that has push > 0,
// i.e. there has been an update (set in notifier.php).
$r = q("SELECT `id`, `callback_url` FROM `push_subscriber` WHERE `push` > 0 ORDER BY `last_update` DESC");
foreach ($r as $rr) {
logger("Publish feed to ".$rr["callback_url"], LOGGER_DEBUG);
Worker::add(array('priority' => PRIORITY_HIGH, 'created' => $a->queue['created'], 'dont_fork' => true),
'pubsubpublish', (int)$rr["id"]);
}
}
handle_pubsubhubbub($pubsubpublish_id);
return;
}
function handle_pubsubhubbub($id) {
global $a;
$r = q("SELECT * FROM `push_subscriber` WHERE `id` = %d", intval($id));
if (!DBM::is_result($r)) {
return;
}
$rr = $r[0];
/// @todo Check server status with poco_check_server()
// Before this can be done we need a way to safely detect the server url.
logger("Generate feed of user ".$rr['nickname']." to ".$rr['callback_url']." - last updated ".$rr['last_update'], LOGGER_DEBUG);
$last_update = $rr['last_update'];
$params = ostatus::feed($a, $rr['nickname'], $last_update);
if (!$params) {
return;
}
$hmac_sig = hash_hmac("sha1", $params, $rr['secret']);
$headers = array("Content-type: application/atom+xml",
sprintf("Link: <%s>;rel=hub,<%s>;rel=self",
System::baseUrl().'/pubsubhubbub/'.$rr['nickname'],
$rr['topic']),
"X-Hub-Signature: sha1=".$hmac_sig);
logger('POST '.print_r($headers, true)."\n".$params, LOGGER_DEBUG);
post_url($rr['callback_url'], $params, $headers);
$ret = $a->get_curl_code();
if ($ret >= 200 && $ret <= 299) {
logger('successfully pushed to '.$rr['callback_url']);
// set last_update to the "created" date of the last item, and reset push=0
q("UPDATE `push_subscriber` SET `push` = 0, last_update = '%s' WHERE id = %d",
dbesc($last_update),
intval($rr['id']));
} else {
logger('error when pushing to '.$rr['callback_url'].' HTTP: '.$ret);
// we use the push variable also as a counter, if we failed we
// increment this until some upper limit where we give up
$new_push = intval($rr['push']) + 1;
if ($new_push > 30) // OK, let's give up
$new_push = 0;
q("UPDATE `push_subscriber` SET `push` = %d WHERE id = %d",
$new_push,
intval($rr['id']));
}
}

View File

@ -1,191 +0,0 @@
<?php
/**
* @file include/queue.php
*/
use Friendica\Core\Cache;
use Friendica\Core\Config;
use Friendica\Core\Worker;
use Friendica\Database\DBM;
use Friendica\Protocol\Diaspora;
use Friendica\Protocol\DFRN;
require_once 'include/queue_fn.php';
require_once 'include/datetime.php';
require_once 'include/items.php';
require_once 'include/bbcode.php';
require_once 'include/socgraph.php';
function queue_run(&$argv, &$argc)
{
global $a;
if ($argc > 1) {
$queue_id = intval($argv[1]);
} else {
$queue_id = 0;
}
$cachekey_deadguy = 'queue_run:deadguy:';
$cachekey_server = 'queue_run:server:';
if (!$queue_id) {
logger('queue: start');
// Handling the pubsubhubbub requests
Worker::add(array('priority' => PRIORITY_HIGH, 'dont_fork' => true), 'pubsubpublish');
$r = q(
"SELECT `queue`.*, `contact`.`name`, `contact`.`uid` FROM `queue`
INNER JOIN `contact` ON `queue`.`cid` = `contact`.`id`
WHERE `queue`.`created` < UTC_TIMESTAMP() - INTERVAL 3 DAY"
);
if (DBM::is_result($r)) {
foreach ($r as $rr) {
logger('Removing expired queue item for ' . $rr['name'] . ', uid=' . $rr['uid']);
logger('Expired queue data: ' . $rr['content'], LOGGER_DATA);
}
q("DELETE FROM `queue` WHERE `created` < UTC_TIMESTAMP() - INTERVAL 3 DAY");
}
/*
* For the first 12 hours we'll try to deliver every 15 minutes
* After that, we'll only attempt delivery once per hour.
*/
$r = q("SELECT `id` FROM `queue` WHERE ((`created` > UTC_TIMESTAMP() - INTERVAL 12 HOUR AND `last` < UTC_TIMESTAMP() - INTERVAL 15 MINUTE) OR (`last` < UTC_TIMESTAMP() - INTERVAL 1 HOUR)) ORDER BY `cid`, `created`");
call_hooks('queue_predeliver', $a, $r);
if (DBM::is_result($r)) {
foreach ($r as $q_item) {
logger('Call queue for id '.$q_item['id']);
Worker::add(array('priority' => PRIORITY_LOW, 'dont_fork' => true), "queue", (int)$q_item['id']);
}
}
return;
}
// delivering
require_once 'include/salmon.php';
$r = q(
"SELECT * FROM `queue` WHERE `id` = %d LIMIT 1",
intval($queue_id)
);
if (!DBM::is_result($r)) {
return;
}
$q_item = $r[0];
$c = q(
"SELECT * FROM `contact` WHERE `id` = %d LIMIT 1",
intval($q_item['cid'])
);
if (!DBM::is_result($c)) {
remove_queue_item($q_item['id']);
return;
}
$dead = Cache::get($cachekey_deadguy.$c[0]['notify']);
if (!is_null($dead) && $dead) {
logger('queue: skipping known dead url: '.$c[0]['notify']);
update_queue_time($q_item['id']);
return;
}
$server = poco_detect_server($c[0]['url']);
if ($server != "") {
$vital = Cache::get($cachekey_server.$server);
if (is_null($vital)) {
logger("Check server ".$server." (".$c[0]["network"].")");
$vital = poco_check_server($server, $c[0]["network"], true);
Cache::set($cachekey_server.$server, $vital, CACHE_QUARTER_HOUR);
}
if (!is_null($vital) && !$vital) {
logger('queue: skipping dead server: '.$server);
update_queue_time($q_item['id']);
return;
}
}
$u = q(
"SELECT `user`.*, `user`.`pubkey` AS `upubkey`, `user`.`prvkey` AS `uprvkey`
FROM `user` WHERE `uid` = %d LIMIT 1",
intval($c[0]['uid'])
);
if (!DBM::is_result($u)) {
remove_queue_item($q_item['id']);
return;
}
$data = $q_item['content'];
$public = $q_item['batch'];
$contact = $c[0];
$owner = $u[0];
$deliver_status = 0;
switch ($contact['network']) {
case NETWORK_DFRN:
logger('queue: dfrndelivery: item '.$q_item['id'].' for '.$contact['name'].' <'.$contact['url'].'>');
$deliver_status = DFRN::deliver($owner, $contact, $data);
if ($deliver_status == (-1)) {
update_queue_time($q_item['id']);
Cache::set($cachekey_deadguy.$contact['notify'], true, CACHE_QUARTER_HOUR);
} else {
remove_queue_item($q_item['id']);
}
break;
case NETWORK_OSTATUS:
if ($contact['notify']) {
logger('queue: slapdelivery: item '.$q_item['id'].' for '.$contact['name'].' <'.$contact['url'].'>');
$deliver_status = slapper($owner, $contact['notify'], $data);
if ($deliver_status == (-1)) {
update_queue_time($q_item['id']);
Cache::set($cachekey_deadguy.$contact['notify'], true, CACHE_QUARTER_HOUR);
} else {
remove_queue_item($q_item['id']);
}
}
break;
case NETWORK_DIASPORA:
if ($contact['notify']) {
logger('queue: diaspora_delivery: item '.$q_item['id'].' for '.$contact['name'].' <'.$contact['url'].'>');
$deliver_status = Diaspora::transmit($owner, $contact, $data, $public, true);
if ($deliver_status == (-1)) {
update_queue_time($q_item['id']);
Cache::set($cachekey_deadguy.$contact['notify'], true, CACHE_QUARTER_HOUR);
} else {
remove_queue_item($q_item['id']);
}
}
break;
default:
$params = array('owner' => $owner, 'contact' => $contact, 'queue' => $q_item, 'result' => false);
call_hooks('queue_deliver', $a, $params);
if ($params['result']) {
remove_queue_item($q_item['id']);
} else {
update_queue_time($q_item['id']);
}
break;
}
logger('Deliver status '.(int)$deliver_status.' for item '.$q_item['id'].' to '.$contact['name'].' <'.$contact['url'].'>');
return;
}

View File

@ -13,9 +13,7 @@ function update_queue_time($id) {
function remove_queue_item($id) {
logger('queue: remove queue item ' . $id);
q("DELETE FROM `queue` WHERE `id` = %d",
intval($id)
);
dba::delete('queue', array('id' => $id));
}
/**

View File

@ -1,24 +0,0 @@
<?php
/**
* @file include/remove_contact.php
* @brief Removes orphaned data from deleted contacts
*/
use Friendica\Core\Config;
function remove_contact_run($argv, $argc) {
if ($argc != 2) {
return;
}
$id = intval($argv[1]);
// Only delete if the contact doesn't exist (anymore)
$r = dba::exists('contact', array('id' => $id));
if ($r) {
return;
}
// Now we delete all the depending table entries
dba::delete('contact', array('id' => $id));
}

View File

@ -112,7 +112,7 @@ function slapper($owner, $url, $slap)
$namespaces = array("me" => "http://salmon-protocol.org/ns/magic-env");
$salmon = XML::from_array($xmldata, $xml, false, $namespaces);
$salmon = XML::fromArray($xmldata, $xml, false, $namespaces);
// slap them
post_url($url, $salmon, array(
@ -138,7 +138,7 @@ function slapper($owner, $url, $slap)
$namespaces = array("me" => "http://salmon-protocol.org/ns/magic-env");
$salmon = XML::from_array($xmldata, $xml, false, $namespaces);
$salmon = XML::fromArray($xmldata, $xml, false, $namespaces);
// slap them
post_url($url, $salmon, array(
@ -161,7 +161,7 @@ function slapper($owner, $url, $slap)
$namespaces = array("me" => "http://salmon-protocol.org/ns/magic-env");
$salmon = XML::from_array($xmldata, $xml, false, $namespaces);
$salmon = XML::fromArray($xmldata, $xml, false, $namespaces);
// slap them
post_url($url, $salmon, array(

View File

@ -15,7 +15,7 @@ use Friendica\Database\DBM;
*/
function cookie_hash($user) {
return(hash("sha256", Config::get("system", "site_prvkey").
$user["uprvkey"].
$user["prvkey"].
$user["password"]));
}

View File

@ -1,29 +0,0 @@
<?php
use Friendica\App;
use Friendica\Core\Config;
require_once("boot.php");
require_once("include/threads.php");
function shadowupdate_run(&$argv, &$argc){
global $a;
if (empty($a)) {
$a = new App(dirname(__DIR__));
}
@include(".htconfig.php");
require_once("include/dba.php");
dba::connect($db_host, $db_user, $db_pass, $db_data);
unset($db_host, $db_user, $db_pass, $db_data);
Config::load();
update_shadow_copy();
}
if (array_search(__file__,get_included_files())===0){
shadowupdate_run($_SERVER["argv"],$_SERVER["argc"]);
killme();
}

File diff suppressed because it is too large Load Diff

View File

@ -1,57 +0,0 @@
<?php
/**
* @file include/spool_post.php
* @brief Posts items that wer spooled because they couldn't be posted.
*/
use Friendica\Core\Config;
require_once("include/items.php");
function spool_post_run($argv, $argc) {
global $a;
$path = get_spoolpath();
if (($path != '') && is_writable($path)){
if ($dh = opendir($path)) {
while (($file = readdir($dh)) !== false) {
// It is not named like a spool file, so we don't care.
if (substr($file, 0, 5) != "item-") {
continue;
}
$fullfile = $path."/".$file;
// We don't care about directories either
if (filetype($fullfile) != "file") {
continue;
}
// We can't read or write the file? So we don't care about it.
if (!is_writable($fullfile) || !is_readable($fullfile)) {
continue;
}
$arr = json_decode(file_get_contents($fullfile), true);
// If it isn't an array then it is no spool file
if (!is_array($arr)) {
continue;
}
// Skip if it doesn't seem to be an item array
if (!isset($arr['uid']) && !isset($arr['uri']) && !isset($arr['network'])) {
continue;
}
$result = item_store($arr);
logger("Spool file ".$file." stored: ".$result, LOGGER_DEBUG);
unlink($fullfile);
}
closedir($dh);
}
}
}

View File

@ -2,6 +2,8 @@
use Friendica\App;
use Friendica\Core\System;
use Friendica\Database\DBM;
use Friendica\Object\Contact;
function create_tags_from_item($itemid) {
$profile_base = System::baseUrl();
@ -148,3 +150,166 @@ function update_items() {
dba::close($messages);
}
/**
* @brief Get alphabetical sorted array of used tags/terms of an user including
* a weighting by frequency of use.
*
* @param int $uid The user ID.
* @param int $count Max number of displayed tags/terms.
* @param int $owner_id The contact id of the owner of the tagged items.
* @param string $flags Special item flags.
* @param int $type The tag/term type.
*
* @return arr Alphabetical sorted array of used tags of an user.
*/
function tagadelic($uid, $count = 0, $owner_id = 0, $flags = '', $type = TERM_HASHTAG) {
require_once('include/security.php');
$item_condition = item_condition();
$sql_options = item_permissions_sql($uid);
$limit = $count ? sprintf("LIMIT %d", intval($count)) : "";
if ($flags) {
if ($flags === 'wall') {
$sql_options .= " AND `item`.`wall` ";
}
}
if ($owner_id) {
$sql_options .= " AND `item`.`owner-id` = ".intval($owner_id)." ";
}
// Fetch tags
$r = dba::p("SELECT `term`, COUNT(`term`) AS `total` FROM `term`
LEFT JOIN `item` ON `term`.`oid` = `item`.`id`
WHERE `term`.`uid` = ? AND `term`.`type` = ?
AND `term`.`otype` = ?
AND $item_condition $sql_options
GROUP BY `term` ORDER BY `total` DESC $limit",
$uid,
$type,
TERM_OBJ_POST
);
if(!DBM::is_result($r)) {
return array();
}
return tag_calc($r);
}
/**
* @brief Construct a tag/term cloud block for an user.
*
* @param int $uid The user ID.
* @param int $count Max number of displayed tags/terms.
* @param int $owner_id The contact ID of the owner of the tagged items.
* @param string $flags Special item flags.
* @param int $type The tag/term type.
*
* @return string HTML formatted output.
*/
function wtagblock($uid, $count = 0,$owner_id = 0, $flags = '', $type = TERM_HASHTAG) {
$o = '';
$r = tagadelic($uid, $count, $owner_id, $flags, $type);
if (count($r)) {
$contact = dba::select(
"contact",
array("url"),
array("id" => $uid),
array("limit" => 1)
);
$url = System::removedBaseUrl($contact['url']);
foreach ($r as $rr) {
$tag['level'] = $rr[2];
$tag['url'] = $url."?tag=".urlencode($rr[0]);
$tag['name'] = $rr[0];
$tags[] = $tag;
}
$tpl = get_markup_template("tagblock_widget.tpl");
$o = replace_macros($tpl, array(
'$title' => t('Tags'),
'$tags' => $tags
));
}
return $o;
}
/**
* @brief Calculate weighting of tags according to the frequency of use.
*
* @param array $arr Array of tags/terms with tag/term name and total count of use.
* @return array Alphabetical sorted array of used tags/terms of an user.
*/
function tag_calc($arr) {
$tags = array();
$min = 1e9;
$max = -1e9;
$x = 0;
if (!$arr) {
return array();
}
foreach ($arr as $rr) {
$tags[$x][0] = $rr['term'];
$tags[$x][1] = log($rr['total']);
$tags[$x][2] = 0;
$min = min($min, $tags[$x][1]);
$max = max($max, $tags[$x][1]);
$x ++;
}
usort($tags, 'tags_sort');
$range = max(.01, $max - $min) * 1.0001;
for ($x = 0; $x < count($tags); $x ++) {
$tags[$x][2] = 1 + floor(9 * ($tags[$x][1] - $min) / $range);
}
return $tags;
}
/**
* @brief Compare function to sort tags/terms alphabetically.
*
* @param type $a
* @param type $b
*
* @return int
*/
function tags_sort($a, $b) {
if (strtolower($a[0]) == strtolower($b[0])) {
return 0;
}
return ((strtolower($a[0]) < strtolower($b[0])) ? -1 : 1);
}
/**
* @brief Insert a tag cloud widget for the present profile.
*
* @param int $limit Max number of displayed tags.
* @return string HTML formattat output.
*/
function tagcloud_wall_widget($limit = 50) {
$a = get_app();
if(!$a->profile['profile_uid'] || !$a->profile['url']) {
return "";
}
if(feature_enabled($a->profile['profile_uid'], 'tagadelic')) {
$owner_id = Contact::getIdForURL($a->profile['url']);
if(!$owner_id) {
return "";
}
return wtagblock($a->profile['profile_uid'], $limit, $owner_id, 'wall');
}
return "";
}

View File

@ -1,6 +0,0 @@
<?php
require_once("include/tags.php");
function tagupdate_run(&$argv, &$argc){
update_items();
}

View File

@ -1,311 +0,0 @@
<?php
/*
* This is the old template engine, now deprecated.
* Friendica's default template engine is Smarty3 (see include/friendica_smarty.php)
*
*/
require_once 'object/TemplateEngine.php';
define("KEY_NOT_EXISTS", '^R_key_not_Exists^');
class Template implements ITemplateEngine {
static $name ="internal";
var $r;
var $search;
var $replace;
var $stack = array();
var $nodes = array();
var $done = false;
var $d = false;
var $lang = null;
var $debug = false;
private function _preg_error() {
switch (preg_last_error()) {
case PREG_INTERNAL_ERROR: echo('PREG_INTERNAL_ERROR');
break;
case PREG_BACKTRACK_LIMIT_ERROR: echo('PREG_BACKTRACK_LIMIT_ERROR');
break;
case PREG_RECURSION_LIMIT_ERROR: echo('PREG_RECURSION_LIMIT_ERROR');
break;
case PREG_BAD_UTF8_ERROR: echo('PREG_BAD_UTF8_ERROR');
break;
// This is only valid for php > 5.3, not certain how to code around it for unit tests
// case PREG_BAD_UTF8_OFFSET_ERROR: echo('PREG_BAD_UTF8_OFFSET_ERROR'); break;
default:
//die("Unknown preg error.");
return;
}
echo "<hr><pre>";
debug_print_backtrace();
die();
}
private function _push_stack() {
$this->stack[] = array($this->r, $this->nodes);
}
private function _pop_stack() {
list($this->r, $this->nodes) = array_pop($this->stack);
}
private function _get_var($name, $retNoKey = false) {
$keys = array_map('trim', explode(".", $name));
if ($retNoKey && !array_key_exists($keys[0], $this->r))
return KEY_NOT_EXISTS;
$val = $this->r;
foreach ($keys as $k) {
$val = (isset($val[$k]) ? $val[$k] : null);
}
return $val;
}
/**
* IF node
*
* {{ if <$var> }}...[{{ else }} ...] {{ endif }}
* {{ if <$var>==<val|$var> }}...[{{ else }} ...]{{ endif }}
* {{ if <$var>!=<val|$var> }}...[{{ else }} ...]{{ endif }}
*/
private function _replcb_if ($args) {
if (strpos($args[2], "==") > 0) {
list($a, $b) = array_map("trim", explode("==", $args[2]));
$a = $this->_get_var($a);
if ($b[0] == "$")
$b = $this->_get_var($b);
$val = ($a == $b);
} else if (strpos($args[2], "!=") > 0) {
list($a, $b) = array_map("trim", explode("!=", $args[2]));
$a = $this->_get_var($a);
if ($b[0] == "$")
$b = $this->_get_var($b);
$val = ($a != $b);
} else {
$val = $this->_get_var($args[2]);
}
$x = preg_split("|{{ *else *}}|", $args[3]);
return ( $val ? $x[0] : (isset($x[1]) ? $x[1] : ""));
}
/**
* FOR node
*
* {{ for <$var> as $name }}...{{ endfor }}
* {{ for <$var> as $key=>$name }}...{{ endfor }}
*/
private function _replcb_for ($args) {
$m = array_map('trim', explode(" as ", $args[2]));
$x = explode("=>", $m[1]);
if (count($x) == 1) {
$varname = $x[0];
$keyname = "";
} else {
list($keyname, $varname) = $x;
}
if ($m[0] == "" || $varname == "" || is_null($varname))
die("template error: 'for " . $m[0] . " as " . $varname . "'");
//$vals = $this->r[$m[0]];
$vals = $this->_get_var($m[0]);
$ret = "";
if (!is_array($vals)) {
return $ret;
}
foreach ($vals as $k => $v) {
$this->_push_stack();
$r = $this->r;
$r[$varname] = $v;
if ($keyname != '') {
$r[$keyname] = (($k === 0) ? '0' : $k);
}
$ret .= $this->replace($args[3], $r);
$this->_pop_stack();
}
return $ret;
}
/**
* INC node
*
* {{ inc <templatefile> [with $var1=$var2] }}{{ endinc }}
*/
private function _replcb_inc($args) {
if (strpos($args[2], "with")) {
list($tplfile, $newctx) = array_map('trim', explode("with", $args[2]));
} else {
$tplfile = trim($args[2]);
$newctx = null;
}
if ($tplfile[0] == "$")
$tplfile = $this->_get_var($tplfile);
$this->_push_stack();
$r = $this->r;
if (!is_null($newctx)) {
list($a, $b) = array_map('trim', explode("=", $newctx));
$r[$a] = $this->_get_var($b);
}
$this->nodes = Array();
$tpl = get_markup_template($tplfile);
$ret = $this->replace($tpl, $r);
$this->_pop_stack();
return $ret;
}
/**
* DEBUG node
*
* {{ debug $var [$var [$var [...]]] }}{{ enddebug }}
*
* replace node with <pre>var_dump($var, $var, ...);</pre>
*/
private function _replcb_debug($args) {
$vars = array_map('trim', explode(" ", $args[2]));
$vars[] = $args[1];
$ret = "<pre>";
foreach ($vars as $var) {
$ret .= htmlspecialchars(var_export($this->_get_var($var), true));
$ret .= "\n";
}
$ret .= "</pre>";
return $ret;
}
private function _replcb_node($m) {
$node = $this->nodes[$m[1]];
if (method_exists($this, "_replcb_" . $node[1])) {
$s = call_user_func(array($this, "_replcb_" . $node[1]), $node);
} else {
$s = "";
}
$s = preg_replace_callback('/\|\|([0-9]+)\|\|/', array($this, "_replcb_node"), $s);
return $s;
}
private function _replcb($m) {
//var_dump(array_map('htmlspecialchars', $m));
$this->done = false;
$this->nodes[] = (array) $m;
return "||" . (count($this->nodes) - 1) . "||";
}
private function _build_nodes($s) {
$this->done = false;
while (!$this->done) {
$this->done = true;
$s = preg_replace_callback('|{{ *([a-z]*) *([^}]*)}}([^{]*({{ *else *}}[^{]*)?){{ *end\1 *}}|', array($this, "_replcb"), $s);
if ($s == Null)
$this->_preg_error();
}
//({{ *else *}}[^{]*)?
krsort($this->nodes);
return $s;
}
private function var_replace($s) {
$m = array();
/** regexp:
* \$ literal $
* (\[)? optional open square bracket
* ([a-zA-Z0-9-_]+\.?)+ var name, followed by optional
* dot, repeated at least 1 time
* (|[a-zA-Z0-9-_:]+)* pipe followed by filter name and args, zero or many
* (?(1)\]) if there was opened square bracket
* (subgrup 1), match close bracket
*/
if (preg_match_all('/\$(\[)?([a-zA-Z0-9-_]+\.?)+(\|[a-zA-Z0-9-_:]+)*(?(1)\])/', $s, $m)) {
foreach ($m[0] as $var) {
$exp = str_replace(array("[", "]"), array("", ""), $var);
$exptks = explode("|", $exp);
$varn = $exptks[0];
unset($exptks[0]);
$val = $this->_get_var($varn, true);
if ($val != KEY_NOT_EXISTS) {
/* run filters */
/*
* Filter are in form of:
* filtername:arg:arg:arg
*
* "filtername" is function name
* "arg"s are optional, var value is appended to the end
* if one "arg"==='x' , is replaced with var value
*
* examples:
* $item.body|htmlspecialchars // escape html chars
* $item.body|htmlspecialchars|strtoupper // escape html and uppercase result
* $item.created|date:%Y %M %j // format date (created is a timestamp)
* $item.body|str_replace:cat:dog // replace all "cat" with "dog"
* $item.body|str_replace:cat:dog:x:1 // replace one "cat" with "dog"
*/
foreach ($exptks as $filterstr) {
$filter = explode(":", $filterstr);
$filtername = $filter[0];
unset($filter[0]);
$valkey = array_search("x", $filter);
if ($valkey === false) {
$filter[] = $val;
} else {
$filter[$valkey] = $val;
}
if (function_exists($filtername)) {
$val = call_user_func_array($filtername, $filter);
}
}
$s = str_replace($var, $val, $s);
}
}
}
return $s;
}
// TemplateEngine interface
public function replace_macros($s, $r) {
$this->r = $r;
// remove comments block
$s = preg_replace('/{#(.*?\s*?)*?#}/', "", $s);
$s = $this->_build_nodes($s);
$s = preg_replace_callback('/\|\|([0-9]+)\|\|/', array($this, "_replcb_node"), $s);
if ($s == Null)
$this->_preg_error();
// replace strings recursively (limit to 10 loops)
$os = "";
$count = 0;
while ($os != $s && $count < 10) {
$os = $s;
$count++;
$s = $this->var_replace($s);
}
return template_unescape($s);
}
public function get_template_file($file, $root='') {
$a = get_app();
$template_file = get_template_file($a, $file, $root);
$content = file_get_contents($template_file);
return $content;
}
}
function template_escape($s) {
return str_replace(array('$', '{{'), array('!_Doll^Ars1Az_!', '!_DoubLe^BraceS4Rw_!'), $s);
}
function template_unescape($s) {
return str_replace(array('!_Doll^Ars1Az_!', '!_DoubLe^BraceS4Rw_!'), array('$', '{{'), $s);
}

View File

@ -1,16 +1,16 @@
<?php
use Friendica\App;
use Friendica\Content\Smilies;
use Friendica\Core\Config;
use Friendica\Core\PConfig;
use Friendica\Core\System;
use Friendica\Database\DBM;
require_once "include/template_processor.php";
require_once "include/friendica_smarty.php";
require_once "include/Smilies.php";
require_once "include/map.php";
require_once "mod/proxy.php";
require_once "include/conversation.php";
/**
* This is our template processor
@ -31,7 +31,7 @@ function replace_macros($s, $r) {
$t = $a->template_engine();
try {
$output = $t->replace_macros($s, $r);
$output = $t->replaceMacros($s, $r);
} catch (Exception $e) {
echo "<pre><b>" . __FUNCTION__ . "</b>: " . $e->getMessage() . "</pre>";
killme();
@ -42,18 +42,21 @@ function replace_macros($s, $r) {
return $output;
}
/**
* @brief Generates a pseudo-random string of hexadecimal characters
*
* @param int $size
* @return string
*/
function random_string($size = 64)
{
$byte_size = ceil($size / 2);
// random string, there are 86 characters max in text mode, 128 for hex
// output is urlsafe
$bytes = random_bytes($byte_size);
define('RANDOM_STRING_HEX', 0x00);
define('RANDOM_STRING_TEXT', 0x01);
$return = substr(bin2hex($bytes), 0, $size);
function random_string($size = 64, $type = RANDOM_STRING_HEX) {
// generate a bit of entropy and run it through the whirlpool
$s = hash('whirlpool', (string) rand() . uniqid(rand(),true) . (string) rand(), (($type == RANDOM_STRING_TEXT) ? true : false));
$s = (($type == RANDOM_STRING_TEXT) ? str_replace("\n", "", base64url_encode($s,true)) : $s);
return substr($s,0,$size);
return $return;
}
/**
@ -592,7 +595,7 @@ function get_markup_template($s, $root = '') {
$a = get_app();
$t = $a->template_engine();
try {
$template = $t->get_template_file($s, $root);
$template = $t->getTemplateFile($s, $root);
} catch (Exception $e) {
echo "<pre><b>" . __FUNCTION__ . "</b>: " . $e->getMessage() . "</pre>";
killme();
@ -1148,7 +1151,7 @@ function get_mood_verbs() {
/**
* @brief Translate days and months names.
*
*
* @param string $s String with day or month name.
* @return string Translated string.
*/
@ -1166,7 +1169,7 @@ function day_translate($s) {
/**
* @brief Translate short days and months names.
*
*
* @param string $s String with short day or month name.
* @return string Translated string.
*/

View File

@ -3,6 +3,7 @@
use Friendica\App;
use Friendica\Core\System;
use Friendica\Database\DBM;
use Friendica\Object\Contact;
function add_thread($itemid, $onlyshadow = false) {
$items = q("SELECT `uid`, `created`, `edited`, `commented`, `received`, `changed`, `wall`, `private`, `pubmail`,
@ -58,7 +59,7 @@ function add_shadow_thread($itemid) {
}
// Is the public contact configured as hidden?
if (hiddenContact($item["owner-id"]) || hiddenContact($item["author-id"])) {
if (Contact::isHidden($item["owner-id"]) || Contact::isHidden($item["author-id"])) {
return;
}
@ -98,13 +99,12 @@ function add_shadow_thread($itemid) {
if (!DBM::is_result($r)) {
// Preparing public shadow (removing user specific data)
require_once("include/items.php");
require_once("include/Contact.php");
unset($item[0]['id']);
$item[0]['uid'] = 0;
$item[0]['origin'] = 0;
$item[0]['wall'] = 0;
$item[0]['contact-id'] = get_contact($item[0]['author-link'], 0);
$item[0]['contact-id'] = Contact::getIdForURL($item[0]['author-link'], 0);
if (in_array($item[0]['type'], array("net-comment", "wall-comment"))) {
$item[0]['type'] = 'remote-comment';
@ -158,13 +158,12 @@ function add_shadow_entry($itemid) {
// Preparing public shadow (removing user specific data)
require_once("include/items.php");
require_once("include/Contact.php");
unset($item['id']);
$item['uid'] = 0;
$item['origin'] = 0;
$item['wall'] = 0;
$item['contact-id'] = get_contact($item['author-link'], 0);
$item['contact-id'] = Contact::getIdForURL($item['author-link'], 0);
if (in_array($item['type'], array("net-comment", "wall-comment"))) {
$item['type'] = 'remote-comment';
@ -252,7 +251,7 @@ function delete_thread($itemid, $itemuri = "") {
}
// Using dba::delete at this time could delete the associated item entries
$result = q("DELETE FROM `thread` WHERE `iid` = %d", intval($itemid));
$result = dba::e("DELETE FROM `thread` WHERE `iid` = ?", $itemid);
logger("delete_thread: Deleted thread for item ".$itemid." - ".print_r($result, true), LOGGER_DEBUG);

View File

@ -1,7 +0,0 @@
<?php
require_once("include/threads.php");
function threadupdate_run(&$argv, &$argc){
update_threads();
update_threads_mention();
}

View File

@ -147,7 +147,6 @@ function import_account(App $a, $file) {
// import user
$r = db_import_assoc('user', $account['user']);
if ($r === false) {
//echo "<pre>"; var_dump($r, $query, mysql_error()); killme();
logger("uimport:insert user : ERROR : " . dba::errorMessage(), LOGGER_NORMAL);
notice(t("User creation error"));
return;
@ -189,7 +188,7 @@ function import_account(App $a, $file) {
}
}
if ($contact['uid'] == $olduid && $contact['self'] == '0') {
// set contacts 'avatar-date' to NULL_DATE to let poller to update urls
// set contacts 'avatar-date' to NULL_DATE to let worker to update urls
$contact["avatar-date"] = NULL_DATE;
switch ($contact['network']) {
@ -286,7 +285,7 @@ function import_account(App $a, $file) {
}
// send relocate messages
Worker::add(PRIORITY_HIGH, 'notifier', 'relocate', $newuid);
Worker::add(PRIORITY_HIGH, 'Notifier', 'relocate', $newuid);
info(t("Done. You can now login with your username and password"));
goaway(System::baseUrl() . "/login");

View File

@ -1,80 +0,0 @@
<?php
use Friendica\Core\Config;
use Friendica\Network\Probe;
use Friendica\Database\DBM;
function update_gcontact_run(&$argv, &$argc) {
global $a;
require_once 'include/socgraph.php';
logger('update_gcontact: start');
if (($argc > 1) && (intval($argv[1]))) {
$contact_id = intval($argv[1]);
}
if (!$contact_id) {
logger('update_gcontact: no contact');
return;
}
$r = q("SELECT * FROM `gcontact` WHERE `id` = %d", intval($contact_id));
if (!DBM::is_result($r)) {
return;
}
if (!in_array($r[0]["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS))) {
return;
}
$data = Probe::uri($r[0]["url"]);
if (!in_array($data["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS))) {
if ($r[0]["server_url"] != "")
poco_check_server($r[0]["server_url"], $r[0]["network"]);
q("UPDATE `gcontact` SET `last_failure` = '%s' WHERE `id` = %d",
dbesc(datetime_convert()), intval($contact_id));
return;
}
if (($data["name"] == "") && ($r[0]['name'] != ""))
$data["name"] = $r[0]['name'];
if (($data["nick"] == "") && ($r[0]['nick'] != ""))
$data["nick"] = $r[0]['nick'];
if (($data["addr"] == "") && ($r[0]['addr'] != ""))
$data["addr"] = $r[0]['addr'];
if (($data["photo"] == "") && ($r[0]['photo'] != ""))
$data["photo"] = $r[0]['photo'];
q("UPDATE `gcontact` SET `name` = '%s', `nick` = '%s', `addr` = '%s', `photo` = '%s'
WHERE `id` = %d",
dbesc($data["name"]),
dbesc($data["nick"]),
dbesc($data["addr"]),
dbesc($data["photo"]),
intval($contact_id)
);
q("UPDATE `contact` SET `name` = '%s', `nick` = '%s', `addr` = '%s', `photo` = '%s'
WHERE `uid` = 0 AND `addr` = '' AND `nurl` = '%s'",
dbesc($data["name"]),
dbesc($data["nick"]),
dbesc($data["addr"]),
dbesc($data["photo"]),
dbesc(normalise_link($data["url"]))
);
q("UPDATE `contact` SET `addr` = '%s'
WHERE `uid` != 0 AND `addr` = '' AND `nurl` = '%s'",
dbesc($data["addr"]),
dbesc(normalise_link($data["url"]))
);
}

View File

@ -4,13 +4,12 @@ use Friendica\Core\Config;
use Friendica\Core\System;
use Friendica\Database\DBM;
require_once('include/network.php');
require_once('include/plugin.php');
require_once('include/text.php');
require_once('include/pgettext.php');
require_once('include/datetime.php');
require_once('include/enotify.php');
require_once 'include/network.php';
require_once 'include/plugin.php';
require_once 'include/text.php';
require_once 'include/pgettext.php';
require_once 'include/datetime.php';
require_once 'include/enotify.php';
function create_user($arr) {
@ -388,7 +387,7 @@ function user_create_self_contact($uid) {
* @param string $email
* @param string $sitename
* @param string $username
* @return NULL|boolean from notification() and email() inherited
* @return NULL|boolean from notification() and email() inherited
*/
function send_register_pending_eml($email, $sitename, $username) {
$body = deindent(t('

119
index.php
View File

@ -1,42 +1,35 @@
<?php
/**
*
* @file index.php
* Friendica
*
*/
/**
*
* bootstrap the application
*
* Bootstrap the application
*/
use Friendica\App;
use Friendica\BaseObject;
use Friendica\Core\System;
use Friendica\Core\Config;
use Friendica\Core\Worker;
use Friendica\Database\DBM;
require_once 'boot.php';
require_once 'object/BaseObject.php';
if (empty($a)) {
$a = new App(__DIR__);
}
BaseObject::set_app($a);
BaseObject::setApp($a);
// We assume that the index.php is called by a frontend process
// The value is set to "true" by default in boot.php
$a->backend = false;
/**
*
* Load the configuration file which contains our DB credentials.
* Ignore errors. If the file doesn't exist or is empty, we are running in
* installation mode.
*
*/
$install = ((file_exists('.htconfig.php') && filesize('.htconfig.php')) ? false : true);
@ -47,9 +40,7 @@ if (!$install) {
}
/**
*
* Try to open the database;
*
*/
require_once "include/dba.php";
@ -71,9 +62,10 @@ if (!$install) {
die("System is currently unavailable. Please try again later");
}
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://")) {
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://")
) {
header("HTTP/1.1 302 Moved Temporarily");
header("Location: " . System::baseUrl() . "/" . $a->query_string);
exit();
@ -91,14 +83,12 @@ $lang = get_browser_language();
load_translation_table($lang);
/**
*
* Important stuff we always need to do.
*
* The order of these may be important so use caution if you think they're all
* intertwingled with no logical order and decide to sort it out. Some of the
* dependencies have changed, but at least at one time in the recent past - the
* order was critical to everything working properly
*
*/
// Exclude the backend processes from the session management
@ -114,7 +104,7 @@ if (!$a->is_backend()) {
* Language was set earlier, but we can over-ride it in the session.
* We have to do it here because the session was just now opened.
*/
if (x($_SESSION,'authenticated') && !x($_SESSION,'language')) {
if (x($_SESSION, 'authenticated') && !x($_SESSION, 'language')) {
// we didn't loaded user data yet, but we need user language
$r = dba::select('user', array('language'), array('uid' => $_SESSION['uid']), array('limit' => 1));
$_SESSION['language'] = $lang;
@ -123,18 +113,19 @@ if (x($_SESSION,'authenticated') && !x($_SESSION,'language')) {
}
}
if ((x($_SESSION,'language')) && ($_SESSION['language'] !== $lang)) {
if ((x($_SESSION, 'language')) && ($_SESSION['language'] !== $lang)) {
$lang = $_SESSION['language'];
load_translation_table($lang);
}
if ((x($_GET,'zrl')) && (!$install && !$maintenance)) {
if ((x($_GET, 'zrl')) && (!$install && !$maintenance)) {
// Only continue when the given profile link seems valid
// Valid profile links contain a path with "/profile/" and no query parameters
if ((parse_url($_GET['zrl'], PHP_URL_QUERY) == "") &&
strstr(parse_url($_GET['zrl'], PHP_URL_PATH), "/profile/")) {
if ((parse_url($_GET['zrl'], PHP_URL_QUERY) == "")
&& strstr(parse_url($_GET['zrl'], PHP_URL_PATH), "/profile/")
) {
$_SESSION['my_url'] = $_GET['zrl'];
$a->query_string = preg_replace('/[\?&]zrl=(.*?)([\?&]|$)/is','',$a->query_string);
$a->query_string = preg_replace('/[\?&]zrl=(.*?)([\?&]|$)/is', '', $a->query_string);
zrl_init($a);
} else {
// Someone came with an invalid parameter, maybe as a DDoS attempt
@ -147,23 +138,21 @@ if ((x($_GET,'zrl')) && (!$install && !$maintenance)) {
}
/**
*
* For Mozilla auth manager - still needs sorting, and this might conflict with LRDD header.
* Apache/PHP lumps the Link: headers into one - and other services might not be able to parse it
* this way. There's a PHP flag to link the headers because by default this will over-write any other
* link header.
*
* What we really need to do is output the raw headers ourselves so we can keep them separate.
*
*/
// header('Link: <' . System::baseUrl() . '/amcd>; rel="acct-mgmt";');
if (x($_COOKIE["Friendica"]) || (x($_SESSION,'authenticated')) || (x($_POST,'auth-params')) || ($a->module === 'login')) {
require("include/auth.php");
if (x($_COOKIE["Friendica"]) || (x($_SESSION, 'authenticated')) || (x($_POST, 'auth-params')) || ($a->module === 'login')) {
require "include/auth.php";
}
if (! x($_SESSION,'authenticated')) {
if (! x($_SESSION, 'authenticated')) {
header('X-Account-Management-Status: none');
}
@ -172,16 +161,16 @@ $a->page['htmlhead'] = '';
$a->page['end'] = '';
if (! x($_SESSION,'sysmsg')) {
if (! x($_SESSION, 'sysmsg')) {
$_SESSION['sysmsg'] = array();
}
if (! x($_SESSION,'sysmsg_info')) {
if (! x($_SESSION, 'sysmsg_info')) {
$_SESSION['sysmsg_info'] = array();
}
// Array for informations about last received items
if (! x($_SESSION,'last_updated')) {
if (! x($_SESSION, 'last_updated')) {
$_SESSION['last_updated'] = array();
}
/*
@ -205,7 +194,7 @@ if ($install && $a->module!="view") {
nav_set_selected('nothing');
//Don't populate apps_menu if apps are private
$privateapps = Config::get('config','private_addons');
$privateapps = Config::get('config', 'private_addons');
if ((local_user()) || (! $privateapps === "1")) {
$arr = array('app_menu' => $a->apps);
@ -215,7 +204,6 @@ if ((local_user()) || (! $privateapps === "1")) {
}
/**
*
* We have already parsed the server path into $a->argc and $a->argv
*
* $a->argv[0] is our module name. We will load the file mod/{$a->argv[0]}.php
@ -236,10 +224,8 @@ if ((local_user()) || (! $privateapps === "1")) {
if (strlen($a->module)) {
/**
*
* We will always have a module name.
* First see if we have a plugin which is masquerading as a module.
*
*/
// Compatibility with the Android Diaspora client
@ -252,14 +238,14 @@ if (strlen($a->module)) {
$a->module = "login";
}
$privateapps = Config::get('config','private_addons');
$privateapps = Config::get('config', 'private_addons');
if (is_array($a->plugins) && in_array($a->module,$a->plugins) && file_exists("addon/{$a->module}/{$a->module}.php")) {
if (is_array($a->plugins) && in_array($a->module, $a->plugins) && file_exists("addon/{$a->module}/{$a->module}.php")) {
//Check if module is an app and if public access to apps is allowed or not
if ((!local_user()) && plugin_is_app($a->module) && $privateapps === "1") {
info( t("You must be logged in to use addons. "));
info(t("You must be logged in to use addons. "));
} else {
include_once("addon/{$a->module}/{$a->module}.php");
include_once "addon/{$a->module}/{$a->module}.php";
if (function_exists($a->module . '_module')) {
$a->module_loaded = true;
}
@ -271,12 +257,11 @@ if (strlen($a->module)) {
*/
if ((! $a->module_loaded) && (file_exists("mod/{$a->module}.php"))) {
include_once("mod/{$a->module}.php");
include_once "mod/{$a->module}.php";
$a->module_loaded = true;
}
/**
*
* The URL provided does not resolve to a valid module.
*
* On Dreamhost sites, quite often things go wrong for no apparent reason and they send us to '/internal_error.html'.
@ -285,17 +270,15 @@ if (strlen($a->module)) {
* this will often succeed and eventually do the right thing.
*
* Otherwise we are going to emit a 404 not found.
*
*/
if (! $a->module_loaded) {
// Stupid browser tried to pre-fetch our Javascript img template. Don't log the event or return anything - just quietly exit.
if ((x($_SERVER,'QUERY_STRING')) && preg_match('/{[0-9]}/',$_SERVER['QUERY_STRING']) !== 0) {
if ((x($_SERVER, 'QUERY_STRING')) && preg_match('/{[0-9]}/', $_SERVER['QUERY_STRING']) !== 0) {
killme();
}
if ((x($_SERVER,'QUERY_STRING')) && ($_SERVER['QUERY_STRING'] === 'q=internal_error.html') && isset($dreamhost_error_hack)) {
if ((x($_SERVER, 'QUERY_STRING')) && ($_SERVER['QUERY_STRING'] === 'q=internal_error.html') && isset($dreamhost_error_hack)) {
logger('index.php: dreamhost_error_hack invoked. Original URI =' . $_SERVER['REQUEST_URI']);
goaway(System::baseUrl() . $_SERVER['REQUEST_URI']);
}
@ -303,29 +286,31 @@ if (strlen($a->module)) {
logger('index.php: page not found: ' . $_SERVER['REQUEST_URI'] . ' ADDRESS: ' . $_SERVER['REMOTE_ADDR'] . ' QUERY: ' . $_SERVER['QUERY_STRING'], LOGGER_DEBUG);
header($_SERVER["SERVER_PROTOCOL"] . ' 404 ' . t('Not Found'));
$tpl = get_markup_template("404.tpl");
$a->page['content'] = replace_macros($tpl, array(
'$message' => t('Page not found.' )
));
$a->page['content'] = replace_macros(
$tpl,
array(
'$message' => t('Page not found.'))
);
}
}
/**
* load current theme info
* Load current theme info
*/
$theme_info_file = "view/theme/".current_theme()."/theme.php";
if (file_exists($theme_info_file)){
require_once($theme_info_file);
if (file_exists($theme_info_file)) {
require_once $theme_info_file;
}
/* initialise content region */
if (! x($a->page,'content')) {
if (! x($a->page, 'content')) {
$a->page['content'] = '';
}
if (!$install && !$maintenance) {
call_hooks('page_content_top',$a->page['content']);
call_hooks('page_content_top', $a->page['content']);
}
/**
@ -342,21 +327,22 @@ if ($a->module_loaded) {
$func($a);
}
if (function_exists(str_replace('-','_',current_theme()) . '_init')) {
$func = str_replace('-','_',current_theme()) . '_init';
if (function_exists(str_replace('-', '_', current_theme()) . '_init')) {
$func = str_replace('-', '_', current_theme()) . '_init';
$func($a);
}
if (($_SERVER['REQUEST_METHOD'] === 'POST') && (! $a->error)
&& (function_exists($a->module . '_post'))
&& (! x($_POST,'auth-params'))) {
&& (! x($_POST, 'auth-params'))
) {
call_hooks($a->module . '_mod_post', $_POST);
$func = $a->module . '_post';
$func($a);
}
if ((! $a->error) && (function_exists($a->module . '_afterpost'))) {
call_hooks($a->module . '_mod_afterpost',$placeholder);
call_hooks($a->module . '_mod_afterpost', $placeholder);
$func = $a->module . '_afterpost';
$func($a);
}
@ -371,8 +357,8 @@ if ($a->module_loaded) {
$a->page['content'] .= $arr['content'];
}
if (function_exists(str_replace('-','_',current_theme()) . '_content_loaded')) {
$func = str_replace('-','_',current_theme()) . '_content_loaded';
if (function_exists(str_replace('-', '_', current_theme()) . '_content_loaded')) {
$func = str_replace('-', '_', current_theme()) . '_content_loaded';
$func($a);
}
}
@ -434,10 +420,12 @@ if ($a->is_mobile || $a->is_tablet) {
} else {
$link = 'toggle_mobile?off=1&address=' . curPageURL();
}
$a->page['footer'] = replace_macros(get_markup_template("toggle_mobile_footer.tpl"), array(
'$toggle_link' => $link,
'$toggle_text' => t('toggle mobile')
));
$a->page['footer'] = replace_macros(
get_markup_template("toggle_mobile_footer.tpl"),
array(
'$toggle_link' => $link,
'$toggle_text' => t('toggle mobile'))
);
}
/**
@ -450,7 +438,7 @@ if (!$a->theme['stylesheet']) {
$stylesheet = $a->theme['stylesheet'];
}
$a->page['htmlhead'] = str_replace('{{$stylesheet}}',$stylesheet,$a->page['htmlhead']);
$a->page['htmlhead'] = str_replace('{{$stylesheet}}', $stylesheet, $a->page['htmlhead']);
//$a->page['htmlhead'] = replace_macros($a->page['htmlhead'], array('$stylesheet' => $stylesheet));
if (isset($_GET["mode"]) && (($_GET["mode"] == "raw") || ($_GET["mode"] == "minimal"))) {
@ -477,7 +465,6 @@ if (isset($_GET["mode"]) && (($_GET["mode"] == "raw") || ($_GET["mode"] == "mini
}
if (isset($_GET["mode"]) && ($_GET["mode"] == "raw")) {
header("Content-type: text/html; charset=utf-8");
echo substr($target->saveHTML(), 6, -8);

View File

@ -7,12 +7,15 @@ function ACL(backend_url, preset, automention, is_mobile){
this.kp_timer = null;
if (preset==undefined) preset = [];
if (preset == undefined) {
preset = [];
}
this.allow_cid = (preset[0] || []);
this.allow_gid = (preset[1] || []);
this.deny_cid = (preset[2] || []);
this.deny_gid = (preset[3] || []);
this.group_uids = [];
this.forumCache = null;
if (this.is_mobile) {
this.nw = 1;
@ -25,7 +28,9 @@ function ACL(backend_url, preset, automention, is_mobile){
this.item_tpl = unescape($(".acl-list-item[rel=acl-template]").html());
this.showall = $("#acl-showall");
if (preset.length==0) this.showall.addClass("selected");
if (preset.length==0) {
this.showall.addClass("selected");
}
/*events*/
this.showall.click(this.on_showall.bind(this));
@ -61,7 +66,7 @@ ACL.prototype.remove_mention = function(id) {
}
var end = start + searchText.length;
this.element.setSelection(start, end).replaceSelectedText('').collapseSelection(false);
}
};
ACL.prototype.add_mention = function(id) {
if (!this.automention) {
@ -96,18 +101,18 @@ ACL.prototype.on_submit = function(){
$(this.deny_cid).each(function(i,v){
aclfields.append("<input type='hidden' name='contact_deny[]' value='"+v+"'>");
});
}
};
ACL.prototype.search = function(){
var srcstr = $("#acl-search").val();
this.list_content.html("");
this.get(0,100, srcstr);
}
};
ACL.prototype.on_search = function(event){
if (this.kp_timer) clearTimeout(this.kp_timer);
this.kp_timer = setTimeout( this.search.bind(this), 1000);
}
};
ACL.prototype.on_showall = function(event){
event.preventDefault()
@ -126,7 +131,7 @@ ACL.prototype.on_showall = function(event){
this.update_view();
return false;
}
};
ACL.prototype.on_button_show = function(event){
event.preventDefault()
@ -136,7 +141,8 @@ ACL.prototype.on_button_show = function(event){
this.set_allow($(event.target).parent().attr('id'));
return false;
}
};
ACL.prototype.on_button_hide = function(event){
event.preventDefault()
event.stopImmediatePropagation()
@ -145,34 +151,50 @@ ACL.prototype.on_button_hide = function(event){
this.set_deny($(event.target).parent().attr('id'));
return false;
}
};
ACL.prototype.set_allow = function(itemid){
ACL.prototype.set_allow = function(itemid) {
type = itemid[0];
id = parseInt(itemid.substr(1));
id = parseInt(itemid.substr(1));
switch(type){
switch (type){
case "g":
if (this.allow_gid.indexOf(id)<0){
this.allow_gid.push(id)
if (this.allow_gid.indexOf(id) < 0) {
this.allow_gid.push(id);
}else {
this.allow_gid.remove(id);
}
if (this.deny_gid.indexOf(id)>=0) this.deny_gid.remove(id);
if (this.deny_gid.indexOf(id) >= 0) {
this.deny_gid.remove(id);
}
break;
case "c":
if (this.allow_cid.indexOf(id)<0){
this.allow_cid.push(id)
if (this.data[id].forum=="1") this.add_mention(id);
if (this.allow_cid.indexOf(id) < 0){
this.allow_cid.push(id);
if (this.data[id].forum == "1") {
// If we have select already a forum,
// we need to remove the old one (because friendica does
// allow only one forum as receiver).
if (this.forumCache !== null && this.forumCache !== id) {
this.deselectCid(this.forumCache);
}
// Update the forum cache.
this.forumCache = id;
this.add_mention(id);
}
} else {
this.allow_cid.remove(id);
if (this.data[id].forum=="1") this.remove_mention(id);
if (this.data[id].forum == "1") {
this.remove_mention(id);
}
}
if (this.deny_cid.indexOf(id) >=0 ) {
this.deny_cid.remove(id);
}
if (this.deny_cid.indexOf(id)>=0) this.deny_cid.remove(id);
break;
}
this.update_view();
}
};
ACL.prototype.set_deny = function(itemid){
type = itemid[0];
@ -198,12 +220,12 @@ ACL.prototype.set_deny = function(itemid){
break;
}
this.update_view();
}
};
ACL.prototype.is_show_all = function() {
return (this.allow_gid.length==0 && this.allow_cid.length==0 &&
this.deny_gid.length==0 && this.deny_cid.length==0);
}
};
ACL.prototype.update_view = function(){
if (this.is_show_all()){
@ -279,7 +301,6 @@ ACL.prototype.update_view = function(){
}
ACL.prototype.get = function(start,count, search){
var postdata = {
start:start,
@ -294,7 +315,7 @@ ACL.prototype.get = function(start,count, search){
dataType: 'json',
success:this.populate.bind(this)
});
}
};
ACL.prototype.populate = function(data){
var height = Math.ceil(data.tot / this.nw) * 42;
@ -319,5 +340,20 @@ ACL.prototype.populate = function(data){
});
this.update_view();
}
};
/**
* @brief Deselect previous selected contact.
*
* @param {int} id The contact ID.
* @returns {void}
*/
ACL.prototype.deselectCid = function(id) {
if (this.allow_cid.indexOf(id) >= 0) {
this.allow_cid.remove(id);
}
if (this.deny_cid.indexOf(id) >=0 ) {
this.deny_cid.remove(id);
}
this.remove_mention(id);
};

View File

@ -11,10 +11,11 @@ use Friendica\Core\System;
use Friendica\Core\Config;
use Friendica\Core\Worker;
use Friendica\Database\DBM;
use Friendica\Model\User;
require_once("include/enotify.php");
require_once("include/text.php");
require_once('include/items.php');
require_once 'include/enotify.php';
require_once 'include/text.php';
require_once 'include/items.php';
/**
* @brief Process send data from the admin panels subpages
@ -705,7 +706,7 @@ function admin_page_site_post(App $a) {
check_form_security_token_redirectOnErr('/admin/site', 'admin_site');
if (!empty($_POST['republish_directory'])) {
Worker::add(PRIORITY_LOW, 'directory');
Worker::add(PRIORITY_LOW, 'Directory');
return;
}
@ -778,7 +779,7 @@ function admin_page_site_post(App $a) {
$users = q("SELECT `uid` FROM `user` WHERE `account_removed` = 0 AND `account_expired` = 0");
foreach ($users as $user) {
Worker::add(PRIORITY_HIGH, 'notifier', 'relocate', $user['uid']);
Worker::add(PRIORITY_HIGH, 'Notifier', 'relocate', $user['uid']);
}
info("Relocation started. Could take a while to complete.");
@ -813,7 +814,6 @@ function admin_page_site_post(App $a) {
$block_public = ((x($_POST,'block_public')) ? True : False);
$force_publish = ((x($_POST,'publish_all')) ? True : False);
$global_directory = ((x($_POST,'directory')) ? notags(trim($_POST['directory'])) : '');
$thread_allow = ((x($_POST,'thread_allow')) ? True : False);
$newuser_private = ((x($_POST,'newuser_private')) ? True : False);
$enotify_no_content = ((x($_POST,'enotify_no_content')) ? True : False);
$private_addons = ((x($_POST,'private_addons')) ? True : False);
@ -867,15 +867,12 @@ function admin_page_site_post(App $a) {
// Has the directory url changed? If yes, then resubmit the existing profiles there
if ($global_directory != Config::get('system', 'directory') && ($global_directory != '')) {
Config::set('system', 'directory', $global_directory);
Worker::add(PRIORITY_LOW, 'directory');
Worker::add(PRIORITY_LOW, 'Directory');
}
if ($a->get_path() != "") {
$diaspora_enabled = false;
}
if (!$thread_allow) {
$ostatus_disabled = true;
}
if ($ssl_policy != intval(Config::get('system','ssl_policy'))) {
if ($ssl_policy == SSL_POLICY_FULL) {
q("UPDATE `contact` SET
@ -974,7 +971,6 @@ function admin_page_site_post(App $a) {
Config::set('system', 'allowed_email', $allowed_email);
Config::set('system', 'block_public', $block_public);
Config::set('system', 'publish_all', $force_publish);
Config::set('system', 'thread_allow', $thread_allow);
Config::set('system', 'newuser_private', $newuser_private);
Config::set('system', 'enotify_no_content', $enotify_no_content);
Config::set('system', 'disable_embedded', $disable_embedded);
@ -1213,7 +1209,6 @@ function admin_page_site(App $a) {
'$block_public' => array('block_public', t("Block public"), Config::get('system','block_public'), t("Check to block public access to all otherwise public personal pages on this site unless you are currently logged in.")),
'$force_publish' => array('publish_all', t("Force publish"), Config::get('system','publish_all'), t("Check to force all profiles on this site to be listed in the site directory.")),
'$global_directory' => array('directory', t("Global directory URL"), Config::get('system','directory'), t("URL to the global directory. If this is not set, the global directory is completely unavailable to the application.")),
'$thread_allow' => array('thread_allow', t("Allow threaded items"), Config::get('system','thread_allow'), t("Allow infinite level threading for items on this site.")),
'$newuser_private' => array('newuser_private', t("Private posts by default for new users"), Config::get('system','newuser_private'), t("Set default post permissions for all new members to the default privacy group rather than public.")),
'$enotify_no_content' => array('enotify_no_content', t("Don't include post content in email notifications"), Config::get('system','enotify_no_content'), t("Don't include the content of a post/comment/private message/etc. in the email notifications that are sent out from this site, as a privacy measure.")),
'$private_addons' => array('private_addons', t("Disallow public access to addons listed in the apps menu."), Config::get('config','private_addons'), t("Checking this box will restrict addons listed in the apps menu to members only.")),
@ -1237,7 +1232,7 @@ function admin_page_site(App $a) {
'$timeout' => array('timeout', t("Network timeout"), (x(Config::get('system','curl_timeout'))?Config::get('system','curl_timeout'):60), t("Value is in seconds. Set to 0 for unlimited (not recommended).")),
'$maxloadavg' => array('maxloadavg', t("Maximum Load Average"), ((intval(Config::get('system','maxloadavg')) > 0)?Config::get('system','maxloadavg'):50), t("Maximum system load before delivery and poll processes are deferred - default 50.")),
'$maxloadavg_frontend' => array('maxloadavg_frontend', t("Maximum Load Average (Frontend)"), ((intval(Config::get('system','maxloadavg_frontend')) > 0)?Config::get('system','maxloadavg_frontend'):50), t("Maximum system load before the frontend quits service - default 50.")),
'$min_memory' => array('min_memory', t("Minimal Memory"), ((intval(Config::get('system','min_memory')) > 0)?Config::get('system','min_memory'):0), t("Minimal free memory in MB for the poller. Needs access to /proc/meminfo - default 0 (deactivated).")),
'$min_memory' => array('min_memory', t("Minimal Memory"), ((intval(Config::get('system','min_memory')) > 0)?Config::get('system','min_memory'):0), t("Minimal free memory in MB for the worker. Needs access to /proc/meminfo - default 0 (deactivated).")),
'$optimize_max_tablesize'=> array('optimize_max_tablesize', t("Maximum table size for optimization"), $optimize_max_tablesize, t("Maximum table size (in MB) for the automatic optimization - default 100 MB. Enter -1 to disable it.")),
'$optimize_fragmentation'=> array('optimize_fragmentation', t("Minimum level of fragmentation"), ((intval(Config::get('system','optimize_fragmentation')) > 0)?Config::get('system','optimize_fragmentation'):30), t("Minimum fragmenation level to start the automatic optimization - default value is 30%.")),
@ -1264,7 +1259,7 @@ function admin_page_site(App $a) {
'$rino' => array('rino', t("RINO Encryption"), intval(Config::get('system','rino_encrypt')), t("Encryption layer between nodes."), array("Disabled", "RINO1 (deprecated)", "RINO2")),
'$worker_queues' => array('worker_queues', t("Maximum number of parallel workers"), Config::get('system','worker_queues'), t("On shared hosters set this to 2. On larger systems, values of 10 are great. Default value is 4.")),
'$worker_dont_fork' => array('worker_dont_fork', t("Don't use 'proc_open' with the worker"), Config::get('system','worker_dont_fork'), t("Enable this if your system doesn't allow the use of 'proc_open'. This can happen on shared hosters. If this is enabled you should increase the frequency of poller calls in your crontab.")),
'$worker_dont_fork' => array('worker_dont_fork', t("Don't use 'proc_open' with the worker"), Config::get('system','worker_dont_fork'), t("Enable this if your system doesn't allow the use of 'proc_open'. This can happen on shared hosters. If this is enabled you should increase the frequency of worker calls in your crontab.")),
'$worker_fastlane' => array('worker_fastlane', t("Enable fastlane"), Config::get('system','worker_fastlane'), t("When enabed, the fastlane mechanism starts an additional worker if processes with higher priority are blocked by processes of lower priority.")),
'$worker_frontend' => array('worker_frontend', t('Enable frontend worker'), Config::get('system','frontend_worker'), sprintf(t('When enabled the Worker process is triggered when backend access is performed (e.g. messages being delivered). On smaller sites you might want to call %s/worker on a regular basis via an external cron job. You should only enable this option if you cannot utilize cron/scheduled jobs on your server.'), System::baseUrl())),
@ -1443,9 +1438,8 @@ function admin_page_users_post(App $a) {
notice(sprintf(tt("%s user blocked/unblocked", "%s users blocked/unblocked", count($users)), count($users)));
}
if (x($_POST,'page_users_delete')) {
require_once("include/Contact.php");
foreach ($users as $uid) {
user_remove($uid);
User::remove($uid);
}
notice(sprintf(tt("%s user deleted", "%s users deleted", count($users)), count($users)));
}
@ -1491,8 +1485,7 @@ function admin_page_users(App $a) {
case "delete":
check_form_security_token_redirectOnErr('/admin/users', 'admin_users', 't');
// delete user
require_once("include/Contact.php");
user_remove($uid);
User::remove($uid);
notice(sprintf(t("User '%s' deleted"), $user[0]['username']).EOL);
break;

View File

@ -1,13 +1,15 @@
<?php
/**
* @file mod/allfriends.php
*/
use Friendica\App;
use Friendica\Core\System;
use Friendica\Database\DBM;
use Friendica\Model\GlobalContact;
use Friendica\Object\Contact;
require_once('include/socgraph.php');
require_once('include/Contact.php');
require_once('include/contact_selectors.php');
require_once('mod/contacts.php');
require_once 'include/contact_selectors.php';
require_once 'mod/contacts.php';
function allfriends_content(App $a) {
@ -37,14 +39,14 @@ function allfriends_content(App $a) {
}
$a->page['aside'] = "";
profile_load($a, "", 0, get_contact_details_by_url($c[0]["url"]));
profile_load($a, "", 0, Contact::getDetailsByURL($c[0]["url"]));
$total = count_all_friends(local_user(), $cid);
$total = GlobalContact::countAllFriends(local_user(), $cid);
if(count($total))
$a->set_pager_total($total);
$r = all_friends(local_user(), $cid, $a->pager['start'], $a->pager['itemspage']);
$r = GlobalContact::allFriends(local_user(), $cid, $a->pager['start'], $a->pager['itemspage']);
if (! DBM::is_result($r)) {
$o .= t('No friends to display.');
@ -56,7 +58,7 @@ function allfriends_content(App $a) {
foreach ($r as $rr) {
//get further details of the contact
$contact_details = get_contact_details_by_url($rr['url'], $uid, $rr);
$contact_details = Contact::getDetailsByURL($rr['url'], $uid, $rr);
$photo_menu = '';
@ -64,7 +66,7 @@ function allfriends_content(App $a) {
// If the contact is not common to the user, Connect/Follow' will be added to the photo menu
if ($rr[cid]) {
$rr[id] = $rr[cid];
$photo_menu = contact_photo_menu ($rr);
$photo_menu = Contact::photoMenu ($rr);
}
else {
$connlnk = System::baseUrl() . '/follow/?url=' . $rr['url'];
@ -83,7 +85,7 @@ function allfriends_content(App $a) {
'details' => $contact_details['location'],
'tags' => $contact_details['keywords'],
'about' => $contact_details['about'],
'account_type' => account_type($contact_details),
'account_type' => Contact::getAccountType($contact_details),
'network' => network_to_name($contact_details['network'], $contact_details['url']),
'photo_menu' => $photo_menu,
'conntxt' => t('Connect'),

View File

@ -11,9 +11,10 @@ use Friendica\Core\Config;
use Friendica\Core\PConfig;
use Friendica\Core\System;
use Friendica\Database\DBM;
use Friendica\Object\Contact;
require_once('include/event.php');
require_once('include/redir.php');
require_once 'include/event.php';
require_once 'include/redir.php';
function cal_init(App $a) {
if($a->argc > 1)
@ -46,7 +47,7 @@ function cal_init(App $a) {
$profile = get_profiledata_by_nick($nick, $a->profile_uid);
$account_type = account_type($profile);
$account_type = Contact::getAccountType($profile);
$tpl = get_markup_template("vcard-widget.tpl");

View File

@ -1,12 +1,14 @@
<?php
/**
* @file include/common.php
*/
use Friendica\App;
use Friendica\Database\DBM;
use Friendica\Model\GlobalContact;
use Friendica\Object\Contact;
require_once('include/socgraph.php');
require_once('include/Contact.php');
require_once('include/contact_selectors.php');
require_once('mod/contacts.php');
require_once 'include/contact_selectors.php';
require_once 'mod/contacts.php';
function common_content(App $a) {
@ -37,7 +39,7 @@ function common_content(App $a) {
);
/// @TODO Handle $c with DBM::is_result()
$a->page['aside'] = "";
profile_load($a, "", 0, get_contact_details_by_url($c[0]["url"]));
profile_load($a, "", 0, Contact::getDetailsByURL($c[0]["url"]));
} else {
$c = q("SELECT `name`, `url`, `photo` FROM `contact` WHERE `self` = 1 AND `uid` = %d LIMIT 1",
intval($uid)
@ -83,23 +85,23 @@ function common_content(App $a) {
}
if ($cid) {
$t = count_common_friends($uid, $cid);
$t = GlobalContact::countCommonFriends($uid, $cid);
} else {
$t = count_common_friends_zcid($uid, $zcid);
$t = GlobalContact::countCommonFriendsZcid($uid, $zcid);
}
if (count($t)) {
$a->set_pager_total($t);
} else {
notice( t('No contacts in common.') . EOL);
notice(t('No contacts in common.') . EOL);
return $o;
}
if ($cid) {
$r = common_friends($uid, $cid, $a->pager['start'], $a->pager['itemspage']);
$r = GlobalContact::commonFriends($uid, $cid, $a->pager['start'], $a->pager['itemspage']);
} else {
$r = common_friends_zcid($uid, $zcid, $a->pager['start'], $a->pager['itemspage']);
$r = GlobalContact::commonFriendsZcid($uid, $zcid, $a->pager['start'], $a->pager['itemspage']);
}
@ -112,14 +114,14 @@ function common_content(App $a) {
foreach ($r as $rr) {
//get further details of the contact
$contact_details = get_contact_details_by_url($rr['url'], $uid);
$contact_details = Contact::getDetailsByURL($rr['url'], $uid);
// $rr['id'] is needed to use contact_photo_menu()
/// @TODO Adding '/" here avoids E_NOTICE on missing constants
$rr['id'] = $rr['cid'];
$photo_menu = '';
$photo_menu = contact_photo_menu($rr);
$photo_menu = Contact::photoMenu($rr);
$entry = array(
'url' => $rr['url'],
@ -130,7 +132,7 @@ function common_content(App $a) {
'details' => $contact_details['location'],
'tags' => $contact_details['keywords'],
'about' => $contact_details['about'],
'account_type' => account_type($contact_details),
'account_type' => Contact::getAccountType($contact_details),
'network' => network_to_name($contact_details['network'], $contact_details['url']),
'photo_menu' => $photo_menu,
'id' => ++$id,

View File

@ -4,10 +4,10 @@ use Friendica\App;
use Friendica\Core\System;
use Friendica\Core\Worker;
use Friendica\Database\DBM;
use Friendica\Model\GlobalContact;
use Friendica\Network\Probe;
use Friendica\Object\Contact;
require_once 'include/Contact.php';
require_once 'include/socgraph.php';
require_once 'include/contact_selectors.php';
require_once 'mod/proxy.php';
require_once 'include/Photo.php';
@ -58,7 +58,7 @@ function contacts_init(App $a) {
'$addr' => (($a->data['contact']['addr'] != "") ? ($a->data['contact']['addr']) : ""),
'$network_name' => $networkname,
'$network' => t('Network:'),
'$account_type' => account_type($a->data['contact'])
'$account_type' => Contact::getAccountType($a->data['contact'])
));
$finpeople_widget = '';
@ -131,7 +131,7 @@ function contacts_batch_actions(App $a) {
if ($r) $count_actions++;
}
if (x($_POST, 'contacts_batch_drop')) {
_contact_drop($contact_id, $orig_record);
_contact_drop($orig_record);
$count_actions++;
}
}
@ -252,7 +252,7 @@ function _contact_update($contact_id) {
intval($contact_id));
} else
// pull feed and consume it, which should subscribe to the hub.
Worker::add(PRIORITY_HIGH, "onepoll", $contact_id, "force");
Worker::add(PRIORITY_HIGH, "OnePoll", $contact_id, "force");
}
function _contact_update_profile($contact_id) {
@ -312,7 +312,7 @@ function _contact_update_profile($contact_id) {
update_contact_avatar($data['photo'], local_user(), $contact_id, true);
// Update the entry in the gcontact table
update_gcontact_from_probe($data["url"]);
GlobalContact::updateFromProbe($data["url"]);
}
function _contact_block($contact_id, $orig_record) {
@ -346,7 +346,9 @@ function _contact_archive($contact_id, $orig_record) {
}
return $r;
}
function _contact_drop($contact_id, $orig_record) {
function _contact_drop($orig_record)
{
$a = get_app();
$r = q("SELECT `contact`.*, `user`.* FROM `contact` INNER JOIN `user` ON `contact`.`uid` = `user`.`uid`
@ -357,9 +359,8 @@ function _contact_drop($contact_id, $orig_record) {
return;
}
$self = ""; // Unused parameter
terminate_friendship($r[0], $self, $orig_record);
contact_remove($orig_record['id']);
Contact::terminateFriendship($r[0], $orig_record);
Contact::remove($orig_record['id']);
}
@ -479,7 +480,7 @@ function contacts_content(App $a) {
}
}
_contact_drop($contact_id, $orig_record[0]);
_contact_drop($orig_record[0]);
info( t('Contact has been removed.') . EOL );
if (x($_SESSION,'return_url')) {
goaway('' . $_SESSION['return_url']);
@ -561,12 +562,12 @@ function contacts_content(App $a) {
$nettype = sprintf( t('Network type: %s'),network_to_name($contact['network'], $contact["url"]));
//$common = count_common_friends(local_user(),$contact['id']);
//$common = GlobalContact::countCommonFriends(local_user(),$contact['id']);
//$common_text = (($common) ? sprintf( tt('%d contact in common','%d contacts in common', $common),$common) : '');
$polling = (($contact['network'] === NETWORK_MAIL | $contact['network'] === NETWORK_FEED) ? 'polling' : '');
//$x = count_all_friends(local_user(), $contact['id']);
//$x = GlobalContact::countAllFriends(local_user(), $contact['id']);
//$all_friends = (($x) ? t('View all contacts') : '');
// tabs
@ -575,8 +576,14 @@ function contacts_content(App $a) {
$lost_contact = (($contact['archive'] && $contact['term-date'] > NULL_DATE && $contact['term-date'] < datetime_convert('','','now')) ? t('Communications lost with this contact!') : '');
if ($contact['network'] == NETWORK_FEED) {
$fetch_further_information = array('fetch_further_information', t('Fetch further information for feeds'), $contact['fetch_further_information'], t('Fetch further information for feeds'),
array('0'=>t('Disabled'), '1'=>t('Fetch information'), '2'=>t('Fetch information and keywords')));
$fetch_further_information = array('fetch_further_information',
t('Fetch further information for feeds'),
$contact['fetch_further_information'],
t("Fetch information like preview pictures, title and teaser from the feed item. You can activate this if the feed doesn't contain much text. Keywords are taken from the meta header in the feed item and are posted as hash tags."),
array('0' => t('Disabled'),
'1' => t('Fetch information'),
'3' => t('Fetch keywords'),
'2' => t('Fetch information and keywords')));
}
if (in_array($contact['network'], array(NETWORK_FEED, NETWORK_MAIL, NETWORK_MAIL2)))
$poll_interval = contact_poll_interval($contact['priority'],(! $poll_enabled));
@ -640,6 +647,7 @@ function contacts_content(App $a) {
'$blocked' => (($contact['blocked']) ? t('Currently blocked') : ''),
'$ignored' => (($contact['readonly']) ? t('Currently ignored') : ''),
'$archived' => (($contact['archive']) ? t('Currently archived') : ''),
'$pending' => (($contact['pending']) ? t('Awaiting connection acknowledge') : ''),
'$hidden' => array('hidden', t('Hide this contact from others'), ($contact['hidden'] == 1), t('Replies/likes to your public posts <strong>may</strong> still be visible')),
'$notify' => array('notify', t('Notification for new posts'), ($contact['notify_new_posts'] == 1), t('Send a notification of every new post of this contact')),
'$fetch_further_information' => $fetch_further_information,
@ -653,7 +661,7 @@ function contacts_content(App $a) {
'$url' => $url,
'$profileurllabel' => t('Profile URL'),
'$profileurl' => $contact['url'],
'$account_type' => account_type($contact),
'$account_type' => Contact::getAccountType($contact),
'$location' => bbcode($contact["location"]),
'$location_label' => t("Location:"),
'$xmpp' => bbcode($contact["xmpp"]),
@ -878,7 +886,7 @@ function contacts_tab($a, $contact_id, $active_tab) {
);
// Show this tab only if there is visible friend list
$x = count_all_friends(local_user(), $contact_id);
$x = GlobalContact::countAllFriends(local_user(), $contact_id);
if ($x)
$tabs[] = array('label'=>t('Contacts'),
'url' => "allfriends/".$contact_id,
@ -888,7 +896,7 @@ function contacts_tab($a, $contact_id, $active_tab) {
'accesskey' => 't');
// Show this tab only if there is visible common friend list
$common = count_common_friends(local_user(),$contact_id);
$common = GlobalContact::countCommonFriends(local_user(), $contact_id);
if ($common)
$tabs[] = array('label'=>t('Common Friends'),
'url' => "common/loc/".local_user()."/".$contact_id,
@ -916,7 +924,7 @@ function contact_posts($a, $contact_id) {
if ($r) {
$contact = $r[0];
$a->page['aside'] = "";
profile_load($a, "", 0, get_contact_details_by_url($contact["url"]));
profile_load($a, "", 0, Contact::getDetailsByURL($contact["url"]));
} else
$profile = "";
@ -924,7 +932,7 @@ function contact_posts($a, $contact_id) {
$o .= $tab_str;
$o .= posts_from_contact_url($a, $contact["url"]);
$o .= Contact::getPostsFromUrl($contact["url"]);
return $o;
}
@ -959,14 +967,14 @@ function _contact_detail_for_template($rr){
return array(
'img_hover' => sprintf( t('Visit %s\'s profile [%s]'),$rr['name'],$rr['url']),
'edit_hover' => t('Edit contact'),
'photo_menu' => contact_photo_menu($rr),
'photo_menu' => Contact::photoMenu($rr),
'id' => $rr['id'],
'alt_text' => $alt_text,
'dir_icon' => $dir_icon,
'thumb' => proxy_url($rr['thumb'], false, PROXY_SIZE_THUMB),
'name' => htmlentities($rr['name']),
'username' => htmlentities($rr['name']),
'account_type' => account_type($rr),
'account_type' => Contact::getAccountType($rr),
'sparkle' => $sparkle,
'itemurl' => (($rr['addr'] != "") ? $rr['addr'] : $rr['url']),
'url' => $url,

View File

@ -3,9 +3,10 @@
use Friendica\App;
use Friendica\Core\Config;
use Friendica\Database\DBM;
use Friendica\Object\Contact;
require_once("include/contact_selectors.php");
require_once("mod/contacts.php");
require_once 'include/contact_selectors.php';
require_once 'mod/contacts.php';
function crepair_init(App $a) {
if (! local_user()) {
@ -31,7 +32,7 @@ function crepair_init(App $a) {
if($contact_id) {
$a->data['contact'] = $r[0];
$contact = $r[0];
profile_load($a, "", 0, get_contact_details_by_url($contact["url"]));
profile_load($a, "", 0, Contact::getDetailsByURL($contact["url"]));
}
}

View File

@ -440,7 +440,7 @@ function dfrn_confirm_post(App $a, $handsfree = null) {
if ((isset($new_relation) && $new_relation == CONTACT_IS_FRIEND)) {
if (($contact) && ($contact['network'] === NETWORK_DIASPORA)) {
$ret = Diaspora::send_share($user[0],$r[0]);
$ret = Diaspora::sendShare($user[0],$r[0]);
logger('share returns: ' . $ret);
}
@ -498,7 +498,7 @@ function dfrn_confirm_post(App $a, $handsfree = null) {
$i = item_store($arr);
if($i)
Worker::add(PRIORITY_HIGH, "notifier", "activity", $i);
Worker::add(PRIORITY_HIGH, "Notifier", "activity", $i);
}
}
}
@ -800,7 +800,7 @@ function dfrn_confirm_post(App $a, $handsfree = null) {
$i = item_store($arr);
if($i)
Worker::add(PRIORITY_HIGH, "notifier", "activity", $i);
Worker::add(PRIORITY_HIGH, "Notifier", "activity", $i);
}
}

View File

@ -9,6 +9,7 @@
use Friendica\App;
use Friendica\Core\Config;
use Friendica\Database\DBM;
use Friendica\Object\Contact;
use Friendica\Protocol\DFRN;
require_once 'include/items.php';
@ -127,13 +128,8 @@ function dfrn_notify_post(App $a) {
logger('dfrn_notify: data: ' . $data, LOGGER_DATA);
if ($dissolve == 1) {
/*
* Relationship is dissolved permanently
*/
require_once('include/Contact.php');
contact_remove($importer['id']);
// Relationship is dissolved permanently
Contact::remove($importer['id']);
logger('relationship dissolved : ' . $importer['name'] . ' dissolved ' . $importer['username']);
xml_status(0, 'relationship dissolved');
}
@ -179,7 +175,7 @@ function dfrn_notify_post(App $a) {
*we got a key. old code send only the key, without RINO version.
* we assume RINO 1 if key and no RINO version
*/
$data = DFRN::aes_decrypt(hex2bin($data), $final_key);
$data = DFRN::aesDecrypt(hex2bin($data), $final_key);
break;
case 2:
try {

View File

@ -1,14 +1,16 @@
<?php
/**
* @file mod/dfrn_poll.php
*/
use Friendica\App;
use Friendica\Core\Config;
use Friendica\Core\System;
use Friendica\Database\DBM;
use Friendica\Protocol\DFRN;
use Friendica\Protocol\OStatus;
require_once('include/items.php');
require_once('include/auth.php');
require_once('include/ostatus.php');
require_once 'include/items.php';
require_once 'include/auth.php';
function dfrn_poll_init(App $a) {
$dfrn_id = ((x($_GET,'dfrn_id')) ? $_GET['dfrn_id'] : '');
@ -25,7 +27,7 @@ function dfrn_poll_init(App $a) {
if (($a->argc > 1) && ($dfrn_id == '') && !strstr($_SERVER["HTTP_USER_AGENT"], 'Friendica')) {
$nickname = $a->argv[1];
header("Content-type: application/atom+xml");
echo ostatus::feed($a, $nickname, $last_update, 10);
echo OStatus::feed($a, $nickname, $last_update, 10);
killme();
}

View File

@ -3,6 +3,7 @@
use Friendica\App;
use Friendica\Core\Config;
use Friendica\Database\DBM;
use Friendica\Object\Contact;
function directory_init(App $a) {
$a->set_pager_itemspage(60);
@ -142,12 +143,7 @@ function directory_content(App $a) {
$about = ((x($profile,'about') == 1) ? t('About:') : False);
if($a->theme['template_engine'] === 'internal') {
$location_e = template_escape($location);
}
else {
$location_e = $location;
}
$location_e = $location;
$photo_menu = array(
'profile' => array(t("View Profile"), zrl($profile_link))
@ -161,7 +157,7 @@ function directory_content(App $a) {
'img_hover' => $rr['name'],
'name' => $rr['name'],
'details' => $details,
'account_type' => account_type($rr),
'account_type' => Contact::getAccountType($rr),
'profile' => $profile,
'location' => $location_e,
'tags' => $rr['pub_keywords'],

View File

@ -1,14 +1,17 @@
<?php
/**
* @file mod/dirfind.php
*/
use Friendica\App;
use Friendica\Core\Config;
use Friendica\Core\System;
use Friendica\Core\Worker;
use Friendica\Model\GlobalContact;
use Friendica\Network\Probe;
use Friendica\Object\Contact;
use Friendica\Protocol\PortableContact;
require_once 'include/contact_widgets.php';
require_once 'include/socgraph.php';
require_once 'include/Contact.php';
require_once 'include/contact_selectors.php';
require_once 'mod/contacts.php';
@ -72,14 +75,14 @@ function dirfind_content(App $a, $prefix = "") {
$objresult->tags = "";
$objresult->network = $user_data["network"];
$contact = get_contact_details_by_url($user_data["url"], local_user());
$contact = Contact::getDetailsByURL($user_data["url"], local_user());
$objresult->cid = $contact["cid"];
$j->results[] = $objresult;
// Add the contact to the global contacts if it isn't already in our system
if (($contact["cid"] == 0) && ($contact["zid"] == 0) && ($contact["gid"] == 0)) {
update_gcontact($user_data);
GlobalContact::update($user_data);
}
} elseif ($local) {
@ -142,11 +145,11 @@ function dirfind_content(App $a, $prefix = "") {
$j->items_page = $perpage;
$j->page = $a->pager['page'];
foreach ($results AS $result) {
if (poco_alternate_ostatus_url($result["url"])) {
if (PortableContact::alternateOStatusUrl($result["url"])) {
continue;
}
$result = get_contact_details_by_url($result["url"], local_user(), $result);
$result = Contact::getDetailsByURL($result["url"], local_user(), $result);
if ($result["name"] == "") {
$urlparts = parse_url($result["url"]);
@ -166,7 +169,7 @@ function dirfind_content(App $a, $prefix = "") {
}
// Add found profiles from the global directory to the local directory
Worker::add(PRIORITY_LOW, 'discover_poco', "dirsearch", urlencode($search));
Worker::add(PRIORITY_LOW, 'DiscoverPoCo', "dirsearch", urlencode($search));
} else {
$p = (($a->pager['page'] != 1) ? '&p=' . $a->pager['page'] : '');
@ -190,7 +193,7 @@ function dirfind_content(App $a, $prefix = "") {
$alt_text = "";
$contact_details = get_contact_details_by_url($jj->url, local_user());
$contact_details = Contact::getDetailsByURL($jj->url, local_user());
$itemurl = (($contact_details["addr"] != "") ? $contact_details["addr"] : $jj->url);
@ -201,7 +204,7 @@ function dirfind_content(App $a, $prefix = "") {
$contact = q("SELECT * FROM `contact` WHERE `id` = %d",
intval($jj->cid));
if ($contact) {
$photo_menu = contact_photo_menu($contact[0]);
$photo_menu = Contact::photoMenu($contact[0]);
$details = _contact_detail_for_template($contact[0]);
$alt_text = $details['alt_text'];
} else {
@ -231,7 +234,7 @@ function dirfind_content(App $a, $prefix = "") {
'details' => $contact_details['location'],
'tags' => $contact_details['keywords'],
'about' => $contact_details['about'],
'account_type' => account_type($contact_details),
'account_type' => Contact::getAccountType($contact_details),
'network' => network_to_name($jj->network, $jj->url),
'id' => ++$id,
);

View File

@ -4,6 +4,7 @@ use Friendica\App;
use Friendica\Core\Config;
use Friendica\Core\System;
use Friendica\Database\DBM;
use Friendica\Object\Contact;
use Friendica\Protocol\DFRN;
function display_init(App $a) {
@ -114,8 +115,6 @@ function display_init(App $a) {
function display_fetchauthor($a, $item) {
require_once("include/Contact.php");
$profiledata = array();
$profiledata["uid"] = -1;
$profiledata["nickname"] = $item["author-name"];
@ -181,7 +180,7 @@ function display_fetchauthor($a, $item) {
$profiledata["about"] = "";
}
$profiledata = get_contact_details_by_url($profiledata["url"], local_user(), $profiledata);
$profiledata = Contact::getDetailsByURL($profiledata["url"], local_user(), $profiledata);
$profiledata["photo"] = System::removedBaseUrl($profiledata["photo"]);

View File

@ -180,7 +180,7 @@ function events_post(App $a) {
$item_id = event_store($datarray);
if (! $cid) {
Worker::add(PRIORITY_HIGH, "notifier", "event", $item_id);
Worker::add(PRIORITY_HIGH, "Notifier", "event", $item_id);
}
goaway($_SESSION['return_url']);

View File

@ -69,13 +69,7 @@ function fbrowser_content(App $a) {
$a = get_app();
$types = Photo::supportedTypes();
$ext = $types[$rr['type']];
if($a->theme['template_engine'] === 'internal') {
$filename_e = template_escape($rr['filename']);
}
else {
$filename_e = $rr['filename'];
}
$filename_e = $rr['filename'];
// Take the largest picture that is smaller or equal 640 pixels
$p = q("SELECT `scale` FROM `photo` WHERE `resource-id` = '%s' AND `height` <= 640 AND `width` <= 640 ORDER BY `resource-id`, `scale` LIMIT 1",
@ -117,14 +111,9 @@ function fbrowser_content(App $a) {
$a = get_app();
list($m1,$m2) = explode("/",$rr['filetype']);
$filetype = ( (file_exists("images/icons/$m1.png"))?$m1:"zip");
$filename_e = $rr['filename'];
if ($a->theme['template_engine'] === 'internal') {
$filename_e = template_escape($rr['filename']);
} else {
$filename_e = $rr['filename'];
}
return array( System::baseUrl() . '/attach/' . $rr['id'], $filename_e, System::baseUrl() . '/images/icons/16/' . $filetype . '.png');
return array(System::baseUrl() . '/attach/' . $rr['id'], $filename_e, System::baseUrl() . '/images/icons/16/' . $filetype . '.png');
}
$files = array_map("_map_files2", $files);

View File

@ -68,12 +68,12 @@ function fetch_init(App $a)
}
$user = $r[0];
$status = Diaspora::build_status($item[0], $user);
$xml = Diaspora::build_post_xml($status["type"], $status["message"]);
$status = Diaspora::buildStatus($item[0], $user);
$xml = Diaspora::buildPostXml($status["type"], $status["message"]);
// Send the envelope
header("Content-Type: application/magic-envelope+xml; charset=utf-8");
echo Diaspora::build_magic_envelope($xml, $user);
echo Diaspora::buildMagicEnvelope($xml, $user);
killme();
}

View File

@ -4,9 +4,9 @@ use Friendica\App;
use Friendica\Core\Config;
use Friendica\Core\System;
use Friendica\Network\Probe;
use Friendica\Object\Contact;
require_once 'include/follow.php';
require_once 'include/Contact.php';
require_once 'include/contact_selectors.php';
function follow_post(App $a) {
@ -176,7 +176,7 @@ function follow_content(App $a) {
));
$a->page['aside'] = "";
profile_load($a, "", 0, get_contact_details_by_url($ret["url"]));
profile_load($a, "", 0, Contact::getDetailsByURL($ret["url"]));
if ($gcontact_id <> 0) {
$o .= replace_macros(get_markup_template('section_title.tpl'),
@ -184,7 +184,7 @@ function follow_content(App $a) {
));
// Show last public posts
$o .= posts_from_contact_url($a, $ret["url"]);
$o .= Contact::getPostsFromUrl($ret["url"]);
}
return $o;

View File

@ -61,7 +61,7 @@ function fsuggest_post(App $a) {
intval($fsuggest_id),
intval(local_user())
);
Worker::add(PRIORITY_HIGH, 'notifier', 'suggest', $fsuggest_id);
Worker::add(PRIORITY_HIGH, 'Notifier', 'suggest', $fsuggest_id);
}
info( t('Friend suggestion sent.') . EOL);
@ -74,38 +74,44 @@ function fsuggest_post(App $a) {
function fsuggest_content(App $a) {
require_once('include/acl_selectors.php');
function fsuggest_content(App $a)
{
require_once 'include/acl_selectors.php';
if (! local_user()) {
notice( t('Permission denied.') . EOL);
notice(t('Permission denied.') . EOL);
return;
}
if($a->argc != 2)
if ($a->argc != 2) {
return;
}
$contact_id = intval($a->argv[1]);
$r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1",
$r = q(
"SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1",
intval($contact_id),
intval(local_user())
);
if (! DBM::is_result($r)) {
notice( t('Contact not found.') . EOL);
notice(t('Contact not found.') . EOL);
return;
}
$contact = $r[0];
$o = '<h3>' . t('Suggest Friends') . '</h3>';
$o .= '<div id="fsuggest-desc" >' . sprintf( t('Suggest a friend for %s'), $contact['name']) . '</div>';
$o .= '<div id="fsuggest-desc" >' . sprintf(t('Suggest a friend for %s'), $contact['name']) . '</div>';
$o .= '<form id="fsuggest-form" action="fsuggest/' . $contact_id . '" method="post" >';
$o .= contact_selector('suggest','suggest-select', false,
array('size' => 4, 'exclude' => $contact_id, 'networks' => 'DFRN_ONLY', 'single' => true));
$o .= contact_selector(
'suggest',
'suggest-select',
array('size' => 4, 'exclude' => $contact_id, 'networks' => 'DFRN_ONLY', 'single' => true),
false
);
$o .= '<div id="fsuggest-submit-wrapper"><input id="fsuggest-submit" type="submit" name="submit" value="' . t('Submit') . '" /></div>';

Some files were not shown because too many files have changed in this diff Show More