]> git.mxchange.org Git - friendica.git/blobdiff - include/api.php
Throw NotFoundException if results are empty in api_users_lookup
[friendica.git] / include / api.php
index 9d360fc7758bccfc22ea8f2e56442119032d44ce..6201b460a3c162e6ce96d68ea9660740568a35ca 100644 (file)
@@ -1485,6 +1485,98 @@ function api_users_search($type)
 /// @TODO move to top of file or somewhere better
 api_register_func('api/users/search', 'api_users_search');
 
+/**
+ * Return user objects
+ *
+ * @see https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-users-lookup
+ *
+ * @param string $type Return format: json or xml
+ *
+ * @return array|string
+ * @throws UnauthorizedException
+ * @throws NotFoundException
+ */
+function api_users_lookup($type)
+{
+       $users = array();
+
+       if (x($_REQUEST['user_id'])) {
+               foreach (explode(',', $_REQUEST['user_id']) as $id) {
+                       if (!empty($id)) {
+                               $users[] = api_get_user(get_app(), $id);
+                       }
+               }
+       }
+
+       if (empty($users)) {
+               throw new NotFoundException;
+       }
+
+       return api_format_data("users", $type, array('users' => $users));
+}
+
+/// @TODO move to top of file or somewhere better
+api_register_func('api/users/lookup', 'api_users_lookup', true);
+
+/**
+ * Returns statuses that match a specified query.
+ *
+ * @see https://developer.twitter.com/en/docs/tweets/search/api-reference/get-search-tweets
+ *
+ * @param string $type Return format: json, xml, atom, rss
+ *
+ * @return array|string
+ * @throws UnauthorizedException
+ * @throws BadRequestException
+ */
+function api_search($type)
+{
+       $data = array();
+
+       if (!x($_REQUEST, 'q')) {
+               throw new BadRequestException("q parameter is required.");
+       }
+
+       if (x($_REQUEST, 'rpp')) {
+               $count = $_REQUEST['rpp'];
+       } elseif (x($_REQUEST, 'count')) {
+               $count = $_REQUEST['count'];
+       } else {
+               $count = 15;
+       }
+
+       $since_id = (x($_REQUEST, 'since_id') ? $_REQUEST['since_id'] : 0);
+       $max_id = (x($_REQUEST, 'max_id') ? $_REQUEST['max_id'] : 0);
+       $page = (x($_REQUEST, 'page') ? $_REQUEST['page'] - 1 : 0);
+
+       $start = $page * $count;
+
+       if ($max_id > 0) {
+               $sql_extra .= ' AND `item`.`id` <= ' . intval($max_id);
+       }
+
+       $r = dba::p(
+               "SELECT ".item_fieldlists()."
+               FROM `item` ".item_joins()."
+               WHERE ".item_condition()." AND (`item`.`uid` = 0 OR (`item`.`uid` = ? AND NOT `item`.`global`))
+               AND `item`.`body` LIKE CONCAT('%',?,'%')
+               $sql_extra
+               AND `item`.`id`>?
+               ORDER BY `item`.`id` DESC LIMIT ".intval($start)." ,".intval($count)." ",
+               api_user(),
+               $_REQUEST['q'],
+               $since_id
+       );
+
+       $data['status'] = api_format_items(dba::inArray($r), api_get_user(get_app()));
+
+       return api_format_data("statuses", $type, $data);
+}
+
+/// @TODO move to top of file or somewhere better
+api_register_func('api/search/tweets', 'api_search', true);
+api_register_func('api/search', 'api_search', true);
+
 /**
  *
  * http://developer.twitter.com/doc/get/statuses/home_timeline
@@ -1612,40 +1704,131 @@ function api_statuses_public_timeline($type)
 
        $start = $page * $count;
 
-       if ($max_id > 0) {
-               $sql_extra = 'AND `item`.`id` <= ' . intval($max_id);
+       if ($exclude_replies && !$conversation_id) {
+               if ($max_id > 0) {
+                       $sql_extra = 'AND `thread`.`iid` <= ' . intval($max_id);
+               }
+
+               $r = dba::p("SELECT " . item_fieldlists() . "
+                       FROM `thread`
+                       STRAIGHT_JOIN `item` ON `item`.`id` = `thread`.`iid`
+                       " . item_joins() . "
+                       STRAIGHT_JOIN `user` ON `user`.`uid` = `thread`.`uid`
+                               AND NOT `user`.`hidewall`
+                       AND `verb` = ?
+                       AND NOT `thread`.`private`
+                       AND `thread`.`wall`
+                       AND `thread`.`visible`
+                       AND NOT `thread`.`deleted`
+                       AND NOT `thread`.`moderated`
+                       AND `thread`.`iid` > ?
+                       $sql_extra
+                       ORDER BY `thread`.`iid` DESC
+                       LIMIT " . intval($start) . ", " . intval($count),
+                       ACTIVITY_POST,
+                       $since_id
+               );
+
+               $r = dba::inArray($r);
+       } else {
+               if ($max_id > 0) {
+                       $sql_extra = 'AND `item`.`id` <= ' . intval($max_id);
+               }
+               if ($conversation_id > 0) {
+                       $sql_extra .= ' AND `item`.`parent` = ' . intval($conversation_id);
+               }
+
+               $r = dba::p("SELECT " . item_fieldlists() . "
+                       FROM `item`
+                       " . item_joins() . "
+                       STRAIGHT_JOIN `user` ON `user`.`uid` = `item`.`uid`
+                               AND NOT `user`.`hidewall`
+                       AND `verb` = ?
+                       AND NOT `item`.`private`
+                       AND `item`.`wall`
+                       AND `item`.`visible`
+                       AND NOT `item`.`deleted`
+                       AND NOT `item`.`moderated`
+                       AND `item`.`id` > ?
+                       $sql_extra
+                       ORDER BY `item`.`id` DESC
+                       LIMIT " . intval($start) . ", " . intval($count),
+                       ACTIVITY_POST,
+                       $since_id
+               );
+
+               $r = dba::inArray($r);
        }
-       if ($exclude_replies > 0) {
-               $sql_extra .= ' AND `item`.`parent` = `item`.`id`';
+
+       $ret = api_format_items($r, $user_info, false, $type);
+
+       $data = array('status' => $ret);
+       switch ($type) {
+               case "atom":
+               case "rss":
+                       $data = api_rss_extra($a, $data, $user_info);
+                       break;
        }
-       if ($conversation_id > 0) {
-               $sql_extra .= ' AND `item`.`parent` = ' . intval($conversation_id);
+
+       return api_format_data("statuses", $type, $data);
+}
+
+/// @TODO move to top of file or somewhere better
+api_register_func('api/statuses/public_timeline', 'api_statuses_public_timeline', true);
+
+/**
+ * @brief Returns the list of public federated posts this node knows about
+ *
+ * @param string $type Return format: json, xml, atom, rss
+ * @return array|string
+ * @throws ForbiddenException
+ */
+function api_statuses_networkpublic_timeline($type)
+{
+       $a = get_app();
+
+       if (api_user() === false) {
+               throw new ForbiddenException();
        }
 
-       $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`.`self`, `contact`.`writable`,
-               `contact`.`id` AS `cid`,
-               `user`.`nickname`, `user`.`hidewall`
-               FROM `item`
-               STRAIGHT_JOIN `contact` ON `contact`.`id` = `item`.`contact-id` AND `contact`.`uid` = `item`.`uid`
-                       AND (NOT `contact`.`blocked` OR `contact`.`pending`)
-               STRAIGHT_JOIN `user` ON `user`.`uid` = `item`.`uid`
-                       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 NOT `item`.`private` AND `item`.`wall`
+       $user_info = api_get_user($a);
+
+       $since_id        = x($_REQUEST, 'since_id')        ? $_REQUEST['since_id']        : 0;
+       $max_id          = x($_REQUEST, 'max_id')          ? $_REQUEST['max_id']          : 0;
+
+       // pagination
+       $count = x($_REQUEST, 'count') ? $_REQUEST['count']   : 20;
+       $page  = x($_REQUEST, 'page')  ? $_REQUEST['page']    : 1;
+       if ($page < 1) {
+               $page = 1;
+       }
+       $start = ($page - 1) * $count;
+
+       $sql_extra = '';
+       if ($max_id > 0) {
+               $sql_extra = 'AND `thread`.`iid` <= ' . intval($max_id);
+       }
+
+       $r = dba::p("SELECT " . item_fieldlists() . "
+               FROM `thread`
+               STRAIGHT_JOIN `item` ON `item`.`id` = `thread`.`iid`
+               " . item_joins() . "
+               WHERE `thread`.`uid` = 0
+               AND `verb` = ?
+               AND NOT `thread`.`private`
+               AND `thread`.`visible`
+               AND NOT `thread`.`deleted`
+               AND NOT `thread`.`moderated`
+               AND `thread`.`iid` > ?
                $sql_extra
-               AND `item`.`id`>%d
-               ORDER BY `item`.`id` DESC LIMIT %d, %d ",
-               dbesc(ACTIVITY_POST),
-               intval($since_id),
-               intval($start),
-               intval($count)
+               ORDER BY `thread`.`iid` DESC
+               LIMIT " . intval($start) . ", " . intval($count),
+               ACTIVITY_POST,
+               $since_id
        );
 
+       $r = dba::inArray($r);
+
        $ret = api_format_items($r, $user_info, false, $type);
 
        $data = array('status' => $ret);
@@ -1660,7 +1843,7 @@ function api_statuses_public_timeline($type)
 }
 
 /// @TODO move to top of file or somewhere better
-api_register_func('api/statuses/public_timeline', 'api_statuses_public_timeline', true);
+api_register_func('api/statuses/networkpublic_timeline', 'api_statuses_networkpublic_timeline', true);
 
 /**
  * @TODO nothing to say?
@@ -2964,12 +3147,20 @@ function api_statuses_f($qtype)
                $sql_extra = " AND false ";
        }
 
+       if ($qtype == 'blocks') {
+               $sql_filter = 'AND `blocked` AND NOT `pending`';
+       } elseif ($qtype == 'incoming') {
+               $sql_filter = 'AND `pending`';
+       } else {
+               $sql_filter = 'AND (NOT `blocked` OR `pending`)';
+       }
+
        $r = q(
                "SELECT `nurl`
                FROM `contact`
                WHERE `uid` = %d
                AND NOT `self`
-               AND (NOT `blocked` OR `pending`)
+               $sql_filter
                $sql_extra
                ORDER BY `nick`
                LIMIT %d, %d",
@@ -3032,6 +3223,56 @@ function api_statuses_followers($type)
 api_register_func('api/statuses/friends', 'api_statuses_friends', true);
 api_register_func('api/statuses/followers', 'api_statuses_followers', true);
 
+/**
+ * Returns the list of blocked users
+ *
+ * @see https://developer.twitter.com/en/docs/accounts-and-users/mute-block-report-users/api-reference/get-blocks-list
+ *
+ * @param string $type Either "json" or "xml"
+ *
+ * @return boolean|string|array
+ * @throws UnauthorizedException
+ */
+function api_blocks_list($type)
+{
+       $data =  api_statuses_f('blocks');
+       if ($data === false) {
+               return false;
+       }
+       return api_format_data("users", $type, $data);
+}
+
+/// @TODO move to top of file or somewhere better
+api_register_func('api/blocks/list', 'api_blocks_list', true);
+
+/**
+ * Returns the list of pending users IDs
+ *
+ * @see https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friendships-incoming
+ *
+ * @param string $type Either "json" or "xml"
+ *
+ * @return boolean|string|array
+ * @throws UnauthorizedException
+ */
+function api_friendships_incoming($type)
+{
+       $data =  api_statuses_f('incoming');
+       if ($data === false) {
+               return false;
+       }
+
+       $ids = array();
+       foreach ($data['user'] as $user) {
+               $ids[] = $user['id'];
+       }
+
+       return api_format_data("ids", $type, array('id' => $ids));
+}
+
+/// @TODO move to top of file or somewhere better
+api_register_func('api/friendships/incoming', 'api_friendships_incoming', true);
+
 function api_statusnet_config($type)
 {
        $a = get_app();