1
0
Fork 0

Merge develop into 0602_contact_profile

This commit is contained in:
rabuzarus 2016-02-08 23:16:02 +01:00
commit 0c764684bb
139 changed files with 2818 additions and 3106 deletions

View file

@ -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.
@ -18,7 +20,7 @@ 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
* Description: This is what my plugin does. It's really cool.
* Version: 1.0
* Author: John Q. Public <john@myfriendicasite.com>
*/
@ -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.
@ -80,7 +82,7 @@ They may also contain plugin_name_post(&$a) which is called before the _content
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.
@ -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);

View file

@ -1,11 +1,12 @@
**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
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.
@ -18,7 +19,7 @@ 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
* Description: This is what my plugin does. It's really cool.
* Version: 1.0
* Author: John Q. Public <john@myfriendicasite.com>
*/
@ -34,6 +35,9 @@ 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) {
@ -50,14 +54,15 @@ Diese Information ist speziell auf den Hook bezogen, der aktuell bearbeitet wird
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.
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.
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://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:
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');
@ -67,7 +72,8 @@ Sie können auch plugin_name_post(&$a) umfassen, welches vor der content-Funktio
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);
@ -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);

View file

@ -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

190
include/ForumManager.php Normal file
View file

@ -0,0 +1,190 @@
<?php
/**
* @file include/forum.php
* @brief Functions related to forum functionality *
*/
/**
* @brief This class handles functions related to the forum functionality
*/
class ForumManager {
/**
* @brief Function to list all forums a user is connected with
*
* @param int $uid of the profile owner
* @param boolean $showhidden
* Show frorums which are not hidden
* @param boolean $lastitem
* Sort by lastitem
* @param boolean $showprivate
* Show private groups
*
* @returns array
* 'url' => 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;
}
}

View file

@ -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) {

View file

@ -1,8 +1,17 @@
<?php
/**
* @file include/datetime.php
* @brief Some functions for date and time related tasks.
*/
// two-level sort for timezones.
if(! function_exists('timezone_cmp')) {
/**
* @brief Two-level sort for timezones.
*
* @param string $a
* @param string $b
* @return int
*/
function timezone_cmp($a, $b) {
if(strstr($a,'/') && strstr($b,'/')) {
if ( t($a) == t($b)) return 0;
@ -11,11 +20,16 @@ function timezone_cmp($a, $b) {
if(strstr($a,'/')) return -1;
if(strstr($b,'/')) return 1;
if ( t($a) == t($b)) return 0;
return ( t($a) < t($b)) ? -1 : 1;
}}
// emit a timezone selector grouped (primarily) by continent
if(! function_exists('select_timezone')) {
return ( t($a) < t($b)) ? -1 : 1;
}
/**
* @brief Emit a timezone selector grouped (primarily) by continent
*
* @param string $current Timezone
* @return string Parsed HTML output
*/
function select_timezone($current = 'America/Los_Angeles') {
$timezone_identifiers = DateTimeZone::listIdentifiers();
@ -52,13 +66,25 @@ function select_timezone($current = 'America/Los_Angeles') {
}
$o .= '</optgroup></select>';
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('<select id="timezone_select" name="timezone">','', $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 = '<input type="text" name="dob" value="' . $value . '" placeholder="' . t('YYYY-MM-DD or MM-DD') . '" />';
// 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 .= "<div class='date'><input type='text' placeholder='$readable_format' name='$id' id='$id' $input_text />";
$o .= '</div>';
$o .= "<script type='text/javascript'>";
$o .= "\$(function () {var picker = \$('#$id').datetimepicker({step:5,format:'$dateformat' $minjs $maxjs $pickers $defaultdatejs}); $extra_js})";
$o .= "</script>";
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()
* <tt>%1$d %2$s ago</tt>, 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,18 +399,21 @@ 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,
@ -353,34 +422,46 @@ function get_dim($y,$m) {
if($m != 2)
return $dim[$m];
if(((($y % 4) == 0) && (($y % 100) != 0)) || (($y % 400) == 0))
return 29;
return $dim[2];
}}
}
// 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(! function_exists('get_first_dim')) {
/**
* @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');
}}
}
// 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.
/// @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='') {
@ -415,11 +496,13 @@ function cal($y = 0,$m = 0, $links = false, $class='') {
$o .= "<caption>$str_month $y</caption><tr>";
for($a = 0; $a < 7; $a ++)
$o .= '<th>' . mb_substr(day_translate($dn[$a]),0,3,'UTF-8') . '</th>';
$o .= '</tr><tr>';
while($d <= $l) {
if(($dow == $f) && (! $started))
$started = true;
$today = (((isset($tddate)) && ($tddate == $d)) ? "class=\"today\" " : '');
$o .= "<td $today>";
$day = str_replace(' ','&nbsp;',sprintf('%2.2d', $d));
@ -428,10 +511,12 @@ function cal($y = 0,$m = 0, $links = false, $class='') {
$o .= "<a href=\"{$links[$d]}\">$day</a>";
else
$o .= $day;
$d ++;
}
else
} else {
$o .= '&nbsp;';
}
$o .= '</td>';
$dow ++;
if(($dow == 7) && ($d <= $l)) {
@ -442,12 +527,17 @@ function cal($y = 0,$m = 0, $links = false, $class='') {
if($dow)
for($a = $dow; $a < 7; $a ++)
$o .= '<td>&nbsp;</td>';
$o .= '</tr></table>'."\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']),

View file

@ -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;
}
}

View file

@ -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);
}
}
?>

View file

@ -1,185 +0,0 @@
<?php
/**
* @file include/forums.php
* @brief Functions related to forum functionality *
*/
/**
* @brief Function to list all forums a user is connected with
*
* @param int $uid of the profile owner
* @param boolean $showhidden
* Show frorums which are not hidden
* @param boolean $lastitem
* Sort by lastitem
* @param boolean $showprivate
* Show private groups
*
* @returns array
* 'url' => 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;
}

View file

@ -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())

View file

@ -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'] = '<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'] .= '<type>' . $child[NAMESPACE_ACTIVITY]['object-type'][0]['data'] . '</type>' . "\n";
}
if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'id') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'])
$res['object'] .= '<id>' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'] . '</id>' . "\n";
if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'link') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['link'])
$res['object'] .= '<link>' . encode_rel_links($child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']) . '</link>' . "\n";
if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'title') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'])
$res['object'] .= '<title>' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'] . '</title>' . "\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'] .= '<orig>' . xmlify($body) . '</orig>' . "\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'] .= '<content>' . $body . '</content>' . "\n";
}
$res['object'] .= '</object>' . "\n";
}
$rawobj = $item->get_item_tags(NAMESPACE_ACTIVITY, 'target');
if($rawobj) {
$res['target'] = '<target>' . "\n";
$child = $rawobj[0]['child'];
if($child[NAMESPACE_ACTIVITY]['object-type'][0]['data']) {
$res['target'] .= '<type>' . $child[NAMESPACE_ACTIVITY]['object-type'][0]['data'] . '</type>' . "\n";
}
if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'id') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'])
$res['target'] .= '<id>' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'] . '</id>' . "\n";
if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'link') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['link'])
$res['target'] .= '<link>' . encode_rel_links($child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']) . '</link>' . "\n";
if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'data') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'])
$res['target'] .= '<title>' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'] . '</title>' . "\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'] .= '<orig>' . xmlify($body) . '</orig>' . "\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'] .= '<content>' . $body . '</content>' . "\n";
}
$res['target'] .= '</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 .= '<link ';
if($link['attribs']['']['rel'])
$o .= 'rel="' . $link['attribs']['']['rel'] . '" ';
if($link['attribs']['']['type'])
$o .= 'type="' . $link['attribs']['']['type'] . '" ';
if($link['attribs']['']['href'])
$o .= 'href="' . $link['attribs']['']['href'] . '" ';
if( (x($link['attribs'],NAMESPACE_MEDIA)) && $link['attribs'][NAMESPACE_MEDIA]['width'])
$o .= 'media:width="' . $link['attribs'][NAMESPACE_MEDIA]['width'] . '" ';
if( (x($link['attribs'],NAMESPACE_MEDIA)) && $link['attribs'][NAMESPACE_MEDIA]['height'])
$o .= 'media:height="' . $link['attribs'][NAMESPACE_MEDIA]['height'] . '" ';
$o .= ' />' . "\n" ;
}
return xmlify($o);
}
function add_guid($item) {
$r = q("SELECT `guid` FROM `guid` WHERE `guid` = '%s' LIMIT 1", dbesc($item["guid"]));
if ($r)
@ -1695,640 +1268,26 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0)
return;
}
require_once('library/simplepie/simplepie.inc');
require_once('include/contact_selectors.php');
if ($contact['network'] === NETWORK_DFRN) {
logger("Consume DFRN messages", LOGGER_DEBUG);
if(! strlen($xml)) {
logger('consume_feed: empty input');
$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;
}
$feed = new SimplePie();
$feed->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;
}
}
}
}
@ -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("<links>".unxmlify($xo->link)."</links>",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",

View file

@ -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);

View file

@ -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"))) {

View file

@ -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;
}
}

View file

@ -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) {
}
}
}
}

View file

@ -3,8 +3,8 @@
require_once("include/acl_selectors.php");
if(! function_exists('acl_init')) {
function acl_init(&$a){
acl_lookup($a);
}
}

View file

@ -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
@ -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,7 +1087,7 @@ function admin_page_dbsync(&$a) {
}
return $o;
}
}
/**
@ -1081,6 +1095,7 @@ function admin_page_dbsync(&$a) {
*
* @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){
/*
@ -1484,12 +1502,14 @@ function admin_page_plugins(&$a){
'$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,6 +1929,7 @@ function admin_page_features_post(&$a) {
goaway($a->get_baseurl(true) . '/admin/features' );
return; // NOTREACHED
}
}
/**
* @brief Subpage for global additional feature management
@ -1913,6 +1945,7 @@ function admin_page_features_post(&$a) {
* @param App $a
* @return string
*/
if(! function_exists('admin_page_features')) {
function admin_page_features(&$a) {
if((argc() > 1) && (argv(1) === 'features')) {
@ -1945,3 +1978,4 @@ function admin_page_features(&$a) {
return $o;
}
}
}

View file

@ -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;
}
}

View file

@ -1,5 +1,5 @@
<?php
if(! function_exists('amcd_content')) {
function amcd_content(&$a) {
//header("Content-type: text/json");
echo <<< EOT
@ -47,3 +47,4 @@ echo <<< EOT
EOT;
killme();
}
}

View file

@ -1,10 +1,8 @@
<?php
require_once('include/api.php');
if(! function_exists('oauth_get_client')) {
function oauth_get_client($request){
$params = $request->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();
}
}

View file

@ -1,11 +1,12 @@
<?php
if(! function_exists('apps_content')) {
function apps_content(&$a) {
$privateaddons = get_config('config','private_addons');
if ($privateaddons === "1") {
if((! (local_user()))) {
info( t("You must be logged in to use addons. "));
return;};
return;
}
}
$title = t('Applications');
@ -13,13 +14,10 @@ function apps_content(&$a) {
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,
));
}
}

View file

@ -1,7 +1,7 @@
<?php
require_once('include/security.php');
if(! function_exists('attach_init')) {
function attach_init(&$a) {
if($a->argc != 2) {
@ -47,3 +47,4 @@ function attach_init(&$a) {
killme();
// NOTREACHED
}
}

View file

@ -9,6 +9,7 @@ function visible_lf($s) {
return str_replace("\n",'<br />', $s);
}
if(! function_exists('babel_content')) {
function babel_content(&$a) {
$o .= '<h1>Babel Diagnostic</h1>';
@ -77,3 +78,4 @@ function babel_content(&$a) {
return $o;
}
}

View file

@ -1,12 +1,14 @@
<?php
require_once('include/conversation.php');
require_once('include/items.php');
if(! function_exists('bookmarklet_init')) {
function bookmarklet_init(&$a) {
$_GET["mode"] = "minimal";
}
}
if(! function_exists('bookmarklet_content')) {
function bookmarklet_content(&$a) {
if(!local_user()) {
$o = '<h2>'.t('Login').'</h2>';
@ -44,3 +46,4 @@ function bookmarklet_content(&$a) {
return $o;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -1,15 +1,14 @@
<?php
if(! function_exists('community_init')) {
function community_init(&$a) {
if(! local_user()) {
unset($_SESSION['theme']);
unset($_SESSION['mobile-theme']);
}
}
}
if(! function_exists('community_content')) {
function community_content(&$a, $update = 0) {
$o = '';
@ -115,7 +114,9 @@ function community_content(&$a, $update = 0) {
return $o;
}
}
if(! function_exists('community_getitems')) {
function community_getitems($start, $itemspage) {
if (get_config('system','community_page_style') == CP_GLOBAL_COMMUNITY)
return(community_getpublicitems($start, $itemspage));
@ -140,9 +141,10 @@ function community_getitems($start, $itemspage) {
);
return($r);
}
}
if(! function_exists('community_getpublicitems')) {
function community_getpublicitems($start, $itemspage) {
$r = q("SELECT `item`.`uri`, `item`.*, `item`.`id` AS `item_id`,
`author-name` AS `name`, `owner-avatar` AS `photo`,
@ -157,3 +159,4 @@ function community_getpublicitems($start, $itemspage) {
return($r);
}
}

View file

@ -2,6 +2,7 @@
require_once('include/group.php');
if(! function_exists('contactgroup_content')) {
function contactgroup_content(&$a) {
@ -48,3 +49,4 @@ function contactgroup_content(&$a) {
killme();
}
}

View file

@ -7,6 +7,7 @@ require_once('include/Scrape.php');
require_once('mod/proxy.php');
require_once('include/Photo.php');
if(! function_exists('contacts_init')) {
function contacts_init(&$a) {
if(! local_user())
return;
@ -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']),
);
}
}
/**

View file

@ -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');
@ -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');
@ -897,5 +897,5 @@ function render_content(&$a, $items, $mode, $update, $preview = false) {
return $threads;
}
}

View file

@ -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,
));
}
}

View file

@ -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;
}
}

View file

@ -1,11 +1,13 @@
<?php
require_once('mod/settings.php');
if(! function_exists('delegate_init')) {
function delegate_init(&$a) {
return settings_init($a);
}
}
if(! function_exists('delegate_content')) {
function delegate_content(&$a) {
if(! local_user()) {
@ -144,5 +146,5 @@ function delegate_content(&$a) {
return $o;
}
}

View file

@ -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
}
}

View file

@ -1,10 +1,12 @@
<?php
require_once('include/items.php');
require_once('include/dfrn.php');
require_once('include/event.php');
require_once('library/defuse/php-encryption-1.2.1/Crypto.php');
if(! function_exists('dfrn_notify_post')) {
function dfrn_notify_post(&$a) {
logger(__function__, LOGGER_TRACE);
$dfrn_id = ((x($_POST,'dfrn_id')) ? notags(trim($_POST['dfrn_id'])) : '');
@ -208,13 +210,14 @@ function dfrn_notify_post(&$a) {
logger('rino: decrypted data: ' . $data, LOGGER_DATA);
}
$ret = local_delivery($importer,$data);
$ret = dfrn::import($data, $importer);
xml_status($ret);
// NOTREACHED
}
}
if(! function_exists('dfrn_notify_content')) {
function dfrn_notify_content(&$a) {
if(x($_GET,'dfrn_id')) {
@ -338,5 +341,5 @@ function dfrn_notify_content(&$a) {
killme();
}
}
}

View file

@ -3,7 +3,7 @@ require_once('include/items.php');
require_once('include/auth.php');
require_once('include/dfrn.php');
if(! function_exists('dfrn_poll_init')) {
function dfrn_poll_init(&$a) {
@ -195,11 +195,11 @@ function dfrn_poll_init(&$a) {
return; // NOTREACHED
}
}
}
}
if(! function_exists('dfrn_poll_post')) {
function dfrn_poll_post(&$a) {
$dfrn_id = ((x($_POST,'dfrn_id')) ? $_POST['dfrn_id'] : '');
@ -377,7 +377,9 @@ function dfrn_poll_post(&$a) {
}
}
}
if(! function_exists('dfrn_poll_content')) {
function dfrn_poll_content(&$a) {
$dfrn_id = ((x($_GET,'dfrn_id')) ? $_GET['dfrn_id'] : '');
@ -562,3 +564,4 @@ function dfrn_poll_content(&$a) {
}
}
}
}

View file

@ -1,5 +1,5 @@
<?php
if(! function_exists('directory_init')) {
function directory_init(&$a) {
$a->set_pager_itemspage(60);
@ -16,17 +16,17 @@ 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;
@ -217,3 +217,4 @@ function directory_content(&$a) {
return $o;
}
}

View file

@ -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;
}
}

View file

@ -1,5 +1,5 @@
<?php
if(! function_exists('display_init')) {
function display_init(&$a) {
if((get_config('system','block_public')) && (! local_user()) && (! remote_user())) {
@ -85,9 +85,10 @@ function display_init(&$a) {
}
profile_load($a, $nick, 0, $profiledata);
}
}
if(! function_exists('display_fetchauthor')) {
function display_fetchauthor($a, $item) {
$profiledata = array();
@ -220,7 +221,9 @@ function display_fetchauthor($a, $item) {
return($profiledata);
}
}
if(! function_exists('display_content')) {
function display_content(&$a, $update = 0) {
if((get_config('system','block_public')) && (! local_user()) && (! remote_user())) {
@ -522,4 +525,4 @@ function display_content(&$a, $update = 0) {
return $o;
}
}

View file

@ -2,6 +2,7 @@
require_once('include/acl_selectors.php');
if(! function_exists('editpost_content')) {
function editpost_content(&$a) {
$o = '';
@ -150,7 +151,5 @@ function editpost_content(&$a) {
));
return $o;
}
}

View file

@ -5,6 +5,7 @@ require_once('include/datetime.php');
require_once('include/event.php');
require_once('include/items.php');
if(! function_exists('events_post')) {
function events_post(&$a) {
logger('post: ' . print_r($_REQUEST,true));
@ -156,9 +157,9 @@ function events_post(&$a) {
goaway($_SESSION['return_url']);
}
}
if(! function_exists('events_content')) {
function events_content(&$a) {
if(! local_user()) {
@ -578,3 +579,4 @@ function events_content(&$a) {
return $o;
}
}
}

View file

@ -10,6 +10,7 @@ require_once('include/Photo.php');
/**
* @param App $a
*/
if(! function_exists('fbrowser_content')) {
function fbrowser_content($a){
if (!local_user())
@ -141,5 +142,5 @@ function fbrowser_content($a){
killme();
}
}
}

View file

@ -4,7 +4,7 @@ require_once('include/security.php');
require_once('include/bbcode.php');
require_once('include/items.php');
if(! function_exists('filer_content')) {
function filer_content(&$a) {
if(! local_user()) {
@ -35,3 +35,4 @@ function filer_content(&$a) {
}
killme();
}
}

View file

@ -1,5 +1,6 @@
<?php
if(! function_exists('filerm_content')) {
function filerm_content(&$a) {
if(! local_user()) {
@ -25,3 +26,4 @@ function filerm_content(&$a) {
killme();
}
}

View file

@ -5,6 +5,7 @@ require_once('include/follow.php');
require_once('include/Contact.php');
require_once('include/contact_selectors.php');
if(! function_exists('follow_content')) {
function follow_content(&$a) {
if(! local_user()) {
@ -148,7 +149,9 @@ function follow_content(&$a) {
return $o;
}
}
if(! function_exists('follow_post')) {
function follow_post(&$a) {
if(! local_user()) {
@ -185,3 +188,4 @@ function follow_post(&$a) {
goaway($return_url);
// NOTREACHED
}
}

View file

@ -1,5 +1,6 @@
<?php
if(! function_exists('friendica_init')) {
function friendica_init(&$a) {
if ($a->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 = '';
@ -105,5 +106,5 @@ function friendica_content(&$a) {
call_hooks('about_hook', $o);
return $o;
}
}

View file

@ -1,6 +1,6 @@
<?php
if(! function_exists('fsuggest_post')) {
function fsuggest_post(&$a) {
if(! local_user()) {
@ -65,11 +65,11 @@ function fsuggest_post(&$a) {
}
}
}
if(! function_exists('fsuggest_content')) {
function fsuggest_content(&$a) {
require_once('include/acl_selectors.php');
@ -109,3 +109,4 @@ function fsuggest_content(&$a) {
return $o;
}
}

View file

@ -1,18 +1,21 @@
<?php
if(! function_exists('validate_members')) {
function validate_members(&$item) {
$item = intval($item);
}
}
if(! function_exists('group_init')) {
function group_init(&$a) {
if(local_user()) {
require_once('include/group.php');
$a->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);
}
}

View file

@ -1,5 +1,6 @@
<?php
if(! function_exists('hcard_init')) {
function hcard_init(&$a) {
$blocked = (((get_config('system','block_public')) && (! local_user()) && (! remote_user())) ? true : false);
@ -46,6 +47,5 @@ function hcard_init(&$a) {
$dfrn_pages = array('request', 'confirm', 'notify', 'poll');
foreach($dfrn_pages as $dfrn)
$a->page['htmlhead'] .= "<link rel=\"dfrn-{$dfrn}\" href=\"".$a->get_baseurl()."/dfrn_{$dfrn}/{$which}\" />\r\n";
}
}

View file

@ -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) {
}
</style>".$html;
return $html;
}
}

View file

@ -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();
}
}

View file

@ -1,6 +1,6 @@
<?php
if(! function_exists('ignored_init')) {
function ignored_init(&$a) {
$ignored = 0;
@ -43,3 +43,4 @@ function ignored_init(&$a) {
echo json_encode($ignored);
killme();
}
}

View file

@ -3,7 +3,7 @@ require_once "include/Photo.php";
$install_wizard_pass=1;
if(! function_exists('install_init')) {
function install_init(&$a){
// $baseurl/install/testrwrite to test if rewite in .htaccess is working
@ -22,9 +22,10 @@ function install_init(&$a){
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,6 +318,7 @@ function install_content(&$a) {
* required : boolean
* help : string optional
*/
if(! function_exists('check_add')) {
function check_add(&$checks, $title, $status, $required, $help) {
$checks[] = array(
'title' => $title,
@ -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 .= "<textarea rows=\"24\" cols=\"80\" >$data</textarea>";
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 <a href='$baseurl/register'>registration page</a> 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.")
."</p>";
}
}

View file

@ -9,6 +9,7 @@
require_once('include/email.php');
if(! function_exists('invite_post')) {
function invite_post(&$a) {
if(! local_user()) {
@ -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()) {
@ -142,3 +144,4 @@ function invite_content(&$a) {
return $o;
}
}

View file

@ -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;
}
}

View file

@ -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();
}
}

View file

@ -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)
@ -45,5 +46,5 @@ function localtime_content(&$a) {
$o .= '<input type="submit" name="submit" value="' . t('Submit') . '" /></form>';
return $o;
}
}

View file

@ -1,6 +1,6 @@
<?php
if(! function_exists('lockview_content')) {
function lockview_content(&$a) {
$type = (($a->argc > 1) ? $a->argv[1] : 0);
@ -86,5 +86,5 @@ function lockview_content(&$a) {
echo $o . implode(', ', $l);
killme();
}
}

View file

@ -1,5 +1,5 @@
<?php
if(! function_exists('login_content')) {
function login_content(&$a) {
if(x($_SESSION,'theme'))
unset($_SESSION['theme']);
@ -9,5 +9,5 @@ function login_content(&$a) {
if(local_user())
goaway(z_root());
return login(($a->config['register_policy'] == REGISTER_CLOSED) ? false : true);
}
}

View file

@ -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;
}
}
}

View file

@ -1,7 +1,8 @@
<?php
if(! function_exists('maintenance_content')) {
function maintenance_content(&$a) {
return replace_macros(get_markup_template('maintenance.tpl'), array(
'$sysdown' => t('System down for maintenance')
));
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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();
}
}

View file

@ -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())
@ -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;
}
}

View file

@ -1,5 +1,6 @@
<?php
if(! function_exists('msearch_post')) {
function msearch_post(&$a) {
$perpage = (($_POST['n']) ? $_POST['n'] : 80);
@ -38,5 +39,5 @@ function msearch_post(&$a) {
echo json_encode($output);
killme();
}
}

View file

@ -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')
));
}
}

View file

@ -1,4 +1,6 @@
<?php
if(! function_exists('network_init')) {
function network_init(&$a) {
if(! local_user()) {
notice( t('Permission denied.') . EOL);
@ -114,7 +116,7 @@ function network_init(&$a) {
require_once('include/group.php');
require_once('include/contact_widgets.php');
require_once('include/items.php');
require_once('include/forums.php');
require_once('include/ForumManager.php');
if(! x($a->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;
}
}

View file

@ -1,5 +1,6 @@
<?php
if(! function_exists('newmember_content')) {
function newmember_content(&$a) {
@ -82,3 +83,4 @@ function newmember_content(&$a) {
return $o;
}
}

View file

@ -7,6 +7,7 @@
require_once("include/plugin.php");
if(! function_exists('nodeinfo_wellknown')) {
function nodeinfo_wellknown(&$a) {
if (!get_config("system", "nodeinfo")) {
http_status_exit(404);
@ -19,7 +20,9 @@ function nodeinfo_wellknown(&$a) {
echo json_encode($nodeinfo, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
exit;
}
}
if(! function_exists('nodeinfo_init')) {
function nodeinfo_init(&$a){
if (!get_config("system", "nodeinfo")) {
http_status_exit(404);
@ -143,9 +146,9 @@ function nodeinfo_init(&$a){
echo json_encode($nodeinfo, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
exit;
}
}
if(! function_exists('nodeinfo_cron')) {
function nodeinfo_cron() {
$a = get_app();
@ -260,5 +263,5 @@ function nodeinfo_cron() {
logger("cron_end");
set_config('nodeinfo','last_calucation', time());
}
}
?>

View file

@ -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;
}
}

View file

@ -1,5 +1,6 @@
<?php
if(! function_exists('noscrape_init')) {
function noscrape_init(&$a) {
if($a->argc > 1)
@ -62,5 +63,5 @@ function noscrape_init(&$a) {
header('Content-type: application/json; charset=utf-8');
echo json_encode($json_info);
exit;
}
}

View file

@ -1,5 +1,6 @@
<?php
if(! function_exists('notes_init')) {
function notes_init(&$a) {
if(! local_user())
@ -12,10 +13,10 @@ function notes_init(&$a) {
nav_set_selected('home');
// profile_load($a,$which,$profile);
}
}
if(! function_exists('notes_content')) {
function notes_content(&$a,$update = false) {
if(! local_user()) {
@ -135,3 +136,4 @@ function notes_content(&$a,$update = false) {
$o .= paginate($a);
return $o;
}
}

View file

@ -1,6 +1,7 @@
<?php
/* 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",
@ -16,5 +17,5 @@
}
return;
}
}

View file

@ -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;
}
}

View file

@ -1,6 +1,6 @@
<?php
if(! function_exists('notify_init')) {
function notify_init(&$a) {
if(! local_user())
return;
@ -42,10 +42,10 @@ function notify_init(&$a) {
echo $j;
killme();
}
}
}
if(! function_exists('notify_content')) {
function notify_content(&$a) {
if(! local_user())
return login();
@ -80,5 +80,5 @@ function notify_content(&$a) {
return $o;
}
}

View file

@ -1,6 +1,7 @@
<?php
require_once("include/oembed.php");
if(! function_exists('oembed_content')) {
function oembed_content(&$a) {
// logger('mod_oembed ' . $a->query_string, LOGGER_ALL);
@ -33,3 +34,4 @@ function oembed_content(&$a){
}
killme();
}
}

View file

@ -1,6 +1,6 @@
<?php
if(! function_exists('oexchange_init')) {
function oexchange_init(&$a) {
if(($a->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()) {
@ -52,7 +53,5 @@ function oexchange_content(&$a) {
$_REQUEST = $post;
require_once('mod/item.php');
item_post($a);
}
}

View file

@ -1,9 +1,8 @@
<?php
require_once('library/openid.php');
if(! function_exists('openid_content')) {
function openid_content(&$a) {
$noid = get_config('system','no_openid');
@ -94,3 +93,4 @@ function openid_content(&$a) {
goaway(z_root());
// NOTREACHED
}
}

View file

@ -1,6 +1,6 @@
<?php
if(! function_exists('opensearch_content')) {
function opensearch_content(&$a) {
$tpl = get_markup_template('opensearch.tpl');
header("Content-type: application/opensearchdescription+xml");
@ -13,6 +13,6 @@
echo $o;
killme();
}
}
?>

View file

@ -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;
}
}

View file

@ -4,6 +4,7 @@ This file is part of the Diaspora protocol. It is used for fetching single publi
*/
require_once("include/diaspora.php");
if(! function_exists('p_init')) {
function p_init($a) {
if ($a->argc != 2) {
header($_SERVER["SERVER_PROTOCOL"].' 510 '.t('Not Extended'));
@ -79,3 +80,4 @@ function p_init($a){
killme();
}
}

View file

@ -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();
}
}
?>

View file

@ -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
}
}

View file

@ -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:
@ -1906,4 +1907,4 @@ function photos_content(&$a) {
$o .= paginate($a);
return $o;
}
}

View file

@ -1,10 +1,11 @@
<?php
require_once("include/datetime.php");
require_once('include/bbcode.php');
require_once('include/forums.php');
require_once('include/ForumManager.php');
require_once('include/group.php');
require_once("mod/proxy.php");
if(! function_exists('ping_init')) {
function ping_init(&$a) {
header("Content-type: text/xml");
@ -96,7 +97,7 @@ function ping_init(&$a) {
}
if(intval(feature_enabled(local_user(),'forumlist_widget'))) {
$forums_unseen = forums_count_unseen();
$forums_unseen = ForumManager::count_unseen_items();
}
}
@ -338,7 +339,9 @@ function ping_init(&$a) {
killme();
}
}
if(! function_exists('ping_get_notifications')) {
function ping_get_notifications($uid) {
$result = array();
@ -389,7 +392,11 @@ function ping_get_notifications($uid) {
// Replace the name with {0} but ensure to make that only once
// The {0} is used later and prints the name in bold.
if ($notification['name'] != "")
$pos = strpos($notification["message"],$notification['name']);
else
$pos = false;
if ($pos !== false)
$notification["message"] = substr_replace($notification["message"],"{0}",$pos,strlen($notification["name"]));
@ -406,3 +413,4 @@ function ping_get_notifications($uid) {
return($result);
}
}

View file

@ -1,5 +1,6 @@
<?php
if(! function_exists('poco_init')) {
function poco_init(&$a) {
require_once("include/bbcode.php");
@ -324,5 +325,5 @@ function poco_init(&$a) {
else
http_status_exit(500);
}
}

View file

@ -18,7 +18,7 @@ require_once('include/security.php');
require_once('include/bbcode.php');
require_once('include/items.php');
if(! function_exists('poke_init')) {
function poke_init(&$a) {
if(! local_user())
@ -140,9 +140,9 @@ function poke_init(&$a) {
return;
}
}
if(! function_exists('poke_content')) {
function poke_content(&$a) {
if(! local_user()) {
@ -201,5 +201,5 @@ function poke_content(&$a) {
));
return $o;
}
}

View file

@ -10,6 +10,7 @@ require_once('include/crypto.php');
// not yet ready for prime time
//require_once('include/zot.php');
if(! function_exists('post_post')) {
function post_post(&$a) {
$bulk_delivery = false;
@ -48,4 +49,4 @@ function post_post(&$a) {
http_status_exit(($ret) ? $ret : 200);
// NOTREACHED
}
}

View file

@ -1,5 +1,6 @@
<?php
if(! function_exists('pretheme_init')) {
function pretheme_init(&$a) {
if($_REQUEST['theme']) {
@ -20,3 +21,4 @@ function pretheme_init(&$a) {
}
killme();
}
}

View file

@ -2,6 +2,7 @@
require_once('include/Scrape.php');
if(! function_exists('probe_content')) {
function probe_content(&$a) {
$o .= '<h3>Probe Diagnostic</h3>';
@ -22,3 +23,4 @@ function probe_content(&$a) {
}
return $o;
}
}

View file

@ -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'] .= "<link rel=\"dfrn-{$dfrn}\" href=\"".$a->get_baseurl()."/dfrn_{$dfrn}/{$which}\" />\r\n";
$a->page['htmlhead'] .= "<link rel=\"dfrn-poco\" href=\"".$a->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;
}
}

View file

@ -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()) {
@ -164,7 +165,7 @@ function profile_photo_post(&$a) {
$ph->orient($src);
@unlink($src);
return profile_photo_crop_ui_head($a, $ph);
}
}
@ -323,4 +324,3 @@ function profile_photo_crop_ui_head(&$a, $ph){
$a->page['end'] .= replace_macros(get_markup_template("cropend.tpl"), array());
return;
}}

View file

@ -1,6 +1,7 @@
<?php
require_once("include/Contact.php");
if(! function_exists('profiles_init')) {
function profiles_init(&$a) {
nav_set_selected('profiles');
@ -139,9 +140,10 @@ function profiles_init(&$a) {
}
}
}
if(! function_exists('profile_clean_keywords')) {
function profile_clean_keywords($keywords) {
$keywords = str_replace(","," ",$keywords);
$keywords = explode(" ", $keywords);
@ -158,7 +160,9 @@ function profile_clean_keywords($keywords) {
return $keywords;
}
}
if(! function_exists('profiles_post')) {
function profiles_post(&$a) {
if(! local_user()) {
@ -502,8 +506,9 @@ function profiles_post(&$a) {
}
}
}
}
if(! function_exists('profile_activity')) {
function profile_activity($changed, $value) {
$a = get_app();
@ -593,8 +598,9 @@ function profile_activity($changed, $value) {
}
}
}
if(! function_exists('profiles_content')) {
function profiles_content(&$a) {
if(! local_user()) {
@ -818,5 +824,5 @@ function profiles_content(&$a) {
}
return $o;
}
}
}

View file

@ -1,5 +1,6 @@
<?php
if(! function_exists('profperm_init')) {
function profperm_init(&$a) {
if(! local_user())
@ -9,10 +10,10 @@ function profperm_init(&$a) {
$profile = $a->argv[1];
profile_load($a,$which,$profile);
}
}
if(! function_exists('profperm_content')) {
function profperm_content(&$a) {
if(! local_user()) {
@ -156,6 +157,5 @@ function profperm_content(&$a) {
}
$o .= '</div>';
return $o;
}
}

View file

@ -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("/(<img [^>]*src *= *[\"'])([^\"']+)([\"'][^>]*>)/siU", "proxy_img_cb", $html);
}
}

View file

@ -1,5 +1,6 @@
<?php
if(! function_exists('hub_return')) {
function hub_return($valid,$body) {
if($valid) {
@ -14,18 +15,18 @@ function hub_return($valid,$body) {
// NOTREACHED
}
}
// when receiving an XML feed, always return OK
if(! function_exists('hub_post_return')) {
function hub_post_return() {
header($_SERVER["SERVER_PROTOCOL"] . ' 200 ' . 'OK');
killme();
}
}
if(! function_exists('pubsub_init')) {
function pubsub_init(&$a) {
$nick = (($a->argc > 1) ? notags(trim($a->argv[1])) : '');
@ -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();
}
}

View file

@ -1,9 +1,12 @@
<?php
if(! function_exists('post_var')) {
function post_var($name) {
return (x($_POST, $name)) ? notags(trim($_POST[$name])) : '';
}
}
if(! function_exists('pubsubhubbub_init')) {
function pubsubhubbub_init(&$a) {
// PuSH subscription must be considered "public" so just block it
// if public access isn't enabled.
@ -158,5 +161,5 @@ function pubsubhubbub_init(&$a) {
killme();
}
}
?>

View file

@ -1,5 +1,6 @@
<?php
if(! function_exists('qsearch_init')) {
function qsearch_init(&$a) {
if(! local_user())
@ -47,4 +48,4 @@ function qsearch_init(&$a) {
echo json_encode((object) $results);
killme();
}
}

View file

@ -1,6 +1,6 @@
<?php
if(! function_exists('randprof_init')) {
function randprof_init(&$a) {
require_once('include/Contact.php');
$x = random_profile();
@ -8,3 +8,4 @@ function randprof_init(&$a) {
goaway(zrl($x));
goaway($a->get_baseurl() . '/profile');
}
}

View file

@ -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
}
}

View file

@ -1,5 +1,6 @@
<?php
if(! function_exists('redir_init')) {
function redir_init(&$a) {
$url = ((x($_GET,'url')) ? $_GET['url'] : '');
@ -75,3 +76,4 @@ function redir_init(&$a) {
goaway(z_root());
}
}

View file

@ -3,6 +3,7 @@
require_once('include/enotify.php');
require_once('include/user.php');
if(! function_exists('user_allow')) {
function user_allow($hash) {
$a = get_app();
@ -55,14 +56,14 @@ function user_allow($hash) {
info( t('Account approved.') . EOL );
return true;
}
}
}
// This does not have to go through user_remove() and save the nickname
// permanently against re-registration, as the person was not yet
// allowed to have friends on this system
if(! function_exists('user_deny')) {
function user_deny($hash) {
$register = q("SELECT * FROM `register` WHERE `hash` = '%s' LIMIT 1",
@ -91,9 +92,10 @@ function user_deny($hash) {
);
notice( sprintf(t('Registration revoked for %s'), $user[0]['username']) . EOL);
return true;
}
}
if(! function_exists('regmod_content')) {
function regmod_content(&$a) {
global $lang;
@ -131,3 +133,4 @@ function regmod_content(&$a) {
killme();
}
}
}

View file

@ -1,5 +1,6 @@
<?php
if(! function_exists('removeme_post')) {
function removeme_post(&$a) {
if(! local_user())
@ -24,9 +25,10 @@ function removeme_post(&$a) {
user_remove($a->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;
}
}

View file

@ -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;
}
}

View file

@ -1,7 +1,6 @@
<?php
if(! function_exists('rsd_xml_content')) {
function rsd_xml_content(&$a) {
header ("Content-Type: text/xml");
echo '<?xml version="1.0" encoding="UTF-8"?>
@ -22,3 +21,4 @@ function rsd_xml_content(&$a) {
';
die();
}
}

View file

@ -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');
@ -185,3 +187,4 @@ function salmon_post(&$a) {
http_status_exit(200);
}
}

View file

@ -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;
}
}

View file

@ -1,5 +1,6 @@
<?php
if(! function_exists('session_content')) {
function session_content(&$a) {
}
}

View file

@ -1,6 +1,6 @@
<?php
if(! function_exists('get_theme_config_file')) {
function get_theme_config_file($theme) {
$a = get_app();
$base_theme = $a->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 .= '</form>' . "\r\n";
return $o;
}
}

View file

@ -1,4 +1,6 @@
<?php
if(! function_exists('share_init')) {
function share_init(&$a) {
$post_id = (($a->argc > 1) ? intval($a->argv[1]) : 0);
@ -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("&#x27;", "&#x5B;", "&#x5D;"),$author).
"' profile='".str_replace(array("'", "[", "]"), array("&#x27;", "&#x5B;", "&#x5D;"),$profile).
@ -56,3 +60,4 @@ function share_header($author, $profile, $avatar, $guid, $posted, $link) {
return $header;
}
}

View file

@ -1,3 +1,7 @@
<?php
function smilies_content(&$a) { return smilies('',true); }
if(! function_exists('smilies_content')) {
function smilies_content(&$a) {
return smilies('',true);
}
}

View file

@ -1,6 +1,6 @@
<?php
if(! function_exists('starred_init')) {
function starred_init(&$a) {
require_once("include/threads.php");
@ -47,3 +47,4 @@ function starred_init(&$a) {
echo json_encode($starred);
killme();
}
}

View file

@ -5,6 +5,7 @@
require_once("include/plugin.php");
if(! function_exists('statistics_json_init')) {
function statistics_json_init(&$a) {
if (!get_config("system", "nodeinfo")) {
@ -57,3 +58,4 @@ function statistics_json_init(&$a) {
logger("statistics_init: printed ".print_r($statistics, true), LOGGER_DATA);
killme();
}
}

View file

@ -4,7 +4,7 @@ require_once('include/security.php');
require_once('include/bbcode.php');
require_once('include/items.php');
if(! function_exists('subthread_content')) {
function subthread_content(&$a) {
if(! local_user() && ! remote_user()) {
@ -154,7 +154,5 @@ EOT;
call_hooks('post_local_end', $arr);
killme();
}
}

View file

@ -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");
@ -115,3 +115,4 @@ function suggest_content(&$a) {
return $o;
}
}

View file

@ -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()) {
@ -216,5 +216,5 @@ EOT;
return; // NOTREACHED
}
}

View file

@ -2,6 +2,7 @@
require_once('include/bbcode.php');
if(! function_exists('tagrm_post')) {
function tagrm_post(&$a) {
if(! local_user())
@ -42,11 +43,11 @@ function tagrm_post(&$a) {
goaway($a->get_baseurl() . '/' . $_SESSION['photo_return']);
// NOTREACHED
}
}
if(! function_exists('tagrm_content')) {
function tagrm_content(&$a) {
$o = '';
@ -95,5 +96,5 @@ function tagrm_content(&$a) {
$o .= '</form>';
return $o;
}
}

View file

@ -1,5 +1,6 @@
<?php
if(! function_exists('toggle_mobile_init')) {
function toggle_mobile_init(&$a) {
if(isset($_GET['off']))
@ -14,4 +15,4 @@ function toggle_mobile_init(&$a) {
goaway($address);
}
}

View file

@ -1,5 +1,6 @@
<?php
if(! function_exists('uexport_init')) {
function uexport_init(&$a) {
if(! local_user())
killme();
@ -55,7 +56,9 @@ function uexport_init(&$a){
));
*/
}
}
if(! function_exists('uexport_content')) {
function uexport_content(&$a) {
if ($a->argc > 1) {
@ -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,8 +121,9 @@ function _uexport_row($query) {
}
return $result;
}
}
if(! function_exists('uexport_account')) {
function uexport_account($a) {
$user = _uexport_row(
@ -164,12 +171,13 @@ function uexport_account($a){
//echo "<pre>"; 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);
@ -199,5 +207,5 @@ function uexport_all(&$a) {
$output = array('item' => $r);
echo json_encode($output)."\n";
}
}
}

View file

@ -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:
@ -34,7 +35,9 @@ function uimport_post(&$a) {
return;
}
}
}
if(! function_exists('uimport_content')) {
function uimport_content(&$a) {
if((! local_user()) && ($a->config['register_policy'] == REGISTER_CLOSED)) {
@ -71,3 +74,4 @@ function uimport_content(&$a) {
),
));
}
}

View file

@ -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 "</section>";
echo "</body></html>\r\n";
killme();
}
}

View file

@ -5,6 +5,7 @@
require_once('mod/display.php');
require_once('include/group.php');
if(! function_exists('update_display_content')) {
function update_display_content(&$a) {
$profile_uid = intval($_GET['p']);
@ -34,5 +35,5 @@ function update_display_content(&$a) {
echo "</section>";
echo "</body></html>\r\n";
killme();
}
}

View file

@ -5,6 +5,7 @@
require_once('mod/network.php');
require_once('include/group.php');
if(! function_exists('update_network_content')) {
function update_network_content(&$a) {
$profile_uid = intval($_GET['p']);
@ -37,5 +38,5 @@ function update_network_content(&$a) {
echo "</section>";
echo "</body></html>\r\n";
killme();
}
}

View file

@ -9,6 +9,7 @@
require_once('mod/notes.php');
if(! function_exists('update_notes_content')) {
function update_notes_content(&$a) {
$profile_uid = intval($_GET['p']);
@ -52,5 +53,5 @@ function update_notes_content(&$a) {
echo "</section>";
echo "</body></html>\r\n";
killme();
}
}

View file

@ -9,6 +9,7 @@
require_once('mod/profile.php');
if(! function_exists('update_profile_content')) {
function update_profile_content(&$a) {
$profile_uid = intval($_GET['p']);
@ -56,5 +57,5 @@ function update_profile_content(&$a) {
echo "</section>";
echo "</body></html>\r\n";
killme();
}
}

View file

@ -5,7 +5,7 @@ require_once('include/bbcode.php');
require_once('include/security.php');
require_once('include/redir.php');
if(! function_exists('videos_init')) {
function videos_init(&$a) {
if($a->argc > 1)
@ -102,9 +102,9 @@ function videos_init(&$a) {
return;
}
}
if(! function_exists('videos_post')) {
function videos_post(&$a) {
$owner_uid = $a->data['user']['uid'];
@ -176,11 +176,11 @@ function videos_post(&$a) {
}
goaway($a->get_baseurl() . '/videos/' . $a->data['user']['nickname']);
}
}
if(! function_exists('videos_content')) {
function videos_content(&$a) {
// URLs (most aren't currently implemented):
@ -407,4 +407,4 @@ function videos_content(&$a) {
$o .= paginate($a);
return $o;
}
}

View file

@ -3,6 +3,7 @@
* load view/theme/$current_theme/style.php with friendica contex
*/
if(! function_exists('view_init')) {
function view_init($a) {
header("Content-Type: text/css");
@ -15,3 +16,4 @@ function view_init($a){
killme();
}
}

View file

@ -2,6 +2,7 @@
require_once('include/Contact.php');
require_once('include/contact_selectors.php');
if(! function_exists('viewcontacts_init')) {
function viewcontacts_init(&$a) {
if((get_config('system','block_public')) && (! local_user()) && (! remote_user())) {
@ -26,8 +27,9 @@ function viewcontacts_init(&$a) {
profile_load($a,$a->argv[1]);
}
}
}
if(! function_exists('viewcontacts_content')) {
function viewcontacts_content(&$a) {
require_once("mod/proxy.php");
@ -121,3 +123,4 @@ function viewcontacts_content(&$a) {
return $o;
}
}

View file

@ -1,6 +1,6 @@
<?php
if(! function_exists('viewsrc_content')) {
function viewsrc_content(&$a) {
if(! local_user()) {
@ -33,4 +33,4 @@ function viewsrc_content(&$a) {
}
return $o;
}
}

View file

@ -3,6 +3,7 @@
require_once('include/attach.php');
require_once('include/datetime.php');
if(! function_exists('wall_attach_post')) {
function wall_attach_post(&$a) {
$r_json = (x($_GET,'response') && $_GET['response']=='json');
@ -190,3 +191,4 @@ function wall_attach_post(&$a) {
killme();
// NOTREACHED
}
}

View file

@ -2,6 +2,7 @@
require_once('include/Photo.php');
if(! function_exists('wall_upload_post')) {
function wall_upload_post(&$a, $desktopmode = true) {
logger("wall upload: starting new upload", LOGGER_DEBUG);
@ -297,3 +298,4 @@ function wall_upload_post(&$a, $desktopmode = true) {
killme();
// NOTREACHED
}
}

View file

@ -2,6 +2,7 @@
require_once('include/message.php');
if(! function_exists('wallmessage_post')) {
function wallmessage_post(&$a) {
$replyto = get_my_url();
@ -69,10 +70,10 @@ function wallmessage_post(&$a) {
}
// goaway($a->get_baseurl() . '/profile/' . $user['nickname']);
}
}
if(! function_exists('wallmessage_content')) {
function wallmessage_content(&$a) {
if(! get_my_url()) {
@ -158,3 +159,4 @@ function wallmessage_content(&$a) {
return $o;
}
}

View file

@ -1,7 +1,6 @@
<?php
if(! function_exists('webfinger_content')) {
function webfinger_content(&$a) {
$o .= '<h3>Webfinger Diagnostic</h3>';
@ -24,3 +23,4 @@ function webfinger_content(&$a) {
}
return $o;
}
}

View file

@ -2,6 +2,7 @@
require_once('include/crypto.php');
if(! function_exists('xrd_init')) {
function xrd_init(&$a) {
$uri = urldecode(notags(trim($_GET['uri'])));
@ -77,5 +78,5 @@ function xrd_init(&$a) {
echo $arr['xml'];
killme();
}
}

View file

@ -35,6 +35,11 @@ body, section, blockquote, blockquote.shared_content, #profile-jot-form,
background-color: #171B1F !important;
}
#profile-jot-acl-wrapper, #event-notice, #event-wrapper,
#cboxLoadedContent, .contact-photo-menu {
background-color: #252C33 !important;
}
div.rte, .mceContentBody {
background:none repeat scroll 0 0 #333333!important;
color:#FFF!important;
@ -67,3 +72,31 @@ li :hover {
table.smiley-preview{
background-color: #252C33 !important;
}
/* ACL permission popup */
.acl-list-item.groupshow {
border-color: #9ade00 !important;
}
.acl-list-item.grouphide {
border-color: #ff4141 !important;
}
/* Notifications */
li.notify-unseen {
background-color: #252C33;
}
li.notify-seen {
background-color: #1C2126;
}
.photo-top-album-name {
background-color: #252C33;
}
#panel {
background-color: #252C33;
border: 3px solid #364e59;
color: #989898;
}

View file

@ -24,7 +24,7 @@ nav .nav-notify {
padding: 1px 3px;
border-radius: 5px 5px 5px 5px;
}
// -----
nav .nav-menu-icon .nav-notify {
top: 0px;
}

View file

@ -220,7 +220,7 @@ function vier_community_info() {
//Community_Pages at right_aside
if($show_pages AND local_user()) {
require_once('include/forums.php');
require_once('include/ForumManager.php');
if(x($_GET['cid']) && intval($_GET['cid']) != 0)
$cid = $_GET['cid'];
@ -228,7 +228,7 @@ function vier_community_info() {
//sort by last updated item
$lastitem = true;
$contacts = get_forumlist($a->user['uid'],true,$lastitem, true);
$contacts = ForumManager::get_list($a->user['uid'],true,$lastitem, true);
$total = count($contacts);
$visible_forums = 10;