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

This commit is contained in:
Michael Vogel 2016-08-01 08:04:11 +02:00
commit d8c4fceef8
28 changed files with 1129 additions and 1192 deletions

View file

@ -38,7 +38,7 @@ define ( 'FRIENDICA_PLATFORM', 'Friendica');
define ( 'FRIENDICA_CODENAME', 'Asparagus');
define ( 'FRIENDICA_VERSION', '3.5-dev' );
define ( 'DFRN_PROTOCOL_VERSION', '2.23' );
define ( 'DB_UPDATE_VERSION', 1199 );
define ( 'DB_UPDATE_VERSION', 1200 );
/**
* @brief Constant with a HTML line break.

View file

@ -1,6 +1,6 @@
-- ------------------------------------------
-- Friendica 3.5-dev (Asparagus)
-- DB_UPDATE_VERSION 1199
-- DB_UPDATE_VERSION 1200
-- ------------------------------------------
@ -522,6 +522,7 @@ CREATE TABLE IF NOT EXISTS `item` (
INDEX `uid_title` (`uid`,`title`),
INDEX `uid_thrparent` (`uid`,`thr-parent`),
INDEX `uid_parenturi` (`uid`,`parent-uri`),
INDEX `uid_contactid_id` (`uid`,`contact-id`,`id`),
INDEX `uid_contactid_created` (`uid`,`contact-id`,`created`),
INDEX `gcontactid_uid_created` (`gcontact-id`,`uid`,`created`),
INDEX `authorid_created` (`author-id`,`created`),
@ -532,7 +533,7 @@ CREATE TABLE IF NOT EXISTS `item` (
INDEX `uid_wall_created` (`uid`,`wall`,`created`),
INDEX `resource-id` (`resource-id`),
INDEX `uid_type` (`uid`,`type`),
INDEX `uid_starred` (`uid`,`starred`),
INDEX `uid_starred_id` (`uid`,`starred`,`id`),
INDEX `contactid_allowcid_allowpid_denycid_denygid` (`contact-id`,`allow_cid`(10),`allow_gid`(10),`deny_cid`(10),`deny_gid`(10)),
INDEX `uid_wall_parent_created` (`uid`,`wall`,`parent`,`created`),
INDEX `uid_type_changed` (`uid`,`type`,`changed`),

View file

@ -631,11 +631,11 @@ function posts_from_contact($a, $contact_id) {
$r = q("SELECT `item`.`uri`, `item`.*, `item`.`id` AS `item_id`,
`author-name` AS `name`, `owner-avatar` AS `photo`,
`owner-link` AS `url`, `owner-avatar` AS `thumb`
FROM `item` FORCE INDEX (`uid_contactid_created`)
FROM `item` FORCE INDEX (`uid_contactid_id`)
WHERE `item`.`uid` = %d AND `contact-id` = %d
AND `author-link` IN ('%s', '%s')
AND NOT `deleted` AND NOT `moderated` AND `visible`
ORDER BY `item`.`created` DESC LIMIT %d, %d",
ORDER BY `item`.`id` DESC LIMIT %d, %d",
intval(local_user()),
intval($contact_id),
dbesc(str_replace("https://", "http://", $contact["url"])),

View file

@ -25,6 +25,7 @@
require_once('include/like.php');
require_once('include/NotificationsManager.php');
require_once('include/plaintext.php');
require_once('include/xml.php');
define('API_METHOD_ANY','*');
@ -91,7 +92,7 @@
*
* Register a function to be the endpont for defined API path.
*
* @param string $path API URL path, relative to $a->get_baseurl()
* @param string $path API URL path, relative to App::get_baseurl()
* @param string $func Function name to call on path request
* @param bool $auth API need logged user
* @param string $method
@ -201,8 +202,8 @@
else {
// process normal login request
$r = q("SELECT * FROM `user` WHERE ( `email` = '%s' OR `nickname` = '%s' )
AND `password` = '%s' AND `blocked` = 0 AND `account_expired` = 0 AND `account_removed` = 0 AND `verified` = 1 LIMIT 1",
$r = q("SELECT * FROM `user` WHERE (`email` = '%s' OR `nickname` = '%s')
AND `password` = '%s' AND NOT `blocked` AND NOT `account_expired` AND NOT `account_removed` AND `verified` LIMIT 1",
dbesc(trim($user)),
dbesc(trim($user)),
dbesc($encrypted)
@ -219,7 +220,9 @@
throw new UnauthorizedException("This API requires login");
}
authenticate_success($record); $_SESSION["allow_api"] = true;
authenticate_success($record);
$_SESSION["allow_api"] = true;
call_hooks('logged_in', $a->user);
@ -256,7 +259,6 @@
if (strpos($a->query_string, ".json")>0) $type="json";
if (strpos($a->query_string, ".rss")>0) $type="rss";
if (strpos($a->query_string, ".atom")>0) $type="atom";
if (strpos($a->query_string, ".as")>0) $type="as";
try {
foreach ($API as $p=>$info){
if (strpos($a->query_string, $p)===0){
@ -274,7 +276,7 @@
logger('API parameters: ' . print_r($_REQUEST,true));
$stamp = microtime(true);
$r = call_user_func($info['func'], $a, $type);
$r = call_user_func($info['func'], $type);
$duration = (float)(microtime(true)-$stamp);
logger("API call duration: ".round($duration, 2)."\t".$a->query_string, LOGGER_DEBUG);
@ -286,9 +288,8 @@
switch($type){
case "xml":
$r = mb_convert_encoding($r, "UTF-8",mb_detect_encoding($r));
header ("Content-Type: text/xml");
return '<?xml version="1.0" encoding="UTF-8"?>'."\n".$r;
return $r;
break;
case "json":
header ("Content-Type: application/json");
@ -306,12 +307,6 @@
header ("Content-Type: application/atom+xml");
return '<?xml version="1.0" encoding="UTF-8"?>'."\n".$r;
break;
case "as":
//header ("Content-Type: application/json");
//foreach($r as $rr)
// return json_encode($rr);
return json_encode($r);
break;
}
}
@ -319,42 +314,46 @@
throw new NotImplementedException();
} catch (HTTPException $e) {
header("HTTP/1.1 {$e->httpcode} {$e->httpdesc}");
return api_error($a, $type, $e);
return api_error($type, $e);
}
}
/**
* @brief Format API error string
*
* @param Api $a
* @param string $type Return type (xml, json, rss, as)
* @param HTTPException $error Error object
* @return strin error message formatted as $type
*/
function api_error(&$a, $type, $e) {
function api_error($type, $e) {
$a = get_app();
$error = ($e->getMessage()!==""?$e->getMessage():$e->httpdesc);
# TODO: https://dev.twitter.com/overview/api/response-codes
$xmlstr = "<status><error>{$error}</error><code>{$e->httpcode} {$e->httpdesc}</code><request>{$a->query_string}</request></status>";
$error = array("error" => $error,
"code" => $e->httpcode." ".$e->httpdesc,
"request" => $a->query_string);
$ret = api_format_data('status', $type, array('status' => $error));
switch($type){
case "xml":
header ("Content-Type: text/xml");
return '<?xml version="1.0" encoding="UTF-8"?>'."\n".$xmlstr;
return $ret;
break;
case "json":
header ("Content-Type: application/json");
return json_encode(array(
'error' => $error,
'request' => $a->query_string,
'code' => $e->httpcode." ".$e->httpdesc
));
return json_encode($ret);
break;
case "rss":
header ("Content-Type: application/rss+xml");
return '<?xml version="1.0" encoding="UTF-8"?>'."\n".$xmlstr;
return $ret;
break;
case "atom":
header ("Content-Type: application/atom+xml");
return '<?xml version="1.0" encoding="UTF-8"?>'."\n".$xmlstr;
return $ret;
break;
}
}
@ -372,12 +371,12 @@
$arr['$user'] = $user_info;
$arr['$rss'] = array(
'alternate' => $user_info['url'],
'self' => $a->get_baseurl(). "/". $a->query_string,
'base' => $a->get_baseurl(),
'self' => App::get_baseurl(). "/". $a->query_string,
'base' => App::get_baseurl(),
'updated' => api_date(null),
'atom_updated' => datetime_convert('UTC','UTC','now',ATOM_TIME),
'language' => $user_info['language'],
'logo' => $a->get_baseurl()."/images/friendica-32.png",
'logo' => App::get_baseurl()."/images/friendica-32.png",
);
return $arr;
@ -481,7 +480,7 @@
return False;
} else {
$user = $_SESSION['uid'];
$extra_query = "AND `contact`.`uid` = %d AND `contact`.`self` = 1 ";
$extra_query = "AND `contact`.`uid` = %d AND `contact`.`self` ";
}
}
@ -541,7 +540,7 @@
'notifications' => false,
'statusnet_profile_url' => $r[0]["url"],
'uid' => 0,
'cid' => 0,
'cid' => get_contact($r[0]["url"], api_user()),
'self' => 0,
'network' => $r[0]["network"],
);
@ -553,6 +552,10 @@
}
if($uinfo[0]['self']) {
if ($uinfo[0]['network'] == "")
$uinfo[0]['network'] = NETWORK_DFRN;
$usr = q("select * from user where uid = %d limit 1",
intval(api_user())
);
@ -641,7 +644,7 @@
'verified' => true,
'statusnet_blocking' => false,
'notifications' => false,
//'statusnet_profile_url' => $a->get_baseurl()."/contacts/".$uinfo[0]['cid'],
//'statusnet_profile_url' => App::get_baseurl()."/contacts/".$uinfo[0]['cid'],
'statusnet_profile_url' => $uinfo[0]['url'],
'uid' => intval($uinfo[0]['uid']),
'cid' => intval($uinfo[0]['cid']),
@ -681,40 +684,104 @@
return (array($status_user, $owner_user));
}
/**
* @brief transform $data array in xml without a template
* @brief walks recursively through an array with the possibility to change value and key
*
* @param array $data
* @return string xml string
* @param array $array The array to walk through
* @param string $callback The callback function
*
* @return array the transformed array
*/
function api_array_to_xml($data, $ename="") {
$attrs="";
$childs="";
if (count($data)==1 && !is_array($data[array_keys($data)[0]])) {
$ename = array_keys($data)[0];
$ename = trim($ename,'$');
$v = $data[$ename];
return "<$ename>$v</$ename>";
}
foreach($data as $k=>$v) {
$k=trim($k,'$');
if (!is_array($v)) {
$attrs .= sprintf('%s="%s" ', $k, $v);
function api_walk_recursive(array &$array, callable $callback) {
$new_array = array();
foreach ($array as $k => $v) {
if (is_array($v)) {
if ($callback($v, $k))
$new_array[$k] = api_walk_recursive($v, $callback);
} else {
if (is_numeric($k)) $k=trim($ename,'s');
$childs.=api_array_to_xml($v, $k);
if ($callback($v, $k))
$new_array[$k] = $v;
}
}
$res = $childs;
if ($ename!="") $res = "<$ename $attrs>$res</$ename>";
return $res;
$array = $new_array;
return $array;
}
/**
* load api $templatename for $type and replace $data array
* @brief Callback function to transform the array in an array that can be transformed in a XML file
*
* @param variant $item Array item value
* @param string $key Array key
*
* @return boolean Should the array item be deleted?
*/
function api_apply_template($templatename, $type, $data){
function api_reformat_xml(&$item, &$key) {
if (is_bool($item))
$item = ($item ? "true" : "false");
if (substr($key, 0, 10) == "statusnet_")
$key = "statusnet:".substr($key, 10);
elseif (substr($key, 0, 10) == "friendica_")
$key = "friendica:".substr($key, 10);
//else
// $key = "default:".$key;
return true;
}
/**
* @brief Creates the XML from a JSON style array
*
* @param array $data JSON style array
* @param string $root_element Name of the root element
*
* @return string The XML data
*/
function api_create_xml($data, $root_element) {
$childname = key($data);
$data2 = array_pop($data);
$key = key($data2);
$namespaces = array("" => "http://api.twitter.com",
"statusnet" => "http://status.net/schema/api/1/",
"friendica" => "http://friendi.ca/schema/api/1/",
"georss" => "http://www.georss.org/georss");
/// @todo Auto detection of needed namespaces
if (in_array($root_element, array("ok", "hash", "config", "version", "ids", "notes", "photos")))
$namespaces = array();
if (is_array($data2))
api_walk_recursive($data2, "api_reformat_xml");
if ($key == "0") {
$data4 = array();
$i = 1;
foreach ($data2 AS $item)
$data4[$i++.":".$childname] = $item;
$data2 = $data4;
}
$data3 = array($root_element => $data2);
$ret = xml::from_array($data3, $xml, false, $namespaces);
return $ret;
}
/**
* @brief Formats the data according to the data type
*
* @param string $root_element Name of the root element
* @param string $type Return type (atom, rss, xml, json)
* @param array $data JSON style array
*
* @return (string|object) XML data or JSON data
*/
function api_format_data($root_element, $type, $data){
$a = get_app();
@ -722,18 +789,7 @@
case "atom":
case "rss":
case "xml":
$data = array_xmlify($data);
if ($templatename==="<auto>") {
$ret = api_array_to_xml($data);
} else {
$tpl = get_markup_template("api_".$templatename."_".$type.".tpl");
if(! $tpl) {
header ("Content-Type: text/xml");
echo '<?xml version="1.0" encoding="UTF-8"?>'."\n".'<status><error>not implemented</error></status>';
killme();
}
$ret = replace_macros($tpl, $data);
}
$ret = api_create_xml($data, $root_element);
break;
case "json":
$ret = $data;
@ -752,7 +808,10 @@
* returns a 401 status code and an error message if not.
* http://developer.twitter.com/doc/get/account/verify_credentials
*/
function api_account_verify_credentials(&$a, $type){
function api_account_verify_credentials($type){
$a = get_app();
if (api_user()===false) throw new ForbiddenException();
unset($_REQUEST["user_id"]);
@ -770,7 +829,7 @@
// - Adding last status
if (!$skip_status) {
$user_info["status"] = api_status_show($a,"raw");
$user_info["status"] = api_status_show("raw");
if (!count($user_info["status"]))
unset($user_info["status"]);
else
@ -781,7 +840,7 @@
unset($user_info["uid"]);
unset($user_info["self"]);
return api_apply_template("user", $type, array('$user' => $user_info));
return api_format_data("user", $type, array('user' => $user_info));
}
api_register_func('api/account/verify_credentials','api_account_verify_credentials', true);
@ -801,7 +860,10 @@
}
/*Waitman Gobble Mod*/
function api_statuses_mediap(&$a, $type) {
function api_statuses_mediap($type) {
$a = get_app();
if (api_user()===false) {
logger('api_statuses_update: no user');
throw new ForbiddenException();
@ -834,13 +896,16 @@
item_post($a);
// this should output the last post (the one we just posted).
return api_status_show($a,$type);
return api_status_show($type);
}
api_register_func('api/statuses/mediap','api_statuses_mediap', true, API_METHOD_POST);
/*Waitman Gobble Mod*/
function api_statuses_update(&$a, $type) {
function api_statuses_update($type) {
$a = get_app();
if (api_user()===false) {
logger('api_statuses_update: no user');
throw new ForbiddenException();
@ -905,7 +970,7 @@
if ($posts_day > $throttle_day) {
logger('Daily posting limit reached for user '.api_user(), LOGGER_DEBUG);
#die(api_error($a, $type, sprintf(t("Daily posting limit of %d posts reached. The post was rejected."), $throttle_day)));
#die(api_error($type, sprintf(t("Daily posting limit of %d posts reached. The post was rejected."), $throttle_day)));
throw new TooManyRequestsException(sprintf(t("Daily posting limit of %d posts reached. The post was rejected."), $throttle_day));
}
}
@ -925,7 +990,7 @@
if ($posts_week > $throttle_week) {
logger('Weekly posting limit reached for user '.api_user(), LOGGER_DEBUG);
#die(api_error($a, $type, sprintf(t("Weekly posting limit of %d posts reached. The post was rejected."), $throttle_week)));
#die(api_error($type, sprintf(t("Weekly posting limit of %d posts reached. The post was rejected."), $throttle_week)));
throw new TooManyRequestsException(sprintf(t("Weekly posting limit of %d posts reached. The post was rejected."), $throttle_week));
}
@ -946,7 +1011,7 @@
if ($posts_month > $throttle_month) {
logger('Monthly posting limit reached for user '.api_user(), LOGGER_DEBUG);
#die(api_error($a, $type, sprintf(t("Monthly posting limit of %d posts reached. The post was rejected."), $throttle_month)));
#die(api_error($type, sprintf(t("Monthly posting limit of %d posts reached. The post was rejected."), $throttle_month)));
throw new TooManyRequestsException(sprintf(t("Monthly posting limit of %d posts reached. The post was rejected."), $throttle_month));
}
}
@ -969,8 +1034,8 @@
if ($r) {
$phototypes = Photo::supportedTypes();
$ext = $phototypes[$r[0]['type']];
$_REQUEST['body'] .= "\n\n".'[url='.$a->get_baseurl().'/photos/'.$r[0]['nickname'].'/image/'.$r[0]['resource-id'].']';
$_REQUEST['body'] .= '[img]'.$a->get_baseurl()."/photo/".$r[0]['resource-id']."-".$r[0]['scale'].".".$ext."[/img][/url]";
$_REQUEST['body'] .= "\n\n".'[url='.App::get_baseurl().'/photos/'.$r[0]['nickname'].'/image/'.$r[0]['resource-id'].']';
$_REQUEST['body'] .= '[img]'.App::get_baseurl()."/photo/".$r[0]['resource-id']."-".$r[0]['scale'].".".$ext."[/img][/url]";
}
}
@ -986,13 +1051,16 @@
item_post($a);
// this should output the last post (the one we just posted).
return api_status_show($a,$type);
return api_status_show($type);
}
api_register_func('api/statuses/update','api_statuses_update', true, API_METHOD_POST);
api_register_func('api/statuses/update_with_media','api_statuses_update', true, API_METHOD_POST);
function api_media_upload(&$a, $type) {
function api_media_upload($type) {
$a = get_app();
if (api_user()===false) {
logger('no user');
throw new ForbiddenException();
@ -1025,7 +1093,10 @@
}
api_register_func('api/media/upload','api_media_upload', true, API_METHOD_POST);
function api_status_show(&$a, $type){
function api_status_show($type){
$a = get_app();
$user_info = api_get_user($a);
logger('api_status_show: user_info: '.print_r($user_info, true), LOGGER_DEBUG);
@ -1042,7 +1113,7 @@
AND ((`item`.`author-link` IN ('%s', '%s')) OR (`item`.`owner-link` IN ('%s', '%s')))
AND `i`.`id` = `item`.`parent`
AND `item`.`type`!='activity' $privacy_sql
ORDER BY `item`.`created` DESC
ORDER BY `item`.`id` DESC
LIMIT 1",
intval($user_info['cid']),
intval(api_user()),
@ -1089,6 +1160,11 @@
$converted = api_convert_item($lastwall);
if ($type == "xml")
$geo = "georss:point";
else
$geo = "geo";
$status_info = array(
'created_at' => api_date($lastwall['created']),
'id' => intval($lastwall['id']),
@ -1102,7 +1178,7 @@
'in_reply_to_user_id_str' => $in_reply_to_user_id_str,
'in_reply_to_screen_name' => $in_reply_to_screen_name,
'user' => $user_info,
'geo' => NULL,
$geo => NULL,
'coordinates' => "",
'place' => "",
'contributors' => "",
@ -1138,7 +1214,7 @@
if ($type == "raw")
return($status_info);
return api_apply_template("status", $type, array('$status' => $status_info));
return api_format_data("statuses", $type, array('status' => $status_info));
}
@ -1151,17 +1227,19 @@
* The author's most recent status will be returned inline.
* http://developer.twitter.com/doc/get/users/show
*/
function api_users_show(&$a, $type){
$user_info = api_get_user($a);
function api_users_show($type){
$a = get_app();
$user_info = api_get_user($a);
$lastwall = q("SELECT `item`.*
FROM `item`, `contact`
FROM `item`
INNER JOIN `contact` ON `contact`.`id`=`item`.`contact-id` AND `contact`.`uid` = `item`.`uid`
WHERE `item`.`uid` = %d AND `verb` = '%s' AND `item`.`contact-id` = %d
AND ((`item`.`author-link` IN ('%s', '%s')) OR (`item`.`owner-link` IN ('%s', '%s')))
AND `contact`.`id`=`item`.`contact-id`
AND `type`!='activity'
AND `item`.`allow_cid`='' AND `item`.`allow_gid`='' AND `item`.`deny_cid`='' AND `item`.`deny_gid`=''
ORDER BY `created` DESC
ORDER BY `id` DESC
LIMIT 1",
intval(api_user()),
dbesc(ACTIVITY_POST),
@ -1171,6 +1249,7 @@
dbesc($user_info['url']),
dbesc(normalise_link($user_info['url']))
);
if (count($lastwall)>0){
$lastwall = $lastwall[0];
@ -1200,6 +1279,11 @@
$converted = api_convert_item($lastwall);
if ($type == "xml")
$geo = "georss:point";
else
$geo = "geo";
$user_info['status'] = array(
'text' => $converted["text"],
'truncated' => false,
@ -1212,7 +1296,7 @@
'in_reply_to_user_id' => $in_reply_to_user_id,
'in_reply_to_user_id_str' => $in_reply_to_user_id_str,
'in_reply_to_screen_name' => $in_reply_to_screen_name,
'geo' => NULL,
$geo => NULL,
'favorited' => $lastwall['starred'] ? true : false,
'statusnet_html' => $converted["html"],
'statusnet_conversation_id' => $lastwall['parent'],
@ -1235,13 +1319,16 @@
unset($user_info["uid"]);
unset($user_info["self"]);
return api_apply_template("user", $type, array('$user' => $user_info));
return api_format_data("user", $type, array('user' => $user_info));
}
api_register_func('api/users/show','api_users_show');
function api_users_search(&$a, $type) {
function api_users_search($type) {
$a = get_app();
$page = (x($_REQUEST,'page')?$_REQUEST['page']-1:0);
$userlist = array();
@ -1252,11 +1339,14 @@
$r = q("SELECT `id` FROM `gcontact` WHERE `nick`='%s'", dbesc($_GET["q"]));
if (count($r)) {
$k = 0;
foreach ($r AS $user) {
$user_info = api_get_user($a, $user["id"]);
//echo print_r($user_info, true)."\n";
$userdata = api_apply_template("user", $type, array('user' => $user_info));
$userlist[] = $userdata["user"];
$user_info = api_get_user($a, $user["id"], "json");
if ($type == "xml")
$userlist[$k++.":user"] = $user_info;
else
$userlist[] = $user_info;
}
$userlist = array("users" => $userlist);
} else {
@ -1265,7 +1355,7 @@
} else {
throw new BadRequestException("User not found.");
}
return ($userlist);
return api_format_data("users", $type, $userlist);
}
api_register_func('api/users/search','api_users_search');
@ -1277,7 +1367,10 @@
* TODO: Optional parameters
* TODO: Add reply info
*/
function api_statuses_home_timeline(&$a, $type){
function api_statuses_home_timeline($type){
$a = get_app();
if (api_user()===false) throw new ForbiddenException();
unset($_REQUEST["user_id"]);
@ -1310,15 +1403,15 @@
if ($conversation_id > 0)
$sql_extra .= ' AND `item`.`parent` = '.intval($conversation_id);
$r = q("SELECT STRAIGHT_JOIN `item`.*, `item`.`id` AS `item_id`, `item`.`network` AS `item_network`,
$r = q("SELECT `item`.*, `item`.`id` AS `item_id`, `item`.`network` AS `item_network`,
`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`,
`contact`.`network`, `contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`,
`contact`.`id` AS `cid`
FROM `item`, `contact`
FROM `item`
STRAIGHT_JOIN `contact` ON `contact`.`id` = `item`.`contact-id` AND `contact`.`uid` = `item`.`uid`
AND NOT `contact`.`blocked` AND NOT `contact`.`pending`
WHERE `item`.`uid` = %d AND `verb` = '%s'
AND `item`.`visible` = 1 and `item`.`moderated` = 0 AND `item`.`deleted` = 0
AND `contact`.`id` = `item`.`contact-id`
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
AND `item`.`visible` AND NOT `item`.`moderated` AND NOT `item`.`deleted`
$sql_extra
AND `item`.`id`>%d
ORDER BY `item`.`id` DESC LIMIT %d ,%d ",
@ -1328,7 +1421,7 @@
intval($start), intval($count)
);
$ret = api_format_items($r,$user_info);
$ret = api_format_items($r,$user_info, false, $type);
// Set all posts from the query above to seen
$idarray = array();
@ -1344,26 +1437,23 @@
$r = q("UPDATE `item` SET `unseen` = 0 WHERE `unseen` AND `id` IN (%s)", $idlist);
}
$data = array('$statuses' => $ret);
$data = array('status' => $ret);
switch($type){
case "atom":
case "rss":
$data = api_rss_extra($a, $data, $user_info);
break;
case "as":
$as = api_format_as($a, $ret, $user_info);
$as['title'] = $a->config['sitename']." Home Timeline";
$as['link']['url'] = $a->get_baseurl()."/".$user_info["screen_name"]."/all";
return($as);
break;
}
return api_apply_template("timeline", $type, $data);
return api_format_data("statuses", $type, $data);
}
api_register_func('api/statuses/home_timeline','api_statuses_home_timeline', true);
api_register_func('api/statuses/friends_timeline','api_statuses_home_timeline', true);
function api_statuses_public_timeline(&$a, $type){
function api_statuses_public_timeline($type){
$a = get_app();
if (api_user()===false) throw new ForbiddenException();
$user_info = api_get_user($a);
@ -1394,13 +1484,15 @@
`contact`.`network`, `contact`.`thumb`, `contact`.`self`, `contact`.`writable`,
`contact`.`id` AS `cid`,
`user`.`nickname`, `user`.`hidewall`
FROM `item` STRAIGHT_JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
FROM `item`
STRAIGHT_JOIN `contact` ON `contact`.`id` = `item`.`contact-id` AND `contact`.`uid` = `item`.`uid`
AND NOT `contact`.`blocked` AND NOT `contact`.`pending`
STRAIGHT_JOIN `user` ON `user`.`uid` = `item`.`uid`
WHERE `verb` = '%s' AND `item`.`visible` = 1 AND `item`.`deleted` = 0 and `item`.`moderated` = 0
AND NOT `user`.`hidewall`
WHERE `verb` = '%s' AND `item`.`visible` AND NOT `item`.`deleted` AND NOT `item`.`moderated`
AND `item`.`allow_cid` = '' AND `item`.`allow_gid` = ''
AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = ''
AND `item`.`private` = 0 AND `item`.`wall` = 1 AND `user`.`hidewall` = 0
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
AND NOT `item`.`private` AND `item`.`wall`
$sql_extra
AND `item`.`id`>%d
ORDER BY `item`.`id` DESC LIMIT %d, %d ",
@ -1409,31 +1501,28 @@
intval($start),
intval($count));
$ret = api_format_items($r,$user_info);
$ret = api_format_items($r,$user_info, false, $type);
$data = array('$statuses' => $ret);
$data = array('status' => $ret);
switch($type){
case "atom":
case "rss":
$data = api_rss_extra($a, $data, $user_info);
break;
case "as":
$as = api_format_as($a, $ret, $user_info);
$as['title'] = $a->config['sitename']." Public Timeline";
$as['link']['url'] = $a->get_baseurl()."/";
return($as);
break;
}
return api_apply_template("timeline", $type, $data);
return api_format_data("statuses", $type, $data);
}
api_register_func('api/statuses/public_timeline','api_statuses_public_timeline', true);
/**
*
*/
function api_statuses_show(&$a, $type){
function api_statuses_show($type){
$a = get_app();
if (api_user()===false) throw new ForbiddenException();
$user_info = api_get_user($a);
@ -1454,7 +1543,7 @@
$sql_extra = '';
if ($conversation)
$sql_extra .= " AND `item`.`parent` = %d ORDER BY `received` ASC ";
$sql_extra .= " AND `item`.`parent` = %d ORDER BY `id` ASC ";
else
$sql_extra .= " AND `item`.`id` = %d";
@ -1462,10 +1551,11 @@
`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`,
`contact`.`network`, `contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`,
`contact`.`id` AS `cid`
FROM `item`, `contact`
WHERE `item`.`visible` = 1 and `item`.`moderated` = 0 AND `item`.`deleted` = 0
AND `contact`.`id` = `item`.`contact-id` AND `item`.`uid` = %d AND `item`.`verb` = '%s'
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
FROM `item`
INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id` AND `contact`.`uid` = `item`.`uid`
AND NOT `contact`.`blocked` AND NOT `contact`.`pending`
WHERE `item`.`visible` AND NOT `item`.`moderated` AND NOT `item`.`deleted`
AND `item`.`uid` = %d AND `item`.`verb` = '%s'
$sql_extra",
intval(api_user()),
dbesc(ACTIVITY_POST),
@ -1476,19 +1566,14 @@
throw new BadRequestException("There is no status with this id.");
}
$ret = api_format_items($r,$user_info);
$ret = api_format_items($r,$user_info, false, $type);
if ($conversation) {
$data = array('$statuses' => $ret);
return api_apply_template("timeline", $type, $data);
$data = array('status' => $ret);
return api_format_data("statuses", $type, $data);
} else {
$data = array('$status' => $ret[0]);
/*switch($type){
case "atom":
case "rss":
$data = api_rss_extra($a, $data, $user_info);
}*/
return api_apply_template("status", $type, $data);
$data = array('status' => $ret[0]);
return api_format_data("status", $type, $data);
}
}
api_register_func('api/statuses/show','api_statuses_show', true);
@ -1497,7 +1582,10 @@
/**
*
*/
function api_conversation_show(&$a, $type){
function api_conversation_show($type){
$a = get_app();
if (api_user()===false) throw new ForbiddenException();
$user_info = api_get_user($a);
@ -1540,11 +1628,11 @@
`contact`.`network`, `contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`,
`contact`.`id` AS `cid`
FROM `item`
INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
STRAIGHT_JOIN `contact` ON `contact`.`id` = `item`.`contact-id` AND `contact`.`uid` = `item`.`uid`
AND NOT `contact`.`blocked` AND NOT `contact`.`pending`
WHERE `item`.`parent` = %d AND `item`.`visible`
AND NOT `item`.`moderated` AND NOT `item`.`deleted`
AND `item`.`uid` = %d AND `item`.`verb` = '%s'
AND NOT `contact`.`blocked` AND NOT `contact`.`pending`
AND `item`.`id`>%d $sql_extra
ORDER BY `item`.`id` DESC LIMIT %d ,%d",
intval($id), intval(api_user()),
@ -1556,10 +1644,10 @@
if (!$r)
throw new BadRequestException("There is no conversation with this id.");
$ret = api_format_items($r,$user_info);
$ret = api_format_items($r,$user_info, false, $type);
$data = array('$statuses' => $ret);
return api_apply_template("timeline", $type, $data);
$data = array('status' => $ret);
return api_format_data("statuses", $type, $data);
}
api_register_func('api/conversation/show','api_conversation_show', true);
api_register_func('api/statusnet/conversation','api_conversation_show', true);
@ -1568,9 +1656,11 @@
/**
*
*/
function api_statuses_repeat(&$a, $type){
function api_statuses_repeat($type){
global $called_api;
$a = get_app();
if (api_user()===false) throw new ForbiddenException();
$user_info = api_get_user($a);
@ -1591,10 +1681,10 @@
`contact`.`name`, `contact`.`photo` as `reply_photo`, `contact`.`url` as `reply_url`, `contact`.`rel`,
`contact`.`network`, `contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`,
`contact`.`id` AS `cid`
FROM `item`, `contact`
WHERE `item`.`visible` = 1 and `item`.`moderated` = 0 AND `item`.`deleted` = 0
AND `contact`.`id` = `item`.`contact-id`
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
FROM `item`
INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id` AND `contact`.`uid` = `item`.`uid`
AND NOT `contact`.`blocked` AND NOT `contact`.`pending`
WHERE `item`.`visible` AND NOT `item`.`moderated` AND NOT `item`.`deleted`
AND NOT `item`.`private` AND `item`.`allow_cid` = '' AND `item`.`allow`.`gid` = ''
AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = ''
$sql_extra
@ -1630,14 +1720,17 @@
// this should output the last post (the one we just posted).
$called_api = null;
return(api_status_show($a,$type));
return(api_status_show($type));
}
api_register_func('api/statuses/retweet','api_statuses_repeat', true, API_METHOD_POST);
/**
*
*/
function api_statuses_destroy(&$a, $type){
function api_statuses_destroy($type){
$a = get_app();
if (api_user()===false) throw new ForbiddenException();
$user_info = api_get_user($a);
@ -1654,7 +1747,7 @@
logger('API: api_statuses_destroy: '.$id);
$ret = api_statuses_show($a, $type);
$ret = api_statuses_show($type);
drop_item($id, false);
@ -1667,7 +1760,10 @@
* http://developer.twitter.com/doc/get/statuses/mentions
*
*/
function api_statuses_mentions(&$a, $type){
function api_statuses_mentions($type){
$a = get_app();
if (api_user()===false) throw new ForbiddenException();
unset($_REQUEST["user_id"]);
@ -1691,7 +1787,7 @@
$start = $page*$count;
// Ugly code - should be changed
$myurl = $a->get_baseurl() . '/profile/'. $a->user['nickname'];
$myurl = App::get_baseurl() . '/profile/'. $a->user['nickname'];
$myurl = substr($myurl,strpos($myurl,'://')+3);
//$myurl = str_replace(array('www.','.'),array('','\\.'),$myurl);
$myurl = str_replace('www.','',$myurl);
@ -1704,12 +1800,12 @@
`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`,
`contact`.`network`, `contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`,
`contact`.`id` AS `cid`
FROM `item` FORCE INDEX (`uid_id`), `contact`
FROM `item` FORCE INDEX (`uid_id`)
STRAIGHT_JOIN `contact` ON `contact`.`id` = `item`.`contact-id` AND `contact`.`uid` = `item`.`uid`
AND NOT `contact`.`blocked` AND NOT `contact`.`pending`
WHERE `item`.`uid` = %d AND `verb` = '%s'
AND NOT (`item`.`author-link` IN ('https://%s', 'http://%s'))
AND `item`.`visible` AND NOT `item`.`moderated` AND NOT `item`.`deleted`
AND `contact`.`id` = `item`.`contact-id`
AND NOT `contact`.`blocked` AND NOT `contact`.`pending`
AND `item`.`parent` IN (SELECT `iid` FROM `thread` WHERE `uid` = %d AND `mention` AND !`ignored`)
$sql_extra
AND `item`.`id`>%d
@ -1723,30 +1819,27 @@
intval($start), intval($count)
);
$ret = api_format_items($r,$user_info);
$ret = api_format_items($r,$user_info, false, $type);
$data = array('$statuses' => $ret);
$data = array('status' => $ret);
switch($type){
case "atom":
case "rss":
$data = api_rss_extra($a, $data, $user_info);
break;
case "as":
$as = api_format_as($a, $ret, $user_info);
$as["title"] = $a->config['sitename']." Mentions";
$as['link']['url'] = $a->get_baseurl()."/";
return($as);
break;
}
return api_apply_template("timeline", $type, $data);
return api_format_data("statuses", $type, $data);
}
api_register_func('api/statuses/mentions','api_statuses_mentions', true);
api_register_func('api/statuses/replies','api_statuses_mentions', true);
function api_statuses_user_timeline(&$a, $type){
function api_statuses_user_timeline($type){
$a = get_app();
if (api_user()===false) throw new ForbiddenException();
$user_info = api_get_user($a);
@ -1781,12 +1874,12 @@
`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`,
`contact`.`network`, `contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`,
`contact`.`id` AS `cid`
FROM `item`, `contact`
FROM `item` FORCE INDEX (`uid_contactid_id`)
STRAIGHT_JOIN `contact` ON `contact`.`id` = `item`.`contact-id` AND `contact`.`uid` = `item`.`uid`
AND NOT `contact`.`blocked` AND NOT `contact`.`pending`
WHERE `item`.`uid` = %d AND `verb` = '%s'
AND `item`.`contact-id` = %d
AND `item`.`visible` = 1 and `item`.`moderated` = 0 AND `item`.`deleted` = 0
AND `contact`.`id` = `item`.`contact-id`
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
AND `item`.`visible` AND NOT `item`.`moderated` AND NOT `item`.`deleted`
$sql_extra
AND `item`.`id`>%d
ORDER BY `item`.`id` DESC LIMIT %d ,%d ",
@ -1797,16 +1890,16 @@
intval($start), intval($count)
);
$ret = api_format_items($r,$user_info, true);
$ret = api_format_items($r,$user_info, true, $type);
$data = array('$statuses' => $ret);
$data = array('status' => $ret);
switch($type){
case "atom":
case "rss":
$data = api_rss_extra($a, $data, $user_info);
}
return api_apply_template("timeline", $type, $data);
return api_format_data("statuses", $type, $data);
}
api_register_func('api/statuses/user_timeline','api_statuses_user_timeline', true);
@ -1817,7 +1910,10 @@
*
* api v1 : https://web.archive.org/web/20131019055350/https://dev.twitter.com/docs/api/1/post/favorites/create/%3Aid
*/
function api_favorites_create_destroy(&$a, $type){
function api_favorites_create_destroy($type){
$a = get_app();
if (api_user()===false) throw new ForbiddenException();
// for versioned api.
@ -1860,24 +1956,26 @@
$user_info = api_get_user($a);
$rets = api_format_items($item,$user_info);
$rets = api_format_items($item, $user_info, false, $type);
$ret = $rets[0];
$data = array('$status' => $ret);
$data = array('status' => $ret);
switch($type){
case "atom":
case "rss":
$data = api_rss_extra($a, $data, $user_info);
}
return api_apply_template("status", $type, $data);
return api_format_data("status", $type, $data);
}
api_register_func('api/favorites/create', 'api_favorites_create_destroy', true, API_METHOD_POST);
api_register_func('api/favorites/destroy', 'api_favorites_create_destroy', true, API_METHOD_DELETE);
function api_favorites(&$a, $type){
function api_favorites($type){
global $called_api;
$a = get_app();
if (api_user()===false) throw new ForbiddenException();
$called_api= array();
@ -1923,88 +2021,21 @@
intval($start), intval($count)
);
$ret = api_format_items($r,$user_info);
$ret = api_format_items($r,$user_info, false, $type);
}
$data = array('$statuses' => $ret);
$data = array('status' => $ret);
switch($type){
case "atom":
case "rss":
$data = api_rss_extra($a, $data, $user_info);
}
return api_apply_template("timeline", $type, $data);
return api_format_data("statuses", $type, $data);
}
api_register_func('api/favorites','api_favorites', true);
function api_format_as($a, $ret, $user_info) {
$as = array();
$as['title'] = $a->config['sitename']." Public Timeline";
$items = array();
foreach ($ret as $item) {
$singleitem["actor"]["displayName"] = $item["user"]["name"];
$singleitem["actor"]["id"] = $item["user"]["contact_url"];
$avatar[0]["url"] = $item["user"]["profile_image_url"];
$avatar[0]["rel"] = "avatar";
$avatar[0]["type"] = "";
$avatar[0]["width"] = 96;
$avatar[0]["height"] = 96;
$avatar[1]["url"] = $item["user"]["profile_image_url"];
$avatar[1]["rel"] = "avatar";
$avatar[1]["type"] = "";
$avatar[1]["width"] = 48;
$avatar[1]["height"] = 48;
$avatar[2]["url"] = $item["user"]["profile_image_url"];
$avatar[2]["rel"] = "avatar";
$avatar[2]["type"] = "";
$avatar[2]["width"] = 24;
$avatar[2]["height"] = 24;
$singleitem["actor"]["avatarLinks"] = $avatar;
$singleitem["actor"]["image"]["url"] = $item["user"]["profile_image_url"];
$singleitem["actor"]["image"]["rel"] = "avatar";
$singleitem["actor"]["image"]["type"] = "";
$singleitem["actor"]["image"]["width"] = 96;
$singleitem["actor"]["image"]["height"] = 96;
$singleitem["actor"]["type"] = "person";
$singleitem["actor"]["url"] = $item["person"]["contact_url"];
$singleitem["actor"]["statusnet:profile_info"]["local_id"] = $item["user"]["id"];
$singleitem["actor"]["statusnet:profile_info"]["following"] = $item["user"]["following"] ? "true" : "false";
$singleitem["actor"]["statusnet:profile_info"]["blocking"] = "false";
$singleitem["actor"]["contact"]["preferredUsername"] = $item["user"]["screen_name"];
$singleitem["actor"]["contact"]["displayName"] = $item["user"]["name"];
$singleitem["actor"]["contact"]["addresses"] = "";
$singleitem["body"] = $item["text"];
$singleitem["object"]["displayName"] = $item["text"];
$singleitem["object"]["id"] = $item["url"];
$singleitem["object"]["type"] = "note";
$singleitem["object"]["url"] = $item["url"];
//$singleitem["context"] =;
$singleitem["postedTime"] = date("c", strtotime($item["published"]));
$singleitem["provider"]["objectType"] = "service";
$singleitem["provider"]["displayName"] = "Test";
$singleitem["provider"]["url"] = "http://test.tld";
$singleitem["title"] = $item["text"];
$singleitem["verb"] = "post";
$singleitem["statusnet:notice_info"]["local_id"] = $item["id"];
$singleitem["statusnet:notice_info"]["source"] = $item["source"];
$singleitem["statusnet:notice_info"]["favorite"] = "false";
$singleitem["statusnet:notice_info"]["repeated"] = "false";
//$singleitem["original"] = $item;
$items[] = $singleitem;
}
$as['items'] = $items;
$as['link']['url'] = $a->get_baseurl()."/".$user_info["screen_name"]."/all";
$as['link']['rel'] = "alternate";
$as['link']['type'] = "text/html";
return($as);
}
function api_format_messages($item, $recipient, $sender) {
// standard meta information
$ret=Array(
@ -2275,11 +2306,10 @@
return($entities);
}
function api_format_items_embeded_images(&$item, $text){
$a = get_app();
$text = preg_replace_callback(
"|data:image/([^;]+)[^=]+=*|m",
function($match) use ($a, $item) {
return $a->get_baseurl()."/display/".$item['guid'];
function($match) use ($item) {
return App::get_baseurl()."/display/".$item['guid'];
},
$text);
return $text;
@ -2320,7 +2350,7 @@
* likes => int count
* dislikes => int count
*/
function api_format_items_activities(&$item) {
function api_format_items_activities(&$item, $type = "json") {
$activities = array(
'like' => array(),
'dislike' => array(),
@ -2336,6 +2366,14 @@
builtin_activity_puller($i, $activities);
}
if ($type == "xml") {
$xml_activities = array();
foreach ($activities as $k => $v)
$xml_activities["friendica:".$k] = $v;
$activities = $xml_activities;
}
$res = array();
$uri = $item['uri']."-l";
foreach($activities as $k => $v) {
@ -2352,9 +2390,10 @@
* @param array $user_info
* @param bool $filter_user filter items by $user_info
*/
function api_format_items($r,$user_info, $filter_user = false) {
function api_format_items($r,$user_info, $filter_user = false, $type = "json") {
$a = get_app();
$ret = Array();
foreach($r as $item) {
@ -2406,6 +2445,11 @@
$converted = api_convert_item($item);
if ($type == "xml")
$geo = "georss:point";
else
$geo = "geo";
$status = array(
'text' => $converted["text"],
'truncated' => False,
@ -2418,14 +2462,14 @@
'in_reply_to_user_id' => $in_reply_to_user_id,
'in_reply_to_user_id_str' => $in_reply_to_user_id_str,
'in_reply_to_screen_name' => $in_reply_to_screen_name,
'geo' => NULL,
$geo => NULL,
'favorited' => $item['starred'] ? true : false,
'user' => $status_user ,
'friendica_owner' => $owner_user,
//'entities' => NULL,
'statusnet_html' => $converted["html"],
'statusnet_conversation_id' => $item['parent'],
'friendica_activities' => api_format_items_activities($item),
'friendica_activities' => api_format_items_activities($item, $type),
);
if (count($converted["attachments"]) > 0)
@ -2463,7 +2507,7 @@
$retweeted_status['text'] = $rt_converted["text"];
$retweeted_status['statusnet_html'] = $rt_converted["html"];
$retweeted_status['friendica_activities'] = api_format_items_activities($retweeted_item);
$retweeted_status['friendica_activities'] = api_format_items_activities($retweeted_item, $type);
$retweeted_status['created_at'] = api_date($retweeted_item['created']);
$status['retweeted_status'] = $retweeted_status;
}
@ -2476,51 +2520,64 @@
if ($item["coord"] != "") {
$coords = explode(' ',$item["coord"]);
if (count($coords) == 2) {
$status["geo"] = array('type' => 'Point',
'coordinates' => array((float) $coords[0],
(float) $coords[1]));
if ($type == "json")
$status["geo"] = array('type' => 'Point',
'coordinates' => array((float) $coords[0],
(float) $coords[1]));
else // Not sure if this is the official format - if someone founds a documentation we can check
$status["georss:point"] = $item["coord"];
}
}
$ret[] = $status;
};
return $ret;
}
function api_account_rate_limit_status(&$a,$type) {
$hash = array(
'reset_time_in_seconds' => strtotime('now + 1 hour'),
'remaining_hits' => (string) 150,
'hourly_limit' => (string) 150,
'reset_time' => api_date(datetime_convert('UTC','UTC','now + 1 hour',ATOM_TIME)),
);
if ($type == "xml")
$hash['resettime_in_seconds'] = $hash['reset_time_in_seconds'];
function api_account_rate_limit_status($type) {
return api_apply_template('ratelimit', $type, array('$hash' => $hash));
if ($type == "xml")
$hash = array(
'remaining-hits' => (string) 150,
'@attributes' => array("type" => "integer"),
'hourly-limit' => (string) 150,
'@attributes2' => array("type" => "integer"),
'reset-time' => datetime_convert('UTC','UTC','now + 1 hour',ATOM_TIME),
'@attributes3' => array("type" => "datetime"),
'reset_time_in_seconds' => strtotime('now + 1 hour'),
'@attributes4' => array("type" => "integer"),
);
else
$hash = array(
'reset_time_in_seconds' => strtotime('now + 1 hour'),
'remaining_hits' => (string) 150,
'hourly_limit' => (string) 150,
'reset_time' => api_date(datetime_convert('UTC','UTC','now + 1 hour',ATOM_TIME)),
);
return api_format_data('hash', $type, array('hash' => $hash));
}
api_register_func('api/account/rate_limit_status','api_account_rate_limit_status',true);
function api_help_test(&$a,$type) {
function api_help_test($type) {
if ($type == 'xml')
$ok = "true";
else
$ok = "ok";
return api_apply_template('test', $type, array("$ok" => $ok));
return api_format_data('ok', $type, array("ok" => $ok));
}
api_register_func('api/help/test','api_help_test',false);
function api_lists(&$a,$type) {
function api_lists($type) {
$ret = array();
return array($ret);
return api_format_data('lists', $type, array("lists_list" => $ret));
}
api_register_func('api/lists','api_lists',true);
function api_lists_list(&$a,$type) {
function api_lists_list($type) {
$ret = array();
return array($ret);
return api_format_data('lists', $type, array("lists_list" => $ret));
}
api_register_func('api/lists/list','api_lists_list',true);
@ -2529,7 +2586,10 @@
* This function is deprecated by Twitter
* returns: json, xml
**/
function api_statuses_f(&$a, $type, $qtype) {
function api_statuses_f($type, $qtype) {
$a = get_app();
if (api_user()===false) throw new ForbiddenException();
$user_info = api_get_user($a);
@ -2568,18 +2628,18 @@
$ret[] = $user;
}
return array('$users' => $ret);
return array('user' => $ret);
}
function api_statuses_friends(&$a, $type){
$data = api_statuses_f($a,$type,"friends");
function api_statuses_friends($type){
$data = api_statuses_f($type, "friends");
if ($data===false) return false;
return api_apply_template("friends", $type, $data);
return api_format_data("users", $type, $data);
}
function api_statuses_followers(&$a, $type){
$data = api_statuses_f($a,$type,"followers");
function api_statuses_followers($type){
$data = api_statuses_f($type, "followers");
if ($data===false) return false;
return api_apply_template("friends", $type, $data);
return api_format_data("users", $type, $data);
}
api_register_func('api/statuses/friends','api_statuses_friends',true);
api_register_func('api/statuses/followers','api_statuses_followers',true);
@ -2589,10 +2649,13 @@
function api_statusnet_config(&$a,$type) {
function api_statusnet_config($type) {
$a = get_app();
$name = $a->config['sitename'];
$server = $a->get_hostname();
$logo = $a->get_baseurl() . '/images/friendica-64.png';
$logo = App::get_baseurl() . '/images/friendica-64.png';
$email = $a->config['admin_email'];
$closed = (($a->config['register_policy'] == REGISTER_CLOSED) ? 'true' : 'false');
$private = (($a->config['system']['block_public']) ? 'true' : 'false');
@ -2600,7 +2663,7 @@
if($a->config['api_import_size'])
$texlimit = string($a->config['api_import_size']);
$ssl = (($a->config['system']['have_ssl']) ? 'true' : 'false');
$sslserver = (($ssl === 'true') ? str_replace('http:','https:',$a->get_baseurl()) : '');
$sslserver = (($ssl === 'true') ? str_replace('http:','https:',App::get_baseurl()) : '');
$config = array(
'site' => array('name' => $name,'server' => $server, 'theme' => 'default', 'path' => '',
@ -2617,32 +2680,26 @@
),
);
return api_apply_template('config', $type, array('$config' => $config));
return api_format_data('config', $type, array('config' => $config));
}
api_register_func('api/statusnet/config','api_statusnet_config',false);
function api_statusnet_version(&$a,$type) {
function api_statusnet_version($type) {
// liar
$fake_statusnet_version = "0.9.7";
if($type === 'xml') {
header("Content-type: application/xml");
echo '<?xml version="1.0" encoding="UTF-8"?>' . "\r\n" . '<version>'.$fake_statusnet_version.'</version>' . "\r\n";
killme();
}
elseif($type === 'json') {
header("Content-type: application/json");
echo '"'.$fake_statusnet_version.'"';
killme();
}
return api_format_data('version', $type, array('version' => $fake_statusnet_version));
}
api_register_func('api/statusnet/version','api_statusnet_version',false);
/**
* @todo use api_apply_template() to return data
* @todo use api_format_data() to return data
*/
function api_ff_ids(&$a,$type,$qtype) {
function api_ff_ids($type,$qtype) {
$a = get_app();
if(! api_user()) throw new ForbiddenException();
$user_info = api_get_user($a);
@ -2661,42 +2718,33 @@
intval(api_user())
);
if(is_array($r)) {
if(!dbm::is_result($r))
return;
if($type === 'xml') {
header("Content-type: application/xml");
echo '<?xml version="1.0" encoding="UTF-8"?>' . "\r\n" . '<ids>' . "\r\n";
foreach($r as $rr)
echo '<id>' . $rr['id'] . '</id>' . "\r\n";
echo '</ids>' . "\r\n";
killme();
}
elseif($type === 'json') {
$ret = array();
header("Content-type: application/json");
foreach($r as $rr)
if ($stringify_ids)
$ret[] = $rr['id'];
else
$ret[] = intval($rr['id']);
$ids = array();
foreach($r as $rr)
if ($stringify_ids)
$ids[] = $rr['id'];
else
$ids[] = intval($rr['id']);
echo json_encode($ret);
killme();
}
}
return api_format_data("ids", $type, array('id' => $ids));
}
function api_friends_ids(&$a,$type) {
api_ff_ids($a,$type,'friends');
function api_friends_ids($type) {
return api_ff_ids($type,'friends');
}
function api_followers_ids(&$a,$type) {
api_ff_ids($a,$type,'followers');
function api_followers_ids($type) {
return api_ff_ids($type,'followers');
}
api_register_func('api/friends/ids','api_friends_ids',true);
api_register_func('api/followers/ids','api_followers_ids',true);
function api_direct_messages_new(&$a, $type) {
function api_direct_messages_new($type) {
$a = get_app();
if (api_user()===false) throw new ForbiddenException();
if (!x($_POST, "text") OR (!x($_POST,"screen_name") AND !x($_POST,"user_id"))) return;
@ -2743,7 +2791,7 @@
$ret = array("error"=>$id);
}
$data = Array('$messages'=>$ret);
$data = Array('direct_message'=>$ret);
switch($type){
case "atom":
@ -2751,12 +2799,15 @@
$data = api_rss_extra($a, $data, $user_info);
}
return api_apply_template("direct_messages", $type, $data);
return api_format_data("direct-messages", $type, $data);
}
api_register_func('api/direct_messages/new','api_direct_messages_new',true, API_METHOD_POST);
function api_direct_messages_box(&$a, $type, $box) {
function api_direct_messages_box($type, $box) {
$a = get_app();
if (api_user()===false) throw new ForbiddenException();
// params
@ -2778,7 +2829,6 @@
unset($_GET["screen_name"]);
$user_info = api_get_user($a);
//$profile_url = $a->get_baseurl() . '/profile/' . $a->user['nickname'];
$profile_url = $user_info["url"];
@ -2831,28 +2881,28 @@
}
$data = array('$messages' => $ret);
$data = array('direct_message' => $ret);
switch($type){
case "atom":
case "rss":
$data = api_rss_extra($a, $data, $user_info);
}
return api_apply_template("direct_messages", $type, $data);
return api_format_data("direct-messages", $type, $data);
}
function api_direct_messages_sentbox(&$a, $type){
return api_direct_messages_box($a, $type, "sentbox");
function api_direct_messages_sentbox($type){
return api_direct_messages_box($type, "sentbox");
}
function api_direct_messages_inbox(&$a, $type){
return api_direct_messages_box($a, $type, "inbox");
function api_direct_messages_inbox($type){
return api_direct_messages_box($type, "inbox");
}
function api_direct_messages_all(&$a, $type){
return api_direct_messages_box($a, $type, "all");
function api_direct_messages_all($type){
return api_direct_messages_box($type, "all");
}
function api_direct_messages_conversation(&$a, $type){
return api_direct_messages_box($a, $type, "conversation");
function api_direct_messages_conversation($type){
return api_direct_messages_box($type, "conversation");
}
api_register_func('api/direct_messages/conversation','api_direct_messages_conversation',true);
api_register_func('api/direct_messages/all','api_direct_messages_all',true);
@ -2861,7 +2911,7 @@
function api_oauth_request_token(&$a, $type){
function api_oauth_request_token($type){
try{
$oauth = new FKOAuth1();
$r = $oauth->fetch_request_token(OAuthRequest::from_request());
@ -2871,7 +2921,7 @@
echo $r;
killme();
}
function api_oauth_access_token(&$a, $type){
function api_oauth_access_token($type){
try{
$oauth = new FKOAuth1();
$r = $oauth->fetch_access_token(OAuthRequest::from_request());
@ -2886,7 +2936,7 @@
api_register_func('api/oauth/access_token', 'api_oauth_access_token', false);
function api_fr_photos_list(&$a,$type) {
function api_fr_photos_list($type) {
if (api_user()===false) throw new ForbiddenException();
$r = q("select `resource-id`, max(scale) as scale, album, filename, type from photo
where uid = %d and album != 'Contact Photos' group by `resource-id`",
@ -2897,7 +2947,7 @@
'image/png' => 'png',
'image/gif' => 'gif'
);
$data = array('photos'=>array());
$data = array('photo'=>array());
if($r) {
foreach($r as $rr) {
$photo = array();
@ -2905,14 +2955,20 @@
$photo['album'] = $rr['album'];
$photo['filename'] = $rr['filename'];
$photo['type'] = $rr['type'];
$photo['thumb'] = $a->get_baseurl()."/photo/".$rr['resource-id']."-".$rr['scale'].".".$typetoext[$rr['type']];
$data['photos'][] = $photo;
$thumb = App::get_baseurl()."/photo/".$rr['resource-id']."-".$rr['scale'].".".$typetoext[$rr['type']];
if ($type == "xml")
$data['photo'][] = array("@attributes" => $photo, "1" => $thumb);
else {
$photo['thumb'] = $thumb;
$data['photo'][] = $photo;
}
}
}
return api_apply_template("photos_list", $type, $data);
return api_format_data("photos", $type, $data);
}
function api_fr_photo_detail(&$a,$type) {
function api_fr_photo_detail($type) {
if (api_user()===false) throw new ForbiddenException();
if(!x($_REQUEST,'photo_id')) throw new BadRequestException("No photo id.");
@ -2937,16 +2993,24 @@
if ($r) {
$data = array('photo' => $r[0]);
$data['photo']['id'] = $data['photo']['resource-id'];
if ($scale !== false) {
$data['photo']['data'] = base64_encode($data['photo']['data']);
} else {
unset($data['photo']['datasize']); //needed only with scale param
}
$data['photo']['link'] = array();
for($k=intval($data['photo']['minscale']); $k<=intval($data['photo']['maxscale']); $k++) {
$data['photo']['link'][$k] = $a->get_baseurl()."/photo/".$data['photo']['resource-id']."-".$k.".".$typetoext[$data['photo']['type']];
if ($type == "xml") {
$data['photo']['links'] = array();
for ($k=intval($data['photo']['minscale']); $k<=intval($data['photo']['maxscale']); $k++)
$data['photo']['links'][$k.":link"]["@attributes"] = array("type" => $data['photo']['type'],
"scale" => $k,
"href" => App::get_baseurl()."/photo/".$data['photo']['resource-id']."-".$k.".".$typetoext[$data['photo']['type']]);
} else {
$data['photo']['link'] = array();
for ($k=intval($data['photo']['minscale']); $k<=intval($data['photo']['maxscale']); $k++) {
$data['photo']['link'][$k] = App::get_baseurl()."/photo/".$data['photo']['resource-id']."-".$k.".".$typetoext[$data['photo']['type']];
}
}
$data['photo']['id'] = $data['photo']['resource-id'];
unset($data['photo']['resource-id']);
unset($data['photo']['minscale']);
unset($data['photo']['maxscale']);
@ -2955,7 +3019,7 @@
throw new NotFoundException();
}
return api_apply_template("photo_detail", $type, $data);
return api_format_data("photo_detail", $type, $data);
}
api_register_func('api/friendica/photos/list', 'api_fr_photos_list', true);
@ -2974,7 +3038,7 @@
* c_url: url of remote contact to auth to
* url: string, url to redirect after auth
*/
function api_friendica_remoteauth(&$a) {
function api_friendica_remoteauth() {
$url = ((x($_GET,'url')) ? $_GET['url'] : '');
$c_url = ((x($_GET,'c_url')) ? $_GET['c_url'] : '');
@ -3271,7 +3335,10 @@
}
// return all or a specified group of the user with the containing contacts
function api_friendica_group_show(&$a, $type) {
function api_friendica_group_show($type) {
$a = get_app();
if (api_user()===false) throw new ForbiddenException();
// params
@ -3296,19 +3363,33 @@
foreach ($r as $rr) {
$members = group_get_members($rr['id']);
$users = array();
foreach ($members as $member) {
$user = api_get_user($a, $member['nurl']);
$users[] = $user;
if ($type == "xml") {
$user_element = "users";
$k = 0;
foreach ($members as $member) {
$user = api_get_user($a, $member['nurl']);
$users[$k++.":user"] = $user;
}
} else {
$user_element = "user";
foreach ($members as $member) {
$user = api_get_user($a, $member['nurl']);
$users[] = $user;
}
}
$grps[] = array('name' => $rr['name'], 'gid' => $rr['id'], 'user' => $users);
$grps[] = array('name' => $rr['name'], 'gid' => $rr['id'], $user_element => $users);
}
return api_apply_template("group_show", $type, array('$groups' => $grps));
return api_format_data("groups", $type, array('group' => $grps));
}
api_register_func('api/friendica/group_show', 'api_friendica_group_show', true);
// delete the specified group of the user
function api_friendica_group_delete(&$a, $type) {
function api_friendica_group_delete($type) {
$a = get_app();
if (api_user()===false) throw new ForbiddenException();
// params
@ -3343,7 +3424,7 @@
if ($ret) {
// return success
$success = array('success' => $ret, 'gid' => $gid, 'name' => $name, 'status' => 'deleted', 'wrong users' => array());
return api_apply_template("group_delete", $type, array('$result' => $success));
return api_format_data("group_delete", $type, array('result' => $success));
}
else
throw new BadRequestException('other API error');
@ -3352,7 +3433,10 @@
// create the specified group with the posted array of contacts
function api_friendica_group_create(&$a, $type) {
function api_friendica_group_create($type) {
$a = get_app();
if (api_user()===false) throw new ForbiddenException();
// params
@ -3409,13 +3493,16 @@
// return success message incl. missing users in array
$status = ($erroraddinguser ? "missing user" : ($reactivate_group ? "reactivated" : "ok"));
$success = array('success' => true, 'gid' => $gid, 'name' => $name, 'status' => $status, 'wrong users' => $errorusers);
return api_apply_template("group_create", $type, array('result' => $success));
return api_format_data("group_create", $type, array('result' => $success));
}
api_register_func('api/friendica/group_create', 'api_friendica_group_create', true, API_METHOD_POST);
// update the specified group with the posted array of contacts
function api_friendica_group_update(&$a, $type) {
function api_friendica_group_update($type) {
$a = get_app();
if (api_user()===false) throw new ForbiddenException();
// params
@ -3466,12 +3553,15 @@
// return success message incl. missing users in array
$status = ($erroraddinguser ? "missing user" : "ok");
$success = array('success' => true, 'gid' => $gid, 'name' => $name, 'status' => $status, 'wrong users' => $errorusers);
return api_apply_template("group_update", $type, array('result' => $success));
return api_format_data("group_update", $type, array('result' => $success));
}
api_register_func('api/friendica/group_update', 'api_friendica_group_update', true, API_METHOD_POST);
function api_friendica_activity(&$a, $type) {
function api_friendica_activity($type) {
$a = get_app();
if (api_user()===false) throw new ForbiddenException();
$verb = strtolower($a->argv[3]);
$verb = preg_replace("|\..*$|", "", $verb);
@ -3481,11 +3571,11 @@
$res = do_like($id, $verb);
if ($res) {
if ($type == 'xml')
if ($type == "xml")
$ok = "true";
else
$ok = "ok";
return api_apply_template('test', $type, array('ok' => $ok));
return api_format_data('ok', $type, array('ok' => $ok));
} else {
throw new BadRequestException('Error adding activity');
}
@ -3505,17 +3595,28 @@
/**
* @brief Returns notifications
*
* @param App $a
* @param string $type Known types are 'atom', 'rss', 'xml' and 'json'
* @return string
*/
function api_friendica_notification(&$a, $type) {
function api_friendica_notification($type) {
$a = get_app();
if (api_user()===false) throw new ForbiddenException();
if ($a->argc!==3) throw new BadRequestException("Invalid argument count");
$nm = new NotificationsManager();
$notes = $nm->getAll(array(), "+seen -date", 50);
return api_apply_template("<auto>", $type, array('$notes' => $notes));
if ($type == "xml") {
$xmlnotes = array();
foreach ($notes AS $note)
$xmlnotes[] = array("@attributes" => $note);
$notes = $xmlnotes;
}
return api_format_data("notes", $type, array('note' => $notes));
}
/**
@ -3523,11 +3624,13 @@
*
* POST request with 'id' param as notification id
*
* @param App $a
* @param string $type Known types are 'atom', 'rss', 'xml' and 'json'
* @return string
*/
function api_friendica_notification_seen(&$a, $type){
function api_friendica_notification_seen($type){
$a = get_app();
if (api_user()===false) throw new ForbiddenException();
if ($a->argc!==4) throw new BadRequestException("Invalid argument count");
@ -3547,13 +3650,13 @@
if ($r!==false) {
// we found the item, return it to the user
$user_info = api_get_user($a);
$ret = api_format_items($r,$user_info);
$data = array('$statuses' => $ret);
return api_apply_template("timeline", $type, $data);
$ret = api_format_items($r,$user_info, false, $type);
$data = array('status' => $ret);
return api_format_data("status", $type, $data);
}
// the item can't be found, but we set the note as seen, so we count this as a success
}
return api_apply_template('<auto>', $type, array('status' => "success"));
return api_format_data('result', $type, array('result' => "success"));
}
api_register_func('api/friendica/notification/seen', 'api_friendica_notification_seen', true, API_METHOD_POST);

View file

@ -858,6 +858,7 @@ function db_definition() {
"uid_title" => array("uid","title"),
"uid_thrparent" => array("uid","thr-parent"),
"uid_parenturi" => array("uid","parent-uri"),
"uid_contactid_id" => array("uid","contact-id","id"),
"uid_contactid_created" => array("uid","contact-id","created"),
"gcontactid_uid_created" => array("gcontact-id","uid","created"),
"authorid_created" => array("author-id","created"),
@ -868,7 +869,7 @@ function db_definition() {
"uid_wall_created" => array("uid","wall","created"),
"resource-id" => array("resource-id"),
"uid_type" => array("uid","type"),
"uid_starred" => array("uid","starred"),
"uid_starred_id" => array("uid","starred", "id"),
"contactid_allowcid_allowpid_denycid_denygid" => array("contact-id","allow_cid(10)","allow_gid(10)","deny_cid(10)","deny_gid(10)"),
"uid_wall_parent_created" => array("uid","wall","parent","created"),
"uid_type_changed" => array("uid","type","changed"),

View file

@ -1971,7 +1971,7 @@ class ostatus {
OR (`item`.`network` = '%s' AND ((`thread`.`network` IN ('%s', '%s')) OR (`thritem`.`network` IN ('%s', '%s')))) AND `thread`.`mention`)
AND ((`item`.`owner-link` IN ('%s', '%s') AND (`item`.`parent` = `item`.`id`))
OR (`item`.`author-link` IN ('%s', '%s')))
ORDER BY `item`.`received` DESC
ORDER BY `item`.`id` DESC
LIMIT 0, 300",
intval($owner["uid"]), dbesc($check_date), dbesc(NETWORK_DFRN),
//dbesc(NETWORK_OSTATUS), dbesc(NETWORK_OSTATUS),

View file

@ -27,8 +27,11 @@ class xml {
foreach ($namespaces AS $nskey => $nsvalue)
$key .= " xmlns".($nskey == "" ? "":":").$nskey.'="'.$nsvalue.'"';
$root = new SimpleXMLElement("<".$key."/>");
self::from_array($value, $root, $remove_header, $namespaces, false);
if (is_array($value)) {
$root = new SimpleXMLElement("<".$key."/>");
self::from_array($value, $root, $remove_header, $namespaces, false);
} else
$root = new SimpleXMLElement("<".$key.">".xmlify($value)."</".$key.">");
$dom = dom_import_simplexml($root)->ownerDocument;
$dom->formatOutput = true;
@ -44,6 +47,15 @@ class xml {
}
foreach($array as $key => $value) {
if (!isset($element) AND isset($xml))
$element = $xml;
if (is_integer($key)) {
if (isset($element))
$element[0] = $value;
continue;
}
if (substr($key, 0, 11) == "@attributes") {
if (!isset($element) OR !is_array($value))
continue;
@ -55,7 +67,7 @@ class xml {
else
$namespace = NULL;
$element->addAttribute ($attr_key, $attr_value, $namespace);
$element->addAttribute($attr_key, $attr_value, $namespace);
}
continue;
@ -64,6 +76,8 @@ class xml {
$element_parts = explode(":", $key);
if ((count($element_parts) > 1) AND isset($namespaces[$element_parts[0]]))
$namespace = $namespaces[$element_parts[0]];
elseif (isset($namespaces[""]))
$namespace = $namespaces[""];
else
$namespace = NULL;

View file

@ -224,7 +224,7 @@ function content_content(&$a, $update = 0) {
$simple_update
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
$sql_extra $sql_nets
ORDER BY `item`.`received` DESC $pager_sql ",
ORDER BY `item`.`id` DESC $pager_sql ",
intval($_SESSION['uid'])
);

View file

@ -59,10 +59,6 @@ function notifications_post(&$a) {
}
}
function notifications_content(&$a) {
if(! local_user()) {
@ -76,6 +72,456 @@ function notifications_content(&$a) {
$o = '';
// get the nav tabs for the notification pages
$tabs = notifications_tabs($a);
$notif_content = array();
if( (($a->argc > 1) && ($a->argv[1] == 'intros')) || (($a->argc == 1))) {
nav_set_selected('introductions');
if(($a->argc > 2) && ($a->argv[2] == 'all'))
$sql_extra = '';
else
$sql_extra = " AND `ignore` = 0 ";
$notif_header = t('Notifications');
$notif_tpl = get_markup_template('notifications.tpl');
$notif_ignored_lnk .= '<a href="' . ((strlen($sql_extra)) ? 'notifications/intros/all' : 'notifications/intros' ) . '" id="notifications-show-hide-link" >'
. ((strlen($sql_extra)) ? t('Show Ignored Requests') : t('Hide Ignored Requests')) . '</a></div>' . "\r\n";
$r = q("SELECT COUNT(*) AS `total` FROM `intro`
WHERE `intro`.`uid` = %d $sql_extra AND `intro`.`blocked` = 0 ",
intval($_SESSION['uid'])
);
if($r && count($r)) {
$a->set_pager_total($r[0]['total']);
$a->set_pager_itemspage(20);
}
/// @todo Fetch contact details by "get_contact_details_by_url" instead of queries to contact, fcontact and gcontact
$r = q("SELECT `intro`.`id` AS `intro_id`, `intro`.*, `contact`.*, `fcontact`.`name` AS `fname`,`fcontact`.`url` AS `furl`,`fcontact`.`photo` AS `fphoto`,`fcontact`.`request` AS `frequest`,
`gcontact`.`location` AS `glocation`, `gcontact`.`about` AS `gabout`,
`gcontact`.`keywords` AS `gkeywords`, `gcontact`.`gender` AS `ggender`,
`gcontact`.`network` AS `gnetwork`
FROM `intro`
LEFT JOIN `contact` ON `contact`.`id` = `intro`.`contact-id`
LEFT JOIN `gcontact` ON `gcontact`.`nurl` = `contact`.`nurl`
LEFT JOIN `fcontact` ON `intro`.`fid` = `fcontact`.`id`
WHERE `intro`.`uid` = %d $sql_extra AND `intro`.`blocked` = 0 ",
intval($_SESSION['uid']));
if(($r !== false) && (count($r))) {
$sugg = get_markup_template('suggestions.tpl');
$tpl = get_markup_template("intros.tpl");
foreach($r as $rr) {
if($rr['fid']) {
$return_addr = bin2hex($a->user['nickname'] . '@' . $a->get_hostname() . (($a->path) ? '/' . $a->path : ''));
$notif_content[] = replace_macros($sugg, array(
'$str_notifytype' => t('Notification type: '),
'$notify_type' => t('Friend Suggestion'),
'$intro_id' => $rr['intro_id'],
'$madeby' => sprintf( t('suggested by %s'),$rr['name']),
'$contact_id' => $rr['contact-id'],
'$photo' => ((x($rr,'fphoto')) ? proxy_url($rr['fphoto'], false, PROXY_SIZE_SMALL) : "images/person-175.jpg"),
'$fullname' => $rr['fname'],
'$url' => zrl($rr['furl']),
'$hidden' => array('hidden', t('Hide this contact from others'), ($rr['hidden'] == 1), ''),
'$activity' => array('activity', t('Post a new friend activity'), (intval(get_pconfig(local_user(),'system','post_newfriend')) ? '1' : 0), t('if applicable')),
'$knowyou' => $knowyou,
'$approve' => t('Approve'),
'$note' => $rr['note'],
'$request' => $rr['frequest'] . '?addr=' . $return_addr,
'$ignore' => t('Ignore'),
'$discard' => t('Discard'),
));
continue;
}
$friend_selected = (($rr['network'] !== NETWORK_OSTATUS) ? ' checked="checked" ' : ' disabled ');
$fan_selected = (($rr['network'] === NETWORK_OSTATUS) ? ' checked="checked" disabled ' : '');
$dfrn_tpl = get_markup_template('netfriend.tpl');
$knowyou = '';
$dfrn_text = '';
if($rr['network'] === NETWORK_DFRN || $rr['network'] === NETWORK_DIASPORA) {
if($rr['network'] === NETWORK_DFRN) {
$lbl_knowyou = t('Claims to be known to you: ');
$knowyou = (($rr['knowyou']) ? t('yes') : t('no'));
$helptext = t('Shall your connection be bidirectional or not? "Friend" implies that you allow to read and you subscribe to their posts. "Fan/Admirer" means that you allow to read but you do not want to read theirs. Approve as: ');
} else {
$knowyou = '';
$helptext = t('Shall your connection be bidirectional or not? "Friend" implies that you allow to read and you subscribe to their posts. "Sharer" means that you allow to read but you do not want to read theirs. Approve as: ');
}
$dfrn_text = replace_macros($dfrn_tpl,array(
'$intro_id' => $rr['intro_id'],
'$friend_selected' => $friend_selected,
'$fan_selected' => $fan_selected,
'$approve_as' => $helptext,
'$as_friend' => t('Friend'),
'$as_fan' => (($rr['network'] == NETWORK_DIASPORA) ? t('Sharer') : t('Fan/Admirer'))
));
}
$header = $rr["name"];
$ret = probe_url($rr["url"]);
if ($rr['gnetwork'] == "")
$rr['gnetwork'] = $ret["network"];
if ($ret["addr"] != "")
$header .= " <".$ret["addr"].">";
$header .= " (".network_to_name($rr['gnetwork'], $rr['url']).")";
// Don't show these data until you are connected. Diaspora is doing the same.
if($rr['gnetwork'] === NETWORK_DIASPORA) {
$rr['glocation'] = "";
$rr['gabout'] = "";
$rr['ggender'] = "";
}
$notif_content[] = replace_macros($tpl, array(
'$header' => htmlentities($header),
'$str_notifytype' => t('Notification type: '),
'$notify_type' => (($rr['network'] !== NETWORK_OSTATUS) ? t('Friend/Connect Request') : t('New Follower')),
'$dfrn_text' => $dfrn_text,
'$dfrn_id' => $rr['issued-id'],
'$uid' => $_SESSION['uid'],
'$intro_id' => $rr['intro_id'],
'$contact_id' => $rr['contact-id'],
'$photo' => ((x($rr,'photo')) ? proxy_url($rr['photo'], false, PROXY_SIZE_SMALL) : "images/person-175.jpg"),
'$fullname' => $rr['name'],
'$location' => bbcode($rr['glocation'], false, false),
'$lbl_location' => t('Location:'),
'$about' => bbcode($rr['gabout'], false, false),
'$lbl_about' => t('About:'),
'$keywords' => $rr['gkeywords'],
'$lbl_keywords' => t('Tags:'),
'$gender' => $rr['ggender'],
'$lbl_gender' => t('Gender:'),
'$hidden' => array('hidden', t('Hide this contact from others'), ($rr['hidden'] == 1), ''),
'$activity' => array('activity', t('Post a new friend activity'), (intval(get_pconfig(local_user(),'system','post_newfriend')) ? '1' : 0), t('if applicable')),
'$url' => $rr['url'],
'$zrl' => zrl($rr['url']),
'$lbl_url' => t('Profile URL'),
'$addr' => $rr['addr'],
'$lbl_knowyou' => $lbl_knowyou,
'$lbl_network' => t('Network:'),
'$network' => network_to_name($rr['gnetwork'], $rr['url']),
'$knowyou' => $knowyou,
'$approve' => t('Approve'),
'$note' => $rr['note'],
'$ignore' => t('Ignore'),
'$discard' => t('Discard'),
));
}
}
else
info( t('No introductions.') . EOL);
} else if (($a->argc > 1) && ($a->argv[1] == 'network')) {
$notif_header = t('Network Notifications');
$notif_tpl = get_markup_template('notifications.tpl');
$r = q("SELECT `item`.`id`,`item`.`parent`, `item`.`verb`, `item`.`author-name`,
`item`.`author-link`, `item`.`author-avatar`, `item`.`created`, `item`.`object` as `object`,
`pitem`.`author-name` as `pname`, `pitem`.`author-link` as `plink`, `pitem`.`guid` as `pguid`
FROM `item` INNER JOIN `item` as `pitem` ON `pitem`.`id`=`item`.`parent`
WHERE `item`.`unseen` = 1 AND `item`.`visible` = 1 AND `pitem`.`parent` != 0 AND
`item`.`deleted` = 0 AND `item`.`uid` = %d AND `item`.`wall` = 0 ORDER BY `item`.`created` DESC" ,
intval(local_user())
);
$tpl_item_likes = get_markup_template('notifications_likes_item.tpl');
$tpl_item_dislikes = get_markup_template('notifications_dislikes_item.tpl');
$tpl_item_friends = get_markup_template('notifications_friends_item.tpl');
$tpl_item_comments = get_markup_template('notifications_comments_item.tpl');
$tpl_item_posts = get_markup_template('notifications_posts_item.tpl');
if ($r) {
foreach ($r as $it) {
switch($it['verb']){
case ACTIVITY_LIKE:
$notif_content[] = replace_macros($tpl_item_likes,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
'$item_text' => sprintf( t("%s liked %s's post"), $it['author-name'], $it['pname']),
'$item_when' => relative_date($it['created'])
));
break;
case ACTIVITY_DISLIKE:
$notif_content[] = replace_macros($tpl_item_dislikes,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
'$item_text' => sprintf( t("%s disliked %s's post"), $it['author-name'], $it['pname']),
'$item_when' => relative_date($it['created'])
));
break;
case ACTIVITY_FRIEND:
$xmlhead="<"."?xml version='1.0' encoding='UTF-8' ?".">";
$obj = parse_xml_string($xmlhead.$it['object']);
$it['fname'] = $obj->title;
$notif_content[] = replace_macros($tpl_item_friends,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
'$item_text' => sprintf( t("%s is now friends with %s"), $it['author-name'], $it['fname']),
'$item_when' => relative_date($it['created'])
));
break;
default:
$item_text = (($it['id'] == $it['parent'])
? sprintf( t("%s created a new post"), $it['author-name'])
: sprintf( t("%s commented on %s's post"), $it['author-name'], $it['pname']));
$tpl = (($it['id'] == $it['parent']) ? $tpl_item_posts : $tpl_item_comments);
$notif_content[] = replace_macros($tpl,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
'$item_text' => $item_text,
'$item_when' => relative_date($it['created'])
));
}
}
} else {
$notif_nocontent = t('No more network notifications.');
}
} else if (($a->argc > 1) && ($a->argv[1] == 'system')) {
$notif_header = t('System Notifications');
$notif_tpl = get_markup_template('notifications.tpl');
$not_tpl = get_markup_template('notify.tpl');
require_once('include/bbcode.php');
$r = q("SELECT * from notify where uid = %d and seen = 0 order by date desc",
intval(local_user())
);
if (count($r) > 0) {
foreach ($r as $it) {
$notif_content[] = replace_macros($not_tpl,array(
'$item_link' => $a->get_baseurl(true).'/notify/view/'. $it['id'],
'$item_image' => proxy_url($it['photo'], false, PROXY_SIZE_MICRO),
'$item_text' => strip_tags(bbcode($it['msg'])),
'$item_when' => relative_date($it['date'])
));
}
} else {
$notif_nocontent = t('No more system notifications.');
}
} else if (($a->argc > 1) && ($a->argv[1] == 'personal')) {
$notif_header = t('Personal Notifications');
$notif_tpl = get_markup_template('notifications.tpl');
$myurl = $a->get_baseurl(true) . '/profile/'. $a->user['nickname'];
$myurl = substr($myurl,strpos($myurl,'://')+3);
$myurl = str_replace(array('www.','.'),array('','\\.'),$myurl);
$diasp_url = str_replace('/profile/','/u/',$myurl);
$sql_extra .= sprintf(" AND ( `item`.`author-link` regexp '%s' or `item`.`tag` regexp '%s' or `item`.`tag` regexp '%s' ) ",
dbesc($myurl . '$'),
dbesc($myurl . '\\]'),
dbesc($diasp_url . '\\]')
);
$r = q("SELECT `item`.`id`,`item`.`parent`, `item`.`verb`, `item`.`author-name`,
`item`.`author-link`, `item`.`author-avatar`, `item`.`created`, `item`.`object` as `object`,
`pitem`.`author-name` as `pname`, `pitem`.`author-link` as `plink`, `pitem`.`guid` as `pguid`
FROM `item` INNER JOIN `item` as `pitem` ON `pitem`.`id`=`item`.`parent`
WHERE `item`.`unseen` = 1 AND `item`.`visible` = 1
$sql_extra
AND `item`.`deleted` = 0 AND `item`.`uid` = %d AND `item`.`wall` = 0 ORDER BY `item`.`created` DESC" ,
intval(local_user())
);
$tpl_item_likes = get_markup_template('notifications_likes_item.tpl');
$tpl_item_dislikes = get_markup_template('notifications_dislikes_item.tpl');
$tpl_item_friends = get_markup_template('notifications_friends_item.tpl');
$tpl_item_comments = get_markup_template('notifications_comments_item.tpl');
$tpl_item_posts = get_markup_template('notifications_posts_item.tpl');
if (count($r) > 0) {
foreach ($r as $it) {
switch($it['verb']){
case ACTIVITY_LIKE:
$notif_content[] = replace_macros($tpl_item_likes,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => $it['author-avatar'],
'$item_text' => sprintf( t("%s liked %s's post"), $it['author-name'], $it['pname']),
'$item_when' => relative_date($it['created'])
));
break;
case ACTIVITY_DISLIKE:
$notif_content[] = replace_macros($tpl_item_dislikes,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => $it['author-avatar'],
'$item_text' => sprintf( t("%s disliked %s's post"), $it['author-name'], $it['pname']),
'$item_when' => relative_date($it['created'])
));
break;
case ACTIVITY_FRIEND:
$xmlhead="<"."?xml version='1.0' encoding='UTF-8' ?".">";
$obj = parse_xml_string($xmlhead.$it['object']);
$it['fname'] = $obj->title;
$notif_content[] = replace_macros($tpl_item_friends,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => $it['author-avatar'],
'$item_text' => sprintf( t("%s is now friends with %s"), $it['author-name'], $it['fname']),
'$item_when' => relative_date($it['created'])
));
break;
default:
$item_text = (($it['id'] == $it['parent'])
? sprintf( t("%s created a new post"), $it['author-name'])
: sprintf( t("%s commented on %s's post"), $it['author-name'], $it['pname']));
$tpl = (($it['id'] == $it['parent']) ? $tpl_item_posts : $tpl_item_comments);
$notif_content[] = replace_macros($tpl,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => $it['author-avatar'],
'$item_text' => $item_text,
'$item_when' => relative_date($it['created'])
));
}
}
} else {
$notif_nocontent = t('No more personal notifications.');
}
} else if (($a->argc > 1) && ($a->argv[1] == 'home')) {
$notif_header = t('Home Notifications');
$notif_tpl = get_markup_template('notifications.tpl');
$r = q("SELECT `item`.`id`,`item`.`parent`, `item`.`verb`, `item`.`author-name`,
`item`.`author-link`, `item`.`author-avatar`, `item`.`created`, `item`.`object` as `object`,
`pitem`.`author-name` as `pname`, `pitem`.`author-link` as `plink`, `pitem`.`guid` as `pguid`
FROM `item` INNER JOIN `item` as `pitem` ON `pitem`.`id`=`item`.`parent`
WHERE `item`.`unseen` = 1 AND `item`.`visible` = 1 AND
`item`.`deleted` = 0 AND `item`.`uid` = %d AND `item`.`wall` = 1 ORDER BY `item`.`created` DESC",
intval(local_user())
);
$tpl_item_likes = get_markup_template('notifications_likes_item.tpl');
$tpl_item_dislikes = get_markup_template('notifications_dislikes_item.tpl');
$tpl_item_friends = get_markup_template('notifications_friends_item.tpl');
$tpl_item_comments = get_markup_template('notifications_comments_item.tpl');
if (count($r) > 0) {
foreach ($r as $it) {
switch($it['verb']){
case ACTIVITY_LIKE:
$notif_content[] = replace_macros($tpl_item_likes,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => $it['author-avatar'],
'$item_text' => sprintf( t("%s liked %s's post"), $it['author-name'], $it['pname']),
'$item_when' => relative_date($it['created'])
));
break;
case ACTIVITY_DISLIKE:
$notif_content[] = replace_macros($tpl_item_dislikes,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => $it['author-avatar'],
'$item_text' => sprintf( t("%s disliked %s's post"), $it['author-name'], $it['pname']),
'$item_when' => relative_date($it['created'])
));
break;
case ACTIVITY_FRIEND:
$xmlhead="<"."?xml version='1.0' encoding='UTF-8' ?".">";
$obj = parse_xml_string($xmlhead.$it['object']);
$it['fname'] = $obj->title;
$notif_content[] = replace_macros($tpl_item_friends,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => $it['author-avatar'],
'$item_text' => sprintf( t("%s is now friends with %s"), $it['author-name'], $it['fname']),
'$item_when' => relative_date($it['created'])
));
break;
default:
$notif_content[] = replace_macros($tpl_item_comments,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => $it['author-avatar'],
'$item_text' => sprintf( t("%s commented on %s's post"), $it['author-name'], $it['pname']),
'$item_when' => relative_date($it['created'])
));
}
}
} else {
$notif_nocontent = t('No more home notifications.');
}
}
$o .= replace_macros($notif_tpl, array(
'$notif_header' => $notif_header,
'$tabs' => $tabs,
'$notif_content' => $notif_content,
'$notif_nocontent' => $notif_nocontent,
'$notif_ignored_lnk' => $notif_ignored_lnk,
));
$o .= paginate($a);
return $o;
}
/**
* @brief List of pages for the Notifications TabBar
*
* @param app $a The
* @return array with with notifications TabBar data
*/
function notifications_tabs($a) {
$tabs = array(
array(
'label' => t('System'),
@ -114,470 +560,5 @@ function notifications_content(&$a) {
),*/ /*while I can have notifications for messages, this tablist is not place for message page link */
);
$o = "";
if( (($a->argc > 1) && ($a->argv[1] == 'intros')) || (($a->argc == 1))) {
nav_set_selected('introductions');
if(($a->argc > 2) && ($a->argv[2] == 'all'))
$sql_extra = '';
else
$sql_extra = " AND `ignore` = 0 ";
$notif_tpl = get_markup_template('notifications.tpl');
$notif_content .= '<a href="' . ((strlen($sql_extra)) ? 'notifications/intros/all' : 'notifications/intros' ) . '" id="notifications-show-hide-link" >'
. ((strlen($sql_extra)) ? t('Show Ignored Requests') : t('Hide Ignored Requests')) . '</a></div>' . "\r\n";
$r = q("SELECT COUNT(*) AS `total` FROM `intro`
WHERE `intro`.`uid` = %d $sql_extra AND `intro`.`blocked` = 0 ",
intval($_SESSION['uid'])
);
if($r && count($r)) {
$a->set_pager_total($r[0]['total']);
$a->set_pager_itemspage(20);
}
/// @todo Fetch contact details by "get_contact_details_by_url" instead of queries to contact, fcontact and gcontact
$r = q("SELECT `intro`.`id` AS `intro_id`, `intro`.*, `contact`.*, `fcontact`.`name` AS `fname`,`fcontact`.`url` AS `furl`,`fcontact`.`photo` AS `fphoto`,`fcontact`.`request` AS `frequest`,
`gcontact`.`location` AS `glocation`, `gcontact`.`about` AS `gabout`,
`gcontact`.`keywords` AS `gkeywords`, `gcontact`.`gender` AS `ggender`,
`gcontact`.`network` AS `gnetwork`
FROM `intro`
LEFT JOIN `contact` ON `contact`.`id` = `intro`.`contact-id`
LEFT JOIN `gcontact` ON `gcontact`.`nurl` = `contact`.`nurl`
LEFT JOIN `fcontact` ON `intro`.`fid` = `fcontact`.`id`
WHERE `intro`.`uid` = %d $sql_extra AND `intro`.`blocked` = 0 ",
intval($_SESSION['uid']));
if(($r !== false) && (count($r))) {
$sugg = get_markup_template('suggestions.tpl');
$tpl = get_markup_template("intros.tpl");
foreach($r as $rr) {
if($rr['fid']) {
$return_addr = bin2hex($a->user['nickname'] . '@' . $a->get_hostname() . (($a->path) ? '/' . $a->path : ''));
$notif_content .= replace_macros($sugg, array(
'$str_notifytype' => t('Notification type: '),
'$notify_type' => t('Friend Suggestion'),
'$intro_id' => $rr['intro_id'],
'$madeby' => sprintf( t('suggested by %s'),$rr['name']),
'$contact_id' => $rr['contact-id'],
'$photo' => ((x($rr,'fphoto')) ? proxy_url($rr['fphoto'], false, PROXY_SIZE_SMALL) : "images/person-175.jpg"),
'$fullname' => $rr['fname'],
'$url' => zrl($rr['furl']),
'$hidden' => array('hidden', t('Hide this contact from others'), ($rr['hidden'] == 1), ''),
'$activity' => array('activity', t('Post a new friend activity'), (intval(get_pconfig(local_user(),'system','post_newfriend')) ? '1' : 0), t('if applicable')),
'$knowyou' => $knowyou,
'$approve' => t('Approve'),
'$note' => $rr['note'],
'$request' => $rr['frequest'] . '?addr=' . $return_addr,
'$ignore' => t('Ignore'),
'$discard' => t('Discard'),
));
continue;
}
$friend_selected = (($rr['network'] !== NETWORK_OSTATUS) ? ' checked="checked" ' : ' disabled ');
$fan_selected = (($rr['network'] === NETWORK_OSTATUS) ? ' checked="checked" disabled ' : '');
$dfrn_tpl = get_markup_template('netfriend.tpl');
$knowyou = '';
$dfrn_text = '';
if($rr['network'] === NETWORK_DFRN || $rr['network'] === NETWORK_DIASPORA) {
if($rr['network'] === NETWORK_DFRN) {
$knowyou = t('Claims to be known to you: ') . (($rr['knowyou']) ? t('yes') : t('no'));
$helptext = t('Shall your connection be bidirectional or not? "Friend" implies that you allow to read and you subscribe to their posts. "Fan/Admirer" means that you allow to read but you do not want to read theirs. Approve as: ');
} else {
$knowyou = '';
$helptext = t('Shall your connection be bidirectional or not? "Friend" implies that you allow to read and you subscribe to their posts. "Sharer" means that you allow to read but you do not want to read theirs. Approve as: ');
}
$dfrn_text = replace_macros($dfrn_tpl,array(
'$intro_id' => $rr['intro_id'],
'$friend_selected' => $friend_selected,
'$fan_selected' => $fan_selected,
'$approve_as' => $helptext,
'$as_friend' => t('Friend'),
'$as_fan' => (($rr['network'] == NETWORK_DIASPORA) ? t('Sharer') : t('Fan/Admirer'))
));
}
$header = $rr["name"];
$ret = probe_url($rr["url"]);
if ($rr['gnetwork'] == "")
$rr['gnetwork'] = $ret["network"];
if ($ret["addr"] != "")
$header .= " <".$ret["addr"].">";
$header .= " (".network_to_name($rr['gnetwork'], $rr['url']).")";
// Don't show these data until you are connected. Diaspora is doing the same.
if($rr['gnetwork'] === NETWORK_DIASPORA) {
$rr['glocation'] = "";
$rr['gabout'] = "";
$rr['ggender'] = "";
}
$notif_content .= replace_macros($tpl, array(
'$header' => htmlentities($header),
'$str_notifytype' => t('Notification type: '),
'$notify_type' => (($rr['network'] !== NETWORK_OSTATUS) ? t('Friend/Connect Request') : t('New Follower')),
'$dfrn_text' => $dfrn_text,
'$dfrn_id' => $rr['issued-id'],
'$uid' => $_SESSION['uid'],
'$intro_id' => $rr['intro_id'],
'$contact_id' => $rr['contact-id'],
'$photo' => ((x($rr,'photo')) ? proxy_url($rr['photo'], false, PROXY_SIZE_SMALL) : "images/person-175.jpg"),
'$fullname' => $rr['name'],
'$location' => bbcode($rr['glocation'], false, false),
'$location_label' => t('Location:'),
'$about' => bbcode($rr['gabout'], false, false),
'$about_label' => t('About:'),
'$keywords' => $rr['gkeywords'],
'$keywords_label' => t('Tags:'),
'$gender' => $rr['ggender'],
'$gender_label' => t('Gender:'),
'$hidden' => array('hidden', t('Hide this contact from others'), ($rr['hidden'] == 1), ''),
'$activity' => array('activity', t('Post a new friend activity'), (intval(get_pconfig(local_user(),'system','post_newfriend')) ? '1' : 0), t('if applicable')),
'$url' => $rr['url'],
'$zrl' => zrl($rr['url']),
'$url_label' => t('Profile URL'),
'$knowyou' => $knowyou,
'$approve' => t('Approve'),
'$note' => $rr['note'],
'$ignore' => t('Ignore'),
'$discard' => t('Discard'),
));
}
}
else
info( t('No introductions.') . EOL);
$o .= replace_macros($notif_tpl, array(
'$notif_header' => t('Notifications'),
'$tabs' => $tabs,
'$notif_content' => $notif_content,
));
$o .= paginate($a);
return $o;
} else if (($a->argc > 1) && ($a->argv[1] == 'network')) {
$notif_tpl = get_markup_template('notifications.tpl');
$r = q("SELECT `item`.`id`,`item`.`parent`, `item`.`verb`, `item`.`author-name`,
`item`.`author-link`, `item`.`author-avatar`, `item`.`created`, `item`.`object` as `object`,
`pitem`.`author-name` as `pname`, `pitem`.`author-link` as `plink`, `pitem`.`guid` as `pguid`
FROM `item` INNER JOIN `item` as `pitem` ON `pitem`.`id`=`item`.`parent`
WHERE `item`.`unseen` = 1 AND `item`.`visible` = 1 AND `pitem`.`parent` != 0 AND
`item`.`deleted` = 0 AND `item`.`uid` = %d AND `item`.`wall` = 0 ORDER BY `item`.`created` DESC" ,
intval(local_user())
);
$tpl_item_likes = get_markup_template('notifications_likes_item.tpl');
$tpl_item_dislikes = get_markup_template('notifications_dislikes_item.tpl');
$tpl_item_friends = get_markup_template('notifications_friends_item.tpl');
$tpl_item_comments = get_markup_template('notifications_comments_item.tpl');
$tpl_item_posts = get_markup_template('notifications_posts_item.tpl');
$notif_content = '';
if ($r) {
foreach ($r as $it) {
switch($it['verb']){
case ACTIVITY_LIKE:
$notif_content .= replace_macros($tpl_item_likes,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
'$item_text' => sprintf( t("%s liked %s's post"), $it['author-name'], $it['pname']),
'$item_when' => relative_date($it['created'])
));
break;
case ACTIVITY_DISLIKE:
$notif_content .= replace_macros($tpl_item_dislikes,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
'$item_text' => sprintf( t("%s disliked %s's post"), $it['author-name'], $it['pname']),
'$item_when' => relative_date($it['created'])
));
break;
case ACTIVITY_FRIEND:
$xmlhead="<"."?xml version='1.0' encoding='UTF-8' ?".">";
$obj = parse_xml_string($xmlhead.$it['object']);
$it['fname'] = $obj->title;
$notif_content .= replace_macros($tpl_item_friends,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
'$item_text' => sprintf( t("%s is now friends with %s"), $it['author-name'], $it['fname']),
'$item_when' => relative_date($it['created'])
));
break;
default:
$item_text = (($it['id'] == $it['parent'])
? sprintf( t("%s created a new post"), $it['author-name'])
: sprintf( t("%s commented on %s's post"), $it['author-name'], $it['pname']));
$tpl = (($it['id'] == $it['parent']) ? $tpl_item_posts : $tpl_item_comments);
$notif_content .= replace_macros($tpl,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
'$item_text' => $item_text,
'$item_when' => relative_date($it['created'])
));
}
}
} else {
$notif_content = t('No more network notifications.');
}
$o .= replace_macros($notif_tpl, array(
'$notif_header' => t('Network Notifications'),
'$tabs' => $tabs,
'$notif_content' => $notif_content,
));
} else if (($a->argc > 1) && ($a->argv[1] == 'system')) {
$notif_tpl = get_markup_template('notifications.tpl');
$not_tpl = get_markup_template('notify.tpl');
require_once('include/bbcode.php');
$r = q("SELECT * from notify where uid = %d and seen = 0 order by date desc",
intval(local_user())
);
if (count($r) > 0) {
foreach ($r as $it) {
$notif_content .= replace_macros($not_tpl,array(
'$item_link' => $a->get_baseurl(true).'/notify/view/'. $it['id'],
'$item_image' => proxy_url($it['photo'], false, PROXY_SIZE_MICRO),
'$item_text' => strip_tags(bbcode($it['msg'])),
'$item_when' => relative_date($it['date'])
));
}
} else {
$notif_content .= t('No more system notifications.');
}
$o .= replace_macros($notif_tpl, array(
'$notif_header' => t('System Notifications'),
'$tabs' => $tabs,
'$notif_content' => $notif_content,
));
} else if (($a->argc > 1) && ($a->argv[1] == 'personal')) {
$notif_tpl = get_markup_template('notifications.tpl');
$myurl = $a->get_baseurl(true) . '/profile/'. $a->user['nickname'];
$myurl = substr($myurl,strpos($myurl,'://')+3);
$myurl = str_replace(array('www.','.'),array('','\\.'),$myurl);
$diasp_url = str_replace('/profile/','/u/',$myurl);
$sql_extra .= sprintf(" AND ( `item`.`author-link` regexp '%s' or `item`.`tag` regexp '%s' or `item`.`tag` regexp '%s' ) ",
dbesc($myurl . '$'),
dbesc($myurl . '\\]'),
dbesc($diasp_url . '\\]')
);
$r = q("SELECT `item`.`id`,`item`.`parent`, `item`.`verb`, `item`.`author-name`,
`item`.`author-link`, `item`.`author-avatar`, `item`.`created`, `item`.`object` as `object`,
`pitem`.`author-name` as `pname`, `pitem`.`author-link` as `plink`, `pitem`.`guid` as `pguid`
FROM `item` INNER JOIN `item` as `pitem` ON `pitem`.`id`=`item`.`parent`
WHERE `item`.`unseen` = 1 AND `item`.`visible` = 1
$sql_extra
AND `item`.`deleted` = 0 AND `item`.`uid` = %d AND `item`.`wall` = 0 ORDER BY `item`.`created` DESC" ,
intval(local_user())
);
$tpl_item_likes = get_markup_template('notifications_likes_item.tpl');
$tpl_item_dislikes = get_markup_template('notifications_dislikes_item.tpl');
$tpl_item_friends = get_markup_template('notifications_friends_item.tpl');
$tpl_item_comments = get_markup_template('notifications_comments_item.tpl');
$tpl_item_posts = get_markup_template('notifications_posts_item.tpl');
$notif_content = '';
if (count($r) > 0) {
foreach ($r as $it) {
switch($it['verb']){
case ACTIVITY_LIKE:
$notif_content .= replace_macros($tpl_item_likes,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => $it['author-avatar'],
'$item_text' => sprintf( t("%s liked %s's post"), $it['author-name'], $it['pname']),
'$item_when' => relative_date($it['created'])
));
break;
case ACTIVITY_DISLIKE:
$notif_content .= replace_macros($tpl_item_dislikes,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => $it['author-avatar'],
'$item_text' => sprintf( t("%s disliked %s's post"), $it['author-name'], $it['pname']),
'$item_when' => relative_date($it['created'])
));
break;
case ACTIVITY_FRIEND:
$xmlhead="<"."?xml version='1.0' encoding='UTF-8' ?".">";
$obj = parse_xml_string($xmlhead.$it['object']);
$it['fname'] = $obj->title;
$notif_content .= replace_macros($tpl_item_friends,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => $it['author-avatar'],
'$item_text' => sprintf( t("%s is now friends with %s"), $it['author-name'], $it['fname']),
'$item_when' => relative_date($it['created'])
));
break;
default:
$item_text = (($it['id'] == $it['parent'])
? sprintf( t("%s created a new post"), $it['author-name'])
: sprintf( t("%s commented on %s's post"), $it['author-name'], $it['pname']));
$tpl = (($it['id'] == $it['parent']) ? $tpl_item_posts : $tpl_item_comments);
$notif_content .= replace_macros($tpl,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => $it['author-avatar'],
'$item_text' => $item_text,
'$item_when' => relative_date($it['created'])
));
}
}
} else {
$notif_content = t('No more personal notifications.');
}
$o .= replace_macros($notif_tpl, array(
'$notif_header' => t('Personal Notifications'),
'$tabs' => $tabs,
'$notif_content' => $notif_content,
));
} else if (($a->argc > 1) && ($a->argv[1] == 'home')) {
$notif_tpl = get_markup_template('notifications.tpl');
$r = q("SELECT `item`.`id`,`item`.`parent`, `item`.`verb`, `item`.`author-name`,
`item`.`author-link`, `item`.`author-avatar`, `item`.`created`, `item`.`object` as `object`,
`pitem`.`author-name` as `pname`, `pitem`.`author-link` as `plink`, `pitem`.`guid` as `pguid`
FROM `item` INNER JOIN `item` as `pitem` ON `pitem`.`id`=`item`.`parent`
WHERE `item`.`unseen` = 1 AND `item`.`visible` = 1 AND
`item`.`deleted` = 0 AND `item`.`uid` = %d AND `item`.`wall` = 1 ORDER BY `item`.`created` DESC",
intval(local_user())
);
$tpl_item_likes = get_markup_template('notifications_likes_item.tpl');
$tpl_item_dislikes = get_markup_template('notifications_dislikes_item.tpl');
$tpl_item_friends = get_markup_template('notifications_friends_item.tpl');
$tpl_item_comments = get_markup_template('notifications_comments_item.tpl');
$notif_content = '';
if (count($r) > 0) {
foreach ($r as $it) {
switch($it['verb']){
case ACTIVITY_LIKE:
$notif_content .= replace_macros($tpl_item_likes,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => $it['author-avatar'],
'$item_text' => sprintf( t("%s liked %s's post"), $it['author-name'], $it['pname']),
'$item_when' => relative_date($it['created'])
));
break;
case ACTIVITY_DISLIKE:
$notif_content .= replace_macros($tpl_item_dislikes,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => $it['author-avatar'],
'$item_text' => sprintf( t("%s disliked %s's post"), $it['author-name'], $it['pname']),
'$item_when' => relative_date($it['created'])
));
break;
case ACTIVITY_FRIEND:
$xmlhead="<"."?xml version='1.0' encoding='UTF-8' ?".">";
$obj = parse_xml_string($xmlhead.$it['object']);
$it['fname'] = $obj->title;
$notif_content .= replace_macros($tpl_item_friends,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => $it['author-avatar'],
'$item_text' => sprintf( t("%s is now friends with %s"), $it['author-name'], $it['fname']),
'$item_when' => relative_date($it['created'])
));
break;
default:
$notif_content .= replace_macros($tpl_item_comments,array(
//'$item_link' => $a->get_baseurl(true).'/display/'.$a->user['nickname']."/".$it['parent'],
'$item_link' => $a->get_baseurl(true).'/display/'.$it['pguid'],
'$item_image' => $it['author-avatar'],
'$item_text' => sprintf( t("%s commented on %s's post"), $it['author-name'], $it['pname']),
'$item_when' => relative_date($it['created'])
));
}
}
} else {
$notif_content = t('No more home notifications.');
}
$o .= replace_macros($notif_tpl, array(
'$notif_header' => t('Home Notifications'),
'$tabs' => $tabs,
'$notif_content' => $notif_content,
));
}
$o .= paginate($a);
return $o;
}
return $tabs;
}

View file

@ -1,6 +1,6 @@
<?php
define('UPDATE_VERSION' , 1199);
define('UPDATE_VERSION' , 1200);
/**
*

View file

@ -1,67 +0,0 @@
<config>
<site>
<name>{{$config.site.name}}</name>
<server>{{$config.site.server}}</server>
<theme>default</theme>
<path></path>
<logo>{{$config.site.logo}}</logo>
<fancy>true</fancy>
<language>en</language>
<email>{{$config.site.email}}</email>
<broughtby></broughtby>
<broughtbyurl></broughtbyurl>
<timezone>UTC</timezone>
<closed>{{$config.site.closed}}</closed>
<inviteonly>false</inviteonly>
<private>{{$config.site.private}}</private>
<textlimit>{{$config.site.textlimit}}</textlimit>
<ssl>{{$config.site.ssl}}</ssl>
<sslserver>{{$config.site.sslserver}}</sslserver>
<shorturllength>30</shorturllength>
</site>
<license>
<type>cc</type>
<owner></owner>
<url>http://creativecommons.org/licenses/by/3.0/</url>
<title>Creative Commons Attribution 3.0</title>
<image>http://i.creativecommons.org/l/by/3.0/80x15.png</image>
</license>
<nickname>
<featured></featured>
</nickname>
<profile>
<biolimit></biolimit>
</profile>
<group>
<desclimit></desclimit>
</group>
<notice>
<contentlimit></contentlimit>
</notice>
<throttle>
<enabled>false</enabled>
<count>20</count>
<timespan>600</timespan>
</throttle>
<xmpp>
<enabled>false</enabled>
<server>INVALID SERVER</server>
<port>5222</port>
<user>update</user>
</xmpp>
<integration>
<source>StatusNet</source>
</integration>
<attachments>
<uploads>false</uploads>
<file_quota>0</file_quota>
</attachments>
</config>

View file

@ -1,6 +0,0 @@
{{* used in include/api.php 'api_statuses_friends' and 'api_statuses_followers' *}}
<users type="array">
{{foreach $users as $u}}
<user>{{include file="api_user_xml.tpl" user=$u}}</user>
{{/foreach}}
</users>

View file

@ -1,21 +0,0 @@
<photo>
<id>{{$photo.id}}</id>
<created>{{$photo.created}}</created>
<edited>{{$photo.edited}}</edited>
<title>{{$photo.title}}</title>
<desc>{{$photo.desc}}</desc>
<album>{{$photo.album}}</album>
<filename>{{$photo.filename}}</filename>
<type>{{$photo.type}}</type>
<height>{{$photo.height}}</height>
<width>{{$photo.width}}</width>
<datasize>{{$photo.datasize}}</datasize>
<profile>1</profile>
<links type="array">{{foreach $photo.link as $scale => $url}}
<link type="{{$photo.type}}" scale="{{$scale}}" href="{{$url}}" />
{{/foreach}}</links>
{{if $photo.data}}
<data encode="base64">{{$photo.data}}</data>
{{/if}}
</photo>

View file

@ -1,5 +0,0 @@
<photos type="array">
{{foreach $photos as $photo}}
<photo id="{{$photo.id}}" album="{{$photo.album}}" filename="{{$photo.filename}}" type="{{$photo.type}}">{{$photo.thumb}}</photo>
{{/foreach}}</photos>

View file

@ -1,7 +0,0 @@
<hash>
<remaining-hits type="integer">{{$hash.remaining_hits}}</remaining-hits>
<hourly-limit type="integer">{{$hash.hourly_limit}}</hourly-limit>
<reset-time type="datetime">{{$hash.reset_time}}</reset-time>
<reset_time_in_seconds type="integer">{{$hash.resettime_in_seconds}}</reset_time_in_seconds>
</hash>

View file

@ -1,25 +0,0 @@
{{* shared structure for statuses. includers must define root element *}}
<text>{{$status.text}}</text>
<truncated>{{$status.truncated}}</truncated>
<created_at>{{$status.created_at}}</created_at>
<in_reply_to_status_id>{{$status.in_reply_to_status_id}}</in_reply_to_status_id>
<source>{{$status.source}}</source>
<id>{{$status.id}}</id>
<in_reply_to_user_id>{{$status.in_reply_to_user_id}}</in_reply_to_user_id>
<in_reply_to_screen_name>{{$status.in_reply_to_screen_name}}</in_reply_to_screen_name>
<geo>{{$status.geo}}</geo>
<favorited>{{$status.favorited}}</favorited>
<user>{{include file="api_user_xml.tpl" user=$status.user}}</user>
<friendica:owner>{{include file="api_user_xml.tpl" user=$status.friendica_owner}}</friendica:owner>
<statusnet:html>{{$status.statusnet_html}}</statusnet:html>
<statusnet:conversation_id>{{$status.statusnet_conversation_id}}</statusnet:conversation_id>
<url>{{$status.url}}</url>
<coordinates>{{$status.coordinates}}</coordinates>
<place>{{$status.place}}</place>
<contributors>{{$status.contributors}}</contributors>
{{if $status.retweeted_status}}<retweeted_status>{{include file="api_single_status_xml.tpl" status=$status.retweeted_status}}</retweeted_status>{{/if}}
<friendica:activities>
{{foreach $status.friendica_activities as $k=>$v}}
<friendica:{{$k}}>{{$v|count}}</friendica:{{$k}}>
{{/foreach}}
</friendica:activities>

View file

@ -1,8 +0,0 @@
{{* used in api.php to return a single status *}}
<status
xmlns:statusnet="http://status.net/schema/api/1/"
xmlns:friendica="http://friendi.ca/schema/api/1/">
{{if $status}}
{{include file="api_single_status_xml.tpl" status=$status}}
{{/if}}
</status>

View file

@ -1,2 +0,0 @@
<ok>{{$ok}}</ok>

View file

@ -1,91 +0,0 @@
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:georss="http://www.georss.org/georss" xmlns:activity="http://activitystrea.ms/spec/1.0/" xmlns:media="http://purl.org/syndication/atommedia" xmlns:poco="http://portablecontacts.net/spec/1.0" xmlns:ostatus="http://ostatus.org/schema/1.0" xmlns:statusnet="http://status.net/schema/api/1/">
<generator uri="http://status.net" version="0.9.7">StatusNet</generator>
<id>{{$rss.self}}</id>
<title>Friendica</title>
<subtitle>Friendica API feed</subtitle>
<logo>{{$rss.logo}}</logo>
<updated>{{$rss.atom_updated}}</updated>
<link type="text/html" rel="alternate" href="{{$rss.alternate}}"/>
<link type="application/atom+xml" rel="self" href="{{$rss.self}}"/>
<author>
<activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
<uri>{{$user.url}}</uri>
<name>{{$user.name}}</name>
<link rel="alternate" type="text/html" href="{{$user.url}}"/>
<link rel="avatar" type="image/jpeg" media:width="106" media:height="106" href="{{$user.profile_image_url}}"/>
<link rel="avatar" type="image/jpeg" media:width="96" media:height="96" href="{{$user.profile_image_url}}"/>
<link rel="avatar" type="image/jpeg" media:width="48" media:height="48" href="{{$user.profile_image_url}}"/>
<link rel="avatar" type="image/jpeg" media:width="24" media:height="24" href="{{$user.profile_image_url}}"/>
<georss:point></georss:point>
<poco:preferredUsername>{{$user.screen_name}}</poco:preferredUsername>
<poco:displayName>{{$user.name}}</poco:displayName>
<poco:urls>
<poco:type>homepage</poco:type>
<poco:value>{{$user.url}}</poco:value>
<poco:primary>true</poco:primary>
</poco:urls>
<statusnet:profile_info local_id="{{$user.id}}"></statusnet:profile_info>
</author>
<!--Deprecation warning: activity:subject is present only for backward compatibility. It will be removed in the next version of StatusNet.-->
<activity:subject>
<activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
<id>{{$user.contact_url}}</id>
<title>{{$user.name}}</title>
<link rel="alternate" type="text/html" href="{{$user.url}}"/>
<link rel="avatar" type="image/jpeg" media:width="106" media:height="106" href="{{$user.profile_image_url}}"/>
<link rel="avatar" type="image/jpeg" media:width="96" media:height="96" href="{{$user.profile_image_url}}"/>
<link rel="avatar" type="image/jpeg" media:width="48" media:height="48" href="{{$user.profile_image_url}}"/>
<link rel="avatar" type="image/jpeg" media:width="24" media:height="24" href="{{$user.profile_image_url}}"/>
<poco:preferredUsername>{{$user.screen_name}}</poco:preferredUsername>
<poco:displayName>{{$user.name}}</poco:displayName>
<poco:urls>
<poco:type>homepage</poco:type>
<poco:value>{{$user.url}}</poco:value>
<poco:primary>true</poco:primary>
</poco:urls>
<statusnet:profile_info local_id="{{$user.id}}"></statusnet:profile_info>
</activity:subject>
{{foreach $statuses as $status}}
<entry>
<activity:object-type>{{$status.objecttype}}</activity:object-type>
<id>{{$status.message_id}}</id>
<title>{{$status.text}}</title>
<content type="html">{{$status.statusnet_html}}</content>
<link rel="alternate" type="text/html" href="{{$status.url}}"/>
<activity:verb>{{$status.verb}}</activity:verb>
<published>{{$status.published}}</published>
<updated>{{$status.updated}}</updated>
<link rel="self" type="application/atom+xml" href="{{$status.self}}"/>
<link rel="edit" type="application/atom+xml" href="{{$status.edit}}"/>
<statusnet:notice_info local_id="{{$status.id}}" source="{{$status.source}}" >
</statusnet:notice_info>
<author>
<activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
<uri>{{$status.user.url}}</uri>
<name>{{$status.user.name}}</name>
<link rel="alternate" type="text/html" href="{{$status.user.url}}"/>
<link rel="avatar" type="image/jpeg" media:width="48" media:height="48" href="{{$status.user.profile_image_url}}"/>
<georss:point/>
<poco:preferredUsername>{{$status.user.screen_name}}</poco:preferredUsername>
<poco:displayName>{{$status.user.name}}</poco:displayName>
<poco:address/>
<poco:urls>
<poco:type>homepage</poco:type>
<poco:value>{{$status.user.url}}</poco:value>
<poco:primary>true</poco:primary>
</poco:urls>
</author>
<link rel="ostatus:conversation" type="text/html" href="{{$status.url}}"/>
</entry>
{{/foreach}}
</feed>

View file

@ -1,27 +0,0 @@
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:georss="http://www.georss.org/georss" xmlns:twitter="http://api.twitter.com">
<channel>
<title>Friendica</title>
<link>{{$rss.alternate}}</link>
<atom:link type="application/rss+xml" rel="self" href="{{$rss.self}}"/>
<description>Friendica timeline</description>
<language>{{$rss.language}}</language>
<ttl>40</ttl>
<image>
<link>{{$user.link}}</link>
<title>{{$user.name}}'s items</title>
<url>{{$user.profile_image_url}}</url>
</image>
{{foreach $statuses as $status}}
<item>
<title>{{$status.user.name}}: {{$status.text}}</title>
<description>{{$status.text}}</description>
<pubDate>{{$status.created_at}}</pubDate>
<guid>{{$status.url}}</guid>
<link>{{$status.url}}</link>
<twitter:source>{{$status.source}}</twitter:source>
</item>
{{/foreach}}
</channel>
</rss>

View file

@ -1,10 +0,0 @@
<statuses type="array"
xmlns:statusnet="http://status.net/schema/api/1/"
xmlns:friendica="http://friendi.ca/schema/api/1/">
{{foreach $statuses as $status}}
<status>
{{include file="api_single_status_xml.tpl" status=$status}}
</status>
{{/foreach}}
</statuses>

View file

@ -1,47 +0,0 @@
{{* includer template MUST provide root element *}}
<id>{{$user.id}}</id>
<name>{{$user.name}}</name>
<screen_name>{{$user.screen_name}}</screen_name>
<location>{{$user.location}}</location>
<description>{{$user.description}}</description>
<profile_image_url>{{$user.profile_image_url}}</profile_image_url>
<url>{{$user.url}}</url>
<protected>{{$user.protected}}</protected>
<followers_count>{{$user.followers_count}}</followers_count>
<friends_count>{{$user.friends_count}}</friends_count>
<created_at>{{$user.created_at}}</created_at>
<favourites_count>{{$user.favourites_count}}</favourites_count>
<utc_offset>{{$user.utc_offset}}</utc_offset>
<time_zone>{{$user.time_zone}}</time_zone>
<statuses_count>{{$user.statuses_count}}</statuses_count>
<following>{{$user.following}}</following>
<profile_background_color>{{$user.profile_background_color}}</profile_background_color>
<profile_text_color>{{$user.profile_text_color}}</profile_text_color>
<profile_link_color>{{$user.profile_link_color}}</profile_link_color>
<profile_sidebar_fill_color>{{$user.profile_sidebar_fill_color}}</profile_sidebar_fill_color>
<profile_sidebar_border_color>{{$user.profile_sidebar_border_color}}</profile_sidebar_border_color>
<profile_background_image_url>{{$user.profile_background_image_url}}</profile_background_image_url>
<profile_background_tile>{{$user.profile_background_tile}}</profile_background_tile>
<profile_use_background_image>{{$user.profile_use_background_image}}</profile_use_background_image>
<notifications>{{$user.notifications}}</notifications>
<geo_enabled>{{$user.geo_enabled}}</geo_enabled>
<verified>{{$user.verified}}</verified>
<lang>{{$user.lang}}</lang>
<contributors_enabled>{{$user.contributors_enabled}}</contributors_enabled>
<status>{{if $user.status}}
<created_at>{{$user.status.created_at}}</created_at>
<id>{{$user.status.id}}</id>
<text>{{$user.status.text}}</text>
<source>{{$user.status.source}}</source>
<truncated>{{$user.status.truncated}}</truncated>
<in_reply_to_status_id>{{$user.status.in_reply_to_status_id}}</in_reply_to_status_id>
<in_reply_to_user_id>{{$user.status.in_reply_to_user_id}}</in_reply_to_user_id>
<favorited>{{$user.status.favorited}}</favorited>
<in_reply_to_screen_name>{{$user.status.in_reply_to_screen_name}}</in_reply_to_screen_name>
<geo>{{$user.status.geo}}</geo>
<coordinates>{{$user.status.coordinates}}</coordinates>
<place>{{$user.status.place}}</place>
<contributors>{{$user.status.contributors}}</contributors>
{{/if}}</status>

View file

@ -4,12 +4,12 @@
<p class="intro-desc">{{$str_notifytype}} {{$notify_type}}</p>
<img id="photo-{{$contact_id}}" class="intro-photo" src="{{$photo}}" width="175" height=175" title="{{$fullname|escape:'html'}}" alt="{{$fullname|escape:'html'}}" />
<dl><dt>{{$url_label}}</dt><dd><a target="blank" href="{{$zrl}}">{{$url}}</a></dd></dl>
{{if $location}}<dl><dt>{{$location_label}}</dt><dd>{{$location}}</dd></dl>{{/if}}
{{if $gender}}<dl><dt>{{$gender_label}}</dt><dd>{{$gender}}</dd></dl>{{/if}}
{{if $keywords}}<dl><dt>{{$keywords_label}}</dt><dd>{{$keywords}}</dd></dl>{{/if}}
{{if $about}}<dl><dt>{{$about_label}}</dt><dd>{{$about}}</dd></dl>{{/if}}
<div class="intro-knowyou">{{$knowyou}}</div>
<dl><dt>{{$lbl_url}}</dt><dd><a target="blank" href="{{$zrl}}">{{$url}}</a></dd></dl>
{{if $location}}<dl><dt>{{$lbl_location}}</dt><dd>{{$location}}</dd></dl>{{/if}}
{{if $gender}}<dl><dt>{{$lbl_gender}}</dt><dd>{{$gender}}</dd></dl>{{/if}}
{{if $keywords}}<dl><dt>{{$lbl_keywords}}</dt><dd>{{$keywords}}</dd></dl>{{/if}}
{{if $about}}<dl><dt>{{$lbl_about}}</dt><dd>{{$about}}</dd></dl>{{/if}}
<div class="intro-knowyou">{{$lbl_knowyou}} {{$knowyou}}</div>
<div class="intro-note" id="intro-note-{{$contact_id}}">{{$note}}</div>
<div class="intro-wrapper-end" id="intro-wrapper-end-{{$contact_id}}"></div>
<form class="intro-form" action="notifications/{{$intro_id}}" method="post">

View file

@ -5,5 +5,18 @@
{{if $tabs }}{{include file="common_tabs.tpl"}}{{/if}}
<div class="notif-network-wrapper">
{{$notif_content}}
{{* The "show ignored" link *}}
{{if $notif_ignored_lnk}}{{$notif_ignored_lnk}}{{/if}}
{{* The notifications *}}
{{if $notif_content}}
{{foreach $notif_content as $notification}}
{{$notification}}
{{/foreach}}
{{/if}}
{{* If no notifications messages available *}}
{{if $notif_nocontent}}
<div class="notif_nocontent">{{$notif_nocontent}}</div>
{{/if}}
</div>

View file

@ -1798,7 +1798,7 @@ ul.dropdown-menu li:hover {
.suggest-content-wrapper, .common-content-wrapper,
.allfriends-content-wrapper, .match-content-wrapper, .dirfind-content-wrapper,
.directory-content-wrapper, .manage-content-wrapper, .notes-content-wrapper,
.message-content-wrapper, .apps-content-wrapper, .notifications-content-wrapper,
.message-content-wrapper, .apps-content-wrapper,
.admin-content-wrapper, .group-content-wrapper, .viewcontacts-content-wrapper {
min-height: calc(100vh - 150px);
padding: 15px;
@ -2157,6 +2157,54 @@ td.fc-day {
.group {
margin-left: 20px;
}
/* Notifications */
ul.notif-network-list {
margin-left: -15px;
margin-right: -15px;
}
ul.notif-network-list > li {
padding-left: 15px;
padding-right: 15px;
}
.intro-wrapper.media {
overflow: visible;
word-wrap: break-word;
margin-top: 0;
}
.intro-photo-wrapper img.intro-photo {
height:80px;
width: 80px;
border-radius: 4px;
}
.intro-actions {
display: flex;
}
.intro-enty-name h4 {
font-size: 15px !important;
}
.intro-wrapper button.intro-action-link {
opacity: 0.1;
transition: all 0.25s ease-in-out;
}
.intro-wrapper button.intro-action-link,
.intro-wrapper button.intro-action-link:hover {
padding-right: 5px;
padding-left: 5px;
color: #555;
}
ul li:hover .intro-wrapper button.intro-action-link {
opacity: 0.8;
transition: all 0.25s ease-in-out;
}
ul li:hover .intro-wrapper button.intro-action-link:hover {
opacity: 1;
}
.intro-desc-label, .intro-url-label, .intro-network-label,
.intro-location-label, .intro-gender-label, .intro-keywords-label,
.intro-about-label, .intro-knowyou-label {
font-weight: bold;
}
/*
* Overwriting for transparency and other colors
*/

View file

@ -204,6 +204,19 @@ function addToModal(url) {
});
}
// Add a element (by it's id) to a bootstrap modal
function addElmToModal(id) {
var elm = $(id).html();
var modal = $('#modal').modal();
modal
.find('#modal-body')
.append(elm)
.modal.show;
loadModalTitle();
}
// function to load the html from the edit post page into
// the jot modal
function editpost(url) {

View file

@ -0,0 +1,54 @@
<div class="intro-wrapper media" id="intro-{{$contact_id}}" >
{{* Contact Photo *}}
<div class="intro-photo-wrapper dropdown pull-left" >
<img id="photo-{{$contact_id}}" class="intro-photo media-object" src="{{$photo}}" title="{{$fullname|escape:'html'}}" alt="{{$fullname|escape:'html'}}" />
</div>
<div class="media-body">
{{* The intro actions like approve, ignore, discard intro*}}
<div class="intro-actions pull-right nav-pills preferences hidden-xs">
<button class="btn-link intro-action-link" onclick="addElmToModal('#intro-approve-wrapper-{{$contact_id}}')"><i class="fa fa-check" aria-hidden="true"></i></button>
<form class="intro-form" action="notifications/{{$intro_id}}" method="post">
<button class="btn-link intro-submit-ignore intro-action-link" type="submit" name="submit" value="{{$ignore|escape:'html'}}"><i class="fa fa-ban" aria-hidden="true"></i></button>
<button class="btn-link intro-submit-discard intro-action-link" type="submit" name="submit" value="{{$discard|escape:'html'}}"><i class="fa fa-trash-o" aria-hidden="true"></i></button>
</form>
</div>
<div class='intro-enty-name'><h4 class="media-heading"><a href="{{$zrl}}">{{$fullname}}</a></h4></div>
<div class="intro-desc"><span class="intro-desc-label">{{$str_notifytype}}</span>{{$notify_type}}</div>
{{* Additional information of the contact *}}
<div class="intro-url"><span class="intro-url-label">{{$lbl_url}}:&nbsp;</span><a href="{{$zrl}}">{{$url}}</a></div>
{{if $network}}<div class="intro-network"><span class="intro-network-label">{{$lbl_network}}</span>&nbsp;{{$network}}</div>{{/if}}
{{if $location}}<div class="intro-location"><span class="intro-location-label">{{$lbl_location}}</span>&nbsp;{{$location}}</div>{{/if}}
{{if $gender}}<div class="intro-gender"><span class="intro-gender-label">{{$lbl_gender}}</span>&nbsp;{{$gender}}</div>{{/if}}
{{if $keywords}}<div class="intro-keywords"><span class="intro-keywords-label">{{$lbl_keywords}}</span>&nbsp;{{$keywords}}</div>{{/if}}
{{if $about}}<div class="intro-about"><span class="intro-about-label">{{$lbl_about}}</span>&nbsp;{{$about}}</div>{{/if}}
<div class="intro-knowyou"><span class="intro-knowyou-label">{{$lbl_knowyou}}</span>{{$knowyou}}</div>
<div class="intro-note" id="intro-note-{{$contact_id}}">{{$note}}</div>
{{* This sections contains special settings for contact approval. We hide it by default and load this section in
a bootstrap modal in the case of approval *}}
<div id="intro-approve-wrapper-{{$contact_id}}" style="display: none;">
<h3 class="heading">{{$fullname}}{{if $addr}}&nbsp;({{$addr}}){{/if}}</h3>
<form class="intro-approve-form" action="dfrn_confirm" method="post">
{{include file="field_checkbox.tpl" field=$hidden}}
{{include file="field_checkbox.tpl" field=$activity}}
<input type="hidden" name="dfrn_id" value="{{$dfrn_id}}" >
<input type="hidden" name="intro_id" value="{{$intro_id}}" >
<input type="hidden" name="contact_id" value="{{$contact_id}}" >
{{$dfrn_text}}
<div class="pull-right">
<button class="btn btn-default intro-submit-approve" type="submit" name="submit" value="{{$approve|escape:'html'}}">{{$approve|escape:'html'}}</button>
</div>
<div class="clear"></div>
</form>
</div>
</div>
</div>
<div class="intro-end"></div>

View file

@ -0,0 +1,25 @@
<div class="generic-page-wrapper">
{{include file="section_title.tpl" title=$notif_header}}
{{if $tabs }}{{include file="common_tabs.tpl"}}{{/if}}
<div class="notif-network-wrapper">
{{* The "show ignored" link *}}
{{if $notif_ignored_lnk}}{{$notif_ignored_lnk}}{{/if}}
{{* The notifications *}}
{{if $notif_content}}
<ul class="notif-network-list media-list">
{{foreach $notif_content as $notification}}
<li>{{$notification}}</li>
{{/foreach}}
</ul>
{{/if}}
{{* If no notifications messages available *}}
{{if $notif_nocontent}}
<div class="notif_nocontent">{{$notif_nocontent}}</div>
{{/if}}
</div>
</div>