diff --git a/doc/Plugins.md b/doc/Plugins.md
index 24d403e1f6..a30a3f4a71 100644
--- a/doc/Plugins.md
+++ b/doc/Plugins.md
@@ -1,5 +1,7 @@
Friendica Addon/Plugin development
-==========================
+==============
+
+* [Home](help)
Please see the sample addon 'randplace' for a working example of using some of these features.
Addons work by intercepting event hooks - which must be registered.
@@ -16,12 +18,12 @@ Future extensions may provide for "setup" amd "remove".
Plugins should contain a comment block with the four following parameters:
- /*
- * Name: My Great Plugin
- * Description: This is what my plugin does. It's really cool
- * Version: 1.0
- * Author: John Q. Public
- */
+ /*
+ * Name: My Great Plugin
+ * Description: This is what my plugin does. It's really cool.
+ * Version: 1.0
+ * Author: John Q. Public
+ */
Register your plugin hooks during installation.
@@ -45,7 +47,7 @@ Your hook callback functions will be called with at least one and possibly two a
If you wish to make changes to the calling data, you must declare them as reference variables (with '&') during function declaration.
-###$a
+#### $a
$a is the Friendica 'App' class.
It contains a wealth of information about the current state of Friendica:
@@ -56,13 +58,13 @@ It contains a wealth of information about the current state of Friendica:
It is recommeded you call this '$a' to match its usage elsewhere.
-###$b
+#### $b
$b can be called anything you like.
This is information specific to the hook currently being processed, and generally contains information that is being immediately processed or acted on that you can use, display, or alter.
Remember to declare it with '&' if you wish to alter it.
Modules
---------
+---
Plugins/addons may also act as "modules" and intercept all page requests for a given URL path.
In order for a plugin to act as a module it needs to define a function "plugin_name_module()" which takes no arguments and needs not do anything.
@@ -72,15 +74,15 @@ These are parsed into an array $a->argv, with a corresponding $a->argc indicatin
So http://my.web.site/plugin/arg1/arg2 would look for a module named "plugin" and pass its module functions the $a App structure (which is available to many components).
This will include:
- $a->argc = 3
- $a->argv = array(0 => 'plugin', 1 => 'arg1', 2 => 'arg2');
+ $a->argc = 3
+ $a->argv = array(0 => 'plugin', 1 => 'arg1', 2 => 'arg2');
Your module functions will often contain the function plugin_name_content(&$a), which defines and returns the page body content.
They may also contain plugin_name_post(&$a) which is called before the _content function and typically handles the results of POST forms.
You may also have plugin_name_init(&$a) which is called very early on and often does module initialisation.
Templates
-----------
+---
If your plugin needs some template, you can use the Friendica template system.
Friendica uses [smarty3](http://www.smarty.net/) as a template engine.
@@ -104,140 +106,140 @@ See also the wiki page [Quick Template Guide](https://github.com/friendica/frien
Current hooks
-------------
-###'authenticate'
+### 'authenticate'
'authenticate' is called when a user attempts to login.
$b is an array containing:
- 'username' => the supplied username
- 'password' => the supplied password
+ 'username' => the supplied username
+ 'password' => the supplied password
'authenticated' => set this to non-zero to authenticate the user.
'user_record' => successful authentication must also return a valid user record from the database
-###'logged_in'
+### 'logged_in'
'logged_in' is called after a user has successfully logged in.
$b contains the $a->user array.
-###'display_item'
+### 'display_item'
'display_item' is called when formatting a post for display.
$b is an array:
'item' => The item (array) details pulled from the database
'output' => the (string) HTML representation of this item prior to adding it to the page
-###'post_local'
+### 'post_local'
* called when a status post or comment is entered on the local system
* $b is the item array of the information to be stored in the database
* Please note: body contents are bbcode - not HTML
-###'post_local_end'
+### 'post_local_end'
* called when a local status post or comment has been stored on the local system
* $b is the item array of the information which has just been stored in the database
* Please note: body contents are bbcode - not HTML
-###'post_remote'
+### 'post_remote'
* called when receiving a post from another source. This may also be used to post local activity or system generated messages.
* $b is the item array of information to be stored in the database and the item body is bbcode.
-###'settings_form'
+### 'settings_form'
* called when generating the HTML for the user Settings page
* $b is the (string) HTML of the settings page before the final '' tag.
-###'settings_post'
+### 'settings_post'
* called when the Settings pages are submitted
* $b is the $_POST array
-###'plugin_settings'
+### 'plugin_settings'
* called when generating the HTML for the addon settings page
* $b is the (string) HTML of the addon settings page before the final '' tag.
-###'plugin_settings_post'
+### 'plugin_settings_post'
* called when the Addon Settings pages are submitted
* $b is the $_POST array
-###'profile_post'
+### 'profile_post'
* called when posting a profile page
* $b is the $_POST array
-###'profile_edit'
+### 'profile_edit'
'profile_edit' is called prior to output of profile edit page.
$b is an array containing:
'profile' => profile (array) record from the database
'entry' => the (string) HTML of the generated entry
-###'profile_advanced'
+### 'profile_advanced'
* called when the HTML is generated for the 'Advanced profile', corresponding to the 'Profile' tab within a person's profile page
* $b is the (string) HTML representation of the generated profile
* The profile array details are in $a->profile.
-###'directory_item'
+### 'directory_item'
'directory_item' is called from the Directory page when formatting an item for display.
$b is an array:
'contact' => contact (array) record for the person from the database
'entry' => the (string) HTML of the generated entry
-###'profile_sidebar_enter'
+### 'profile_sidebar_enter'
* called prior to generating the sidebar "short" profile for a page
* $b is the person's profile array
-###'profile_sidebar'
+### 'profile_sidebar'
'profile_sidebar is called when generating the sidebar "short" profile for a page.
$b is an array:
'profile' => profile (array) record for the person from the database
'entry' => the (string) HTML of the generated entry
-###'contact_block_end'
+### 'contact_block_end'
is called when formatting the block of contacts/friends on a profile sidebar has completed.
$b is an array:
'contacts' => array of contacts
'output' => the (string) generated HTML of the contact block
-###'bbcode'
+### 'bbcode'
* called during conversion of bbcode to html
* $b is a string converted text
-###'html2bbcode'
+### 'html2bbcode'
* called during conversion of html to bbcode (e.g. remote message posting)
* $b is a string converted text
-###'page_header'
+### 'page_header'
* called after building the page navigation section
* $b is a string HTML of nav region
-###'personal_xrd'
+### 'personal_xrd'
'personal_xrd' is called prior to output of personal XRD file.
$b is an array:
'user' => the user record for the person
'xml' => the complete XML to be output
-###'home_content'
+### 'home_content'
* called prior to output home page content, shown to unlogged users
* $b is (string) HTML of section region
-###'contact_edit'
+### 'contact_edit'
is called when editing contact details on an individual from the Contacts page.
$b is an array:
'contact' => contact record (array) of target contact
'output' => the (string) generated HTML of the contact edit page
-###'contact_edit_post'
+### 'contact_edit_post'
* called when posting the contact edit page.
* $b is the $_POST array
-###'init_1'
+### 'init_1'
* called just after DB has been opened and before session start
* $b is not used or passed
-###'page_end'
+### 'page_end'
* called after HTML content functions have completed
* $b is (string) HTML of content div
-###'avatar_lookup'
+### 'avatar_lookup'
'avatar_lookup' is called when looking up the avatar.
$b is an array:
@@ -245,11 +247,11 @@ $b is an array:
'email' => email to look up the avatar for
'url' => the (string) generated URL of the avatar
-###'emailer_send_prepare'
+### 'emailer_send_prepare'
'emailer_send_prepare' called from Emailer::send() before building the mime message.
$b is an array, params to Emailer::send()
- 'fromName' => name of the sender
+ 'fromName' => name of the sender
'fromEmail' => email fo the sender
'replyTo' => replyTo address to direct responses
'toEmail' => destination email address
@@ -258,20 +260,20 @@ $b is an array, params to Emailer::send()
'textVersion' => text only version of the message
'additionalMailHeader' => additions to the smtp mail header
-###'emailer_send'
+### 'emailer_send'
is called before calling PHP's mail().
$b is an array, params to mail()
- 'to'
- 'subject'
+ 'to'
+ 'subject'
'body'
'headers'
-###'nav_info'
+### 'nav_info'
is called after the navigational menu is build in include/nav.php.
$b is an array containing $nav from nav.php.
-###'template_vars'
+### 'template_vars'
is called before vars are passed to the template engine to render the page.
The registered function can add,change or remove variables passed to template.
$b is an array with:
@@ -463,4 +465,3 @@ mod/cb.php: call_hooks('cb_afterpost');
mod/cb.php: call_hooks('cb_content', $o);
mod/directory.php: call_hooks('directory_item', $arr);
-
diff --git a/doc/de/Plugins.md b/doc/de/Plugins.md
index dcff41a4b6..40be4a0695 100644
--- a/doc/de/Plugins.md
+++ b/doc/de/Plugins.md
@@ -1,27 +1,28 @@
-**Friendica Addon/Plugin-Entwicklung**
+Friendica Addon/Plugin-Entwicklung
==============
* [Zur Startseite der Hilfe](help)
-Bitte schau dir das Beispiel-Addon "randplace" für ein funktionierendes Beispiel für manche der hier aufgeführten Funktionen an.
-Das Facebook-Addon bietet ein Beispiel dafür, die "addon"- und "module"-Funktion gemeinsam zu integrieren.
-Addons arbeiten, indem sie Event Hooks abfangen. Module arbeiten, indem bestimmte Seitenanfragen (durch den URL-Pfad) abgefangen werden
+Bitte schau dir das Beispiel-Addon "randplace" für ein funktionierendes Beispiel für manche der hier aufgeführten Funktionen an.
+Das Facebook-Addon bietet ein Beispiel dafür, die "addon"- und "module"-Funktion gemeinsam zu integrieren.
+Addons arbeiten, indem sie Event Hooks abfangen.
+Module arbeiten, indem bestimmte Seitenanfragen (durch den URL-Pfad) abgefangen werden.
-Plugin-Namen können keine Leerstellen oder andere Interpunktionen enthalten und werden als Datei- und Funktionsnamen genutzt.
-Du kannst einen lesbaren Namen im Kommentarblock eintragen.
-Jedes Addon muss beides beinhalten - eine Installations- und eine Deinstallationsfunktion, die auf dem Addon-/Plugin-Namen basieren; z.B. "plugin1name_install()".
-Diese beiden Funktionen haben keine Argumente und sind dafür verantwortlich, Event Hooks zu registrieren und abzumelden (unregistering), die dein Plugin benötigt.
-Die Installations- und Deinstallationsfunktionfunktionen werden auch ausgeführt (z.B. neu installiert), wenn sich das Plugin nach der Installation ändert - somit sollte deine Deinstallationsfunktion keine Daten zerstört und deine Installationsfunktion sollte bestehende Daten berücksichtigen.
+Plugin-Namen können keine Leerstellen oder andere Interpunktionen enthalten und werden als Datei- und Funktionsnamen genutzt.
+Du kannst einen lesbaren Namen im Kommentarblock eintragen.
+Jedes Addon muss beides beinhalten - eine Installations- und eine Deinstallationsfunktion, die auf dem Addon-/Plugin-Namen basieren; z.B. "plugin1name_install()".
+Diese beiden Funktionen haben keine Argumente und sind dafür verantwortlich, Event Hooks zu registrieren und abzumelden (unregistering), die dein Plugin benötigt.
+Die Installations- und Deinstallationsfunktionfunktionen werden auch ausgeführt (z.B. neu installiert), wenn sich das Plugin nach der Installation ändert - somit sollte deine Deinstallationsfunktion keine Daten zerstört und deine Installationsfunktion sollte bestehende Daten berücksichtigen.
Zukünftige Extensions werden möglicherweise "Setup" und "Entfernen" anbieten.
Plugins sollten einen Kommentarblock mit den folgenden vier Parametern enthalten:
- /*
- * Name: My Great Plugin
- * Description: This is what my plugin does. It's really cool
- * Version: 1.0
- * Author: John Q. Public
- */
+ /*
+ * Name: My Great Plugin
+ * Description: This is what my plugin does. It's really cool.
+ * Version: 1.0
+ * Author: John Q. Public
+ */
Registriere deine Plugin-Hooks während der Installation.
@@ -29,45 +30,50 @@ Registriere deine Plugin-Hooks während der Installation.
$hookname ist ein String und entspricht einem bekannten Friendica-Hook.
-$file steht für den Pfadnamen, der relativ zum Top-Level-Friendicaverzeichnis liegt.
+$file steht für den Pfadnamen, der relativ zum Top-Level-Friendicaverzeichnis liegt.
Das *sollte* "addon/plugin_name/plugin_name.php' sein.
$function ist ein String und der Name der Funktion, die ausgeführt wird, wenn der Hook aufgerufen wird.
+Argumente
+---
+
Deine Hook-Callback-Funktion wird mit mindestens einem und bis zu zwei Argumenten aufgerufen
function myhook_function(&$a, &$b) {
}
-Wenn du Änderungen an den aufgerufenen Daten vornehmen willst, musst du diese als Referenzvariable (mit "&") während der Funktionsdeklaration deklarieren.
+Wenn du Änderungen an den aufgerufenen Daten vornehmen willst, musst du diese als Referenzvariable (mit "&") während der Funktionsdeklaration deklarieren.
-$a ist die Friendica "App"-Klasse, die eine Menge an Informationen über den aktuellen Friendica-Status beinhaltet, u.a. welche Module genutzt werden, Konfigurationsinformationen, Inhalte der Seite zum Zeitpunkt des Hook-Aufrufs.
-Es ist empfohlen, diese Funktion "$a" zu nennen, um seine Nutzung an den Gebrauch an anderer Stelle anzugleichen.
+$a ist die Friendica "App"-Klasse, die eine Menge an Informationen über den aktuellen Friendica-Status beinhaltet, u.a. welche Module genutzt werden, Konfigurationsinformationen, Inhalte der Seite zum Zeitpunkt des Hook-Aufrufs.
+Es ist empfohlen, diese Funktion "$a" zu nennen, um seine Nutzung an den Gebrauch an anderer Stelle anzugleichen.
-$b kann frei benannt werden.
-Diese Information ist speziell auf den Hook bezogen, der aktuell bearbeitet wird, und beinhaltet normalerweise Daten, die du sofort nutzen, anzeigen oder bearbeiten kannst.
-Achte darauf, diese mit "&" zu deklarieren, wenn du sie bearbeiten willst.
+$b kann frei benannt werden.
+Diese Information ist speziell auf den Hook bezogen, der aktuell bearbeitet wird, und beinhaltet normalerweise Daten, die du sofort nutzen, anzeigen oder bearbeiten kannst.
+Achte darauf, diese mit "&" zu deklarieren, wenn du sie bearbeiten willst.
-**Module**
+Module
+---
-Plugins/Addons können auch als "Module" agieren und alle Seitenanfragen für eine bestimte URL abfangen.
-Um ein Plugin als Modul zu nutzen, ist es nötig, die Funktion "plugin_name_module()" zu definieren, die keine Argumente benötigt und nichts weiter machen muss.
+Plugins/Addons können auch als "Module" agieren und alle Seitenanfragen für eine bestimte URL abfangen.
+Um ein Plugin als Modul zu nutzen, ist es nötig, die Funktion "plugin_name_module()" zu definieren, die keine Argumente benötigt und nichts weiter machen muss.
-Wenn diese Funktion existiert, wirst du nun alle Seitenanfragen für "http://my.web.site/plugin_name" erhalten - mit allen URL-Komponenten als zusätzliche Argumente.
-Diese werden in ein Array $a->argv geparst und stimmen mit $a->argc überein, wobei sie die Anzahl der URL-Komponenten abbilden.
-So würde http://my.web.site/plugin/arg1/arg2 nach einem Modul "plugin" suchen und seiner Modulfunktion die $a-App-Strukur übergeben (dies ist für viele Komponenten verfügbar). Das umfasst:
+Wenn diese Funktion existiert, wirst du nun alle Seitenanfragen für "http://example.com/plugin_name" erhalten - mit allen URL-Komponenten als zusätzliche Argumente.
+Diese werden in ein Array $a->argv geparst und stimmen mit $a->argc überein, wobei sie die Anzahl der URL-Komponenten abbilden.
+So würde http://example.com/plugin/arg1/arg2 nach einem Modul "plugin" suchen und seiner Modulfunktion die $a-App-Strukur übergeben (dies ist für viele Komponenten verfügbar). Das umfasst:
- $a->argc = 3
- $a->argv = array(0 => 'plugin', 1 => 'arg1', 2 => 'arg2');
+ $a->argc = 3
+ $a->argv = array(0 => 'plugin', 1 => 'arg1', 2 => 'arg2');
-Deine Modulfunktionen umfassen oft die Funktion plugin_name_content(&$a), welche den Seiteninhalt definiert und zurückgibt.
-Sie können auch plugin_name_post(&$a) umfassen, welches vor der content-Funktion aufgerufen wird und normalerweise die Resultate der POST-Formulare handhabt.
+Deine Modulfunktionen umfassen oft die Funktion plugin_name_content(&$a), welche den Seiteninhalt definiert und zurückgibt.
+Sie können auch plugin_name_post(&$a) umfassen, welches vor der content-Funktion aufgerufen wird und normalerweise die Resultate der POST-Formulare handhabt.
Du kannst ebenso plugin_name_init(&$a) nutzen, was oft frühzeitig aufgerufen wird und das Modul initialisert.
-**Derzeitige Hooks:**
+Derzeitige Hooks
+---
**'authenticate'** - wird aufgerufen, wenn sich der User einloggt.
$b ist ein Array
@@ -180,6 +186,9 @@ Du kannst ebenso plugin_name_init(&$a) nutzen, was oft frühzeitig aufgerufen wi
- wird aufgerufen nachdem in include/nav,php der Inhalt des Navigations Menüs erzeugt wurde.
- $b ist ein Array, das $nav wiederspiegelt.
+Komplette Liste der Hook-Callbacks
+---
+
Eine komplette Liste aller Hook-Callbacks mit den zugehörigen Dateien (am 14-Feb-2012 generiert): Bitte schau in die Quellcodes für Details zu Hooks, die oben nicht dokumentiert sind.
boot.php: call_hooks('login_hook',$o);
@@ -204,7 +213,7 @@ include/text.php: call_hooks('contact_block_end', $arr);
include/text.php: call_hooks('smilie', $s);
-include/text.php: call_hooks('prepare_body_init', $item);
+include/text.php: call_hooks('prepare_body_init', $item);
include/text.php: call_hooks('prepare_body', $prep_arr);
@@ -359,4 +368,3 @@ mod/cb.php: call_hooks('cb_afterpost');
mod/cb.php: call_hooks('cb_content', $o);
mod/directory.php: call_hooks('directory_item', $arr);
-
diff --git a/doc/themes.md b/doc/themes.md
index add44c776b..ec3a76ac28 100644
--- a/doc/themes.md
+++ b/doc/themes.md
@@ -59,7 +59,19 @@ The same rule applies to the JavaScript files found in
they will be overwritten by files in
- /view/theme/**your-theme-name**/js.
+ /view/theme/**your-theme-name**/js
+
+### Modules
+
+You have the freedom to override core modules found in
+
+ /mod
+
+They will be overwritten by files in
+
+ /view/theme/**your-theme-name**/mod
+
+Be aware that you can break things easily here if you don't know what you do. Also notice that you can override parts of the module – functions not defined in your theme module will be loaded from the core module.
## Expand an existing Theme
@@ -288,4 +300,4 @@ The default file is in
/view/default.php
if you want to change it, say adding a 4th column for banners of your favourite FLOSS projects, place a new default.php file in your theme directory.
-As with the theme.php file, you can use the properties of the $a variable with holds the friendica application to decide what content is displayed.
\ No newline at end of file
+As with the theme.php file, you can use the properties of the $a variable with holds the friendica application to decide what content is displayed.
diff --git a/include/ForumManager.php b/include/ForumManager.php
new file mode 100644
index 0000000000..49417d1831
--- /dev/null
+++ b/include/ForumManager.php
@@ -0,0 +1,190 @@
+ forum url
+ * 'name' => forum name
+ * 'id' => number of the key from the array
+ * 'micro' => contact photo in format micro
+ */
+ public static function get_list($uid, $showhidden = true, $lastitem, $showprivate = false) {
+
+ $forumlist = array();
+
+ $order = (($showhidden) ? '' : ' AND NOT `hidden` ');
+ $order .= (($lastitem) ? ' ORDER BY `last-item` DESC ' : ' ORDER BY `name` ASC ');
+ $select = '`forum` ';
+ if ($showprivate) {
+ $select = '(`forum` OR `prv`)';
+ }
+
+ $contacts = q("SELECT `contact`.`id`, `contact`.`url`, `contact`.`name`, `contact`.`micro` FROM `contact`
+ WHERE `network`= 'dfrn' AND $select AND `uid` = %d
+ AND NOT `blocked` AND NOT `hidden` AND NOT `pending` AND NOT `archive`
+ AND `success_update` > `failure_update`
+ $order ",
+ intval($uid)
+ );
+
+ if (!$contacts)
+ return($forumlist);
+
+ foreach($contacts as $contact) {
+ $forumlist[] = array(
+ 'url' => $contact['url'],
+ 'name' => $contact['name'],
+ 'id' => $contact['id'],
+ 'micro' => $contact['micro'],
+ );
+ }
+ return($forumlist);
+ }
+
+
+ /**
+ * @brief Forumlist widget
+ *
+ * Sidebar widget to show subcribed friendica forums. If activated
+ * in the settings, it appears at the notwork page sidebar
+ *
+ * @param int $uid The ID of the User
+ * @param int $cid
+ * The contact id which is used to mark a forum as "selected"
+ * @return string
+ */
+ public static function widget($uid,$cid = 0) {
+
+ if(! intval(feature_enabled(local_user(),'forumlist_widget')))
+ return;
+
+ $o = '';
+
+ //sort by last updated item
+ $lastitem = true;
+
+ $contacts = self::get_list($uid,true,$lastitem, true);
+ $total = count($contacts);
+ $visible_forums = 10;
+
+ if(count($contacts)) {
+
+ $id = 0;
+
+ foreach($contacts as $contact) {
+
+ $selected = (($cid == $contact['id']) ? ' forum-selected' : '');
+
+ $entry = array(
+ 'url' => z_root() . '/network?f=&cid=' . $contact['id'],
+ 'external_url' => z_root() . '/redir/' . $contact['id'],
+ 'name' => $contact['name'],
+ 'cid' => $contact['id'],
+ 'selected' => $selected,
+ 'micro' => proxy_url($contact['micro'], false, PROXY_SIZE_MICRO),
+ 'id' => ++$id,
+ );
+ $entries[] = $entry;
+ }
+
+ $tpl = get_markup_template('widget_forumlist.tpl');
+
+ $o .= replace_macros($tpl,array(
+ '$title' => t('Forums'),
+ '$forums' => $entries,
+ '$link_desc' => t('External link to forum'),
+ '$total' => $total,
+ '$visible_forums' => $visible_forums,
+ '$showmore' => t('show more'),
+ ));
+ }
+
+ return $o;
+ }
+
+ /**
+ * @brief Format forumlist as contact block
+ *
+ * This function is used to show the forumlist in
+ * the advanced profile.
+ *
+ * @param int $uid The ID of the User
+ * @return string
+ *
+ */
+ public static function profile_advanced($uid) {
+
+ $profile = intval(feature_enabled($uid,'forumlist_profile'));
+ if(! $profile)
+ return;
+
+ $o = '';
+
+ // place holder in case somebody wants configurability
+ $show_total = 9999;
+
+ //don't sort by last updated item
+ $lastitem = false;
+
+ $contacts = self::get_list($uid,false,$lastitem,false);
+
+ $total_shown = 0;
+
+ foreach($contacts as $contact) {
+ $forumlist .= micropro($contact,false,'forumlist-profile-advanced');
+ $total_shown ++;
+ if($total_shown == $show_total)
+ break;
+ }
+
+ if(count($contacts) > 0)
+ $o .= $forumlist;
+ return $o;
+ }
+
+ /**
+ * @brief count unread forum items
+ *
+ * Count unread items of connected forums and private groups
+ *
+ * @return array
+ * 'id' => contact id
+ * 'name' => contact/forum name
+ * 'count' => counted unseen forum items
+ *
+ */
+ public static function count_unseen_items() {
+ $r = q("SELECT `contact`.`id`, `contact`.`name`, COUNT(*) AS `count` FROM `item`
+ INNER JOIN `contact` ON `item`.`contact-id` = `contact`.`id`
+ WHERE `item`.`uid` = %d AND `item`.`visible` AND NOT `item`.`deleted` AND `item`.`unseen`
+ AND `contact`.`network`= 'dfrn' AND (`contact`.`forum` OR `contact`.`prv`)
+ AND NOT `contact`.`blocked` AND NOT `contact`.`hidden`
+ AND NOT `contact`.`pending` AND NOT `contact`.`archive`
+ AND `contact`.`success_update` > `failure_update`
+ GROUP BY `contact`.`id` ",
+ intval(local_user())
+ );
+
+ return $r;
+ }
+
+}
\ No newline at end of file
diff --git a/include/Photo.php b/include/Photo.php
index 3f1608d3ec..91fce55a86 100644
--- a/include/Photo.php
+++ b/include/Photo.php
@@ -726,10 +726,11 @@ function guess_image_type($filename, $fromcurl=false) {
* @param string $avatar Link to avatar picture
* @param int $uid User id of contact owner
* @param int $cid Contact id
+ * @param bool $force force picture update
*
* @return array Returns array of the different avatar sizes
*/
-function update_contact_avatar($avatar,$uid,$cid) {
+function update_contact_avatar($avatar,$uid,$cid, $force = false) {
$r = q("SELECT `avatar`, `photo`, `thumb`, `micro` FROM `contact` WHERE `id` = %d LIMIT 1", intval($cid));
if (!$r)
@@ -737,7 +738,7 @@ function update_contact_avatar($avatar,$uid,$cid) {
else
$data = array($r[0]["photo"], $r[0]["thumb"], $r[0]["micro"]);
- if ($r[0]["avatar"] != $avatar) {
+ if (($r[0]["avatar"] != $avatar) OR $force) {
$photos = import_profile_photo($avatar,$uid,$cid, true);
if ($photos) {
diff --git a/include/datetime.php b/include/datetime.php
index a05af5e38f..89305a2406 100644
--- a/include/datetime.php
+++ b/include/datetime.php
@@ -1,8 +1,17 @@
';
return $o;
-}}
+}
-// return a select using 'field_select_raw' template, with timezones
-// groupped (primarily) by continent
-// arguments follow convetion as other field_* template array:
-// 'name', 'label', $value, 'help'
-if (!function_exists('field_timezone')){
+
+
+/**
+ * @brief Generating a Timezone selector
+ *
+ * Return a select using 'field_select_raw' template, with timezones
+ * groupped (primarily) by continent
+ * arguments follow convetion as other field_* template array:
+ * 'name', 'label', $value, 'help'
+ *
+ * @param string $name Name of the selector
+ * @param string $label Label for the selector
+ * @param string $current Timezone
+ * @param string $help Help text
+ *
+ * @return string Parsed HTML
+ */
function field_timezone($name='timezone', $label='', $current = 'America/Los_Angeles', $help){
$options = select_timezone($current);
$options = str_replace('','', $options);
@@ -69,15 +95,19 @@ function field_timezone($name='timezone', $label='', $current = 'America/Los_Ang
'$field' => array($name, $label, $current, $help, $options),
));
-}}
+}
-// General purpose date parse/convert function.
-// $from = source timezone
-// $to = dest timezone
-// $s = some parseable date/time string
-// $fmt = output format
-
-if(! function_exists('datetime_convert')) {
+/**
+ * @brief General purpose date parse/convert function.
+ *
+ * @param string $from Source timezone
+ * @param string $to Dest timezone
+ * @param string $s Some parseable date/time string
+ * @param string $fmt Output format recognised from php's DateTime class
+ * http://www.php.net/manual/en/datetime.format.php
+ *
+ * @return string Formatted date according to given format
+ */
function datetime_convert($from = 'UTC', $to = 'UTC', $s = 'now', $fmt = "Y-m-d H:i:s") {
// Defaults to UTC if nothing is set, but throws an exception if set to empty string.
@@ -123,14 +153,20 @@ function datetime_convert($from = 'UTC', $to = 'UTC', $s = 'now', $fmt = "Y-m-d
}
$d->setTimeZone($to_obj);
+
return($d->format($fmt));
-}}
+}
-// wrapper for date selector, tailored for use in birthday fields
-
+/**
+ * @brief Wrapper for date selector, tailored for use in birthday fields.
+ *
+ * @param string $dob Date of Birth
+ * @return string
+ */
function dob($dob) {
list($year,$month,$day) = sscanf($dob,'%4d-%2d-%2d');
+
$f = get_config('system','birthday_input_format');
if(! $f)
$f = 'ymd';
@@ -138,62 +174,69 @@ function dob($dob) {
$value = '';
else
$value = (($year) ? datetime_convert('UTC','UTC',$dob,'Y-m-d') : datetime_convert('UTC','UTC',$dob,'m-d'));
+
$o = ' ';
+
// if ($dob && $dob != '0000-00-00')
// $o = datesel($f,mktime(0,0,0,0,0,1900),mktime(),mktime(0,0,0,$month,$day,$year),'dob');
// else
// $o = datesel($f,mktime(0,0,0,0,0,1900),mktime(),false,'dob');
+
return $o;
}
/**
- * returns a date selector
- * @param $format
- * format string, e.g. 'ymd' or 'mdy'. Not currently supported
- * @param $min
- * unix timestamp of minimum date
- * @param $max
- * unix timestap of maximum date
- * @param $default
- * unix timestamp of default date
- * @param $id
- * id and name of datetimepicker (defaults to "datetimepicker")
+ * @brief Returns a date selector
+ *
+ * @param string $format
+ * Format string, e.g. 'ymd' or 'mdy'. Not currently supported
+ * @param string $min
+ * Unix timestamp of minimum date
+ * @param string $max
+ * Unix timestap of maximum date
+ * @param string $default
+ * Unix timestamp of default date
+ * @param string $id
+ * ID and name of datetimepicker (defaults to "datetimepicker")
+ *
+ * @return string Parsed HTML output.
*/
-if(! function_exists('datesel')) {
function datesel($format, $min, $max, $default, $id = 'datepicker') {
return datetimesel($format,$min,$max,$default,$id,true,false, '','');
-}}
+}
/**
- * returns a time selector
- * @param $format
- * format string, e.g. 'ymd' or 'mdy'. Not currently supported
+ * @brief Returns a time selector
+ *
+ * @param string $format
+ * Format string, e.g. 'ymd' or 'mdy'. Not currently supported
* @param $h
- * already selected hour
+ * Already selected hour
* @param $m
- * already selected minute
- * @param $id
- * id and name of datetimepicker (defaults to "timepicker")
+ * Already selected minute
+ * @param string $id
+ * ID and name of datetimepicker (defaults to "timepicker")
+ *
+ * @return string Parsed HTML output.
*/
-if(! function_exists('timesel')) {
function timesel($format, $h, $m, $id='timepicker') {
return datetimesel($format,new DateTime(),new DateTime(),new DateTime("$h:$m"),$id,false,true);
-}}
+}
/**
* @brief Returns a datetime selector.
*
- * @param $format
+ * @param string $format
* format string, e.g. 'ymd' or 'mdy'. Not currently supported
- * @param $min
+ * @param string $min
* unix timestamp of minimum date
- * @param $max
+ * @param string $max
* unix timestap of maximum date
- * @param $default
+ * @param string $default
* unix timestamp of default date
* @param string $id
* id and name of datetimepicker (defaults to "datetimepicker")
- * @param boolean $pickdate
+ * @param bool $pickdate
* true to show date picker (default)
* @param boolean $picktime
* true to show time picker (default)
@@ -201,17 +244,15 @@ function timesel($format, $h, $m, $id='timepicker') {
* set minimum date from picker with id $minfrom (none by default)
* @param $maxfrom
* set maximum date from picker with id $maxfrom (none by default)
- * @param boolean $required default false
+ * @param bool $required default false
+ *
* @return string Parsed HTML output.
*
* @todo Once browser support is better this could probably be replaced with
* native HTML5 date picker.
*/
-if(! function_exists('datetimesel')) {
function datetimesel($format, $min, $max, $default, $id = 'datetimepicker', $pickdate = true, $picktime = true, $minfrom = '', $maxfrom = '', $required = false) {
- $a = get_app();
-
// First day of the week (0 = Sunday)
$firstDay = get_pconfig(local_user(),'system','first_day_of_week');
if ($firstDay === false) $firstDay=0;
@@ -224,43 +265,58 @@ function datetimesel($format, $min, $max, $default, $id = 'datetimepicker', $pic
$o = '';
$dateformat = '';
+
if($pickdate) $dateformat .= 'Y-m-d';
if($pickdate && $picktime) $dateformat .= ' ';
if($picktime) $dateformat .= 'H:i';
+
$minjs = $min ? ",minDate: new Date({$min->getTimestamp()}*1000), yearStart: " . $min->format('Y') : '';
$maxjs = $max ? ",maxDate: new Date({$max->getTimestamp()}*1000), yearEnd: " . $max->format('Y') : '';
$input_text = $default ? 'value="' . date($dateformat, $default->getTimestamp()) . '"' : '';
$defaultdatejs = $default ? ",defaultDate: new Date({$default->getTimestamp()}*1000)" : '';
+
$pickers = '';
if(!$pickdate) $pickers .= ',datepicker: false';
if(!$picktime) $pickers .= ',timepicker: false';
+
$extra_js = '';
$pickers .= ",dayOfWeekStart: ".$firstDay.",lang:'".$lang."'";
if($minfrom != '')
$extra_js .= "\$('#$minfrom').data('xdsoft_datetimepicker').setOptions({onChangeDateTime: function (currentDateTime) { \$('#$id').data('xdsoft_datetimepicker').setOptions({minDate: currentDateTime})}})";
if($maxfrom != '')
$extra_js .= "\$('#$maxfrom').data('xdsoft_datetimepicker').setOptions({onChangeDateTime: function (currentDateTime) { \$('#$id').data('xdsoft_datetimepicker').setOptions({maxDate: currentDateTime})}})";
+
$readable_format = $dateformat;
$readable_format = str_replace('Y','yyyy',$readable_format);
$readable_format = str_replace('m','mm',$readable_format);
$readable_format = str_replace('d','dd',$readable_format);
$readable_format = str_replace('H','HH',$readable_format);
$readable_format = str_replace('i','MM',$readable_format);
+
$o .= " ";
$o .= '
';
$o .= "";
+
return $o;
-}}
+}
-// implements "3 seconds ago" etc.
-// based on $posted_date, (UTC).
-// Results relative to current timezone
-// Limited to range of timestamps
-
-if(! function_exists('relative_date')) {
+/**
+ * @brief Returns a relative date string.
+ *
+ * Implements "3 seconds ago" etc.
+ * Based on $posted_date, (UTC).
+ * Results relative to current timezone.
+ * Limited to range of timestamps.
+ *
+ * @param string $posted_date
+ * @param string $format (optional) Parsed with sprintf()
+ * %1$d %2$s ago , e.g. 22 hours ago, 1 minute ago
+ *
+ * @return string with relative date
+ */
function relative_date($posted_date,$format = null) {
$localtime = datetime_convert('UTC',date_default_timezone_get(),$posted_date);
@@ -300,23 +356,33 @@ function relative_date($posted_date,$format = null) {
// translators - e.g. 22 hours ago, 1 minute ago
if(! $format)
$format = t('%1$d %2$s ago');
+
return sprintf( $format,$r, (($r == 1) ? $str[0] : $str[1]));
- }
- }
-}}
-
-
-
-// Returns age in years, given a date of birth,
-// the timezone of the person whose date of birth is provided,
-// and the timezone of the person viewing the result.
-// Why? Bear with me. Let's say I live in Mittagong, Australia, and my
-// birthday is on New Year's. You live in San Bruno, California.
-// When exactly are you going to see my age increase?
-// A: 5:00 AM Dec 31 San Bruno time. That's precisely when I start
-// celebrating and become a year older. If you wish me happy birthday
-// on January 1 (San Bruno time), you'll be a day late.
+ }
+ }
+}
+/**
+ * @brief Returns timezone correct age in years.
+ *
+ * Returns the age in years, given a date of birth, the timezone of the person
+ * whose date of birth is provided, and the timezone of the person viewing the
+ * result.
+ *
+ * Why? Bear with me. Let's say I live in Mittagong, Australia, and my birthday
+ * is on New Year's. You live in San Bruno, California.
+ * When exactly are you going to see my age increase?
+ *
+ * A: 5:00 AM Dec 31 San Bruno time. That's precisely when I start celebrating
+ * and become a year older. If you wish me happy birthday on January 1
+ * (San Bruno time), you'll be a day late.
+ *
+ * @param string $dob Date of Birth
+ * @param string $owner_tz (optional) Timezone of the person of interest
+ * @param string $viewer_tz (optional) Timezone of the person viewing
+ *
+ * @return int Age in years
+ */
function age($dob,$owner_tz = '',$viewer_tz = '') {
if(! intval($dob))
return 0;
@@ -333,64 +399,79 @@ function age($dob,$owner_tz = '',$viewer_tz = '') {
if(($curr_month < $month) || (($curr_month == $month) && ($curr_day < $day)))
$year_diff--;
+
return $year_diff;
}
-
-
-// Get days in month
-// get_dim($year, $month);
-// returns number of days.
-// $month[1] = 'January';
-// to match human usage.
-
-if(! function_exists('get_dim')) {
+/**
+ * @brief Get days of a month in a given year.
+ *
+ * Returns number of days in the month of the given year.
+ * $m = 1 is 'January' to match human usage.
+ *
+ * @param int $y Year
+ * @param int $m Month (1=January, 12=December)
+ *
+ * @return int Number of days in the given month
+ */
function get_dim($y,$m) {
- $dim = array( 0,
- 31, 28, 31, 30, 31, 30,
- 31, 31, 30, 31, 30, 31);
-
- if($m != 2)
- return $dim[$m];
- if(((($y % 4) == 0) && (($y % 100) != 0)) || (($y % 400) == 0))
- return 29;
- return $dim[2];
-}}
+ $dim = array( 0,
+ 31, 28, 31, 30, 31, 30,
+ 31, 31, 30, 31, 30, 31);
+ if($m != 2)
+ return $dim[$m];
-// Returns the first day in month for a given month, year
-// get_first_dim($year,$month)
-// returns 0 = Sunday through 6 = Saturday
-// Months start at 1.
+ if(((($y % 4) == 0) && (($y % 100) != 0)) || (($y % 400) == 0))
+ return 29;
-if(! function_exists('get_first_dim')) {
+ return $dim[2];
+}
+
+/**
+ * @brief Returns the first day in month for a given month, year.
+ *
+ * Months start at 1.
+ *
+ * @param int $y Year
+ * @param int $m Month (1=January, 12=December)
+ *
+ * @return string day 0 = Sunday through 6 = Saturday
+ */
function get_first_dim($y,$m) {
- $d = sprintf('%04d-%02d-01 00:00', intval($y), intval($m));
- return datetime_convert('UTC','UTC',$d,'w');
-}}
+ $d = sprintf('%04d-%02d-01 00:00', intval($y), intval($m));
-// output a calendar for the given month, year.
-// if $links are provided (array), e.g. $links[12] => 'http://mylink' ,
-// date 12 will be linked appropriately. Today's date is also noted by
-// altering td class.
-// Months count from 1.
+ return datetime_convert('UTC','UTC',$d,'w');
+}
-
-/// @TODO Provide (prev,next) links, define class variations for different size calendars
-
-
-if(! function_exists('cal')) {
+/**
+ * @brief Output a calendar for the given month, year.
+ *
+ * If $links are provided (array), e.g. $links[12] => 'http://mylink' ,
+ * date 12 will be linked appropriately. Today's date is also noted by
+ * altering td class.
+ * Months count from 1.
+ *
+ * @param int $y Year
+ * @param int $m Month
+ * @param bool $links (default false)
+ * @param string $class
+ *
+ * @return string
+ *
+ * @todo Provide (prev,next) links, define class variations for different size calendars
+ */
function cal($y = 0,$m = 0, $links = false, $class='') {
// month table - start at 1 to match human usage.
$mtab = array(' ',
- 'January','February','March',
- 'April','May','June',
- 'July','August','September',
- 'October','November','December'
+ 'January','February','March',
+ 'April','May','June',
+ 'July','August','September',
+ 'October','November','December'
);
$thisyear = datetime_convert('UTC',date_default_timezone_get(),'now','Y');
@@ -400,54 +481,63 @@ function cal($y = 0,$m = 0, $links = false, $class='') {
if(! $m)
$m = intval($thismonth);
- $dn = array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
- $f = get_first_dim($y,$m);
- $l = get_dim($y,$m);
- $d = 1;
- $dow = 0;
- $started = false;
+ $dn = array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
+ $f = get_first_dim($y,$m);
+ $l = get_dim($y,$m);
+ $d = 1;
+ $dow = 0;
+ $started = false;
- if(($y == $thisyear) && ($m == $thismonth))
- $tddate = intval(datetime_convert('UTC',date_default_timezone_get(),'now','j'));
+ if(($y == $thisyear) && ($m == $thismonth))
+ $tddate = intval(datetime_convert('UTC',date_default_timezone_get(),'now','j'));
$str_month = day_translate($mtab[$m]);
- $o = '';
- $o .= "$str_month $y ";
- for($a = 0; $a < 7; $a ++)
- $o .= '' . mb_substr(day_translate($dn[$a]),0,3,'UTF-8') . ' ';
- $o .= ' ';
+ $o = '';
+ $o .= "$str_month $y ";
+ for($a = 0; $a < 7; $a ++)
+ $o .= '' . mb_substr(day_translate($dn[$a]),0,3,'UTF-8') . ' ';
- while($d <= $l) {
- if(($dow == $f) && (! $started))
- $started = true;
- $today = (((isset($tddate)) && ($tddate == $d)) ? "class=\"today\" " : '');
- $o .= "";
- $day = str_replace(' ',' ',sprintf('%2.2d', $d));
- if($started) {
- if(is_array($links) && isset($links[$d]))
- $o .= "$day ";
- else
- $o .= $day;
- $d ++;
- }
- else
- $o .= ' ';
- $o .= ' ';
- $dow ++;
- if(($dow == 7) && ($d <= $l)) {
- $dow = 0;
- $o .= ' ';
- }
- }
- if($dow)
- for($a = $dow; $a < 7; $a ++)
- $o .= ' ';
- $o .= '
'."\r\n";
+ $o .= ' ';
- return $o;
-}}
+ while($d <= $l) {
+ if(($dow == $f) && (! $started))
+ $started = true;
+ $today = (((isset($tddate)) && ($tddate == $d)) ? "class=\"today\" " : '');
+ $o .= "";
+ $day = str_replace(' ',' ',sprintf('%2.2d', $d));
+ if($started) {
+ if(is_array($links) && isset($links[$d]))
+ $o .= "$day ";
+ else
+ $o .= $day;
+ $d ++;
+ } else {
+ $o .= ' ';
+ }
+
+ $o .= ' ';
+ $dow ++;
+ if(($dow == 7) && ($d <= $l)) {
+ $dow = 0;
+ $o .= ' ';
+ }
+ }
+ if($dow)
+ for($a = $dow; $a < 7; $a ++)
+ $o .= ' ';
+
+ $o .= '
'."\r\n";
+
+ return $o;
+}
+
+/**
+ * @brief Create a birthday event.
+ *
+ * Update the year and the birthday.
+ */
function update_contact_birthdays() {
// This only handles foreign or alien networks where a birthday has been provided.
@@ -474,8 +564,6 @@ function update_contact_birthdays() {
$bdtext = sprintf( t('%s\'s birthday'), $rr['name']);
$bdtext2 = sprintf( t('Happy Birthday %s'), ' [url=' . $rr['url'] . ']' . $rr['name'] . '[/url]') ;
-
-
$r = q("INSERT INTO `event` (`uid`,`cid`,`created`,`edited`,`start`,`finish`,`summary`,`desc`,`type`,`adjust`)
VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%d' ) ",
intval($rr['uid']),
diff --git a/include/delivery.php b/include/delivery.php
index 5ef942dd06..021ceb9968 100644
--- a/include/delivery.php
+++ b/include/delivery.php
@@ -374,7 +374,7 @@ function delivery_run(&$argv, &$argc){
break;
logger('mod-delivery: local delivery');
- local_delivery($x[0],$atom);
+ dfrn::import($atom, $x[0]);
break;
}
}
diff --git a/include/dfrn.php b/include/dfrn.php
index 2c8e8ce38f..c6c8deef58 100644
--- a/include/dfrn.php
+++ b/include/dfrn.php
@@ -6,9 +6,19 @@
* https://github.com/friendica/friendica/wiki/Protocol
*/
-require_once('include/items.php');
-require_once('include/Contact.php');
-require_once('include/ostatus.php');
+require_once("include/Contact.php");
+require_once("include/ostatus.php");
+require_once("include/enotify.php");
+require_once("include/threads.php");
+require_once("include/socgraph.php");
+require_once("include/items.php");
+require_once("include/tags.php");
+require_once("include/files.php");
+require_once("include/event.php");
+require_once("include/text.php");
+require_once("include/oembed.php");
+require_once("include/html2bbcode.php");
+require_once("library/HTMLPurifier.auto.php");
/**
* @brief This class contain functions to create and send DFRN XML files
@@ -16,6 +26,10 @@ require_once('include/ostatus.php');
*/
class dfrn {
+ const DFRN_TOP_LEVEL = 0; // Top level posting
+ const DFRN_REPLY = 1; // Regular reply that is stored locally
+ const DFRN_REPLY_RC = 2; // Reply that will be relayed
+
/**
* @brief Generates the atom entries for delivery.php
*
@@ -26,7 +40,7 @@ class dfrn {
*
* @return string DFRN entries
*/
- function entries($items,$owner) {
+ public static function entries($items,$owner) {
$doc = new DOMDocument('1.0', 'utf-8');
$doc->formatOutput = true;
@@ -56,7 +70,7 @@ class dfrn {
*
* @return string DFRN feed entries
*/
- function feed($dfrn_id, $owner_nick, $last_update, $direction = 0) {
+ public static function feed($dfrn_id, $owner_nick, $last_update, $direction = 0) {
$a = get_app();
@@ -263,7 +277,7 @@ class dfrn {
*
* @return string DFRN mail
*/
- function mail($item, $owner) {
+ public static function mail($item, $owner) {
$doc = new DOMDocument('1.0', 'utf-8');
$doc->formatOutput = true;
@@ -297,7 +311,7 @@ class dfrn {
*
* @return string DFRN suggestions
*/
- function fsuggest($item, $owner) {
+ public static function fsuggest($item, $owner) {
$doc = new DOMDocument('1.0', 'utf-8');
$doc->formatOutput = true;
@@ -324,7 +338,7 @@ class dfrn {
*
* @return string DFRN relocations
*/
- function relocate($owner, $uid) {
+ public static function relocate($owner, $uid) {
/* get site pubkey. this could be a new installation with no site keys*/
$pubkey = get_config('system','site_pubkey');
@@ -383,20 +397,19 @@ class dfrn {
if ($alternatelink == "")
$alternatelink = $owner['url'];
- $root = $doc->createElementNS(NS_ATOM, 'feed');
+ $root = $doc->createElementNS(NAMESPACE_ATOM1, 'feed');
$doc->appendChild($root);
- $root->setAttribute("xmlns:thr", NS_THR);
- $root->setAttribute("xmlns:at", "http://purl.org/atompub/tombstones/1.0");
- $root->setAttribute("xmlns:media", NS_MEDIA);
- $root->setAttribute("xmlns:dfrn", "http://purl.org/macgirvin/dfrn/1.0");
- $root->setAttribute("xmlns:activity", NS_ACTIVITY);
- $root->setAttribute("xmlns:georss", NS_GEORSS);
- $root->setAttribute("xmlns:poco", NS_POCO);
- $root->setAttribute("xmlns:ostatus", NS_OSTATUS);
- $root->setAttribute("xmlns:statusnet", NS_STATUSNET);
+ $root->setAttribute("xmlns:thr", NAMESPACE_THREAD);
+ $root->setAttribute("xmlns:at", NAMESPACE_TOMB);
+ $root->setAttribute("xmlns:media", NAMESPACE_MEDIA);
+ $root->setAttribute("xmlns:dfrn", NAMESPACE_DFRN);
+ $root->setAttribute("xmlns:activity", NAMESPACE_ACTIVITY);
+ $root->setAttribute("xmlns:georss", NAMESPACE_GEORSS);
+ $root->setAttribute("xmlns:poco", NAMESPACE_POCO);
+ $root->setAttribute("xmlns:ostatus", NAMESPACE_OSTATUS);
+ $root->setAttribute("xmlns:statusnet", NAMESPACE_STATUSNET);
- //xml_add_element($doc, $root, "id", app::get_baseurl()."/profile/".$owner["nick"]);
xml_add_element($doc, $root, "id", app::get_baseurl()."/profile/".$owner["nick"]);
xml_add_element($doc, $root, "title", $owner["name"]);
@@ -409,9 +422,11 @@ class dfrn {
$attributes = array("rel" => "alternate", "type" => "text/html", "href" => $alternatelink);
xml_add_element($doc, $root, "link", "", $attributes);
- ostatus_hublinks($doc, $root);
if ($public) {
+ // DFRN itself doesn't uses this. But maybe someone else wants to subscribe to the public feed.
+ ostatus_hublinks($doc, $root);
+
$attributes = array("rel" => "salmon", "href" => app::get_baseurl()."/salmon/".$owner["nick"]);
xml_add_element($doc, $root, "link", "", $attributes);
@@ -425,6 +440,8 @@ class dfrn {
if ($owner['page-flags'] == PAGE_COMMUNITY)
xml_add_element($doc, $root, "dfrn:community", 1);
+ /// @todo We need a way to transmit the different page flags like "PAGE_PRVGROUP"
+
xml_add_element($doc, $root, "updated", datetime_convert("UTC", "UTC", "now", ATOM_TIME));
$author = self::add_author($doc, $owner, $authorelement, $public);
@@ -727,9 +744,14 @@ class dfrn {
xml_add_element($doc, $entry, "published", datetime_convert("UTC","UTC",$item["created"]."+00:00",ATOM_TIME));
xml_add_element($doc, $entry, "updated", datetime_convert("UTC","UTC",$item["edited"]."+00:00",ATOM_TIME));
+ // "dfrn:env" is used to read the content
xml_add_element($doc, $entry, "dfrn:env", base64url_encode($body, true));
+
+ // The "content" field is not read by the receiver. We could remove it when the type is "text"
+ // We keep it at the moment, maybe there is some old version that doesn't read "dfrn:env"
xml_add_element($doc, $entry, "content", (($type === 'html') ? $htmlbody : $body), array("type" => $type));
+ // We save this value in "plink". Maybe we should read it from there as well?
xml_add_element($doc, $entry, "link", "", array("rel" => "alternate", "type" => "text/html",
"href" => app::get_baseurl()."/display/".$item["guid"]));
@@ -824,7 +846,7 @@ class dfrn {
*
* @return int Deliver status. -1 means an error.
*/
- function deliver($owner,$contact,$atom, $dissolve = false) {
+ public static function deliver($owner,$contact,$atom, $dissolve = false) {
$a = get_app();
@@ -1045,4 +1067,1343 @@ class dfrn {
return $res->status;
}
+
+ /**
+ * @brief Add new birthday event for this person
+ *
+ * @param array $contact Contact record
+ * @param string $birthday Birthday of the contact
+ *
+ */
+ private function birthday_event($contact, $birthday) {
+
+ logger("updating birthday: ".$birthday." for contact ".$contact["id"]);
+
+ $bdtext = sprintf(t("%s\'s birthday"), $contact["name"]);
+ $bdtext2 = sprintf(t("Happy Birthday %s"), " [url=".$contact["url"]."]".$contact["name"]."[/url]") ;
+
+
+ $r = q("INSERT INTO `event` (`uid`,`cid`,`created`,`edited`,`start`,`finish`,`summary`,`desc`,`type`)
+ VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s') ",
+ intval($contact["uid"]),
+ intval($contact["id"]),
+ dbesc(datetime_convert()),
+ dbesc(datetime_convert()),
+ dbesc(datetime_convert("UTC","UTC", $birthday)),
+ dbesc(datetime_convert("UTC","UTC", $birthday." + 1 day ")),
+ dbesc($bdtext),
+ dbesc($bdtext2),
+ dbesc("birthday")
+ );
+ }
+
+ /**
+ * @brief Fetch the author data from head or entry items
+ *
+ * @param object $xpath XPath object
+ * @param object $context In which context should the data be searched
+ * @param array $importer Record of the importer user mixed with contact of the content
+ * @param string $element Element name from which the data is fetched
+ * @param bool $onlyfetch Should the data only be fetched or should it update the contact record as well
+ *
+ * @return Returns an array with relevant data of the author
+ */
+ private function fetchauthor($xpath, $context, $importer, $element, $onlyfetch) {
+
+ $author = array();
+ $author["name"] = $xpath->evaluate($element."/atom:name/text()", $context)->item(0)->nodeValue;
+ $author["link"] = $xpath->evaluate($element."/atom:uri/text()", $context)->item(0)->nodeValue;
+
+ $r = q("SELECT `id`, `uid`, `network`, `avatar-date`, `name-date`, `uri-date`, `addr`,
+ `name`, `nick`, `about`, `location`, `keywords`, `bdyear`, `bd`
+ FROM `contact` WHERE `uid` = %d AND `nurl` = '%s' AND `network` != '%s'",
+ intval($importer["uid"]), dbesc(normalise_link($author["link"])), dbesc(NETWORK_STATUSNET));
+ if ($r) {
+ $contact = $r[0];
+ $author["contact-id"] = $r[0]["id"];
+ $author["network"] = $r[0]["network"];
+ } else {
+ $author["contact-id"] = $importer["id"];
+ $author["network"] = $importer["network"];
+ $onlyfetch = true;
+ }
+
+ // Until now we aren't serving different sizes - but maybe later
+ $avatarlist = array();
+ // @todo check if "avatar" or "photo" would be the best field in the specification
+ $avatars = $xpath->query($element."/atom:link[@rel='avatar']", $context);
+ foreach($avatars AS $avatar) {
+ $href = "";
+ $width = 0;
+ foreach($avatar->attributes AS $attributes) {
+ if ($attributes->name == "href")
+ $href = $attributes->textContent;
+ if ($attributes->name == "width")
+ $width = $attributes->textContent;
+ if ($attributes->name == "updated")
+ $contact["avatar-date"] = $attributes->textContent;
+ }
+ if (($width > 0) AND ($href != ""))
+ $avatarlist[$width] = $href;
+ }
+ if (count($avatarlist) > 0) {
+ krsort($avatarlist);
+ $author["avatar"] = current($avatarlist);
+ }
+
+ if ($r AND !$onlyfetch) {
+
+ // When was the last change to name or uri?
+ $name_element = $xpath->query($element."/atom:name", $context)->item(0);
+ foreach($name_element->attributes AS $attributes)
+ if ($attributes->name == "updated")
+ $contact["name-date"] = $attributes->textContent;
+
+ $link_element = $xpath->query($element."/atom:link", $context)->item(0);
+ foreach($link_element->attributes AS $attributes)
+ if ($attributes->name == "updated")
+ $contact["uri-date"] = $attributes->textContent;
+
+ // Update contact data
+ $value = $xpath->evaluate($element."/dfrn:handle/text()", $context)->item(0)->nodeValue;
+ if ($value != "")
+ $contact["addr"] = $value;
+
+ $value = $xpath->evaluate($element."/poco:displayName/text()", $context)->item(0)->nodeValue;
+ if ($value != "")
+ $contact["name"] = $value;
+
+ $value = $xpath->evaluate($element."/poco:preferredUsername/text()", $context)->item(0)->nodeValue;
+ if ($value != "")
+ $contact["nick"] = $value;
+
+ $value = $xpath->evaluate($element."/poco:note/text()", $context)->item(0)->nodeValue;
+ if ($value != "")
+ $contact["about"] = $value;
+
+ $value = $xpath->evaluate($element."/poco:address/poco:formatted/text()", $context)->item(0)->nodeValue;
+ if ($value != "")
+ $contact["location"] = $value;
+
+ /// @todo Add support for the following fields that we don't support by now in the contact table:
+ /// - poco:utcOffset
+ /// - poco:ims
+ /// - poco:urls
+ /// - poco:locality
+ /// - poco:region
+ /// - poco:country
+
+ // Save the keywords into the contact table
+ $tags = array();
+ $tagelements = $xpath->evaluate($element."/poco:tags/text()", $context);
+ foreach($tagelements AS $tag)
+ $tags[$tag->nodeValue] = $tag->nodeValue;
+
+ if (count($tags))
+ $contact["keywords"] = implode(", ", $tags);
+
+ // "dfrn:birthday" contains the birthday converted to UTC
+ $old_bdyear = $contact["bdyear"];
+
+ $birthday = $xpath->evaluate($element."/dfrn:birthday/text()", $context)->item(0)->nodeValue;
+
+ if (strtotime($birthday) > time()) {
+ $bd_timestamp = strtotime($birthday);
+
+ $contact["bdyear"] = date("Y", $bd_timestamp);
+ }
+
+ // "poco:birthday" is the birthday in the format "yyyy-mm-dd"
+ $value = $xpath->evaluate($element."/poco:birthday/text()", $context)->item(0)->nodeValue;
+
+ if (!in_array($value, array("", "0000-00-00"))) {
+ $bdyear = date("Y");
+ $value = str_replace("0000", $bdyear, $value);
+
+ if (strtotime($value) < time()) {
+ $value = str_replace($bdyear, $bdyear + 1, $value);
+ $bdyear = $bdyear + 1;
+ }
+
+ $contact["bd"] = $value;
+ }
+
+ if ($old_bdyear != $contact["bdyear"])
+ self::birthday_event($contact, $birthday);
+
+ // Get all field names
+ $fields = array();
+ foreach ($r[0] AS $field => $data)
+ $fields[$field] = $data;
+
+ unset($fields["id"]);
+ unset($fields["uid"]);
+ unset($fields["avatar-date"]);
+ unset($fields["name-date"]);
+ unset($fields["uri-date"]);
+
+ // Update check for this field has to be done differently
+ $datefields = array("name-date", "uri-date");
+ foreach ($datefields AS $field)
+ if (strtotime($contact[$field]) > strtotime($r[0][$field]))
+ $update = true;
+
+ foreach ($fields AS $field => $data)
+ if ($contact[$field] != $r[0][$field]) {
+ logger("Difference for contact ".$contact["id"]." in field '".$field."'. Old value: '".$contact[$field]."', new value '".$r[0][$field]."'", LOGGER_DEBUG);
+ $update = true;
+ }
+
+ if ($update) {
+ logger("Update contact data for contact ".$contact["id"], LOGGER_DEBUG);
+
+ q("UPDATE `contact` SET `name` = '%s', `nick` = '%s', `about` = '%s', `location` = '%s',
+ `addr` = '%s', `keywords` = '%s', `bdyear` = '%s', `bd` = '%s',
+ `name-date` = '%s', `uri-date` = '%s'
+ WHERE `id` = %d AND `network` = '%s'",
+ dbesc($contact["name"]), dbesc($contact["nick"]), dbesc($contact["about"]), dbesc($contact["location"]),
+ dbesc($contact["addr"]), dbesc($contact["keywords"]), dbesc($contact["bdyear"]),
+ dbesc($contact["bd"]), dbesc($contact["name-date"]), dbesc($contact["uri-date"]),
+ intval($contact["id"]), dbesc($contact["network"]));
+ }
+
+ update_contact_avatar($author["avatar"], $importer["uid"], $contact["id"],
+ (strtotime($contact["avatar-date"]) > strtotime($r[0]["avatar-date"])));
+
+ // The generation is a sign for the reliability of the provided data.
+ // It is used in the socgraph.php to prevent that old contact data
+ // that was relayed over several servers can overwrite contact
+ // data that we received directly.
+ $contact["generation"] = 2;
+ $contact["photo"] = $author["avatar"];
+ update_gcontact($contact);
+ }
+
+ return($author);
+ }
+
+ /**
+ * @brief Transforms activity objects into an XML string
+ *
+ * @param object $xpath XPath object
+ * @param object $activity Activity object
+ * @param text $element element name
+ *
+ * @return string XML string
+ */
+ private function transform_activity($xpath, $activity, $element) {
+ if (!is_object($activity))
+ return "";
+
+ $obj_doc = new DOMDocument("1.0", "utf-8");
+ $obj_doc->formatOutput = true;
+
+ $obj_element = $obj_doc->createElementNS(NAMESPACE_ATOM1, $element);
+
+ $activity_type = $xpath->query("activity:object-type/text()", $activity)->item(0)->nodeValue;
+ xml_add_element($obj_doc, $obj_element, "type", $activity_type);
+
+ $id = $xpath->query("atom:id", $activity)->item(0);
+ if (is_object($id))
+ $obj_element->appendChild($obj_doc->importNode($id, true));
+
+ $title = $xpath->query("atom:title", $activity)->item(0);
+ if (is_object($title))
+ $obj_element->appendChild($obj_doc->importNode($title, true));
+
+ $link = $xpath->query("atom:link", $activity)->item(0);
+ if (is_object($link))
+ $obj_element->appendChild($obj_doc->importNode($link, true));
+
+ $content = $xpath->query("atom:content", $activity)->item(0);
+ if (is_object($content))
+ $obj_element->appendChild($obj_doc->importNode($content, true));
+
+ $obj_doc->appendChild($obj_element);
+
+ $objxml = $obj_doc->saveXML($obj_element);
+
+ // @todo This isn't totally clean. We should find a way to transform the namespaces
+ $objxml = str_replace("<".$element.' xmlns="http://www.w3.org/2005/Atom">', "<".$element.">", $objxml);
+ return($objxml);
+ }
+
+ /**
+ * @brief Processes the mail elements
+ *
+ * @param object $xpath XPath object
+ * @param object $mail mail elements
+ * @param array $importer Record of the importer user mixed with contact of the content
+ */
+ private function process_mail($xpath, $mail, $importer) {
+
+ logger("Processing mails");
+
+ $msg = array();
+ $msg["uid"] = $importer["importer_uid"];
+ $msg["from-name"] = $xpath->query("dfrn:sender/dfrn:name/text()", $mail)->item(0)->nodeValue;
+ $msg["from-url"] = $xpath->query("dfrn:sender/dfrn:uri/text()", $mail)->item(0)->nodeValue;
+ $msg["from-photo"] = $xpath->query("dfrn:sender/dfrn:avatar/text()", $mail)->item(0)->nodeValue;
+ $msg["contact-id"] = $importer["id"];
+ $msg["uri"] = $xpath->query("dfrn:id/text()", $mail)->item(0)->nodeValue;
+ $msg["parent-uri"] = $xpath->query("dfrn:in-reply-to/text()", $mail)->item(0)->nodeValue;
+ $msg["created"] = $xpath->query("dfrn:sentdate/text()", $mail)->item(0)->nodeValue;
+ $msg["title"] = $xpath->query("dfrn:subject/text()", $mail)->item(0)->nodeValue;
+ $msg["body"] = $xpath->query("dfrn:content/text()", $mail)->item(0)->nodeValue;
+ $msg["seen"] = 0;
+ $msg["replied"] = 0;
+
+ dbesc_array($msg);
+
+ $r = dbq("INSERT INTO `mail` (`".implode("`, `", array_keys($msg))."`) VALUES ('".implode("', '", array_values($msg))."')");
+
+ // send notifications.
+
+ $notif_params = array(
+ "type" => NOTIFY_MAIL,
+ "notify_flags" => $importer["notify-flags"],
+ "language" => $importer["language"],
+ "to_name" => $importer["username"],
+ "to_email" => $importer["email"],
+ "uid" => $importer["importer_uid"],
+ "item" => $msg,
+ "source_name" => $msg["from-name"],
+ "source_link" => $importer["url"],
+ "source_photo" => $importer["thumb"],
+ "verb" => ACTIVITY_POST,
+ "otype" => "mail"
+ );
+
+ notification($notif_params);
+
+ logger("Mail is processed, notification was sent.");
+ }
+
+ /**
+ * @brief Processes the suggestion elements
+ *
+ * @param object $xpath XPath object
+ * @param object $suggestion suggestion elements
+ * @param array $importer Record of the importer user mixed with contact of the content
+ */
+ private function process_suggestion($xpath, $suggestion, $importer) {
+
+ logger("Processing suggestions");
+
+ $suggest = array();
+ $suggest["uid"] = $importer["importer_uid"];
+ $suggest["cid"] = $importer["id"];
+ $suggest["url"] = $xpath->query("dfrn:url/text()", $suggestion)->item(0)->nodeValue;
+ $suggest["name"] = $xpath->query("dfrn:name/text()", $suggestion)->item(0)->nodeValue;
+ $suggest["photo"] = $xpath->query("dfrn:photo/text()", $suggestion)->item(0)->nodeValue;
+ $suggest["request"] = $xpath->query("dfrn:request/text()", $suggestion)->item(0)->nodeValue;
+ $suggest["body"] = $xpath->query("dfrn:note/text()", $suggestion)->item(0)->nodeValue;
+
+ // Does our member already have a friend matching this description?
+
+ $r = q("SELECT `id` FROM `contact` WHERE `name` = '%s' AND `nurl` = '%s' AND `uid` = %d LIMIT 1",
+ dbesc($suggest["name"]),
+ dbesc(normalise_link($suggest["url"])),
+ intval($suggest["uid"])
+ );
+ if(count($r))
+ return false;
+
+ // Do we already have an fcontact record for this person?
+
+ $fid = 0;
+ $r = q("SELECT `id` FROM `fcontact` WHERE `url` = '%s' AND `name` = '%s' AND `request` = '%s' LIMIT 1",
+ dbesc($suggest["url"]),
+ dbesc($suggest["name"]),
+ dbesc($suggest["request"])
+ );
+ if(count($r)) {
+ $fid = $r[0]["id"];
+
+ // OK, we do. Do we already have an introduction for this person ?
+ $r = q("SELECT `id` FROM `intro` WHERE `uid` = %d AND `fid` = %d LIMIT 1",
+ intval($suggest["uid"]),
+ intval($fid)
+ );
+ if(count($r))
+ return false;
+ }
+ if(!$fid)
+ $r = q("INSERT INTO `fcontact` (`name`,`url`,`photo`,`request`) VALUES ('%s', '%s', '%s', '%s')",
+ dbesc($suggest["name"]),
+ dbesc($suggest["url"]),
+ dbesc($suggest["photo"]),
+ dbesc($suggest["request"])
+ );
+ $r = q("SELECT `id` FROM `fcontact` WHERE `url` = '%s' AND `name` = '%s' AND `request` = '%s' LIMIT 1",
+ dbesc($suggest["url"]),
+ dbesc($suggest["name"]),
+ dbesc($suggest["request"])
+ );
+ if(count($r))
+ $fid = $r[0]["id"];
+ else
+ // database record did not get created. Quietly give up.
+ return false;
+
+
+ $hash = random_string();
+
+ $r = q("INSERT INTO `intro` (`uid`, `fid`, `contact-id`, `note`, `hash`, `datetime`, `blocked`)
+ VALUES(%d, %d, %d, '%s', '%s', '%s', %d)",
+ intval($suggest["uid"]),
+ intval($fid),
+ intval($suggest["cid"]),
+ dbesc($suggest["body"]),
+ dbesc($hash),
+ dbesc(datetime_convert()),
+ intval(0)
+ );
+
+ notification(array(
+ "type" => NOTIFY_SUGGEST,
+ "notify_flags" => $importer["notify-flags"],
+ "language" => $importer["language"],
+ "to_name" => $importer["username"],
+ "to_email" => $importer["email"],
+ "uid" => $importer["importer_uid"],
+ "item" => $suggest,
+ "link" => App::get_baseurl()."/notifications/intros",
+ "source_name" => $importer["name"],
+ "source_link" => $importer["url"],
+ "source_photo" => $importer["photo"],
+ "verb" => ACTIVITY_REQ_FRIEND,
+ "otype" => "intro"
+ ));
+
+ return true;
+
+ }
+
+ /**
+ * @brief Processes the relocation elements
+ *
+ * @param object $xpath XPath object
+ * @param object $relocation relocation elements
+ * @param array $importer Record of the importer user mixed with contact of the content
+ */
+ private function process_relocation($xpath, $relocation, $importer) {
+
+ logger("Processing relocations");
+
+ $relocate = array();
+ $relocate["uid"] = $importer["importer_uid"];
+ $relocate["cid"] = $importer["id"];
+ $relocate["url"] = $xpath->query("dfrn:url/text()", $relocation)->item(0)->nodeValue;
+ $relocate["name"] = $xpath->query("dfrn:name/text()", $relocation)->item(0)->nodeValue;
+ $relocate["photo"] = $xpath->query("dfrn:photo/text()", $relocation)->item(0)->nodeValue;
+ $relocate["thumb"] = $xpath->query("dfrn:thumb/text()", $relocation)->item(0)->nodeValue;
+ $relocate["micro"] = $xpath->query("dfrn:micro/text()", $relocation)->item(0)->nodeValue;
+ $relocate["request"] = $xpath->query("dfrn:request/text()", $relocation)->item(0)->nodeValue;
+ $relocate["confirm"] = $xpath->query("dfrn:confirm/text()", $relocation)->item(0)->nodeValue;
+ $relocate["notify"] = $xpath->query("dfrn:notify/text()", $relocation)->item(0)->nodeValue;
+ $relocate["poll"] = $xpath->query("dfrn:poll/text()", $relocation)->item(0)->nodeValue;
+ $relocate["sitepubkey"] = $xpath->query("dfrn:sitepubkey/text()", $relocation)->item(0)->nodeValue;
+
+ // update contact
+ $r = q("SELECT `photo`, `url` FROM `contact` WHERE `id` = %d AND `uid` = %d;",
+ intval($importer["id"]),
+ intval($importer["importer_uid"]));
+ if (!$r)
+ return false;
+
+ $old = $r[0];
+
+ $x = q("UPDATE `contact` SET
+ `name` = '%s',
+ `photo` = '%s',
+ `thumb` = '%s',
+ `micro` = '%s',
+ `url` = '%s',
+ `nurl` = '%s',
+ `request` = '%s',
+ `confirm` = '%s',
+ `notify` = '%s',
+ `poll` = '%s',
+ `site-pubkey` = '%s'
+ WHERE `id` = %d AND `uid` = %d;",
+ dbesc($relocate["name"]),
+ dbesc($relocate["photo"]),
+ dbesc($relocate["thumb"]),
+ dbesc($relocate["micro"]),
+ dbesc($relocate["url"]),
+ dbesc(normalise_link($relocate["url"])),
+ dbesc($relocate["request"]),
+ dbesc($relocate["confirm"]),
+ dbesc($relocate["notify"]),
+ dbesc($relocate["poll"]),
+ dbesc($relocate["sitepubkey"]),
+ intval($importer["id"]),
+ intval($importer["importer_uid"]));
+
+ if ($x === false)
+ return false;
+
+ // update items
+ $fields = array(
+ 'owner-link' => array($old["url"], $relocate["url"]),
+ 'author-link' => array($old["url"], $relocate["url"]),
+ 'owner-avatar' => array($old["photo"], $relocate["photo"]),
+ 'author-avatar' => array($old["photo"], $relocate["photo"]),
+ );
+ foreach ($fields as $n=>$f){
+ $x = q("UPDATE `item` SET `%s` = '%s' WHERE `%s` = '%s' AND `uid` = %d",
+ $n, dbesc($f[1]),
+ $n, dbesc($f[0]),
+ intval($importer["importer_uid"]));
+ if ($x === false)
+ return false;
+ }
+
+ /// @TODO
+ /// merge with current record, current contents have priority
+ /// update record, set url-updated
+ /// update profile photos
+ /// schedule a scan?
+ return true;
+ }
+
+ /**
+ * @brief Updates an item
+ *
+ * @param array $current the current item record
+ * @param array $item the new item record
+ * @param array $importer Record of the importer user mixed with contact of the content
+ * @param int $entrytype Is it a toplevel entry, a comment or a relayed comment?
+ */
+ private function update_content($current, $item, $importer, $entrytype) {
+ $changed = false;
+
+ if (edited_timestamp_is_newer($current, $item)) {
+
+ // do not accept (ignore) an earlier edit than one we currently have.
+ if(datetime_convert("UTC","UTC",$item["edited"]) < $current["edited"])
+ return(false);
+
+ $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s', `changed` = '%s' WHERE `uri` = '%s' AND `uid` = %d",
+ dbesc($item["title"]),
+ dbesc($item["body"]),
+ dbesc($item["tag"]),
+ dbesc(datetime_convert("UTC","UTC",$item["edited"])),
+ dbesc(datetime_convert()),
+ dbesc($item["uri"]),
+ intval($importer["importer_uid"])
+ );
+ create_tags_from_itemuri($item["uri"], $importer["importer_uid"]);
+ update_thread_uri($item["uri"], $importer["importer_uid"]);
+
+ $changed = true;
+
+ if ($entrytype == DFRN_REPLY_RC)
+ proc_run("php", "include/notifier.php","comment-import", $current["id"]);
+ }
+
+ // update last-child if it changes
+ if($item["last-child"] AND ($item["last-child"] != $current["last-child"])) {
+ $r = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d",
+ dbesc(datetime_convert()),
+ dbesc($item["parent-uri"]),
+ intval($importer["importer_uid"])
+ );
+ $r = q("UPDATE `item` SET `last-child` = %d , `changed` = '%s' WHERE `uri` = '%s' AND `uid` = %d",
+ intval($item["last-child"]),
+ dbesc(datetime_convert()),
+ dbesc($item["uri"]),
+ intval($importer["importer_uid"])
+ );
+ }
+ return $changed;
+ }
+
+ /**
+ * @brief Detects the entry type of the item
+ *
+ * @param array $importer Record of the importer user mixed with contact of the content
+ * @param array $item the new item record
+ *
+ * @return int Is it a toplevel entry, a comment or a relayed comment?
+ */
+ private function get_entry_type($importer, $item) {
+ if ($item["parent-uri"] != $item["uri"]) {
+ $community = false;
+
+ if($importer["page-flags"] == PAGE_COMMUNITY || $importer["page-flags"] == PAGE_PRVGROUP) {
+ $sql_extra = "";
+ $community = true;
+ logger("possible community action");
+ } else
+ $sql_extra = " AND `contact`.`self` AND `item`.`wall` ";
+
+ // was the top-level post for this action written by somebody on this site?
+ // Specifically, the recipient?
+
+ $is_a_remote_action = false;
+
+ $r = q("SELECT `item`.`parent-uri` FROM `item`
+ WHERE `item`.`uri` = '%s'
+ LIMIT 1",
+ dbesc($item["parent-uri"])
+ );
+ if($r && count($r)) {
+ $r = q("SELECT `item`.`forum_mode`, `item`.`wall` FROM `item`
+ INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
+ WHERE `item`.`uri` = '%s' AND (`item`.`parent-uri` = '%s' OR `item`.`thr-parent` = '%s')
+ AND `item`.`uid` = %d
+ $sql_extra
+ LIMIT 1",
+ dbesc($r[0]["parent-uri"]),
+ dbesc($r[0]["parent-uri"]),
+ dbesc($r[0]["parent-uri"]),
+ intval($importer["importer_uid"])
+ );
+ if($r && count($r))
+ $is_a_remote_action = true;
+ }
+
+ // Does this have the characteristics of a community or private group action?
+ // If it's an action to a wall post on a community/prvgroup page it's a
+ // valid community action. Also forum_mode makes it valid for sure.
+ // If neither, it's not.
+
+ if($is_a_remote_action && $community) {
+ if((!$r[0]["forum_mode"]) && (!$r[0]["wall"])) {
+ $is_a_remote_action = false;
+ logger("not a community action");
+ }
+ }
+
+ if ($is_a_remote_action)
+ return DFRN_REPLY_RC;
+ else
+ return DFRN_REPLY;
+
+ } else
+ return DFRN_TOP_LEVEL;
+
+ }
+
+ /**
+ * @brief Send a "poke"
+ *
+ * @param array $item the new item record
+ * @param array $importer Record of the importer user mixed with contact of the content
+ * @param int $posted_id The record number of item record that was just posted
+ */
+ private function do_poke($item, $importer, $posted_id) {
+ $verb = urldecode(substr($item["verb"],strpos($item["verb"], "#")+1));
+ if(!$verb)
+ return;
+ $xo = parse_xml_string($item["object"],false);
+
+ if(($xo->type == ACTIVITY_OBJ_PERSON) && ($xo->id)) {
+
+ // somebody was poked/prodded. Was it me?
+ foreach($xo->link as $l) {
+ $atts = $l->attributes();
+ switch($atts["rel"]) {
+ case "alternate":
+ $Blink = $atts["href"];
+ break;
+ default:
+ break;
+ }
+ }
+
+ if($Blink && link_compare($Blink,App::get_baseurl()."/profile/".$importer["nickname"])) {
+
+ // send a notification
+ notification(array(
+ "type" => NOTIFY_POKE,
+ "notify_flags" => $importer["notify-flags"],
+ "language" => $importer["language"],
+ "to_name" => $importer["username"],
+ "to_email" => $importer["email"],
+ "uid" => $importer["importer_uid"],
+ "item" => $item,
+ "link" => App::get_baseurl()."/display/".urlencode(get_item_guid($posted_id)),
+ "source_name" => stripslashes($item["author-name"]),
+ "source_link" => $item["author-link"],
+ "source_photo" => ((link_compare($item["author-link"],$importer["url"]))
+ ? $importer["thumb"] : $item["author-avatar"]),
+ "verb" => $item["verb"],
+ "otype" => "person",
+ "activity" => $verb,
+ "parent" => $item["parent"]
+ ));
+ }
+ }
+ }
+
+ /**
+ * @brief Processes several actions, depending on the verb
+ *
+ * @param int $entrytype Is it a toplevel entry, a comment or a relayed comment?
+ * @param array $importer Record of the importer user mixed with contact of the content
+ * @param array $item the new item record
+ * @param bool $is_like Is the verb a "like"?
+ *
+ * @return bool Should the processing of the entries be continued?
+ */
+ private function process_verbs($entrytype, $importer, &$item, &$is_like) {
+ if (($entrytype == DFRN_TOP_LEVEL)) {
+ // The filling of the the "contact" variable is done for legcy reasons
+ // The functions below are partly used by ostatus.php as well - where we have this variable
+ $r = q("SELECT * FROM `contact` WHERE `id` = %d", intval($importer["id"]));
+ $contact = $r[0];
+ $nickname = $contact["nick"];
+
+ // Big question: Do we need these functions? They were part of the "consume_feed" function.
+ // This function once was responsible for DFRN and OStatus.
+ if(activity_match($item["verb"],ACTIVITY_FOLLOW)) {
+ logger("New follower");
+ new_follower($importer, $contact, $item, $nickname);
+ return false;
+ }
+ if(activity_match($item["verb"],ACTIVITY_UNFOLLOW)) {
+ logger("Lost follower");
+ lose_follower($importer, $contact, $item);
+ return false;
+ }
+ if(activity_match($item["verb"],ACTIVITY_REQ_FRIEND)) {
+ logger("New friend request");
+ new_follower($importer, $contact, $item, $nickname, true);
+ return false;
+ }
+ if(activity_match($item["verb"],ACTIVITY_UNFRIEND)) {
+ logger("Lost sharer");
+ lose_sharer($importer, $contact, $item);
+ return false;
+ }
+ } else {
+ if(($item["verb"] === ACTIVITY_LIKE)
+ || ($item["verb"] === ACTIVITY_DISLIKE)
+ || ($item["verb"] === ACTIVITY_ATTEND)
+ || ($item["verb"] === ACTIVITY_ATTENDNO)
+ || ($item["verb"] === ACTIVITY_ATTENDMAYBE)) {
+ $is_like = true;
+ $item["type"] = "activity";
+ $item["gravity"] = GRAVITY_LIKE;
+ // only one like or dislike per person
+ // splitted into two queries for performance issues
+ $r = q("SELECT `id` FROM `item` WHERE `uid` = %d AND `author-link` = '%s' AND `verb` = '%s' AND `parent-uri` = '%s' AND NOT `deleted` LIMIT 1",
+ intval($item["uid"]),
+ dbesc($item["author-link"]),
+ dbesc($item["verb"]),
+ dbesc($item["parent-uri"])
+ );
+ if($r && count($r))
+ return false;
+
+ $r = q("SELECT `id` FROM `item` WHERE `uid` = %d AND `author-link` = '%s' AND `verb` = '%s' AND `thr-parent` = '%s' AND NOT `deleted` LIMIT 1",
+ intval($item["uid"]),
+ dbesc($item["author-link"]),
+ dbesc($item["verb"]),
+ dbesc($item["parent-uri"])
+ );
+ if($r && count($r))
+ return false;
+ } else
+ $is_like = false;
+
+ if(($item["verb"] === ACTIVITY_TAG) && ($item["object-type"] === ACTIVITY_OBJ_TAGTERM)) {
+
+ $xo = parse_xml_string($item["object"],false);
+ $xt = parse_xml_string($item["target"],false);
+
+ if($xt->type == ACTIVITY_OBJ_NOTE) {
+ $r = q("SELECT `id`, `tag` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
+ dbesc($xt->id),
+ intval($importer["importer_uid"])
+ );
+
+ if(!count($r))
+ return false;
+
+ // extract tag, if not duplicate, add to parent item
+ if($xo->content) {
+ if(!(stristr($r[0]["tag"],trim($xo->content)))) {
+ q("UPDATE `item` SET `tag` = '%s' WHERE `id` = %d",
+ dbesc($r[0]["tag"] . (strlen($r[0]["tag"]) ? ',' : '') . '#[url=' . $xo->id . ']'. $xo->content . '[/url]'),
+ intval($r[0]["id"])
+ );
+ create_tags_from_item($r[0]["id"]);
+ }
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * @brief Processes the link elements
+ *
+ * @param object $links link elements
+ * @param array $item the item record
+ */
+ private function parse_links($links, &$item) {
+ $rel = "";
+ $href = "";
+ $type = "";
+ $length = "0";
+ $title = "";
+ foreach ($links AS $link) {
+ foreach($link->attributes AS $attributes) {
+ if ($attributes->name == "href")
+ $href = $attributes->textContent;
+ if ($attributes->name == "rel")
+ $rel = $attributes->textContent;
+ if ($attributes->name == "type")
+ $type = $attributes->textContent;
+ if ($attributes->name == "length")
+ $length = $attributes->textContent;
+ if ($attributes->name == "title")
+ $title = $attributes->textContent;
+ }
+ if (($rel != "") AND ($href != ""))
+ switch($rel) {
+ case "alternate":
+ $item["plink"] = $href;
+ break;
+ case "enclosure":
+ $enclosure = $href;
+ if(strlen($item["attach"]))
+ $item["attach"] .= ",";
+
+ $item["attach"] .= '[attach]href="'.$href.'" length="'.$length.'" type="'.$type.'" title="'.$title.'"[/attach]';
+ break;
+ }
+ }
+ }
+
+ /**
+ * @brief Processes the entry elements which contain the items and comments
+ *
+ * @param array $header Array of the header elements that always stay the same
+ * @param object $xpath XPath object
+ * @param object $entry entry elements
+ * @param array $importer Record of the importer user mixed with contact of the content
+ */
+ private function process_entry($header, $xpath, $entry, $importer) {
+
+ logger("Processing entries");
+
+ $item = $header;
+
+ // Get the uri
+ $item["uri"] = $xpath->query("atom:id/text()", $entry)->item(0)->nodeValue;
+
+ // Fetch the owner
+ $owner = self::fetchauthor($xpath, $entry, $importer, "dfrn:owner", true);
+
+ $item["owner-name"] = $owner["name"];
+ $item["owner-link"] = $owner["link"];
+ $item["owner-avatar"] = $owner["avatar"];
+
+ // fetch the author
+ $author = self::fetchauthor($xpath, $entry, $importer, "atom:author", true);
+
+ $item["author-name"] = $author["name"];
+ $item["author-link"] = $author["link"];
+ $item["author-avatar"] = $author["avatar"];
+
+ $item["title"] = $xpath->query("atom:title/text()", $entry)->item(0)->nodeValue;
+
+ $item["created"] = $xpath->query("atom:published/text()", $entry)->item(0)->nodeValue;
+ $item["edited"] = $xpath->query("atom:updated/text()", $entry)->item(0)->nodeValue;
+
+ $item["body"] = $xpath->query("dfrn:env/text()", $entry)->item(0)->nodeValue;
+ $item["body"] = str_replace(array(' ',"\t","\r","\n"), array('','','',''),$item["body"]);
+ // make sure nobody is trying to sneak some html tags by us
+ $item["body"] = notags(base64url_decode($item["body"]));
+
+ $item["body"] = limit_body_size($item["body"]);
+
+ /// @todo Do we really need this check for HTML elements? (It was copied from the old function)
+ if((strpos($item['body'],'<') !== false) && (strpos($item['body'],'>') !== false)) {
+
+ $item['body'] = reltoabs($item['body'],$base_url);
+
+ $item['body'] = html2bb_video($item['body']);
+
+ $item['body'] = oembed_html2bbcode($item['body']);
+
+ $config = HTMLPurifier_Config::createDefault();
+ $config->set('Cache.DefinitionImpl', null);
+
+ // we shouldn't need a whitelist, because the bbcode converter
+ // will strip out any unsupported tags.
+
+ $purifier = new HTMLPurifier($config);
+ $item['body'] = $purifier->purify($item['body']);
+
+ $item['body'] = @html2bbcode($item['body']);
+ }
+
+ // We don't need the content element since "dfrn:env" is always present
+ //$item["body"] = $xpath->query("atom:content/text()", $entry)->item(0)->nodeValue;
+
+ $item["last-child"] = $xpath->query("dfrn:comment-allow/text()", $entry)->item(0)->nodeValue;
+ $item["location"] = $xpath->query("dfrn:location/text()", $entry)->item(0)->nodeValue;
+
+ $georsspoint = $xpath->query("georss:point", $entry);
+ if ($georsspoint)
+ $item["coord"] = $georsspoint->item(0)->nodeValue;
+
+ $item["private"] = $xpath->query("dfrn:private/text()", $entry)->item(0)->nodeValue;
+
+ $item["extid"] = $xpath->query("dfrn:extid/text()", $entry)->item(0)->nodeValue;
+
+ if ($xpath->query("dfrn:extid/text()", $entry)->item(0)->nodeValue == "true")
+ $item["bookmark"] = true;
+
+ $notice_info = $xpath->query("statusnet:notice_info", $entry);
+ if ($notice_info AND ($notice_info->length > 0)) {
+ foreach($notice_info->item(0)->attributes AS $attributes) {
+ if ($attributes->name == "source")
+ $item["app"] = strip_tags($attributes->textContent);
+ }
+ }
+
+ $item["guid"] = $xpath->query("dfrn:diaspora_guid/text()", $entry)->item(0)->nodeValue;
+
+ // We store the data from "dfrn:diaspora_signature" in a different table, this is done in "item_store"
+ $dsprsig = unxmlify($xpath->query("dfrn:diaspora_signature/text()", $entry)->item(0)->nodeValue);
+ if ($dsprsig != "")
+ $item["dsprsig"] = $dsprsig;
+
+ $item["verb"] = $xpath->query("activity:verb/text()", $entry)->item(0)->nodeValue;
+
+ if ($xpath->query("activity:object-type/text()", $entry)->item(0)->nodeValue != "")
+ $item["object-type"] = $xpath->query("activity:object-type/text()", $entry)->item(0)->nodeValue;
+
+ $object = $xpath->query("activity:object", $entry)->item(0);
+ $item["object"] = self::transform_activity($xpath, $object, "object");
+
+ if (trim($item["object"]) != "") {
+ $r = parse_xml_string($item["object"], false);
+ if (isset($r->type))
+ $item["object-type"] = $r->type;
+ }
+
+ $target = $xpath->query("activity:target", $entry)->item(0);
+ $item["target"] = self::transform_activity($xpath, $target, "target");
+
+ $categories = $xpath->query("atom:category", $entry);
+ if ($categories) {
+ foreach ($categories AS $category) {
+ foreach($category->attributes AS $attributes)
+ if ($attributes->name == "term") {
+ $term = $attributes->textContent;
+ if(strlen($item["tag"]))
+ $item["tag"] .= ",";
+
+ $item["tag"] .= "#[url=".App::get_baseurl()."/search?tag=".$term."]".$term."[/url]";
+ }
+ }
+ }
+
+ $enclosure = "";
+
+ $links = $xpath->query("atom:link", $entry);
+ if ($links)
+ self::parse_links($links, $item);
+
+ // Is it a reply or a top level posting?
+ $item["parent-uri"] = $item["uri"];
+
+ $inreplyto = $xpath->query("thr:in-reply-to", $entry);
+ if (is_object($inreplyto->item(0)))
+ foreach($inreplyto->item(0)->attributes AS $attributes)
+ if ($attributes->name == "ref")
+ $item["parent-uri"] = $attributes->textContent;
+
+ // Get the type of the item (Top level post, reply or remote reply)
+ $entrytype = self::get_entry_type($importer, $item);
+
+ // Now assign the rest of the values that depend on the type of the message
+ if (in_array($entrytype, array(DFRN_REPLY, DFRN_REPLY_RC))) {
+ if (!isset($item["object-type"]))
+ $item["object-type"] = ACTIVITY_OBJ_COMMENT;
+
+ if ($item["contact-id"] != $owner["contact-id"])
+ $item["contact-id"] = $owner["contact-id"];
+
+ if (($item["network"] != $owner["network"]) AND ($owner["network"] != ""))
+ $item["network"] = $owner["network"];
+
+ if ($item["contact-id"] != $author["contact-id"])
+ $item["contact-id"] = $author["contact-id"];
+
+ if (($item["network"] != $author["network"]) AND ($author["network"] != ""))
+ $item["network"] = $author["network"];
+
+ if($importer["rel"] == CONTACT_IS_FOLLOWER) {
+ logger("Contact ".$importer["id"]." is only follower. Quitting", LOGGER_DEBUG);
+ return;
+ }
+ }
+
+ if ($entrytype == DFRN_REPLY_RC) {
+ $item["type"] = "remote-comment";
+ $item["wall"] = 1;
+ } elseif ($entrytype == DFRN_TOP_LEVEL) {
+ if (!isset($item["object-type"]))
+ $item["object-type"] = ACTIVITY_OBJ_NOTE;
+
+ // Is it an event?
+ if ($item["object-type"] == ACTIVITY_OBJ_EVENT) {
+ logger("Item ".$item["uri"]." seems to contain an event.", LOGGER_DEBUG);
+ $ev = bbtoevent($item["body"]);
+ if((x($ev, "desc") || x($ev, "summary")) && x($ev, "start")) {
+ logger("Event in item ".$item["uri"]." was found.", LOGGER_DEBUG);
+ $ev["cid"] = $importer["id"];
+ $ev["uid"] = $importer["uid"];
+ $ev["uri"] = $item["uri"];
+ $ev["edited"] = $item["edited"];
+ $ev['private'] = $item['private'];
+ $ev["guid"] = $item["guid"];
+
+ $r = q("SELECT `id` FROM `event` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
+ dbesc($item["uri"]),
+ intval($importer["uid"])
+ );
+ if(count($r))
+ $ev["id"] = $r[0]["id"];
+
+ $event_id = event_store($ev);
+ logger("Event ".$event_id." was stored", LOGGER_DEBUG);
+ return;
+ }
+ }
+ }
+
+ $r = q("SELECT `id`, `uid`, `last-child`, `edited`, `body` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
+ dbesc($item["uri"]),
+ intval($importer["importer_uid"])
+ );
+
+ if (!self::process_verbs($entrytype, $importer, $item, $is_like)) {
+ logger("Exiting because 'process_verbs' told us so", LOGGER_DEBUG);
+ return;
+ }
+
+ // Update content if 'updated' changes
+ if(count($r)) {
+ if (self::update_content($r[0], $item, $importer, $entrytype))
+ logger("Item ".$item["uri"]." was updated.", LOGGER_DEBUG);
+ else
+ logger("Item ".$item["uri"]." already existed.", LOGGER_DEBUG);
+ return;
+ }
+
+ if (in_array($entrytype, array(DFRN_REPLY, DFRN_REPLY_RC))) {
+ $posted_id = item_store($item);
+ $parent = 0;
+
+ if($posted_id) {
+
+ logger("Reply from contact ".$item["contact-id"]." was stored with id ".$posted_id, LOGGER_DEBUG);
+
+ $item["id"] = $posted_id;
+
+ $r = q("SELECT `parent`, `parent-uri` FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1",
+ intval($posted_id),
+ intval($importer["importer_uid"])
+ );
+ if(count($r)) {
+ $parent = $r[0]["parent"];
+ $parent_uri = $r[0]["parent-uri"];
+ }
+
+ if(!$is_like) {
+ $r1 = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `uid` = %d AND `parent` = %d",
+ dbesc(datetime_convert()),
+ intval($importer["importer_uid"]),
+ intval($r[0]["parent"])
+ );
+
+ $r2 = q("UPDATE `item` SET `last-child` = 1, `changed` = '%s' WHERE `uid` = %d AND `id` = %d",
+ dbesc(datetime_convert()),
+ intval($importer["importer_uid"]),
+ intval($posted_id)
+ );
+ }
+
+ if($posted_id AND $parent AND ($entrytype == DFRN_REPLY_RC)) {
+ logger("Notifying followers about comment ".$posted_id, LOGGER_DEBUG);
+ proc_run("php", "include/notifier.php", "comment-import", $posted_id);
+ }
+
+ return true;
+ }
+ } else { // $entrytype == DFRN_TOP_LEVEL
+ if(!link_compare($item["owner-link"],$importer["url"])) {
+ // The item owner info is not our contact. It's OK and is to be expected if this is a tgroup delivery,
+ // but otherwise there's a possible data mixup on the sender's system.
+ // the tgroup delivery code called from item_store will correct it if it's a forum,
+ // but we're going to unconditionally correct it here so that the post will always be owned by our contact.
+ logger('Correcting item owner.', LOGGER_DEBUG);
+ $item["owner-name"] = $importer["senderName"];
+ $item["owner-link"] = $importer["url"];
+ $item["owner-avatar"] = $importer["thumb"];
+ }
+
+ if(($importer["rel"] == CONTACT_IS_FOLLOWER) && (!tgroup_check($importer["importer_uid"], $item))) {
+ logger("Contact ".$importer["id"]." is only follower and tgroup check was negative.", LOGGER_DEBUG);
+ return;
+ }
+
+ // This is my contact on another system, but it's really me.
+ // Turn this into a wall post.
+ $notify = item_is_remote_self($importer, $item);
+
+ $posted_id = item_store($item, false, $notify);
+
+ logger("Item was stored with id ".$posted_id, LOGGER_DEBUG);
+
+ if(stristr($item["verb"],ACTIVITY_POKE))
+ self::do_poke($item, $importer, $posted_id);
+ }
+ }
+
+ /**
+ * @brief Deletes items
+ *
+ * @param object $xpath XPath object
+ * @param object $deletion deletion elements
+ * @param array $importer Record of the importer user mixed with contact of the content
+ */
+ private function process_deletion($xpath, $deletion, $importer) {
+
+ logger("Processing deletions");
+
+ foreach($deletion->attributes AS $attributes) {
+ if ($attributes->name == "ref")
+ $uri = $attributes->textContent;
+ if ($attributes->name == "when")
+ $when = $attributes->textContent;
+ }
+ if ($when)
+ $when = datetime_convert("UTC", "UTC", $when, "Y-m-d H:i:s");
+ else
+ $when = datetime_convert("UTC", "UTC", "now", "Y-m-d H:i:s");
+
+ if (!$uri OR !$importer["id"])
+ return false;
+
+ /// @todo Only select the used fields
+ $r = q("SELECT `item`.*, `contact`.`self` FROM `item` INNER JOIN `contact` on `item`.`contact-id` = `contact`.`id`
+ WHERE `uri` = '%s' AND `item`.`uid` = %d AND `contact-id` = %d AND NOT `item`.`file` LIKE '%%[%%' LIMIT 1",
+ dbesc($uri),
+ intval($importer["uid"]),
+ intval($importer["id"])
+ );
+ if(!count($r)) {
+ logger("Item with uri ".$uri." from contact ".$importer["id"]." for user ".$importer["uid"]." wasn't found.", LOGGER_DEBUG);
+ return;
+ } else {
+
+ $item = $r[0];
+
+ $entrytype = self::get_entry_type($importer, $item);
+
+ if(!$item["deleted"])
+ logger('deleting item '.$item["id"].' uri='.$uri, LOGGER_DEBUG);
+ else
+ return;
+
+ if($item["object-type"] === ACTIVITY_OBJ_EVENT) {
+ logger("Deleting event ".$item["event-id"], LOGGER_DEBUG);
+ event_delete($item["event-id"]);
+ }
+
+ if(($item["verb"] === ACTIVITY_TAG) && ($item["object-type"] === ACTIVITY_OBJ_TAGTERM)) {
+ $xo = parse_xml_string($item["object"],false);
+ $xt = parse_xml_string($item["target"],false);
+ if($xt->type === ACTIVITY_OBJ_NOTE) {
+ $i = q("SELECT `id`, `contact-id`, `tag` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
+ dbesc($xt->id),
+ intval($importer["importer_uid"])
+ );
+ if(count($i)) {
+
+ // For tags, the owner cannot remove the tag on the author's copy of the post.
+
+ $owner_remove = (($item["contact-id"] == $i[0]["contact-id"]) ? true: false);
+ $author_remove = (($item["origin"] && $item["self"]) ? true : false);
+ $author_copy = (($item["origin"]) ? true : false);
+
+ if($owner_remove && $author_copy)
+ return;
+ if($author_remove || $owner_remove) {
+ $tags = explode(',',$i[0]["tag"]);
+ $newtags = array();
+ if(count($tags)) {
+ foreach($tags as $tag)
+ if(trim($tag) !== trim($xo->body))
+ $newtags[] = trim($tag);
+ }
+ q("UPDATE `item` SET `tag` = '%s' WHERE `id` = %d",
+ dbesc(implode(',',$newtags)),
+ intval($i[0]["id"])
+ );
+ create_tags_from_item($i[0]["id"]);
+ }
+ }
+ }
+ }
+
+ if($entrytype == DFRN_TOP_LEVEL) {
+ $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s',
+ `body` = '', `title` = ''
+ WHERE `parent-uri` = '%s' AND `uid` = %d",
+ dbesc($when),
+ dbesc(datetime_convert()),
+ dbesc($uri),
+ intval($importer["uid"])
+ );
+ create_tags_from_itemuri($uri, $importer["uid"]);
+ create_files_from_itemuri($uri, $importer["uid"]);
+ update_thread_uri($uri, $importer["uid"]);
+ } else {
+ $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s',
+ `body` = '', `title` = ''
+ WHERE `uri` = '%s' AND `uid` = %d",
+ dbesc($when),
+ dbesc(datetime_convert()),
+ dbesc($uri),
+ intval($importer["uid"])
+ );
+ create_tags_from_itemuri($uri, $importer["uid"]);
+ create_files_from_itemuri($uri, $importer["uid"]);
+ update_thread_uri($uri, $importer["importer_uid"]);
+ if($item["last-child"]) {
+ // ensure that last-child is set in case the comment that had it just got wiped.
+ q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d ",
+ dbesc(datetime_convert()),
+ dbesc($item["parent-uri"]),
+ intval($item["uid"])
+ );
+ // who is the last child now?
+ $r = q("SELECT `id` FROM `item` WHERE `parent-uri` = '%s' AND `type` != 'activity' AND `deleted` = 0 AND `moderated` = 0 AND `uid` = %d
+ ORDER BY `created` DESC LIMIT 1",
+ dbesc($item["parent-uri"]),
+ intval($importer["uid"])
+ );
+ if(count($r)) {
+ q("UPDATE `item` SET `last-child` = 1 WHERE `id` = %d",
+ intval($r[0]["id"])
+ );
+ }
+ }
+ // if this is a relayed delete, propagate it to other recipients
+
+ if($entrytype == DFRN_REPLY_RC) {
+ logger("Notifying followers about deletion of post ".$item["id"], LOGGER_DEBUG);
+ proc_run("php", "include/notifier.php","drop", $item["id"]);
+ }
+ }
+ }
+ }
+
+ /**
+ * @brief Imports a DFRN message
+ *
+ * @param text $xml The DFRN message
+ * @param array $importer Record of the importer user mixed with contact of the content
+ * @param bool $sort_by_date Is used when feeds are polled
+ */
+ public static function import($xml,$importer, $sort_by_date = false) {
+
+ if ($xml == "")
+ return;
+
+ if($importer["readonly"]) {
+ // We aren't receiving stuff from this person. But we will quietly ignore them
+ // rather than a blatant "go away" message.
+ logger('ignoring contact '.$importer["id"]);
+ return;
+ }
+
+ $doc = new DOMDocument();
+ @$doc->loadXML($xml);
+
+ $xpath = new DomXPath($doc);
+ $xpath->registerNamespace("atom", NAMESPACE_ATOM1);
+ $xpath->registerNamespace("thr", NAMESPACE_THREAD);
+ $xpath->registerNamespace("at", NAMESPACE_TOMB);
+ $xpath->registerNamespace("media", NAMESPACE_MEDIA);
+ $xpath->registerNamespace("dfrn", NAMESPACE_DFRN);
+ $xpath->registerNamespace("activity", NAMESPACE_ACTIVITY);
+ $xpath->registerNamespace("georss", NAMESPACE_GEORSS);
+ $xpath->registerNamespace("poco", NAMESPACE_POCO);
+ $xpath->registerNamespace("ostatus", NAMESPACE_OSTATUS);
+ $xpath->registerNamespace("statusnet", NAMESPACE_STATUSNET);
+
+ $header = array();
+ $header["uid"] = $importer["uid"];
+ $header["network"] = NETWORK_DFRN;
+ $header["type"] = "remote";
+ $header["wall"] = 0;
+ $header["origin"] = 0;
+ $header["contact-id"] = $importer["id"];
+
+ // Update the contact table if the data has changed
+ // Only the "dfrn:owner" in the head section contains all data
+ self::fetchauthor($xpath, $doc->firstChild, $importer, "dfrn:owner", false);
+
+ logger("Import DFRN message for user ".$importer["uid"]." from contact ".$importer["id"], LOGGER_DEBUG);
+
+ // is it a public forum? Private forums aren't supported by now with this method
+ $forum = intval($xpath->evaluate("/atom:feed/dfrn:community/text()", $context)->item(0)->nodeValue);
+
+ if ($forum != $importer["forum"])
+ q("UPDATE `contact` SET `forum` = %d WHERE `forum` != %d AND `id` = %d",
+ intval($forum), intval($forum),
+ intval($importer["id"])
+ );
+
+ $mails = $xpath->query("/atom:feed/dfrn:mail");
+ foreach ($mails AS $mail)
+ self::process_mail($xpath, $mail, $importer);
+
+ $suggestions = $xpath->query("/atom:feed/dfrn:suggest");
+ foreach ($suggestions AS $suggestion)
+ self::process_suggestion($xpath, $suggestion, $importer);
+
+ $relocations = $xpath->query("/atom:feed/dfrn:relocate");
+ foreach ($relocations AS $relocation)
+ self::process_relocation($xpath, $relocation, $importer);
+
+ $deletions = $xpath->query("/atom:feed/at:deleted-entry");
+ foreach ($deletions AS $deletion)
+ self::process_deletion($xpath, $deletion, $importer);
+
+ if (!$sort_by_date) {
+ $entries = $xpath->query("/atom:feed/atom:entry");
+ foreach ($entries AS $entry)
+ self::process_entry($header, $xpath, $entry, $importer);
+ } else {
+ $newentries = array();
+ $entries = $xpath->query("/atom:feed/atom:entry");
+ foreach ($entries AS $entry) {
+ $created = $xpath->query("atom:published/text()", $entry)->item(0)->nodeValue;
+ $newentries[strtotime($created)] = $entry;
+ }
+
+ // Now sort after the publishing date
+ ksort($newentries);
+
+ foreach ($newentries AS $entry)
+ self::process_entry($header, $xpath, $entry, $importer);
+ }
+ logger("Import done for user ".$importer["uid"]." from contact ".$importer["id"], LOGGER_DEBUG);
+ }
}
+?>
diff --git a/include/forums.php b/include/forums.php
deleted file mode 100644
index 952d09a494..0000000000
--- a/include/forums.php
+++ /dev/null
@@ -1,185 +0,0 @@
- forum url
- * 'name' => forum name
- * 'id' => number of the key from the array
- * 'micro' => contact photo in format micro
- */
-function get_forumlist($uid, $showhidden = true, $lastitem, $showprivate = false) {
-
- $forumlist = array();
-
- $order = (($showhidden) ? '' : ' AND NOT `hidden` ');
- $order .= (($lastitem) ? ' ORDER BY `last-item` DESC ' : ' ORDER BY `name` ASC ');
- $select = '`forum` ';
- if ($showprivate) {
- $select = '(`forum` OR `prv`)';
- }
-
- $contacts = q("SELECT `contact`.`id`, `contact`.`url`, `contact`.`name`, `contact`.`micro` FROM `contact`
- WHERE `network`= 'dfrn' AND $select AND `uid` = %d
- AND NOT `blocked` AND NOT `hidden` AND NOT `pending` AND NOT `archive`
- AND `success_update` > `failure_update`
- $order ",
- intval($uid)
- );
-
- if (!$contacts)
- return($forumlist);
-
- foreach($contacts as $contact) {
- $forumlist[] = array(
- 'url' => $contact['url'],
- 'name' => $contact['name'],
- 'id' => $contact['id'],
- 'micro' => $contact['micro'],
- );
- }
- return($forumlist);
-}
-
-
-/**
- * @brief Forumlist widget
- *
- * Sidebar widget to show subcribed friendica forums. If activated
- * in the settings, it appears at the notwork page sidebar
- *
- * @param int $uid
- * @param int $cid
- * The contact id which is used to mark a forum as "selected"
- * @return string
- */
-function widget_forumlist($uid,$cid = 0) {
-
- if(! intval(feature_enabled(local_user(),'forumlist_widget')))
- return;
-
- $o = '';
-
- //sort by last updated item
- $lastitem = true;
-
- $contacts = get_forumlist($uid,true,$lastitem, true);
- $total = count($contacts);
- $visible_forums = 10;
-
- if(count($contacts)) {
-
- $id = 0;
-
- foreach($contacts as $contact) {
-
- $selected = (($cid == $contact['id']) ? ' forum-selected' : '');
-
- $entry = array(
- 'url' => z_root() . '/network?f=&cid=' . $contact['id'],
- 'external_url' => z_root() . '/redir/' . $contact['id'],
- 'name' => $contact['name'],
- 'cid' => $contact['id'],
- 'selected' => $selected,
- 'micro' => proxy_url($contact['micro'], false, PROXY_SIZE_MICRO),
- 'id' => ++$id,
- );
- $entries[] = $entry;
- }
-
- $tpl = get_markup_template('widget_forumlist.tpl');
-
- $o .= replace_macros($tpl,array(
- '$title' => t('Forums'),
- '$forums' => $entries,
- '$link_desc' => t('External link to forum'),
- '$total' => $total,
- '$visible_forums' => $visible_forums,
- '$showmore' => t('show more'),
- ));
- }
-
- return $o;
-}
-
-/**
- * @brief Format forumlist as contact block
- *
- * This function is used to show the forumlist in
- * the advanced profile.
- *
- * @param int $uid
- * @return string
- *
- */
-function forumlist_profile_advanced($uid) {
-
- $profile = intval(feature_enabled($uid,'forumlist_profile'));
- if(! $profile)
- return;
-
- $o = '';
-
- // place holder in case somebody wants configurability
- $show_total = 9999;
-
- //don't sort by last updated item
- $lastitem = false;
-
- $contacts = get_forumlist($uid,false,$lastitem,false);
-
- $total_shown = 0;
-
- foreach($contacts as $contact) {
- $forumlist .= micropro($contact,false,'forumlist-profile-advanced');
- $total_shown ++;
- if($total_shown == $show_total)
- break;
- }
-
- if(count($contacts) > 0)
- $o .= $forumlist;
- return $o;
-}
-
-/**
- * @brief count unread forum items
- *
- * Count unread items of connected forums and private groups
- *
- * @return array
- * 'id' => contact id
- * 'name' => contact/forum name
- * 'count' => counted unseen forum items
- *
- */
-
-function forums_count_unseen() {
- $r = q("SELECT `contact`.`id`, `contact`.`name`, COUNT(*) AS `count` FROM `item`
- INNER JOIN `contact` ON `item`.`contact-id` = `contact`.`id`
- WHERE `item`.`uid` = %d AND `item`.`visible` AND NOT `item`.`deleted` AND `item`.`unseen`
- AND `contact`.`network`= 'dfrn' AND (`contact`.`forum` OR `contact`.`prv`)
- AND NOT `contact`.`blocked` AND NOT `contact`.`hidden`
- AND NOT `contact`.`pending` AND NOT `contact`.`archive`
- AND `contact`.`success_update` > `failure_update`
- GROUP BY `contact`.`id` ",
- intval(local_user())
- );
-
- return $r;
-}
diff --git a/include/identity.php b/include/identity.php
index fdd28f81ce..ec66225d0f 100644
--- a/include/identity.php
+++ b/include/identity.php
@@ -3,7 +3,7 @@
* @file include/identity.php
*/
-require_once('include/forums.php');
+require_once('include/ForumManager.php');
require_once('include/bbcode.php');
require_once("mod/proxy.php");
@@ -655,7 +655,7 @@ function advanced_profile(&$a) {
//show subcribed forum if it is enabled in the usersettings
if (feature_enabled($uid,'forumlist_profile')) {
- $profile['forumlist'] = array( t('Forums:'), forumlist_profile_advanced($uid));
+ $profile['forumlist'] = array( t('Forums:'), ForumManager::profile_advanced($uid));
}
if ($a->profile['uid'] == local_user())
diff --git a/include/items.php b/include/items.php
index c149660fac..798ee56958 100644
--- a/include/items.php
+++ b/include/items.php
@@ -17,6 +17,7 @@ require_once('include/feed.php');
require_once('include/Contact.php');
require_once('mod/share.php');
require_once('include/enotify.php');
+require_once('include/dfrn.php');
require_once('library/defuse/php-encryption-1.2.1/Crypto.php');
@@ -144,413 +145,6 @@ function title_is_body($title, $body) {
return($title == $body);
}
-function get_atom_elements($feed, $item, $contact = array()) {
-
- require_once('library/HTMLPurifier.auto.php');
- require_once('include/html2bbcode.php');
-
- $best_photo = array();
-
- $res = array();
-
- $author = $item->get_author();
- if($author) {
- $res['author-name'] = unxmlify($author->get_name());
- $res['author-link'] = unxmlify($author->get_link());
- }
- else {
- $res['author-name'] = unxmlify($feed->get_title());
- $res['author-link'] = unxmlify($feed->get_permalink());
- }
- $res['uri'] = unxmlify($item->get_id());
- $res['title'] = unxmlify($item->get_title());
- $res['body'] = unxmlify($item->get_content());
- $res['plink'] = unxmlify($item->get_link(0));
-
- if($res['plink'])
- $base_url = implode('/', array_slice(explode('/',$res['plink']),0,3));
- else
- $base_url = '';
-
- // look for a photo. We should check media size and find the best one,
- // but for now let's just find any author photo
- // Additionally we look for an alternate author link. On OStatus this one is the one we want.
-
- $authorlinks = $item->feed->data["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["feed"][0]["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["author"][0]["child"]["http://www.w3.org/2005/Atom"]["link"];
- if (is_array($authorlinks)) {
- foreach ($authorlinks as $link) {
- $linkdata = array_shift($link["attribs"]);
-
- if ($linkdata["rel"] == "alternate")
- $res["author-link"] = $linkdata["href"];
- };
- }
-
- $rawauthor = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10,'author');
-
- if($rawauthor && $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) {
- $base = $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link'];
- foreach($base as $link) {
- if($link['attribs']['']['rel'] === 'alternate')
- $res['author-link'] = unxmlify($link['attribs']['']['href']);
-
- if(!x($res, 'author-avatar') || !$res['author-avatar']) {
- if($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar')
- $res['author-avatar'] = unxmlify($link['attribs']['']['href']);
- }
- }
- }
-
- $rawactor = $item->get_item_tags(NAMESPACE_ACTIVITY, 'actor');
-
- if($rawactor && activity_match($rawactor[0]['child'][NAMESPACE_ACTIVITY]['object-type'][0]['data'],ACTIVITY_OBJ_PERSON)) {
- $base = $rawactor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link'];
- if($base && count($base)) {
- foreach($base as $link) {
- if($link['attribs']['']['rel'] === 'alternate' && (! $res['author-link']))
- $res['author-link'] = unxmlify($link['attribs']['']['href']);
- if(!x($res, 'author-avatar') || !$res['author-avatar']) {
- if($link['attribs']['']['rel'] === 'avatar' || $link['attribs']['']['rel'] === 'photo')
- $res['author-avatar'] = unxmlify($link['attribs']['']['href']);
- }
- }
- }
- }
-
- // No photo/profile-link on the item - look at the feed level
-
- if((! (x($res,'author-link'))) || (! (x($res,'author-avatar')))) {
- $rawauthor = $feed->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10,'author');
- if($rawauthor && $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) {
- $base = $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link'];
- foreach($base as $link) {
- if($link['attribs']['']['rel'] === 'alternate' && (! $res['author-link']))
- $res['author-link'] = unxmlify($link['attribs']['']['href']);
- if(! $res['author-avatar']) {
- if($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar')
- $res['author-avatar'] = unxmlify($link['attribs']['']['href']);
- }
- }
- }
-
- $rawactor = $feed->get_feed_tags(NAMESPACE_ACTIVITY, 'subject');
-
- if($rawactor && activity_match($rawactor[0]['child'][NAMESPACE_ACTIVITY]['object-type'][0]['data'],ACTIVITY_OBJ_PERSON)) {
- $base = $rawactor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link'];
-
- if($base && count($base)) {
- foreach($base as $link) {
- if($link['attribs']['']['rel'] === 'alternate' && (! $res['author-link']))
- $res['author-link'] = unxmlify($link['attribs']['']['href']);
- if(! (x($res,'author-avatar'))) {
- if($link['attribs']['']['rel'] === 'avatar' || $link['attribs']['']['rel'] === 'photo')
- $res['author-avatar'] = unxmlify($link['attribs']['']['href']);
- }
- }
- }
- }
- }
-
- $apps = $item->get_item_tags(NAMESPACE_STATUSNET,'notice_info');
- if($apps && $apps[0]['attribs']['']['source']) {
- $res['app'] = strip_tags(unxmlify($apps[0]['attribs']['']['source']));
- if($res['app'] === 'web')
- $res['app'] = 'OStatus';
- }
-
- // base64 encoded json structure representing Diaspora signature
-
- $dsig = $item->get_item_tags(NAMESPACE_DFRN,'diaspora_signature');
- if($dsig) {
- $res['dsprsig'] = unxmlify($dsig[0]['data']);
- }
-
- $dguid = $item->get_item_tags(NAMESPACE_DFRN,'diaspora_guid');
- if($dguid)
- $res['guid'] = unxmlify($dguid[0]['data']);
-
- $bm = $item->get_item_tags(NAMESPACE_DFRN,'bookmark');
- if($bm)
- $res['bookmark'] = ((unxmlify($bm[0]['data']) === 'true') ? 1 : 0);
-
-
- /**
- * If there's a copy of the body content which is guaranteed to have survived mangling in transit, use it.
- */
-
- $have_real_body = false;
-
- $rawenv = $item->get_item_tags(NAMESPACE_DFRN, 'env');
- if($rawenv) {
- $have_real_body = true;
- $res['body'] = $rawenv[0]['data'];
- $res['body'] = str_replace(array(' ',"\t","\r","\n"), array('','','',''),$res['body']);
- // make sure nobody is trying to sneak some html tags by us
- $res['body'] = notags(base64url_decode($res['body']));
- }
-
-
- $res['body'] = limit_body_size($res['body']);
-
- // It isn't certain at this point whether our content is plaintext or html and we'd be foolish to trust
- // the content type. Our own network only emits text normally, though it might have been converted to
- // html if we used a pubsubhubbub transport. But if we see even one html tag in our text, we will
- // have to assume it is all html and needs to be purified.
-
- // It doesn't matter all that much security wise - because before this content is used anywhere, we are
- // going to escape any tags we find regardless, but this lets us import a limited subset of html from
- // the wild, by sanitising it and converting supported tags to bbcode before we rip out any remaining
- // html.
-
- if((strpos($res['body'],'<') !== false) && (strpos($res['body'],'>') !== false)) {
-
- $res['body'] = reltoabs($res['body'],$base_url);
-
- $res['body'] = html2bb_video($res['body']);
-
- $res['body'] = oembed_html2bbcode($res['body']);
-
- $config = HTMLPurifier_Config::createDefault();
- $config->set('Cache.DefinitionImpl', null);
-
- // we shouldn't need a whitelist, because the bbcode converter
- // will strip out any unsupported tags.
-
- $purifier = new HTMLPurifier($config);
- $res['body'] = $purifier->purify($res['body']);
-
- $res['body'] = @html2bbcode($res['body']);
-
-
- }
- elseif(! $have_real_body) {
-
- // it's not one of our messages and it has no tags
- // so it's probably just text. We'll escape it just to be safe.
-
- $res['body'] = escape_tags($res['body']);
- }
-
-
- // this tag is obsolete but we keep it for really old sites
-
- $allow = $item->get_item_tags(NAMESPACE_DFRN,'comment-allow');
- if($allow && $allow[0]['data'] == 1)
- $res['last-child'] = 1;
- else
- $res['last-child'] = 0;
-
- $private = $item->get_item_tags(NAMESPACE_DFRN,'private');
- if($private && intval($private[0]['data']) > 0)
- $res['private'] = intval($private[0]['data']);
- else
- $res['private'] = 0;
-
- $extid = $item->get_item_tags(NAMESPACE_DFRN,'extid');
- if($extid && $extid[0]['data'])
- $res['extid'] = $extid[0]['data'];
-
- $rawlocation = $item->get_item_tags(NAMESPACE_DFRN, 'location');
- if($rawlocation)
- $res['location'] = unxmlify($rawlocation[0]['data']);
-
-
- $rawcreated = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10,'published');
- if($rawcreated)
- $res['created'] = unxmlify($rawcreated[0]['data']);
-
-
- $rawedited = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10,'updated');
- if($rawedited)
- $res['edited'] = unxmlify($rawedited[0]['data']);
-
- if((x($res,'edited')) && (! (x($res,'created'))))
- $res['created'] = $res['edited'];
-
- if(! $res['created'])
- $res['created'] = $item->get_date('c');
-
- if(! $res['edited'])
- $res['edited'] = $item->get_date('c');
-
-
- // Disallow time travelling posts
-
- $d1 = strtotime($res['created']);
- $d2 = strtotime($res['edited']);
- $d3 = strtotime('now');
-
- if($d1 > $d3)
- $res['created'] = datetime_convert();
- if($d2 > $d3)
- $res['edited'] = datetime_convert();
-
- $rawowner = $item->get_item_tags(NAMESPACE_DFRN, 'owner');
- if($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])
- $res['owner-name'] = unxmlify($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']);
- elseif($rawowner[0]['child'][NAMESPACE_DFRN]['name'][0]['data'])
- $res['owner-name'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['name'][0]['data']);
- if($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])
- $res['owner-link'] = unxmlify($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']);
- elseif($rawowner[0]['child'][NAMESPACE_DFRN]['uri'][0]['data'])
- $res['owner-link'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['uri'][0]['data']);
-
- if($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) {
- $base = $rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link'];
-
- foreach($base as $link) {
- if(!x($res, 'owner-avatar') || !$res['owner-avatar']) {
- if($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar')
- $res['owner-avatar'] = unxmlify($link['attribs']['']['href']);
- }
- }
- }
-
- $rawgeo = $item->get_item_tags(NAMESPACE_GEORSS,'point');
- if($rawgeo)
- $res['coord'] = unxmlify($rawgeo[0]['data']);
-
- if ($contact["network"] == NETWORK_FEED) {
- $res['verb'] = ACTIVITY_POST;
- $res['object-type'] = ACTIVITY_OBJ_NOTE;
- }
-
- $rawverb = $item->get_item_tags(NAMESPACE_ACTIVITY, 'verb');
-
- // select between supported verbs
-
- if($rawverb) {
- $res['verb'] = unxmlify($rawverb[0]['data']);
- }
-
- // translate OStatus unfollow to activity streams if it happened to get selected
-
- if((x($res,'verb')) && ($res['verb'] === 'http://ostatus.org/schema/1.0/unfollow'))
- $res['verb'] = ACTIVITY_UNFOLLOW;
-
- $cats = $item->get_categories();
- if($cats) {
- $tag_arr = array();
- foreach($cats as $cat) {
- $term = $cat->get_term();
- if(! $term)
- $term = $cat->get_label();
- $scheme = $cat->get_scheme();
- if($scheme && $term && stristr($scheme,'X-DFRN:'))
- $tag_arr[] = substr($scheme,7,1) . '[url=' . unxmlify(substr($scheme,9)) . ']' . unxmlify($term) . '[/url]';
- elseif($term)
- $tag_arr[] = notags(trim($term));
- }
- $res['tag'] = implode(',', $tag_arr);
- }
-
- $attach = $item->get_enclosures();
- if($attach) {
- $att_arr = array();
- foreach($attach as $att) {
- $len = intval($att->get_length());
- $link = str_replace(array(',','"'),array('%2D','%22'),notags(trim(unxmlify($att->get_link()))));
- $title = str_replace(array(',','"'),array('%2D','%22'),notags(trim(unxmlify($att->get_title()))));
- $type = str_replace(array(',','"'),array('%2D','%22'),notags(trim(unxmlify($att->get_type()))));
- if(strpos($type,';'))
- $type = substr($type,0,strpos($type,';'));
- if((! $link) || (strpos($link,'http') !== 0))
- continue;
-
- if(! $title)
- $title = ' ';
- if(! $type)
- $type = 'application/octet-stream';
-
- $att_arr[] = '[attach]href="' . $link . '" length="' . $len . '" type="' . $type . '" title="' . $title . '"[/attach]';
- }
- $res['attach'] = implode(',', $att_arr);
- }
-
- $rawobj = $item->get_item_tags(NAMESPACE_ACTIVITY, 'object');
-
- if($rawobj) {
- $res['object'] = '' . "\n";
- $child = $rawobj[0]['child'];
- if($child[NAMESPACE_ACTIVITY]['object-type'][0]['data']) {
- $res['object-type'] = $child[NAMESPACE_ACTIVITY]['object-type'][0]['data'];
- $res['object'] .= '' . $child[NAMESPACE_ACTIVITY]['object-type'][0]['data'] . ' ' . "\n";
- }
- if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'id') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'])
- $res['object'] .= '' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'] . ' ' . "\n";
- if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'link') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['link'])
- $res['object'] .= ' ' . encode_rel_links($child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']) . '' . "\n";
- if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'title') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'])
- $res['object'] .= '' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'] . ' ' . "\n";
- if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'content') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']) {
- $body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data'];
- if(! $body)
- $body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['summary'][0]['data'];
- // preserve a copy of the original body content in case we later need to parse out any microformat information, e.g. events
- $res['object'] .= '' . xmlify($body) . ' ' . "\n";
- if((strpos($body,'<') !== false) || (strpos($body,'>') !== false)) {
-
- $body = html2bb_video($body);
-
- $config = HTMLPurifier_Config::createDefault();
- $config->set('Cache.DefinitionImpl', null);
-
- $purifier = new HTMLPurifier($config);
- $body = $purifier->purify($body);
- $body = html2bbcode($body);
- }
-
- $res['object'] .= '' . $body . ' ' . "\n";
- }
-
- $res['object'] .= ' ' . "\n";
- }
-
- $rawobj = $item->get_item_tags(NAMESPACE_ACTIVITY, 'target');
-
- if($rawobj) {
- $res['target'] = '' . "\n";
- $child = $rawobj[0]['child'];
- if($child[NAMESPACE_ACTIVITY]['object-type'][0]['data']) {
- $res['target'] .= '' . $child[NAMESPACE_ACTIVITY]['object-type'][0]['data'] . ' ' . "\n";
- }
- if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'id') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'])
- $res['target'] .= '' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'] . ' ' . "\n";
- if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'link') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['link'])
- $res['target'] .= ' ' . encode_rel_links($child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']) . '' . "\n";
- if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'data') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'])
- $res['target'] .= '' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'] . ' ' . "\n";
- if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'data') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']) {
- $body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data'];
- if(! $body)
- $body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['summary'][0]['data'];
- // preserve a copy of the original body content in case we later need to parse out any microformat information, e.g. events
- $res['target'] .= '' . xmlify($body) . ' ' . "\n";
- if((strpos($body,'<') !== false) || (strpos($body,'>') !== false)) {
-
- $body = html2bb_video($body);
-
- $config = HTMLPurifier_Config::createDefault();
- $config->set('Cache.DefinitionImpl', null);
-
- $purifier = new HTMLPurifier($config);
- $body = $purifier->purify($body);
- $body = html2bbcode($body);
- }
-
- $res['target'] .= '' . $body . ' ' . "\n";
- }
-
- $res['target'] .= ' ' . "\n";
- }
-
- $arr = array('feed' => $feed, 'item' => $item, 'result' => $res);
-
- call_hooks('parse_atom', $arr);
-
- return $res;
-}
-
function add_page_info_data($data) {
call_hooks('page_info_data', $data);
@@ -697,27 +291,6 @@ function add_page_info_to_body($body, $texturl = false, $no_photos = false) {
return $body;
}
-function encode_rel_links($links) {
- $o = '';
- if(! ((is_array($links)) && (count($links))))
- return $o;
- foreach($links as $link) {
- $o .= ' set_raw_data($xml);
- if($datedir)
- $feed->enable_order_by_date(true);
- else
- $feed->enable_order_by_date(false);
- $feed->init();
-
- if($feed->error())
- logger('consume_feed: Error parsing XML: ' . $feed->error());
-
- $permalink = $feed->get_permalink();
-
- // Check at the feed level for updated contact name and/or photo
-
- $name_updated = '';
- $new_name = '';
- $photo_timestamp = '';
- $photo_url = '';
- $birthday = '';
- $contact_updated = '';
-
- $hubs = $feed->get_links('hub');
- logger('consume_feed: hubs: ' . print_r($hubs,true), LOGGER_DATA);
-
- if(count($hubs))
- $hub = implode(',', $hubs);
-
- $rawtags = $feed->get_feed_tags( NAMESPACE_DFRN, 'owner');
- if(! $rawtags)
- $rawtags = $feed->get_feed_tags( SIMPLEPIE_NAMESPACE_ATOM_10, 'author');
- if($rawtags) {
- $elems = $rawtags[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10];
- if($elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated']) {
- $name_updated = $elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated'];
- $new_name = $elems['name'][0]['data'];
-
- // Manually checking for changed contact names
- if (($new_name != $contact['name']) AND ($new_name != "") AND ($name_updated <= $contact['name-date'])) {
- $name_updated = date("c");
- $photo_timestamp = date("c");
- }
- }
- if((x($elems,'link')) && ($elems['link'][0]['attribs']['']['rel'] === 'photo') && ($elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated'])) {
- if ($photo_timestamp == "")
- $photo_timestamp = datetime_convert('UTC','UTC',$elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated']);
- $photo_url = $elems['link'][0]['attribs']['']['href'];
- }
-
- if((x($rawtags[0]['child'], NAMESPACE_DFRN)) && (x($rawtags[0]['child'][NAMESPACE_DFRN],'birthday'))) {
- $birthday = datetime_convert('UTC','UTC', $rawtags[0]['child'][NAMESPACE_DFRN]['birthday'][0]['data']);
- }
- }
-
- if((is_array($contact)) && ($photo_timestamp) && (strlen($photo_url)) && ($photo_timestamp > $contact['avatar-date'])) {
- logger('consume_feed: Updating photo for '.$contact['name'].' from '.$photo_url.' uid: '.$contact['uid']);
-
- $contact_updated = $photo_timestamp;
-
- require_once("include/Photo.php");
- $photos = import_profile_photo($photo_url,$contact['uid'],$contact['id']);
-
- q("UPDATE `contact` SET `avatar-date` = '%s', `photo` = '%s', `thumb` = '%s', `micro` = '%s'
- WHERE `uid` = %d AND `id` = %d AND NOT `self`",
- dbesc(datetime_convert()),
- dbesc($photos[0]),
- dbesc($photos[1]),
- dbesc($photos[2]),
- intval($contact['uid']),
- intval($contact['id'])
- );
- }
-
- if((is_array($contact)) && ($name_updated) && (strlen($new_name)) && ($name_updated > $contact['name-date'])) {
- if ($name_updated > $contact_updated)
- $contact_updated = $name_updated;
-
- $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `id` = %d LIMIT 1",
- intval($contact['uid']),
- intval($contact['id'])
- );
-
- $x = q("UPDATE `contact` SET `name` = '%s', `name-date` = '%s' WHERE `uid` = %d AND `id` = %d AND `name` != '%s' AND NOT `self`",
- dbesc(notags(trim($new_name))),
- dbesc(datetime_convert()),
- intval($contact['uid']),
- intval($contact['id']),
- dbesc(notags(trim($new_name)))
- );
-
- // do our best to update the name on content items
-
- if(count($r) AND (notags(trim($new_name)) != $r[0]['name'])) {
- q("UPDATE `item` SET `author-name` = '%s' WHERE `author-name` = '%s' AND `author-link` = '%s' AND `uid` = %d AND `author-name` != '%s'",
- dbesc(notags(trim($new_name))),
- dbesc($r[0]['name']),
- dbesc($r[0]['url']),
- intval($contact['uid']),
- dbesc(notags(trim($new_name)))
- );
- }
- }
-
- if ($contact_updated AND $new_name AND $photo_url)
- poco_check($contact['url'], $new_name, NETWORK_DFRN, $photo_url, "", "", "", "", "", $contact_updated, 2, $contact['id'], $contact['uid']);
-
- if(strlen($birthday)) {
- if(substr($birthday,0,4) != $contact['bdyear']) {
- logger('consume_feed: updating birthday: ' . $birthday);
-
- /**
- *
- * Add new birthday event for this person
- *
- * $bdtext is just a readable placeholder in case the event is shared
- * with others. We will replace it during presentation to our $importer
- * to contain a sparkle link and perhaps a photo.
- *
- */
-
- $bdtext = sprintf( t('%s\'s birthday'), $contact['name']);
- $bdtext2 = sprintf( t('Happy Birthday %s'), ' [url=' . $contact['url'] . ']' . $contact['name'] . '[/url]' ) ;
-
-
- $r = q("INSERT INTO `event` (`uid`,`cid`,`created`,`edited`,`start`,`finish`,`summary`,`desc`,`type`)
- VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ",
- intval($contact['uid']),
- intval($contact['id']),
- dbesc(datetime_convert()),
- dbesc(datetime_convert()),
- dbesc(datetime_convert('UTC','UTC', $birthday)),
- dbesc(datetime_convert('UTC','UTC', $birthday . ' + 1 day ')),
- dbesc($bdtext),
- dbesc($bdtext2),
- dbesc('birthday')
- );
-
-
- // update bdyear
-
- q("UPDATE `contact` SET `bdyear` = '%s' WHERE `uid` = %d AND `id` = %d",
- dbesc(substr($birthday,0,4)),
- intval($contact['uid']),
- intval($contact['id'])
- );
-
- // This function is called twice without reloading the contact
- // Make sure we only create one event. This is why &$contact
- // is a reference var in this function
-
- $contact['bdyear'] = substr($birthday,0,4);
- }
- }
-
- $community_page = 0;
- $rawtags = $feed->get_feed_tags( NAMESPACE_DFRN, 'community');
- if($rawtags) {
- $community_page = intval($rawtags[0]['data']);
- }
- if(is_array($contact) && intval($contact['forum']) != $community_page) {
- q("update contact set forum = %d where id = %d",
- intval($community_page),
- intval($contact['id'])
- );
- $contact['forum'] = (string) $community_page;
- }
-
-
- // process any deleted entries
-
- $del_entries = $feed->get_feed_tags(NAMESPACE_TOMB, 'deleted-entry');
- if(is_array($del_entries) && count($del_entries) && $pass != 2) {
- foreach($del_entries as $dentry) {
- $deleted = false;
- if(isset($dentry['attribs']['']['ref'])) {
- $uri = $dentry['attribs']['']['ref'];
- $deleted = true;
- if(isset($dentry['attribs']['']['when'])) {
- $when = $dentry['attribs']['']['when'];
- $when = datetime_convert('UTC','UTC', $when, 'Y-m-d H:i:s');
- }
- else
- $when = datetime_convert('UTC','UTC','now','Y-m-d H:i:s');
- }
- if($deleted && is_array($contact)) {
- $r = q("SELECT `item`.*, `contact`.`self` FROM `item` INNER JOIN `contact` on `item`.`contact-id` = `contact`.`id`
- WHERE `uri` = '%s' AND `item`.`uid` = %d AND `contact-id` = %d AND NOT `item`.`file` LIKE '%%[%%' LIMIT 1",
- dbesc($uri),
- intval($importer['uid']),
- intval($contact['id'])
- );
- if(count($r)) {
- $item = $r[0];
-
- if(! $item['deleted'])
- logger('consume_feed: deleting item ' . $item['id'] . ' uri=' . $item['uri'], LOGGER_DEBUG);
-
- if($item['object-type'] === ACTIVITY_OBJ_EVENT) {
- logger("Deleting event ".$item['event-id'], LOGGER_DEBUG);
- event_delete($item['event-id']);
- }
-
- if(($item['verb'] === ACTIVITY_TAG) && ($item['object-type'] === ACTIVITY_OBJ_TAGTERM)) {
- $xo = parse_xml_string($item['object'],false);
- $xt = parse_xml_string($item['target'],false);
- if($xt->type === ACTIVITY_OBJ_NOTE) {
- $i = q("select * from `item` where uri = '%s' and uid = %d limit 1",
- dbesc($xt->id),
- intval($importer['importer_uid'])
- );
- if(count($i)) {
-
- // For tags, the owner cannot remove the tag on the author's copy of the post.
-
- $owner_remove = (($item['contact-id'] == $i[0]['contact-id']) ? true: false);
- $author_remove = (($item['origin'] && $item['self']) ? true : false);
- $author_copy = (($item['origin']) ? true : false);
-
- if($owner_remove && $author_copy)
- continue;
- if($author_remove || $owner_remove) {
- $tags = explode(',',$i[0]['tag']);
- $newtags = array();
- if(count($tags)) {
- foreach($tags as $tag)
- if(trim($tag) !== trim($xo->body))
- $newtags[] = trim($tag);
- }
- q("update item set tag = '%s' where id = %d",
- dbesc(implode(',',$newtags)),
- intval($i[0]['id'])
- );
- create_tags_from_item($i[0]['id']);
- }
- }
- }
- }
-
- if($item['uri'] == $item['parent-uri']) {
- $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s',
- `body` = '', `title` = ''
- WHERE `parent-uri` = '%s' AND `uid` = %d",
- dbesc($when),
- dbesc(datetime_convert()),
- dbesc($item['uri']),
- intval($importer['uid'])
- );
- create_tags_from_itemuri($item['uri'], $importer['uid']);
- create_files_from_itemuri($item['uri'], $importer['uid']);
- update_thread_uri($item['uri'], $importer['uid']);
- }
- else {
- $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s',
- `body` = '', `title` = ''
- WHERE `uri` = '%s' AND `uid` = %d",
- dbesc($when),
- dbesc(datetime_convert()),
- dbesc($uri),
- intval($importer['uid'])
- );
- create_tags_from_itemuri($uri, $importer['uid']);
- create_files_from_itemuri($uri, $importer['uid']);
- if($item['last-child']) {
- // ensure that last-child is set in case the comment that had it just got wiped.
- q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d ",
- dbesc(datetime_convert()),
- dbesc($item['parent-uri']),
- intval($item['uid'])
- );
- // who is the last child now?
- $r = q("SELECT `id` FROM `item` WHERE `parent-uri` = '%s' AND `type` != 'activity' AND `deleted` = 0 AND `moderated` = 0 AND `uid` = %d
- ORDER BY `created` DESC LIMIT 1",
- dbesc($item['parent-uri']),
- intval($importer['uid'])
- );
- if(count($r)) {
- q("UPDATE `item` SET `last-child` = 1 WHERE `id` = %d",
- intval($r[0]['id'])
- );
- }
- }
- }
- }
- }
- }
- }
-
- // Now process the feed
-
- if($feed->get_item_quantity()) {
-
- logger('consume_feed: feed item count = ' . $feed->get_item_quantity());
-
- // in inverse date order
- if ($datedir)
- $items = array_reverse($feed->get_items());
- else
- $items = $feed->get_items();
-
-
- foreach($items as $item) {
-
- $is_reply = false;
- $item_id = $item->get_id();
- $rawthread = $item->get_item_tags( NAMESPACE_THREAD,'in-reply-to');
- if(isset($rawthread[0]['attribs']['']['ref'])) {
- $is_reply = true;
- $parent_uri = $rawthread[0]['attribs']['']['ref'];
- }
-
- if(($is_reply) && is_array($contact)) {
-
- if($pass == 1)
- continue;
-
- // not allowed to post
-
- if($contact['rel'] == CONTACT_IS_FOLLOWER)
- continue;
-
-
- // Have we seen it? If not, import it.
-
- $item_id = $item->get_id();
- $datarray = get_atom_elements($feed, $item, $contact);
-
- if((! x($datarray,'author-name')) && ($contact['network'] != NETWORK_DFRN))
- $datarray['author-name'] = $contact['name'];
- if((! x($datarray,'author-link')) && ($contact['network'] != NETWORK_DFRN))
- $datarray['author-link'] = $contact['url'];
- if((! x($datarray,'author-avatar')) && ($contact['network'] != NETWORK_DFRN))
- $datarray['author-avatar'] = $contact['thumb'];
-
- if((! x($datarray,'author-name')) || (! x($datarray,'author-link'))) {
- logger('consume_feed: no author information! ' . print_r($datarray,true));
- continue;
- }
-
- $force_parent = false;
- if($contact['network'] === NETWORK_OSTATUS || stristr($contact['url'],'twitter.com')) {
- if($contact['network'] === NETWORK_OSTATUS)
- $force_parent = true;
- if(strlen($datarray['title']))
- unset($datarray['title']);
- $r = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d",
- dbesc(datetime_convert()),
- dbesc($parent_uri),
- intval($importer['uid'])
- );
- $datarray['last-child'] = 1;
- update_thread_uri($parent_uri, $importer['uid']);
- }
-
-
- $r = q("SELECT `uid`, `last-child`, `edited`, `body` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
- dbesc($item_id),
- intval($importer['uid'])
- );
-
- // Update content if 'updated' changes
-
- if(count($r)) {
- if (edited_timestamp_is_newer($r[0], $datarray)) {
-
- // do not accept (ignore) an earlier edit than one we currently have.
- if(datetime_convert('UTC','UTC',$datarray['edited']) < $r[0]['edited'])
- continue;
-
- $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s', `changed` = '%s' WHERE `uri` = '%s' AND `uid` = %d",
- dbesc($datarray['title']),
- dbesc($datarray['body']),
- dbesc($datarray['tag']),
- dbesc(datetime_convert('UTC','UTC',$datarray['edited'])),
- dbesc(datetime_convert()),
- dbesc($item_id),
- intval($importer['uid'])
- );
- create_tags_from_itemuri($item_id, $importer['uid']);
- update_thread_uri($item_id, $importer['uid']);
- }
-
- // update last-child if it changes
-
- $allow = $item->get_item_tags( NAMESPACE_DFRN, 'comment-allow');
- if(($allow) && ($allow[0]['data'] != $r[0]['last-child'])) {
- $r = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d",
- dbesc(datetime_convert()),
- dbesc($parent_uri),
- intval($importer['uid'])
- );
- $r = q("UPDATE `item` SET `last-child` = %d , `changed` = '%s' WHERE `uri` = '%s' AND `uid` = %d",
- intval($allow[0]['data']),
- dbesc(datetime_convert()),
- dbesc($item_id),
- intval($importer['uid'])
- );
- update_thread_uri($item_id, $importer['uid']);
- }
- continue;
- }
-
-
- if(($contact['network'] === NETWORK_FEED) || (! strlen($contact['notify']))) {
- // one way feed - no remote comment ability
- $datarray['last-child'] = 0;
- }
- $datarray['parent-uri'] = $parent_uri;
- $datarray['uid'] = $importer['uid'];
- $datarray['contact-id'] = $contact['id'];
- if(($datarray['verb'] === ACTIVITY_LIKE)
- || ($datarray['verb'] === ACTIVITY_DISLIKE)
- || ($datarray['verb'] === ACTIVITY_ATTEND)
- || ($datarray['verb'] === ACTIVITY_ATTENDNO)
- || ($datarray['verb'] === ACTIVITY_ATTENDMAYBE)) {
- $datarray['type'] = 'activity';
- $datarray['gravity'] = GRAVITY_LIKE;
- // only one like or dislike per person
- // splitted into two queries for performance issues
- $r = q("SELECT `id` FROM `item` WHERE `uid` = %d AND `author-link` = '%s' AND `verb` = '%s' AND `parent-uri` = '%s' AND NOT `deleted` LIMIT 1",
- intval($datarray['uid']),
- dbesc($datarray['author-link']),
- dbesc($datarray['verb']),
- dbesc($datarray['parent-uri'])
- );
- if($r && count($r))
- continue;
-
- $r = q("SELECT `id` FROM `item` WHERE `uid` = %d AND `author-link` = '%s' AND `verb` = '%s' AND `thr-parent` = '%s' AND NOT `deleted` LIMIT 1",
- intval($datarray['uid']),
- dbesc($datarray['author-link']),
- dbesc($datarray['verb']),
- dbesc($datarray['parent-uri'])
- );
- if($r && count($r))
- continue;
- }
-
- if(($datarray['verb'] === ACTIVITY_TAG) && ($datarray['object-type'] === ACTIVITY_OBJ_TAGTERM)) {
- $xo = parse_xml_string($datarray['object'],false);
- $xt = parse_xml_string($datarray['target'],false);
-
- if($xt->type == ACTIVITY_OBJ_NOTE) {
- $r = q("select * from item where `uri` = '%s' AND `uid` = %d limit 1",
- dbesc($xt->id),
- intval($importer['importer_uid'])
- );
- if(! count($r))
- continue;
-
- // extract tag, if not duplicate, add to parent item
- if($xo->id && $xo->content) {
- $newtag = '#[url=' . $xo->id . ']'. $xo->content . '[/url]';
- if(! (stristr($r[0]['tag'],$newtag))) {
- q("UPDATE item SET tag = '%s' WHERE id = %d",
- dbesc($r[0]['tag'] . (strlen($r[0]['tag']) ? ',' : '') . $newtag),
- intval($r[0]['id'])
- );
- create_tags_from_item($r[0]['id']);
- }
- }
- }
- }
-
- $r = item_store($datarray,$force_parent);
- continue;
- }
-
- else {
-
- // Head post of a conversation. Have we seen it? If not, import it.
-
- $item_id = $item->get_id();
-
- $datarray = get_atom_elements($feed, $item, $contact);
-
- if(is_array($contact)) {
- if((! x($datarray,'author-name')) && ($contact['network'] != NETWORK_DFRN))
- $datarray['author-name'] = $contact['name'];
- if((! x($datarray,'author-link')) && ($contact['network'] != NETWORK_DFRN))
- $datarray['author-link'] = $contact['url'];
- if((! x($datarray,'author-avatar')) && ($contact['network'] != NETWORK_DFRN))
- $datarray['author-avatar'] = $contact['thumb'];
- }
-
- if((! x($datarray,'author-name')) || (! x($datarray,'author-link'))) {
- logger('consume_feed: no author information! ' . print_r($datarray,true));
- continue;
- }
-
- // special handling for events
-
- if((x($datarray,'object-type')) && ($datarray['object-type'] === ACTIVITY_OBJ_EVENT)) {
- $ev = bbtoevent($datarray['body']);
- if((x($ev,'desc') || x($ev,'summary')) && x($ev,'start')) {
- $ev['uid'] = $importer['uid'];
- $ev['uri'] = $item_id;
- $ev['edited'] = $datarray['edited'];
- $ev['private'] = $datarray['private'];
- $ev['guid'] = $datarray['guid'];
-
- if(is_array($contact))
- $ev['cid'] = $contact['id'];
- $r = q("SELECT * FROM `event` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
- dbesc($item_id),
- intval($importer['uid'])
- );
- if(count($r))
- $ev['id'] = $r[0]['id'];
- $xyz = event_store($ev);
- continue;
- }
- }
-
- if($contact['network'] === NETWORK_OSTATUS || stristr($contact['url'],'twitter.com')) {
- if(strlen($datarray['title']))
- unset($datarray['title']);
- $datarray['last-child'] = 1;
- }
-
-
- $r = q("SELECT `uid`, `last-child`, `edited`, `body` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
- dbesc($item_id),
- intval($importer['uid'])
- );
-
- // Update content if 'updated' changes
-
- if(count($r)) {
- if (edited_timestamp_is_newer($r[0], $datarray)) {
-
- // do not accept (ignore) an earlier edit than one we currently have.
- if(datetime_convert('UTC','UTC',$datarray['edited']) < $r[0]['edited'])
- continue;
-
- $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s', `changed` = '%s' WHERE `uri` = '%s' AND `uid` = %d",
- dbesc($datarray['title']),
- dbesc($datarray['body']),
- dbesc($datarray['tag']),
- dbesc(datetime_convert('UTC','UTC',$datarray['edited'])),
- dbesc(datetime_convert()),
- dbesc($item_id),
- intval($importer['uid'])
- );
- create_tags_from_itemuri($item_id, $importer['uid']);
- update_thread_uri($item_id, $importer['uid']);
- }
-
- // update last-child if it changes
-
- $allow = $item->get_item_tags( NAMESPACE_DFRN, 'comment-allow');
- if($allow && $allow[0]['data'] != $r[0]['last-child']) {
- $r = q("UPDATE `item` SET `last-child` = %d , `changed` = '%s' WHERE `uri` = '%s' AND `uid` = %d",
- intval($allow[0]['data']),
- dbesc(datetime_convert()),
- dbesc($item_id),
- intval($importer['uid'])
- );
- update_thread_uri($item_id, $importer['uid']);
- }
- continue;
- }
-
- if(activity_match($datarray['verb'],ACTIVITY_FOLLOW)) {
- logger('consume-feed: New follower');
- new_follower($importer,$contact,$datarray,$item);
- return;
- }
- if(activity_match($datarray['verb'],ACTIVITY_UNFOLLOW)) {
- lose_follower($importer,$contact,$datarray,$item);
- return;
- }
-
- if(activity_match($datarray['verb'],ACTIVITY_REQ_FRIEND)) {
- logger('consume-feed: New friend request');
- new_follower($importer,$contact,$datarray,$item,true);
- return;
- }
- if(activity_match($datarray['verb'],ACTIVITY_UNFRIEND)) {
- lose_sharer($importer,$contact,$datarray,$item);
- return;
- }
-
-
- if(! is_array($contact))
- return;
-
-
- if(($contact['network'] === NETWORK_FEED) || (! strlen($contact['notify']))) {
- // one way feed - no remote comment ability
- $datarray['last-child'] = 0;
- }
- if($contact['network'] === NETWORK_FEED)
- $datarray['private'] = 2;
-
- $datarray['parent-uri'] = $item_id;
- $datarray['uid'] = $importer['uid'];
- $datarray['contact-id'] = $contact['id'];
-
- if(! link_compare($datarray['owner-link'],$contact['url'])) {
- // The item owner info is not our contact. It's OK and is to be expected if this is a tgroup delivery,
- // but otherwise there's a possible data mixup on the sender's system.
- // the tgroup delivery code called from item_store will correct it if it's a forum,
- // but we're going to unconditionally correct it here so that the post will always be owned by our contact.
- logger('consume_feed: Correcting item owner.', LOGGER_DEBUG);
- $datarray['owner-name'] = $contact['name'];
- $datarray['owner-link'] = $contact['url'];
- $datarray['owner-avatar'] = $contact['thumb'];
- }
-
- // We've allowed "followers" to reach this point so we can decide if they are
- // posting an @-tag delivery, which followers are allowed to do for certain
- // page types. Now that we've parsed the post, let's check if it is legit. Otherwise ignore it.
-
- if(($contact['rel'] == CONTACT_IS_FOLLOWER) && (! tgroup_check($importer['uid'],$datarray)))
- continue;
-
- // This is my contact on another system, but it's really me.
- // Turn this into a wall post.
- $notify = item_is_remote_self($contact, $datarray);
-
- $r = item_store($datarray, false, $notify);
- logger('Stored - Contact '.$contact['url'].' Notify '.$notify.' return '.$r.' Item '.print_r($datarray, true), LOGGER_DEBUG);
- continue;
-
- }
+ if ($contact['network'] === NETWORK_DFRN) {
+ logger("Consume DFRN messages", LOGGER_DEBUG);
+
+ $r = q("SELECT `contact`.*, `contact`.`uid` AS `importer_uid`,
+ `contact`.`pubkey` AS `cpubkey`,
+ `contact`.`prvkey` AS `cprvkey`,
+ `contact`.`thumb` AS `thumb`,
+ `contact`.`url` as `url`,
+ `contact`.`name` as `senderName`,
+ `user`.*
+ FROM `contact`
+ LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid`
+ WHERE `contact`.`id` = %d AND `user`.`uid` = %d",
+ dbesc($contact["id"]), dbesc($importer["uid"])
+ );
+ if ($r) {
+ logger("Now import the DFRN feed");
+ dfrn::import($xml,$r[0], true);
+ return;
}
}
}
@@ -2392,1068 +1351,6 @@ function item_is_remote_self($contact, &$datarray) {
return true;
}
-function local_delivery($importer,$data) {
-
- require_once('library/simplepie/simplepie.inc');
-
- $a = get_app();
-
- logger(__function__, LOGGER_TRACE);
-
- if($importer['readonly']) {
- // We aren't receiving stuff from this person. But we will quietly ignore them
- // rather than a blatant "go away" message.
- logger('local_delivery: ignoring');
- return 0;
- //NOTREACHED
- }
-
- // Consume notification feed. This may differ from consuming a public feed in several ways
- // - might contain email or friend suggestions
- // - might contain remote followup to our message
- // - in which case we need to accept it and then notify other conversants
- // - we may need to send various email notifications
-
- $feed = new SimplePie();
- $feed->set_raw_data($data);
- $feed->enable_order_by_date(false);
- $feed->init();
-
-
- if($feed->error())
- logger('local_delivery: Error parsing XML: ' . $feed->error());
-
-
- // Check at the feed level for updated contact name and/or photo
-
- $name_updated = '';
- $new_name = '';
- $photo_timestamp = '';
- $photo_url = '';
- $contact_updated = '';
-
-
- $rawtags = $feed->get_feed_tags( NAMESPACE_DFRN, 'owner');
-
-// Fallback should not be needed here. If it isn't DFRN it won't have DFRN updated tags
-// if(! $rawtags)
-// $rawtags = $feed->get_feed_tags( SIMPLEPIE_NAMESPACE_ATOM_10, 'author');
-
- if($rawtags) {
- $elems = $rawtags[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10];
- if($elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated']) {
- $name_updated = $elems['name'][0]['attribs'][NAMESPACE_DFRN]['updated'];
- $new_name = $elems['name'][0]['data'];
-
- // Manually checking for changed contact names
- if (($new_name != $importer['name']) AND ($new_name != "") AND ($name_updated <= $importer['name-date'])) {
- $name_updated = date("c");
- $photo_timestamp = date("c");
- }
- }
- if((x($elems,'link')) && ($elems['link'][0]['attribs']['']['rel'] === 'photo') && ($elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated'])) {
- if ($photo_timestamp == "")
- $photo_timestamp = datetime_convert('UTC','UTC',$elems['link'][0]['attribs'][NAMESPACE_DFRN]['updated']);
- $photo_url = $elems['link'][0]['attribs']['']['href'];
- }
- }
-
- if(($photo_timestamp) && (strlen($photo_url)) && ($photo_timestamp > $importer['avatar-date'])) {
-
- $contact_updated = $photo_timestamp;
-
- logger('local_delivery: Updating photo for ' . $importer['name']);
- require_once("include/Photo.php");
-
- $photos = import_profile_photo($photo_url,$importer['importer_uid'],$importer['id']);
-
- q("UPDATE `contact` SET `avatar-date` = '%s', `photo` = '%s', `thumb` = '%s', `micro` = '%s'
- WHERE `uid` = %d AND `id` = %d AND NOT `self`",
- dbesc(datetime_convert()),
- dbesc($photos[0]),
- dbesc($photos[1]),
- dbesc($photos[2]),
- intval($importer['importer_uid']),
- intval($importer['id'])
- );
- }
-
- if(($name_updated) && (strlen($new_name)) && ($name_updated > $importer['name-date'])) {
- if ($name_updated > $contact_updated)
- $contact_updated = $name_updated;
-
- $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `id` = %d LIMIT 1",
- intval($importer['importer_uid']),
- intval($importer['id'])
- );
-
- $x = q("UPDATE `contact` SET `name` = '%s', `name-date` = '%s' WHERE `uid` = %d AND `id` = %d AND `name` != '%s' AND NOT `self`",
- dbesc(notags(trim($new_name))),
- dbesc(datetime_convert()),
- intval($importer['importer_uid']),
- intval($importer['id']),
- dbesc(notags(trim($new_name)))
- );
-
- // do our best to update the name on content items
-
- if(count($r) AND (notags(trim($new_name)) != $r[0]['name'])) {
- q("UPDATE `item` SET `author-name` = '%s' WHERE `author-name` = '%s' AND `author-link` = '%s' AND `uid` = %d AND `author-name` != '%s'",
- dbesc(notags(trim($new_name))),
- dbesc($r[0]['name']),
- dbesc($r[0]['url']),
- intval($importer['importer_uid']),
- dbesc(notags(trim($new_name)))
- );
- }
- }
-
- if ($contact_updated AND $new_name AND $photo_url)
- poco_check($importer['url'], $new_name, NETWORK_DFRN, $photo_url, "", "", "", "", "", $contact_updated, 2, $importer['id'], $importer['importer_uid']);
-
- // Currently unsupported - needs a lot of work
- $reloc = $feed->get_feed_tags( NAMESPACE_DFRN, 'relocate' );
- if(isset($reloc[0]['child'][NAMESPACE_DFRN])) {
- $base = $reloc[0]['child'][NAMESPACE_DFRN];
- $newloc = array();
- $newloc['uid'] = $importer['importer_uid'];
- $newloc['cid'] = $importer['id'];
- $newloc['name'] = notags(unxmlify($base['name'][0]['data']));
- $newloc['photo'] = notags(unxmlify($base['photo'][0]['data']));
- $newloc['thumb'] = notags(unxmlify($base['thumb'][0]['data']));
- $newloc['micro'] = notags(unxmlify($base['micro'][0]['data']));
- $newloc['url'] = notags(unxmlify($base['url'][0]['data']));
- $newloc['request'] = notags(unxmlify($base['request'][0]['data']));
- $newloc['confirm'] = notags(unxmlify($base['confirm'][0]['data']));
- $newloc['notify'] = notags(unxmlify($base['notify'][0]['data']));
- $newloc['poll'] = notags(unxmlify($base['poll'][0]['data']));
- $newloc['sitepubkey'] = notags(unxmlify($base['sitepubkey'][0]['data']));
- /** relocated user must have original key pair */
- /*$newloc['pubkey'] = notags(unxmlify($base['pubkey'][0]['data']));
- $newloc['prvkey'] = notags(unxmlify($base['prvkey'][0]['data']));*/
-
- logger("items:relocate contact ".print_r($newloc, true).print_r($importer, true), LOGGER_DEBUG);
-
- // update contact
- $r = q("SELECT photo, url FROM contact WHERE id=%d AND uid=%d;",
- intval($importer['id']),
- intval($importer['importer_uid']));
- if ($r === false)
- return 1;
- $old = $r[0];
-
- $x = q("UPDATE contact SET
- name = '%s',
- photo = '%s',
- thumb = '%s',
- micro = '%s',
- url = '%s',
- nurl = '%s',
- request = '%s',
- confirm = '%s',
- notify = '%s',
- poll = '%s',
- `site-pubkey` = '%s'
- WHERE id=%d AND uid=%d;",
- dbesc($newloc['name']),
- dbesc($newloc['photo']),
- dbesc($newloc['thumb']),
- dbesc($newloc['micro']),
- dbesc($newloc['url']),
- dbesc(normalise_link($newloc['url'])),
- dbesc($newloc['request']),
- dbesc($newloc['confirm']),
- dbesc($newloc['notify']),
- dbesc($newloc['poll']),
- dbesc($newloc['sitepubkey']),
- intval($importer['id']),
- intval($importer['importer_uid']));
-
- if ($x === false)
- return 1;
- // update items
- $fields = array(
- 'owner-link' => array($old['url'], $newloc['url']),
- 'author-link' => array($old['url'], $newloc['url']),
- 'owner-avatar' => array($old['photo'], $newloc['photo']),
- 'author-avatar' => array($old['photo'], $newloc['photo']),
- );
- foreach ($fields as $n=>$f){
- $x = q("UPDATE `item` SET `%s`='%s' WHERE `%s`='%s' AND uid=%d",
- $n, dbesc($f[1]),
- $n, dbesc($f[0]),
- intval($importer['importer_uid']));
- if ($x === false)
- return 1;
- }
-
- /// @TODO
- /// merge with current record, current contents have priority
- /// update record, set url-updated
- /// update profile photos
- /// schedule a scan?
- return 0;
- }
-
-
- // handle friend suggestion notification
-
- $sugg = $feed->get_feed_tags( NAMESPACE_DFRN, 'suggest' );
- if(isset($sugg[0]['child'][NAMESPACE_DFRN])) {
- $base = $sugg[0]['child'][NAMESPACE_DFRN];
- $fsugg = array();
- $fsugg['uid'] = $importer['importer_uid'];
- $fsugg['cid'] = $importer['id'];
- $fsugg['name'] = notags(unxmlify($base['name'][0]['data']));
- $fsugg['photo'] = notags(unxmlify($base['photo'][0]['data']));
- $fsugg['url'] = notags(unxmlify($base['url'][0]['data']));
- $fsugg['request'] = notags(unxmlify($base['request'][0]['data']));
- $fsugg['body'] = escape_tags(unxmlify($base['note'][0]['data']));
-
- // Does our member already have a friend matching this description?
-
- $r = q("SELECT * FROM `contact` WHERE `name` = '%s' AND `nurl` = '%s' AND `uid` = %d LIMIT 1",
- dbesc($fsugg['name']),
- dbesc(normalise_link($fsugg['url'])),
- intval($fsugg['uid'])
- );
- if(count($r))
- return 0;
-
- // Do we already have an fcontact record for this person?
-
- $fid = 0;
- $r = q("SELECT * FROM `fcontact` WHERE `url` = '%s' AND `name` = '%s' AND `request` = '%s' LIMIT 1",
- dbesc($fsugg['url']),
- dbesc($fsugg['name']),
- dbesc($fsugg['request'])
- );
- if(count($r)) {
- $fid = $r[0]['id'];
-
- // OK, we do. Do we already have an introduction for this person ?
- $r = q("select id from intro where uid = %d and fid = %d limit 1",
- intval($fsugg['uid']),
- intval($fid)
- );
- if(count($r))
- return 0;
- }
- if(! $fid)
- $r = q("INSERT INTO `fcontact` ( `name`,`url`,`photo`,`request` ) VALUES ( '%s', '%s', '%s', '%s' ) ",
- dbesc($fsugg['name']),
- dbesc($fsugg['url']),
- dbesc($fsugg['photo']),
- dbesc($fsugg['request'])
- );
- $r = q("SELECT * FROM `fcontact` WHERE `url` = '%s' AND `name` = '%s' AND `request` = '%s' LIMIT 1",
- dbesc($fsugg['url']),
- dbesc($fsugg['name']),
- dbesc($fsugg['request'])
- );
- if(count($r)) {
- $fid = $r[0]['id'];
- }
- // database record did not get created. Quietly give up.
- else
- return 0;
-
-
- $hash = random_string();
-
- $r = q("INSERT INTO `intro` ( `uid`, `fid`, `contact-id`, `note`, `hash`, `datetime`, `blocked` )
- VALUES( %d, %d, %d, '%s', '%s', '%s', %d )",
- intval($fsugg['uid']),
- intval($fid),
- intval($fsugg['cid']),
- dbesc($fsugg['body']),
- dbesc($hash),
- dbesc(datetime_convert()),
- intval(0)
- );
-
- notification(array(
- 'type' => NOTIFY_SUGGEST,
- 'notify_flags' => $importer['notify-flags'],
- 'language' => $importer['language'],
- 'to_name' => $importer['username'],
- 'to_email' => $importer['email'],
- 'uid' => $importer['importer_uid'],
- 'item' => $fsugg,
- 'link' => $a->get_baseurl() . '/notifications/intros',
- 'source_name' => $importer['name'],
- 'source_link' => $importer['url'],
- 'source_photo' => $importer['photo'],
- 'verb' => ACTIVITY_REQ_FRIEND,
- 'otype' => 'intro'
- ));
-
- return 0;
- }
-
- $ismail = false;
-
- $rawmail = $feed->get_feed_tags( NAMESPACE_DFRN, 'mail' );
- if(isset($rawmail[0]['child'][NAMESPACE_DFRN])) {
-
- logger('local_delivery: private message received');
-
- $ismail = true;
- $base = $rawmail[0]['child'][NAMESPACE_DFRN];
-
- $msg = array();
- $msg['uid'] = $importer['importer_uid'];
- $msg['from-name'] = notags(unxmlify($base['sender'][0]['child'][NAMESPACE_DFRN]['name'][0]['data']));
- $msg['from-photo'] = notags(unxmlify($base['sender'][0]['child'][NAMESPACE_DFRN]['avatar'][0]['data']));
- $msg['from-url'] = notags(unxmlify($base['sender'][0]['child'][NAMESPACE_DFRN]['uri'][0]['data']));
- $msg['contact-id'] = $importer['id'];
- $msg['title'] = notags(unxmlify($base['subject'][0]['data']));
- $msg['body'] = escape_tags(unxmlify($base['content'][0]['data']));
- $msg['seen'] = 0;
- $msg['replied'] = 0;
- $msg['uri'] = notags(unxmlify($base['id'][0]['data']));
- $msg['parent-uri'] = notags(unxmlify($base['in-reply-to'][0]['data']));
- $msg['created'] = datetime_convert(notags(unxmlify('UTC','UTC',$base['sentdate'][0]['data'])));
-
- dbesc_array($msg);
-
- $r = dbq("INSERT INTO `mail` (`" . implode("`, `", array_keys($msg))
- . "`) VALUES ('" . implode("', '", array_values($msg)) . "')" );
-
- // send notifications.
-
- require_once('include/enotify.php');
-
- $notif_params = array(
- 'type' => NOTIFY_MAIL,
- 'notify_flags' => $importer['notify-flags'],
- 'language' => $importer['language'],
- 'to_name' => $importer['username'],
- 'to_email' => $importer['email'],
- 'uid' => $importer['importer_uid'],
- 'item' => $msg,
- 'source_name' => $msg['from-name'],
- 'source_link' => $importer['url'],
- 'source_photo' => $importer['thumb'],
- 'verb' => ACTIVITY_POST,
- 'otype' => 'mail'
- );
-
- notification($notif_params);
- return 0;
-
- // NOTREACHED
- }
-
- $community_page = 0;
- $rawtags = $feed->get_feed_tags( NAMESPACE_DFRN, 'community');
- if($rawtags) {
- $community_page = intval($rawtags[0]['data']);
- }
- if(intval($importer['forum']) != $community_page) {
- q("update contact set forum = %d where id = %d",
- intval($community_page),
- intval($importer['id'])
- );
- $importer['forum'] = (string) $community_page;
- }
-
- logger('local_delivery: feed item count = ' . $feed->get_item_quantity());
-
- // process any deleted entries
-
- $del_entries = $feed->get_feed_tags(NAMESPACE_TOMB, 'deleted-entry');
- if(is_array($del_entries) && count($del_entries)) {
- foreach($del_entries as $dentry) {
- $deleted = false;
- if(isset($dentry['attribs']['']['ref'])) {
- $uri = $dentry['attribs']['']['ref'];
- $deleted = true;
- if(isset($dentry['attribs']['']['when'])) {
- $when = $dentry['attribs']['']['when'];
- $when = datetime_convert('UTC','UTC', $when, 'Y-m-d H:i:s');
- }
- else
- $when = datetime_convert('UTC','UTC','now','Y-m-d H:i:s');
- }
- if($deleted) {
-
- // check for relayed deletes to our conversation
-
- $is_reply = false;
- $r = q("select * from item where uri = '%s' and uid = %d limit 1",
- dbesc($uri),
- intval($importer['importer_uid'])
- );
- if(count($r)) {
- $parent_uri = $r[0]['parent-uri'];
- if($r[0]['id'] != $r[0]['parent'])
- $is_reply = true;
- }
-
- if($is_reply) {
- $community = false;
-
- if($importer['page-flags'] == PAGE_COMMUNITY || $importer['page-flags'] == PAGE_PRVGROUP ) {
- $sql_extra = '';
- $community = true;
- logger('local_delivery: possible community delete');
- }
- else
- $sql_extra = " and contact.self = 1 and item.wall = 1 ";
-
- // was the top-level post for this reply written by somebody on this site?
- // Specifically, the recipient?
-
- $is_a_remote_delete = false;
-
- // POSSIBLE CLEANUP --> Why select so many fields when only forum_mode and wall are used?
- $r = q("select `item`.`id`, `item`.`uri`, `item`.`tag`, `item`.`forum_mode`,`item`.`origin`,`item`.`wall`,
- `contact`.`name`, `contact`.`url`, `contact`.`thumb` from `item`
- INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
- WHERE `item`.`uri` = '%s' AND (`item`.`parent-uri` = '%s' or `item`.`thr-parent` = '%s')
- AND `item`.`uid` = %d
- $sql_extra
- LIMIT 1",
- dbesc($parent_uri),
- dbesc($parent_uri),
- dbesc($parent_uri),
- intval($importer['importer_uid'])
- );
- if($r && count($r))
- $is_a_remote_delete = true;
-
- // Does this have the characteristics of a community or private group comment?
- // If it's a reply to a wall post on a community/prvgroup page it's a
- // valid community comment. Also forum_mode makes it valid for sure.
- // If neither, it's not.
-
- if($is_a_remote_delete && $community) {
- if((! $r[0]['forum_mode']) && (! $r[0]['wall'])) {
- $is_a_remote_delete = false;
- logger('local_delivery: not a community delete');
- }
- }
-
- if($is_a_remote_delete) {
- logger('local_delivery: received remote delete');
- }
- }
-
- $r = q("SELECT `item`.*, `contact`.`self` FROM `item` INNER JOIN contact on `item`.`contact-id` = `contact`.`id`
- WHERE `uri` = '%s' AND `item`.`uid` = %d AND `contact-id` = %d AND NOT `item`.`file` LIKE '%%[%%' LIMIT 1",
- dbesc($uri),
- intval($importer['importer_uid']),
- intval($importer['id'])
- );
-
- if(count($r)) {
- $item = $r[0];
-
- if($item['deleted'])
- continue;
-
- logger('local_delivery: deleting item ' . $item['id'] . ' uri=' . $item['uri'], LOGGER_DEBUG);
-
- if($item['object-type'] === ACTIVITY_OBJ_EVENT) {
- logger("Deleting event ".$item['event-id'], LOGGER_DEBUG);
- event_delete($item['event-id']);
- }
-
- if(($item['verb'] === ACTIVITY_TAG) && ($item['object-type'] === ACTIVITY_OBJ_TAGTERM)) {
- $xo = parse_xml_string($item['object'],false);
- $xt = parse_xml_string($item['target'],false);
-
- if($xt->type === ACTIVITY_OBJ_NOTE) {
- $i = q("select * from `item` where uri = '%s' and uid = %d limit 1",
- dbesc($xt->id),
- intval($importer['importer_uid'])
- );
- if(count($i)) {
-
- // For tags, the owner cannot remove the tag on the author's copy of the post.
-
- $owner_remove = (($item['contact-id'] == $i[0]['contact-id']) ? true: false);
- $author_remove = (($item['origin'] && $item['self']) ? true : false);
- $author_copy = (($item['origin']) ? true : false);
-
- if($owner_remove && $author_copy)
- continue;
- if($author_remove || $owner_remove) {
- $tags = explode(',',$i[0]['tag']);
- $newtags = array();
- if(count($tags)) {
- foreach($tags as $tag)
- if(trim($tag) !== trim($xo->body))
- $newtags[] = trim($tag);
- }
- q("update item set tag = '%s' where id = %d",
- dbesc(implode(',',$newtags)),
- intval($i[0]['id'])
- );
- create_tags_from_item($i[0]['id']);
- }
- }
- }
- }
-
- if($item['uri'] == $item['parent-uri']) {
- $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s',
- `body` = '', `title` = ''
- WHERE `parent-uri` = '%s' AND `uid` = %d",
- dbesc($when),
- dbesc(datetime_convert()),
- dbesc($item['uri']),
- intval($importer['importer_uid'])
- );
- create_tags_from_itemuri($item['uri'], $importer['importer_uid']);
- create_files_from_itemuri($item['uri'], $importer['importer_uid']);
- update_thread_uri($item['uri'], $importer['importer_uid']);
- }
- else {
- $r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s',
- `body` = '', `title` = ''
- WHERE `uri` = '%s' AND `uid` = %d",
- dbesc($when),
- dbesc(datetime_convert()),
- dbesc($uri),
- intval($importer['importer_uid'])
- );
- create_tags_from_itemuri($uri, $importer['importer_uid']);
- create_files_from_itemuri($uri, $importer['importer_uid']);
- update_thread_uri($uri, $importer['importer_uid']);
- if($item['last-child']) {
- // ensure that last-child is set in case the comment that had it just got wiped.
- q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d ",
- dbesc(datetime_convert()),
- dbesc($item['parent-uri']),
- intval($item['uid'])
- );
- // who is the last child now?
- $r = q("SELECT `id` FROM `item` WHERE `parent-uri` = '%s' AND `type` != 'activity' AND `deleted` = 0 AND `uid` = %d
- ORDER BY `created` DESC LIMIT 1",
- dbesc($item['parent-uri']),
- intval($importer['importer_uid'])
- );
- if(count($r)) {
- q("UPDATE `item` SET `last-child` = 1 WHERE `id` = %d",
- intval($r[0]['id'])
- );
- }
- }
- // if this is a relayed delete, propagate it to other recipients
-
- if($is_a_remote_delete)
- proc_run('php',"include/notifier.php","drop",$item['id']);
- }
- }
- }
- }
- }
-
-
- foreach($feed->get_items() as $item) {
-
- $is_reply = false;
- $item_id = $item->get_id();
- $rawthread = $item->get_item_tags( NAMESPACE_THREAD, 'in-reply-to');
- if(isset($rawthread[0]['attribs']['']['ref'])) {
- $is_reply = true;
- $parent_uri = $rawthread[0]['attribs']['']['ref'];
- }
-
- if($is_reply) {
- $community = false;
-
- if($importer['page-flags'] == PAGE_COMMUNITY || $importer['page-flags'] == PAGE_PRVGROUP ) {
- $sql_extra = '';
- $community = true;
- logger('local_delivery: possible community reply');
- }
- else
- $sql_extra = " and contact.self = 1 and item.wall = 1 ";
-
- // was the top-level post for this reply written by somebody on this site?
- // Specifically, the recipient?
-
- $is_a_remote_comment = false;
- $top_uri = $parent_uri;
-
- $r = q("select `item`.`parent-uri` from `item`
- WHERE `item`.`uri` = '%s'
- LIMIT 1",
- dbesc($parent_uri)
- );
- if($r && count($r)) {
- $top_uri = $r[0]['parent-uri'];
-
- // POSSIBLE CLEANUP --> Why select so many fields when only forum_mode and wall are used?
- $r = q("select `item`.`id`, `item`.`uri`, `item`.`tag`, `item`.`forum_mode`,`item`.`origin`,`item`.`wall`,
- `contact`.`name`, `contact`.`url`, `contact`.`thumb` from `item`
- INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
- WHERE `item`.`uri` = '%s' AND (`item`.`parent-uri` = '%s' or `item`.`thr-parent` = '%s')
- AND `item`.`uid` = %d
- $sql_extra
- LIMIT 1",
- dbesc($top_uri),
- dbesc($top_uri),
- dbesc($top_uri),
- intval($importer['importer_uid'])
- );
- if($r && count($r))
- $is_a_remote_comment = true;
- }
-
- // Does this have the characteristics of a community or private group comment?
- // If it's a reply to a wall post on a community/prvgroup page it's a
- // valid community comment. Also forum_mode makes it valid for sure.
- // If neither, it's not.
-
- if($is_a_remote_comment && $community) {
- if((! $r[0]['forum_mode']) && (! $r[0]['wall'])) {
- $is_a_remote_comment = false;
- logger('local_delivery: not a community reply');
- }
- }
-
- if($is_a_remote_comment) {
- logger('local_delivery: received remote comment');
- $is_like = false;
- // remote reply to our post. Import and then notify everybody else.
-
- $datarray = get_atom_elements($feed, $item);
-
- $r = q("SELECT `id`, `uid`, `last-child`, `edited`, `body` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
- dbesc($item_id),
- intval($importer['importer_uid'])
- );
-
- // Update content if 'updated' changes
-
- if(count($r)) {
- $iid = $r[0]['id'];
- if (edited_timestamp_is_newer($r[0], $datarray)) {
-
- // do not accept (ignore) an earlier edit than one we currently have.
- if(datetime_convert('UTC','UTC',$datarray['edited']) < $r[0]['edited'])
- continue;
-
- logger('received updated comment' , LOGGER_DEBUG);
- $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s', `changed` = '%s' WHERE `uri` = '%s' AND `uid` = %d",
- dbesc($datarray['title']),
- dbesc($datarray['body']),
- dbesc($datarray['tag']),
- dbesc(datetime_convert('UTC','UTC',$datarray['edited'])),
- dbesc(datetime_convert()),
- dbesc($item_id),
- intval($importer['importer_uid'])
- );
- create_tags_from_itemuri($item_id, $importer['importer_uid']);
-
- proc_run('php',"include/notifier.php","comment-import",$iid);
-
- }
-
- continue;
- }
-
-
-
- $own = q("select name,url,thumb from contact where uid = %d and self = 1 limit 1",
- intval($importer['importer_uid'])
- );
-
-
- $datarray['type'] = 'remote-comment';
- $datarray['wall'] = 1;
- $datarray['parent-uri'] = $parent_uri;
- $datarray['uid'] = $importer['importer_uid'];
- $datarray['owner-name'] = $own[0]['name'];
- $datarray['owner-link'] = $own[0]['url'];
- $datarray['owner-avatar'] = $own[0]['thumb'];
- $datarray['contact-id'] = $importer['id'];
-
- if(($datarray['verb'] === ACTIVITY_LIKE)
- || ($datarray['verb'] === ACTIVITY_DISLIKE)
- || ($datarray['verb'] === ACTIVITY_ATTEND)
- || ($datarray['verb'] === ACTIVITY_ATTENDNO)
- || ($datarray['verb'] === ACTIVITY_ATTENDMAYBE)) {
- $is_like = true;
- $datarray['type'] = 'activity';
- $datarray['gravity'] = GRAVITY_LIKE;
- $datarray['last-child'] = 0;
- // only one like or dislike per person
- // splitted into two queries for performance issues
- $r = q("SELECT `id` FROM `item` WHERE `uid` = %d AND `author-link` = '%s' AND `verb` = '%s' AND `parent-uri` = '%s' AND NOT `deleted` LIMIT 1",
- intval($datarray['uid']),
- dbesc($datarray['author-link']),
- dbesc($datarray['verb']),
- dbesc($datarray['parent-uri'])
- );
- if($r && count($r))
- continue;
-
- $r = q("SELECT `id` FROM `item` WHERE `uid` = %d AND `author-link` = '%s' AND `verb` = '%s' AND `thr-parent` = '%s' AND NOT `deleted` LIMIT 1",
- intval($datarray['uid']),
- dbesc($datarray['author-link']),
- dbesc($datarray['verb']),
- dbesc($datarray['parent-uri'])
-
- );
- if($r && count($r))
- continue;
- }
-
- if(($datarray['verb'] === ACTIVITY_TAG) && ($datarray['object-type'] === ACTIVITY_OBJ_TAGTERM)) {
-
- $xo = parse_xml_string($datarray['object'],false);
- $xt = parse_xml_string($datarray['target'],false);
-
- if(($xt->type == ACTIVITY_OBJ_NOTE) && ($xt->id)) {
-
- // fetch the parent item
-
- $tagp = q("select * from item where uri = '%s' and uid = %d limit 1",
- dbesc($xt->id),
- intval($importer['importer_uid'])
- );
- if(! count($tagp))
- continue;
-
- // extract tag, if not duplicate, and this user allows tags, add to parent item
-
- if($xo->id && $xo->content) {
- $newtag = '#[url=' . $xo->id . ']'. $xo->content . '[/url]';
- if(! (stristr($tagp[0]['tag'],$newtag))) {
- $i = q("SELECT `blocktags` FROM `user` where `uid` = %d LIMIT 1",
- intval($importer['importer_uid'])
- );
- if(count($i) && ! intval($i[0]['blocktags'])) {
- q("UPDATE item SET tag = '%s', `edited` = '%s', `changed` = '%s' WHERE id = %d",
- dbesc($tagp[0]['tag'] . (strlen($tagp[0]['tag']) ? ',' : '') . $newtag),
- intval($tagp[0]['id']),
- dbesc(datetime_convert()),
- dbesc(datetime_convert())
- );
- create_tags_from_item($tagp[0]['id']);
- }
- }
- }
- }
- }
-
-
- $posted_id = item_store($datarray);
- $parent = 0;
-
- if($posted_id) {
-
- $datarray["id"] = $posted_id;
-
- $r = q("SELECT `parent`, `parent-uri` FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1",
- intval($posted_id),
- intval($importer['importer_uid'])
- );
- if(count($r)) {
- $parent = $r[0]['parent'];
- $parent_uri = $r[0]['parent-uri'];
- }
-
- if(! $is_like) {
- $r1 = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `uid` = %d AND `parent` = %d",
- dbesc(datetime_convert()),
- intval($importer['importer_uid']),
- intval($r[0]['parent'])
- );
-
- $r2 = q("UPDATE `item` SET `last-child` = 1, `changed` = '%s' WHERE `uid` = %d AND `id` = %d",
- dbesc(datetime_convert()),
- intval($importer['importer_uid']),
- intval($posted_id)
- );
- }
-
- if($posted_id && $parent) {
- proc_run('php',"include/notifier.php","comment-import","$posted_id");
- }
-
- return 0;
- // NOTREACHED
- }
- }
- else {
-
- // regular comment that is part of this total conversation. Have we seen it? If not, import it.
-
- $item_id = $item->get_id();
- $datarray = get_atom_elements($feed,$item);
-
- if($importer['rel'] == CONTACT_IS_FOLLOWER)
- continue;
-
- $r = q("SELECT `uid`, `last-child`, `edited`, `body` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
- dbesc($item_id),
- intval($importer['importer_uid'])
- );
-
- // Update content if 'updated' changes
-
- if(count($r)) {
- if (edited_timestamp_is_newer($r[0], $datarray)) {
-
- // do not accept (ignore) an earlier edit than one we currently have.
- if(datetime_convert('UTC','UTC',$datarray['edited']) < $r[0]['edited'])
- continue;
-
- $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s', `changed` = '%s' WHERE `uri` = '%s' AND `uid` = %d",
- dbesc($datarray['title']),
- dbesc($datarray['body']),
- dbesc($datarray['tag']),
- dbesc(datetime_convert('UTC','UTC',$datarray['edited'])),
- dbesc(datetime_convert()),
- dbesc($item_id),
- intval($importer['importer_uid'])
- );
- create_tags_from_itemuri($item_id, $importer['importer_uid']);
- }
-
- // update last-child if it changes
-
- $allow = $item->get_item_tags( NAMESPACE_DFRN, 'comment-allow');
- if(($allow) && ($allow[0]['data'] != $r[0]['last-child'])) {
- $r = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d",
- dbesc(datetime_convert()),
- dbesc($parent_uri),
- intval($importer['importer_uid'])
- );
- $r = q("UPDATE `item` SET `last-child` = %d , `changed` = '%s' WHERE `uri` = '%s' AND `uid` = %d",
- intval($allow[0]['data']),
- dbesc(datetime_convert()),
- dbesc($item_id),
- intval($importer['importer_uid'])
- );
- }
- continue;
- }
-
- $datarray['parent-uri'] = $parent_uri;
- $datarray['uid'] = $importer['importer_uid'];
- $datarray['contact-id'] = $importer['id'];
- if(($datarray['verb'] === ACTIVITY_LIKE)
- || ($datarray['verb'] === ACTIVITY_DISLIKE)
- || ($datarray['verb'] === ACTIVITY_ATTEND)
- || ($datarray['verb'] === ACTIVITY_ATTENDNO)
- || ($datarray['verb'] === ACTIVITY_ATTENDMAYBE)) {
- $datarray['type'] = 'activity';
- $datarray['gravity'] = GRAVITY_LIKE;
- // only one like or dislike per person
- // splitted into two queries for performance issues
- $r = q("SELECT `id` FROM `item` WHERE `uid` = %d AND `author-link` = '%s' AND `verb` = '%s' AND `parent-uri` = '%s' AND NOT `deleted` LIMIT 1",
- intval($datarray['uid']),
- dbesc($datarray['author-link']),
- dbesc($datarray['verb']),
- dbesc($datarray['parent-uri'])
- );
- if($r && count($r))
- continue;
-
- $r = q("SELECT `id` FROM `item` WHERE `uid` = %d AND `author-link` = '%s' AND `verb` = '%s' AND `thr-parent` = '%s' AND NOT `deleted` LIMIT 1",
- intval($datarray['uid']),
- dbesc($datarray['author-link']),
- dbesc($datarray['verb']),
- dbesc($datarray['parent-uri'])
- );
- if($r && count($r))
- continue;
-
- }
-
- if(($datarray['verb'] === ACTIVITY_TAG) && ($datarray['object-type'] === ACTIVITY_OBJ_TAGTERM)) {
-
- $xo = parse_xml_string($datarray['object'],false);
- $xt = parse_xml_string($datarray['target'],false);
-
- if($xt->type == ACTIVITY_OBJ_NOTE) {
- $r = q("select * from item where `uri` = '%s' AND `uid` = %d limit 1",
- dbesc($xt->id),
- intval($importer['importer_uid'])
- );
- if(! count($r))
- continue;
-
- // extract tag, if not duplicate, add to parent item
- if($xo->content) {
- if(! (stristr($r[0]['tag'],trim($xo->content)))) {
- q("UPDATE item SET tag = '%s' WHERE id = %d",
- dbesc($r[0]['tag'] . (strlen($r[0]['tag']) ? ',' : '') . '#[url=' . $xo->id . ']'. $xo->content . '[/url]'),
- intval($r[0]['id'])
- );
- create_tags_from_item($r[0]['id']);
- }
- }
- }
- }
-
- $posted_id = item_store($datarray);
-
- continue;
- }
- }
-
- else {
-
- // Head post of a conversation. Have we seen it? If not, import it.
-
-
- $item_id = $item->get_id();
- $datarray = get_atom_elements($feed,$item);
-
- if((x($datarray,'object-type')) && ($datarray['object-type'] === ACTIVITY_OBJ_EVENT)) {
- $ev = bbtoevent($datarray['body']);
- if((x($ev,'desc') || x($ev,'summary')) && x($ev,'start')) {
- $ev['cid'] = $importer['id'];
- $ev['uid'] = $importer['uid'];
- $ev['uri'] = $item_id;
- $ev['edited'] = $datarray['edited'];
- $ev['private'] = $datarray['private'];
- $ev['guid'] = $datarray['guid'];
-
- $r = q("SELECT * FROM `event` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
- dbesc($item_id),
- intval($importer['uid'])
- );
- if(count($r))
- $ev['id'] = $r[0]['id'];
- $xyz = event_store($ev);
- continue;
- }
- }
-
- $r = q("SELECT `uid`, `last-child`, `edited`, `body` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
- dbesc($item_id),
- intval($importer['importer_uid'])
- );
-
- // Update content if 'updated' changes
-
- if(count($r)) {
- if (edited_timestamp_is_newer($r[0], $datarray)) {
-
- // do not accept (ignore) an earlier edit than one we currently have.
- if(datetime_convert('UTC','UTC',$datarray['edited']) < $r[0]['edited'])
- continue;
-
- $r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s', `changed` = '%s' WHERE `uri` = '%s' AND `uid` = %d",
- dbesc($datarray['title']),
- dbesc($datarray['body']),
- dbesc($datarray['tag']),
- dbesc(datetime_convert('UTC','UTC',$datarray['edited'])),
- dbesc(datetime_convert()),
- dbesc($item_id),
- intval($importer['importer_uid'])
- );
- create_tags_from_itemuri($item_id, $importer['importer_uid']);
- update_thread_uri($item_id, $importer['importer_uid']);
- }
-
- // update last-child if it changes
-
- $allow = $item->get_item_tags( NAMESPACE_DFRN, 'comment-allow');
- if($allow && $allow[0]['data'] != $r[0]['last-child']) {
- $r = q("UPDATE `item` SET `last-child` = %d , `changed` = '%s' WHERE `uri` = '%s' AND `uid` = %d",
- intval($allow[0]['data']),
- dbesc(datetime_convert()),
- dbesc($item_id),
- intval($importer['importer_uid'])
- );
- }
- continue;
- }
-
- $datarray['parent-uri'] = $item_id;
- $datarray['uid'] = $importer['importer_uid'];
- $datarray['contact-id'] = $importer['id'];
-
-
- if(! link_compare($datarray['owner-link'],$importer['url'])) {
- // The item owner info is not our contact. It's OK and is to be expected if this is a tgroup delivery,
- // but otherwise there's a possible data mixup on the sender's system.
- // the tgroup delivery code called from item_store will correct it if it's a forum,
- // but we're going to unconditionally correct it here so that the post will always be owned by our contact.
- logger('local_delivery: Correcting item owner.', LOGGER_DEBUG);
- $datarray['owner-name'] = $importer['senderName'];
- $datarray['owner-link'] = $importer['url'];
- $datarray['owner-avatar'] = $importer['thumb'];
- }
-
- if(($importer['rel'] == CONTACT_IS_FOLLOWER) && (! tgroup_check($importer['importer_uid'],$datarray)))
- continue;
-
- // This is my contact on another system, but it's really me.
- // Turn this into a wall post.
- $notify = item_is_remote_self($importer, $datarray);
-
- $posted_id = item_store($datarray, false, $notify);
-
- if(stristr($datarray['verb'],ACTIVITY_POKE)) {
- $verb = urldecode(substr($datarray['verb'],strpos($datarray['verb'],'#')+1));
- if(! $verb)
- continue;
- $xo = parse_xml_string($datarray['object'],false);
-
- if(($xo->type == ACTIVITY_OBJ_PERSON) && ($xo->id)) {
-
- // somebody was poked/prodded. Was it me?
-
- $links = parse_xml_string("".unxmlify($xo->link)." ",false);
-
- foreach($links->link as $l) {
- $atts = $l->attributes();
- switch($atts['rel']) {
- case "alternate":
- $Blink = $atts['href'];
- break;
- default:
- break;
- }
- }
- if($Blink && link_compare($Blink,$a->get_baseurl() . '/profile/' . $importer['nickname'])) {
-
- // send a notification
- require_once('include/enotify.php');
-
- notification(array(
- 'type' => NOTIFY_POKE,
- 'notify_flags' => $importer['notify-flags'],
- 'language' => $importer['language'],
- 'to_name' => $importer['username'],
- 'to_email' => $importer['email'],
- 'uid' => $importer['importer_uid'],
- 'item' => $datarray,
- 'link' => $a->get_baseurl().'/display/'.urlencode(get_item_guid($posted_id)),
- 'source_name' => stripslashes($datarray['author-name']),
- 'source_link' => $datarray['author-link'],
- 'source_photo' => ((link_compare($datarray['author-link'],$importer['url']))
- ? $importer['thumb'] : $datarray['author-avatar']),
- 'verb' => $datarray['verb'],
- 'otype' => 'person',
- 'activity' => $verb,
- 'parent' => $datarray['parent']
- ));
- }
- }
- }
-
- continue;
- }
- }
-
- return 0;
- // NOTREACHED
-
-}
-
-
function new_follower($importer,$contact,$datarray,$item,$sharing = false) {
$url = notags(trim($datarray['author-link']));
$name = notags(trim($datarray['author-name']));
@@ -3564,7 +1461,7 @@ function new_follower($importer,$contact,$datarray,$item,$sharing = false) {
}
}
-function lose_follower($importer,$contact,$datarray,$item) {
+function lose_follower($importer,$contact,$datarray = array(),$item = "") {
if(($contact['rel'] == CONTACT_IS_FRIEND) || ($contact['rel'] == CONTACT_IS_SHARING)) {
q("UPDATE `contact` SET `rel` = %d WHERE `id` = %d",
@@ -3577,7 +1474,7 @@ function lose_follower($importer,$contact,$datarray,$item) {
}
}
-function lose_sharer($importer,$contact,$datarray,$item) {
+function lose_sharer($importer,$contact,$datarray = array(),$item = "") {
if(($contact['rel'] == CONTACT_IS_FRIEND) || ($contact['rel'] == CONTACT_IS_FOLLOWER)) {
q("UPDATE `contact` SET `rel` = %d WHERE `id` = %d",
diff --git a/include/ostatus.php b/include/ostatus.php
index 37b308db70..00022f8c6c 100644
--- a/include/ostatus.php
+++ b/include/ostatus.php
@@ -17,15 +17,6 @@ define('OSTATUS_DEFAULT_POLL_INTERVAL', 30); // given in minutes
define('OSTATUS_DEFAULT_POLL_TIMEFRAME', 1440); // given in minutes
define('OSTATUS_DEFAULT_POLL_TIMEFRAME_MENTIONS', 14400); // given in minutes
-define("NS_ATOM", "http://www.w3.org/2005/Atom");
-define("NS_THR", "http://purl.org/syndication/thread/1.0");
-define("NS_GEORSS", "http://www.georss.org/georss");
-define("NS_ACTIVITY", "http://activitystrea.ms/spec/1.0/");
-define("NS_MEDIA", "http://purl.org/syndication/atommedia");
-define("NS_POCO", "http://portablecontacts.net/spec/1.0");
-define("NS_OSTATUS", "http://ostatus.org/schema/1.0");
-define("NS_STATUSNET", "http://status.net/schema/api/1/");
-
function ostatus_check_follow_friends() {
$r = q("SELECT `uid`,`v` FROM `pconfig` WHERE `cat`='system' AND `k`='ostatus_legacy_contact' AND `v` != ''");
@@ -193,14 +184,14 @@ function ostatus_salmon_author($xml, $importer) {
@$doc->loadXML($xml);
$xpath = new DomXPath($doc);
- $xpath->registerNamespace('atom', "http://www.w3.org/2005/Atom");
- $xpath->registerNamespace('thr', "http://purl.org/syndication/thread/1.0");
- $xpath->registerNamespace('georss', "http://www.georss.org/georss");
- $xpath->registerNamespace('activity', "http://activitystrea.ms/spec/1.0/");
- $xpath->registerNamespace('media', "http://purl.org/syndication/atommedia");
- $xpath->registerNamespace('poco', "http://portablecontacts.net/spec/1.0");
- $xpath->registerNamespace('ostatus', "http://ostatus.org/schema/1.0");
- $xpath->registerNamespace('statusnet', "http://status.net/schema/api/1/");
+ $xpath->registerNamespace('atom', NAMESPACE_ATOM1);
+ $xpath->registerNamespace('thr', NAMESPACE_THREAD);
+ $xpath->registerNamespace('georss', NAMESPACE_GEORSS);
+ $xpath->registerNamespace('activity', NAMESPACE_ACTIVITY);
+ $xpath->registerNamespace('media', NAMESPACE_MEDIA);
+ $xpath->registerNamespace('poco', NAMESPACE_POCO);
+ $xpath->registerNamespace('ostatus', NAMESPACE_OSTATUS);
+ $xpath->registerNamespace('statusnet', NAMESPACE_STATUSNET);
$entries = $xpath->query('/atom:entry');
@@ -224,14 +215,14 @@ function ostatus_import($xml,$importer,&$contact, &$hub) {
@$doc->loadXML($xml);
$xpath = new DomXPath($doc);
- $xpath->registerNamespace('atom', "http://www.w3.org/2005/Atom");
- $xpath->registerNamespace('thr', "http://purl.org/syndication/thread/1.0");
- $xpath->registerNamespace('georss', "http://www.georss.org/georss");
- $xpath->registerNamespace('activity', "http://activitystrea.ms/spec/1.0/");
- $xpath->registerNamespace('media', "http://purl.org/syndication/atommedia");
- $xpath->registerNamespace('poco', "http://portablecontacts.net/spec/1.0");
- $xpath->registerNamespace('ostatus', "http://ostatus.org/schema/1.0");
- $xpath->registerNamespace('statusnet', "http://status.net/schema/api/1/");
+ $xpath->registerNamespace('atom', NAMESPACE_ATOM1);
+ $xpath->registerNamespace('thr', NAMESPACE_THREAD);
+ $xpath->registerNamespace('georss', NAMESPACE_GEORSS);
+ $xpath->registerNamespace('activity', NAMESPACE_ACTIVITY);
+ $xpath->registerNamespace('media', NAMESPACE_MEDIA);
+ $xpath->registerNamespace('poco', NAMESPACE_POCO);
+ $xpath->registerNamespace('ostatus', NAMESPACE_OSTATUS);
+ $xpath->registerNamespace('statusnet', NAMESPACE_STATUSNET);
$gub = "";
$hub_attributes = $xpath->query("/atom:feed/atom:link[@rel='hub']")->item(0)->attributes;
@@ -1120,16 +1111,16 @@ function ostatus_format_picture_post($body) {
function ostatus_add_header($doc, $owner) {
$a = get_app();
- $root = $doc->createElementNS(NS_ATOM, 'feed');
+ $root = $doc->createElementNS(NAMESPACE_ATOM1, 'feed');
$doc->appendChild($root);
- $root->setAttribute("xmlns:thr", NS_THR);
- $root->setAttribute("xmlns:georss", NS_GEORSS);
- $root->setAttribute("xmlns:activity", NS_ACTIVITY);
- $root->setAttribute("xmlns:media", NS_MEDIA);
- $root->setAttribute("xmlns:poco", NS_POCO);
- $root->setAttribute("xmlns:ostatus", NS_OSTATUS);
- $root->setAttribute("xmlns:statusnet", NS_STATUSNET);
+ $root->setAttribute("xmlns:thr", NAMESPACE_THREAD);
+ $root->setAttribute("xmlns:georss", NAMESPACE_GEORSS);
+ $root->setAttribute("xmlns:activity", NAMESPACE_ACTIVITY);
+ $root->setAttribute("xmlns:media", NAMESPACE_MEDIA);
+ $root->setAttribute("xmlns:poco", NAMESPACE_POCO);
+ $root->setAttribute("xmlns:ostatus", NAMESPACE_OSTATUS);
+ $root->setAttribute("xmlns:statusnet", NAMESPACE_STATUSNET);
$attributes = array("uri" => "https://friendi.ca", "version" => FRIENDICA_VERSION."-".DB_UPDATE_VERSION);
xml_add_element($doc, $root, "generator", FRIENDICA_PLATFORM, $attributes);
@@ -1321,6 +1312,10 @@ function ostatus_add_author($doc, $owner) {
function ostatus_entry($doc, $item, $owner, $toplevel = false, $repeat = false) {
$a = get_app();
+ if (($item["id"] != $item["parent"]) AND (normalise_link($item["author-link"]) != normalise_link($owner["url"]))) {
+ logger("OStatus entry is from author ".$owner["url"]." - not from ".$item["author-link"].". Quitting.", LOGGER_DEBUG);
+ }
+
$is_repeat = false;
/* if (!$repeat) {
@@ -1343,15 +1338,15 @@ function ostatus_entry($doc, $item, $owner, $toplevel = false, $repeat = false)
$entry = $doc->createElement("activity:object");
$title = sprintf("New note by %s", $owner["nick"]);
} else {
- $entry = $doc->createElementNS(NS_ATOM, "entry");
+ $entry = $doc->createElementNS(NAMESPACE_ATOM1, "entry");
- $entry->setAttribute("xmlns:thr", NS_THR);
- $entry->setAttribute("xmlns:georss", NS_GEORSS);
- $entry->setAttribute("xmlns:activity", NS_ACTIVITY);
- $entry->setAttribute("xmlns:media", NS_MEDIA);
- $entry->setAttribute("xmlns:poco", NS_POCO);
- $entry->setAttribute("xmlns:ostatus", NS_OSTATUS);
- $entry->setAttribute("xmlns:statusnet", NS_STATUSNET);
+ $entry->setAttribute("xmlns:thr", NAMESPACE_THREAD);
+ $entry->setAttribute("xmlns:georss", NAMESPACE_GEORSS);
+ $entry->setAttribute("xmlns:activity", NAMESPACE_ACTIVITY);
+ $entry->setAttribute("xmlns:media", NAMESPACE_MEDIA);
+ $entry->setAttribute("xmlns:poco", NAMESPACE_POCO);
+ $entry->setAttribute("xmlns:ostatus", NAMESPACE_OSTATUS);
+ $entry->setAttribute("xmlns:statusnet", NAMESPACE_STATUSNET);
$author = ostatus_add_author($doc, $owner);
$entry->appendChild($author);
diff --git a/index.php b/index.php
index bf926d1fe7..2b1053cc1b 100644
--- a/index.php
+++ b/index.php
@@ -233,7 +233,16 @@ if(strlen($a->module)) {
}
/**
- * If not, next look for a 'standard' program module in the 'mod' directory
+ * If not, next look for module overrides by the theme
+ */
+
+ if((! $a->module_loaded) && (file_exists("view/theme/" . current_theme() . "/mod/{$a->module}.php"))) {
+ include_once("view/theme/" . current_theme() . "/mod/{$a->module}.php");
+ // We will not set module_loaded to true to allow for partial overrides.
+ }
+
+ /**
+ * Finally, look for a 'standard' program module in the 'mod' directory
*/
if((! $a->module_loaded) && (file_exists("mod/{$a->module}.php"))) {
diff --git a/mod/_well_known.php b/mod/_well_known.php
index 33070a1ecd..6c33136f95 100644
--- a/mod/_well_known.php
+++ b/mod/_well_known.php
@@ -2,6 +2,7 @@
require_once("mod/hostxrd.php");
require_once("mod/nodeinfo.php");
+if(! function_exists('_well_known_init')) {
function _well_known_init(&$a){
if ($a->argc > 1) {
switch($a->argv[1]) {
@@ -19,7 +20,9 @@ function _well_known_init(&$a){
http_status_exit(404);
killme();
}
+}
+if(! function_exists('wk_social_relay')) {
function wk_social_relay(&$a) {
define('SR_SCOPE_ALL', 'all');
@@ -64,3 +67,4 @@ function wk_social_relay(&$a) {
echo json_encode($relay, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
exit;
}
+}
diff --git a/mod/acctlink.php b/mod/acctlink.php
index a2365803ac..a551e3dbd6 100644
--- a/mod/acctlink.php
+++ b/mod/acctlink.php
@@ -2,8 +2,8 @@
require_once('include/Scrape.php');
+if(! function_exists('acctlink_init')) {
function acctlink_init(&$a) {
-
if(x($_GET,'addr')) {
$addr = trim($_GET['addr']);
$res = probe_url($addr);
@@ -14,3 +14,4 @@ function acctlink_init(&$a) {
}
}
}
+}
diff --git a/mod/acl.php b/mod/acl.php
index f5e04b96a7..5666ccabb8 100644
--- a/mod/acl.php
+++ b/mod/acl.php
@@ -3,8 +3,8 @@
require_once("include/acl_selectors.php");
+if(! function_exists('acl_init')) {
function acl_init(&$a){
acl_lookup($a);
}
-
-
+}
diff --git a/mod/admin.php b/mod/admin.php
index 7f9000807b..ff17c0b8c4 100644
--- a/mod/admin.php
+++ b/mod/admin.php
@@ -2,7 +2,7 @@
/**
* @file mod/admin.php
- *
+ *
* @brief Friendica admin
*/
@@ -23,6 +23,7 @@ require_once("include/text.php");
* @param App $a
*
*/
+if(! function_exists('admin_post')) {
function admin_post(&$a){
@@ -110,6 +111,7 @@ function admin_post(&$a){
goaway($a->get_baseurl(true) . '/admin' );
return; // NOTREACHED
}
+}
/**
* @brief Generates content of the admin panel pages
@@ -128,6 +130,7 @@ function admin_post(&$a){
* @param App $a
* @return string
*/
+if(! function_exists('admin_content')) {
function admin_content(&$a) {
if(!is_site_admin()) {
@@ -245,6 +248,7 @@ function admin_content(&$a) {
return $o;
}
}
+}
/**
* @brief Subpage with some stats about "the federation" network
@@ -260,6 +264,7 @@ function admin_content(&$a) {
* @param App $a
* @return string
*/
+if(! function_exists('admin_page_federation')) {
function admin_page_federation(&$a) {
// get counts on active friendica, diaspora, redmatrix, hubzilla, gnu
// social and statusnet nodes this node is knowing
@@ -284,7 +289,7 @@ function admin_page_federation(&$a) {
// what versions for that platform do we know at all?
// again only the active nodes
$v = q('SELECT count(*) AS total, version FROM gserver
- WHERE last_contact > last_failure AND platform LIKE "%s"
+ WHERE last_contact > last_failure AND platform LIKE "%s"
GROUP BY version
ORDER BY version;', $p);
@@ -301,12 +306,12 @@ function admin_page_federation(&$a) {
$newVC = $vv['total'];
$newVV = $vv['version'];
$posDash = strpos($newVV, '-');
- if($posDash)
+ if($posDash)
$newVV = substr($newVV, 0, $posDash);
if(isset($newV[$newVV]))
- $newV[$newVV] += $newVC;
+ $newV[$newVV] += $newVC;
else
- $newV[$newVV] = $newVC;
+ $newV[$newVV] = $newVC;
}
foreach ($newV as $key => $value) {
array_push($newVv, array('total'=>$value, 'version'=>$key));
@@ -361,6 +366,7 @@ function admin_page_federation(&$a) {
'$baseurl' => $a->get_baseurl(),
));
}
+}
/**
* @brief Admin Inspect Queue Page
@@ -375,6 +381,7 @@ function admin_page_federation(&$a) {
* @param App $a
* @return string
*/
+if(! function_exists('admin_page_queue')) {
function admin_page_queue(&$a) {
// get content from the queue table
$r = q("SELECT c.name,c.nurl,q.id,q.network,q.created,q.last from queue as q, contact as c where c.id=q.cid order by q.cid, q.created;");
@@ -394,6 +401,7 @@ function admin_page_queue(&$a) {
'$entries' => $r,
));
}
+}
/**
* @brief Admin Summary Page
@@ -406,6 +414,7 @@ function admin_page_queue(&$a) {
* @param App $a
* @return string
*/
+if(! function_exists('admin_page_summary')) {
function admin_page_summary(&$a) {
$r = q("SELECT `page-flags`, COUNT(uid) as `count` FROM `user` GROUP BY `page-flags`");
$accounts = array(
@@ -452,12 +461,14 @@ function admin_page_summary(&$a) {
'$plugins' => array( t('Active plugins'), $a->plugins )
));
}
+}
/**
* @brief Process send data from Admin Site Page
- *
+ *
* @param App $a
*/
+if(! function_exists('admin_page_site_post')) {
function admin_page_site_post(&$a) {
if(!x($_POST,"page_site")) {
return;
@@ -770,6 +781,7 @@ function admin_page_site_post(&$a) {
return; // NOTREACHED
}
+}
/**
* @brief Generate Admin Site subpage
@@ -779,6 +791,7 @@ function admin_page_site_post(&$a) {
* @param App $a
* @return string
*/
+if(! function_exists('admin_page_site')) {
function admin_page_site(&$a) {
/* Installed langs */
@@ -983,7 +996,7 @@ function admin_page_site(&$a) {
'$form_security_token' => get_form_security_token("admin_site")
));
-
+}
}
/**
@@ -998,6 +1011,7 @@ function admin_page_site(&$a) {
* @param App $a
* @return string
**/
+if(! function_exists('admin_page_dbsync')) {
function admin_page_dbsync(&$a) {
$o = '';
@@ -1073,14 +1087,15 @@ function admin_page_dbsync(&$a) {
}
return $o;
-
+}
}
/**
* @brief Process data send by Users admin page
- *
+ *
* @param App $a
*/
+if(! function_exists('admin_page_users_post')) {
function admin_page_users_post(&$a){
$pending = ( x($_POST, 'pending') ? $_POST['pending'] : array() );
$users = ( x($_POST, 'user') ? $_POST['user'] : array() );
@@ -1171,6 +1186,7 @@ function admin_page_users_post(&$a){
goaway($a->get_baseurl(true) . '/admin/users' );
return; // NOTREACHED
}
+}
/**
* @brief Admin panel subpage for User management
@@ -1184,6 +1200,7 @@ function admin_page_users_post(&$a){
* @param App $a
* @return string
*/
+if(! function_exists('admin_page_users')) {
function admin_page_users(&$a){
if($a->argc>2) {
$uid = $a->argv[3];
@@ -1336,7 +1353,7 @@ function admin_page_users(&$a){
$o .= paginate($a);
return $o;
}
-
+}
/**
* @brief Plugins admin page
@@ -1354,6 +1371,7 @@ function admin_page_users(&$a){
* @param App $a
* @return string
*/
+if(! function_exists('admin_page_plugins')) {
function admin_page_plugins(&$a){
/*
@@ -1479,17 +1497,19 @@ function admin_page_plugins(&$a){
'$baseurl' => $a->get_baseurl(true),
'$function' => 'plugins',
'$plugins' => $plugins,
- '$pcount' => count($plugins),
+ '$pcount' => count($plugins),
'$noplugshint' => sprintf( t('There are currently no plugins available on your node. You can find the official plugin repository at %1$s and might find other interesting plugins in the open plugin registry at %2$s'), 'https://github.com/friendica/friendica-addons', 'http://addons.friendi.ca'),
'$form_security_token' => get_form_security_token("admin_themes"),
));
}
+}
/**
* @param array $themes
* @param string $th
* @param int $result
*/
+if(! function_exists('toggle_theme')) {
function toggle_theme(&$themes,$th,&$result) {
for($x = 0; $x < count($themes); $x ++) {
if($themes[$x]['name'] === $th) {
@@ -1504,12 +1524,14 @@ function toggle_theme(&$themes,$th,&$result) {
}
}
}
+}
/**
* @param array $themes
* @param string $th
* @return int
*/
+if(! function_exists('theme_status')) {
function theme_status($themes,$th) {
for($x = 0; $x < count($themes); $x ++) {
if($themes[$x]['name'] === $th) {
@@ -1523,12 +1545,13 @@ function theme_status($themes,$th) {
}
return 0;
}
-
+}
/**
* @param array $themes
* @return string
*/
+if(! function_exists('rebuild_theme_table')) {
function rebuild_theme_table($themes) {
$o = '';
if(count($themes)) {
@@ -1542,7 +1565,7 @@ function rebuild_theme_table($themes) {
}
return $o;
}
-
+}
/**
* @brief Themes admin page
@@ -1560,6 +1583,7 @@ function rebuild_theme_table($themes) {
* @param App $a
* @return string
*/
+if(! function_exists('admin_page_themes')) {
function admin_page_themes(&$a){
$allowed_themes_str = get_config('system','allowed_themes');
@@ -1734,13 +1758,14 @@ function admin_page_themes(&$a){
'$form_security_token' => get_form_security_token("admin_themes"),
));
}
-
+}
/**
* @brief Prosesses data send by Logs admin page
- *
+ *
* @param App $a
*/
+if(! function_exists('admin_page_logs_post')) {
function admin_page_logs_post(&$a) {
if(x($_POST,"page_logs")) {
check_form_security_token_redirectOnErr('/admin/logs', 'admin_logs');
@@ -1758,6 +1783,7 @@ function admin_page_logs_post(&$a) {
goaway($a->get_baseurl(true) . '/admin/logs' );
return; // NOTREACHED
}
+}
/**
* @brief Generates admin panel subpage for configuration of the logs
@@ -1775,6 +1801,7 @@ function admin_page_logs_post(&$a) {
* @param App $a
* @return string
*/
+if(! function_exists('admin_page_logs')) {
function admin_page_logs(&$a){
$log_choices = array(
@@ -1806,6 +1833,7 @@ function admin_page_logs(&$a){
'$phplogcode' => "error_reporting(E_ERROR | E_WARNING | E_PARSE );\nini_set('error_log','php.out');\nini_set('log_errors','1');\nini_set('display_errors', '1');",
));
}
+}
/**
* @brief Generates admin panel subpage to view the Friendica log
@@ -1825,6 +1853,7 @@ function admin_page_logs(&$a){
* @param App $a
* @return string
*/
+if(! function_exists('admin_page_viewlogs')) {
function admin_page_viewlogs(&$a){
$t = get_markup_template("admin_viewlogs.tpl");
$f = get_config('system','logfile');
@@ -1861,12 +1890,14 @@ function admin_page_viewlogs(&$a){
'$logname' => get_config('system','logfile')
));
}
+}
/**
* @brief Prosesses data send by the features admin page
- *
+ *
* @param App $a
*/
+if(! function_exists('admin_page_features_post')) {
function admin_page_features_post(&$a) {
check_form_security_token_redirectOnErr('/admin/features', 'admin_manage_features');
@@ -1898,23 +1929,25 @@ function admin_page_features_post(&$a) {
goaway($a->get_baseurl(true) . '/admin/features' );
return; // NOTREACHED
}
+}
/**
* @brief Subpage for global additional feature management
- *
+ *
* This functin generates the subpage 'Manage Additional Features'
* for the admin panel. At this page the admin can set preferences
- * for the user settings of the 'additional features'. If needed this
+ * for the user settings of the 'additional features'. If needed this
* preferences can be locked through the admin.
- *
+ *
* The returned string contains the HTML code of the subpage 'Manage
* Additional Features'
- *
+ *
* @param App $a
* @return string
*/
+if(! function_exists('admin_page_features')) {
function admin_page_features(&$a) {
-
+
if((argc() > 1) && (argv(1) === 'features')) {
$arr = array();
$features = get_features(false);
@@ -1933,7 +1966,7 @@ function admin_page_features(&$a) {
);
}
}
-
+
$tpl = get_markup_template("admin_settings_features.tpl");
$o .= replace_macros($tpl, array(
'$form_security_token' => get_form_security_token("admin_manage_features"),
@@ -1945,3 +1978,4 @@ function admin_page_features(&$a) {
return $o;
}
}
+}
diff --git a/mod/allfriends.php b/mod/allfriends.php
index 356a389b83..8843265a99 100644
--- a/mod/allfriends.php
+++ b/mod/allfriends.php
@@ -5,6 +5,7 @@ require_once('include/Contact.php');
require_once('include/contact_selectors.php');
require_once('mod/contacts.php');
+if(! function_exists('allfriends_content')) {
function allfriends_content(&$a) {
$o = '';
@@ -97,3 +98,4 @@ function allfriends_content(&$a) {
return $o;
}
+}
diff --git a/mod/amcd.php b/mod/amcd.php
index a2a1327e6d..141a804298 100644
--- a/mod/amcd.php
+++ b/mod/amcd.php
@@ -1,5 +1,5 @@
get_parameters();
$token = $params['oauth_token'];
@@ -19,9 +17,10 @@ function oauth_get_client($request){
return $r[0];
}
+}
+if(! function_exists('api_post')) {
function api_post(&$a) {
-
if(! local_user()) {
notice( t('Permission denied.') . EOL);
return;
@@ -31,9 +30,10 @@ function api_post(&$a) {
notice( t('Permission denied.') . EOL);
return;
}
-
+}
}
+if(! function_exists('api_content')) {
function api_content(&$a) {
if ($a->cmd=='api/oauth/authorize'){
/*
@@ -114,3 +114,4 @@ function api_content(&$a) {
echo api_call($a);
killme();
}
+}
diff --git a/mod/apps.php b/mod/apps.php
index a821ef5d5b..e807feae74 100644
--- a/mod/apps.php
+++ b/mod/apps.php
@@ -1,25 +1,23 @@
apps)==0)
+ notice( t('No installed applications.') . EOL);
+
+ $tpl = get_markup_template("apps.tpl");
+ return replace_macros($tpl, array(
+ '$title' => $title,
+ '$apps' => $a->apps,
+ ));
}
-
- $title = t('Applications');
-
- if(count($a->apps)==0)
- notice( t('No installed applications.') . EOL);
-
-
- $tpl = get_markup_template("apps.tpl");
- return replace_macros($tpl, array(
- '$title' => $title,
- '$apps' => $a->apps,
- ));
-
-
-
}
diff --git a/mod/attach.php b/mod/attach.php
index 03f850f0d1..849faa26ec 100644
--- a/mod/attach.php
+++ b/mod/attach.php
@@ -1,7 +1,7 @@
argc != 2) {
@@ -47,3 +47,4 @@ function attach_init(&$a) {
killme();
// NOTREACHED
}
+}
diff --git a/mod/babel.php b/mod/babel.php
index d31e090c55..56455bdb21 100644
--- a/mod/babel.php
+++ b/mod/babel.php
@@ -9,55 +9,56 @@ function visible_lf($s) {
return str_replace("\n",' ', $s);
}
+if(! function_exists('babel_content')) {
function babel_content(&$a) {
$o .= 'Babel Diagnostic ';
$o .= '';
+ $o .= ' ';
$o .= ' ';
$o .= '';
$o .= t('Source (Diaspora) text to convert to BBcode:') . EOL . '' . htmlspecialchars($_REQUEST['d2bbtext']) .' ' . EOL;
- $o .= ' ';
+ $o .= ' ';
$o .= ' ';
if(x($_REQUEST,'text')) {
$text = trim($_REQUEST['text']);
- $o .= "" . t("Source input: ") . " " . EOL. EOL;
- $o .= visible_lf($text) . EOL. EOL;
+ $o .= "" . t("Source input: ") . " " . EOL. EOL;
+ $o .= visible_lf($text) . EOL. EOL;
$html = bbcode($text);
- $o .= "" . t("bb2html (raw HTML): ") . " " . EOL. EOL;
- $o .= htmlspecialchars($html). EOL. EOL;
+ $o .= "" . t("bb2html (raw HTML): ") . " " . EOL. EOL;
+ $o .= htmlspecialchars($html). EOL. EOL;
//$html = bbcode($text);
- $o .= "" . t("bb2html: ") . " " . EOL. EOL;
- $o .= $html. EOL. EOL;
+ $o .= "" . t("bb2html: ") . " " . EOL. EOL;
+ $o .= $html. EOL. EOL;
$bbcode = html2bbcode($html);
- $o .= "" . t("bb2html2bb: ") . " " . EOL. EOL;
- $o .= visible_lf($bbcode) . EOL. EOL;
+ $o .= "" . t("bb2html2bb: ") . " " . EOL. EOL;
+ $o .= visible_lf($bbcode) . EOL. EOL;
$diaspora = bb2diaspora($text);
- $o .= "" . t("bb2md: ") . " " . EOL. EOL;
- $o .= visible_lf($diaspora) . EOL. EOL;
+ $o .= "" . t("bb2md: ") . " " . EOL. EOL;
+ $o .= visible_lf($diaspora) . EOL. EOL;
$html = Markdown($diaspora);
- $o .= "" . t("bb2md2html: ") . " " . EOL. EOL;
- $o .= $html. EOL. EOL;
+ $o .= "" . t("bb2md2html: ") . " " . EOL. EOL;
+ $o .= $html. EOL. EOL;
$bbcode = diaspora2bb($diaspora);
- $o .= "" . t("bb2dia2bb: ") . " " . EOL. EOL;
- $o .= visible_lf($bbcode) . EOL. EOL;
+ $o .= "" . t("bb2dia2bb: ") . " " . EOL. EOL;
+ $o .= visible_lf($bbcode) . EOL. EOL;
$bbcode = html2bbcode($html);
- $o .= "" . t("bb2md2html2bb: ") . " " . EOL. EOL;
- $o .= visible_lf($bbcode) . EOL. EOL;
+ $o .= "" . t("bb2md2html2bb: ") . " " . EOL. EOL;
+ $o .= visible_lf($bbcode) . EOL. EOL;
@@ -66,14 +67,15 @@ function babel_content(&$a) {
if(x($_REQUEST,'d2bbtext')) {
$d2bbtext = trim($_REQUEST['d2bbtext']);
- $o .= "" . t("Source input (Diaspora format): ") . " " . EOL. EOL;
- $o .= visible_lf($d2bbtext) . EOL. EOL;
+ $o .= "" . t("Source input (Diaspora format): ") . " " . EOL. EOL;
+ $o .= visible_lf($d2bbtext) . EOL. EOL;
$bb = diaspora2bb($d2bbtext);
- $o .= "" . t("diaspora2bb: ") . " " . EOL. EOL;
- $o .= visible_lf($bb) . EOL. EOL;
+ $o .= "" . t("diaspora2bb: ") . " " . EOL. EOL;
+ $o .= visible_lf($bb) . EOL. EOL;
}
return $o;
}
+}
diff --git a/mod/bookmarklet.php b/mod/bookmarklet.php
index be8645c1fd..4db6bf401e 100644
--- a/mod/bookmarklet.php
+++ b/mod/bookmarklet.php
@@ -1,12 +1,14 @@
'.t('Login').'';
@@ -44,3 +46,4 @@ function bookmarklet_content(&$a) {
return $o;
}
+}
diff --git a/mod/cb.php b/mod/cb.php
index 6375d23984..04d01302c1 100644
--- a/mod/cb.php
+++ b/mod/cb.php
@@ -4,21 +4,28 @@
* General purpose landing page for plugins/addons
*/
-
+if(! function_exists('cb_init')) {
function cb_init(&$a) {
call_hooks('cb_init');
}
+}
+if(! function_exists('cb_post')) {
function cb_post(&$a) {
call_hooks('cb_post', $_POST);
}
+}
+if(! function_exists('cb_afterpost')) {
function cb_afterpost(&$a) {
call_hooks('cb_afterpost');
}
+}
+if(! function_exists('cb_content')) {
function cb_content(&$a) {
$o = '';
call_hooks('cb_content', $o);
return $o;
-}
\ No newline at end of file
+}
+}
diff --git a/mod/common.php b/mod/common.php
index c9409b3ef1..4cdbe9641b 100644
--- a/mod/common.php
+++ b/mod/common.php
@@ -5,6 +5,7 @@ require_once('include/Contact.php');
require_once('include/contact_selectors.php');
require_once('mod/contacts.php');
+if(! function_exists('common_content')) {
function common_content(&$a) {
$o = '';
@@ -144,3 +145,4 @@ function common_content(&$a) {
return $o;
}
+}
diff --git a/mod/community.php b/mod/community.php
index b6d72a3555..c64c6216b1 100644
--- a/mod/community.php
+++ b/mod/community.php
@@ -1,15 +1,14 @@
data['contact']['network'] != "") AND ($a->data['contact']['network'] != NETWORK_DFRN)) {
$networkname = format_network_name($a->data['contact']['network'],$a->data['contact']['url']);
- } else
+ } else
$networkname = '';
$vcard_widget = replace_macros(get_markup_template("vcard-widget.tpl"),array(
@@ -88,9 +89,10 @@ function contacts_init(&$a) {
'$base' => $base
));
-
+}
}
+if(! function_exists('contacts_batch_actions')) {
function contacts_batch_actions(&$a){
$contacts_id = $_POST['contact_batch'];
if (!is_array($contacts_id)) return;
@@ -132,10 +134,10 @@ function contacts_batch_actions(&$a){
goaway($a->get_baseurl(true) . '/' . $_SESSION['return_url']);
else
goaway($a->get_baseurl(true) . '/contacts');
-
+}
}
-
+if(! function_exists('contacts_post')) {
function contacts_post(&$a) {
if(! local_user())
@@ -215,10 +217,11 @@ function contacts_post(&$a) {
$a->data['contact'] = $r[0];
return;
-
+}
}
/*contact actions*/
+if(! function_exists('_contact_update')) {
function _contact_update($contact_id) {
$r = q("SELECT `uid`, `url`, `network` FROM `contact` WHERE `id` = %d", intval($contact_id));
if (!$r)
@@ -239,7 +242,9 @@ function _contact_update($contact_id) {
// pull feed and consume it, which should subscribe to the hub.
proc_run('php',"include/onepoll.php","$contact_id", "force");
}
+}
+if(! function_exists('_contact_update_profile')) {
function _contact_update_profile($contact_id) {
$r = q("SELECT `uid`, `url`, `network` FROM `contact` WHERE `id` = %d", intval($contact_id));
if (!$r)
@@ -299,7 +304,9 @@ function _contact_update_profile($contact_id) {
// Update the entry in the gcontact table
update_gcontact_from_probe($data["url"]);
}
+}
+if(! function_exists('_contact_block')) {
function _contact_block($contact_id, $orig_record) {
$blocked = (($orig_record['blocked']) ? 0 : 1);
$r = q("UPDATE `contact` SET `blocked` = %d WHERE `id` = %d AND `uid` = %d",
@@ -308,8 +315,10 @@ function _contact_block($contact_id, $orig_record) {
intval(local_user())
);
return $r;
-
}
+}
+
+if(! function_exists('_contact_ignore')) {
function _contact_ignore($contact_id, $orig_record) {
$readonly = (($orig_record['readonly']) ? 0 : 1);
$r = q("UPDATE `contact` SET `readonly` = %d WHERE `id` = %d AND `uid` = %d",
@@ -319,6 +328,9 @@ function _contact_ignore($contact_id, $orig_record) {
);
return $r;
}
+}
+
+if(! function_exists('_contact_archive')) {
function _contact_archive($contact_id, $orig_record) {
$archived = (($orig_record['archive']) ? 0 : 1);
$r = q("UPDATE `contact` SET `archive` = %d WHERE `id` = %d AND `uid` = %d",
@@ -331,14 +343,18 @@ function _contact_archive($contact_id, $orig_record) {
}
return $r;
}
+}
+
+if(! function_exists('_contact_drop')) {
function _contact_drop($contact_id, $orig_record) {
$a = get_app();
terminate_friendship($a->user,$a->contact,$orig_record);
contact_remove($orig_record['id']);
}
+}
-
+if(! function_exists('contacts_content')) {
function contacts_content(&$a) {
$sort_type = 0;
@@ -806,7 +822,9 @@ function contacts_content(&$a) {
return $o;
}
+}
+if(! function_exists('contacts_tab')) {
function contacts_tab($a, $contact_id, $active_tab) {
// tabs
$tabs = array(
@@ -880,7 +898,9 @@ function contacts_tab($a, $contact_id, $active_tab) {
return $tab_str;
}
+}
+if(! function_exists('contact_posts')) {
function contact_posts($a, $contact_id) {
$r = q("SELECT `url` FROM `contact` WHERE `id` = %d", intval($contact_id));
@@ -908,7 +928,9 @@ function contact_posts($a, $contact_id) {
return $o;
}
+}
+if(! function_exists('_contact_detail_for_template')) {
function _contact_detail_for_template($rr){
$community = '';
@@ -959,7 +981,7 @@ function _contact_detail_for_template($rr){
'url' => $url,
'network' => network_to_name($rr['network'], $rr['url']),
);
-
+}
}
/**
diff --git a/mod/content.php b/mod/content.php
index c5a5556116..ab0fe7e4bf 100644
--- a/mod/content.php
+++ b/mod/content.php
@@ -15,7 +15,7 @@
// fast - e.g. one or two milliseconds to fetch parent items for the current content,
// and 10-20 milliseconds to fetch all the child items.
-
+if(! function_exists('content_content')) {
function content_content(&$a, $update = 0) {
require_once('include/conversation.php');
@@ -61,7 +61,7 @@ function content_content(&$a, $update = 0) {
$o = '';
-
+
$contact_id = $a->cid;
@@ -100,7 +100,7 @@ function content_content(&$a, $update = 0) {
$def_acl = array('allow_cid' => $str);
}
-
+
$sql_options = (($star) ? " and starred = 1 " : '');
$sql_options .= (($bmark) ? " and bookmark = 1 " : '');
@@ -137,7 +137,7 @@ function content_content(&$a, $update = 0) {
}
elseif($cid) {
- $r = q("SELECT `id`,`name`,`network`,`writable`,`nurl` FROM `contact` WHERE `id` = %d
+ $r = q("SELECT `id`,`name`,`network`,`writable`,`nurl` FROM `contact` WHERE `id` = %d
AND `blocked` = 0 AND `pending` = 0 LIMIT 1",
intval($cid)
);
@@ -304,9 +304,9 @@ function content_content(&$a, $update = 0) {
echo json_encode($o);
killme();
}
+}
-
-
+if(! function_exists('render_content')) {
function render_content(&$a, $items, $mode, $update, $preview = false) {
require_once('include/bbcode.php');
@@ -373,7 +373,7 @@ function render_content(&$a, $items, $mode, $update, $preview = false) {
if($mode === 'network-new' || $mode === 'search' || $mode === 'community') {
- // "New Item View" on network page or search page results
+ // "New Item View" on network page or search page results
// - just loop through the items and format them minimally for display
//$tpl = get_markup_template('search_item.tpl');
@@ -389,7 +389,7 @@ function render_content(&$a, $items, $mode, $update, $preview = false) {
$sparkle = '';
if($mode === 'search' || $mode === 'community') {
- if(((activity_match($item['verb'],ACTIVITY_LIKE)) || (activity_match($item['verb'],ACTIVITY_DISLIKE)))
+ if(((activity_match($item['verb'],ACTIVITY_LIKE)) || (activity_match($item['verb'],ACTIVITY_DISLIKE)))
&& ($item['id'] != $item['parent']))
continue;
$nickname = $item['nickname'];
@@ -436,7 +436,7 @@ function render_content(&$a, $items, $mode, $update, $preview = false) {
$drop = array(
'dropping' => $dropping,
- 'select' => t('Select'),
+ 'select' => t('Select'),
'delete' => t('Delete'),
);
@@ -526,11 +526,11 @@ function render_content(&$a, $items, $mode, $update, $preview = false) {
$comments[$item['parent']] = 1;
else
$comments[$item['parent']] += 1;
- } elseif(! x($comments,$item['parent']))
+ } elseif(! x($comments,$item['parent']))
$comments[$item['parent']] = 0; // avoid notices later on
}
- // map all the like/dislike activities for each parent item
+ // map all the like/dislike activities for each parent item
// Store these in the $alike and $dlike arrays
foreach($items as $item) {
@@ -617,14 +617,14 @@ function render_content(&$a, $items, $mode, $update, $preview = false) {
$redirect_url = $a->get_baseurl($ssl_state) . '/redir/' . $item['cid'] ;
- $lock = ((($item['private'] == 1) || (($item['uid'] == local_user()) && (strlen($item['allow_cid']) || strlen($item['allow_gid'])
+ $lock = ((($item['private'] == 1) || (($item['uid'] == local_user()) && (strlen($item['allow_cid']) || strlen($item['allow_gid'])
|| strlen($item['deny_cid']) || strlen($item['deny_gid']))))
? t('Private Message')
: false);
// Top-level wall post not written by the wall owner (wall-to-wall)
- // First figure out who owns it.
+ // First figure out who owns it.
$osparkle = '';
@@ -651,13 +651,13 @@ function render_content(&$a, $items, $mode, $update, $preview = false) {
if((! $owner_linkmatch) && (! $alias_linkmatch) && (! $owner_namematch)) {
// The author url doesn't match the owner (typically the contact)
- // and also doesn't match the contact alias.
- // The name match is a hack to catch several weird cases where URLs are
+ // and also doesn't match the contact alias.
+ // The name match is a hack to catch several weird cases where URLs are
// all over the park. It can be tricked, but this prevents you from
// seeing "Bob Smith to Bob Smith via Wall-to-wall" and you know darn
- // well that it's the same Bob Smith.
+ // well that it's the same Bob Smith.
- // But it could be somebody else with the same name. It just isn't highly likely.
+ // But it could be somebody else with the same name. It just isn't highly likely.
$owner_url = $item['owner-link'];
@@ -666,7 +666,7 @@ function render_content(&$a, $items, $mode, $update, $preview = false) {
$template = $wallwall;
$commentww = 'ww';
// If it is our contact, use a friendly redirect link
- if((link_compare($item['owner-link'],$item['url']))
+ if((link_compare($item['owner-link'],$item['url']))
&& ($item['network'] === NETWORK_DFRN)) {
$owner_url = $redirect_url;
$osparkle = ' sparkle';
@@ -678,7 +678,7 @@ function render_content(&$a, $items, $mode, $update, $preview = false) {
}
$likebuttons = '';
- $shareable = ((($profile_owner == local_user()) && ($item['private'] != 1)) ? true : false);
+ $shareable = ((($profile_owner == local_user()) && ($item['private'] != 1)) ? true : false);
if($page_writeable) {
/* if($toplevelpost) { */
@@ -698,7 +698,7 @@ function render_content(&$a, $items, $mode, $update, $preview = false) {
if(($show_comment_box) || (($show_comment_box == false) && ($override_comment_box == false) && ($item['last-child']))) {
$comment = replace_macros($cmnt_tpl,array(
- '$return_path' => '',
+ '$return_path' => '',
'$jsreload' => (($mode === 'display') ? $_SESSION['return_url'] : ''),
'$type' => (($mode === 'profile') ? 'wall-comment' : 'net-comment'),
'$id' => $item['item_id'],
@@ -739,7 +739,7 @@ function render_content(&$a, $items, $mode, $update, $preview = false) {
$drop = array(
'dropping' => $dropping,
- 'select' => t('Select'),
+ 'select' => t('Select'),
'delete' => t('Delete'),
);
@@ -805,9 +805,9 @@ function render_content(&$a, $items, $mode, $update, $preview = false) {
$shiny = "";
if(strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC','now - 12 hours')) > 0)
- $shiny = 'shiny';
+ $shiny = 'shiny';
- //
+ //
localize_item($item);
@@ -897,5 +897,5 @@ function render_content(&$a, $items, $mode, $update, $preview = false) {
return $threads;
-
+}
}
diff --git a/mod/credits.php b/mod/credits.php
index f8cfb03f37..8e6321760b 100644
--- a/mod/credits.php
+++ b/mod/credits.php
@@ -5,6 +5,7 @@
* addons repository will be listed though ATM)
*/
+if(! function_exists('credits_content')) {
function credits_content (&$a) {
/* fill the page with credits */
$f = fopen('util/credits.txt','r');
@@ -18,3 +19,4 @@ function credits_content (&$a) {
'$names' => $arr,
));
}
+}
diff --git a/mod/crepair.php b/mod/crepair.php
index 5b4db09dac..50502b4987 100644
--- a/mod/crepair.php
+++ b/mod/crepair.php
@@ -2,6 +2,7 @@
require_once("include/contact_selectors.php");
require_once("mod/contacts.php");
+if(! function_exists('crepair_init')) {
function crepair_init(&$a) {
if(! local_user())
return;
@@ -28,8 +29,9 @@ function crepair_init(&$a) {
profile_load($a, "", 0, get_contact_details_by_url($contact["url"]));
}
}
+}
-
+if(! function_exists('crepair_post')) {
function crepair_post(&$a) {
if(! local_user())
return;
@@ -91,9 +93,9 @@ function crepair_post(&$a) {
return;
}
+}
-
-
+if(! function_exists('crepair_content')) {
function crepair_content(&$a) {
if(! local_user()) {
@@ -180,5 +182,5 @@ function crepair_content(&$a) {
));
return $o;
-
+}
}
diff --git a/mod/delegate.php b/mod/delegate.php
index 20d2e605e0..d421de3764 100644
--- a/mod/delegate.php
+++ b/mod/delegate.php
@@ -1,11 +1,13 @@
get_baseurl())),
intval(local_user()),
dbesc(NETWORK_DFRN)
- );
+ );
if(! count($r)) {
notice( t('No potential page delegates located.') . EOL);
@@ -144,5 +146,5 @@ function delegate_content(&$a) {
return $o;
-
+}
}
diff --git a/mod/dfrn_confirm.php b/mod/dfrn_confirm.php
index 27c04a908d..00e215e334 100644
--- a/mod/dfrn_confirm.php
+++ b/mod/dfrn_confirm.php
@@ -16,6 +16,7 @@
require_once('include/enotify.php');
+if(! function_exists('dfrn_confirm_post')) {
function dfrn_confirm_post(&$a,$handsfree = null) {
if(is_array($handsfree)) {
@@ -801,5 +802,5 @@ function dfrn_confirm_post(&$a,$handsfree = null) {
goaway(z_root());
// NOTREACHED
-
+}
}
diff --git a/mod/dfrn_notify.php b/mod/dfrn_notify.php
index 4aa777b550..7623b366cb 100644
--- a/mod/dfrn_notify.php
+++ b/mod/dfrn_notify.php
@@ -1,10 +1,12 @@
set_pager_itemspage(60);
@@ -16,23 +16,23 @@ function directory_init(&$a) {
unset($_SESSION['mobile-theme']);
}
-
+}
}
-
+if(! function_exists('directory_post')) {
function directory_post(&$a) {
if(x($_POST,'search'))
$a->data['search'] = $_POST['search'];
}
+}
-
-
+if(! function_exists('directory_content')) {
function directory_content(&$a) {
global $db;
require_once("mod/proxy.php");
- if((get_config('system','block_public')) && (! local_user()) && (! remote_user()) ||
+ if((get_config('system','block_public')) && (! local_user()) && (! remote_user()) ||
(get_config('system','block_local_dir')) && (! local_user()) && (! remote_user())) {
notice( t('Public access denied.') . EOL);
return;
@@ -123,14 +123,14 @@ function directory_content(&$a) {
}
// if(strlen($rr['dob'])) {
// if(($years = age($rr['dob'],$rr['timezone'],'')) != 0)
-// $details .= ' ' . t('Age: ') . $years ;
+// $details .= ' ' . t('Age: ') . $years ;
// }
// if(strlen($rr['gender']))
// $details .= ' ' . t('Gender: ') . $rr['gender'];
// show if account is a community account
- /// @TODO The other page types should be also respected, but first we need a good
+ /// @TODO The other page types should be also respected, but first we need a good
/// translatiion and systemwide consistency for displaying the page type
if((intval($rr['page-flags']) == PAGE_COMMUNITY) OR (intval($rr['page-flags']) == PAGE_PRVGROUP))
$community = true;
@@ -158,7 +158,7 @@ function directory_content(&$a) {
else {
$location_e = $location;
}
-
+
$photo_menu = array(array(t("View Profile"), zrl($profile_link)));
$entry = array(
@@ -217,3 +217,4 @@ function directory_content(&$a) {
return $o;
}
+}
diff --git a/mod/dirfind.php b/mod/dirfind.php
index 0dfe4d67a9..f5e90705b7 100644
--- a/mod/dirfind.php
+++ b/mod/dirfind.php
@@ -5,6 +5,7 @@ require_once('include/Contact.php');
require_once('include/contact_selectors.php');
require_once('mod/contacts.php');
+if(! function_exists('dirfind_init')) {
function dirfind_init(&$a) {
if(! local_user()) {
@@ -19,9 +20,9 @@ function dirfind_init(&$a) {
$a->page['aside'] .= follow_widget();
}
+}
-
-
+if(! function_exists('dirfind_content')) {
function dirfind_content(&$a, $prefix = "") {
$community = false;
@@ -235,3 +236,4 @@ function dirfind_content(&$a, $prefix = "") {
return $o;
}
+}
diff --git a/mod/display.php b/mod/display.php
index 4e33927072..9995a2b3ef 100644
--- a/mod/display.php
+++ b/mod/display.php
@@ -1,5 +1,5 @@
array('term', t("Save to Folder:"), '', '', $filetags, t('- select -')),
'$submit' => t('Save'),
));
-
+
echo $o;
}
killme();
}
+}
diff --git a/mod/filerm.php b/mod/filerm.php
index c266082c8f..be3456b58d 100644
--- a/mod/filerm.php
+++ b/mod/filerm.php
@@ -1,5 +1,6 @@
argv[1]=="json"){
$register_policy = Array('REGISTER_CLOSED', 'REGISTER_APPROVE', 'REGISTER_OPEN');
@@ -56,9 +57,9 @@ function friendica_init(&$a) {
killme();
}
}
+}
-
-
+if(! function_exists('friendica_content')) {
function friendica_content(&$a) {
$o = '';
@@ -70,7 +71,7 @@ function friendica_content(&$a) {
$o .= t('This is Friendica, version') . ' ' . FRIENDICA_VERSION . ' ';
$o .= t('running at web location') . ' ' . z_root() . '
';
- $o .= t('Please visit Friendica.com to learn more about the Friendica project.') . '
';
+ $o .= t('Please visit Friendica.com to learn more about the Friendica project.') . '
';
$o .= t('Bug reports and issues: please visit') . ' ' . ''.t('the bugtracker at github').'
';
$o .= t('Suggestions, praise, donations, etc. - please email "Info" at Friendica - dot com') . '
';
@@ -102,8 +103,8 @@ function friendica_content(&$a) {
else
$o .= '' . t('No installed plugins/addons/apps') . '
';
- call_hooks('about_hook', $o);
+ call_hooks('about_hook', $o);
return $o;
-
+}
}
diff --git a/mod/fsuggest.php b/mod/fsuggest.php
index 6b1cbd7533..26a5e98063 100644
--- a/mod/fsuggest.php
+++ b/mod/fsuggest.php
@@ -1,6 +1,6 @@
';
- $o .= contact_selector('suggest','suggest-select', false,
+ $o .= contact_selector('suggest','suggest-select', false,
array('size' => 4, 'exclude' => $contact_id, 'networks' => 'DFRN_ONLY', 'single' => true));
@@ -109,3 +109,4 @@ function fsuggest_content(&$a) {
return $o;
}
+}
diff --git a/mod/group.php b/mod/group.php
index 5b28784f56..2f8053eefb 100644
--- a/mod/group.php
+++ b/mod/group.php
@@ -1,18 +1,21 @@
page['aside'] = group_side('contacts','group','extended',(($a->argc > 1) ? intval($a->argv[1]) : 0));
}
}
+}
-
-
+if(! function_exists('group_post')) {
function group_post(&$a) {
if(! local_user()) {
@@ -64,7 +67,9 @@ function group_post(&$a) {
}
return;
}
+}
+if(! function_exists('group_content')) {
function group_content(&$a) {
$change = false;
@@ -229,5 +234,5 @@ function group_content(&$a) {
}
return replace_macros($tpl, $context);
-
+}
}
diff --git a/mod/hcard.php b/mod/hcard.php
index 6d2d9e2ebf..af49423de3 100644
--- a/mod/hcard.php
+++ b/mod/hcard.php
@@ -1,5 +1,6 @@
argc > 2) && ($a->argv[2] === 'view')) {
$which = $a->user['nickname'];
- $profile = $a->argv[1];
+ $profile = $a->argv[1];
}
profile_load($a,$which,$profile);
@@ -23,7 +24,7 @@ function hcard_init(&$a) {
if((x($a->profile,'page-flags')) && ($a->profile['page-flags'] == PAGE_COMMUNITY)) {
$a->page['htmlhead'] .= ' ';
}
- if(x($a->profile,'openidserver'))
+ if(x($a->profile,'openidserver'))
$a->page['htmlhead'] .= ' ' . "\r\n";
if(x($a->profile,'openid')) {
$delegate = ((strstr($a->profile['openid'],'://')) ? $a->profile['openid'] : 'http://' . $a->profile['openid']);
@@ -42,10 +43,9 @@ function hcard_init(&$a) {
$uri = urlencode('acct:' . $a->profile['nickname'] . '@' . $a->get_hostname() . (($a->path) ? '/' . $a->path : ''));
$a->page['htmlhead'] .= ' ' . "\r\n";
header('Link: <' . $a->get_baseurl() . '/xrd/?uri=' . $uri . '>; rel="lrdd"; type="application/xrd+xml"', false);
-
+
$dfrn_pages = array('request', 'confirm', 'notify', 'poll');
foreach($dfrn_pages as $dfrn)
$a->page['htmlhead'] .= " get_baseurl()."/dfrn_{$dfrn}/{$which}\" />\r\n";
-
}
-
+}
diff --git a/mod/help.php b/mod/help.php
index 5465d3e900..320e622fa5 100644
--- a/mod/help.php
+++ b/mod/help.php
@@ -18,6 +18,7 @@ if (!function_exists('load_doc_file')) {
}
+if(! function_exists('help_content')) {
function help_content(&$a) {
nav_set_selected('help');
@@ -98,5 +99,5 @@ function help_content(&$a) {
}
".$html;
return $html;
-
+}
}
diff --git a/mod/hostxrd.php b/mod/hostxrd.php
index 4121764f1a..5b178e9b8f 100644
--- a/mod/hostxrd.php
+++ b/mod/hostxrd.php
@@ -2,6 +2,7 @@
require_once('include/crypto.php');
+if(! function_exists('hostxrd_init')) {
function hostxrd_init(&$a) {
header('Access-Control-Allow-Origin: *');
header("Content-type: text/xml");
@@ -27,5 +28,5 @@ function hostxrd_init(&$a) {
));
session_write_close();
exit();
-
+}
}
diff --git a/mod/ignored.php b/mod/ignored.php
index e876b4ef8b..8a681a1154 100644
--- a/mod/ignored.php
+++ b/mod/ignored.php
@@ -1,6 +1,6 @@
config['system']['theme'] = "../install";
$a->theme['stylesheet'] = $a->get_baseurl()."/view/install/style.css";
-
-
-
+
+
+
global $install_wizard_pass;
if (x($_POST,'pass'))
$install_wizard_pass = intval($_POST['pass']);
-
+}
}
+if(! function_exists('install_post')) {
function install_post(&$a) {
global $install_wizard_pass, $db;
@@ -112,14 +113,18 @@ function install_post(&$a) {
break;
}
}
+}
+if(! function_exists('get_db_errno')) {
function get_db_errno() {
if(class_exists('mysqli'))
return mysqli_connect_errno();
else
return mysql_errno();
}
+}
+if(! function_exists('install_content')) {
function install_content(&$a) {
global $install_wizard_pass, $db;
@@ -304,6 +309,7 @@ function install_content(&$a) {
}
}
+}
/**
* checks : array passed to template
@@ -312,7 +318,8 @@ function install_content(&$a) {
* required : boolean
* help : string optional
*/
-function check_add(&$checks, $title, $status, $required, $help){
+if(! function_exists('check_add')) {
+function check_add(&$checks, $title, $status, $required, $help) {
$checks[] = array(
'title' => $title,
'status' => $status,
@@ -320,7 +327,9 @@ function check_add(&$checks, $title, $status, $required, $help){
'help' => $help,
);
}
+}
+if(! function_exists('check_php')) {
function check_php(&$phpath, &$checks) {
$passed = $passed2 = $passed3 = false;
if (strlen($phpath)){
@@ -370,9 +379,10 @@ function check_php(&$phpath, &$checks) {
check_add($checks, t('PHP register_argc_argv'), $passed3, true, $help);
}
-
+}
}
+if(! function_exists('check_keys')) {
function check_keys(&$checks) {
$help = '';
@@ -392,10 +402,10 @@ function check_keys(&$checks) {
$help .= t('If running under Windows, please see "http://www.php.net/manual/en/openssl.installation.php".');
}
check_add($checks, t('Generate encryption keys'), $res, true, $help);
-
+}
}
-
+if(! function_exists('check_funcs')) {
function check_funcs(&$checks) {
$ck_funcs = array();
check_add($ck_funcs, t('libCurl PHP module'), true, true, "");
@@ -457,8 +467,9 @@ function check_funcs(&$checks) {
/*if((x($_SESSION,'sysmsg')) && is_array($_SESSION['sysmsg']) && count($_SESSION['sysmsg']))
notice( t('Please see the file "INSTALL.txt".') . EOL);*/
}
+}
-
+if(! function_exists('check_htconfig')) {
function check_htconfig(&$checks) {
$status = true;
$help = "";
@@ -473,9 +484,10 @@ function check_htconfig(&$checks) {
}
check_add($checks, t('.htconfig.php is writable'), $status, false, $help);
-
+}
}
+if(! function_exists('check_smarty3')) {
function check_smarty3(&$checks) {
$status = true;
$help = "";
@@ -489,9 +501,10 @@ function check_smarty3(&$checks) {
}
check_add($checks, t('view/smarty3 is writable'), $status, true, $help);
-
+}
}
+if(! function_exists('check_htaccess')) {
function check_htaccess(&$checks) {
$a = get_app();
$status = true;
@@ -511,7 +524,9 @@ function check_htaccess(&$checks) {
// cannot check modrewrite if libcurl is not installed
}
}
+}
+if(! function_exists('check_imagik')) {
function check_imagik(&$checks) {
$imagick = false;
$gif = false;
@@ -528,16 +543,18 @@ function check_imagik(&$checks) {
check_add($checks, t('ImageMagick supports GIF'), $gif, false, "");
}
}
+}
-
-
+if(! function_exists('manual_config')) {
function manual_config(&$a) {
$data = htmlentities($a->data['txt'],ENT_COMPAT,'UTF-8');
$o = t('The database configuration file ".htconfig.php" could not be written. Please use the enclosed text to create a configuration file in your web server root.');
$o .= "$data ";
return $o;
}
+}
+if(! function_exists('load_database_rem')) {
function load_database_rem($v, $i){
$l = trim($i);
if (strlen($l)>1 && ($l[0]=="-" || ($l[0]=="/" && $l[1]=="*"))){
@@ -546,8 +563,9 @@ function load_database_rem($v, $i){
return $v."\n".$i;
}
}
+}
-
+if(! function_exists('load_database')) {
function load_database($db) {
require_once("include/dbstructure.php");
@@ -567,7 +585,9 @@ function load_database($db) {
return $errors;
}
+}
+if(! function_exists('what_next')) {
function what_next() {
$a = get_app();
$baseurl = $a->get_baseurl();
@@ -579,5 +599,4 @@ function what_next() {
.t("Go to your new Friendica node registration page and register as new user. Remember to use the same email you have entered as administrator email. This will allow you to enter the site admin panel.")
."";
}
-
-
+}
diff --git a/mod/invite.php b/mod/invite.php
index ccf876c7c0..1f559dabc0 100644
--- a/mod/invite.php
+++ b/mod/invite.php
@@ -9,6 +9,7 @@
require_once('include/email.php');
+if(! function_exists('invite_post')) {
function invite_post(&$a) {
if(! local_user()) {
@@ -49,7 +50,7 @@ function invite_post(&$a) {
notice( sprintf( t('%s : Not a valid email address.'), $recip) . EOL);
continue;
}
-
+
if($invonly && ($x || is_site_admin())) {
$code = autoname(8) . srand(1000,9999);
$nmessage = str_replace('$invite_code',$code,$message);
@@ -70,8 +71,8 @@ function invite_post(&$a) {
else
$nmessage = $message;
- $res = mail($recip, email_header_encode( t('Please join us on Friendica'),'UTF-8'),
- $nmessage,
+ $res = mail($recip, email_header_encode( t('Please join us on Friendica'),'UTF-8'),
+ $nmessage,
"From: " . $a->user['email'] . "\n"
. 'Content-type: text/plain; charset=UTF-8' . "\n"
. 'Content-transfer-encoding: 8bit' );
@@ -93,8 +94,9 @@ function invite_post(&$a) {
notice( sprintf( tt("%d message sent.", "%d messages sent.", $total) , $total) . EOL);
return;
}
+}
-
+if(! function_exists('invite_content')) {
function invite_content(&$a) {
if(! local_user()) {
@@ -134,7 +136,7 @@ function invite_content(&$a) {
'$msg_text' => t('Your message:'),
'$default_message' => t('You are cordially invited to join me and other close friends on Friendica - and help us to create a better social web.') . "\r\n" . "\r\n"
. $linktxt
- . "\r\n" . "\r\n" . (($invonly) ? t('You will need to supply this invitation code: $invite_code') . "\r\n" . "\r\n" : '') .t('Once you have registered, please connect with me via my profile page at:')
+ . "\r\n" . "\r\n" . (($invonly) ? t('You will need to supply this invitation code: $invite_code') . "\r\n" . "\r\n" : '') .t('Once you have registered, please connect with me via my profile page at:')
. "\r\n" . "\r\n" . $a->get_baseurl() . '/profile/' . $a->user['nickname']
. "\r\n" . "\r\n" . t('For more information about the Friendica project and why we feel it is important, please visit http://friendica.com') . "\r\n" . "\r\n" ,
'$submit' => t('Submit')
@@ -142,3 +144,4 @@ function invite_content(&$a) {
return $o;
}
+}
diff --git a/mod/item.php b/mod/item.php
index 8c5a479646..f8f2e0fafe 100644
--- a/mod/item.php
+++ b/mod/item.php
@@ -25,6 +25,7 @@ require_once('include/text.php');
require_once('include/items.php');
require_once('include/Scrape.php');
+if(! function_exists('item_post')) {
function item_post(&$a) {
if((! local_user()) && (! remote_user()) && (! x($_REQUEST,'commenter')))
@@ -1017,7 +1018,9 @@ function item_post(&$a) {
item_post_return($a->get_baseurl(), $api_source, $return_path);
// NOTREACHED
}
+}
+if(! function_exists('item_post_return')) {
function item_post_return($baseurl, $api_source, $return_path) {
// figure out how to return, depending on from whence we came
@@ -1037,9 +1040,9 @@ function item_post_return($baseurl, $api_source, $return_path) {
echo json_encode($json);
killme();
}
+}
-
-
+if(! function_exists('item_content')) {
function item_content(&$a) {
if((! local_user()) && (! remote_user()))
@@ -1058,6 +1061,7 @@ function item_content(&$a) {
}
return $o;
}
+}
/**
* This function removes the tag $tag from the text $body and replaces it with
@@ -1071,6 +1075,7 @@ function item_content(&$a) {
*
* @return boolean true if replaced, false if not replaced
*/
+if(! function_exists('handle_tag')) {
function handle_tag($a, &$body, &$inform, &$str_tags, $profile_uid, $tag, $network = "") {
require_once("include/Scrape.php");
require_once("include/socgraph.php");
@@ -1245,8 +1250,9 @@ function handle_tag($a, &$body, &$inform, &$str_tags, $profile_uid, $tag, $netwo
return array('replaced' => $replaced, 'contact' => $r[0]);
}
+}
-
+if(! function_exists('store_diaspora_comment_sig')) {
function store_diaspora_comment_sig($datarray, $author, $uprvkey, $parent_item, $post_id) {
// We won't be able to sign Diaspora comments for authenticated visitors - we don't have their private key
@@ -1284,3 +1290,4 @@ function store_diaspora_comment_sig($datarray, $author, $uprvkey, $parent_item,
return;
}
+}
diff --git a/mod/like.php b/mod/like.php
index 8d383b9abe..ef483a1f9e 100755
--- a/mod/like.php
+++ b/mod/like.php
@@ -5,6 +5,7 @@ require_once('include/bbcode.php');
require_once('include/items.php');
require_once('include/like.php');
+if(! function_exists('like_content')) {
function like_content(&$a) {
if(! local_user() && ! remote_user()) {
return false;
@@ -28,11 +29,11 @@ function like_content(&$a) {
killme(); // NOTREACHED
// return; // NOTREACHED
}
-
+}
// Decide how to return. If we were called with a 'return' argument,
// then redirect back to the calling page. If not, just quietly end
-
+if(! function_exists('like_content_return')) {
function like_content_return($baseurl, $return_path) {
if($return_path) {
@@ -45,4 +46,4 @@ function like_content_return($baseurl, $return_path) {
killme();
}
-
+}
diff --git a/mod/localtime.php b/mod/localtime.php
index d1453bc527..fc500f4dd9 100644
--- a/mod/localtime.php
+++ b/mod/localtime.php
@@ -2,7 +2,7 @@
require_once('include/datetime.php');
-
+if(! function_exists('localtime_post')) {
function localtime_post(&$a) {
$t = $_REQUEST['time'];
@@ -13,9 +13,10 @@ function localtime_post(&$a) {
if($_POST['timezone'])
$a->data['mod-localtime'] = datetime_convert('UTC',$_POST['timezone'],$t,$bd_format);
-
+}
}
+if(! function_exists('localtime_content')) {
function localtime_content(&$a) {
$t = $_REQUEST['time'];
if(! $t)
@@ -38,12 +39,12 @@ function localtime_content(&$a) {
$o .= '';
- $o .= '' . t('Please select your timezone:') . '
';
+ $o .= '' . t('Please select your timezone:') . '
';
$o .= select_timezone(($_REQUEST['timezone']) ? $_REQUEST['timezone'] : 'America/Los_Angeles');
$o .= ' ';
return $o;
-
-}
\ No newline at end of file
+}
+}
diff --git a/mod/lockview.php b/mod/lockview.php
index 0ae54c8c12..82f93f4985 100644
--- a/mod/lockview.php
+++ b/mod/lockview.php
@@ -1,8 +1,8 @@
argc > 1) ? $a->argv[1] : 0);
if (is_numeric($type)) {
$item_id = intval($type);
@@ -10,13 +10,13 @@ function lockview_content(&$a) {
} else {
$item_id = (($a->argc > 2) ? intval($a->argv[2]) : 0);
}
-
+
if(! $item_id)
killme();
if (!in_array($type, array('item','photo','event')))
killme();
-
+
$r = q("SELECT * FROM `%s` WHERE `id` = %d LIMIT 1",
dbesc($type),
intval($item_id)
@@ -33,7 +33,7 @@ function lockview_content(&$a) {
}
- if(($item['private'] == 1) && (! strlen($item['allow_cid'])) && (! strlen($item['allow_gid']))
+ if(($item['private'] == 1) && (! strlen($item['allow_cid'])) && (! strlen($item['allow_gid']))
&& (! strlen($item['deny_cid'])) && (! strlen($item['deny_gid']))) {
echo t('Remote privacy information not available.') . ' ';
@@ -53,7 +53,7 @@ function lockview_content(&$a) {
dbesc(implode(', ', $allowed_groups))
);
if(count($r))
- foreach($r as $rr)
+ foreach($r as $rr)
$l[] = '' . $rr['name'] . ' ';
}
if(count($allowed_users)) {
@@ -61,7 +61,7 @@ function lockview_content(&$a) {
dbesc(implode(', ',$allowed_users))
);
if(count($r))
- foreach($r as $rr)
+ foreach($r as $rr)
$l[] = $rr['name'];
}
@@ -71,7 +71,7 @@ function lockview_content(&$a) {
dbesc(implode(', ', $deny_groups))
);
if(count($r))
- foreach($r as $rr)
+ foreach($r as $rr)
$l[] = '' . $rr['name'] . ' ';
}
if(count($deny_users)) {
@@ -79,12 +79,12 @@ function lockview_content(&$a) {
dbesc(implode(', ',$deny_users))
);
if(count($r))
- foreach($r as $rr)
+ foreach($r as $rr)
$l[] = '' . $rr['name'] . ' ';
}
echo $o . implode(', ', $l);
killme();
-
+}
}
diff --git a/mod/login.php b/mod/login.php
index d09fc1868f..47c329eb63 100644
--- a/mod/login.php
+++ b/mod/login.php
@@ -1,5 +1,5 @@
config['register_policy'] == REGISTER_CLOSED) ? false : true);
-
+}
}
diff --git a/mod/lostpass.php b/mod/lostpass.php
index 938d1cbb00..0c4bb1a833 100644
--- a/mod/lostpass.php
+++ b/mod/lostpass.php
@@ -4,6 +4,7 @@ require_once('include/email.php');
require_once('include/enotify.php');
require_once('include/text.php');
+if(! function_exists('lostpass_post')) {
function lostpass_post(&$a) {
$loginame = notags(trim($_POST['login-name']));
@@ -74,10 +75,10 @@ function lostpass_post(&$a) {
'body' => $body));
goaway(z_root());
-
+}
}
-
+if(! function_exists('lostpass_content')) {
function lostpass_content(&$a) {
@@ -164,5 +165,5 @@ function lostpass_content(&$a) {
return $o;
}
-
+}
}
diff --git a/mod/maintenance.php b/mod/maintenance.php
index b50c94c9b9..02de29108f 100644
--- a/mod/maintenance.php
+++ b/mod/maintenance.php
@@ -1,7 +1,8 @@
t('System down for maintenance')
));
}
+}
diff --git a/mod/manage.php b/mod/manage.php
index adcc3d787a..6af3db9971 100644
--- a/mod/manage.php
+++ b/mod/manage.php
@@ -2,7 +2,7 @@
require_once("include/text.php");
-
+if(! function_exists('manage_post')) {
function manage_post(&$a) {
if(! local_user())
@@ -87,9 +87,9 @@ function manage_post(&$a) {
goaway( $a->get_baseurl() . "/profile/" . $a->user['nickname'] );
// NOTREACHED
}
+}
-
-
+if(! function_exists('manage_content')) {
function manage_content(&$a) {
if(! local_user()) {
@@ -144,5 +144,5 @@ function manage_content(&$a) {
));
return $o;
-
+}
}
diff --git a/mod/match.php b/mod/match.php
index 3b0367b429..f4936b28dc 100644
--- a/mod/match.php
+++ b/mod/match.php
@@ -13,6 +13,7 @@ require_once('mod/proxy.php');
* @param App &$a
* @return void|string
*/
+if(! function_exists('match_content')) {
function match_content(&$a) {
$o = '';
@@ -109,3 +110,4 @@ function match_content(&$a) {
return $o;
}
+}
diff --git a/mod/message.php b/mod/message.php
index 1724ebc424..1f11797d8b 100644
--- a/mod/message.php
+++ b/mod/message.php
@@ -3,6 +3,7 @@
require_once('include/acl_selectors.php');
require_once('include/message.php');
+if(! function_exists('message_init')) {
function message_init(&$a) {
$tabs = '';
@@ -36,9 +37,10 @@ function message_init(&$a) {
'$baseurl' => $a->get_baseurl(true),
'$base' => $base
));
-
+}
}
+if(! function_exists('message_post')) {
function message_post(&$a) {
if(! local_user()) {
@@ -91,7 +93,7 @@ function message_post(&$a) {
}
else
goaway($a->get_baseurl(true) . '/' . $_SESSION['return_url']);
-
+}
}
// Note: the code in 'item_extract_images' and 'item_redir_and_replace_images'
@@ -171,7 +173,7 @@ function item_redir_and_replace_images($body, $images, $cid) {
}}
-
+if(! function_exists('message_content')) {
function message_content(&$a) {
$o = '';
@@ -530,7 +532,9 @@ function message_content(&$a) {
return $o;
}
}
+}
+if(! function_exists('get_messages')) {
function get_messages($user, $lstart, $lend) {
return q("SELECT max(`mail`.`created`) AS `mailcreated`, min(`mail`.`seen`) AS `mailseen`,
@@ -541,7 +545,9 @@ function get_messages($user, $lstart, $lend) {
intval($user), intval($lstart), intval($lend)
);
}
+}
+if(! function_exists('render_messages')) {
function render_messages($msg, $t) {
$a = get_app();
@@ -593,3 +599,4 @@ function render_messages($msg, $t) {
return $rslt;
}
+}
diff --git a/mod/modexp.php b/mod/modexp.php
index bba2c2882d..282d55a24b 100644
--- a/mod/modexp.php
+++ b/mod/modexp.php
@@ -2,6 +2,7 @@
require_once('library/asn1.php');
+if(! function_exists('modexp_init')) {
function modexp_init(&$a) {
if($a->argc != 2)
@@ -29,6 +30,5 @@ function modexp_init(&$a) {
echo 'RSA' . '.' . $m . '.' . $e ;
killme();
-
}
-
+}
diff --git a/mod/mood.php b/mod/mood.php
index eee11e20c5..2476f06562 100644
--- a/mod/mood.php
+++ b/mod/mood.php
@@ -4,7 +4,7 @@ require_once('include/security.php');
require_once('include/bbcode.php');
require_once('include/items.php');
-
+if(! function_exists('mood_init')) {
function mood_init(&$a) {
if(! local_user())
@@ -59,7 +59,7 @@ function mood_init(&$a) {
$uri = item_new_uri($a->get_hostname(),$uid);
- $action = sprintf( t('%1$s is currently %2$s'), '[url=' . $poster['url'] . ']' . $poster['name'] . '[/url]' , $verbs[$verb]);
+ $action = sprintf( t('%1$s is currently %2$s'), '[url=' . $poster['url'] . ']' . $poster['name'] . '[/url]' , $verbs[$verb]);
$arr = array();
@@ -105,9 +105,9 @@ function mood_init(&$a) {
return;
}
+}
-
-
+if(! function_exists('mood_content')) {
function mood_content(&$a) {
if(! local_user()) {
@@ -138,5 +138,5 @@ function mood_content(&$a) {
));
return $o;
-
+}
}
diff --git a/mod/msearch.php b/mod/msearch.php
index 89de5b7057..3b1b0b617a 100644
--- a/mod/msearch.php
+++ b/mod/msearch.php
@@ -1,5 +1,6 @@
$rr['name'],
- 'url' => $a->get_baseurl() . '/profile/' . $rr['nickname'],
+ 'name' => $rr['name'],
+ 'url' => $a->get_baseurl() . '/profile/' . $rr['nickname'],
'photo' => $a->get_baseurl() . '/photo/avatar/' . $rr['uid'] . '.jpg',
'tags' => str_replace(array(',',' '),array(' ',' '),$rr['pub_keywords'])
);
@@ -38,5 +39,5 @@ function msearch_post(&$a) {
echo json_encode($output);
killme();
-
-}
\ No newline at end of file
+}
+}
diff --git a/mod/navigation.php b/mod/navigation.php
index 5db69b171e..8fbabfda96 100644
--- a/mod/navigation.php
+++ b/mod/navigation.php
@@ -2,6 +2,7 @@
require_once("include/nav.php");
+if(! function_exists('navigation_content')) {
function navigation_content(&$a) {
$nav_info = nav_info($a);
@@ -22,5 +23,5 @@ function navigation_content(&$a) {
'$apps' => $a->apps,
'$clear_notifs' => t('Clear notifications')
));
-
+}
}
diff --git a/mod/network.php b/mod/network.php
index a07c5868ec..f9a0bec238 100644
--- a/mod/network.php
+++ b/mod/network.php
@@ -1,4 +1,6 @@
page,'aside'))
$a->page['aside'] = '';
@@ -148,14 +150,15 @@ function network_init(&$a) {
}
$a->page['aside'] .= (feature_enabled(local_user(),'groups') ? group_side('network/0','network','standard',$group_id) : '');
- $a->page['aside'] .= (feature_enabled(local_user(),'forumlist_widget') ? widget_forumlist(local_user(),$cid) : '');
+ $a->page['aside'] .= (feature_enabled(local_user(),'forumlist_widget') ? ForumManager::widget(local_user(),$cid) : '');
$a->page['aside'] .= posted_date_widget($a->get_baseurl() . '/network',local_user(),false);
$a->page['aside'] .= networks_widget($a->get_baseurl(true) . '/network',(x($_GET, 'nets') ? $_GET['nets'] : ''));
$a->page['aside'] .= saved_searches($search);
$a->page['aside'] .= fileas_widget($a->get_baseurl(true) . '/network',(x($_GET, 'file') ? $_GET['file'] : ''));
-
+}
}
+if(! function_exists('saved_searches')) {
function saved_searches($search) {
if(! feature_enabled(local_user(),'savedsearch'))
@@ -204,7 +207,7 @@ function saved_searches($search) {
));
return $o;
-
+}
}
/**
@@ -222,6 +225,7 @@ function saved_searches($search) {
*
* @return Array ( $no_active, $comment_active, $postord_active, $conv_active, $new_active, $starred_active, $bookmarked_active, $spam_active );
*/
+if(! function_exists('network_query_get_sel_tab')) {
function network_query_get_sel_tab($a) {
$no_active='';
$starred_active = '';
@@ -278,10 +282,12 @@ function network_query_get_sel_tab($a) {
return array($no_active, $all_active, $postord_active, $conv_active, $new_active, $starred_active, $bookmarked_active, $spam_active);
}
+}
/**
* Return selected network from query
*/
+if(! function_exists('network_query_get_sel_net')) {
function network_query_get_sel_net() {
$network = false;
@@ -291,7 +297,9 @@ function network_query_get_sel_net() {
return $network;
}
+}
+if(! function_exists('network_query_get_sel_group')) {
function network_query_get_sel_group($a) {
$group = false;
@@ -301,8 +309,9 @@ function network_query_get_sel_group($a) {
return $group;
}
+}
-
+if(! function_exists('network_content')) {
function network_content(&$a, $update = 0) {
require_once('include/conversation.php');
@@ -886,4 +895,4 @@ function network_content(&$a, $update = 0) {
return $o;
}
-
+}
diff --git a/mod/newmember.php b/mod/newmember.php
index aa55c3a098..ef25333302 100644
--- a/mod/newmember.php
+++ b/mod/newmember.php
@@ -1,5 +1,6 @@
';
- $o .= ' ' . '' . t('Friendica Walk-Through') . ' ' . t('On your Quick Start page - find a brief introduction to your profile and network tabs, make some new connections, and find some groups to join.') . ' ' . EOL;
+ $o .= ' ' . '' . t('Friendica Walk-Through') . ' ' . t('On your Quick Start page - find a brief introduction to your profile and network tabs, make some new connections, and find some groups to join.') . ' ' . EOL;
$o .= '';
@@ -23,7 +24,7 @@ function newmember_content(&$a) {
$o .= '';
- $o .= '' . '' . t('Go to Your Settings') . ' ' . t('On your Settings page - change your initial password. Also make a note of your Identity Address. This looks just like an email address - and will be useful in making friends on the free social web.') . ' ' . EOL;
+ $o .= '' . '' . t('Go to Your Settings') . ' ' . t('On your Settings page - change your initial password. Also make a note of your Identity Address. This looks just like an email address - and will be useful in making friends on the free social web.') . ' ' . EOL;
$o .= '' . t('Review the other settings, particularly the privacy settings. An unpublished directory listing is like having an unlisted phone number. In general, you should probably publish your listing - unless all of your friends and potential friends know exactly how to find you.') . ' ' . EOL;
@@ -33,7 +34,7 @@ function newmember_content(&$a) {
$o .= '';
- $o .= '' . '' . t('Upload Profile Photo') . ' ' . t('Upload a profile photo if you have not done so already. Studies have shown that people with real photos of themselves are ten times more likely to make friends than people who do not.') . ' ' . EOL;
+ $o .= '' . '' . t('Upload Profile Photo') . ' ' . t('Upload a profile photo if you have not done so already. Studies have shown that people with real photos of themselves are ten times more likely to make friends than people who do not.') . ' ' . EOL;
$o .= '' . '' . t('Edit Your Profile') . ' ' . t('Edit your default profile to your liking. Review the settings for hiding your list of friends and hiding the profile from unknown visitors.') . ' ' . EOL;
@@ -46,7 +47,7 @@ function newmember_content(&$a) {
$o .= '';
$mail_disabled = ((function_exists('imap_open') && (! get_config('system','imap_disabled'))) ? 0 : 1);
-
+
if(! $mail_disabled)
$o .= '' . '' . t('Importing Emails') . ' ' . t('Enter your email access information on your Connector Settings page if you wish to import and interact with friends or mailing lists from your email INBOX') . ' ' . EOL;
@@ -82,3 +83,4 @@ function newmember_content(&$a) {
return $o;
}
+}
diff --git a/mod/nodeinfo.php b/mod/nodeinfo.php
index ba310a1051..7f8939182e 100644
--- a/mod/nodeinfo.php
+++ b/mod/nodeinfo.php
@@ -1,12 +1,13 @@
diff --git a/mod/nogroup.php b/mod/nogroup.php
index 9f6e978433..818b0da77a 100644
--- a/mod/nogroup.php
+++ b/mod/nogroup.php
@@ -4,6 +4,7 @@ require_once('include/Contact.php');
require_once('include/socgraph.php');
require_once('include/contact_selectors.php');
+if(! function_exists('nogroup_init')) {
function nogroup_init(&$a) {
if(! local_user())
@@ -17,8 +18,9 @@ function nogroup_init(&$a) {
$a->page['aside'] .= group_side('contacts','group','extended',0,$contact_id);
}
+}
-
+if(! function_exists('nogroup_content')) {
function nogroup_content(&$a) {
if(! local_user()) {
@@ -66,5 +68,5 @@ function nogroup_content(&$a) {
));
return $o;
-
+}
}
diff --git a/mod/noscrape.php b/mod/noscrape.php
index 51bd7234cf..49fe2b9a37 100644
--- a/mod/noscrape.php
+++ b/mod/noscrape.php
@@ -1,5 +1,6 @@
argc > 1)
@@ -62,5 +63,5 @@ function noscrape_init(&$a) {
header('Content-type: application/json; charset=utf-8');
echo json_encode($json_info);
exit;
-
+}
}
diff --git a/mod/notes.php b/mod/notes.php
index 73c1507e3e..7817e25547 100644
--- a/mod/notes.php
+++ b/mod/notes.php
@@ -1,5 +1,6 @@
contact['id'] . ">' ";
$r = q("SELECT COUNT(*) AS `total`
FROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
- WHERE `item`.`uid` = %d AND `item`.`visible` = 1 and `item`.`moderated` = 0
+ WHERE `item`.`uid` = %d AND `item`.`visible` = 1 and `item`.`moderated` = 0
AND `item`.`deleted` = 0 AND `item`.`type` = 'note'
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 AND `contact`.`self` = 1
AND `item`.`id` = `item`.`parent` AND `item`.`wall` = 0
@@ -90,7 +91,7 @@ function notes_content(&$a,$update = false) {
$r = q("SELECT `item`.`id` AS `item_id`, `contact`.`uid` AS `contact-uid`
FROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
- WHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND `item`.`deleted` = 0
+ WHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND `item`.`deleted` = 0
and `item`.`moderated` = 0 AND `item`.`type` = 'note'
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 AND `contact`.`self` = 1
AND `item`.`id` = `item`.`parent` AND `item`.`wall` = 0
@@ -109,10 +110,10 @@ function notes_content(&$a,$update = false) {
foreach($r as $rr)
$parents_arr[] = $rr['item_id'];
$parents_str = implode(', ', $parents_arr);
-
- $r = q("SELECT `item`.*, `item`.`id` AS `item_id`,
- `contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`alias`, `contact`.`network`, `contact`.`rel`,
- `contact`.`thumb`, `contact`.`self`, `contact`.`writable`,
+
+ $r = q("SELECT `item`.*, `item`.`id` AS `item_id`,
+ `contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`alias`, `contact`.`network`, `contact`.`rel`,
+ `contact`.`thumb`, `contact`.`self`, `contact`.`writable`,
`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`
FROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
WHERE `item`.`uid` = %d AND `item`.`visible` = 1 and `item`.`moderated` = 0 AND `item`.`deleted` = 0
@@ -135,3 +136,4 @@ function notes_content(&$a,$update = false) {
$o .= paginate($a);
return $o;
}
+}
diff --git a/mod/notice.php b/mod/notice.php
index 19cf53189a..a42d60dd40 100644
--- a/mod/notice.php
+++ b/mod/notice.php
@@ -1,7 +1,8 @@
friendica items permanent-url compatibility */
-
- function notice_init(&$a){
+/* identi.ca -> friendica items permanent-url compatibility */
+
+if(! function_exists('notice_init')) {
+ function notice_init(&$a) {
$id = $a->argv[1];
$r = q("SELECT user.nickname FROM user LEFT JOIN item ON item.uid=user.uid WHERE item.id=%d",
intval($id)
@@ -16,5 +17,5 @@
}
return;
-
}
+}
diff --git a/mod/notifications.php b/mod/notifications.php
index a267b7c958..c7421b2d42 100644
--- a/mod/notifications.php
+++ b/mod/notifications.php
@@ -3,6 +3,7 @@ include_once("include/bbcode.php");
include_once("include/contact_selectors.php");
include_once("include/Scrape.php");
+if(! function_exists('notifications_post')) {
function notifications_post(&$a) {
if(! local_user()) {
@@ -58,11 +59,11 @@ function notifications_post(&$a) {
}
}
}
+}
-
-
+if(! function_exists('notifications_content')) {
function notifications_content(&$a) {
if(! local_user()) {
@@ -579,3 +580,4 @@ function notifications_content(&$a) {
$o .= paginate($a);
return $o;
}
+}
diff --git a/mod/notify.php b/mod/notify.php
index 02260514af..7acac1084a 100644
--- a/mod/notify.php
+++ b/mod/notify.php
@@ -1,6 +1,6 @@
query_string, LOGGER_ALL);
if ($a->argv[1]=='b2h'){
@@ -33,3 +34,4 @@ function oembed_content(&$a){
}
killme();
}
+}
diff --git a/mod/oexchange.php b/mod/oexchange.php
index bbb436e702..1e7c9b23c9 100644
--- a/mod/oexchange.php
+++ b/mod/oexchange.php
@@ -1,6 +1,6 @@
argc > 1) && ($a->argv[1] === 'xrd')) {
@@ -11,9 +11,10 @@ function oexchange_init(&$a) {
killme();
}
-
+}
}
+if(! function_exists('oexchange_content')) {
function oexchange_content(&$a) {
if(! local_user()) {
@@ -26,13 +27,13 @@ function oexchange_content(&$a) {
return;
}
- $url = (((x($_REQUEST,'url')) && strlen($_REQUEST['url']))
+ $url = (((x($_REQUEST,'url')) && strlen($_REQUEST['url']))
? urlencode(notags(trim($_REQUEST['url']))) : '');
- $title = (((x($_REQUEST,'title')) && strlen($_REQUEST['title']))
+ $title = (((x($_REQUEST,'title')) && strlen($_REQUEST['title']))
? '&title=' . urlencode(notags(trim($_REQUEST['title']))) : '');
- $description = (((x($_REQUEST,'description')) && strlen($_REQUEST['description']))
+ $description = (((x($_REQUEST,'description')) && strlen($_REQUEST['description']))
? '&description=' . urlencode(notags(trim($_REQUEST['description']))) : '');
- $tags = (((x($_REQUEST,'tags')) && strlen($_REQUEST['tags']))
+ $tags = (((x($_REQUEST,'tags')) && strlen($_REQUEST['tags']))
? '&tags=' . urlencode(notags(trim($_REQUEST['tags']))) : '');
$s = fetch_url($a->get_baseurl() . '/parse_url?f=&url=' . $url . $title . $description . $tags);
@@ -52,7 +53,5 @@ function oexchange_content(&$a) {
$_REQUEST = $post;
require_once('mod/item.php');
item_post($a);
-
}
-
-
+}
diff --git a/mod/openid.php b/mod/openid.php
index 5d5539f00e..a92a124c0d 100644
--- a/mod/openid.php
+++ b/mod/openid.php
@@ -1,9 +1,8 @@
$a->get_baseurl(),
'$nodename' => $a->get_hostname(),
));
-
+
echo $o;
-
+
killme();
-
}
-?>
\ No newline at end of file
+}
+?>
diff --git a/mod/ostatus_subscribe.php b/mod/ostatus_subscribe.php
index 6cca0bf679..a21436db49 100644
--- a/mod/ostatus_subscribe.php
+++ b/mod/ostatus_subscribe.php
@@ -3,6 +3,7 @@
require_once('include/Scrape.php');
require_once('include/follow.php');
+if(! function_exists('ostatus_subscribe_content')) {
function ostatus_subscribe_content(&$a) {
if(! local_user()) {
@@ -76,3 +77,4 @@ function ostatus_subscribe_content(&$a) {
return $o;
}
+}
diff --git a/mod/p.php b/mod/p.php
index 92b72dc1ce..225b831fea 100644
--- a/mod/p.php
+++ b/mod/p.php
@@ -4,7 +4,8 @@ This file is part of the Diaspora protocol. It is used for fetching single publi
*/
require_once("include/diaspora.php");
-function p_init($a){
+if(! function_exists('p_init')) {
+function p_init($a) {
if ($a->argc != 2) {
header($_SERVER["SERVER_PROTOCOL"].' 510 '.t('Not Extended'));
killme();
@@ -79,3 +80,4 @@ function p_init($a){
killme();
}
+}
diff --git a/mod/parse_url.php b/mod/parse_url.php
index a1ca5a3db5..481cb89361 100644
--- a/mod/parse_url.php
+++ b/mod/parse_url.php
@@ -1,14 +1,14 @@
*
*
- *
+ *
*
* Shiny Trinket
*
@@ -27,6 +27,7 @@ if(!function_exists('deletenode')) {
}
}
+if(! function_exists('completeurl')) {
function completeurl($url, $scheme) {
$urlarr = parse_url($url);
@@ -53,7 +54,9 @@ function completeurl($url, $scheme) {
return($complete);
}
+}
+if(! function_exists('parseurl_getsiteinfo_cached')) {
function parseurl_getsiteinfo_cached($url, $no_guessing = false, $do_oembed = true) {
if ($url == "")
@@ -77,7 +80,9 @@ function parseurl_getsiteinfo_cached($url, $no_guessing = false, $do_oembed = tr
return $data;
}
+}
+if(! function_exists('parseurl_getsiteinfo')) {
function parseurl_getsiteinfo($url, $no_guessing = false, $do_oembed = true, $count = 1) {
require_once("include/network.php");
require_once("include/Photo.php");
@@ -400,11 +405,15 @@ function parseurl_getsiteinfo($url, $no_guessing = false, $do_oembed = true, $co
return($siteinfo);
}
+}
+if(! function_exists('arr_add_hashes')) {
function arr_add_hashes(&$item,$k) {
$item = '#' . $item;
}
+}
+if(! function_exists('parse_url_content')) {
function parse_url_content(&$a) {
$text = null;
@@ -558,4 +567,5 @@ function parse_url_content(&$a) {
killme();
}
+}
?>
diff --git a/mod/photo.php b/mod/photo.php
index 4166b4d539..3baff13db5 100644
--- a/mod/photo.php
+++ b/mod/photo.php
@@ -3,6 +3,7 @@
require_once('include/security.php');
require_once('include/Photo.php');
+if(! function_exists('photo_init')) {
function photo_init(&$a) {
global $_SERVER;
@@ -209,3 +210,4 @@ function photo_init(&$a) {
killme();
// NOTREACHED
}
+}
diff --git a/mod/photos.php b/mod/photos.php
index a9dade6a81..9821918e5e 100644
--- a/mod/photos.php
+++ b/mod/photos.php
@@ -9,6 +9,7 @@ require_once('include/redir.php');
require_once('include/tags.php');
require_once('include/threads.php');
+if(! function_exists('photos_init')) {
function photos_init(&$a) {
if($a->argc > 1)
@@ -121,9 +122,9 @@ function photos_init(&$a) {
return;
}
+}
-
-
+if(! function_exists('photos_post')) {
function photos_post(&$a) {
logger('mod-photos: photos_post: begin' , LOGGER_DEBUG);
@@ -957,9 +958,9 @@ function photos_post(&$a) {
goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']);
// NOTREACHED
}
+}
-
-
+if(! function_exists('photos_content')) {
function photos_content(&$a) {
// URLs:
@@ -1328,7 +1329,7 @@ function photos_content(&$a) {
}
- /**
+ /**
* Display one photo
*/
@@ -1861,7 +1862,7 @@ function photos_content(&$a) {
//hide profile photos to others
if((! $is_owner) && (! remote_user()) && ($rr['album'] == t('Profile Photos')))
continue;
-
+
if($twist == 'rotright')
$twist = 'rotleft';
else
@@ -1906,4 +1907,4 @@ function photos_content(&$a) {
$o .= paginate($a);
return $o;
}
-
+}
diff --git a/mod/ping.php b/mod/ping.php
index 57728d3294..9183dcbba2 100644
--- a/mod/ping.php
+++ b/mod/ping.php
@@ -1,10 +1,11 @@
argv[2];
- $r = q("SELECT * FROM `user` WHERE `nickname` = '%s'
+ $r = q("SELECT * FROM `user` WHERE `nickname` = '%s'
AND `account_expired` = 0 AND `account_removed` = 0 LIMIT 1",
dbesc($nickname)
);
@@ -48,4 +49,4 @@ function post_post(&$a) {
http_status_exit(($ret) ? $ret : 200);
// NOTREACHED
}
-
+}
diff --git a/mod/pretheme.php b/mod/pretheme.php
index 4584cb29e2..5d1c261fcb 100644
--- a/mod/pretheme.php
+++ b/mod/pretheme.php
@@ -1,7 +1,8 @@
Probe Diagnostic';
$o .= ' ';
$o .= 'Lookup address: ';
- $o .= ' ';
+ $o .= ' ';
$o .= ' ';
@@ -22,3 +23,4 @@ function probe_content(&$a) {
}
return $o;
}
+}
diff --git a/mod/profile.php b/mod/profile.php
index 26bd395230..b02570d5af 100644
--- a/mod/profile.php
+++ b/mod/profile.php
@@ -3,7 +3,7 @@
require_once('include/contact_widgets.php');
require_once('include/redir.php');
-
+if(! function_exists('profile_init')) {
function profile_init(&$a) {
if(! x($a->page,'aside'))
@@ -65,10 +65,10 @@ function profile_init(&$a) {
foreach($dfrn_pages as $dfrn)
$a->page['htmlhead'] .= " get_baseurl()."/dfrn_{$dfrn}/{$which}\" />\r\n";
$a->page['htmlhead'] .= " get_baseurl()."/poco/{$which}\" />\r\n";
-
+}
}
-
+if(! function_exists('profile_content')) {
function profile_content(&$a, $update = 0) {
$category = $datequery = $datequery2 = '';
@@ -350,3 +350,4 @@ function profile_content(&$a, $update = 0) {
return $o;
}
+}
diff --git a/mod/profile_photo.php b/mod/profile_photo.php
index 4e8d279a97..e3d6adb491 100644
--- a/mod/profile_photo.php
+++ b/mod/profile_photo.php
@@ -2,6 +2,7 @@
require_once("include/Photo.php");
+if(! function_exists('profile_photo_init')) {
function profile_photo_init(&$a) {
if(! local_user()) {
@@ -9,10 +10,10 @@ function profile_photo_init(&$a) {
}
profile_load($a,$a->user['nickname']);
-
+}
}
-
+if(! function_exists('profile_photo_post')) {
function profile_photo_post(&$a) {
if(! local_user()) {
@@ -143,7 +144,7 @@ function profile_photo_post(&$a) {
$filesize = intval($_FILES['userfile']['size']);
$filetype = $_FILES['userfile']['type'];
if ($filetype=="") $filetype=guess_image_type($filename);
-
+
$maximagesize = get_config('system','maximagesize');
if(($maximagesize) && ($filesize > $maximagesize)) {
@@ -164,7 +165,7 @@ function profile_photo_post(&$a) {
$ph->orient($src);
@unlink($src);
return profile_photo_crop_ui_head($a, $ph);
-
+}
}
@@ -175,7 +176,7 @@ function profile_photo_content(&$a) {
notice( t('Permission denied.') . EOL );
return;
}
-
+
$newuser = false;
if($a->argc == 2 && $a->argv[1] === 'new')
@@ -186,9 +187,9 @@ function profile_photo_content(&$a) {
notice( t('Permission denied.') . EOL );
return;
};
-
+
// check_form_security_token_redirectOnErr('/profile_photo', 'profile_photo');
-
+
$resource_id = $a->argv[2];
//die(":".local_user());
$r=q("SELECT * FROM `photo` WHERE `uid` = %d AND `resource-id` = '%s' ORDER BY `scale` ASC",
@@ -240,7 +241,7 @@ function profile_photo_content(&$a) {
if(! x($a->config,'imagecrop')) {
-
+
$tpl = get_markup_template('profile_photo.tpl');
$o .= replace_macros($tpl,array(
@@ -295,11 +296,11 @@ function profile_photo_crop_ui_head(&$a, $ph){
}
$hash = photo_new_resource();
-
+
$smallest = 0;
- $r = $ph->store(local_user(), 0 , $hash, $filename, t('Profile Photos'), 0 );
+ $r = $ph->store(local_user(), 0 , $hash, $filename, t('Profile Photos'), 0 );
if($r)
info( t('Image uploaded successfully.') . EOL );
@@ -308,8 +309,8 @@ function profile_photo_crop_ui_head(&$a, $ph){
if($width > 640 || $height > 640) {
$ph->scaleImage(640);
- $r = $ph->store(local_user(), 0 , $hash, $filename, t('Profile Photos'), 1 );
-
+ $r = $ph->store(local_user(), 0 , $hash, $filename, t('Profile Photos'), 1 );
+
if($r === false)
notice( sprintf(t('Image size reduction [%s] failed.'),"640") . EOL );
else
@@ -323,4 +324,3 @@ function profile_photo_crop_ui_head(&$a, $ph){
$a->page['end'] .= replace_macros(get_markup_template("cropend.tpl"), array());
return;
}}
-
diff --git a/mod/profiles.php b/mod/profiles.php
index 5c372de8ee..9ce478ba19 100644
--- a/mod/profiles.php
+++ b/mod/profiles.php
@@ -1,6 +1,7 @@
argv[1];
profile_load($a,$which,$profile);
-
+}
}
-
+if(! function_exists('profperm_content')) {
function profperm_content(&$a) {
if(! local_user()) {
@@ -108,9 +109,9 @@ function profperm_content(&$a) {
}
$o .= '';
- if($change)
+ if($change)
$o = '';
-
+
$o .= '
';
$o .= '
' . t('Visible To') . ' ';
$o .= '';
@@ -156,6 +157,5 @@ function profperm_content(&$a) {
}
$o .= '
';
return $o;
-
}
-
+}
diff --git a/mod/proxy.php b/mod/proxy.php
index abcaf49127..8e2a389254 100644
--- a/mod/proxy.php
+++ b/mod/proxy.php
@@ -12,6 +12,7 @@ define("PROXY_SIZE_LARGE", "large");
require_once('include/security.php');
require_once("include/Photo.php");
+if(! function_exists('proxy_init')) {
function proxy_init() {
global $a, $_SERVER;
@@ -232,7 +233,9 @@ function proxy_init() {
killme();
}
+}
+if(! function_exists('proxy_url')) {
function proxy_url($url, $writemode = false, $size = "") {
global $_SERVER;
@@ -294,11 +297,13 @@ function proxy_url($url, $writemode = false, $size = "") {
else
return ($proxypath.$size);
}
+}
/**
* @param $url string
* @return boolean
*/
+if(! function_exists('proxy_is_local_image')) {
function proxy_is_local_image($url) {
if ($url[0] == '/') return true;
@@ -309,7 +314,9 @@ function proxy_is_local_image($url) {
$url = normalise_link($url);
return (substr($url, 0, strlen($baseurl)) == $baseurl);
}
+}
+if(! function_exists('proxy_parse_query')) {
function proxy_parse_query($var) {
/**
* Use this function to parse out the query array element from
@@ -328,7 +335,9 @@ function proxy_parse_query($var) {
unset($val, $x, $var);
return $arr;
}
+}
+if(! function_exists('proxy_img_cb')) {
function proxy_img_cb($matches) {
// if the picture seems to be from another picture cache then take the original source
@@ -342,10 +351,13 @@ function proxy_img_cb($matches) {
return $matches[1].proxy_url(htmlspecialchars_decode($matches[2])).$matches[3];
}
+}
+if(! function_exists('proxy_parse_html')) {
function proxy_parse_html($html) {
$a = get_app();
$html = str_replace(normalise_link($a->get_baseurl())."/", $a->get_baseurl()."/", $html);
return preg_replace_callback("/( ]*src *= *[\"'])([^\"']+)([\"'][^>]*>)/siU", "proxy_img_cb", $html);
}
+}
diff --git a/mod/pubsub.php b/mod/pubsub.php
index beb73b4e2c..15523e637a 100644
--- a/mod/pubsub.php
+++ b/mod/pubsub.php
@@ -1,5 +1,6 @@
argc > 1) ? notags(trim($a->argv[1])) : '');
@@ -57,7 +58,7 @@ function pubsub_init(&$a) {
$sql_extra = ((strlen($hub_verify)) ? sprintf(" AND `hub-verify` = '%s' ", dbesc($hub_verify)) : '');
- $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d
+ $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d
AND `blocked` = 0 AND `pending` = 0 $sql_extra LIMIT 1",
intval($contact_id),
intval($owner['uid'])
@@ -75,7 +76,7 @@ function pubsub_init(&$a) {
$contact = $r[0];
- // We must initiate an unsubscribe request with a verify_token.
+ // We must initiate an unsubscribe request with a verify_token.
// Don't allow outsiders to unsubscribe us.
if($hub_mode === 'unsubscribe') {
@@ -95,9 +96,11 @@ function pubsub_init(&$a) {
hub_return(true, $hub_challenge);
}
}
+}
require_once('include/security.php');
+if(! function_exists('pubsub_post')) {
function pubsub_post(&$a) {
$xml = file_get_contents('php://input');
@@ -155,8 +158,5 @@ function pubsub_post(&$a) {
consume_feed($xml,$importer,$contact,$feedhub,1,2);
hub_post_return();
-
}
-
-
-
+}
diff --git a/mod/pubsubhubbub.php b/mod/pubsubhubbub.php
index 5d7621cc74..b0e3ef3099 100644
--- a/mod/pubsubhubbub.php
+++ b/mod/pubsubhubbub.php
@@ -1,9 +1,12 @@
diff --git a/mod/qsearch.php b/mod/qsearch.php
index c35e253b67..cffc3e50ba 100644
--- a/mod/qsearch.php
+++ b/mod/qsearch.php
@@ -1,5 +1,6 @@
get_baseurl() . '/profile');
}
+}
diff --git a/mod/receive.php b/mod/receive.php
index 95a5101675..3a30058cdc 100644
--- a/mod/receive.php
+++ b/mod/receive.php
@@ -9,7 +9,7 @@ require_once('include/salmon.php');
require_once('include/crypto.php');
require_once('include/diaspora.php');
-
+if(! function_exists('receive_post')) {
function receive_post(&$a) {
@@ -73,4 +73,4 @@ function receive_post(&$a) {
http_status_exit(($ret) ? $ret : 200);
// NOTREACHED
}
-
+}
diff --git a/mod/redir.php b/mod/redir.php
index 632c395786..2dda0571b2 100644
--- a/mod/redir.php
+++ b/mod/redir.php
@@ -1,5 +1,6 @@
user['uid']);
// NOTREACHED
}
-
+}
}
+if(! function_exists('removeme_content')) {
function removeme_content(&$a) {
if(! local_user())
@@ -50,5 +52,5 @@ function removeme_content(&$a) {
));
return $o;
-
+}
}
diff --git a/mod/repair_ostatus.php b/mod/repair_ostatus.php
index 2b1224f423..e3956ba8cb 100755
--- a/mod/repair_ostatus.php
+++ b/mod/repair_ostatus.php
@@ -3,6 +3,7 @@
require_once('include/Scrape.php');
require_once('include/follow.php');
+if(! function_exists('repair_ostatus_content')) {
function repair_ostatus_content(&$a) {
if(! local_user()) {
@@ -55,3 +56,4 @@ function repair_ostatus_content(&$a) {
return $o;
}
+}
diff --git a/mod/rsd_xml.php b/mod/rsd_xml.php
index f4984f0f0f..6f9c209fab 100644
--- a/mod/rsd_xml.php
+++ b/mod/rsd_xml.php
@@ -1,7 +1,6 @@
@@ -21,4 +20,5 @@ function rsd_xml_content(&$a) {
';
die();
-}
\ No newline at end of file
+}
+}
diff --git a/mod/salmon.php b/mod/salmon.php
index 9c22e42d11..ee3826d8a8 100644
--- a/mod/salmon.php
+++ b/mod/salmon.php
@@ -6,6 +6,7 @@ require_once('include/crypto.php');
require_once('include/items.php');
require_once('include/follow.php');
+if(! function_exists('salmon_return')) {
function salmon_return($val) {
if($val >= 400)
@@ -16,9 +17,10 @@ function salmon_return($val) {
logger('mod-salmon returns ' . $val);
header($_SERVER["SERVER_PROTOCOL"] . ' ' . $val . ' ' . $err);
killme();
-
+}
}
+if(! function_exists('salmon_post')) {
function salmon_post(&$a) {
$xml = file_get_contents('php://input');
@@ -155,7 +157,7 @@ function salmon_post(&$a) {
if(get_pconfig($importer['uid'],'system','ostatus_autofriend')) {
$result = new_contact($importer['uid'],$author_link);
if($result['success']) {
- $r = q("SELECT * FROM `contact` WHERE `network` = '%s' AND ( `url` = '%s' OR `alias` = '%s')
+ $r = q("SELECT * FROM `contact` WHERE `network` = '%s' AND ( `url` = '%s' OR `alias` = '%s')
AND `uid` = %d LIMIT 1",
dbesc(NETWORK_OSTATUS),
dbesc($author_link),
@@ -185,3 +187,4 @@ function salmon_post(&$a) {
http_status_exit(200);
}
+}
diff --git a/mod/search.php b/mod/search.php
index 7c78339c70..431bd821d6 100644
--- a/mod/search.php
+++ b/mod/search.php
@@ -4,6 +4,7 @@ require_once('include/security.php');
require_once('include/conversation.php');
require_once('mod/dirfind.php');
+if(! function_exists('search_saved_searches')) {
function search_saved_searches() {
$o = '';
@@ -39,10 +40,10 @@ function search_saved_searches() {
}
return $o;
-
+}
}
-
+if(! function_exists('search_init')) {
function search_init(&$a) {
$search = ((x($_GET,'search')) ? notags(trim(rawurldecode($_GET['search']))) : '');
@@ -76,17 +77,18 @@ function search_init(&$a) {
}
-
+}
}
-
+if(! function_exists('search_post')) {
function search_post(&$a) {
if(x($_POST,'search'))
$a->data['search'] = $_POST['search'];
}
+}
-
+if(! function_exists('search_content')) {
function search_content(&$a) {
if((get_config('system','block_public')) && (! local_user()) && (! remote_user())) {
@@ -248,4 +250,4 @@ function search_content(&$a) {
return $o;
}
-
+}
diff --git a/mod/session.php b/mod/session.php
index 22c855edba..ac3d885b63 100644
--- a/mod/session.php
+++ b/mod/session.php
@@ -1,5 +1,6 @@
theme_info['extends'];
@@ -13,7 +13,9 @@ function get_theme_config_file($theme){
}
return null;
}
+}
+if(! function_exists('settings_init')) {
function settings_init(&$a) {
if(! local_user()) {
@@ -110,10 +112,10 @@ function settings_init(&$a) {
'$class' => 'settings-widget',
'$items' => $tabs,
));
-
+}
}
-
+if(! function_exists('settings_post')) {
function settings_post(&$a) {
if(! local_user())
@@ -630,8 +632,9 @@ function settings_post(&$a) {
goaway($a->get_baseurl(true) . '/settings' );
return; // NOTREACHED
}
+}
-
+if(! function_exists('settings_content')) {
function settings_content(&$a) {
$o = '';
@@ -1295,6 +1298,5 @@ function settings_content(&$a) {
$o .= '' . "\r\n";
return $o;
-
}
-
+}
diff --git a/mod/share.php b/mod/share.php
index 085da4e30d..f3a221eb8e 100644
--- a/mod/share.php
+++ b/mod/share.php
@@ -1,12 +1,14 @@
argc > 1) ? intval($a->argv[1]) : 0);
if((! $post_id) || (! local_user()))
killme();
- $r = q("SELECT item.*, contact.network FROM `item`
- inner join contact on `item`.`contact-id` = `contact`.`id`
+ $r = q("SELECT item.*, contact.network FROM `item`
+ inner join contact on `item`.`contact-id` = `contact`.`id`
WHERE `item`.`id` = %d AND `item`.`uid` = %d LIMIT 1",
intval($post_id),
@@ -40,7 +42,9 @@ function share_init(&$a) {
echo $o;
killme();
}
+}
+if(! function_exists('share_header')) {
function share_header($author, $profile, $avatar, $guid, $posted, $link) {
$header = "[share author='".str_replace(array("'", "[", "]"), array("'", "[", "]"),$author).
"' profile='".str_replace(array("'", "[", "]"), array("'", "[", "]"),$profile).
@@ -56,3 +60,4 @@ function share_header($author, $profile, $avatar, $guid, $posted, $link) {
return $header;
}
+}
diff --git a/mod/smilies.php b/mod/smilies.php
index c47f95da76..4d498b6746 100644
--- a/mod/smilies.php
+++ b/mod/smilies.php
@@ -1,3 +1,7 @@
get_baseurl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . ']' . $post_type . '[/url]';
@@ -154,7 +154,5 @@ EOT;
call_hooks('post_local_end', $arr);
killme();
-
}
-
-
+}
diff --git a/mod/suggest.php b/mod/suggest.php
index b73c2cd1b6..8f5f4f6a12 100644
--- a/mod/suggest.php
+++ b/mod/suggest.php
@@ -3,7 +3,7 @@
require_once('include/socgraph.php');
require_once('include/contact_widgets.php');
-
+if(! function_exists('suggest_init')) {
function suggest_init(&$a) {
if(! local_user())
return;
@@ -42,13 +42,13 @@ function suggest_init(&$a) {
);
}
}
-
+}
}
-
+if(! function_exists('suggest_content')) {
function suggest_content(&$a) {
require_once("mod/proxy.php");
@@ -110,8 +110,9 @@ function suggest_content(&$a) {
$o .= replace_macros($tpl,array(
'$title' => t('Friend Suggestions'),
'$contacts' => $entries,
-
+
));
return $o;
}
+}
diff --git a/mod/tagger.php b/mod/tagger.php
index 2c469a58bb..bee37015ea 100644
--- a/mod/tagger.php
+++ b/mod/tagger.php
@@ -4,7 +4,7 @@ require_once('include/security.php');
require_once('include/bbcode.php');
require_once('include/items.php');
-
+if(! function_exists('tagger_content')) {
function tagger_content(&$a) {
if(! local_user() && ! remote_user()) {
@@ -95,7 +95,7 @@ EOT;
$bodyverb = t('%1$s tagged %2$s\'s %3$s with %4$s');
if(! isset($bodyverb))
- return;
+ return;
$termlink = html_entity_decode('⌗') . '[url=' . $a->get_baseurl() . '/search?tag=' . urlencode($term) . ']'. $term . '[/url]';
@@ -115,7 +115,7 @@ EOT;
$arr['author-name'] = $contact['name'];
$arr['author-link'] = $contact['url'];
$arr['author-avatar'] = $contact['thumb'];
-
+
$ulink = '[url=' . $contact['url'] . ']' . $contact['name'] . '[/url]';
$alink = '[url=' . $item['author-link'] . ']' . $item['author-name'] . '[/url]';
$plink = '[url=' . $item['plink'] . ']' . $post_type . '[/url]';
@@ -216,5 +216,5 @@ EOT;
return; // NOTREACHED
-
+}
}
diff --git a/mod/tagrm.php b/mod/tagrm.php
index 176986bc38..70b3ef048f 100644
--- a/mod/tagrm.php
+++ b/mod/tagrm.php
@@ -2,6 +2,7 @@
require_once('include/bbcode.php');
+if(! function_exists('tagrm_post')) {
function tagrm_post(&$a) {
if(! local_user())
@@ -40,13 +41,13 @@ function tagrm_post(&$a) {
info( t('Tag removed') . EOL );
goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']);
-
- // NOTREACHED
+ // NOTREACHED
+}
}
-
+if(! function_exists('tagrm_content')) {
function tagrm_content(&$a) {
$o = '';
@@ -95,5 +96,5 @@ function tagrm_content(&$a) {
$o .= '';
return $o;
-
+}
}
diff --git a/mod/toggle_mobile.php b/mod/toggle_mobile.php
index 00991e44ca..dbf0996bba 100644
--- a/mod/toggle_mobile.php
+++ b/mod/toggle_mobile.php
@@ -1,5 +1,6 @@
argc > 1) {
header("Content-type: application/json");
@@ -86,9 +89,10 @@ function uexport_content(&$a){
'$options' => $options
));
-
+}
}
+if(! function_exists('_uexport_multirow')) {
function _uexport_multirow($query) {
$result = array();
$r = q($query);
@@ -103,7 +107,9 @@ function _uexport_multirow($query) {
}
return $result;
}
+}
+if(! function_exists('_uexport_row')) {
function _uexport_row($query) {
$result = array();
$r = q($query);
@@ -115,9 +121,10 @@ function _uexport_row($query) {
}
return $result;
}
+}
-
-function uexport_account($a){
+if(! function_exists('uexport_account')) {
+function uexport_account($a) {
$user = _uexport_row(
sprintf( "SELECT * FROM `user` WHERE `uid` = %d LIMIT 1", intval(local_user()) )
@@ -153,9 +160,9 @@ function uexport_account($a){
'version' => FRIENDICA_VERSION,
'schema' => DB_UPDATE_VERSION,
'baseurl' => $a->get_baseurl(),
- 'user' => $user,
- 'contact' => $contact,
- 'profile' => $profile,
+ 'user' => $user,
+ 'contact' => $contact,
+ 'profile' => $profile,
'photo' => $photo,
'pconfig' => $pconfig,
'group' => $group,
@@ -164,14 +171,15 @@ function uexport_account($a){
//echo ""; var_dump(json_encode($output)); killme();
echo json_encode($output);
-
+}
}
/**
* echoes account data and items as separated json, one per line
*/
+if(! function_exists('uexport_all')) {
function uexport_all(&$a) {
-
+
uexport_account($a);
echo "\n";
@@ -199,5 +207,5 @@ function uexport_all(&$a) {
$output = array('item' => $r);
echo json_encode($output)."\n";
}
-
+}
}
diff --git a/mod/uimport.php b/mod/uimport.php
index 7ed5648d9e..942268b0ef 100644
--- a/mod/uimport.php
+++ b/mod/uimport.php
@@ -5,6 +5,7 @@
require_once("include/uimport.php");
+if(! function_exists('uimport_post')) {
function uimport_post(&$a) {
switch($a->config['register_policy']) {
case REGISTER_OPEN:
@@ -27,16 +28,18 @@ function uimport_post(&$a) {
$verified = 0;
break;
}
-
+
if (x($_FILES,'accountfile')){
/// @TODO Pass $blocked / $verified, send email to admin on REGISTER_APPROVE
import_account($a, $_FILES['accountfile']);
return;
}
}
+}
+if(! function_exists('uimport_content')) {
function uimport_content(&$a) {
-
+
if((! local_user()) && ($a->config['register_policy'] == REGISTER_CLOSED)) {
notice("Permission denied." . EOL);
return;
@@ -51,8 +54,8 @@ function uimport_content(&$a) {
return;
}
}
-
-
+
+
if(x($_SESSION,'theme'))
unset($_SESSION['theme']);
if(x($_SESSION,'mobile-theme'))
@@ -71,3 +74,4 @@ function uimport_content(&$a) {
),
));
}
+}
diff --git a/mod/update_community.php b/mod/update_community.php
index 512629b005..396f4234c0 100644
--- a/mod/update_community.php
+++ b/mod/update_community.php
@@ -4,6 +4,7 @@
require_once('mod/community.php');
+if(! function_exists('update_community_content')) {
function update_community_content(&$a) {
header("Content-type: text/html");
@@ -29,5 +30,5 @@ function update_community_content(&$a) {
echo "";
echo "