streams/include/api.php

2069 lines
58 KiB
PHP
Raw Normal View History

2013-02-26 01:09:40 +00:00
<?php /** @file */
2013-01-19 14:08:13 +00:00
2015-12-09 22:56:08 +00:00
require_once("include/bbcode.php");
require_once("include/datetime.php");
require_once("include/conversation.php");
require_once("include/oauth.php");
require_once("include/html2plain.php");
2013-01-19 14:08:13 +00:00
require_once('include/security.php');
require_once('include/photos.php');
2014-01-25 02:50:47 +00:00
require_once('include/items.php');
require_once('include/attach.php');
require_once('include/api_auth.php');
2016-10-11 23:13:52 +00:00
require_once('include/api_zot.php');
2013-01-16 23:51:21 +00:00
/*
*
2016-07-28 20:10:19 +00:00
* Hubzilla API. Loosely based on and possibly compatible with Twitter-Like (v1.0) API but all similarities end there.
*
2011-02-15 11:24:21 +00:00
*/
2013-01-19 14:08:13 +00:00
/**
** TWITTER API
*/
$API = array();
$called_api = Null;
2011-04-21 15:03:31 +00:00
// All commands which require authentication accept a "channel" parameter
// which is the left hand side of the channel address/nickname.
// If provided, the desired channel is selected before caarying out the command.
// If not provided, the default channel associated with the account is used.
// If channel selection fails, the API command requiring login will fail.
2013-01-16 23:51:21 +00:00
function api_user() {
$aid = get_account_id();
2016-03-31 23:06:03 +00:00
$channel = App::get_channel();
if(($aid) && (x($_REQUEST,'channel'))) {
// Only change channel if it is different than the current channel
if($channel && x($channel,'channel_address') && $channel['channel_address'] != $_REQUEST['channel']) {
$c = q("select channel_id from channel where channel_address = '%s' and channel_account_id = %d limit 1",
dbesc($_REQUEST['channel']),
intval($aid)
);
if((! $c) || (! change_channel($c[0]['channel_id'])))
return false;
}
}
2013-01-16 23:51:21 +00:00
if ($_SESSION["allow_api"])
2015-01-29 04:56:04 +00:00
return local_channel();
2013-01-16 23:51:21 +00:00
return false;
}
2011-02-15 11:24:21 +00:00
function api_date($str){
//Wed May 23 06:01:13 +0000 2007
2011-08-16 11:55:38 +00:00
return datetime_convert('UTC', 'UTC', $str, "D M d H:i:s +0000 Y" );
2011-02-15 11:24:21 +00:00
}
2016-10-12 01:37:47 +00:00
function api_register_func($path, $func, $auth = false) {
\Zotlabs\Lib\Api_router::register($path,$func,$auth);
2011-02-15 11:24:21 +00:00
}
2011-02-15 11:24:21 +00:00
2011-04-21 15:03:31 +00:00
/**************************
* MAIN API ENTRY POINT *
**************************/
2013-01-19 14:08:13 +00:00
2016-08-12 02:42:44 +00:00
function api_call(){
$p = App::$cmd;
$type = null;
if(strrpos($p,'.')) {
$type = substr($p,strrpos($p,'.')+1);
if(strpos($type,'/') === false) {
$p = substr($p,0,strrpos($p,'.'));
// recalculate App argc,argv since we just extracted the type from it
App::$argv = explode('/',$p);
App::$argc = count(App::$argv);
}
2011-02-15 11:24:21 +00:00
}
if((! $type) || (! in_array($type, [ 'json', 'xml', 'rss', 'as', 'atom' ])))
$type = 'json';
$info = \Zotlabs\Lib\Api_router::find($p);
2016-10-11 23:13:52 +00:00
if(in_array($type, [ 'rss', 'atom', 'as' ])) {
// These types no longer supported.
$info = false;
}
logger('API info: ' . $p . ' type: ' . $type . ' ' . print_r($info,true), LOGGER_DEBUG,LOG_INFO);
if($info) {
if ($info['auth'] === true && api_user() === false) {
api_login($a);
}
load_contact_links(api_user());
$channel = App::get_channel();
logger('API call for ' . $channel['channel_name'] . ': ' . App::$query_string);
logger('API parameters: ' . print_r($_REQUEST,true));
2016-08-12 02:42:44 +00:00
$r = call_user_func($info['func'],$type);
if($r === false)
return;
2016-08-12 02:42:44 +00:00
switch($type) {
case "xml":
header ("Content-Type: text/xml");
2016-10-11 23:13:52 +00:00
return $r;
break;
case "json":
header ("Content-Type: application/json");
// Lookup JSONP to understand these lines. They provide cross-domain AJAX ability.
if ($_GET['callback'])
2016-10-11 23:13:52 +00:00
$r = $_GET['callback'] . '(' . $r . ')' ;
return $r;
break;
}
2011-08-01 03:01:00 +00:00
}
2011-04-21 15:03:31 +00:00
header("HTTP/1.1 404 Not Found");
logger('API call not implemented: ' . App::$query_string . ' - ' . print_r($_REQUEST,true));
$r = '<status><error>not implemented</error></status>';
switch($type){
case "xml":
header ("Content-Type: text/xml");
return '<?xml version="1.0" encoding="UTF-8"?>'."\n".$r;
break;
case "json":
header ("Content-Type: application/json");
return json_encode(array('error' => 'not implemented'));
break;
case "rss":
header ("Content-Type: application/rss+xml");
return '<?xml version="1.0" encoding="UTF-8"?>'."\n".$r;
break;
case "atom":
header ("Content-Type: application/atom+xml");
return '<?xml version="1.0" encoding="UTF-8"?>'."\n".$r;
break;
}
}
2011-04-21 15:03:31 +00:00
/**
* RSS extra info
*/
2016-08-12 02:42:44 +00:00
function api_rss_extra( $arr, $user_info){
2016-10-12 01:37:47 +00:00
if (is_null($user_info)) $user_info = api_get_user();
$arr['$user'] = $user_info;
2011-04-21 15:03:31 +00:00
$arr['$rss'] = array(
'alternate' => $user_info['url'],
2016-03-31 23:06:03 +00:00
'self' => z_root(). "/". App::$query_string,
2016-03-31 05:13:24 +00:00
'base' => z_root(),
2011-04-21 15:03:31 +00:00
'updated' => api_date(null),
2011-07-31 23:35:53 +00:00
'atom_updated' => datetime_convert('UTC','UTC','now',ATOM_TIME),
2011-04-21 15:03:31 +00:00
'language' => $user_info['language'],
2016-03-31 05:13:24 +00:00
'logo' => z_root()."/images/rm-64.png",
2011-04-21 15:03:31 +00:00
);
return $arr;
}
2011-02-15 11:24:21 +00:00
/**
2011-04-21 15:03:31 +00:00
* Returns user info array.
2011-02-15 11:24:21 +00:00
*/
2016-10-11 23:13:52 +00:00
function api_get_user($contact_id = null, $contact_xchan = null){
2016-08-12 02:42:44 +00:00
2011-02-15 11:24:21 +00:00
$user = null;
$extra_query = "";
2011-07-31 07:53:46 +00:00
2011-08-19 14:55:43 +00:00
2015-04-20 01:14:17 +00:00
if(! is_null($contact_xchan)) {
$user = local_channel();
$extra_query = " and abook_xchan = '" . dbesc($contact_xchan) . "' ";
2011-02-15 11:24:21 +00:00
}
2015-04-20 01:14:17 +00:00
else {
2016-10-11 23:13:52 +00:00
if(! is_null($contact_id)){
$user = $contact_id;
2015-04-20 01:14:17 +00:00
$extra_query = " AND abook_id = %d ";
}
2011-02-15 11:24:21 +00:00
2015-04-20 01:14:17 +00:00
if(is_null($user) && x($_GET, 'user_id')) {
$user = intval($_GET['user_id']);
$extra_query = " AND abook_id = %d ";
2015-04-20 01:14:17 +00:00
}
if(is_null($user) && x($_GET, 'screen_name')) {
$user = dbesc($_GET['screen_name']);
$extra_query = " AND xchan_addr like '%s@%%' ";
2016-10-11 23:13:52 +00:00
if(api_user() !== false)
$extra_query .= " AND abook_channel = " . intval(api_user());
2011-02-15 11:24:21 +00:00
}
}
if (! $user) {
if (api_user() === false) {
api_login($a);
2016-08-12 02:42:44 +00:00
return false;
2011-02-16 07:56:47 +00:00
} else {
2015-01-29 04:56:04 +00:00
$user = local_channel();
2015-06-15 04:08:00 +00:00
$extra_query = " AND abook_channel = %d AND abook_self = 1 ";
2011-02-16 07:56:47 +00:00
}
2011-02-15 11:24:21 +00:00
}
2016-08-12 02:42:44 +00:00
logger('api_user: ' . $extra_query . ', user: ' . $user, LOGGER_DATA, LOG_INFO);
2011-02-15 11:24:21 +00:00
// user info
$uinfo = q("SELECT * from abook left join xchan on abook_xchan = xchan_hash
2016-10-11 23:13:52 +00:00
WHERE true
2011-02-15 11:24:21 +00:00
$extra_query",
$user
);
2016-10-11 23:13:52 +00:00
if (! $uinfo) {
return false;
2011-02-15 11:24:21 +00:00
}
2016-10-11 23:13:52 +00:00
2015-12-16 04:21:40 +00:00
$following = false;
2011-02-15 11:24:21 +00:00
2015-06-15 04:08:00 +00:00
if(intval($uinfo[0]['abook_self'])) {
$usr = q("select * from channel where channel_id = %d limit 1",
2013-01-16 23:51:21 +00:00
intval(api_user())
2011-08-05 12:17:18 +00:00
);
2016-10-09 23:13:49 +00:00
$profile = q("select * from profile where uid = %d and is_default = 1 limit 1",
2013-01-16 23:51:21 +00:00
intval(api_user())
2011-08-05 12:17:18 +00:00
);
2015-06-10 23:59:04 +00:00
$item_normal = item_normal();
2011-08-01 03:01:00 +00:00
// count public wall messages
2016-10-09 23:13:49 +00:00
$r = q("SELECT COUNT(id) as total FROM item
WHERE uid = %d
2015-06-10 23:59:04 +00:00
AND item_wall = 1 $item_normal
2016-10-09 23:13:49 +00:00
AND allow_cid='' AND allow_gid='' AND deny_cid='' AND deny_gid=''
2015-12-16 04:21:40 +00:00
AND item_private = 0 ",
intval($usr[0]['channel_id'])
2011-08-01 03:01:00 +00:00
);
2016-10-11 23:13:52 +00:00
if($r) {
$countitms = $r[0]['total'];
$following = true;
}
2011-08-01 03:01:00 +00:00
}
else {
2016-10-09 23:13:49 +00:00
$r = q("SELECT COUNT(id) as total FROM item
WHERE author_xchan = '%s'
2016-10-09 23:13:49 +00:00
AND allow_cid='' AND allow_gid='' AND deny_cid='' AND deny_gid=''
2015-12-16 04:21:40 +00:00
AND item_private = 0 ",
intval($uinfo[0]['xchan_hash'])
2011-08-01 03:01:00 +00:00
);
2016-10-11 23:13:52 +00:00
if($r) {
$countitms = $r[0]['total'];
}
2016-07-20 05:57:23 +00:00
$following = ((get_abconfig($uinfo[0]['abook_channel'],$uinfo[0]['abook_xchan'],'my_perms','view_stream')) ? true : false );
2011-08-01 03:01:00 +00:00
}
2011-02-15 11:24:21 +00:00
// count friends
2013-01-17 03:18:10 +00:00
if($usr) {
2016-10-09 23:13:49 +00:00
$r = q("SELECT COUNT(abook_id) as total FROM abook
2015-06-15 04:08:00 +00:00
WHERE abook_channel = %d AND abook_self = 0 ",
2013-01-17 03:18:10 +00:00
intval($usr[0]['channel_id'])
);
2016-10-11 23:13:52 +00:00
if($r) {
$countfriends = $r[0]['total'];
$countfollowers = $r[0]['total'];
}
2013-01-17 03:18:10 +00:00
}
2011-08-01 05:22:34 +00:00
2016-10-09 23:13:49 +00:00
$r = q("SELECT count(id) as total FROM item where item_starred = 1 and uid = %d " . item_normal(),
intval($uinfo[0]['channel_id'])
2011-08-05 12:17:18 +00:00
);
2016-10-11 23:13:52 +00:00
if($r)
$starred = $r[0]['total'];
2011-08-05 12:17:18 +00:00
2015-06-15 04:08:00 +00:00
if(! intval($uinfo[0]['abook_self'])) {
2011-08-01 03:01:00 +00:00
$countfriends = 0;
2011-08-01 05:22:34 +00:00
$countfollowers = 0;
2011-08-05 12:17:18 +00:00
$starred = 0;
2011-08-01 03:01:00 +00:00
}
2011-02-16 07:56:47 +00:00
2016-10-11 23:13:52 +00:00
$ret = array(
2013-01-17 03:18:10 +00:00
'id' => intval($uinfo[0]['abook_id']),
2015-06-15 04:08:00 +00:00
'self' => (intval($uinfo[0]['abook_self']) ? 1 : 0),
2013-01-17 03:18:10 +00:00
'uid' => intval($uinfo[0]['abook_channel']),
'guid' => $uinfo[0]['xchan_hash'],
'name' => (($uinfo[0]['xchan_name']) ? $uinfo[0]['xchan_name'] : substr($uinfo[0]['xchan_addr'],0,strpos($uinfo[0]['xchan_addr'],'@'))),
'screen_name' => substr($uinfo[0]['xchan_addr'],0,strpos($uinfo[0]['xchan_addr'],'@')),
'location' => ($usr) ? $usr[0]['channel_location'] : '',
'profile_image_url' => $uinfo[0]['xchan_photo_l'],
'url' => $uinfo[0]['xchan_url'],
2016-03-31 05:13:24 +00:00
'contact_url' => z_root() . "/connections/".$uinfo[0]['abook_id'],
2011-08-05 12:17:18 +00:00
'protected' => false,
'friends_count' => intval($countfriends),
2013-01-17 03:18:10 +00:00
'created_at' => api_date($uinfo[0]['abook_created']),
2011-08-05 12:17:18 +00:00
'utc_offset' => "+00:00",
'time_zone' => 'UTC', //$uinfo[0]['timezone'],
2011-02-16 07:56:47 +00:00
'geo_enabled' => false,
2015-04-20 00:39:17 +00:00
'statuses_count' => intval($countitms), //#XXX: fix me
2016-03-31 23:06:03 +00:00
'lang' => App::$language,
2011-08-05 12:17:18 +00:00
'description' => (($profile) ? $profile[0]['pdesc'] : ''),
'followers_count' => intval($countfollowers),
'favourites_count' => intval($starred),
2011-02-16 07:56:47 +00:00
'contributors_enabled' => false,
2011-08-26 14:35:51 +00:00
'follow_request_sent' => true,
2011-02-16 07:56:47 +00:00
'profile_background_color' => 'cfe8f6',
'profile_text_color' => '000000',
'profile_link_color' => 'FF8500',
'profile_sidebar_fill_color' =>'AD0066',
'profile_sidebar_border_color' => 'AD0066',
'profile_background_image_url' => '',
'profile_background_tile' => false,
'profile_use_background_image' => false,
2011-04-21 15:03:31 +00:00
'notifications' => false,
2015-12-16 04:21:40 +00:00
'following' => $following,
2015-04-20 00:39:17 +00:00
'verified' => true // #XXX: fix me
2011-02-16 07:56:47 +00:00
);
2015-04-20 00:39:17 +00:00
$x = api_get_status($uinfo[0]['xchan_hash']);
if($x)
$ret['status'] = $x;
2016-10-11 23:13:52 +00:00
// logger('api_get_user: ' . print_r($ret,true));
2011-02-16 07:56:47 +00:00
return $ret;
}
2011-04-21 15:03:31 +00:00
2016-08-12 02:42:44 +00:00
function api_client_register($type) {
$ret = array();
$key = random_string(16);
$secret = random_string(16);
$name = trim(escape_tags($_REQUEST['application_name']));
if(! $name)
json_return_and_die($ret);
if(is_array($_REQUEST['redirect_uris']))
$redirect = trim($_REQUEST['redirect_uris'][0]);
else
$redirect = trim($_REQUEST['redirect_uris']);
$icon = trim($_REQUEST['logo_uri']);
$r = q("INSERT INTO clients (client_id, pw, clname, redirect_uri, icon, uid)
VALUES ('%s','%s','%s','%s','%s',%d)",
dbesc($key),
dbesc($secret),
dbesc($name),
dbesc($redirect),
dbesc($icon),
intval(0)
);
$ret['client_id'] = $key;
$ret['client_secret'] = $secret;
$ret['expires_at'] = 0;
json_return_and_die($ret);
}
api_register_func('api/client/register','api_client_register', false);
2016-08-12 02:42:44 +00:00
function api_item_get_user( $item) {
2011-07-31 23:35:53 +00:00
// The author is our direct contact, in a conversation with us.
2013-01-19 14:08:13 +00:00
if($item['author']['abook_id']) {
2016-08-12 02:42:44 +00:00
return api_get_user($item['author']['abook_id']);
}
2011-07-31 23:35:53 +00:00
// We don't know this person directly.
2011-08-19 18:33:34 +00:00
$nick = substr($item['author']['xchan_addr'],0,strpos($item['author']['xchan_addr'],'@'));
$name = $item['author']['xchan_name'];
// Generating a random ID
2015-12-01 23:51:15 +00:00
if (! $nick)
$nick = mt_rand(2000000, 2100000);
2011-07-31 07:53:46 +00:00
$ret = array(
2015-12-01 23:51:15 +00:00
'id' => $nick,
2011-08-19 18:33:34 +00:00
'name' => $name,
'screen_name' => $nick,
2011-07-31 07:53:46 +00:00
'location' => '', //$uinfo[0]['default-location'],
'description' => '',
'profile_image_url' => $item['author']['xchan_photo_m'],
'url' => $item['author']['xchan_url'],
2015-04-20 00:39:17 +00:00
'protected' => false,
'followers_count' => 0,
2011-07-31 07:53:46 +00:00
'friends_count' => 0,
2011-07-31 23:35:53 +00:00
'created_at' => '',
'favourites_count' => 0,
2015-04-20 00:39:17 +00:00
'utc_offset' => 0, // #XXX: fix me
2011-07-31 07:53:46 +00:00
'time_zone' => '', //$uinfo[0]['timezone'],
'statuses_count' => 0,
2015-12-16 04:21:40 +00:00
'following' => false,
'statusnet_blocking' => false,
'notifications' => false,
'uid' => 0,
'contact_url' => 0,
'geo_enabled' => false,
2015-04-20 00:39:17 +00:00
'lang' => 'en', // #XXX: fix me
2011-07-31 07:53:46 +00:00
'contributors_enabled' => false,
'follow_request_sent' => false,
'profile_background_color' => 'cfe8f6',
'profile_text_color' => '000000',
'profile_link_color' => 'FF8500',
'profile_sidebar_fill_color' =>'AD0066',
'profile_sidebar_border_color' => 'AD0066',
'profile_background_image_url' => '',
'profile_background_tile' => false,
'profile_use_background_image' => false,
2015-04-20 00:39:17 +00:00
'verified' => true, // #XXX: fix me
'followers' => '' // #XXX: fix me
2011-07-31 07:53:46 +00:00
);
return $ret;
}
2011-04-21 15:03:31 +00:00
/**
* load api $templatename for $type and replace $data array
*/
2016-10-11 23:13:52 +00:00
2011-04-21 15:03:31 +00:00
function api_apply_template($templatename, $type, $data){
2011-06-21 00:16:13 +00:00
2011-04-21 15:03:31 +00:00
switch($type){
case "xml":
2016-10-11 23:13:52 +00:00
if($data) {
foreach($data as $k => $v)
$ret = arrtoxml(str_replace('$','',$k),$v);
}
2011-04-21 15:03:31 +00:00
break;
case "json":
2016-10-11 06:24:30 +00:00
default:
2016-10-11 23:13:52 +00:00
if($data) {
foreach($data as $rv) {
$ret = json_encode($rv);
}
}
2011-04-21 15:03:31 +00:00
break;
}
2016-10-11 06:24:30 +00:00
2011-04-21 15:03:31 +00:00
return $ret;
}
2011-02-16 07:56:47 +00:00
/**
* Returns an HTTP 200 OK response code and a representation of the requesting user if authentication was successful;
* returns a 401 status code and an error message if not.
* http://developer.twitter.com/doc/get/account/verify_credentials
*/
2016-10-11 23:13:52 +00:00
function api_account_verify_credentials($type){
if(api_user()===false)
return false;
2016-10-12 01:37:47 +00:00
$user_info = api_get_user();
2016-10-11 23:13:52 +00:00
return api_apply_template('user', $type, array('user' => $user_info));
2011-02-16 07:56:47 +00:00
}
api_register_func('api/account/verify_credentials','api_account_verify_credentials', true);
2013-01-17 03:18:10 +00:00
2016-08-12 02:42:44 +00:00
function api_account_logout( $type){
2013-01-17 03:18:10 +00:00
require_once('include/auth.php');
App::$session->nuke();
2016-10-11 23:13:52 +00:00
return api_apply_template('user', $type, array('user' => null));
2013-01-17 03:18:10 +00:00
}
api_register_func('api/account/logout','api_account_logout', false);
2011-02-16 07:56:47 +00:00
2013-01-17 03:18:10 +00:00
/**
2013-01-17 03:18:10 +00:00
* get data from $_REQUEST ( e.g. $_POST or $_GET )
*/
2013-01-17 03:18:10 +00:00
function requestdata($k) {
if(array_key_exists($k,$_REQUEST))
return $_REQUEST[$k];
return null;
}
2011-09-12 04:52:50 +00:00
2016-08-12 02:42:44 +00:00
function api_statuses_mediap( $type) {
2013-01-19 14:08:13 +00:00
if (api_user() === false) {
logger('api_statuses_update: no user');
return false;
}
2016-10-12 01:37:47 +00:00
$user_info = api_get_user();
2013-01-19 14:08:13 +00:00
2015-11-17 23:03:27 +00:00
// logger('status_with_media: ' . print_r($_REQUEST,true), LOGGER_DEBUG);
2013-01-19 14:08:13 +00:00
$_REQUEST['type'] = 'wall';
$_REQUEST['profile_uid'] = api_user();
$_REQUEST['api_source'] = true;
2015-08-19 05:14:16 +00:00
2013-01-19 14:08:13 +00:00
$txt = requestdata('status');
require_once('library/HTMLPurifier.auto.php');
require_once('include/html2bbcode.php');
if((strpos($txt,'<') !== false) || (strpos($txt,'>') !== false)) {
$txt = html2bb_video($txt);
$config = HTMLPurifier_Config::createDefault();
2013-01-19 14:08:13 +00:00
$config->set('Cache.DefinitionImpl', null);
$purifier = new HTMLPurifier($config);
2013-01-19 14:08:13 +00:00
$txt = $purifier->purify($txt);
}
$txt = html2bbcode($txt);
2016-03-31 23:06:03 +00:00
App::$argv[1] = $user_info['screen_name'];
$_REQUEST['silent']='1'; //tell wall_upload function to return img info instead of echo
$_FILES['userfile'] = $_FILES['media'];
2016-04-19 03:38:38 +00:00
$mod = new Zotlabs\Module\Wall_attach();
$mod->post();
2013-01-19 14:08:13 +00:00
$_REQUEST['body']=$txt."\n\n".$posted;
2016-04-19 03:38:38 +00:00
$mod = new Zotlabs\Module\Item();
$mod->post();
2013-01-17 03:18:10 +00:00
// this should output the last post (the one we just posted).
2016-08-12 02:42:44 +00:00
return api_status_show($type);
2013-01-17 03:18:10 +00:00
}
api_register_func('api/statuses/mediap','api_statuses_mediap', true);
2016-08-12 02:42:44 +00:00
function api_statuses_update( $type) {
if (api_user() === false) {
logger('api_statuses_update: no user');
return false;
}
logger('api_statuses_update: REQUEST ' . print_r($_REQUEST,true));
logger('api_statuses_update: FILES ' . print_r($_FILES,true));
// set this so that the item_post() function is quiet and doesn't redirect or emit json
$_REQUEST['api_source'] = true;
2016-10-12 01:37:47 +00:00
$user_info = api_get_user();
// convert $_POST array items to the form we use for web posts.
// logger('api_post: ' . print_r($_POST,true));
2011-09-12 04:52:50 +00:00
if(requestdata('htmlstatus')) {
require_once('library/HTMLPurifier.auto.php');
require_once('include/html2bbcode.php');
$txt = requestdata('htmlstatus');
2011-09-12 04:52:50 +00:00
if((strpos($txt,'<') !== false) || (strpos($txt,'>') !== false)) {
$txt = html2bb_video($txt);
2011-09-12 04:52:50 +00:00
$config = HTMLPurifier_Config::createDefault();
$config->set('Cache.DefinitionImpl', null);
$purifier = new HTMLPurifier($config);
$txt = $purifier->purify($txt);
}
$_REQUEST['body'] = html2bbcode($txt);
2011-09-12 04:52:50 +00:00
}
else
$_REQUEST['body'] = requestdata('status');
$parent = requestdata('in_reply_to_status_id');
if(ctype_digit($parent))
$_REQUEST['parent'] = $parent;
else
$_REQUEST['parent_mid'] = $parent;
2015-03-23 03:30:23 +00:00
if($_REQUEST['namespace'] && $parent) {
$x = q("select iid from iconfig where cat = 'system' and k = '%s' and v = '%s' limit 1",
2015-03-23 03:30:23 +00:00
dbesc($_REQUEST['namespace']),
dbesc($parent)
);
if($x) {
$_REQUEST['parent'] = $x[0]['iid'];
}
}
if(requestdata('lat') && requestdata('long'))
$_REQUEST['coord'] = sprintf("%s %s",requestdata('lat'),requestdata('long'));
2013-01-16 23:51:21 +00:00
$_REQUEST['profile_uid'] = api_user();
2012-06-26 00:45:33 +00:00
if($parent)
$_REQUEST['type'] = 'net-comment';
else {
$_REQUEST['type'] = 'wall';
if(x($_FILES,'media')) {
2015-12-18 00:22:13 +00:00
if(is_array($_FILES['media']['name'])) {
$num_uploads = count($_FILES['media']['name']);
for($x = 0; $x < $num_uploads; $x ++) {
$_FILES['userfile'] = array();
$_FILES['userfile']['name'] = $_FILES['media']['name'][$x];
$_FILES['userfile']['type'] = $_FILES['media']['type'][$x];
$_FILES['userfile']['tmp_name'] = $_FILES['media']['tmp_name'][$x];
$_FILES['userfile']['error'] = $_FILES['media']['error'][$x];
$_FILES['userfile']['size'] = $_FILES['media']['size'][$x];
// upload each image if we have any
$_REQUEST['silent']='1'; //tell wall_upload function to return img info instead of echo
2016-04-19 03:38:38 +00:00
$mod = new Zotlabs\Module\Wall_attach();
2016-03-31 23:06:03 +00:00
App::$data['api_info'] = $user_info;
2016-04-19 03:38:38 +00:00
$media = $mod->post();
2015-12-18 00:22:13 +00:00
if(strlen($media)>0)
$_REQUEST['body'] .= "\n\n" . $media;
}
}
else {
// AndStatus doesn't present media as an array
$_FILES['userfile'] = $_FILES['media'];
2015-12-14 03:15:42 +00:00
// upload each image if we have any
$_REQUEST['silent']='1'; //tell wall_upload function to return img info instead of echo
2016-04-19 03:38:38 +00:00
$mod = new Zotlabs\Module\Wall_attach();
2016-03-31 23:06:03 +00:00
App::$data['api_info'] = $user_info;
2016-04-19 03:38:38 +00:00
$media = $mod->post();
2015-12-14 03:15:42 +00:00
if(strlen($media)>0)
$_REQUEST['body'] .= "\n\n" . $media;
}
}
}
// call out normal post function
2016-04-19 03:38:38 +00:00
$mod = new Zotlabs\Module\Item();
$mod->post();
// this should output the last post (the one we just posted).
2016-08-12 02:42:44 +00:00
return api_status_show($type);
}
api_register_func('api/statuses/update_with_media','api_statuses_update', true);
api_register_func('api/statuses/update','api_statuses_update', true);
function api_get_status($xchan_hash) {
require_once('include/security.php');
2015-06-10 23:59:04 +00:00
$item_normal = item_normal();
$lastwall = q("SELECT * from item where
2015-06-10 23:59:04 +00:00
item_private = 0 $item_normal
and author_xchan = '%s'
and allow_cid = '' and allow_gid = '' and deny_cid = '' and deny_gid = ''
and verb = '%s'
order by created desc limit 1",
dbesc($xchan_hash),
dbesc(ACTIVITY_POST)
);
if($lastwall){
$lastwall = $lastwall[0];
$in_reply_to_status_id = '';
$in_reply_to_user_id = '';
$in_reply_to_screen_name = '';
if($lastwall['author_xchan'] != $lastwall['owner_xchan']) {
$w = q("select * from abook left join xchan on abook_xchan = xchan_hash where
xchan_hash = '%s' limit 1",
dbesc($lastwall['owner_xchan'])
);
if($w) {
$in_reply_to_user_id = $w[0]['abook_id'];
$in_reply_to_screen_name = substr($w[0]['xchan_addr'],0,strpos($w[0]['xchan_addr'],'@'));
}
}
if ($lastwall['parent']!=$lastwall['id']) {
$in_reply_to_status_id=$lastwall['thr_parent'];
if(! $in_reply_to_user_id) {
$in_reply_to_user_id = $user_info['id'];
$in_reply_to_screen_name = $user_info['screen_name'];
}
}
unobscure($lastwall);
$status_info = array(
'text' => html2plain(prepare_text($lastwall['body'],$lastwall['mimetype']), 0),
'truncated' => false,
'created_at' => api_date($lastwall['created']),
'in_reply_to_status_id' => $in_reply_to_status_id,
'source' => (($lastwall['app']) ? $lastwall['app'] : 'web'),
'id' => ($lastwall['id']),
'in_reply_to_user_id' => $in_reply_to_user_id,
'in_reply_to_screen_name' => $in_reply_to_screen_name,
'geo' => '',
'favorited' => false,
'coordinates' => $lastwall['coord'],
'place' => $lastwall['location'],
'contributors' => ''
);
}
return $status_info;
}
2016-08-12 02:42:44 +00:00
function api_status_show( $type){
2016-10-12 01:37:47 +00:00
$user_info = api_get_user();
2013-01-17 03:18:10 +00:00
// get last public message
2013-01-21 02:36:33 +00:00
require_once('include/security.php');
2015-06-10 23:59:04 +00:00
$item_normal = item_normal();
2013-01-21 02:36:33 +00:00
2015-02-16 23:08:53 +00:00
$lastwall = q("SELECT * from item where
2015-06-10 23:59:04 +00:00
item_private = 0 $item_normal
2013-01-17 03:18:10 +00:00
and author_xchan = '%s'
and allow_cid = '' and allow_gid = '' and deny_cid = '' and deny_gid = ''
and verb = '%s'
order by created desc limit 1",
dbesc($user_info['guid']),
dbesc(ACTIVITY_POST)
);
2013-01-17 03:18:10 +00:00
if($lastwall){
$lastwall = $lastwall[0];
$in_reply_to_status_id = '';
$in_reply_to_user_id = '';
$in_reply_to_screen_name = '';
2013-01-17 03:18:10 +00:00
if($lastwall['author_xchan'] != $lastwall['owner_xchan']) {
$w = q("select * from abook left join xchan on abook_xchan = xchan_hash where
xchan_hash = '%s' limit 1",
dbesc($lastwall['owner_xchan'])
);
if($w) {
$in_reply_to_user_id = $w[0]['abook_id'];
$in_reply_to_screen_name = substr($w[0]['xchan_addr'],0,strpos($w[0]['xchan_addr'],'@'));
}
}
if ($lastwall['parent']!=$lastwall['id']) {
2013-01-17 03:18:10 +00:00
$in_reply_to_status_id=$lastwall['thr_parent'];
if(! $in_reply_to_user_id) {
$in_reply_to_user_id = $user_info['id'];
$in_reply_to_screen_name = $user_info['screen_name'];
}
}
unobscure($lastwall);
$status_info = array(
'text' => html2plain(prepare_text($lastwall['body'],$lastwall['mimetype']), 0),
'truncated' => false,
'created_at' => api_date($lastwall['created']),
'in_reply_to_status_id' => $in_reply_to_status_id,
'source' => (($lastwall['app']) ? $lastwall['app'] : 'web'),
2013-11-27 00:38:48 +00:00
'id' => ($lastwall['id']),
'in_reply_to_user_id' => $in_reply_to_user_id,
'in_reply_to_screen_name' => $in_reply_to_screen_name,
'geo' => '',
'favorited' => false,
'coordinates' => $lastwall['coord'],
'place' => $lastwall['location'],
'contributors' => ''
);
$status_info['user'] = $user_info;
2015-12-12 05:10:20 +00:00
if(array_key_exists('status',$status_info['user']))
unset($status_info['user']['status']);
}
return api_apply_template("status", $type, array('$status' => $status_info));
}
2011-02-16 07:56:47 +00:00
/**
* Returns extended information of a given user, specified by ID or screen name as per the required id parameter.
* The author's most recent status will be returned inline.
* http://developer.twitter.com/doc/get/users/show
*/
2013-01-17 03:18:10 +00:00
// FIXME - this is essentially the same as api_status_show except for the template formatting at the end. Consolidate.
2016-08-12 02:42:44 +00:00
function api_users_show( $type){
2016-10-12 01:37:47 +00:00
$user_info = api_get_user();
2013-01-17 03:18:10 +00:00
2013-01-21 02:36:33 +00:00
require_once('include/security.php');
2015-06-10 23:59:04 +00:00
$item_normal = item_normal();
2013-01-21 02:36:33 +00:00
2013-01-17 03:18:10 +00:00
$lastwall = q("SELECT * from item where 1
2015-06-10 23:59:04 +00:00
and item_private != 0 $item_normal
2013-01-17 03:18:10 +00:00
and author_xchan = '%s'
and allow_cid = '' and allow_gid = '' and deny_cid = '' and deny_gid = ''
and verb = '%s'
order by created desc limit 1",
dbesc($user_info['guid']),
dbesc(ACTIVITY_POST)
2011-02-15 11:24:21 +00:00
);
2011-02-16 07:56:47 +00:00
2013-01-17 03:18:10 +00:00
if($lastwall){
2011-04-21 15:03:31 +00:00
$lastwall = $lastwall[0];
$in_reply_to_status_id = '';
$in_reply_to_user_id = '';
$in_reply_to_screen_name = '';
2013-01-17 03:18:10 +00:00
if($lastwall['author_xchan'] != $lastwall['owner_xchan']) {
$w = q("select * from abook left join xchan on abook_xchan = xchan_hash where
xchan_hash = '%s' limit 1",
dbesc($lastwall['owner_xchan'])
);
if($w) {
$in_reply_to_user_id = $w[0]['abook_id'];
$in_reply_to_screen_name = substr($w[0]['xchan_addr'],0,strpos($w[0]['xchan_addr'],'@'));
}
}
2011-04-21 15:03:31 +00:00
if ($lastwall['parent']!=$lastwall['id']) {
2013-01-17 03:18:10 +00:00
$in_reply_to_status_id=$lastwall['thr_parent'];
if(! $in_reply_to_user_id) {
$in_reply_to_user_id = $user_info['id'];
$in_reply_to_screen_name = $user_info['screen_name'];
}
2011-04-21 15:03:31 +00:00
}
unobscure($lastwall);
2011-04-21 15:03:31 +00:00
$user_info['status'] = array(
'text' => html2plain(prepare_text($lastwall['body'],$lastwall['mimetype']), 0),
2011-04-21 15:03:31 +00:00
'truncated' => false,
2013-01-17 03:18:10 +00:00
'created_at' => api_date($lastwall['created']),
2011-04-21 15:03:31 +00:00
'in_reply_to_status_id' => $in_reply_to_status_id,
2013-01-17 03:18:10 +00:00
'source' => (($lastwall['app']) ? $lastwall['app'] : 'web'),
'id' => (($w) ? $w[0]['abook_id'] : $user_info['id']),
2011-04-21 15:03:31 +00:00
'in_reply_to_user_id' => $in_reply_to_user_id,
'in_reply_to_screen_name' => $in_reply_to_screen_name,
'geo' => '',
2013-01-17 03:18:10 +00:00
'favorited' => false,
2011-04-21 15:03:31 +00:00
'coordinates' => $lastwall['coord'],
'place' => $lastwall['location'],
2013-01-17 03:18:10 +00:00
'contributors' => ''
2011-04-21 15:03:31 +00:00
);
2013-01-17 03:18:10 +00:00
2011-04-21 15:03:31 +00:00
}
return api_apply_template("user", $type, array('$user' => $user_info));
2011-02-15 11:24:21 +00:00
}
api_register_func('api/users/show','api_users_show');
2011-02-15 11:24:21 +00:00
/**
*
2011-02-15 11:24:21 +00:00
* http://developer.twitter.com/doc/get/statuses/home_timeline
*
2011-04-21 15:03:31 +00:00
* TODO: Optional parameters
* TODO: Add reply info
2011-02-15 11:24:21 +00:00
*/
2016-08-12 02:42:44 +00:00
function api_statuses_home_timeline( $type){
2013-01-19 14:08:13 +00:00
if (api_user() === false)
return false;
2016-10-12 01:37:47 +00:00
$user_info = api_get_user();
2013-01-19 14:08:13 +00:00
// get last network messages
2011-07-31 23:35:53 +00:00
2011-08-26 14:35:51 +00:00
// params
2013-01-19 14:08:13 +00:00
$count = (x($_REQUEST,'count')?$_REQUEST['count']:20);
$page = (x($_REQUEST,'page')?$_REQUEST['page']-1:0);
if($page < 0)
$page = 0;
$since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0);
$max_id = (x($_REQUEST,'max_id')?$_REQUEST['max_id']:0);
$exclude_replies = (x($_REQUEST,'exclude_replies')?1:0);
//$since_id = 0;//$since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0);
$start = $page*$count;
//$include_entities = (x($_REQUEST,'include_entities')?$_REQUEST['include_entities']:false);
$sql_extra = '';
2012-03-18 18:00:24 +00:00
if ($max_id > 0)
2016-10-09 23:13:49 +00:00
$sql_extra .= ' AND item.id <= '.intval($max_id);
if ($exclude_replies > 0)
2016-10-09 23:13:49 +00:00
$sql_extra .= ' AND item.parent = item.id';
2012-03-18 18:00:24 +00:00
2013-01-20 23:36:04 +00:00
if (api_user() != $user_info['uid']) {
2016-03-31 23:06:03 +00:00
$observer = App::get_observer();
2013-01-20 23:36:04 +00:00
require_once('include/permissions.php');
if(! perm_is_allowed($user_info['uid'],(($observer) ? $observer['xchan_hash'] : ''),'view_stream'))
return '';
$sql_extra .= " and item_private = 0 ";
}
2015-06-10 23:59:04 +00:00
$item_normal = item_normal();
$r = q("SELECT * from item WHERE uid = %d $item_normal
2011-07-31 23:35:53 +00:00
$sql_extra
2013-01-19 14:08:13 +00:00
AND id > %d
ORDER BY received DESC LIMIT %d ,%d ",
2011-07-31 23:35:53 +00:00
intval($user_info['uid']),
2011-08-19 18:33:34 +00:00
intval($since_id),
2013-01-19 14:08:13 +00:00
intval($start),
intval($count)
2011-07-31 23:35:53 +00:00
);
xchan_query($r,true);
2013-01-19 14:08:13 +00:00
2011-07-31 23:35:53 +00:00
$ret = api_format_items($r,$user_info);
// We aren't going to try to figure out at the item, group, and page
// level which items you've seen and which you haven't. If you're looking
// at the network timeline just mark everything seen.
2013-01-20 23:36:04 +00:00
if (api_user() == $user_info['uid']) {
$r = q("UPDATE item SET item_unseen = 0 WHERE item_unseen = 1 and uid = %d",
2013-01-20 23:36:04 +00:00
intval($user_info['uid'])
);
}
2011-07-31 23:35:53 +00:00
$data = array('$statuses' => $ret);
return api_apply_template("timeline", $type, $data);
}
2016-10-12 01:37:47 +00:00
2011-07-31 23:35:53 +00:00
api_register_func('api/statuses/home_timeline','api_statuses_home_timeline', true);
api_register_func('api/statuses/friends_timeline','api_statuses_home_timeline', true);
2016-08-12 02:42:44 +00:00
function api_statuses_public_timeline( $type){
2013-01-16 23:51:21 +00:00
if (api_user()===false) return false;
2016-10-12 01:37:47 +00:00
$user_info = api_get_user();
2012-04-08 18:19:14 +00:00
2015-04-20 01:57:12 +00:00
$sys = get_sys_channel();
2012-04-08 18:19:14 +00:00
// params
$count = (x($_REQUEST,'count')?$_REQUEST['count']:20);
$page = (x($_REQUEST,'page')?$_REQUEST['page']-1:0);
if ($page<0) $page=0;
$since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0);
$max_id = (x($_REQUEST,'max_id')?$_REQUEST['max_id']:0);
//$since_id = 0;//$since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0);
2012-04-08 18:19:14 +00:00
$start = $page*$count;
//$include_entities = (x($_REQUEST,'include_entities')?$_REQUEST['include_entities']:false);
if ($max_id > 0)
2016-10-09 23:13:49 +00:00
$sql_extra = 'AND item.id <= '.intval($max_id);
require_once('include/security.php');
2015-06-10 23:59:04 +00:00
$item_normal = item_normal();
2012-04-08 18:19:14 +00:00
2015-06-10 23:59:04 +00:00
$r = q("select * from item where allow_cid = '' and allow_gid = ''
2013-01-19 14:08:13 +00:00
and deny_cid = '' and deny_gid = ''
and item_private = 0
2015-06-10 23:59:04 +00:00
$item_normal
2015-04-20 01:57:12 +00:00
and uid = " . $sys['channel_id'] . "
2012-04-08 18:19:14 +00:00
$sql_extra
AND id > %d group by mid
2015-08-19 05:14:16 +00:00
order by received desc LIMIT %d OFFSET %d ",
2012-04-08 18:19:14 +00:00
intval($since_id),
PostgreSQL support initial commit There were 11 main types of changes: - UPDATE's and DELETE's sometimes had LIMIT 1 at the end of them. This is not only non-compliant but it would certainly not do what whoever wrote it thought it would. It is likely this mistake was just copied from Friendica. All of these instances, the LIMIT 1 was simply removed. - Bitwise operations (and even some non-zero int checks) erroneously rely on MySQL implicit integer-boolean conversion in the WHERE clauses. This is non-compliant (and bad programming practice to boot). Proper explicit boolean conversions were added. New queries should use proper conventions. - MySQL has a different operator for bitwise XOR than postgres. Rather than add yet another dba_ func, I converted them to "& ~" ("AND NOT") when turning off, and "|" ("OR") when turning on. There were no true toggles (XOR). New queries should refrain from using XOR when not necessary. - There are several fields which the schema has marked as NOT NULL, but the inserts don't specify them. The reason this works is because mysql totally ignores the constraint and adds an empty text default automatically. Again, non-compliant, obviously. In these cases a default of empty text was added. - Several statements rely on a non-standard MySQL feature (http://dev.mysql.com/doc/refman/5.5/en/group-by-handling.html). These queries can all be rewritten to be standards compliant. Interestingly enough, the newly rewritten standards compliant queries run a zillion times faster, even on MySQL. - A couple of function/operator name translations were needed (RAND/RANDOM, GROUP_CONCAT/STRING_AGG, UTC_NOW, REGEXP/~, ^/#) -- assist functions added in the dba_ - INTERVALs: postgres requires quotes around the value, mysql requires that there are not quotes around the value -- assist functions added in the dba_ - NULL_DATE's -- Postgres does not allow the invalid date '0000-00-00 00:00:00' (there is no such thing as year 0 or month 0 or day 0). We use '0001-01-01 00:00:00' for postgres. Conversions are handled in Zot/item packets automagically by quoting all dates with dbescdate(). - char(##) specifications in the schema creates fields with blank spaces that aren't trimmed in the code. MySQL apparently treats char(##) as varchar(##), again, non-compliant. Since postgres works better with text fields anyway, this ball of bugs was simply side-stepped by using 'text' datatype for all text fields in the postgres schema. varchar was used in a couple of places where it actually seemed appropriate (size constraint), but without rigorously vetting that all of the PHP code actually validates data, new bugs might come out from under the rug. - postgres doesn't store nul bytes and a few other non-printables in text fields, even when quoted. bytea fields were used when storing binary data (photo.data, attach.data). A new dbescbin() function was added to handle this transparently. - postgres does not support LIMIT #,# syntax. All databases support LIMIT # OFFSET # syntax. Statements were updated to be standard. These changes require corresponding changes in the coding standards. Please review those before adding any code going forward. Still on my TODO list: - remove quotes from non-reserved identifiers and make reserved identifiers use dba func for quoting - Rewrite search queries for better results (both MySQL and Postgres)
2014-11-13 20:21:58 +00:00
intval($count),
intval($start)
2013-01-19 14:08:13 +00:00
);
xchan_query($r,true);
2012-04-08 18:19:14 +00:00
$ret = api_format_items($r,$user_info);
2012-04-08 18:19:14 +00:00
$data = array('$statuses' => $ret);
switch($type){
case "atom":
case "rss":
2016-08-12 02:42:44 +00:00
$data = api_rss_extra( $data, $user_info);
2012-04-08 18:19:14 +00:00
break;
case "as":
2016-08-12 02:42:44 +00:00
$as = api_format_as( $ret, $user_info);
2016-03-31 23:06:03 +00:00
$as['title'] = App::$config['sitename']. " " . t('Public Timeline');
2016-03-31 05:13:24 +00:00
$as['link']['url'] = z_root()."/";
2012-04-08 18:19:14 +00:00
return($as);
break;
}
2012-04-08 18:19:14 +00:00
return api_apply_template("timeline", $type, $data);
}
api_register_func('api/statuses/public_timeline','api_statuses_public_timeline', true);
/**
*
2013-01-19 14:08:13 +00:00
*/
2016-08-12 02:42:44 +00:00
function api_statuses_show( $type){
2013-01-16 23:51:21 +00:00
if (api_user()===false) return false;
2016-10-12 01:37:47 +00:00
$user_info = api_get_user();
// params
2013-01-19 14:08:13 +00:00
$id = intval(argv(3));
2015-12-12 05:10:20 +00:00
if(! $id)
$id = $_REQUEST['id'];
logger('API: api_statuses_show: '.$id);
//$include_entities = (x($_REQUEST,'include_entities')?$_REQUEST['include_entities']:false);
$conversation = (x($_REQUEST,'conversation')?1:0);
$sql_extra = '';
if ($conversation)
2016-10-09 23:13:49 +00:00
$sql_extra .= " AND item.parent = %d ORDER BY received ASC ";
else
2016-10-09 23:13:49 +00:00
$sql_extra .= " AND item.id = %d";
2015-06-10 23:59:04 +00:00
$item_normal = item_normal();
$r = q("select * from item where true $item_normal $sql_extra",
intval($id)
);
2015-12-12 05:10:20 +00:00
xchan_query($r,true);
$ret = api_format_items($r,$user_info);
2015-12-12 05:10:20 +00:00
if ($conversation) {
$data = array('$statuses' => $ret);
return api_apply_template("timeline", $type, $data);
} else {
$data = array('$status' => $ret[0]);
/*switch($type){
case "atom":
case "rss":
2016-08-12 02:42:44 +00:00
$data = api_rss_extra( $data, $user_info);
}*/
return api_apply_template("status", $type, $data);
}
}
api_register_func('api/statuses/show','api_statuses_show', true);
2011-07-31 23:35:53 +00:00
/**
*
*/
2016-08-12 02:42:44 +00:00
function api_statuses_repeat( $type){
2013-01-16 23:51:21 +00:00
if (api_user()===false) return false;
2016-10-12 01:37:47 +00:00
$user_info = api_get_user();
// params
2013-01-21 02:36:33 +00:00
$id = intval(argv(3));
logger('API: api_statuses_repeat: '.$id);
//$include_entities = (x($_REQUEST,'include_entities')?$_REQUEST['include_entities']:false);
2013-01-21 02:36:33 +00:00
2016-03-31 23:06:03 +00:00
$observer = App::get_observer();
2013-01-21 02:36:33 +00:00
2015-06-10 23:59:04 +00:00
$item_normal = item_normal();
$r = q("SELECT * from item where and id = %d $item_normal limit 1",
intval($id)
);
2013-01-21 02:36:33 +00:00
if(perm_is_allowed($r[0]['uid'],$observer['xchan_hash'],'view_stream')) {
if ($r[0]['body'] != "") {
$_REQUEST['body'] = html_entity_decode("&#x2672; ", ENT_QUOTES, 'UTF-8')."[zrl=".$r[0]['reply_url']."]".$r[0]['reply_author']."[/zrl] \n".$r[0]['body'];
2013-01-21 02:36:33 +00:00
$_REQUEST['profile_uid'] = api_user();
$_REQUEST['type'] = 'wall';
$_REQUEST['api_source'] = true;
2016-04-19 03:38:38 +00:00
$mod = new Zotlabs\Module\Item();
$mod->post();
2013-01-21 02:36:33 +00:00
}
}
2013-01-21 02:36:33 +00:00
else
return false;
if ($type == 'xml')
$ok = "true";
else
$ok = "ok";
return api_apply_template('test', $type, array('$ok' => $ok));
}
api_register_func('api/statuses/retweet','api_statuses_repeat', true);
/**
*
*/
2013-01-21 02:36:33 +00:00
2016-08-12 02:42:44 +00:00
function api_statuses_destroy( $type){
2013-01-16 23:51:21 +00:00
if (api_user()===false) return false;
2016-10-12 01:37:47 +00:00
$user_info = api_get_user();
// params
2013-01-20 23:36:04 +00:00
$id = intval(argv(3));
if($id) {
// first prove that we own the item
$r = q("select * from item where id = %d and uid = %d limit 1",
intval($id),
intval($user_info['uid'])
);
if(! $r)
return false;
}
else {
if($_REQUEST['namespace'] && $_REQUEST['remote_id']) {
$r = q("select * from iconfig left join item on iconfig.iid = item.id
where cat = 'system' and k = '%s' and v = '%s' and item.uid = %d limit 1",
dbesc($_REQUEST['namespace']),
dbesc($_REQUEST['remote_id']),
intval($user_info['uid'])
);
if(! $r)
return false;
$id = $r[0]['iid'];
}
if($_REQUEST['namespace'] && $_REQUEST['comment_id']) {
$r = q("select * from iconfig left join item on item.id = iconfig.iid where cat = 'system' and k = '%s' and v = '%s' and uid = %d and item.id != item.parent limit 1",
dbesc($_REQUEST['namespace']),
dbesc($_REQUEST['comment_id']),
intval($user_info['uid'])
);
if(! $r)
return false;
$id = $r[0]['iid'];
}
}
if(! $id)
return false;
2013-11-27 00:38:48 +00:00
logger('API: api_statuses_destroy: '.$id);
require_once('include/items.php');
drop_item($id, false);
if ($type == 'xml')
$ok = "true";
else
$ok = "ok";
return api_apply_template('test', $type, array('$ok' => $ok));
}
api_register_func('api/statuses/destroy','api_statuses_destroy', true);
/**
*
* http://developer.twitter.com/doc/get/statuses/mentions
*
*/
2013-01-20 23:36:04 +00:00
2016-08-12 02:42:44 +00:00
function api_statuses_mentions( $type){
2013-01-16 23:51:21 +00:00
if (api_user()===false) return false;
2016-10-12 01:37:47 +00:00
$user_info = api_get_user();
// get last network messages
// params
$count = (x($_REQUEST,'count')?$_REQUEST['count']:20);
$page = (x($_REQUEST,'page')?$_REQUEST['page']-1:0);
if ($page<0) $page=0;
$since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0);
$max_id = (x($_REQUEST,'max_id')?$_REQUEST['max_id']:0);
//$since_id = 0;//$since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0);
$start = $page*$count;
//$include_entities = (x($_REQUEST,'include_entities')?$_REQUEST['include_entities']:false);
2016-03-31 23:06:03 +00:00
$myurl = z_root() . '/channel/'. App::$user['nickname'];
$myurl = substr($myurl,strpos($myurl,'://')+3);
$myurl = str_replace(array('www.','.'),array('','\\.'),$myurl);
$diasp_url = str_replace('/channel/','/u/',$myurl);
$sql_extra .= " AND item_mentionsme = 1 ";
if ($max_id > 0)
$sql_extra .= " AND item.id <= " . intval($max_id) . " ";
require_once('include/security.php');
$item_normal = item_normal();
$r = q("select * from item where uid = " . intval(api_user()) . "
$item_normal $sql_extra
AND id > %d group by mid
order by received desc LIMIT %d OFFSET %d ",
intval($since_id),
intval($count),
intval($start)
);
xchan_query($r,true);
$ret = api_format_items($r,$user_info);
$data = array('$statuses' => $ret);
switch($type){
case "atom":
case "rss":
2016-08-12 02:42:44 +00:00
$data = api_rss_extra( $data, $user_info);
break;
case "as":
2016-08-12 02:42:44 +00:00
$as = api_format_as( $ret, $user_info);
2016-03-31 23:06:03 +00:00
$as["title"] = App::$config['sitename']." Mentions";
2016-03-31 05:13:24 +00:00
$as['link']['url'] = z_root()."/";
return($as);
break;
}
return api_apply_template("timeline", $type, $data);
}
api_register_func('api/statuses/mentions','api_statuses_mentions', true);
2013-01-20 23:36:04 +00:00
// FIXME?? I don't think mentions and replies are congruent in this case
api_register_func('api/statuses/replies','api_statuses_mentions', true);
2012-03-18 18:00:24 +00:00
2011-07-31 23:35:53 +00:00
2016-08-12 02:42:44 +00:00
function api_statuses_user_timeline( $type){
2013-01-16 23:51:21 +00:00
if (api_user()===false) return false;
2011-07-31 23:35:53 +00:00
2016-10-12 01:37:47 +00:00
$user_info = api_get_user();
2013-01-20 23:36:04 +00:00
// get last network messages
2011-07-31 23:35:53 +00:00
2011-08-26 14:35:51 +00:00
2013-01-16 23:51:21 +00:00
logger("api_statuses_user_timeline: api_user: ". api_user() .
2011-08-26 14:35:51 +00:00
"\nuser_info: ".print_r($user_info, true) .
"\n_REQUEST: ".print_r($_REQUEST, true),
LOGGER_DEBUG);
// params
2011-08-19 18:33:34 +00:00
$count = (x($_REQUEST,'count')?$_REQUEST['count']:20);
$page = (x($_REQUEST,'page')?$_REQUEST['page']-1:0);
if ($page<0) $page=0;
$since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0);
$exclude_replies = (x($_REQUEST,'exclude_replies')?1:0);
//$since_id = 0;//$since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0);
$start = $page*$count;
$sql_extra = '';
2016-10-09 23:13:49 +00:00
if ($user_info['self']==1) $sql_extra .= " AND item.wall = 1 ";
2014-01-25 23:51:10 +00:00
//FIXME - this isn't yet implemented
2016-10-09 23:13:49 +00:00
if ($exclude_replies > 0) $sql_extra .= ' AND item.parent = item.id';
// $r = q("SELECT item.*, item.id AS item_id,
// contact.name, contact.photo, contact.url, contact.rel,
// contact.network, contact.thumb, contact.dfrn_id, contact.self,
// contact.id AS cid, contact.uid AS contact-uid
// FROM item, contact
// WHERE item.uid = %d
// 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
2014-01-25 02:50:47 +00:00
// $sql_extra
2016-10-09 23:13:49 +00:00
// AND item.id>%d
// ORDER BY item.received DESC LIMIT %d ,%d ",
2014-01-25 02:50:47 +00:00
// intval(api_user()),
// intval($user_info['id']),
// intval($since_id),
// intval($start), intval($count)
// );
2014-01-25 23:51:10 +00:00
$arr = array(
2015-08-19 05:14:16 +00:00
'uid' => api_user(),
'since_id' => $since_id,
'start' => $start,
'records' => $count);
2014-01-25 23:51:10 +00:00
if ($user_info['self']==1)
$arr['wall'] = 1;
else
$arr['cid'] = $user_info['id'];
2016-03-31 23:06:03 +00:00
$r = items_fetch($arr,App::get_channel(),get_observer_hash());
2015-08-19 05:14:16 +00:00
2011-07-31 23:35:53 +00:00
$ret = api_format_items($r,$user_info);
2011-07-31 23:35:53 +00:00
$data = array('$statuses' => $ret);
switch($type){
case "atom":
case "rss":
2016-08-12 02:42:44 +00:00
$data = api_rss_extra( $data, $user_info);
2011-07-31 23:35:53 +00:00
}
2011-07-31 23:35:53 +00:00
return api_apply_template("timeline", $type, $data);
}
api_register_func('api/statuses/user_timeline','api_statuses_user_timeline', true);
2015-08-19 05:14:16 +00:00
/**
* Star/unstar an item
* param: id : id of the item
*
* api v1 : https://web.archive.org/web/20131019055350/https://dev.twitter.com/docs/api/1/post/favorites/create/%3Aid
*/
2016-10-12 01:37:47 +00:00
function api_favorites_create_destroy($type){
2016-10-12 01:37:47 +00:00
if(api_user() === false)
return false;
2016-10-12 01:37:47 +00:00
$action = str_replace('.' . $type,'',argv(2));
2015-08-19 05:14:16 +00:00
if (argc() > 3) {
$itemid = intval(argv(3));
2016-10-12 01:37:47 +00:00
}
else {
2015-08-19 05:14:16 +00:00
$itemid = intval($_REQUEST['id']);
}
$item = q("SELECT * FROM item WHERE id = %d AND uid = %d",
intval($itemid),
intval(api_user())
);
2016-10-12 01:37:47 +00:00
if(! $item)
return false;
switch($action){
2016-10-12 01:37:47 +00:00
case 'create':
$flags = $item[0]['item_starred'] = 1;
break;
2016-10-12 01:37:47 +00:00
case 'destroy':
$flags = $item[0]['item_starred'] = 0;
break;
default:
return false;
}
$r = q("UPDATE item SET item_starred = %d where id = %d and uid = %d",
intval($flags),
intval($itemid),
intval(api_user())
);
if(! $r)
return false;
$item = q("SELECT * FROM item WHERE id = %d AND uid = %d",
intval($itemid),
intval(api_user())
);
xchan_query($item,true);
2016-10-12 01:37:47 +00:00
$user_info = api_get_user();
2015-08-19 05:14:16 +00:00
$rets = api_format_items($item,$user_info);
$ret = $rets[0];
2016-10-12 01:37:47 +00:00
$data = array('status' => $ret);
2016-10-12 01:37:47 +00:00
return api_apply_template('status', $type, $data);
2015-08-19 05:14:16 +00:00
}
2015-08-19 05:14:16 +00:00
api_register_func('api/favorites/create', 'api_favorites_create_destroy', true);
api_register_func('api/favorites/destroy', 'api_favorites_create_destroy', true);
2016-08-12 02:42:44 +00:00
function api_favorites( $type){
if (api_user()===false)
return false;
2016-10-12 01:37:47 +00:00
$user_info = api_get_user();
// params
2015-08-19 05:14:16 +00:00
$count = (x($_REQUEST,'count')?$_REQUEST['count']:20);
$page = (x($_REQUEST,'page')?$_REQUEST['page']-1:0);
if($page < 0)
$page = 0;
$since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0);
$max_id = (x($_REQUEST,'max_id')?$_REQUEST['max_id']:0);
$exclude_replies = (x($_REQUEST,'exclude_replies')?1:0);
$start = $page*$count;
//$include_entities = (x($_REQUEST,'include_entities')?$_REQUEST['include_entities']:false);
2011-07-31 23:35:53 +00:00
$sql_extra = '';
if ($max_id > 0)
2016-10-09 23:13:49 +00:00
$sql_extra .= ' AND item.id <= '.intval($max_id);
if ($exclude_replies > 0)
2016-10-09 23:13:49 +00:00
$sql_extra .= ' AND item.parent = item.id';
if (api_user() != $user_info['uid']) {
2016-03-31 23:06:03 +00:00
$observer = App::get_observer();
require_once('include/permissions.php');
if(! perm_is_allowed($user_info['uid'],(($observer) ? $observer['xchan_hash'] : ''),'view_stream'))
return '';
$sql_extra .= " and item_private = 0 ";
2011-08-26 14:35:51 +00:00
}
2015-06-10 23:59:04 +00:00
$item_normal = item_normal();
$r = q("SELECT * from item WHERE uid = %d $item_normal
and item_starred = 1 $sql_extra
AND id > %d
ORDER BY received DESC LIMIT %d ,%d ",
intval($user_info['uid']),
intval($since_id),
intval($start),
intval($count)
);
xchan_query($r,true);
$ret = api_format_items($r,$user_info);
2016-10-12 01:37:47 +00:00
$data = array('statuses' => $ret);
return(api_apply_template("timeline", $type, $data));
2011-07-31 23:35:53 +00:00
}
api_register_func('api/favorites','api_favorites', true);
2016-08-12 02:42:44 +00:00
function api_format_as( $ret, $user_info) {
$as = array();
2016-03-31 23:06:03 +00:00
$as['title'] = App::$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;
2016-03-31 05:13:24 +00:00
$as['link']['url'] = z_root()."/".$user_info["screen_name"]."/all";
2012-04-08 18:19:14 +00:00
$as['link']['rel'] = "alternate";
$as['link']['type'] = "text/html";
return($as);
}
2015-04-19 20:41:12 +00:00
function api_format_message($item, $recipient, $sender) {
// standard meta information
2013-01-19 14:08:13 +00:00
$ret = array(
'id' => $item['id'],
'created_at' => api_date($item['created']),
'sender_id' => $sender['id'] ,
'sender_screen_name' => $sender['screen_name'],
'sender' => $sender,
'recipient_id' => $recipient['id'],
'recipient_screen_name' => $recipient['screen_name'],
'recipient' => $recipient,
);
2015-04-19 20:41:12 +00:00
unobscure_mail($item);
//don't send title to regular StatusNET requests to avoid confusing these apps
if (x($_GET, 'getText')) {
$ret['title'] = $item['title'] ;
if ($_GET["getText"] == "html") {
$ret['text'] = prepare_text($item['body'],$item['mimetype']);
}
elseif ($_GET["getText"] == "plain") {
$ret['text'] = html2plain(prepare_text($item['body'],$item['mimetype']), 0);
}
}
else {
$ret['text'] = $item['title']."\n".html2plain(prepare_text($item['body'],$item['mimetype']), 0);
}
if (isset($_GET["getUserObjects"]) && $_GET["getUserObjects"] == "false") {
unset($ret['sender']);
unset($ret['recipient']);
}
return $ret;
}
2011-07-31 23:35:53 +00:00
function api_format_items($r,$user_info) {
2011-08-01 03:01:00 +00:00
//logger('api_format_items: ' . print_r($r,true));
//logger('api_format_items: ' . print_r($user_info,true));
2013-01-19 14:08:13 +00:00
$ret = array();
2011-02-15 11:24:21 +00:00
$x = array('items' => $r,'api_user' => api_user(),'user_info' => $user_info);
call_hooks('api_format_items',$x);
$r = $x['items'];
2014-08-15 00:55:14 +00:00
if(! $r)
return $ret;
2011-02-16 07:56:47 +00:00
foreach($r as $item) {
2011-08-26 14:35:51 +00:00
localize_item($item);
2016-08-12 02:42:44 +00:00
$status_user = (($item['author_xchan']==$user_info['guid'])?$user_info: api_item_get_user($item));
2015-04-20 00:39:17 +00:00
if(array_key_exists('status',$status_user))
unset($status_user['status']);
2013-01-19 14:08:13 +00:00
if($item['parent'] != $item['id']) {
$r = q("select id from item where parent= %d and id < %d order by id desc limit 1",
intval($item['parent']),
intval($item['id'])
);
2012-03-18 17:21:51 +00:00
if ($r)
$in_reply_to_status_id = $r[0]['id'];
else
$in_reply_to_status_id = $item['parent'];
xchan_query($r,true);
2013-01-19 14:08:13 +00:00
$in_reply_to_screen_name = $r[0]['author']['xchan_name'];
$in_reply_to_user_id = $r[0]['author']['abook_id'];
2012-03-18 17:21:51 +00:00
} else {
$in_reply_to_screen_name = '';
$in_reply_to_user_id = 0;
2012-03-18 17:21:51 +00:00
$in_reply_to_status_id = 0;
}
unobscure($item);
// Workaround for ostatus messages where the title is identically to the body
$statusbody = trim(html2plain(prepare_text($item['body'],$item['mimetype']), 0));
$statustitle = trim($item['title']);
if (($statustitle != '') and (strpos($statusbody, $statustitle) !== false))
$statustext = trim($statusbody);
else
$statustext = trim($statustitle."\n\n".$statusbody);
2011-04-21 15:03:31 +00:00
$status = array(
2013-01-19 14:08:13 +00:00
'text' => $statustext,
'truncated' => False,
'created_at' => api_date($item['created']),
'in_reply_to_status_id' => $in_reply_to_status_id,
'source' => (($item['app']) ? $item['app'] : 'web'),
'id' => intval($item['id']),
'in_reply_to_user_id' => $in_reply_to_user_id,
'in_reply_to_screen_name' => $in_reply_to_screen_name,
'geo' => '',
'favorited' => (intval($item['item_starred']) ? true : false),
2013-01-19 14:08:13 +00:00
'user' => $status_user ,
2014-03-16 22:20:04 +00:00
'statusnet_html' => trim(prepare_text($item['body'],$item['mimetype'])),
'statusnet_conversation_id' => $item['parent'],
2011-04-21 15:03:31 +00:00
);
// Seesmic doesn't like the following content
if ($_SERVER['HTTP_USER_AGENT'] != 'Seesmic') {
$status2 = array(
2013-01-19 14:08:13 +00:00
'updated' => api_date($item['edited']),
'published' => api_date($item['created']),
'message_id' => $item['mid'],
2013-01-19 14:08:13 +00:00
'url' => $item['plink'],
'coordinates' => $item['coord'],
'place' => $item['location'],
'contributors' => '',
'annotations' => '',
2013-01-19 14:08:13 +00:00
'entities' => '',
'objecttype' => (($item['obj_type']) ? $item['obj_type'] : ACTIVITY_OBJ_NOTE),
'verb' => (($item['verb']) ? $item['verb'] : ACTIVITY_POST),
2016-03-31 05:13:24 +00:00
'self' => z_root()."/api/statuses/show/".$item['id'].".".$type,
'edit' => z_root()."/api/statuses/show/".$item['id'].".".$type,
);
$status = array_merge($status, $status2);
}
2011-02-15 11:24:21 +00:00
$ret[]=$status;
};
2011-07-31 23:35:53 +00:00
return $ret;
2011-02-16 07:56:47 +00:00
}
2011-07-31 23:35:53 +00:00
2011-06-21 00:16:13 +00:00
2016-08-12 02:42:44 +00:00
function api_account_rate_limit_status($type) {
2011-06-21 00:16:13 +00:00
$hash = array(
'reset_time_in_seconds' => strtotime('now + 1 hour'),
2011-06-21 00:16:13 +00:00
'remaining_hits' => (string) 150,
'hourly_limit' => (string) 150,
'reset_time' => datetime_convert('UTC','UTC','now + 1 hour',ATOM_TIME),
);
if ($type == "xml")
$hash['resettime_in_seconds'] = $hash['reset_time_in_seconds'];
2011-06-21 00:16:13 +00:00
return api_apply_template('ratelimit', $type, array('$hash' => $hash));
}
api_register_func('api/account/rate_limit_status','api_account_rate_limit_status',true);
2011-07-29 04:56:56 +00:00
2016-08-12 02:42:44 +00:00
function api_help_test($type) {
if ($type == 'xml')
$ok = "true";
else
$ok = "ok";
2016-10-12 01:37:47 +00:00
return api_apply_template('test', $type, array('ok' => $ok));
}
2013-03-11 01:45:58 +00:00
api_register_func('api/help/test','api_help_test',false);
/**
* https://dev.twitter.com/docs/api/1/get/statuses/friends
* This function is deprecated by Twitter
* returns: json, xml
**/
2016-08-12 02:42:44 +00:00
function api_statuses_f( $type, $qtype) {
2013-01-16 23:51:21 +00:00
if (api_user()===false) return false;
2016-10-12 01:37:47 +00:00
$user_info = api_get_user();
2011-08-26 14:35:51 +00:00
// friends and followers only for self
if ($user_info['self']==0){
return false;
}
if (x($_GET,'cursor') && $_GET['cursor']=='undefined'){
/* this is to stop Hotot to load friends multiple times
* I'm not sure if I'm missing return something or
* is a bug in hotot. Workaround, meantime
*/
2011-08-26 14:35:51 +00:00
/*$ret=Array();
return array('$users' => $ret);*/
return false;
}
2016-10-12 01:37:47 +00:00
if($qtype == 'friends') {
$r = q("select abook_id from abook left join abconfig on abook_xchan = xchan and abook_channel = chan
where chan = %d and abook_self = 0 and abook_pending = 0 and cat = 'my_perms' and k = 'view_stream' and v = '1' ",
intval(api_user())
);
}
if($qtype == 'followers') {
$r = q("select abook_id from abook left join abconfig on abook_xchan = xchan and abook_channel = chan
where chan = %d and abook_self = 0 and abook_pending = 0 and cat = 'their_perms' and k = 'view_stream' and v = '1' ",
intval(api_user())
);
}
$ret = array();
2016-10-12 01:37:47 +00:00
if($r) {
foreach($r as $cid) {
$ret[] = api_get_user($cid['abook_id']);
}
}
2016-10-12 01:37:47 +00:00
return array('users' => $ret);
}
2016-10-12 01:37:47 +00:00
function api_statuses_friends($type){
$data = api_statuses_f($type,'friends');
if($data === false)
return false;
return(api_apply_template('friends', $type, $data));
}
2016-10-12 01:37:47 +00:00
function api_statuses_followers($type){
$data = api_statuses_f($type,'followers');
if ($data === false)
return false;
return(api_apply_template('friends', $type, $data));
}
2016-10-12 01:37:47 +00:00
api_register_func('api/statuses/friends','api_statuses_friends',true);
api_register_func('api/statuses/followers','api_statuses_followers',true);
2011-07-29 04:56:56 +00:00
2016-08-12 02:42:44 +00:00
function api_statusnet_config($type) {
2013-01-16 23:51:21 +00:00
2016-10-12 01:37:47 +00:00
$name = get_config('system','sitename');
$server = App::get_hostname();
$logo = z_root() . '/images/hz-64.png';
$email = get_config('system','admin_email');
$closed = ((get_config('system','register_policy') == REGISTER_CLOSED) ? true : false);
$private = ((get_config('system','block_public')) ? true : false);
$textlimit = ((get_config('system','max_import_size')) ? get_config('system','max_import_size') : 200000);
2013-01-16 23:51:21 +00:00
if(get_config('system','api_import_size'))
2016-10-12 01:37:47 +00:00
$texlimit = get_config('system','api_import_size');
$m = parse_url(z_root());
$ssl = (($m['scheme'] === 'https') ? true : false);
$sslserver = (($ssl) ? str_replace('http:','https:',z_root()) : '');
$config = [
'site' => [
'name' => $name,
'server' => $server,
'theme' => 'default',
'path' => '',
'logo' => $logo,
'fancy' => true,
'language' => 'en',
'email' => $email,
'broughtby' => '',
'broughtbyurl' => '',
'timezone' => 'UTC',
'closed' => $closed,
'inviteonly' => false,
'private' => $private,
'textlimit' => $textlimit,
'sslserver' => $sslserver,
'ssl' => $ssl,
'shorturllength' => 30,
'platform' => [
'PLATFORM_NAME' => Zotlabs\Lib\System::get_platform_name(),
'STD_VERSION' => Zotlabs\Lib\System::get_project_version(),
'ZOT_REVISION' => ZOT_REVISION,
'DB_UPDATE_VERSION' => Zotlabs\Lib\System::get_update_version()
]
]
];
2011-07-29 04:56:56 +00:00
2016-10-11 23:13:52 +00:00
return api_apply_template('config', $type, array('config' => $config));
2011-07-29 04:56:56 +00:00
}
api_register_func('api/statusnet/config','api_statusnet_config',false);
2013-01-16 23:51:21 +00:00
api_register_func('api/friendica/config','api_statusnet_config',false);
api_register_func('api/red/config','api_statusnet_config',false);
2016-10-09 23:13:49 +00:00
api_register_func('api/z/1.0/config','api_statusnet_config',false);
2011-07-29 04:56:56 +00:00
2016-08-12 02:42:44 +00:00
function api_statusnet_version($type) {
2011-07-30 01:21:54 +00:00
// liar
if($type === 'xml') {
header("Content-type: application/xml");
echo '<?xml version="1.0" encoding="UTF-8"?>' . "\r\n" . '<version>0.9.7</version>' . "\r\n";
killme();
}
elseif($type === 'json') {
header("Content-type: application/json");
echo '"0.9.7"';
killme();
}
}
api_register_func('api/statusnet/version','api_statusnet_version',false);
2011-08-01 05:22:34 +00:00
2016-08-12 02:42:44 +00:00
function api_friendica_version($type) {
2013-01-16 23:51:21 +00:00
if($type === 'xml') {
header("Content-type: application/xml");
echo '<?xml version="1.0" encoding="UTF-8"?>' . "\r\n" . '<version>' . Zotlabs\Lib\System::get_project_version() . '</version>' . "\r\n";
2013-01-16 23:51:21 +00:00
killme();
}
elseif($type === 'json') {
header("Content-type: application/json");
echo '"' . Zotlabs\Lib\System::get_project_version() . '"';
2013-01-16 23:51:21 +00:00
killme();
}
}
api_register_func('api/friendica/version','api_friendica_version',false);
api_register_func('api/red/version','api_friendica_version',false);
2016-10-09 23:13:49 +00:00
api_register_func('api/z/1.0/version','api_friendica_version',false);
2013-01-16 23:51:21 +00:00
2016-08-12 02:42:44 +00:00
function api_ff_ids($type,$qtype) {
2016-10-12 01:37:47 +00:00
2013-01-16 23:51:21 +00:00
if(! api_user())
2011-08-01 05:22:34 +00:00
return false;
2016-10-12 01:37:47 +00:00
if($qtype == 'friends') {
$r = q("select abook_id from abook left join abconfig on abook_xchan = xchan and abook_channel = chan
where chan = %d and abook_self = 0 and abook_pending = 0 and cat = 'my_perms' and k = 'view_stream' and v = '1' ",
intval(api_user())
);
}
2013-01-21 02:36:33 +00:00
2016-10-12 01:37:47 +00:00
if($qtype == 'followers') {
$r = q("select abook_id from abook left join abconfig on abook_xchan = xchan and abook_channel = chan
where chan = %d and abook_self = 0 and abook_pending = 0 and cat = 'their_perms' and k = 'view_stream' and v = '1' ",
intval(api_user())
);
}
2011-08-01 05:22:34 +00:00
2016-10-12 01:37:47 +00:00
if($r) {
2011-08-01 05:22:34 +00:00
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['abook_id'] . '</id>' . "\r\n";
2011-08-01 05:22:34 +00:00
echo '</ids>' . "\r\n";
killme();
}
elseif($type === 'json') {
$ret = array();
header("Content-type: application/json");
foreach($r as $rr) $ret[] = $rr['abook_id'];
2011-08-01 05:22:34 +00:00
echo json_encode($ret);
killme();
}
}
}
2016-08-12 02:42:44 +00:00
function api_friends_ids($type) {
api_ff_ids($type,'friends');
2011-08-01 05:22:34 +00:00
}
2016-08-12 02:42:44 +00:00
function api_followers_ids($type) {
api_ff_ids($type,'followers');
2011-08-01 05:22:34 +00:00
}
api_register_func('api/friends/ids','api_friends_ids',true);
api_register_func('api/followers/ids','api_followers_ids',true);
2016-08-12 02:42:44 +00:00
function api_direct_messages_new( $type) {
2013-01-16 23:51:21 +00:00
if (api_user()===false) return false;
2011-08-19 14:55:43 +00:00
if (!x($_POST, "text") || !x($_POST,"screen_name")) return;
2016-10-12 01:37:47 +00:00
$sender = api_get_user();
2011-08-19 14:55:43 +00:00
require_once("include/message.php");
// in a decentralised world the screen name is ambiguous
2016-10-12 01:37:47 +00:00
$r = q("SELECT abook_id FROM abook left join xchan on abook_xchan = xchan_hash
WHERE abook_channel = %d and xchan_addr like '%s'",
intval(api_user()),
dbesc($_POST['screen_name'] . '@%')
);
2016-10-12 01:37:47 +00:00
$recipient = api_get_user($r[0]['abook_id']);
$replyto = '';
$sub = '';
if(array_key_exists('replyto',$_REQUEST) && $_REQUEST['replyto']) {
2016-10-09 23:13:49 +00:00
$r = q('SELECT parent_mid, title FROM mail WHERE uid=%d AND id=%d',
2016-10-12 01:37:47 +00:00
intval(api_user()),
intval($_REQUEST['replyto'])
);
if($r) {
$replyto = $r[0]['parent_mid'];
$sub = $r[0]['title'];
}
}
else {
2016-10-12 01:37:47 +00:00
if(x($_REQUEST,'title')) {
$sub = $_REQUEST['title'];
}
else {
$sub = ((strlen($_POST['text'])>10)?substr($_POST['text'],0,10)."...":$_POST['text']);
}
}
$id = send_message(api_user(),$recipient['guid'], $_POST['text'], $sub, $replyto);
2011-08-19 14:55:43 +00:00
2016-10-09 23:13:49 +00:00
if ($id > (-1)) {
$r = q("SELECT * FROM mail WHERE id = %d", intval($id));
2015-04-19 20:41:12 +00:00
$ret = api_format_message($r[0], $recipient, $sender);
2011-08-19 14:55:43 +00:00
2016-10-12 01:37:47 +00:00
}
else {
$ret = [ 'error' => $id ];
2011-08-19 14:55:43 +00:00
}
2016-10-12 01:37:47 +00:00
$data = [ 'messages' => $ret ];
return(api_apply_template('direct_messages', $type, $data));
2011-08-19 14:55:43 +00:00
}
2016-10-12 01:37:47 +00:00
2011-08-19 14:55:43 +00:00
api_register_func('api/direct_messages/new','api_direct_messages_new',true);
2016-08-12 02:42:44 +00:00
function api_direct_messages_box( $type, $box) {
2016-10-12 01:37:47 +00:00
if(api_user()===false)
return false;
2011-08-19 14:55:43 +00:00
2016-10-12 01:37:47 +00:00
$user_info = api_get_user();
2011-08-19 14:55:43 +00:00
// params
2016-10-12 01:37:47 +00:00
$count = (x($_GET,'count') ? $_GET['count'] : 20);
$page = (x($_REQUEST,'page') ? $_REQUEST['page'] - 1 : 0);
if($page < 0)
$page=0;
2011-08-19 14:55:43 +00:00
2016-10-12 01:37:47 +00:00
$start = $page*$count;
2016-03-31 23:06:03 +00:00
$channel = App::get_channel();
2016-03-31 05:13:24 +00:00
$profile_url = z_root() . '/channel/' . $channel['channel_address'];
2016-10-12 01:37:47 +00:00
if ($box === 'sentbox') {
$sql_extra = "from_xchan = '" . dbesc( $channel['channel_hash'] ) . "'";
}
2016-10-12 01:37:47 +00:00
elseif($box === 'conversation') {
$sql_extra = "parent_mid = '" . dbesc($_GET['uri']) . "'";
}
2016-10-12 01:37:47 +00:00
elseif($box === 'all') {
$sql_extra = 'true';
}
2016-10-12 01:37:47 +00:00
elseif($box === 'inbox') {
$sql_extra = "from_xchan != '" . dbesc($channel['channel_hash']) . "'";
2011-08-19 14:55:43 +00:00
}
2016-10-09 23:13:49 +00:00
$r = q("SELECT * FROM mail WHERE channel_id = %d AND $sql_extra ORDER BY created DESC LIMIT %d OFFSET %d",
2013-01-16 23:51:21 +00:00
intval(api_user()),
2016-10-12 01:37:47 +00:00
intval($count),
intval($start)
2012-06-23 17:21:48 +00:00
);
2011-08-19 14:55:43 +00:00
2016-10-12 01:37:47 +00:00
$ret = array();
2014-08-15 00:55:14 +00:00
if($r) {
foreach($r as $item) {
2016-10-12 01:37:47 +00:00
if ($item['from_xchan'] === $channel['channel_hash']) {
2014-08-15 00:55:14 +00:00
$sender = $user_info;
2016-08-12 02:42:44 +00:00
$recipient = api_get_user( null, $item['to_xchan']);
2015-04-20 01:14:17 +00:00
}
else {
2016-08-12 02:42:44 +00:00
$sender = api_get_user( null, $item['from_xchan']);
2015-04-20 01:14:17 +00:00
$recipient = $user_info;
2014-08-15 00:55:14 +00:00
}
2016-10-12 01:37:47 +00:00
$ret[] = api_format_message($item, $recipient, $sender);
}
2011-08-19 14:55:43 +00:00
}
2016-10-12 01:37:47 +00:00
$data = array('messages' => $ret);
return(api_apply_template('direct_messages', $type, $data));
2011-08-19 14:55:43 +00:00
}
2016-10-12 01:37:47 +00:00
function api_direct_messages_sentbox($type){
return api_direct_messages_box($type, 'sentbox');
2011-08-19 14:55:43 +00:00
}
2016-10-12 01:37:47 +00:00
function api_direct_messages_inbox($type){
return api_direct_messages_box($type, 'inbox');
2011-08-19 14:55:43 +00:00
}
2016-10-12 01:37:47 +00:00
function api_direct_messages_all($type){
return api_direct_messages_box($type, 'all');
2012-06-23 17:21:48 +00:00
}
2016-10-12 01:37:47 +00:00
function api_direct_messages_conversation($type){
return api_direct_messages_box($type, 'conversation');
2012-06-23 17:21:48 +00:00
}
api_register_func('api/direct_messages/conversation','api_direct_messages_conversation',true);
api_register_func('api/direct_messages/all','api_direct_messages_all',true);
2011-08-19 14:55:43 +00:00
api_register_func('api/direct_messages/sent','api_direct_messages_sentbox',true);
api_register_func('api/direct_messages','api_direct_messages_inbox',true);
2011-10-20 13:57:35 +00:00
2016-08-12 02:42:44 +00:00
function api_oauth_request_token( $type){
2011-10-20 13:57:35 +00:00
try{
$oauth = new ZotOAuth1();
$req = OAuth1Request::from_request();
logger('Req: ' . var_export($req,true),LOGGER_DATA);
$r = $oauth->fetch_request_token($req);
2011-10-20 13:57:35 +00:00
}catch(Exception $e){
logger('oauth_exception: ' . print_r($e->getMessage(),true));
echo "error=". OAuth1Util::urlencode_rfc3986($e->getMessage());
killme();
2011-10-20 13:57:35 +00:00
}
2011-11-07 16:36:58 +00:00
echo $r;
2011-10-20 13:57:35 +00:00
killme();
}
2016-08-12 02:42:44 +00:00
function api_oauth_access_token( $type){
2011-10-20 13:57:35 +00:00
try{
$oauth = new ZotOAuth1();
2016-10-12 01:37:47 +00:00
$req = OAuth1Request::from_request();
$r = $oauth->fetch_access_token($req);
}
catch(Exception $e) {
echo 'error=' . OAuth1Util::urlencode_rfc3986($e->getMessage());
killme();
2011-10-20 13:57:35 +00:00
}
2011-11-07 16:36:58 +00:00
echo $r;
2011-10-20 13:57:35 +00:00
killme();
}
2011-10-26 15:15:36 +00:00
2011-10-20 13:57:35 +00:00
api_register_func('api/oauth/request_token', 'api_oauth_request_token', false);
api_register_func('api/oauth/access_token', 'api_oauth_access_token', false);
2011-10-26 15:15:36 +00:00
/*
Not implemented by now:
statuses/retweets_of_me
friendships/create
friendships/destroy
friendships/exists
friendships/show
account/update_location
account/update_profile_background_image
account/update_profile_image
blocks/create
blocks/destroy
Not implemented in status.net:
statuses/retweeted_to_me
statuses/retweeted_by_me
direct_messages/destroy
account/end_session
account/update_delivery_device
notifications/follow
notifications/leave
blocks/exists
blocks/blocking
lists
*/